@aylith/inspekt-core 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/actions/built-in.d.ts +17 -0
  2. package/dist/actions/built-in.d.ts.map +1 -0
  3. package/dist/adapters/generic.d.ts +3 -0
  4. package/dist/adapters/generic.d.ts.map +1 -0
  5. package/dist/adapters/index.d.ts +5 -0
  6. package/dist/adapters/index.d.ts.map +1 -0
  7. package/dist/adapters/react.d.ts +3 -0
  8. package/dist/adapters/react.d.ts.map +1 -0
  9. package/dist/adapters/solid.d.ts +3 -0
  10. package/dist/adapters/solid.d.ts.map +1 -0
  11. package/dist/adapters/svelte.d.ts +3 -0
  12. package/dist/adapters/svelte.d.ts.map +1 -0
  13. package/dist/adapters/types.d.ts +19 -0
  14. package/dist/adapters/types.d.ts.map +1 -0
  15. package/dist/adapters/vue.d.ts +3 -0
  16. package/dist/adapters/vue.d.ts.map +1 -0
  17. package/dist/capability-probe-AKVKYSDE.js +107 -0
  18. package/dist/capability-probe-AKVKYSDE.js.map +1 -0
  19. package/dist/components/rich-select.d.ts +62 -0
  20. package/dist/components/rich-select.d.ts.map +1 -0
  21. package/dist/components/tooltip.d.ts +34 -0
  22. package/dist/components/tooltip.d.ts.map +1 -0
  23. package/dist/detection/capability-probe.d.ts +31 -0
  24. package/dist/detection/capability-probe.d.ts.map +1 -0
  25. package/dist/detection/fiber-detector.d.ts +12 -0
  26. package/dist/detection/fiber-detector.d.ts.map +1 -0
  27. package/dist/detection/source-detector.d.ts +30 -0
  28. package/dist/detection/source-detector.d.ts.map +1 -0
  29. package/dist/detection/vue-detector.d.ts +14 -0
  30. package/dist/detection/vue-detector.d.ts.map +1 -0
  31. package/dist/fiber-detector-CFB7M7OY.js +50 -0
  32. package/dist/fiber-detector-CFB7M7OY.js.map +1 -0
  33. package/dist/highlight/bounding-boxes.d.ts +20 -0
  34. package/dist/highlight/bounding-boxes.d.ts.map +1 -0
  35. package/dist/highlight/highlighter.d.ts +11 -0
  36. package/dist/highlight/highlighter.d.ts.map +1 -0
  37. package/dist/highlight/prism.d.ts +23 -0
  38. package/dist/highlight/prism.d.ts.map +1 -0
  39. package/dist/index.cjs +3560 -0
  40. package/dist/index.cjs.map +1 -0
  41. package/dist/index.d.ts +12 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +3222 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/overlay/overlay.d.ts +30 -0
  46. package/dist/overlay/overlay.d.ts.map +1 -0
  47. package/dist/popover/popover.d.ts +54 -0
  48. package/dist/popover/popover.d.ts.map +1 -0
  49. package/dist/runtime/context.d.ts +3 -0
  50. package/dist/runtime/context.d.ts.map +1 -0
  51. package/dist/runtime/freeze.d.ts +2 -0
  52. package/dist/runtime/freeze.d.ts.map +1 -0
  53. package/dist/runtime/index.d.ts +4 -0
  54. package/dist/runtime/index.d.ts.map +1 -0
  55. package/dist/runtime/open-file.d.ts +2 -0
  56. package/dist/runtime/open-file.d.ts.map +1 -0
  57. package/dist/snippet/cache.d.ts +13 -0
  58. package/dist/snippet/cache.d.ts.map +1 -0
  59. package/dist/snippet/snippet-resolver.d.ts +21 -0
  60. package/dist/snippet/snippet-resolver.d.ts.map +1 -0
  61. package/dist/snippet/sourcemap-resolver.d.ts +9 -0
  62. package/dist/snippet/sourcemap-resolver.d.ts.map +1 -0
  63. package/dist/sourcemap-resolver-3PQ6R6PU.js +182 -0
  64. package/dist/sourcemap-resolver-3PQ6R6PU.js.map +1 -0
  65. package/dist/styles.d.ts +2 -0
  66. package/dist/styles.d.ts.map +1 -0
  67. package/dist/tree-panel/tree-panel.d.ts +33 -0
  68. package/dist/tree-panel/tree-panel.d.ts.map +1 -0
  69. package/dist/types.d.ts +148 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/package.json +51 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/detection/vue-detector.ts","../src/detection/source-detector.ts","../src/highlight/highlighter.ts","../src/highlight/bounding-boxes.ts","../src/snippet/snippet-resolver.ts","../src/highlight/prism.ts","../src/components/tooltip.ts","../src/popover/popover.ts","../src/overlay/overlay.ts","../src/actions/built-in.ts","../src/tree-panel/tree-panel.ts","../src/adapters/react.ts","../src/adapters/vue.ts","../src/adapters/svelte.ts","../src/adapters/solid.ts","../src/adapters/generic.ts","../src/adapters/index.ts","../src/styles.ts","../src/components/rich-select.ts","../src/index.ts"],"sourcesContent":["// Vue source detection — the Vue parallel to fiber-detector.ts.\n//\n// Vue 3 (dev mode, `@vitejs/plugin-vue` with `isProduction === false`) hangs\n// `__vueParentComponent` off every host element. The component instance's\n// `type.__file` carries the source path. Vue 2 used `__vue__.$options.__file`\n// on the element itself. Both are *dev-only* — production builds strip them.\n//\n// Unlike React fiber detection, Vue introspection needs no async import:\n// the references are plain properties, so this runs synchronously and slots\n// into the click/hover hot path with zero added latency.\n\nimport type { SourceInfo } from './source-detector.js';\n\ninterface Vue3Component {\n type?: {\n __file?: string;\n __name?: string;\n name?: string;\n };\n parent?: Vue3Component | null;\n}\n\ninterface Vue2Instance {\n $options?: {\n __file?: string;\n name?: string;\n _componentTag?: string;\n };\n $parent?: Vue2Instance | null;\n}\n\ninterface VueAugmentedElement extends HTMLElement {\n __vueParentComponent?: Vue3Component;\n __vue__?: Vue2Instance;\n}\n\nfunction fromVue3(el: VueAugmentedElement): SourceInfo | null {\n let cmp: Vue3Component | null | undefined = el.__vueParentComponent;\n // Walk up to the nearest component that owns a source file. The leaf\n // component's `type.__file` is usually the host DOM element's owner,\n // but defensive walking handles edge cases (slot content, transitions).\n while (cmp) {\n const file = cmp.type?.__file;\n if (file) {\n const name = cmp.type?.__name ?? cmp.type?.name ?? fileNameOf(file);\n return {\n filePath: file,\n line: 1,\n column: 1,\n componentName: name,\n rawPath: `${file}:1:1:${name}`,\n };\n }\n cmp = cmp.parent ?? null;\n }\n return null;\n}\n\nfunction fromVue2(el: VueAugmentedElement): SourceInfo | null {\n let vm: Vue2Instance | null | undefined = el.__vue__;\n while (vm) {\n const file = vm.$options?.__file;\n if (file) {\n const name =\n vm.$options?.name ?? vm.$options?._componentTag ?? fileNameOf(file);\n return {\n filePath: file,\n line: 1,\n column: 1,\n componentName: name,\n rawPath: `${file}:1:1:${name}`,\n };\n }\n vm = vm.$parent ?? null;\n }\n return null;\n}\n\nfunction fileNameOf(path: string): string {\n return path.split('/').pop()?.replace(/\\.\\w+$/, '') ?? 'Unknown';\n}\n\n/**\n * Sync Vue source lookup. Walks up `__vueParentComponent` (Vue 3) or\n * `__vue__` (Vue 2) until it finds a component with a `__file` source\n * attached at compile time. Returns null in production builds and on\n * non-Vue pages.\n *\n * Vue strips line/column from `__file`, so this surfaces `line: 1` —\n * good enough to open the file in the user's editor. The DOM-attribute\n * path (`data-insp-path`) remains the line-accurate option for Vue\n * projects that opt into `@aylith/inspekt-vite`.\n */\nexport function vueSourceFor(element: Element): SourceInfo | null {\n const el = element as VueAugmentedElement;\n return fromVue3(el) ?? fromVue2(el);\n}\n","import type { InspectedElement } from '../types.js';\nimport { vueSourceFor } from './vue-detector.js';\n\n// Single source attribute, aligned with @code-inspector/core's hardcoded\n// constant. Anything emitting the older `data-inspekt-path` (the rename\n// transition) must update — we don't carry a back-compat shim.\nconst SOURCE_ATTRIBUTE = 'data-insp-path';\n\nexport interface SourceInfo {\n filePath: string;\n line: number;\n column: number;\n componentName: string;\n rawPath: string;\n}\n\nexport function parseSourceAttribute(value: string): SourceInfo | null {\n // Format: filePath:line:column:componentName\n const parts = value.split(':');\n if (parts.length < 2) return null;\n\n // Handle Windows paths (C:\\...) — the colon after drive letter\n let filePath: string;\n let rest: string[];\n if (/^[A-Z]$/i.test(parts[0] ?? '') && parts[1]?.startsWith('\\\\')) {\n filePath = `${parts[0]}:${parts[1]}`;\n rest = parts.slice(2);\n } else {\n filePath = parts[0]!;\n rest = parts.slice(1);\n }\n\n const line = parseInt(rest[0] ?? '', 10);\n const column = parseInt(rest[1] ?? '', 10);\n const componentName = rest[2] ?? filePath.split('/').pop()?.replace(/\\.\\w+$/, '') ?? 'Unknown';\n\n if (isNaN(line)) return null;\n\n return {\n filePath,\n line,\n column: isNaN(column) ? 1 : column,\n componentName,\n rawPath: value,\n };\n}\n\nexport function findSourceAttribute(element: HTMLElement): string | null {\n return element.getAttribute(SOURCE_ATTRIBUTE);\n}\n\nexport function findClosestSource(element: HTMLElement): { element: HTMLElement; source: SourceInfo } | null {\n let current: HTMLElement | null = element;\n\n while (current) {\n const attrValue = findSourceAttribute(current);\n if (attrValue) {\n const source = parseSourceAttribute(attrValue);\n if (source) return { element: current, source };\n }\n current = current.parentElement;\n }\n\n // No DOM-attribute hit — try Vue's sync `__vueParentComponent` / `__vue__`\n // (dev-mode only). Cheap to call on every miss, so we don't need to gate it\n // on framework detection.\n const vueSource = vueSourceFor(element);\n if (vueSource) return { element, source: vueSource };\n\n return null;\n}\n\nexport function elementToInspected(\n domElement: HTMLElement,\n source: SourceInfo,\n pathMapping: Record<string, string> = {},\n detectionSource: 'fiber' | 'attribute' = 'attribute',\n): InspectedElement {\n let resolvedPath = source.filePath;\n for (const [containerPath, hostPath] of Object.entries(pathMapping)) {\n if (resolvedPath.startsWith(containerPath)) {\n resolvedPath = resolvedPath.replace(containerPath, hostPath);\n break;\n }\n }\n\n return {\n filePath: resolvedPath,\n line: source.line,\n column: source.column,\n componentName: source.componentName,\n rawPath: source.rawPath,\n domElement,\n tagName: domElement.tagName.toLowerCase(),\n classList: Array.from(domElement.classList),\n id: domElement.id || null,\n boundingRect: domElement.getBoundingClientRect(),\n ancestors: [],\n children: [],\n props: null,\n framework: detectionSource === 'fiber' ? 'react' : 'unknown',\n detectionSource,\n };\n}\n\n/**\n * Resolves source for a DOM element using the strategy chain:\n * 1. React fiber `_debugSource` (zero-config for React/Preact)\n * 2. `data-insp-path` / `data-inspekt-path` DOM attribute\n * 3. null (no source available)\n *\n * Returns the matching element AND the source info. The element may be\n * an ancestor of the input when only ancestors carry the attribute.\n */\nexport async function resolveElementSource(\n element: HTMLElement,\n): Promise<{ element: HTMLElement; source: SourceInfo; from: 'fiber' | 'attribute' } | null> {\n // Tier 1 — fiber. Lazy-import keeps bippy out of bundles that don't need it.\n try {\n const { fiberSourceFor } = await import('./fiber-detector.js');\n const fiberSource = await fiberSourceFor(element);\n if (fiberSource) {\n return { element, source: fiberSource, from: 'fiber' };\n }\n } catch {\n // bippy unavailable or threw — fall through silently\n }\n\n // Tier 2 — DOM attribute on element or ancestor (and, as a tail step,\n // Vue's sync component metadata — see `findClosestSource`).\n const attrHit = findClosestSource(element);\n if (attrHit) {\n return { element: attrHit.element, source: attrHit.source, from: 'attribute' };\n }\n\n return null;\n}\n","import type { HighlightConfig } from '../types.js';\n\nconst HIGHLIGHT_ATTR = 'data-inspekt-highlight';\n\ninterface HighlightState {\n element: HTMLElement;\n originalOutline: string;\n originalOutlineOffset: string;\n originalBoxShadow: string;\n type: 'selected' | 'hovered' | 'border';\n}\n\nexport class Highlighter {\n private highlights = new Map<HTMLElement, HighlightState>();\n private config: HighlightConfig;\n\n constructor(config: HighlightConfig) {\n this.config = config;\n }\n\n highlight(element: HTMLElement, type: 'selected' | 'hovered' | 'border' = 'selected'): void {\n if (this.highlights.has(element)) {\n this.unhighlight(element);\n }\n\n const state: HighlightState = {\n element,\n originalOutline: element.style.outline,\n originalOutlineOffset: element.style.outlineOffset,\n originalBoxShadow: element.style.boxShadow,\n type,\n };\n this.highlights.set(element, state);\n\n element.setAttribute(HIGHLIGHT_ATTR, type);\n\n switch (type) {\n case 'selected':\n element.style.outline = `2px solid ${this.config.color}`;\n element.style.outlineOffset = '2px';\n if (this.config.style === 'glow') {\n element.style.boxShadow = `0 0 8px 2px ${this.config.color}40`;\n }\n break;\n case 'hovered':\n element.style.outline = '2px dashed #a855f7';\n element.style.outlineOffset = '2px';\n break;\n case 'border':\n element.style.outline = `1px solid ${this.config.color}60`;\n element.style.outlineOffset = '0px';\n break;\n }\n }\n\n unhighlight(element: HTMLElement): void {\n const state = this.highlights.get(element);\n if (!state) return;\n\n element.style.outline = state.originalOutline;\n element.style.outlineOffset = state.originalOutlineOffset;\n element.style.boxShadow = state.originalBoxShadow;\n element.removeAttribute(HIGHLIGHT_ATTR);\n\n this.highlights.delete(element);\n }\n\n unhighlightAll(): void {\n for (const [element] of this.highlights) {\n this.unhighlight(element);\n }\n }\n\n updateConfig(config: HighlightConfig): void {\n this.config = config;\n }\n}\n","// Persistent bounding-box overlay across every inspectable element. Used by\n// the `view` activation mode and the standalone `showBoundingBoxes` toggle.\n//\n// Scans the document for `data-insp-path` / fiber-detectable elements, draws\n// a fixed-position labelled box per match, and refreshes on scroll/resize.\n// Boxes are pointer-events: none so they don't intercept the user's clicks.\n\nimport { findClosestSource, type SourceInfo } from '../detection/source-detector.js';\n\ninterface BoxBinding {\n el: HTMLElement;\n box: HTMLElement;\n label: HTMLElement;\n source: SourceInfo;\n}\n\nexport class BoundingBoxOverlay {\n private container: HTMLElement;\n private boxes: BoxBinding[] = [];\n private mounted = false;\n private rafHandle: number | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(private shadowRoot: ShadowRoot) {\n this.container = document.createElement('div');\n this.container.className = 'inspekt-bbox-layer';\n this.shadowRoot.appendChild(this.container);\n }\n\n enable(): void {\n if (this.mounted) return;\n this.mounted = true;\n this.scan();\n\n window.addEventListener('scroll', this.scheduleRepaint, true);\n window.addEventListener('resize', this.scheduleRepaint);\n\n this.resizeObserver = new ResizeObserver(this.scheduleRepaint);\n for (const { el } of this.boxes) this.resizeObserver.observe(el);\n\n this.mutationObserver = new MutationObserver(this.scheduleRescan);\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['data-insp-path'],\n });\n }\n\n disable(): void {\n if (!this.mounted) return;\n this.mounted = false;\n window.removeEventListener('scroll', this.scheduleRepaint, true);\n window.removeEventListener('resize', this.scheduleRepaint);\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.resizeObserver = null;\n this.mutationObserver = null;\n if (this.rafHandle !== null) cancelAnimationFrame(this.rafHandle);\n this.rafHandle = null;\n this.clear();\n }\n\n destroy(): void {\n this.disable();\n this.container.remove();\n }\n\n private clear(): void {\n this.container.innerHTML = '';\n this.boxes = [];\n }\n\n private scan(): void {\n this.clear();\n const seen = new Set<HTMLElement>();\n const nodes = document.querySelectorAll<HTMLElement>('[data-insp-path]');\n for (const node of nodes) {\n const hit = findClosestSource(node);\n if (!hit || seen.has(hit.element)) continue;\n seen.add(hit.element);\n this.boxes.push(this.makeBox(hit.element, hit.source));\n }\n this.repaint();\n }\n\n private makeBox(el: HTMLElement, source: SourceInfo): BoxBinding {\n const box = document.createElement('div');\n box.className = 'inspekt-bbox';\n const label = document.createElement('span');\n label.className = 'inspekt-bbox-label';\n label.textContent = `${source.componentName} · ${fileTail(source.filePath)}:${source.line}`;\n box.appendChild(label);\n this.container.appendChild(box);\n return { el, box, label, source };\n }\n\n private scheduleRepaint = (): void => {\n if (this.rafHandle !== null) return;\n this.rafHandle = requestAnimationFrame(() => {\n this.rafHandle = null;\n this.repaint();\n });\n };\n\n private scheduleRescan = (): void => {\n if (this.rafHandle !== null) cancelAnimationFrame(this.rafHandle);\n this.rafHandle = requestAnimationFrame(() => {\n this.rafHandle = null;\n this.scan();\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n for (const { el } of this.boxes) this.resizeObserver.observe(el);\n }\n });\n };\n\n private repaint(): void {\n for (const binding of this.boxes) {\n const rect = binding.el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) {\n binding.box.style.display = 'none';\n continue;\n }\n binding.box.style.display = '';\n binding.box.style.transform = `translate(${rect.left}px, ${rect.top}px)`;\n binding.box.style.width = `${rect.width}px`;\n binding.box.style.height = `${rect.height}px`;\n }\n }\n}\n\nfunction fileTail(path: string): string {\n return path.split('/').pop() ?? path;\n}\n","// Resolves source snippets for the overlay popover.\n//\n// Phase 1: dev-server fetch only — when @aylith/inspekt-vite is running, hits\n// `/__inspekt/snippet?file=&line=&context=` and renders the response.\n//\n// Phase 5 will extend this with an opt-in source-map fallback for production\n// pages and chrome-extension URLs.\n//\n// All results are cached in memory keyed by `${filePath}:${line}:${context}`.\n// LRU bounded so long-running pages don't grow unbounded.\n\nimport type { SourceSnippet } from '../types.js';\n\nexport interface SnippetResolverOptions {\n filePath: string;\n line: number;\n serverUrl?: string;\n context?: number;\n fetcher?: typeof fetch;\n /** When true, attempts source-map fallback after the dev server fails. */\n sourceMapEnabled?: boolean;\n /**\n * Pre-baked snippet content keyed by `filePath`. Checked first, before\n * the dev server / source map. Lets demo / playground surfaces deliver\n * working snippets without needing a backend.\n */\n staticSnippets?: Record<string, Pick<SourceSnippet, 'language' | 'lines'> & { startLine?: number }>;\n}\n\nconst CACHE_LIMIT = 100;\nconst cache = new Map<string, SourceSnippet | null>();\n\nfunction cacheKey(opts: SnippetResolverOptions): string {\n return `${opts.filePath}:${opts.line}:${opts.context ?? 5}`;\n}\n\nfunction lruTouch(key: string, value: SourceSnippet | null): void {\n cache.delete(key);\n cache.set(key, value);\n if (cache.size > CACHE_LIMIT) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n}\n\nexport function clearSnippetCache(): void {\n cache.clear();\n}\n\nasync function fetchFromDevServer(opts: SnippetResolverOptions): Promise<SourceSnippet | null> {\n if (!opts.serverUrl) return null;\n const fetcher = opts.fetcher ?? fetch;\n const url = new URL('/__inspekt/snippet', opts.serverUrl);\n url.searchParams.set('file', opts.filePath);\n url.searchParams.set('line', String(opts.line));\n url.searchParams.set('context', String(opts.context ?? 5));\n try {\n const res = await fetcher(url.toString(), { method: 'GET' });\n if (!res.ok) return null;\n const data = (await res.json()) as Omit<SourceSnippet, 'source'>;\n return { ...data, source: 'devserver' };\n } catch {\n return null;\n }\n}\n\nexport async function resolveSnippet(\n opts: SnippetResolverOptions,\n): Promise<SourceSnippet | null> {\n const key = cacheKey(opts);\n if (cache.has(key)) {\n return cache.get(key) ?? null;\n }\n\n const stat = opts.staticSnippets?.[opts.filePath];\n if (stat) {\n const startLine = stat.startLine ?? 1;\n const snippet: SourceSnippet = {\n startLine,\n endLine: startLine + stat.lines.length - 1,\n targetLine: opts.line,\n lines: stat.lines,\n language: stat.language,\n source: 'devserver',\n };\n lruTouch(key, snippet);\n return snippet;\n }\n\n const fromServer = await fetchFromDevServer(opts);\n if (fromServer) {\n lruTouch(key, fromServer);\n return fromServer;\n }\n\n // Source-map fallback (opt-in; default off). Lazy-imported so projects that\n // don't enable it never pay the @jridgewell/trace-mapping bundle cost.\n if (opts.sourceMapEnabled) {\n try {\n const mod = await import('./sourcemap-resolver.js');\n const fromMap = await mod.resolveFromSourceMap({\n filePath: opts.filePath,\n line: opts.line,\n context: opts.context,\n fetcher: opts.fetcher,\n });\n if (fromMap) {\n lruTouch(key, fromMap);\n return fromMap;\n }\n } catch {\n // sourcemap-resolver failed (network, parse error). Fall through.\n }\n }\n\n // Negative-cache the miss so we don't re-fetch on every popover open.\n lruTouch(key, null);\n return null;\n}\n","/**\n * Prism.js tokenizer wrapper.\n *\n * Returns a per-line token array so callers can keep their own\n * line-number gutter / target-line marker (we don't want a single\n * Prism.highlight() HTML blob that we'd have to re-split).\n *\n * Languages bundled: markup, clike, javascript, jsx, typescript, tsx,\n * css, json. Anything else falls through to a single \"plain\" token per\n * line.\n */\nimport Prism from 'prismjs';\n// Loading order matters: each component augments Prism.languages with its key.\n// `markup` is the base for jsx/tsx. `clike` is the base for js/ts.\nimport 'prismjs/components/prism-markup.js';\nimport 'prismjs/components/prism-clike.js';\nimport 'prismjs/components/prism-javascript.js';\nimport 'prismjs/components/prism-jsx.js';\nimport 'prismjs/components/prism-typescript.js';\nimport 'prismjs/components/prism-tsx.js';\nimport 'prismjs/components/prism-css.js';\nimport 'prismjs/components/prism-json.js';\n\nexport interface CodeToken {\n text: string;\n /** Prism token type, e.g. \"keyword\", \"string\", \"comment\". Empty for plain text. */\n type: string;\n}\n\nexport interface CodeLine {\n tokens: CodeToken[];\n}\n\n/** Map common file extensions / language hints to Prism grammar keys. */\nfunction resolveGrammarKey(lang: string | undefined): string {\n switch ((lang || '').toLowerCase()) {\n case 'js':\n case 'jsx':\n case 'mjs':\n case 'cjs':\n return 'jsx';\n case 'ts':\n case 'tsx':\n return 'tsx';\n case 'javascript':\n return 'javascript';\n case 'typescript':\n return 'typescript';\n case 'json':\n return 'json';\n case 'css':\n case 'scss':\n case 'less':\n return 'css';\n case 'html':\n case 'htm':\n case 'xml':\n case 'svg':\n case 'markup':\n return 'markup';\n default:\n return 'plain';\n }\n}\n\n/**\n * Tokenize source code and split into per-line token arrays. Newlines are\n * consumed by the splitter (not emitted as tokens), so the caller can join\n * the resulting lines with its own `\\n` if rendering to a single `<pre>`.\n */\nexport function tokenizeToLines(code: string, lang?: string): CodeLine[] {\n const key = resolveGrammarKey(lang);\n const grammar = key === 'plain' ? undefined : Prism.languages[key];\n if (!grammar) {\n return code.split('\\n').map((text) => ({ tokens: [{ text, type: '' }] }));\n }\n\n const tokens = Prism.tokenize(code, grammar);\n return splitTokensIntoLines(tokens);\n}\n\ntype PrismNode = string | Prism.Token | Array<string | Prism.Token>;\n\nfunction splitTokensIntoLines(nodes: PrismNode[]): CodeLine[] {\n const lines: CodeLine[] = [{ tokens: [] }];\n const current = (): CodeToken[] => lines[lines.length - 1]!.tokens;\n\n function visit(node: PrismNode, parentType: string): void {\n if (typeof node === 'string') {\n pushText(node, parentType);\n return;\n }\n if (Array.isArray(node)) {\n for (const n of node) visit(n, parentType);\n return;\n }\n // Prism.Token — its content may be a string OR nested token array.\n const type = parentType ? `${parentType} ${node.type}` : node.type;\n visit(node.content as PrismNode, type);\n }\n\n function pushText(text: string, type: string): void {\n let buf = text;\n while (buf.length > 0) {\n const nl = buf.indexOf('\\n');\n if (nl === -1) {\n if (buf.length > 0) current().push({ text: buf, type });\n return;\n }\n const before = buf.slice(0, nl);\n if (before.length > 0) current().push({ text: before, type });\n lines.push({ tokens: [] });\n buf = buf.slice(nl + 1);\n }\n }\n\n for (const n of nodes) visit(n, '');\n return lines;\n}\n","/**\n * Tooltip — drop-in replacement for the OS `title=\"\"` attribute.\n *\n * Two modes:\n * - **Plain**: `content` is a string → renders a small pill.\n * - **Rich**: `content` is an HTMLElement → the tooltip stays open while the\n * cursor is over the bubble itself (so anchors inside are clickable).\n *\n * Portal-aware: the bubble is appended into the provided `root` (a shadow\n * root for in-page popover usage, or `document.body` for the extension's\n * options/popup/welcome pages).\n *\n * Positioning is delegated to `@floating-ui/dom` — `computePosition` + `flip` +\n * `shift` middleware keep the bubble inside the viewport; `autoUpdate` keeps\n * it locked to the trigger as the page scrolls or resizes.\n */\nimport {\n autoUpdate,\n computePosition,\n flip,\n offset,\n shift,\n type Placement,\n} from '@floating-ui/dom';\n\nexport interface TooltipOptions {\n /** Render target. Defaults to `document.body`. */\n root?: HTMLElement | ShadowRoot;\n /** ms before showing on enter. Default 200. */\n enterDelay?: number;\n /** ms before hiding on leave. Default 80. */\n leaveDelay?: number;\n /**\n * Floating-UI placement. Defaults to `'top'`. Auto-flips via the `flip`\n * middleware when there's no room.\n */\n placement?: Placement;\n /** Px gap between the trigger and the bubble. Default 8. */\n offsetPx?: number;\n}\n\nlet counter = 0;\n\nexport function attachTooltip(\n trigger: HTMLElement,\n content: string | HTMLElement,\n opts: TooltipOptions = {},\n): () => void {\n const enterDelay = opts.enterDelay ?? 200;\n const leaveDelay = opts.leaveDelay ?? 80;\n const placement = opts.placement ?? 'top';\n const offsetPx = opts.offsetPx ?? 8;\n const root = opts.root ?? document.body;\n const isRich = typeof content !== 'string';\n\n let bubble: HTMLDivElement | null = null;\n let enterTimer: ReturnType<typeof setTimeout> | null = null;\n let leaveTimer: ReturnType<typeof setTimeout> | null = null;\n let cleanupAutoUpdate: (() => void) | null = null;\n const id = `inspekt-tooltip-${++counter}`;\n\n function show(): void {\n if (bubble) return;\n bubble = document.createElement('div');\n bubble.className = 'inspekt-tooltip';\n bubble.id = id;\n bubble.setAttribute('role', 'tooltip');\n bubble.style.position = 'fixed';\n bubble.style.top = '0';\n bubble.style.left = '0';\n bubble.style.zIndex = '2147483647';\n if (typeof content === 'string') {\n bubble.textContent = content;\n } else {\n bubble.classList.add('inspekt-tooltip--rich');\n bubble.appendChild(content);\n }\n root.appendChild(bubble);\n\n // autoUpdate immediately fires `update`, so position is set right away.\n cleanupAutoUpdate = autoUpdate(trigger, bubble, update);\n\n if (isRich) {\n bubble.addEventListener('mouseenter', cancelLeave);\n bubble.addEventListener('mouseleave', scheduleHide);\n }\n }\n\n function hide(): void {\n if (!bubble) return;\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n bubble.remove();\n bubble = null;\n }\n\n function update(): void {\n if (!bubble) return;\n void computePosition(trigger, bubble, {\n placement,\n strategy: 'fixed',\n middleware: [offset(offsetPx), flip(), shift({ padding: 6 })],\n }).then(({ x, y }) => {\n // Bubble may have been removed during the microtask hop. Belt + braces\n // so a late computePosition() resolution can't paint at the fallback\n // (0,0) coordinate after detach.\n if (!bubble || !bubble.isConnected) return;\n bubble.style.left = `${Math.round(x)}px`;\n bubble.style.top = `${Math.round(y)}px`;\n });\n }\n\n function scheduleShow(): void {\n cancelLeave();\n if (enterTimer) clearTimeout(enterTimer);\n enterTimer = setTimeout(() => {\n enterTimer = null;\n show();\n }, enterDelay);\n }\n\n function scheduleHide(): void {\n if (enterTimer) {\n clearTimeout(enterTimer);\n enterTimer = null;\n }\n if (leaveTimer) clearTimeout(leaveTimer);\n leaveTimer = setTimeout(() => {\n leaveTimer = null;\n hide();\n }, leaveDelay);\n }\n\n function cancelLeave(): void {\n if (leaveTimer) {\n clearTimeout(leaveTimer);\n leaveTimer = null;\n }\n }\n\n function onKey(e: KeyboardEvent): void {\n if (e.key === 'Escape') hide();\n }\n\n trigger.setAttribute('aria-describedby', id);\n trigger.addEventListener('mouseenter', scheduleShow);\n trigger.addEventListener('mouseleave', scheduleHide);\n trigger.addEventListener('focus', scheduleShow);\n trigger.addEventListener('blur', scheduleHide);\n trigger.addEventListener('keydown', onKey);\n\n return function detach(): void {\n if (enterTimer) clearTimeout(enterTimer);\n if (leaveTimer) clearTimeout(leaveTimer);\n trigger.removeEventListener('mouseenter', scheduleShow);\n trigger.removeEventListener('mouseleave', scheduleHide);\n trigger.removeEventListener('focus', scheduleShow);\n trigger.removeEventListener('blur', scheduleHide);\n trigger.removeEventListener('keydown', onKey);\n trigger.removeAttribute('aria-describedby');\n hide();\n };\n}\n","import type { InspektAction, InspectedElement, SourceSnippet } from '../types.js';\nimport { resolveSnippet } from '../snippet/snippet-resolver.js';\nimport { tokenizeToLines } from '../highlight/prism.js';\nimport { attachTooltip } from '../components/tooltip.js';\n\n// Inline SVGs reused by the DOM-fallback popover so it shows the same\n// icon-button toolbar as the instrumented popover (not bare text labels).\nconst ICON_COPY = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\"/><path d=\"M5 15V5a2 2 0 0 1 2-2h10\"/></svg>`;\n// Angle brackets — universal \"code/markup\" glyph. Visually nothing like the\n// clipboard outline above, so the two copy buttons can sit next to each other.\nconst ICON_HTML = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>`;\nconst ICON_CONSOLE = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"4 17 10 11 4 5\"/><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\"/></svg>`;\nconst ICON_INFO = `<svg viewBox=\"0 0 24 24\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9.5\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16.5\"/><circle cx=\"12\" cy=\"7.8\" r=\"0.6\" fill=\"currentColor\" stroke=\"none\"/></svg>`;\n\nexport interface PopoverSnippetConfig {\n /** Where the dev-server lives (set by @aylith/inspekt-vite at init time). */\n serverUrl?: string;\n /** Lines of context above and below the target line. */\n context: number;\n /** When true, the snippet section is expanded immediately on show(). */\n defaultExpanded: boolean;\n /** When true, attempts source-map fallback if the dev server can't help. */\n sourceMapEnabled: boolean;\n /** Pre-baked snippets indexed by filePath (demos/playgrounds). */\n staticSnippets?: Record<\n string,\n { language: string; lines: string[]; startLine?: number }\n >;\n}\n\nconst DEFAULT_SNIPPET_CONFIG: PopoverSnippetConfig = {\n context: 5,\n defaultExpanded: false,\n sourceMapEnabled: false,\n};\n\nexport class Popover {\n private container: HTMLElement;\n private visible = false;\n private pinned = false;\n private snippetConfig: PopoverSnippetConfig = { ...DEFAULT_SNIPPET_CONFIG };\n\n constructor(private shadowRoot: ShadowRoot) {\n this.container = document.createElement('div');\n this.container.className = 'inspekt-popover';\n this.container.style.display = 'none';\n this.shadowRoot.appendChild(this.container);\n }\n\n /** Lock the popover in place — hover/move handlers will not reposition or\n * hide it until {@link unpin} is called. Clicks set this; Escape clears it. */\n pin(): void {\n this.pinned = true;\n }\n\n unpin(): void {\n this.pinned = false;\n }\n\n isPinned(): boolean {\n return this.pinned;\n }\n\n configureSnippet(config: Partial<PopoverSnippetConfig>): void {\n this.snippetConfig = { ...this.snippetConfig, ...config };\n }\n\n /**\n * Fallback popover for Standalone-on-an-unbuilt-page: no source attrs,\n * no React fibers — so we show DOM info (selector, classes, id) plus a\n * minimal action set. Keeps Inspekt useful as a pure inspection tool.\n */\n showDom(\n domElement: HTMLElement,\n position: { x: number; y: number },\n onCopySelector: (selector: string) => Promise<boolean> | boolean,\n onCopyHtml: (html: string) => Promise<boolean> | boolean,\n onConsoleLog: () => void,\n ): void {\n this.container.innerHTML = '';\n\n const selector = computeSelector(domElement);\n\n const header = document.createElement('div');\n header.className = 'inspekt-popover-header';\n\n // Eyebrow row: \"DOM element\" + (i) info badge with tooltip explaining\n // why no source data is shown (replaces the old inline paragraph).\n const eyebrow = document.createElement('div');\n eyebrow.className = 'inspekt-popover-path-dir inspekt-popover-path-dir-row';\n const eyebrowText = document.createElement('span');\n eyebrowText.textContent = 'DOM element';\n eyebrow.appendChild(eyebrowText);\n\n const infoBadge = document.createElement('span');\n infoBadge.className = 'inspekt-info-badge';\n infoBadge.setAttribute('tabindex', '0');\n infoBadge.setAttribute('aria-label', 'Why no source data?');\n infoBadge.innerHTML = `${ICON_INFO}<span class=\"inspekt-info-badge-label\">No source</span>`;\n attachTooltip(\n infoBadge,\n 'No Inspekt source data on this page. Build with the Inspekt plugin (Vite, Webpack, Rspack, esbuild) to get editor-jump and file paths.',\n { root: this.shadowRoot as unknown as HTMLElement, enterDelay: 100 },\n );\n eyebrow.appendChild(infoBadge);\n\n const sel = document.createElement('div');\n sel.className = 'inspekt-popover-path-file';\n sel.textContent = selector;\n\n header.appendChild(eyebrow);\n header.appendChild(sel);\n this.container.appendChild(header);\n\n const actionsBar = document.createElement('div');\n actionsBar.className = 'inspekt-popover-actions';\n\n const copyBtn = document.createElement('button');\n copyBtn.className = 'inspekt-popover-action';\n copyBtn.setAttribute('aria-label', 'Copy CSS selector');\n copyBtn.innerHTML = ICON_COPY;\n attachTooltip(copyBtn, 'Copy CSS selector', {\n root: this.shadowRoot as unknown as HTMLElement,\n });\n copyBtn.addEventListener('click', async (e) => {\n e.preventDefault();\n e.stopPropagation();\n const ok = await onCopySelector(selector);\n this.showToast(ok ? 'Copied' : 'Copy failed');\n // Keep the popover up briefly so the toast is visible.\n setTimeout(() => this.hide(), 700);\n });\n actionsBar.appendChild(copyBtn);\n\n // Copy HTML — distinguishable from Copy selector by the angle-brackets icon.\n const htmlBtn = document.createElement('button');\n htmlBtn.className = 'inspekt-popover-action';\n htmlBtn.setAttribute('aria-label', 'Copy HTML');\n htmlBtn.innerHTML = ICON_HTML;\n attachTooltip(htmlBtn, 'Copy HTML (outerHTML)', {\n root: this.shadowRoot as unknown as HTMLElement,\n });\n htmlBtn.addEventListener('click', async (e) => {\n e.preventDefault();\n e.stopPropagation();\n // Capture outerHTML at click time so it reflects the live DOM.\n const ok = await onCopyHtml(domElement.outerHTML);\n this.showToast(ok ? 'HTML copied' : 'Copy failed');\n setTimeout(() => this.hide(), 700);\n });\n actionsBar.appendChild(htmlBtn);\n\n const logBtn = document.createElement('button');\n logBtn.className = 'inspekt-popover-action';\n logBtn.setAttribute('aria-label', 'console.log this element');\n logBtn.innerHTML = ICON_CONSOLE;\n attachTooltip(logBtn, 'console.log this element', {\n root: this.shadowRoot as unknown as HTMLElement,\n });\n logBtn.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n onConsoleLog();\n this.showToast('Logged to console');\n setTimeout(() => this.hide(), 700);\n });\n actionsBar.appendChild(logBtn);\n\n this.container.appendChild(actionsBar);\n\n this.positionAt(position.x, position.y);\n this.container.style.display = 'block';\n this.visible = true;\n }\n\n /** Brief feedback toast attached to the shadow root. */\n private showToast(message: string): void {\n const existing = this.shadowRoot.querySelector('.inspekt-popover-toast');\n if (existing) existing.remove();\n const toast = document.createElement('div');\n toast.className = 'inspekt-popover-toast';\n toast.textContent = message;\n this.shadowRoot.appendChild(toast);\n setTimeout(() => toast.remove(), 1200);\n }\n\n show(element: InspectedElement, actions: InspektAction[], position: { x: number; y: number }): void {\n this.container.innerHTML = '';\n\n // Header: file path + line\n const header = document.createElement('div');\n header.className = 'inspekt-popover-header';\n\n const pathDir = document.createElement('div');\n pathDir.className = 'inspekt-popover-path-dir';\n const parts = element.filePath.split('/');\n pathDir.textContent = parts.slice(0, -1).join('/') + '/';\n\n const pathFile = document.createElement('div');\n pathFile.className = 'inspekt-popover-path-file';\n pathFile.textContent = `${parts[parts.length - 1]}:${element.line}`;\n\n header.appendChild(pathDir);\n header.appendChild(pathFile);\n this.container.appendChild(header);\n\n // Snippet section (between header and actions for visual hierarchy).\n const snippetSection = this.buildSnippetSection(element);\n this.container.appendChild(snippetSection);\n\n // Actions bar\n const actionsBar = document.createElement('div');\n actionsBar.className = 'inspekt-popover-actions';\n\n for (const action of actions) {\n const btn = document.createElement('button');\n btn.className = 'inspekt-popover-action';\n btn.setAttribute('aria-label', action.label);\n btn.innerHTML = action.icon;\n attachTooltip(btn, action.label, {\n root: this.shadowRoot as unknown as HTMLElement,\n });\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n action.handler(element);\n this.hide();\n });\n actionsBar.appendChild(btn);\n }\n\n this.container.appendChild(actionsBar);\n\n // Position the popover\n this.positionAt(position.x, position.y);\n this.container.style.display = 'block';\n this.visible = true;\n }\n\n private buildSnippetSection(element: InspectedElement): HTMLElement {\n const section = document.createElement('div');\n section.className = 'inspekt-snippet';\n // Stay hidden until we know a snippet actually resolves. Avoids the\n // \"Show source\" toggle that then reveals a useless error message.\n section.hidden = true;\n const initialState = this.snippetConfig.defaultExpanded ? 'expanded' : 'collapsed';\n section.dataset['state'] = initialState;\n\n const toggle = document.createElement('button');\n toggle.type = 'button';\n toggle.className = 'inspekt-snippet-toggle';\n toggle.textContent =\n initialState === 'collapsed' ? 'Show source ▾' : 'Hide source ▴';\n\n const body = document.createElement('div');\n body.className = 'inspekt-snippet-body';\n if (initialState === 'collapsed') body.hidden = true;\n\n section.appendChild(toggle);\n section.appendChild(body);\n\n void this.resolveAndMountSnippet(section, toggle, body, element, initialState);\n\n return section;\n }\n\n private async resolveAndMountSnippet(\n section: HTMLElement,\n toggle: HTMLButtonElement,\n body: HTMLElement,\n element: InspectedElement,\n initialState: 'expanded' | 'collapsed',\n ): Promise<void> {\n const snippet = await resolveSnippet({\n filePath: element.filePath,\n line: element.line,\n serverUrl: this.snippetConfig.serverUrl,\n context: this.snippetConfig.context,\n sourceMapEnabled: this.snippetConfig.sourceMapEnabled,\n staticSnippets: this.snippetConfig.staticSnippets,\n });\n if (!snippet) {\n // No dev server, no source map — drop the section entirely so the\n // popover doesn't surface a dead \"Show source\" affordance.\n section.remove();\n return;\n }\n element.snippet = snippet;\n section.hidden = false;\n\n let rendered = false;\n const expand = (): void => {\n section.dataset['state'] = 'expanded';\n // Mirror data-state on the body so the 1.5×-width CSS rule has a target.\n body.dataset['state'] = 'expanded';\n body.hidden = false;\n toggle.textContent = 'Hide source ▴';\n if (!rendered) {\n rendered = true;\n body.innerHTML = '';\n body.appendChild(this.renderSnippet(snippet));\n }\n // Center the target line in the snippet body after layout settles.\n requestAnimationFrame(() => {\n const target = body.querySelector<HTMLElement>('.inspekt-line-target');\n target?.scrollIntoView({ block: 'center', inline: 'nearest' });\n });\n };\n const collapse = (): void => {\n section.dataset['state'] = 'collapsed';\n body.dataset['state'] = 'collapsed';\n body.hidden = true;\n toggle.textContent = 'Show source ▾';\n };\n\n toggle.addEventListener('click', (e) => {\n e.stopPropagation();\n if (section.dataset['state'] === 'collapsed') expand();\n else collapse();\n });\n\n if (initialState === 'expanded') expand();\n }\n\n private renderSnippet(snippet: SourceSnippet): HTMLElement {\n const pre = document.createElement('pre');\n pre.className = 'inspekt-snippet-pre';\n pre.dataset['language'] = snippet.language;\n\n // Tokenize the whole snippet, then walk per source line so we keep the\n // line-number gutter and target-line marker. (Prism would otherwise hand\n // back a single HTML blob.)\n const highlighted = tokenizeToLines(snippet.lines.join('\\n'), snippet.language);\n\n snippet.lines.forEach((rawText, index) => {\n const lineNumber = snippet.startLine + index;\n const isTarget = lineNumber === snippet.targetLine;\n\n const lineEl = document.createElement('span');\n lineEl.className = isTarget ? 'inspekt-line inspekt-line-target' : 'inspekt-line';\n\n const num = document.createElement('span');\n num.className = 'inspekt-line-no';\n num.textContent = String(lineNumber);\n lineEl.appendChild(num);\n\n const code = document.createElement('span');\n code.className = 'inspekt-line-code';\n const tokens = highlighted[index]?.tokens;\n if (!tokens || tokens.length === 0) {\n // Empty line or tokenization fallback.\n code.textContent = rawText;\n } else {\n for (const tok of tokens) {\n if (!tok.type) {\n code.appendChild(document.createTextNode(tok.text));\n } else {\n const span = document.createElement('span');\n // Prism class convention: \"token <type> <subtype …>\"\n span.className = `token ${tok.type}`;\n span.textContent = tok.text;\n code.appendChild(span);\n }\n }\n }\n lineEl.appendChild(code);\n\n pre.appendChild(lineEl);\n pre.appendChild(document.createTextNode('\\n'));\n });\n\n return pre;\n }\n\n hide(): void {\n this.container.style.display = 'none';\n this.visible = false;\n this.pinned = false;\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n private positionAt(x: number, y: number): void {\n const padding = 8;\n const vpWidth = window.innerWidth;\n const vpHeight = window.innerHeight;\n\n // Temporarily show to measure\n this.container.style.display = 'block';\n this.container.style.left = '0px';\n this.container.style.top = '0px';\n const rect = this.container.getBoundingClientRect();\n\n let left = x;\n let top = y + 10; // Below cursor\n\n // Flip horizontal if overflowing right\n if (left + rect.width + padding > vpWidth) {\n left = vpWidth - rect.width - padding;\n }\n if (left < padding) left = padding;\n\n // Flip vertical if overflowing bottom\n if (top + rect.height + padding > vpHeight) {\n top = y - rect.height - 10; // Above cursor\n }\n if (top < padding) top = padding;\n\n this.container.style.left = `${left}px`;\n this.container.style.top = `${top}px`;\n }\n\n destroy(): void {\n this.container.remove();\n }\n}\n\n// Short, human-readable selector for the DOM-only popover. Prefers id, then\n// tag + first 2 classes — not a uniqueness-guaranteed locator.\nfunction computeSelector(el: HTMLElement): string {\n const tag = el.tagName.toLowerCase();\n if (el.id) return `${tag}#${el.id}`;\n const classes = Array.from(el.classList).slice(0, 2);\n if (classes.length) return `${tag}.${classes.join('.')}`;\n return tag;\n}\n","import { findSourceAttribute, parseSourceAttribute } from '../detection/source-detector.js';\n\nexport interface Badge {\n element: HTMLElement;\n componentName: string;\n badgeElement: HTMLElement;\n visible: boolean;\n}\n\nconst MAX_VISIBLE_BADGES = 200;\n\nexport class Overlay {\n private badges: Badge[] = [];\n private mutationObserver: MutationObserver | null = null;\n private intersectionObserver: IntersectionObserver | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private container: HTMLElement;\n private visible = false;\n\n constructor(private shadowRoot: ShadowRoot) {\n this.container = document.createElement('div');\n this.container.className = 'inspekt-overlay';\n this.container.style.display = 'none';\n this.shadowRoot.appendChild(this.container);\n }\n\n show(): void {\n this.visible = true;\n this.container.style.display = 'block';\n this.scan();\n this.startObserving();\n }\n\n hide(): void {\n this.visible = false;\n this.container.style.display = 'none';\n this.clear();\n this.stopObserving();\n }\n\n toggle(): void {\n if (this.visible) this.hide();\n else this.show();\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n private scan(): void {\n this.clear();\n\n const elements = document.querySelectorAll<HTMLElement>(\n '[data-insp-path], [data-insp-path]',\n );\n\n // Track which elements are children of other detected elements\n // to show only outermost components\n const detected = new Set(elements);\n const outermost: HTMLElement[] = [];\n\n for (const el of elements) {\n let parent = el.parentElement;\n let isNested = false;\n while (parent) {\n if (detected.has(parent)) {\n isNested = true;\n break;\n }\n parent = parent.parentElement;\n }\n if (!isNested) outermost.push(el);\n }\n\n // Limit badge count for performance on large pages\n const toRender = outermost.slice(0, MAX_VISIBLE_BADGES);\n\n // Set up IntersectionObserver for visibility-based rendering\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const badge = this.badges.find((b) => b.element === entry.target);\n if (!badge) continue;\n\n if (entry.isIntersecting) {\n badge.visible = true;\n badge.badgeElement.style.display = 'block';\n this.positionBadge(badge.badgeElement, badge.element);\n } else {\n badge.visible = false;\n badge.badgeElement.style.display = 'none';\n }\n }\n },\n { rootMargin: '50px' },\n );\n\n for (const el of toRender) {\n const attrValue = findSourceAttribute(el);\n if (!attrValue) continue;\n\n const source = parseSourceAttribute(attrValue);\n if (!source) continue;\n\n this.createBadge(el, source.componentName);\n }\n }\n\n private createBadge(element: HTMLElement, componentName: string): void {\n const badge = document.createElement('div');\n badge.className = 'inspekt-badge';\n badge.textContent = componentName;\n badge.addEventListener('click', (e) => {\n e.stopPropagation();\n element.dispatchEvent(\n new CustomEvent('inspekt:badge-click', {\n bubbles: true,\n detail: { element },\n }),\n );\n });\n badge.addEventListener('mouseenter', () => {\n element.dispatchEvent(\n new CustomEvent('inspekt:badge-hover', {\n bubbles: true,\n detail: { element },\n }),\n );\n });\n badge.addEventListener('mouseleave', () => {\n element.dispatchEvent(\n new CustomEvent('inspekt:badge-leave', {\n bubbles: true,\n detail: { element },\n }),\n );\n });\n\n this.container.appendChild(badge);\n this.positionBadge(badge, element);\n\n const badgeEntry: Badge = { element, componentName, badgeElement: badge, visible: true };\n this.badges.push(badgeEntry);\n\n // Track visibility\n this.intersectionObserver?.observe(element);\n }\n\n private positionBadge(badge: HTMLElement, target: HTMLElement): void {\n const rect = target.getBoundingClientRect();\n const badgeHeight = 18;\n const badgeWidth = badge.offsetWidth || 60;\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n\n let left = rect.left + scrollX;\n let top = rect.top + scrollY - badgeHeight - 2;\n\n // Clamp to viewport — keep badge visible\n const vpWidth = window.innerWidth;\n\n // Prevent badge from going off-screen right\n if (left + badgeWidth > vpWidth + scrollX) {\n left = vpWidth + scrollX - badgeWidth - 4;\n }\n // Prevent going off-screen left\n if (left < scrollX + 4) {\n left = scrollX + 4;\n }\n\n // If badge would be above viewport, place below the element\n if (top < scrollY) {\n top = rect.bottom + scrollY + 2;\n }\n\n badge.style.left = `${left}px`;\n badge.style.top = `${top}px`;\n }\n\n updatePositions(): void {\n for (const { badgeElement, element, visible } of this.badges) {\n if (visible) {\n this.positionBadge(badgeElement, element);\n }\n }\n }\n\n private startObserving(): void {\n this.mutationObserver = new MutationObserver(() => {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => this.scan(), 100);\n });\n\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n window.addEventListener('scroll', this.handleScrollResize, true);\n window.addEventListener('resize', this.handleScrollResize);\n }\n\n private stopObserving(): void {\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n this.intersectionObserver?.disconnect();\n this.intersectionObserver = null;\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n window.removeEventListener('scroll', this.handleScrollResize, true);\n window.removeEventListener('resize', this.handleScrollResize);\n }\n\n private handleScrollResize = (): void => {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => this.updatePositions(), 16);\n };\n\n private clear(): void {\n this.intersectionObserver?.disconnect();\n for (const { badgeElement } of this.badges) {\n badgeElement.remove();\n }\n this.badges = [];\n }\n\n destroy(): void {\n this.hide();\n this.container.remove();\n }\n}\n","import type { InspektAction, InspectedElement, InspektCustomEditor } from '../types.js';\n\nconst EDITOR_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z\"/><path d=\"m15 5 4 4\"/></svg>`;\nconst COPY_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg>`;\nconst GITHUB_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0 1 12 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z\"/></svg>`;\nconst CONSOLE_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"4 17 10 11 4 5\"/><line x1=\"12\" x2=\"20\" y1=\"19\" y2=\"19\"/></svg>`;\nconst AGENT_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m22 2-7 20-4-9-9-4Z\"/><path d=\"M22 2 11 13\"/></svg>`;\n\nexport interface SendToAgentOptions {\n /** Daemon base URL — typically http://127.0.0.1:5678. */\n daemonUrl: string;\n /** Token required in X-Inspekt-Token. Set by `npx inspekt setup`. */\n token: string;\n /** Callback fired after a successful POST — used for UX (toast, etc.). */\n onSent?: (grabId: string) => void;\n /** Callback for errors. */\n onError?: (err: Error) => void;\n}\n\nexport function createSendToAgentAction(opts: SendToAgentOptions): InspektAction {\n return {\n id: 'send-to-agent',\n label: 'Send to Agent',\n icon: AGENT_ICON,\n async handler(element: InspectedElement) {\n try {\n const url = `${opts.daemonUrl.replace(/\\/$/, '')}/__inspekt/grab`;\n const body = JSON.stringify({\n url: window.location.href,\n element: {\n filePath: element.filePath,\n line: element.line,\n column: element.column,\n componentName: element.componentName,\n tagName: element.tagName,\n classList: element.classList,\n id: element.id,\n ...(element.snippet ? { snippet: element.snippet } : {}),\n },\n source: 'extension',\n });\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Inspekt-Token': opts.token,\n },\n body,\n });\n if (!res.ok) throw new Error(`Daemon returned ${res.status}`);\n const grab = (await res.json()) as { id: string };\n opts.onSent?.(grab.id);\n } catch (err) {\n opts.onError?.(err as Error);\n }\n },\n };\n}\n\nexport function createOpenEditorAction(\n serverUrl: string,\n editor: string,\n customEditors: InspektCustomEditor[] = [],\n): InspektAction {\n return {\n id: 'open-editor',\n label: 'Open in Editor',\n icon: EDITOR_ICON,\n handler(element: InspectedElement) {\n const url = `${serverUrl}/__inspekt/open`;\n const body = JSON.stringify({\n file: element.filePath,\n line: element.line,\n column: element.column,\n editor,\n });\n\n fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n }).catch(() => {\n // Fallback to protocol handler\n const protocol = editorProtocol(editor, element, customEditors);\n if (protocol) window.open(protocol, '_blank');\n });\n },\n };\n}\n\nexport function createCopyPathAction(): InspektAction {\n return {\n id: 'copy-path',\n label: 'Copy Path',\n icon: COPY_ICON,\n handler(element: InspectedElement) {\n const text = `${element.filePath}:${element.line}`;\n navigator.clipboard.writeText(text).catch(() => {\n // Fallback for non-secure contexts\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n });\n },\n };\n}\n\nexport function createOpenGithubAction(repo: string, branch: string): InspektAction {\n return {\n id: 'open-github',\n label: 'Open on GitHub',\n icon: GITHUB_ICON,\n handler(element: InspectedElement) {\n if (!repo) return;\n const url = `https://github.com/${repo}/blob/${branch}/${element.filePath}#L${element.line}`;\n window.open(url, '_blank');\n },\n };\n}\n\nexport function createConsoleLogAction(): InspektAction {\n return {\n id: 'console-log',\n label: 'Log to Console',\n icon: CONSOLE_ICON,\n handler(element: InspectedElement) {\n console.group(`[Inspekt] ${element.componentName}`);\n console.log('File:', `${element.filePath}:${element.line}:${element.column}`);\n console.log('Element:', element.domElement);\n console.log('Tag:', element.tagName);\n if (element.props) console.log('Props:', element.props);\n console.groupEnd();\n },\n };\n}\n\nfunction editorProtocol(\n editor: string,\n element: InspectedElement,\n customEditors: InspektCustomEditor[] = [],\n): string | null {\n const { filePath, line, column } = element;\n\n // User-defined editors win over built-in defaults — lets a user patch\n // a broken built-in scheme (or add a brand-new editor) without an\n // Inspekt release.\n for (const ce of customEditors) {\n if (ce.value === editor) {\n return ce.urlTemplate\n .replace(/\\{file\\}/g, encodeURIComponent(filePath))\n .replace(/\\{line\\}/g, String(line))\n .replace(/\\{column\\}/g, String(column));\n }\n }\n\n switch (editor) {\n case 'vscode':\n return `vscode://file/${filePath}:${line}:${column}`;\n case 'vscode-insiders':\n return `vscode-insiders://file/${filePath}:${line}:${column}`;\n case 'cursor':\n return `cursor://file/${filePath}:${line}:${column}`;\n case 'windsurf':\n return `windsurf://file/${filePath}:${line}:${column}`;\n case 'webstorm':\n return `webstorm://open?file=${filePath}&line=${line}&column=${column}`;\n case 'phpstorm':\n return `phpstorm://open?file=${filePath}&line=${line}&column=${column}`;\n case 'idea':\n return `idea://open?file=${filePath}&line=${line}&column=${column}`;\n case 'zed':\n return `zed://file/${filePath}:${line}:${column}`;\n case 'sublime':\n return `subl://open?url=file://${filePath}&line=${line}&column=${column}`;\n\n // JetBrains family — query-string shape, same as webstorm/phpstorm/idea.\n case 'pycharm':\n return `pycharm://open?file=${filePath}&line=${line}&column=${column}`;\n case 'rubymine':\n return `rubymine://open?file=${filePath}&line=${line}&column=${column}`;\n case 'goland':\n return `goland://open?file=${filePath}&line=${line}&column=${column}`;\n case 'clion':\n return `clion://open?file=${filePath}&line=${line}&column=${column}`;\n case 'rider':\n return `rider://open?file=${filePath}&line=${line}&column=${column}`;\n\n // VS Code family\n case 'vscodium':\n return `vscodium://file/${filePath}:${line}:${column}`;\n\n // AI editors — VS Code fork URL shape. Trae/Antigravity/Qoder/CodeBuddy\n // are inferred (vendor docs don't enumerate the file-open scheme); we\n // surface this in the UI as \"(unverified)\" so users can test before\n // committing.\n case 'trae':\n return `trae://file/${filePath}:${line}:${column}`;\n case 'kiro':\n return `kiro://file/${filePath}:${line}:${column}`;\n case 'antigravity':\n return `antigravity://file/${filePath}:${line}:${column}`;\n case 'pearai':\n return `pearai://file/${filePath}:${line}:${column}`;\n case 'qoder':\n return `qoder://file/${filePath}:${line}:${column}`;\n case 'codebuddy':\n return `codebuddy://file/${filePath}:${line}:${column}`;\n\n default:\n return `vscode://file/${filePath}:${line}:${column}`;\n }\n}\n","import type { ComponentNode } from '../adapters/types.js';\nimport type { InspectedElement } from '../types.js';\n\nexport interface TreePanelOptions {\n position: 'left' | 'right';\n showProps: boolean;\n showLineNumbers: boolean;\n onSelect: (node: ComponentNode) => void;\n onHover: (node: ComponentNode | null) => void;\n}\n\nexport class TreePanel {\n private container: HTMLElement;\n private visible = false;\n private searchInput: HTMLInputElement | null = null;\n private treeContainer: HTMLElement | null = null;\n private filter = '';\n\n constructor(\n private shadowRoot: ShadowRoot,\n private options: TreePanelOptions,\n ) {\n this.container = document.createElement('div');\n this.container.className = `inspekt-tree-panel inspekt-tree-${options.position}`;\n this.container.style.display = 'none';\n this.shadowRoot.appendChild(this.container);\n this.buildUI();\n }\n\n private buildUI(): void {\n // Header with search\n const header = document.createElement('div');\n header.className = 'inspekt-tree-header';\n\n const title = document.createElement('span');\n title.className = 'inspekt-tree-title';\n title.textContent = 'Component Tree';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'inspekt-tree-close';\n closeBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`;\n closeBtn.addEventListener('click', () => this.hide());\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n this.container.appendChild(header);\n\n // Search\n const searchWrap = document.createElement('div');\n searchWrap.className = 'inspekt-tree-search';\n this.searchInput = document.createElement('input');\n this.searchInput.type = 'text';\n this.searchInput.placeholder = 'Filter components...';\n this.searchInput.className = 'inspekt-tree-search-input';\n this.searchInput.addEventListener('input', () => {\n this.filter = this.searchInput!.value.toLowerCase();\n this.renderCurrentTree();\n });\n searchWrap.appendChild(this.searchInput);\n this.container.appendChild(searchWrap);\n\n // Tree content area\n this.treeContainer = document.createElement('div');\n this.treeContainer.className = 'inspekt-tree-content';\n this.container.appendChild(this.treeContainer);\n\n // Make panel draggable via resize handle\n const resizeHandle = document.createElement('div');\n resizeHandle.className = `inspekt-tree-resize inspekt-tree-resize-${this.options.position === 'right' ? 'left' : 'right'}`;\n this.container.appendChild(resizeHandle);\n this.setupResize(resizeHandle);\n }\n\n private currentTree: ComponentNode | null = null;\n\n show(): void {\n this.visible = true;\n this.container.style.display = 'flex';\n }\n\n hide(): void {\n this.visible = false;\n this.container.style.display = 'none';\n }\n\n toggle(): void {\n if (this.visible) this.hide();\n else this.show();\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n updateTree(tree: ComponentNode | null): void {\n this.currentTree = tree;\n this.renderCurrentTree();\n }\n\n selectElement(element: InspectedElement): void {\n // Find and highlight matching node in tree\n if (!this.treeContainer) return;\n const nodes = this.treeContainer.querySelectorAll('.inspekt-tree-node');\n for (const node of nodes) {\n node.classList.remove('inspekt-tree-node-selected');\n const path = node.getAttribute('data-path');\n if (path === `${element.filePath}:${element.line}`) {\n node.classList.add('inspekt-tree-node-selected');\n node.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }\n }\n\n private renderCurrentTree(): void {\n if (!this.treeContainer) return;\n this.treeContainer.innerHTML = '';\n\n if (!this.currentTree) {\n const empty = document.createElement('div');\n empty.className = 'inspekt-tree-empty';\n empty.textContent = 'No component tree detected';\n this.treeContainer.appendChild(empty);\n return;\n }\n\n const fragment = document.createDocumentFragment();\n this.renderNode(this.currentTree, fragment, 0);\n this.treeContainer.appendChild(fragment);\n }\n\n private renderNode(node: ComponentNode, parent: DocumentFragment | HTMLElement, depth: number): void {\n // Filter check\n if (this.filter && !this.matchesFilter(node)) return;\n\n const row = document.createElement('div');\n row.className = 'inspekt-tree-node';\n row.setAttribute('data-path', `${node.filePath ?? ''}:${node.line ?? ''}`);\n row.style.paddingLeft = `${depth * 16 + 8}px`;\n\n // Expand/collapse arrow\n const hasChildren = node.children.length > 0;\n const arrow = document.createElement('span');\n arrow.className = 'inspekt-tree-arrow';\n if (hasChildren) {\n arrow.innerHTML = `<svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 12 15 18 9\"/></svg>`;\n arrow.classList.add('inspekt-tree-arrow-expanded');\n }\n row.appendChild(arrow);\n\n // Component name\n const name = document.createElement('span');\n name.className = 'inspekt-tree-name';\n name.textContent = node.name;\n row.appendChild(name);\n\n // Line number\n if (this.options.showLineNumbers && node.line) {\n const line = document.createElement('span');\n line.className = 'inspekt-tree-line';\n line.textContent = `:${node.line}`;\n row.appendChild(line);\n }\n\n // Props preview\n if (this.options.showProps && node.props) {\n const propsEl = document.createElement('span');\n propsEl.className = 'inspekt-tree-props';\n const entries = Object.entries(node.props).slice(0, 3);\n propsEl.textContent = entries.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(' ');\n row.appendChild(propsEl);\n }\n\n // Click to select\n row.addEventListener('click', (e) => {\n e.stopPropagation();\n this.options.onSelect(node);\n\n // Toggle expand/collapse\n if (hasChildren) {\n const childContainer = row.nextElementSibling;\n if (childContainer?.classList.contains('inspekt-tree-children')) {\n const isCollapsed = childContainer.classList.toggle('inspekt-tree-collapsed');\n arrow.classList.toggle('inspekt-tree-arrow-collapsed', isCollapsed);\n arrow.classList.toggle('inspekt-tree-arrow-expanded', !isCollapsed);\n }\n }\n\n // Update selected state\n this.treeContainer!.querySelectorAll('.inspekt-tree-node-selected')\n .forEach((n) => n.classList.remove('inspekt-tree-node-selected'));\n row.classList.add('inspekt-tree-node-selected');\n });\n\n // Hover to highlight\n row.addEventListener('mouseenter', () => this.options.onHover(node));\n row.addEventListener('mouseleave', () => this.options.onHover(null));\n\n parent.appendChild(row);\n\n // Children\n if (hasChildren) {\n const childContainer = document.createElement('div');\n childContainer.className = 'inspekt-tree-children';\n for (const child of node.children) {\n this.renderNode(child, childContainer, depth + 1);\n }\n parent.appendChild(childContainer);\n }\n }\n\n private matchesFilter(node: ComponentNode): boolean {\n if (node.name.toLowerCase().includes(this.filter)) return true;\n return node.children.some((child) => this.matchesFilter(child));\n }\n\n private setupResize(handle: HTMLElement): void {\n let startX: number;\n let startWidth: number;\n const isRight = this.options.position === 'right';\n\n const onMouseMove = (e: MouseEvent) => {\n const dx = e.clientX - startX;\n const newWidth = isRight ? startWidth - dx : startWidth + dx;\n this.container.style.width = `${Math.max(200, Math.min(600, newWidth))}px`;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.container.style.userSelect = '';\n };\n\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n startX = e.clientX;\n startWidth = this.container.offsetWidth;\n this.container.style.userSelect = 'none';\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n }\n\n destroy(): void {\n this.container.remove();\n }\n}\n","import type { ComponentNode, FrameworkAdapter } from './types.js';\nimport { parseSourceAttribute, findSourceAttribute } from '../detection/source-detector.js';\n\n// React Fiber internal key prefix\nconst FIBER_KEY_PREFIX = '__reactFiber$';\nconst INTERNAL_KEY_PREFIX = '__reactInternalInstance$';\n\nfunction getFiberFromElement(element: HTMLElement): Record<string, unknown> | null {\n for (const key of Object.keys(element)) {\n if (key.startsWith(FIBER_KEY_PREFIX) || key.startsWith(INTERNAL_KEY_PREFIX)) {\n return (element as unknown as Record<string, unknown>)[key] as Record<string, unknown>;\n }\n }\n return null;\n}\n\nfunction isUserComponent(fiber: Record<string, unknown>): boolean {\n const tag = fiber['tag'] as number;\n // FunctionComponent = 0, ClassComponent = 1, ForwardRef = 11, MemoComponent = 14, SimpleMemoComponent = 15\n return tag === 0 || tag === 1 || tag === 11 || tag === 14 || tag === 15;\n}\n\ninterface FunctionWithDisplayName {\n displayName?: string;\n name?: string;\n}\n\nfunction getComponentName(fiber: Record<string, unknown>): string {\n // A fiber's `type` is a host string (\"div\"), a component function, or an\n // object wrapper (forwardRef/memo). Keep all three in the union so the\n // `typeof` checks below narrow correctly.\n const type = fiber['type'] as\n | string\n | (FunctionWithDisplayName & ((...args: unknown[]) => unknown))\n | Record<string, unknown>\n | null;\n if (!type) return 'Unknown';\n\n if (typeof type === 'function') {\n return type.displayName ?? type.name ?? 'Anonymous';\n }\n\n // ForwardRef, memo wrappers\n if (typeof type === 'object') {\n const render = type['render'] as FunctionWithDisplayName | undefined;\n if (render) return render.displayName ?? render.name ?? 'ForwardRef';\n\n const innerType = type['type'] as FunctionWithDisplayName | undefined;\n if (innerType) return innerType.displayName ?? innerType.name ?? 'Memo';\n }\n\n if (typeof type === 'string') return type;\n\n return 'Unknown';\n}\n\nfunction getProps(fiber: Record<string, unknown>): Record<string, unknown> | null {\n const memoizedProps = fiber['memoizedProps'] as Record<string, unknown> | null;\n if (!memoizedProps) return null;\n\n // Filter out children and internal props\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(memoizedProps)) {\n if (key === 'children') continue;\n if (typeof value === 'function') {\n cleaned[key] = `[Function: ${(value as Function).name || 'anonymous'}]`;\n } else if (typeof value === 'object' && value !== null) {\n cleaned[key] = '[Object]';\n } else {\n cleaned[key] = value;\n }\n }\n return Object.keys(cleaned).length > 0 ? cleaned : null;\n}\n\nfunction getSourceFromFiber(fiber: Record<string, unknown>): { filePath: string; line: number; column: number } | null {\n // Check _debugSource (React dev mode)\n const debugSource = fiber['_debugSource'] as Record<string, unknown> | undefined;\n if (debugSource) {\n return {\n filePath: (debugSource['fileName'] as string) ?? '',\n line: (debugSource['lineNumber'] as number) ?? 0,\n column: (debugSource['columnNumber'] as number) ?? 0,\n };\n }\n\n // Fall back to DOM element's data attribute\n const stateNode = fiber['stateNode'] as HTMLElement | null;\n if (stateNode && stateNode instanceof HTMLElement) {\n const attr = findSourceAttribute(stateNode);\n if (attr) {\n const parsed = parseSourceAttribute(attr);\n if (parsed) return { filePath: parsed.filePath, line: parsed.line, column: parsed.column };\n }\n }\n\n return null;\n}\n\nfunction fiberToNode(fiber: Record<string, unknown>, depth: number): ComponentNode | null {\n if (!isUserComponent(fiber)) return null;\n\n const name = getComponentName(fiber);\n const source = getSourceFromFiber(fiber);\n const stateNode = fiber['stateNode'] as HTMLElement | null;\n const domElement = stateNode instanceof HTMLElement ? stateNode : findDomElement(fiber);\n\n const node: ComponentNode = {\n name,\n filePath: source?.filePath ?? null,\n line: source?.line ?? null,\n column: source?.column ?? null,\n domElement,\n props: getProps(fiber),\n children: [],\n framework: 'react',\n depth,\n };\n\n // Walk children\n let child = fiber['child'] as Record<string, unknown> | null;\n while (child) {\n const childNode = fiberToNode(child, depth + 1);\n if (childNode) {\n node.children.push(childNode);\n } else {\n // Skip non-user components but traverse their children\n const grandchildren = collectUserChildren(child, depth + 1);\n node.children.push(...grandchildren);\n }\n child = child['sibling'] as Record<string, unknown> | null;\n }\n\n return node;\n}\n\nfunction collectUserChildren(fiber: Record<string, unknown>, depth: number): ComponentNode[] {\n const result: ComponentNode[] = [];\n let child = fiber['child'] as Record<string, unknown> | null;\n while (child) {\n const node = fiberToNode(child, depth);\n if (node) {\n result.push(node);\n } else {\n result.push(...collectUserChildren(child, depth));\n }\n child = child['sibling'] as Record<string, unknown> | null;\n }\n return result;\n}\n\nfunction findDomElement(fiber: Record<string, unknown>): HTMLElement | null {\n // Walk down the fiber tree to find the first DOM element\n let current: Record<string, unknown> | null = fiber;\n while (current) {\n const stateNode = current['stateNode'];\n if (stateNode instanceof HTMLElement) return stateNode;\n current = current['child'] as Record<string, unknown> | null;\n }\n return null;\n}\n\nfunction findRootFiber(container: HTMLElement): Record<string, unknown> | null {\n // React 18+ uses _reactRootContainer or __reactContainer$\n for (const key of Object.keys(container)) {\n if (key.startsWith('__reactContainer$')) {\n return (container as unknown as Record<string, unknown>)[key] as Record<string, unknown>;\n }\n }\n\n const root = (container as unknown as Record<string, unknown>)['_reactRootContainer'] as Record<string, unknown> | undefined;\n if (root) {\n const internalRoot = root['_internalRoot'] as Record<string, unknown> | undefined;\n if (internalRoot) {\n return internalRoot['current'] as Record<string, unknown> | null;\n }\n }\n\n return null;\n}\n\nexport const reactAdapter: FrameworkAdapter = {\n name: 'react',\n\n detect(): boolean {\n // Check for React root containers\n const root = document.getElementById('root') ?? document.getElementById('app') ?? document.querySelector('[data-reactroot]');\n if (!root) return false;\n\n for (const key of Object.keys(root)) {\n if (key.startsWith('__reactContainer$') || key.startsWith(FIBER_KEY_PREFIX) || key.startsWith(INTERNAL_KEY_PREFIX)) {\n return true;\n }\n }\n\n return !!(root as unknown as Record<string, unknown>)['_reactRootContainer'];\n },\n\n getComponentTree(root: HTMLElement): ComponentNode | null {\n const rootFiber = findRootFiber(root);\n if (!rootFiber) return null;\n\n // The root fiber's child is the actual app\n const appFiber = rootFiber['child'] as Record<string, unknown> | null;\n if (!appFiber) return null;\n\n return fiberToNode(appFiber, 0);\n },\n\n getComponentAtElement(element: HTMLElement): ComponentNode | null {\n const fiber = getFiberFromElement(element);\n if (!fiber) return null;\n\n // Walk up to find the nearest user component\n let current: Record<string, unknown> | null = fiber;\n while (current) {\n if (isUserComponent(current)) {\n return fiberToNode(current, 0);\n }\n current = current['return'] as Record<string, unknown> | null;\n }\n\n return null;\n },\n\n getAncestors(element: HTMLElement): ComponentNode[] {\n const fiber = getFiberFromElement(element);\n if (!fiber) return [];\n\n const ancestors: ComponentNode[] = [];\n let current = fiber['return'] as Record<string, unknown> | null;\n\n while (current) {\n if (isUserComponent(current)) {\n const node = fiberToNode(current, 0);\n if (node) {\n node.children = []; // Don't include full subtrees for ancestors\n ancestors.push(node);\n }\n }\n current = current['return'] as Record<string, unknown> | null;\n }\n\n return ancestors;\n },\n};\n","import type { ComponentNode, FrameworkAdapter } from './types.js';\nimport { findSourceAttribute, parseSourceAttribute } from '../detection/source-detector.js';\n\nconst VUE_KEY = '__vue__'; // Vue 2\nconst VUE3_KEY = '__vue_app__'; // Vue 3 app root\nconst VUE_PARENT_KEY = '__vueParentComponent'; // Vue 3 component\n\ninterface VueInstance {\n $options?: { name?: string; __file?: string; _componentTag?: string };\n $parent?: VueInstance | null;\n $children?: VueInstance[];\n $el?: HTMLElement;\n $props?: Record<string, unknown>;\n type?: { name?: string; __file?: string; __name?: string };\n parent?: VueInstance | null;\n subTree?: { children?: VueInstance[]; el?: HTMLElement };\n props?: Record<string, unknown>;\n}\n\nfunction getVueInstance(element: HTMLElement): VueInstance | null {\n // Vue 3\n const vue3 = (element as unknown as Record<string, unknown>)[VUE_PARENT_KEY] as VueInstance | undefined;\n if (vue3) return vue3;\n\n // Vue 2\n const vue2 = (element as unknown as Record<string, unknown>)[VUE_KEY] as VueInstance | undefined;\n if (vue2) return vue2;\n\n return null;\n}\n\nfunction getComponentName(instance: VueInstance): string {\n // Vue 3\n if (instance.type) {\n return instance.type.name ?? instance.type.__name ?? 'Anonymous';\n }\n // Vue 2\n if (instance.$options) {\n return instance.$options.name ?? instance.$options._componentTag ?? 'Anonymous';\n }\n return 'Unknown';\n}\n\nfunction getFilePath(instance: VueInstance): string | null {\n // Vue 3\n if (instance.type?.__file) return instance.type.__file;\n // Vue 2\n if (instance.$options?.__file) return instance.$options.__file;\n return null;\n}\n\nfunction getElement(instance: VueInstance): HTMLElement | null {\n if (instance.subTree?.el instanceof HTMLElement) return instance.subTree.el;\n if (instance.$el instanceof HTMLElement) return instance.$el;\n return null;\n}\n\nfunction getProps(instance: VueInstance): Record<string, unknown> | null {\n const raw = instance.props ?? instance.$props;\n if (!raw || Object.keys(raw).length === 0) return null;\n\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(raw)) {\n if (typeof value === 'function') {\n cleaned[key] = `[Function]`;\n } else if (typeof value === 'object' && value !== null) {\n cleaned[key] = '[Object]';\n } else {\n cleaned[key] = value;\n }\n }\n return cleaned;\n}\n\nfunction instanceToNode(instance: VueInstance, depth: number): ComponentNode {\n const name = getComponentName(instance);\n const file = getFilePath(instance);\n const el = getElement(instance);\n let filePath = file;\n let line: number | null = null;\n\n // Check DOM element for data attribute (more accurate)\n if (el) {\n const attr = findSourceAttribute(el);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n filePath = source.filePath;\n line = source.line;\n }\n }\n }\n\n return {\n name,\n filePath,\n line,\n column: null,\n domElement: el,\n props: getProps(instance),\n children: [],\n framework: 'vue',\n depth,\n };\n}\n\nexport const vueAdapter: FrameworkAdapter = {\n name: 'vue',\n\n detect(): boolean {\n const root = document.getElementById('app') ?? document.getElementById('root');\n if (!root) return false;\n return !!(\n (root as unknown as Record<string, unknown>)[VUE3_KEY] ||\n (root as unknown as Record<string, unknown>)[VUE_KEY]\n );\n },\n\n getComponentTree(root: HTMLElement): ComponentNode | null {\n // Walk DOM to find Vue component instances\n const rootNode: ComponentNode = {\n name: 'App',\n filePath: null,\n line: null,\n column: null,\n domElement: root,\n props: null,\n children: [],\n framework: 'vue',\n depth: 0,\n };\n\n function walkDOM(el: HTMLElement, parent: ComponentNode, depth: number): void {\n for (const child of Array.from(el.children)) {\n if (!(child instanceof HTMLElement)) continue;\n\n const instance = getVueInstance(child);\n if (instance) {\n const node = instanceToNode(instance, depth);\n parent.children.push(node);\n walkDOM(child, node, depth + 1);\n } else {\n walkDOM(child, parent, depth);\n }\n }\n }\n\n walkDOM(root, rootNode, 1);\n return rootNode.children.length > 0 ? rootNode : null;\n },\n\n getComponentAtElement(element: HTMLElement): ComponentNode | null {\n const instance = getVueInstance(element);\n if (!instance) return null;\n return instanceToNode(instance, 0);\n },\n\n getAncestors(element: HTMLElement): ComponentNode[] {\n const ancestors: ComponentNode[] = [];\n let instance = getVueInstance(element);\n\n while (instance) {\n const parent = instance.parent ?? instance.$parent;\n if (parent) {\n ancestors.push(instanceToNode(parent, 0));\n }\n instance = parent ?? null;\n }\n\n return ancestors;\n },\n};\n","import type { ComponentNode, FrameworkAdapter } from './types.js';\nimport { findSourceAttribute, parseSourceAttribute } from '../detection/source-detector.js';\n\n// Svelte 4/5 attaches context to DOM elements\nconst SVELTE_CONTEXT_KEY = '__svelte_meta';\n\ninterface SvelteContext {\n loc?: { file?: string; line?: number; column?: number; char?: number };\n}\n\nfunction getSvelteContext(element: HTMLElement): SvelteContext | null {\n return (element as unknown as Record<string, unknown>)[SVELTE_CONTEXT_KEY] as SvelteContext | null;\n}\n\nfunction getComponentNameFromFile(file: string): string {\n const parts = file.split('/');\n const filename = parts[parts.length - 1] ?? '';\n return filename.replace(/\\.svelte$/, '');\n}\n\nexport const svelteAdapter: FrameworkAdapter = {\n name: 'svelte',\n\n detect(): boolean {\n // Check for Svelte's internal markers\n return document.querySelector(`[class*=\"svelte-\"]`) !== null ||\n document.querySelector('[data-svelte-h]') !== null;\n },\n\n getComponentTree(root: HTMLElement): ComponentNode | null {\n const rootNode: ComponentNode = {\n name: 'App',\n filePath: null,\n line: null,\n column: null,\n domElement: root,\n props: null,\n children: [],\n framework: 'svelte',\n depth: 0,\n };\n\n function walkDOM(el: HTMLElement, parent: ComponentNode, depth: number): void {\n for (const child of Array.from(el.children)) {\n if (!(child instanceof HTMLElement)) continue;\n\n // Try inspekt data attribute first\n const attr = findSourceAttribute(child);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n const node: ComponentNode = {\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: child,\n props: null,\n children: [],\n framework: 'svelte',\n depth,\n };\n parent.children.push(node);\n walkDOM(child, node, depth + 1);\n continue;\n }\n }\n\n // Try Svelte context\n const ctx = getSvelteContext(child);\n if (ctx?.loc?.file) {\n const node: ComponentNode = {\n name: getComponentNameFromFile(ctx.loc.file),\n filePath: ctx.loc.file,\n line: ctx.loc.line ?? null,\n column: ctx.loc.column ?? null,\n domElement: child,\n props: null,\n children: [],\n framework: 'svelte',\n depth,\n };\n parent.children.push(node);\n walkDOM(child, node, depth + 1);\n continue;\n }\n\n // Not a component — continue walking\n walkDOM(child, parent, depth);\n }\n }\n\n walkDOM(root, rootNode, 1);\n return rootNode.children.length > 0 ? rootNode : null;\n },\n\n getComponentAtElement(element: HTMLElement): ComponentNode | null {\n const attr = findSourceAttribute(element);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n return {\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: element,\n props: null,\n children: [],\n framework: 'svelte',\n depth: 0,\n };\n }\n }\n\n const ctx = getSvelteContext(element);\n if (ctx?.loc?.file) {\n return {\n name: getComponentNameFromFile(ctx.loc.file),\n filePath: ctx.loc.file,\n line: ctx.loc.line ?? null,\n column: ctx.loc.column ?? null,\n domElement: element,\n props: null,\n children: [],\n framework: 'svelte',\n depth: 0,\n };\n }\n\n return null;\n },\n\n getAncestors(element: HTMLElement): ComponentNode[] {\n const ancestors: ComponentNode[] = [];\n let current = element.parentElement;\n\n while (current) {\n const node = this.getComponentAtElement(current);\n if (node) ancestors.push(node);\n current = current.parentElement;\n }\n\n return ancestors;\n },\n};\n","import type { ComponentNode, FrameworkAdapter } from './types.js';\nimport { findSourceAttribute, parseSourceAttribute } from '../detection/source-detector.js';\n\n// Solid attaches owner information to DOM elements in dev mode\nconst SOLID_DEV_KEY = '_$owner';\n\ninterface SolidOwner {\n name?: string;\n componentName?: string;\n sourceMap?: { file?: string; line?: number; column?: number };\n owner?: SolidOwner;\n}\n\nfunction getSolidOwner(element: HTMLElement): SolidOwner | null {\n return (element as unknown as Record<string, unknown>)[SOLID_DEV_KEY] as SolidOwner | null;\n}\n\nexport const solidAdapter: FrameworkAdapter = {\n name: 'solid',\n\n detect(): boolean {\n // Solid uses _$HY for hydration and data-hk for hydration keys\n return document.querySelector('[data-hk]') !== null ||\n !!(document as unknown as Record<string, unknown>)['_$HY'];\n },\n\n getComponentTree(root: HTMLElement): ComponentNode | null {\n const rootNode: ComponentNode = {\n name: 'App',\n filePath: null,\n line: null,\n column: null,\n domElement: root,\n props: null,\n children: [],\n framework: 'solid',\n depth: 0,\n };\n\n function walkDOM(el: HTMLElement, parent: ComponentNode, depth: number): void {\n for (const child of Array.from(el.children)) {\n if (!(child instanceof HTMLElement)) continue;\n\n // Try inspekt data attribute first\n const attr = findSourceAttribute(child);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n const node: ComponentNode = {\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: child,\n props: null,\n children: [],\n framework: 'solid',\n depth,\n };\n parent.children.push(node);\n walkDOM(child, node, depth + 1);\n continue;\n }\n }\n\n // Try Solid owner\n const owner = getSolidOwner(child);\n if (owner?.componentName || owner?.name) {\n const node: ComponentNode = {\n name: owner.componentName ?? owner.name ?? 'Component',\n filePath: owner.sourceMap?.file ?? null,\n line: owner.sourceMap?.line ?? null,\n column: owner.sourceMap?.column ?? null,\n domElement: child,\n props: null,\n children: [],\n framework: 'solid',\n depth,\n };\n parent.children.push(node);\n walkDOM(child, node, depth + 1);\n continue;\n }\n\n walkDOM(child, parent, depth);\n }\n }\n\n walkDOM(root, rootNode, 1);\n return rootNode.children.length > 0 ? rootNode : null;\n },\n\n getComponentAtElement(element: HTMLElement): ComponentNode | null {\n const attr = findSourceAttribute(element);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n return {\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: element,\n props: null,\n children: [],\n framework: 'solid',\n depth: 0,\n };\n }\n }\n\n const owner = getSolidOwner(element);\n if (owner?.componentName || owner?.name) {\n return {\n name: owner.componentName ?? owner.name ?? 'Component',\n filePath: owner.sourceMap?.file ?? null,\n line: owner.sourceMap?.line ?? null,\n column: owner.sourceMap?.column ?? null,\n domElement: element,\n props: null,\n children: [],\n framework: 'solid',\n depth: 0,\n };\n }\n\n return null;\n },\n\n getAncestors(element: HTMLElement): ComponentNode[] {\n const ancestors: ComponentNode[] = [];\n let current = element.parentElement;\n\n while (current) {\n const node = this.getComponentAtElement(current);\n if (node) ancestors.push(node);\n current = current.parentElement;\n }\n\n return ancestors;\n },\n};\n","import type { ComponentNode, FrameworkAdapter } from './types.js';\nimport { findSourceAttribute, parseSourceAttribute } from '../detection/source-detector.js';\n\nfunction buildTreeFromDOM(element: HTMLElement, depth: number): ComponentNode[] {\n const nodes: ComponentNode[] = [];\n\n for (const child of Array.from(element.children)) {\n if (!(child instanceof HTMLElement)) continue;\n if (child.tagName === 'INSPEKT-ROOT') continue;\n if (child.tagName === 'SCRIPT' || child.tagName === 'STYLE') continue;\n\n const attr = findSourceAttribute(child);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n const node: ComponentNode = {\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: child,\n props: null,\n children: buildTreeFromDOM(child, depth + 1),\n framework: 'unknown',\n depth,\n };\n nodes.push(node);\n continue;\n }\n }\n\n // Not a component — recurse into children\n nodes.push(...buildTreeFromDOM(child, depth));\n }\n\n return nodes;\n}\n\nexport const genericAdapter: FrameworkAdapter = {\n name: 'generic',\n\n detect(): boolean {\n return document.querySelector('[data-insp-path], [data-insp-path]') !== null;\n },\n\n getComponentTree(root: HTMLElement): ComponentNode | null {\n const children = buildTreeFromDOM(root, 1);\n if (children.length === 0) return null;\n\n return {\n name: 'Root',\n filePath: null,\n line: null,\n column: null,\n domElement: root,\n props: null,\n children,\n framework: 'unknown',\n depth: 0,\n };\n },\n\n getComponentAtElement(element: HTMLElement): ComponentNode | null {\n const attr = findSourceAttribute(element);\n if (!attr) return null;\n\n const source = parseSourceAttribute(attr);\n if (!source) return null;\n\n return {\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: element,\n props: null,\n children: buildTreeFromDOM(element, 1),\n framework: 'unknown',\n depth: 0,\n };\n },\n\n getAncestors(element: HTMLElement): ComponentNode[] {\n const ancestors: ComponentNode[] = [];\n let current = element.parentElement;\n\n while (current) {\n const attr = findSourceAttribute(current);\n if (attr) {\n const source = parseSourceAttribute(attr);\n if (source) {\n ancestors.push({\n name: source.componentName,\n filePath: source.filePath,\n line: source.line,\n column: source.column,\n domElement: current,\n props: null,\n children: [],\n framework: 'unknown',\n depth: 0,\n });\n }\n }\n current = current.parentElement;\n }\n\n return ancestors;\n },\n};\n","import type { FrameworkAdapter } from './types.js';\nimport { reactAdapter } from './react.js';\nimport { vueAdapter } from './vue.js';\nimport { svelteAdapter } from './svelte.js';\nimport { solidAdapter } from './solid.js';\nimport { genericAdapter } from './generic.js';\n\nexport type { ComponentNode, FrameworkAdapter } from './types.js';\n\nconst adapters: FrameworkAdapter[] = [\n reactAdapter,\n vueAdapter,\n svelteAdapter,\n solidAdapter,\n];\n\nexport function detectAdapter(): FrameworkAdapter {\n for (const adapter of adapters) {\n if (adapter.detect()) return adapter;\n }\n return genericAdapter;\n}\n\nexport function getAdapter(framework: string): FrameworkAdapter {\n switch (framework) {\n case 'react':\n return reactAdapter;\n case 'vue':\n return vueAdapter;\n case 'svelte':\n return svelteAdapter;\n case 'solid':\n return solidAdapter;\n default:\n return genericAdapter;\n }\n}\n","export const STYLES = /* css */ `\n :host {\n all: initial;\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n z-index: 2147483647;\n pointer-events: none;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* Theme variables */\n :host {\n --dl-bg: #1e1e2e;\n --dl-bg-hover: #313244;\n --dl-text: #cdd6f4;\n --dl-text-dim: #a6adc8;\n --dl-border: #45475a;\n --dl-accent: #3b82f6;\n --dl-accent-dim: #3b82f640;\n --dl-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);\n --dl-radius: 8px;\n }\n\n :host(.inspekt-light) {\n --dl-bg: #ffffff;\n --dl-bg-hover: #f1f5f9;\n --dl-text: #1e293b;\n --dl-text-dim: #64748b;\n --dl-border: #e2e8f0;\n --dl-accent: #3b82f6;\n --dl-accent-dim: #3b82f620;\n --dl-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\n }\n\n /* Popover */\n .inspekt-popover {\n position: fixed;\n background: var(--dl-bg);\n border: 1px solid var(--dl-border);\n border-radius: var(--dl-radius);\n box-shadow: var(--dl-shadow);\n color: var(--dl-text);\n min-width: 200px;\n max-width: 400px;\n overflow: hidden;\n pointer-events: auto;\n z-index: 2147483647;\n animation: inspekt-fade-in 0.15s ease;\n }\n\n @keyframes inspekt-fade-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .inspekt-popover-header {\n padding: 8px 12px;\n border-bottom: 1px solid var(--dl-border);\n }\n\n .inspekt-popover-path-dir {\n font-size: 11px;\n color: var(--dl-text-dim);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .inspekt-popover-path-file {\n font-size: 13px;\n font-weight: 600;\n color: var(--dl-text);\n }\n\n .inspekt-popover-actions {\n display: flex;\n gap: 2px;\n padding: 6px 8px;\n }\n\n /* Snippet section */\n .inspekt-snippet {\n border-bottom: 1px solid var(--dl-border);\n }\n\n .inspekt-snippet-toggle {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 6px 12px;\n background: transparent;\n border: none;\n color: var(--dl-text-dim);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n text-align: left;\n pointer-events: auto;\n }\n\n .inspekt-snippet-toggle:hover {\n background: var(--dl-bg-hover);\n color: var(--dl-text);\n }\n\n .inspekt-snippet-body {\n padding: 0;\n max-width: 600px;\n max-height: 240px;\n overflow: auto;\n border-top: 1px solid var(--dl-border);\n }\n\n .inspekt-snippet-pre {\n margin: 0;\n padding: 8px 0;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Consolas', monospace;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dl-text);\n background: transparent;\n white-space: pre;\n tab-size: 2;\n }\n\n .inspekt-line {\n display: inline-flex;\n align-items: baseline;\n padding: 0 12px 0 0;\n }\n\n .inspekt-line-target {\n background: var(--dl-accent-dim);\n border-left: 2px solid var(--dl-accent);\n padding-left: 10px;\n }\n\n .inspekt-line:not(.inspekt-line-target) {\n padding-left: 12px;\n }\n\n .inspekt-line-no {\n display: inline-block;\n min-width: 30px;\n text-align: right;\n color: var(--dl-text-dim);\n margin-right: 10px;\n user-select: none;\n flex-shrink: 0;\n }\n\n .inspekt-line-code {\n white-space: pre;\n }\n\n .inspekt-snippet-skeleton,\n .inspekt-snippet-empty {\n padding: 12px;\n font-size: 11px;\n color: var(--dl-text-dim);\n text-align: center;\n font-style: italic;\n }\n\n .inspekt-popover-action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--dl-text-dim);\n cursor: pointer;\n transition: all 0.15s ease;\n pointer-events: auto;\n }\n\n .inspekt-popover-action:hover {\n background: var(--dl-bg-hover);\n color: var(--dl-text);\n }\n\n .inspekt-popover-action:active {\n transform: scale(0.92);\n }\n\n .inspekt-popover-action svg {\n width: 16px;\n height: 16px;\n }\n\n /* Popover toast — brief feedback after Copy / console.log actions */\n .inspekt-popover-toast {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n padding: 6px 14px;\n background: var(--dl-text);\n color: var(--dl-bg);\n font: 500 12px/1.4 inherit;\n border-radius: 999px;\n box-shadow: var(--dl-shadow);\n pointer-events: none;\n z-index: 2147483647;\n animation: inspekt-toast 1.2s ease;\n }\n @keyframes inspekt-toast {\n 0% { opacity: 0; transform: translate(-50%, 6px); }\n 15%, 80% { opacity: 1; transform: translate(-50%, 0); }\n 100% { opacity: 0; transform: translate(-50%, 0); }\n }\n\n /* Info badge — small pill rendered in the DOM-fallback popover header.\n Shows an info icon + \"No source\" label so users see it without hover. */\n .inspekt-info-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px 2px 6px;\n border-radius: 999px;\n background: var(--dl-bg-hover);\n color: var(--dl-text-dim);\n font-size: 10.5px;\n font-weight: 500;\n letter-spacing: 0.01em;\n line-height: 1.4;\n cursor: help;\n flex-shrink: 0;\n margin-left: 8px;\n border: 1px solid var(--dl-border);\n text-transform: none;\n }\n .inspekt-info-badge:hover,\n .inspekt-info-badge:focus-visible {\n color: var(--dl-text);\n border-color: var(--dl-accent);\n outline: none;\n }\n .inspekt-info-badge svg { display: block; }\n .inspekt-info-badge-label {\n white-space: nowrap;\n }\n .inspekt-popover-path-dir-row {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n /* Tooltip (replaces native title=\"\") */\n .inspekt-tooltip {\n position: fixed;\n max-width: 280px;\n padding: 6px 10px;\n background: var(--dl-bg);\n color: var(--dl-text);\n border: 1px solid var(--dl-border);\n border-radius: 6px;\n box-shadow: var(--dl-shadow);\n font-size: 12px;\n line-height: 1.4;\n pointer-events: none;\n z-index: 2147483647;\n opacity: 0;\n animation: inspekt-tt-in 120ms ease-out forwards;\n }\n .inspekt-tooltip--rich {\n pointer-events: auto;\n max-width: 320px;\n padding: 10px 12px;\n }\n @keyframes inspekt-tt-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n /* Wider source snippet body when accordion is expanded (1.5× collapsed) */\n .inspekt-snippet-body[data-state='expanded'] {\n max-width: 900px;\n }\n\n /* Prism syntax tokens — neutral palette mapped to theme variables. */\n .inspekt-snippet-pre .token.comment,\n .inspekt-snippet-pre .token.prolog,\n .inspekt-snippet-pre .token.doctype,\n .inspekt-snippet-pre .token.cdata { color: var(--dl-text-dim); font-style: italic; }\n .inspekt-snippet-pre .token.punctuation { color: var(--dl-text-dim); }\n .inspekt-snippet-pre .token.namespace { opacity: 0.7; }\n .inspekt-snippet-pre .token.property,\n .inspekt-snippet-pre .token.tag,\n .inspekt-snippet-pre .token.constant,\n .inspekt-snippet-pre .token.symbol,\n .inspekt-snippet-pre .token.deleted { color: #e06c75; }\n .inspekt-snippet-pre .token.boolean,\n .inspekt-snippet-pre .token.number { color: #d19a66; }\n .inspekt-snippet-pre .token.selector,\n .inspekt-snippet-pre .token.attr-name,\n .inspekt-snippet-pre .token.string,\n .inspekt-snippet-pre .token.char,\n .inspekt-snippet-pre .token.builtin,\n .inspekt-snippet-pre .token.inserted { color: #98c379; }\n .inspekt-snippet-pre .token.operator,\n .inspekt-snippet-pre .token.entity,\n .inspekt-snippet-pre .token.url,\n .inspekt-snippet-pre .language-css .token.string,\n .inspekt-snippet-pre .style .token.string { color: #56b6c2; }\n .inspekt-snippet-pre .token.atrule,\n .inspekt-snippet-pre .token.attr-value,\n .inspekt-snippet-pre .token.keyword { color: #c678dd; }\n .inspekt-snippet-pre .token.function,\n .inspekt-snippet-pre .token.class-name { color: #61afef; }\n .inspekt-snippet-pre .token.regex,\n .inspekt-snippet-pre .token.important,\n .inspekt-snippet-pre .token.variable { color: #d19a66; }\n .inspekt-snippet-pre .token.important,\n .inspekt-snippet-pre .token.bold { font-weight: bold; }\n .inspekt-snippet-pre .token.italic { font-style: italic; }\n\n /* Overlay badges */\n .inspekt-overlay {\n position: absolute;\n top: 0;\n left: 0;\n pointer-events: none;\n }\n\n .inspekt-badge {\n position: absolute;\n background: var(--dl-accent);\n color: #fff;\n font-size: 10px;\n font-weight: 600;\n padding: 1px 6px;\n border-radius: 4px;\n white-space: nowrap;\n pointer-events: auto;\n cursor: pointer;\n opacity: 0.9;\n transition: opacity 0.15s ease;\n z-index: 2147483646;\n }\n\n .inspekt-badge:hover {\n opacity: 1;\n }\n\n /* Pulse animation for selected highlight */\n @keyframes inspekt-pulse {\n 0%, 100% { box-shadow: 0 0 0 0 var(--dl-accent-dim); }\n 50% { box-shadow: 0 0 8px 4px var(--dl-accent-dim); }\n }\n\n /* Tree Panel */\n .inspekt-tree-panel {\n position: fixed;\n top: 0;\n height: 100vh;\n width: 320px;\n background: var(--dl-bg);\n border-left: 1px solid var(--dl-border);\n color: var(--dl-text);\n display: flex;\n flex-direction: column;\n pointer-events: auto;\n z-index: 2147483647;\n box-shadow: var(--dl-shadow);\n animation: inspekt-slide-in 0.2s ease;\n }\n\n .inspekt-tree-right { right: 0; border-left: 1px solid var(--dl-border); border-right: none; }\n .inspekt-tree-left { left: 0; border-right: 1px solid var(--dl-border); border-left: none; }\n\n @keyframes inspekt-slide-in {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n }\n\n .inspekt-tree-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-bottom: 1px solid var(--dl-border);\n flex-shrink: 0;\n }\n\n .inspekt-tree-title {\n font-weight: 600;\n font-size: 13px;\n }\n\n .inspekt-tree-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--dl-text-dim);\n cursor: pointer;\n }\n\n .inspekt-tree-close:hover {\n background: var(--dl-bg-hover);\n color: var(--dl-text);\n }\n\n .inspekt-tree-search {\n padding: 6px 12px;\n border-bottom: 1px solid var(--dl-border);\n flex-shrink: 0;\n }\n\n .inspekt-tree-search-input {\n width: 100%;\n padding: 5px 8px;\n border: 1px solid var(--dl-border);\n border-radius: 6px;\n background: var(--dl-bg-hover);\n color: var(--dl-text);\n font-size: 12px;\n outline: none;\n font-family: inherit;\n }\n\n .inspekt-tree-search-input:focus {\n border-color: var(--dl-accent);\n }\n\n .inspekt-tree-search-input::placeholder {\n color: var(--dl-text-dim);\n }\n\n .inspekt-tree-content {\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n scrollbar-width: thin;\n scrollbar-color: var(--dl-border) transparent;\n }\n\n .inspekt-tree-content::-webkit-scrollbar { width: 6px; }\n .inspekt-tree-content::-webkit-scrollbar-thumb { background: var(--dl-border); border-radius: 3px; }\n\n .inspekt-tree-node {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n cursor: pointer;\n min-height: 26px;\n transition: background 0.1s ease;\n }\n\n .inspekt-tree-node:hover {\n background: var(--dl-bg-hover);\n }\n\n .inspekt-tree-node-selected {\n background: var(--dl-accent-dim) !important;\n }\n\n .inspekt-tree-arrow {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n transition: transform 0.15s ease;\n }\n\n .inspekt-tree-arrow svg { color: var(--dl-text-dim); }\n\n .inspekt-tree-arrow-expanded { transform: rotate(0deg); }\n .inspekt-tree-arrow-collapsed { transform: rotate(-90deg); }\n\n .inspekt-tree-name {\n font-size: 12px;\n font-weight: 500;\n color: #c792ea;\n }\n\n :host(.inspekt-light) .inspekt-tree-name {\n color: #7c3aed;\n }\n\n .inspekt-tree-line {\n font-size: 11px;\n color: var(--dl-text-dim);\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Consolas', monospace;\n }\n\n .inspekt-tree-props {\n font-size: 10px;\n color: var(--dl-text-dim);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 120px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Consolas', monospace;\n }\n\n .inspekt-tree-children.inspekt-tree-collapsed {\n display: none;\n }\n\n .inspekt-tree-empty {\n padding: 16px;\n text-align: center;\n color: var(--dl-text-dim);\n font-size: 12px;\n }\n\n /* Resize handle */\n .inspekt-tree-resize {\n position: absolute;\n top: 0;\n width: 4px;\n height: 100%;\n cursor: col-resize;\n }\n\n .inspekt-tree-resize-left { left: 0; }\n .inspekt-tree-resize-right { right: 0; }\n\n .inspekt-tree-resize:hover {\n background: var(--dl-accent);\n opacity: 0.5;\n }\n\n /* Bounding-box overlay — view mode & \"Show bounding boxes\" toggle */\n .inspekt-bbox-layer {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 2147483646;\n }\n .inspekt-bbox {\n position: fixed;\n top: 0;\n left: 0;\n box-sizing: border-box;\n border: 1.5px dashed var(--dl-accent, oklch(0.62 0.18 285));\n background: oklch(0.62 0.18 285 / 0.05);\n pointer-events: none;\n will-change: transform, width, height;\n border-radius: 2px;\n }\n .inspekt-bbox-label {\n position: absolute;\n top: -18px;\n left: 0;\n font: 500 10px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n color: #fff;\n background: var(--dl-accent, oklch(0.55 0.18 285));\n padding: 2px 5px;\n border-radius: 3px 3px 3px 0;\n white-space: nowrap;\n pointer-events: none;\n max-width: 280px;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n`;\n","/**\n * RichSelect — a small, framework-free dropdown that supports per-item\n * icons, hint text, and an optional side-popover (used for the Editor\n * picker which shows a \"Visit website\" link on hover).\n *\n * Lives in document scope (not shadow DOM) — it's meant for the Chrome\n * extension's options / welcome surfaces, not the in-page popover. The\n * listbox is portal-mounted on `document.body` so it escapes overflow:\n * hidden ancestors.\n */\nimport {\n autoUpdate,\n computePosition,\n flip,\n offset,\n shift,\n size,\n type Placement,\n} from '@floating-ui/dom';\nimport { attachTooltip } from './tooltip.js';\n\nexport interface RichSelectItem<V extends string = string> {\n value: V;\n label: string;\n /** Secondary descriptive line shown under the label. */\n hint?: string;\n /** Path / data URL / SVG inline string. If absent we render a letter tile. */\n icon?: string;\n /** Optional element rendered inside the per-row side popover. */\n popover?: () => HTMLElement;\n /**\n * Optional group label. When two consecutive items have different group\n * strings, a non-interactive header row is inserted before the second.\n * Items with the same group string render together; the order of items\n * decides the order of groups. Items without `group` form an implicit\n * leading \"ungrouped\" section.\n */\n group?: string;\n /**\n * Optional click handler. When set, takes precedence over the default\n * `select(value)` behavior — useful for action rows like \"+ Add custom\".\n * The row is still rendered but skips the selected-state marker.\n */\n action?: () => void;\n}\n\nexport interface RichSelectOptions<V extends string = string> {\n /** Element to host the trigger button (replaced). */\n anchor: HTMLElement;\n items: RichSelectItem<V>[];\n /** Current selected value. */\n value: V;\n /** Called on selection change. */\n onChange: (value: V) => void;\n /** ms delay before the per-item side popover appears. Default 50. */\n popoverDelay?: number;\n /** Optional aria label for the trigger. */\n ariaLabel?: string;\n /**\n * Floating-UI placement for the per-row side popover. Defaults to `'top'`\n * (matches the simple tooltip behavior). For the editor dropdown we pass\n * `'left-start'` so the rich card slides in to the side without covering\n * the listbox rows.\n */\n popoverPlacement?: Placement;\n}\n\nexport interface RichSelectController<V extends string = string> {\n setValue(value: V): void;\n getValue(): V;\n destroy(): void;\n}\n\nexport function createRichSelect<V extends string = string>(\n opts: RichSelectOptions<V>,\n): RichSelectController<V> {\n let current: V = opts.value;\n let listEl: HTMLDivElement | null = null;\n let activeIndex = -1;\n let cleanupAutoUpdate: (() => void) | null = null;\n // Each per-row attachTooltip call returns a detach function. We must run\n // them all before removing the listbox — otherwise the tooltip bubbles\n // (which live in document.body, outside the listbox) survive with their\n // autoUpdate watchers still ticking against now-detached row references,\n // and floating-ui snaps them to a zero-rect → top-left corner.\n const tooltipDetachers: Array<() => void> = [];\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'inspekt-rich-select-trigger';\n trigger.setAttribute('aria-haspopup', 'listbox');\n trigger.setAttribute('aria-expanded', 'false');\n if (opts.ariaLabel) trigger.setAttribute('aria-label', opts.ariaLabel);\n\n opts.anchor.replaceChildren(trigger);\n renderTrigger();\n\n trigger.addEventListener('click', (e) => {\n e.preventDefault();\n if (listEl) close();\n else open();\n });\n\n trigger.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n open();\n }\n });\n\n function renderTrigger(): void {\n trigger.innerHTML = '';\n const item = opts.items.find((i) => i.value === current) ?? opts.items[0];\n if (!item) return;\n trigger.appendChild(renderIcon(item));\n const labelEl = document.createElement('span');\n labelEl.className = 'rs-label';\n labelEl.textContent = item.label;\n trigger.appendChild(labelEl);\n }\n\n function renderIcon(item: RichSelectItem<V>): HTMLElement {\n if (item.icon) {\n if (/^<svg|^<\\?xml/.test(item.icon.trim())) {\n const wrap = document.createElement('span');\n wrap.className = 'rs-icon';\n wrap.innerHTML = item.icon;\n return wrap;\n }\n const img = document.createElement('img');\n img.className = 'rs-icon';\n img.src = item.icon;\n img.alt = '';\n return img;\n }\n const tile = document.createElement('span');\n tile.className = 'inspekt-rich-select-item-letter';\n tile.textContent = (item.label[0] ?? '?').toUpperCase();\n return tile;\n }\n\n function open(): void {\n if (listEl) return;\n listEl = document.createElement('div');\n listEl.className = 'inspekt-rich-select-list';\n listEl.setAttribute('role', 'listbox');\n\n let lastGroup: string | undefined;\n opts.items.forEach((item, i) => {\n // Insert a non-interactive group header whenever the group changes.\n if (item.group && item.group !== lastGroup) {\n const header = document.createElement('div');\n header.className = 'inspekt-rich-select-group-header';\n header.setAttribute('role', 'presentation');\n header.textContent = item.group;\n listEl!.appendChild(header);\n }\n lastGroup = item.group;\n\n const row = document.createElement('div');\n row.className = 'inspekt-rich-select-item';\n if (item.action) row.classList.add('inspekt-rich-select-item-action');\n row.setAttribute('role', 'option');\n row.dataset['value'] = item.value;\n // Action rows aren't real selections; never paint as selected.\n if (!item.action && item.value === current) row.dataset['selected'] = 'true';\n\n row.appendChild(renderIcon(item));\n\n const body = document.createElement('div');\n body.className = 'inspekt-rich-select-item-body';\n const labelEl = document.createElement('span');\n labelEl.className = 'inspekt-rich-select-item-label';\n labelEl.textContent = item.label;\n body.appendChild(labelEl);\n if (item.hint) {\n const hintEl = document.createElement('span');\n hintEl.className = 'inspekt-rich-select-item-hint';\n hintEl.textContent = item.hint;\n body.appendChild(hintEl);\n }\n row.appendChild(body);\n\n row.addEventListener('mouseenter', () => setActive(i));\n row.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (item.action) {\n close();\n item.action();\n return;\n }\n select(item.value);\n });\n\n if (item.popover) {\n tooltipDetachers.push(\n attachTooltip(row, item.popover(), {\n enterDelay: opts.popoverDelay ?? 50,\n leaveDelay: 200,\n placement: opts.popoverPlacement ?? 'top',\n }),\n );\n }\n\n listEl!.appendChild(row);\n });\n\n listEl.style.position = 'fixed';\n listEl.style.top = '0';\n listEl.style.left = '0';\n document.body.appendChild(listEl);\n // autoUpdate fires `update` immediately, so the listbox is in place before\n // it paints. Continues to track on scroll/resize/ancestor scroll.\n cleanupAutoUpdate = autoUpdate(trigger, listEl, updateListPosition);\n trigger.setAttribute('aria-expanded', 'true');\n setActive(opts.items.findIndex((i) => i.value === current));\n\n document.addEventListener('mousedown', onOutside, true);\n document.addEventListener('keydown', onKey, true);\n }\n\n function close(): void {\n if (!listEl) return;\n // Detach all per-row tooltips FIRST — otherwise their autoUpdate\n // watchers tick against the now-removed rows and snap the bubbles\n // to a zero-rect (top-left corner of the viewport).\n for (const d of tooltipDetachers) d();\n tooltipDetachers.length = 0;\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n listEl.remove();\n listEl = null;\n trigger.setAttribute('aria-expanded', 'false');\n document.removeEventListener('mousedown', onOutside, true);\n document.removeEventListener('keydown', onKey, true);\n }\n\n function updateListPosition(): void {\n if (!listEl) return;\n const list = listEl;\n const triggerWidth = trigger.getBoundingClientRect().width;\n list.style.minWidth = `${triggerWidth}px`;\n\n void computePosition(trigger, list, {\n placement: 'bottom-start',\n strategy: 'fixed',\n middleware: [\n offset(4),\n flip(),\n shift({ padding: 8 }),\n size({\n apply({ availableHeight }) {\n list.style.maxHeight = `${Math.max(160, availableHeight - 8)}px`;\n },\n padding: 8,\n }),\n ],\n }).then(({ x, y }) => {\n list.style.left = `${Math.round(x)}px`;\n list.style.top = `${Math.round(y)}px`;\n });\n }\n\n function setActive(i: number): void {\n if (!listEl) return;\n activeIndex = i;\n const rows = listEl.querySelectorAll<HTMLDivElement>('.inspekt-rich-select-item');\n rows.forEach((r, idx) => {\n if (idx === i) r.dataset['active'] = 'true';\n else delete r.dataset['active'];\n });\n }\n\n function select(value: V): void {\n if (value !== current) {\n current = value;\n renderTrigger();\n opts.onChange(value);\n }\n close();\n }\n\n function onOutside(e: MouseEvent): void {\n const t = e.target as Node;\n if (listEl?.contains(t) || trigger.contains(t)) return;\n // Clicks inside one of our row tooltips (rich popover) shouldn't close\n // the listbox immediately — the click might be on an `<a target=\"_blank\">`\n // that needs the trigger row alive long enough to navigate without\n // floating-ui re-anchoring the bubble against a zero-rect (which would\n // snap it to the top-left). Defer the close to a microtask so the\n // navigation is already in flight by the time we tear down.\n if (t instanceof Element && t.closest('.inspekt-tooltip')) {\n setTimeout(close, 0);\n return;\n }\n close();\n }\n\n function onKey(e: KeyboardEvent): void {\n if (!listEl) return;\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n trigger.focus();\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActive(Math.min(opts.items.length - 1, activeIndex + 1));\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActive(Math.max(0, activeIndex - 1));\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n const item = opts.items[activeIndex];\n if (!item) return;\n if (item.action) {\n close();\n item.action();\n } else {\n select(item.value);\n }\n return;\n }\n // Type-ahead: jump to first item whose label starts with the key.\n if (e.key.length === 1) {\n const ch = e.key.toLowerCase();\n const next = opts.items.findIndex((it) => it.label.toLowerCase().startsWith(ch));\n if (next >= 0) setActive(next);\n }\n }\n\n return {\n setValue(value) {\n current = value;\n renderTrigger();\n },\n getValue() {\n return current;\n },\n destroy() {\n close();\n trigger.remove();\n },\n };\n}\n","import type {\n InspektOptions,\n InspektInstance,\n InspektAction,\n InspektEventMap,\n InspectedElement,\n} from './types.js';\nimport { findClosestSource, elementToInspected } from './detection/source-detector.js';\nimport { Highlighter } from './highlight/highlighter.js';\nimport { BoundingBoxOverlay } from './highlight/bounding-boxes.js';\nimport { Popover } from './popover/popover.js';\nimport { Overlay } from './overlay/overlay.js';\nimport {\n createOpenEditorAction,\n createCopyPathAction,\n createOpenGithubAction,\n createConsoleLogAction,\n} from './actions/built-in.js';\nimport { TreePanel } from './tree-panel/tree-panel.js';\nimport { detectAdapter, type ComponentNode } from './adapters/index.js';\nimport { STYLES } from './styles.js';\n\nexport type { ComponentNode } from './adapters/index.js';\nexport type {\n InspektOptions,\n InspektInstance,\n InspektAction,\n InspektEventMap,\n InspectedElement,\n};\nexport type { ShortcutConfig, HighlightConfig, BadgeConfig, TreePanelConfig } from './types.js';\n\n// Component primitives shared with the Chrome extension.\nexport { attachTooltip } from './components/tooltip.js';\nexport type { TooltipOptions } from './components/tooltip.js';\nexport { createRichSelect } from './components/rich-select.js';\nexport type { RichSelectItem, RichSelectController, RichSelectOptions } from './components/rich-select.js';\nexport { tokenizeToLines } from './highlight/prism.js';\nexport type { CodeToken, CodeLine } from './highlight/prism.js';\n\nconst DEFAULT_OPTIONS: InspektOptions = {\n // Default preserves the legacy click-mod behavior: page interactions never\n // intercepted unless Ctrl+Alt is held. Empty array = always-on hover.\n requireModifiers: ['ctrl', 'alt'],\n showBoundingBoxes: false,\n shortcut: { key: 'click', modifiers: ['ctrl', 'alt'] },\n toggleShortcut: { key: 'i', modifiers: ['ctrl', 'alt'] },\n theme: 'auto',\n highlight: {\n color: '#3b82f6',\n style: 'glow',\n animation: 'pulse',\n },\n badge: {\n show: true,\n position: 'auto',\n showPath: false,\n },\n borders: false,\n actions: ['open-editor', 'copy-path', 'open-github', 'console-log'],\n editor: 'cursor',\n editorPathBase: '',\n githubRepo: '',\n githubBranch: 'main',\n pathMapping: {},\n treePanel: {\n enabled: true,\n position: 'right',\n showProps: true,\n showLineNumbers: true,\n },\n sourceAttribute: 'data-insp-path',\n serverUrl: '',\n defaultSnippetExpanded: false,\n snippetContext: 5,\n sourceMapEnabled: false,\n customEditors: [],\n};\n\nexport function createInspekt(userOptions: Partial<InspektOptions> = {}): InspektInstance {\n const options: InspektOptions = { ...DEFAULT_OPTIONS, ...userOptions };\n let capabilityTeardown: (() => void) | null = null;\n\n // Merge nested objects\n if (userOptions.highlight) options.highlight = { ...DEFAULT_OPTIONS.highlight, ...userOptions.highlight };\n if (userOptions.badge) options.badge = { ...DEFAULT_OPTIONS.badge, ...userOptions.badge };\n if (userOptions.treePanel) options.treePanel = { ...DEFAULT_OPTIONS.treePanel, ...userOptions.treePanel };\n if (userOptions.shortcut) options.shortcut = { ...DEFAULT_OPTIONS.shortcut, ...userOptions.shortcut };\n if (userOptions.toggleShortcut) options.toggleShortcut = { ...DEFAULT_OPTIONS.toggleShortcut, ...userOptions.toggleShortcut };\n\n let enabled = false;\n const listeners = new Map<string, Set<Function>>();\n const customActions = new Map<string, InspektAction>();\n\n // Create Shadow DOM host\n const host = document.createElement('inspekt-root');\n const shadow = host.attachShadow({ mode: 'open' });\n\n // Inject styles\n const style = document.createElement('style');\n style.textContent = STYLES;\n shadow.appendChild(style);\n\n // Apply theme\n applyTheme(host, options.theme);\n\n // Components\n const highlighter = new Highlighter(options.highlight);\n const popover = new Popover(shadow);\n popover.configureSnippet({\n serverUrl: options.serverUrl || undefined,\n context: options.snippetContext,\n defaultExpanded: options.defaultSnippetExpanded,\n sourceMapEnabled: options.sourceMapEnabled,\n staticSnippets: options.staticSnippets,\n });\n const overlay = new Overlay(shadow);\n const bboxOverlay = new BoundingBoxOverlay(shadow);\n const adapter = detectAdapter();\n\n let treePanel: TreePanel | null = null;\n if (options.treePanel.enabled) {\n treePanel = new TreePanel(shadow, {\n position: options.treePanel.position,\n showProps: options.treePanel.showProps,\n showLineNumbers: options.treePanel.showLineNumbers,\n onSelect(node: ComponentNode) {\n if (node.domElement) {\n highlighter.unhighlightAll();\n highlighter.highlight(node.domElement, 'selected');\n node.domElement.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n emit('tree-select', node);\n },\n onHover(node: ComponentNode | null) {\n highlighter.unhighlightAll();\n if (node?.domElement) {\n highlighter.highlight(node.domElement, 'hovered');\n }\n },\n });\n }\n\n function refreshTree(): void {\n if (!treePanel) return;\n const root = document.getElementById('root') ?? document.getElementById('app') ?? document.body;\n const tree = adapter.getComponentTree(root);\n treePanel.updateTree(tree);\n }\n\n // Build actions list\n function getActions(): InspektAction[] {\n const builtInMap: Record<string, () => InspektAction> = {\n 'open-editor': () => createOpenEditorAction(options.serverUrl, options.editor, options.customEditors),\n 'copy-path': () => createCopyPathAction(),\n 'open-github': () => createOpenGithubAction(options.githubRepo, options.githubBranch),\n 'console-log': () => createConsoleLogAction(),\n };\n\n const result: InspektAction[] = [];\n for (const id of options.actions) {\n const factory = builtInMap[id];\n if (factory) {\n result.push(factory());\n }\n }\n for (const action of customActions.values()) {\n result.push(action);\n }\n return result;\n }\n\n // Engagement gate. The inspector engages only when the user holds every\n // modifier listed in `options.requireModifiers`. Empty array = always-on.\n // Cmd (meta) on macOS is treated as Ctrl for ergonomic parity.\n function modifiersOk(e: MouseEvent | KeyboardEvent): boolean {\n return options.requireModifiers.every((mod) => {\n switch (mod) {\n case 'ctrl': return e.ctrlKey || e.metaKey;\n case 'alt': return e.altKey;\n case 'shift': return e.shiftKey;\n case 'meta': return e.metaKey;\n }\n });\n }\n\n // Event handlers\n function handleClick(e: MouseEvent): void {\n if (!enabled) return;\n\n // Outside-click dismisses a pinned popover. The shadow host re-targets\n // clicks inside the popover to <inspekt-root>, so any other target is\n // \"outside\".\n const clickTarget = e.target as HTMLElement;\n const isInsideInspekt = clickTarget?.tagName === 'INSPEKT-ROOT';\n if (popover.isPinned() && !isInsideInspekt) {\n popover.unpin();\n popover.hide();\n highlighter.unhighlightAll();\n // fall through — the click might also be a fresh inspect target\n }\n\n // Shift+Alt+Click = direct open in editor. Global power-user shortcut,\n // independent of the engagement gate.\n if (e.shiftKey && e.altKey && !e.ctrlKey && !e.metaKey) {\n e.preventDefault();\n e.stopPropagation();\n const target = e.target as HTMLElement;\n const result = findClosestSource(target);\n if (result) {\n const inspected = elementToInspected(result.element, result.source, options.pathMapping);\n const editorAction = getActions().find((a) => a.id === 'open-editor');\n if (editorAction) editorAction.handler(inspected);\n emit('action', 'open-editor', inspected);\n }\n return;\n }\n\n // Engagement gate. If the required modifiers aren't held, the click is a\n // real page click — never intercept.\n if (!modifiersOk(e)) return;\n\n const target = e.target as HTMLElement;\n const result = findClosestSource(target);\n const isFallback = !result && isFallbackTarget(target);\n\n // Only intercept the click when we have something to inspect; empty\n // clicks (e.g., on the welcome tour's Next button) must pass through.\n if (!result && !isFallback) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n if (result) {\n const inspected = elementToInspected(result.element, result.source, options.pathMapping);\n highlighter.unhighlightAll();\n highlighter.highlight(result.element, 'selected');\n popover.show(inspected, getActions(), { x: e.clientX, y: e.clientY });\n popover.pin();\n treePanel?.selectElement(inspected);\n emit('inspect', inspected);\n } else if (isFallback) {\n // DOM-only fallback — no source attrs / fibers, but the user still\n // expects visible feedback on a Standalone session.\n showDomFallback(target, e.clientX, e.clientY);\n popover.pin();\n }\n }\n\n function showDomFallback(el: HTMLElement, x: number, y: number): void {\n highlighter.unhighlightAll();\n highlighter.highlight(el, 'selected');\n popover.showDom(\n el,\n { x, y },\n async (selector) => copyToClipboard(selector),\n async (html) => copyToClipboard(html),\n () => {\n // eslint-disable-next-line no-console\n console.log('[Inspekt]', el);\n },\n );\n }\n\n /**\n * Robust clipboard copy. `navigator.clipboard` rejects on:\n * - non-secure contexts (http://);\n * - documents that don't have transient activation (we're inside a\n * capture-phase listener AFTER a stopPropagation — some browsers\n * consider activation consumed);\n * - sandboxed/embedded frames without clipboard-write permission.\n * Fall back to the legacy `document.execCommand('copy')` flow which only\n * needs a focused selection.\n */\n async function copyToClipboard(text: string): Promise<boolean> {\n if (navigator.clipboard?.writeText) {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n // fall through to execCommand fallback\n }\n }\n try {\n const ta = document.createElement('textarea');\n ta.value = text;\n ta.style.cssText =\n 'position:fixed;top:-1000px;left:-1000px;opacity:0;pointer-events:none;';\n document.body.appendChild(ta);\n ta.focus();\n ta.select();\n const ok = document.execCommand('copy');\n ta.remove();\n return ok;\n } catch {\n return false;\n }\n }\n\n function handleKeydown(e: KeyboardEvent): void {\n // Toggle shortcut\n if (matchesShortcut(e, options.toggleShortcut)) {\n e.preventDefault();\n instance.toggle();\n return;\n }\n\n // Escape to close popover\n if (e.key === 'Escape' && popover.isVisible()) {\n popover.unpin();\n popover.hide();\n highlighter.unhighlightAll();\n }\n\n // Ctrl+Alt+O = toggle overlay\n if (e.key === 'o' && e.ctrlKey && e.altKey) {\n e.preventDefault();\n overlay.toggle();\n }\n\n // Ctrl+Alt+T = toggle tree panel\n if (e.key === 't' && e.ctrlKey && e.altKey) {\n e.preventDefault();\n if (treePanel) {\n treePanel.toggle();\n if (treePanel.isVisible()) refreshTree();\n }\n }\n }\n\n function matchesShortcut(e: KeyboardEvent, shortcut: { key: string; modifiers: Array<'ctrl' | 'alt' | 'shift' | 'meta'> }): boolean {\n if (e.key.toLowerCase() !== shortcut.key.toLowerCase()) return false;\n const needCtrl = shortcut.modifiers.includes('ctrl');\n const needAlt = shortcut.modifiers.includes('alt');\n const needShift = shortcut.modifiers.includes('shift');\n const needMeta = shortcut.modifiers.includes('meta');\n return (\n (needCtrl ? e.ctrlKey || e.metaKey : true) &&\n (needAlt ? e.altKey : true) &&\n (needShift ? e.shiftKey : true) &&\n (needMeta ? e.metaKey : true)\n );\n }\n\n function handleMouseMove(e: MouseEvent): void {\n if (!enabled) return;\n // Pinned popover stays put — no follow-the-cursor.\n if (popover.isPinned()) return;\n\n // Engagement gate. When the user's modifier choice isn't satisfied,\n // hover does nothing and any previously-shown popover tears down.\n if (!modifiersOk(e)) {\n highlighter.unhighlightAll();\n popover.hide();\n return;\n }\n\n const target = e.target as HTMLElement;\n const result = findClosestSource(target);\n highlighter.unhighlightAll();\n if (result) {\n highlighter.highlight(result.element, 'selected');\n const inspected = elementToInspected(result.element, result.source, options.pathMapping);\n popover.show(inspected, getActions(), { x: e.clientX, y: e.clientY });\n treePanel?.selectElement(inspected);\n emit('inspect', inspected);\n } else if (isFallbackTarget(target)) {\n showDomFallback(target, e.clientX, e.clientY);\n } else {\n popover.hide();\n }\n }\n\n function isFallbackTarget(el: HTMLElement | null): el is HTMLElement {\n if (!el) return false;\n if (el === document.body || el === document.documentElement) return false;\n // Inspekt's own shadow host shows up as e.target due to shadow retargeting.\n if (el.tagName === 'INSPEKT-ROOT') return false;\n return true;\n }\n\n // Event emitter\n function emit(event: string, ...args: unknown[]): void {\n const handlers = listeners.get(event);\n if (handlers) {\n for (const handler of handlers) {\n (handler as Function)(...args);\n }\n }\n }\n\n function applyTheme(el: HTMLElement, theme: 'light' | 'dark' | 'auto'): void {\n el.classList.remove('inspekt-light', 'inspekt-dark');\n if (theme === 'auto') {\n const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n if (!isDark) el.classList.add('inspekt-light');\n } else if (theme === 'light') {\n el.classList.add('inspekt-light');\n }\n }\n\n // Listen for theme changes\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const themeHandler = () => applyTheme(host, options.theme);\n mediaQuery.addEventListener('change', themeHandler);\n\n // Listen for settings from Chrome extension\n document.addEventListener('inspekt:settings-update', ((e: CustomEvent) => {\n const newSettings = e.detail;\n Object.assign(options, newSettings);\n if (newSettings.highlight) highlighter.updateConfig(options.highlight);\n applyTheme(host, options.theme);\n if (enabled) {\n if (options.showBoundingBoxes === true) bboxOverlay.enable();\n else bboxOverlay.disable();\n }\n }) as EventListener);\n\n const instance: InspektInstance = {\n enable() {\n if (enabled) return;\n enabled = true;\n document.body.appendChild(host);\n document.addEventListener('click', handleClick, true);\n document.addEventListener('keydown', handleKeydown, true);\n document.addEventListener('mousemove', handleMouseMove);\n\n // Signal to Chrome extension\n (window as unknown as Record<string, unknown>).__INSPEKT__ = { version: '0.1.0', options };\n document.dispatchEvent(new CustomEvent('inspekt:status', { detail: { enabled: true } }));\n\n // Start capability probe: publishes via window.postMessage so the Chrome\n // extension content script can forward to the background and update the\n // toolbar icon. Lives behind a dynamic import so headless / SSR use of\n // @aylith/inspekt-core doesn't pay for it.\n void import('./detection/capability-probe.js').then(({ watchCapabilities }) => {\n if (!enabled) return; // Could have been disabled during the import.\n capabilityTeardown = watchCapabilities({\n serverUrl: options.serverUrl || undefined,\n sourceMapEnabled: options.sourceMapEnabled,\n });\n });\n\n // Initialize tree panel with current component tree\n if (treePanel && options.treePanel.enabled) {\n // Delay to let the DOM settle after React/Vue renders\n setTimeout(() => refreshTree(), 100);\n }\n\n // Persistent bounding-box overlay — controlled by the independent\n // `showBoundingBoxes` toggle (no longer tied to any activation mode).\n if (options.showBoundingBoxes) {\n bboxOverlay.enable();\n }\n\n emit('enable');\n },\n\n disable() {\n if (!enabled) return;\n enabled = false;\n popover.hide();\n overlay.hide();\n treePanel?.hide();\n bboxOverlay.disable();\n highlighter.unhighlightAll();\n capabilityTeardown?.();\n capabilityTeardown = null;\n document.removeEventListener('click', handleClick, true);\n document.removeEventListener('keydown', handleKeydown, true);\n document.removeEventListener('mousemove', handleMouseMove);\n host.remove();\n\n document.dispatchEvent(new CustomEvent('inspekt:status', { detail: { enabled: false } }));\n emit('disable');\n },\n\n toggle() {\n if (enabled) instance.disable();\n else instance.enable();\n },\n\n destroy() {\n instance.disable();\n popover.destroy();\n overlay.destroy();\n treePanel?.destroy();\n bboxOverlay.destroy();\n mediaQuery.removeEventListener('change', themeHandler);\n listeners.clear();\n customActions.clear();\n delete (window as unknown as Record<string, unknown>).__INSPEKT__;\n },\n\n registerAction(action: InspektAction) {\n customActions.set(action.id, action);\n },\n\n unregisterAction(id: string) {\n customActions.delete(id);\n },\n\n on<K extends keyof InspektEventMap>(event: K, handler: InspektEventMap[K]) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n },\n\n off<K extends keyof InspektEventMap>(event: K, handler: InspektEventMap[K]) {\n listeners.get(event)?.delete(handler);\n },\n };\n\n return instance;\n}\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["getComponentName","getProps","autoUpdate","computePosition","flip","offset","shift","autoUpdate","computePosition","offset","flip","shift","target","result"]}
@@ -0,0 +1,30 @@
1
+ export interface Badge {
2
+ element: HTMLElement;
3
+ componentName: string;
4
+ badgeElement: HTMLElement;
5
+ visible: boolean;
6
+ }
7
+ export declare class Overlay {
8
+ private shadowRoot;
9
+ private badges;
10
+ private mutationObserver;
11
+ private intersectionObserver;
12
+ private debounceTimer;
13
+ private container;
14
+ private visible;
15
+ constructor(shadowRoot: ShadowRoot);
16
+ show(): void;
17
+ hide(): void;
18
+ toggle(): void;
19
+ isVisible(): boolean;
20
+ private scan;
21
+ private createBadge;
22
+ private positionBadge;
23
+ updatePositions(): void;
24
+ private startObserving;
25
+ private stopObserving;
26
+ private handleScrollResize;
27
+ private clear;
28
+ destroy(): void;
29
+ }
30
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/overlay/overlay.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,qBAAa,OAAO;IAQN,OAAO,CAAC,UAAU;IAP9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,OAAO,CAAS;IAExB,YAAoB,UAAU,EAAE,UAAU,EAKzC;IAED,IAAI,IAAI,IAAI,CAKX;IAED,IAAI,IAAI,IAAI,CAKX;IAED,MAAM,IAAI,IAAI,CAGb;IAED,SAAS,IAAI,OAAO,CAEnB;IAED,OAAO,CAAC,IAAI;IA2DZ,OAAO,CAAC,WAAW;IAwCnB,OAAO,CAAC,aAAa;IA+BrB,eAAe,IAAI,IAAI,CAMtB;IAED,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,kBAAkB,CAGxB;IAEF,OAAO,CAAC,KAAK;IAQb,OAAO,IAAI,IAAI,CAGd;CACF"}
@@ -0,0 +1,54 @@
1
+ import type { InspektAction, InspectedElement } from '../types.js';
2
+ export interface PopoverSnippetConfig {
3
+ /** Where the dev-server lives (set by @aylith/inspekt-vite at init time). */
4
+ serverUrl?: string;
5
+ /** Lines of context above and below the target line. */
6
+ context: number;
7
+ /** When true, the snippet section is expanded immediately on show(). */
8
+ defaultExpanded: boolean;
9
+ /** When true, attempts source-map fallback if the dev server can't help. */
10
+ sourceMapEnabled: boolean;
11
+ /** Pre-baked snippets indexed by filePath (demos/playgrounds). */
12
+ staticSnippets?: Record<string, {
13
+ language: string;
14
+ lines: string[];
15
+ startLine?: number;
16
+ }>;
17
+ }
18
+ export declare class Popover {
19
+ private shadowRoot;
20
+ private container;
21
+ private visible;
22
+ private pinned;
23
+ private snippetConfig;
24
+ constructor(shadowRoot: ShadowRoot);
25
+ /** Lock the popover in place — hover/move handlers will not reposition or
26
+ * hide it until {@link unpin} is called. Clicks set this; Escape clears it. */
27
+ pin(): void;
28
+ unpin(): void;
29
+ isPinned(): boolean;
30
+ configureSnippet(config: Partial<PopoverSnippetConfig>): void;
31
+ /**
32
+ * Fallback popover for Standalone-on-an-unbuilt-page: no source attrs,
33
+ * no React fibers — so we show DOM info (selector, classes, id) plus a
34
+ * minimal action set. Keeps Inspekt useful as a pure inspection tool.
35
+ */
36
+ showDom(domElement: HTMLElement, position: {
37
+ x: number;
38
+ y: number;
39
+ }, onCopySelector: (selector: string) => Promise<boolean> | boolean, onCopyHtml: (html: string) => Promise<boolean> | boolean, onConsoleLog: () => void): void;
40
+ /** Brief feedback toast attached to the shadow root. */
41
+ private showToast;
42
+ show(element: InspectedElement, actions: InspektAction[], position: {
43
+ x: number;
44
+ y: number;
45
+ }): void;
46
+ private buildSnippetSection;
47
+ private resolveAndMountSnippet;
48
+ private renderSnippet;
49
+ hide(): void;
50
+ isVisible(): boolean;
51
+ private positionAt;
52
+ destroy(): void;
53
+ }
54
+ //# sourceMappingURL=popover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../src/popover/popover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAclF,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,eAAe,EAAE,OAAO,CAAC;IACzB,4EAA4E;IAC5E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CACrB,MAAM,EACN;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAC1D,CAAC;CACH;AAQD,qBAAa,OAAO;IAMN,OAAO,CAAC,UAAU;IAL9B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAuD;IAE5E,YAAoB,UAAU,EAAE,UAAU,EAKzC;IAED;oFACgF;IAChF,GAAG,IAAI,IAAI,CAEV;IAED,KAAK,IAAI,IAAI,CAEZ;IAED,QAAQ,IAAI,OAAO,CAElB;IAED,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAE5D;IAED;;;;OAIG;IACH,OAAO,CACL,UAAU,EAAE,WAAW,EACvB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,EAChE,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,EACxD,YAAY,EAAE,MAAM,IAAI,GACvB,IAAI,CA+FN;IAED,wDAAwD;IACxD,OAAO,CAAC,SAAS;IAUjB,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAkDlG;IAED,OAAO,CAAC,mBAAmB;YA2Bb,sBAAsB;IA0DpC,OAAO,CAAC,aAAa;IAkDrB,IAAI,IAAI,IAAI,CAIX;IAED,SAAS,IAAI,OAAO,CAEnB;IAED,OAAO,CAAC,UAAU;IA8BlB,OAAO,IAAI,IAAI,CAEd;CACF"}
@@ -0,0 +1,3 @@
1
+ export { getElementContext } from 'react-grab/primitives';
2
+ export type { ReactGrabElementContext, StackFrame } from 'react-grab/primitives';
3
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { freeze, unfreeze, isFreezeActive } from 'react-grab/primitives';
2
+ //# sourceMappingURL=freeze.d.ts.map