@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.
- package/dist/actions/built-in.d.ts +17 -0
- package/dist/actions/built-in.d.ts.map +1 -0
- package/dist/adapters/generic.d.ts +3 -0
- package/dist/adapters/generic.d.ts.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/react.d.ts +3 -0
- package/dist/adapters/react.d.ts.map +1 -0
- package/dist/adapters/solid.d.ts +3 -0
- package/dist/adapters/solid.d.ts.map +1 -0
- package/dist/adapters/svelte.d.ts +3 -0
- package/dist/adapters/svelte.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +19 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/vue.d.ts +3 -0
- package/dist/adapters/vue.d.ts.map +1 -0
- package/dist/capability-probe-AKVKYSDE.js +107 -0
- package/dist/capability-probe-AKVKYSDE.js.map +1 -0
- package/dist/components/rich-select.d.ts +62 -0
- package/dist/components/rich-select.d.ts.map +1 -0
- package/dist/components/tooltip.d.ts +34 -0
- package/dist/components/tooltip.d.ts.map +1 -0
- package/dist/detection/capability-probe.d.ts +31 -0
- package/dist/detection/capability-probe.d.ts.map +1 -0
- package/dist/detection/fiber-detector.d.ts +12 -0
- package/dist/detection/fiber-detector.d.ts.map +1 -0
- package/dist/detection/source-detector.d.ts +30 -0
- package/dist/detection/source-detector.d.ts.map +1 -0
- package/dist/detection/vue-detector.d.ts +14 -0
- package/dist/detection/vue-detector.d.ts.map +1 -0
- package/dist/fiber-detector-CFB7M7OY.js +50 -0
- package/dist/fiber-detector-CFB7M7OY.js.map +1 -0
- package/dist/highlight/bounding-boxes.d.ts +20 -0
- package/dist/highlight/bounding-boxes.d.ts.map +1 -0
- package/dist/highlight/highlighter.d.ts +11 -0
- package/dist/highlight/highlighter.d.ts.map +1 -0
- package/dist/highlight/prism.d.ts +23 -0
- package/dist/highlight/prism.d.ts.map +1 -0
- package/dist/index.cjs +3560 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3222 -0
- package/dist/index.js.map +1 -0
- package/dist/overlay/overlay.d.ts +30 -0
- package/dist/overlay/overlay.d.ts.map +1 -0
- package/dist/popover/popover.d.ts +54 -0
- package/dist/popover/popover.d.ts.map +1 -0
- package/dist/runtime/context.d.ts +3 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/freeze.d.ts +2 -0
- package/dist/runtime/freeze.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/open-file.d.ts +2 -0
- package/dist/runtime/open-file.d.ts.map +1 -0
- package/dist/snippet/cache.d.ts +13 -0
- package/dist/snippet/cache.d.ts.map +1 -0
- package/dist/snippet/snippet-resolver.d.ts +21 -0
- package/dist/snippet/snippet-resolver.d.ts.map +1 -0
- package/dist/snippet/sourcemap-resolver.d.ts +9 -0
- package/dist/snippet/sourcemap-resolver.d.ts.map +1 -0
- package/dist/sourcemap-resolver-3PQ6R6PU.js +182 -0
- package/dist/sourcemap-resolver-3PQ6R6PU.js.map +1 -0
- package/dist/styles.d.ts +2 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/tree-panel/tree-panel.d.ts +33 -0
- package/dist/tree-panel/tree-panel.d.ts.map +1 -0
- package/dist/types.d.ts +148 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/snippet/cache.ts","../src/snippet/sourcemap-resolver.ts","../src/detection/capability-probe.ts","../src/index.ts","../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"],"sourcesContent":["/// <reference types=\"chrome\" />\n// Caches for the source-map resolver.\n//\n// Two layers:\n// 1. In-memory parsed-map LRU (max 5). Holds parsed TraceMap instances —\n// these are heap-heavy (large pre-decoded mappings), so we keep the\n// bound small.\n// 2. Raw-map text cache. When running inside the Chrome extension we\n// delegate to chrome.storage.session (per-session, ~10MB quota,\n// shared across tabs in the extension context). When running outside\n// the extension (e.g. unit tests, server-side use), we fall back to\n// an in-memory Map.\n\nconst PARSED_LIMIT = 5;\nconst RAW_QUOTA_BYTES = 9 * 1024 * 1024;\n\n// Generic-typed parsed-map cache. We can't pin TraceMap here without forcing\n// @jridgewell/trace-mapping into the bundle even when unused, so the cache\n// stores `unknown` and callers type-assert.\nconst parsed = new Map<string, unknown>();\n\nexport function getParsedMap(key: string): unknown {\n const v = parsed.get(key);\n if (v !== undefined) {\n // LRU touch.\n parsed.delete(key);\n parsed.set(key, v);\n }\n return v;\n}\n\nexport function setParsedMap(key: string, value: unknown): void {\n if (parsed.has(key)) parsed.delete(key);\n parsed.set(key, value);\n if (parsed.size > PARSED_LIMIT) {\n const oldest = parsed.keys().next().value;\n if (oldest !== undefined) parsed.delete(oldest);\n }\n}\n\nexport function clearParsedCache(): void {\n parsed.clear();\n}\n\n// Raw-map cache. We expose a small async interface and pick the backend at\n// runtime based on what's available.\n\nexport interface RawMapBackend {\n get(key: string): Promise<string | 'not-found' | undefined>;\n set(key: string, value: string): Promise<void>;\n setNotFound(key: string): Promise<void>;\n clear(): Promise<void>;\n}\n\nclass MemoryBackend implements RawMapBackend {\n private store = new Map<string, string | 'not-found'>();\n async get(key: string): Promise<string | 'not-found' | undefined> {\n return this.store.get(key);\n }\n async set(key: string, value: string): Promise<void> {\n this.store.set(key, value);\n }\n async setNotFound(key: string): Promise<void> {\n this.store.set(key, 'not-found');\n }\n async clear(): Promise<void> {\n this.store.clear();\n }\n}\n\n// Detect chrome.storage.session at module init; fall back to memory otherwise.\nfunction hasChromeSession(): boolean {\n try {\n return (\n typeof chrome !== 'undefined' &&\n typeof chrome.storage !== 'undefined' &&\n typeof chrome.storage.session !== 'undefined'\n );\n } catch {\n return false;\n }\n}\n\nconst PREFIX_HIT = 'inspekt-mapcache:';\nconst PREFIX_MISS = 'inspekt-notfound:';\n\nclass ChromeSessionBackend implements RawMapBackend {\n async get(key: string): Promise<string | 'not-found' | undefined> {\n const hitKey = PREFIX_HIT + key;\n const missKey = PREFIX_MISS + key;\n const res = await chrome.storage.session.get([hitKey, missKey]);\n if (res[missKey]) return 'not-found';\n const entry = res[hitKey];\n if (typeof entry === 'string') return entry;\n return undefined;\n }\n async set(key: string, value: string): Promise<void> {\n await this.evictIfNeeded(value.length);\n await chrome.storage.session.set({ [PREFIX_HIT + key]: value });\n }\n async setNotFound(key: string): Promise<void> {\n await chrome.storage.session.set({ [PREFIX_MISS + key]: true });\n }\n async clear(): Promise<void> {\n const all = await chrome.storage.session.get(null);\n const inspektKeys = Object.keys(all).filter(\n (k) => k.startsWith(PREFIX_HIT) || k.startsWith(PREFIX_MISS),\n );\n if (inspektKeys.length > 0) await chrome.storage.session.remove(inspektKeys);\n }\n\n private async evictIfNeeded(incomingBytes: number): Promise<void> {\n const used = await chrome.storage.session.getBytesInUse(null);\n if (used + incomingBytes < RAW_QUOTA_BYTES) return;\n // Evict every hit entry (cheap heuristic — source maps are infrequent).\n const all = await chrome.storage.session.get(null);\n const hits = Object.keys(all).filter((k) => k.startsWith(PREFIX_HIT));\n if (hits.length > 0) await chrome.storage.session.remove(hits);\n }\n}\n\nlet backend: RawMapBackend | null = null;\n\nexport function getRawMapBackend(): RawMapBackend {\n if (!backend) {\n backend = hasChromeSession() ? new ChromeSessionBackend() : new MemoryBackend();\n }\n return backend;\n}\n\n// Test seam: lets unit tests swap the backend without monkey-patching globals.\nexport function setRawMapBackendForTesting(b: RawMapBackend | null): void {\n backend = b;\n}\n\nexport async function clearRawMapCache(): Promise<void> {\n await getRawMapBackend().clear();\n}\n","// Source-map fallback for the snippet resolver.\n//\n// Activates only when sourceMapEnabled=true in the Chrome extension options\n// (default off — fetching .map files makes additional network requests\n// observable in DevTools/proxies and we don't want to do that without user\n// consent). When enabled, we:\n// 1. Walk the page's <script src> tags and try to find the source map\n// adjacent to each bundle.\n// 2. Fetch the .map file (with a per-session cache).\n// 3. Parse it with @jridgewell/trace-mapping.\n// 4. Find the original source by matching the desired filePath against the\n// map's `sources[]` array.\n// 5. Slice `sourcesContent[index]` around the target line.\n\nimport { TraceMap } from '@jridgewell/trace-mapping';\nimport type { SourceSnippet } from '../types.js';\nimport {\n getParsedMap,\n setParsedMap,\n getRawMapBackend,\n} from './cache.js';\n\nexport interface SourceMapResolverOptions {\n filePath: string;\n line: number;\n context?: number;\n fetcher?: typeof fetch;\n}\n\n/** Discovers candidate .map URLs from the document's loaded scripts. */\nfunction candidateMapUrls(): string[] {\n if (typeof document === 'undefined') return [];\n const urls: string[] = [];\n for (const script of Array.from(document.querySelectorAll<HTMLScriptElement>('script[src]'))) {\n const src = script.src;\n if (!src) continue;\n if (src.endsWith('.map')) {\n urls.push(src);\n continue;\n }\n if (src.includes('.js')) {\n urls.push(`${src}.map`);\n }\n }\n return urls;\n}\n\nasync function fetchRawMap(\n mapUrl: string,\n fetcher: typeof fetch,\n): Promise<string | null> {\n const cache = getRawMapBackend();\n const cached = await cache.get(mapUrl);\n if (cached === 'not-found') return null;\n if (typeof cached === 'string') return cached;\n try {\n const res = await fetcher(mapUrl);\n if (!res.ok) {\n await cache.setNotFound(mapUrl);\n return null;\n }\n const text = await res.text();\n await cache.set(mapUrl, text);\n return text;\n } catch {\n await cache.setNotFound(mapUrl);\n return null;\n }\n}\n\nfunction getOrParse(mapUrl: string, raw: string): TraceMap {\n const cached = getParsedMap(mapUrl);\n if (cached) return cached as TraceMap;\n const parsed = new TraceMap(raw);\n setParsedMap(mapUrl, parsed);\n return parsed;\n}\n\nfunction matchSourceIndex(sources: ReadonlyArray<string | null>, target: string): number {\n const normalize = (p: string): string => p.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n const normalizedTarget = normalize(target);\n const tail = normalizedTarget.split('/').slice(-3).join('/');\n for (let i = 0; i < sources.length; i++) {\n const s = sources[i];\n if (!s) continue;\n const ns = normalize(s);\n if (ns === normalizedTarget) return i;\n if (ns.endsWith(tail)) return i;\n }\n return -1;\n}\n\nexport async function resolveFromSourceMap(\n opts: SourceMapResolverOptions,\n): Promise<SourceSnippet | null> {\n const fetcher = opts.fetcher ?? fetch;\n const context = opts.context ?? 5;\n\n for (const mapUrl of candidateMapUrls()) {\n const raw = await fetchRawMap(mapUrl, fetcher);\n if (!raw) continue;\n let map: TraceMap;\n try {\n map = getOrParse(mapUrl, raw);\n } catch {\n continue;\n }\n const sources = map.sources ?? [];\n const idx = matchSourceIndex(sources, opts.filePath);\n if (idx === -1) continue;\n\n const sourcesContent = map.sourcesContent ?? [];\n const content = sourcesContent[idx];\n if (!content) continue;\n\n const allLines = content.split('\\n');\n if (opts.line < 1 || opts.line > allLines.length) continue;\n\n const startLine = Math.max(1, opts.line - context);\n const endLine = Math.min(allLines.length, opts.line + context);\n const lines = allLines.slice(startLine - 1, endLine);\n const ext = (opts.filePath.split('.').pop() ?? '').toLowerCase();\n return {\n startLine,\n endLine,\n targetLine: opts.line,\n lines,\n language: ext || 'text',\n source: 'sourcemap',\n };\n }\n\n return null;\n}\n","// Per-tab capability probe. Runs in the page's main world (or content-script\n// world — works in either because it only touches the DOM and `fetch`) and\n// posts the result via `window.postMessage` so the Chrome extension's content\n// script can forward it to the background.\n//\n// The background script uses the result to pick the correct toolbar icon\n// (greyscale vs color) and badge text (\"OFF\" / \"ON\" / \"DEV\" / \"MAP\" / \"AI\").\n\nimport type { PageCapabilities } from '../types.js';\n\nconst PROBE_THROTTLE_MS = 500;\nconst PROBE_TIMEOUT_MS = 1000;\nexport const INSPEKT_CAPABILITIES_MESSAGE = 'inspekt:capabilities';\n\nexport interface ProbeContext {\n /** When set, used as the URL prefix for the dev-server `/capabilities` ping. */\n serverUrl?: string;\n /** When set, used as the URL prefix for the daemon `/daemon` ping (Phase 3+). */\n daemonUrl?: string;\n /**\n * When true, source-map fallback is enabled. The probe will set\n * snippetSource='sourcemap' even if the dev server is unreachable, as long\n * as the page has at least one .map-bearing script.\n */\n sourceMapEnabled?: boolean;\n /** Custom fetcher (injectable for tests). */\n fetcher?: typeof fetch;\n /** When set, posts the probe result via this callback instead of postMessage. */\n onResult?: (caps: PageCapabilities) => void;\n}\n\nasync function pingHead(url: string, fetcher: typeof fetch): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), PROBE_TIMEOUT_MS);\n try {\n const res = await fetcher(url, { method: 'HEAD', signal: controller.signal });\n return res.ok;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction hasInstrumentation(): boolean {\n // Either a build-time attribute (multi-framework) or React fiber on the root\n // (zero-config React/Preact). Cheap synchronous check first.\n if (document.querySelector('[data-insp-path]')) return true;\n // Detecting React fiber here without importing bippy is unreliable; the\n // resolveElementSource() path will do it on actual element clicks. For the\n // probe we only flag instrumented when the static signal is present.\n return false;\n}\n\nfunction detectSourceMapHint(): boolean {\n // Cheap heuristic: at least one <script src=...> that returns the\n // `SourceMap` header or whose response ends with the `sourceMappingURL`\n // comment. We can't fetch every script body in the probe, so we look at\n // the document head for `<script>` tags whose URLs end with `.map` or\n // adjacent declarations. Conservative — Phase 5's resolver does the real\n // lookup on demand.\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const s of Array.from(scripts).slice(0, 5)) {\n if (s.src.endsWith('.map')) return true;\n }\n return false;\n}\n\nexport async function probeCapabilities(ctx: ProbeContext = {}): Promise<PageCapabilities> {\n const fetcher = ctx.fetcher ?? fetch;\n const instrumented = hasInstrumentation();\n const sourceMapAvailable = detectSourceMapHint();\n\n const serverReachable = ctx.serverUrl\n ? await pingHead(new URL('/__inspekt/capabilities', ctx.serverUrl).toString(), fetcher)\n : false;\n\n const agentConnected = ctx.daemonUrl\n ? await pingHead(new URL('/__inspekt/daemon', ctx.daemonUrl).toString(), fetcher)\n : false;\n\n // Only claim sourcemap as the snippet source when the user has explicitly\n // opted in — otherwise the icon would imply we'll fetch .map files when in\n // fact we won't.\n const snippetSource: PageCapabilities['snippetSource'] = serverReachable\n ? 'devserver'\n : ctx.sourceMapEnabled && sourceMapAvailable\n ? 'sourcemap'\n : null;\n\n return {\n instrumented,\n snippetSource,\n serverReachable,\n sourceMapAvailable,\n agentConnected,\n };\n}\n\n/**\n * Publishes the probe result via `window.postMessage` so a Chrome extension\n * content script can forward it to the background. The message envelope is\n * stable and namespaced under `inspekt:capabilities`.\n */\nexport function publishCapabilities(caps: PageCapabilities, ctx: ProbeContext = {}): void {\n if (ctx.onResult) {\n ctx.onResult(caps);\n return;\n }\n window.postMessage(\n { source: 'inspekt', type: INSPEKT_CAPABILITIES_MESSAGE, payload: caps },\n '*',\n );\n}\n\n/**\n * Installs a MutationObserver that re-probes when `data-insp-path` attributes\n * appear/disappear from the document. Returns a teardown function.\n */\nexport function watchCapabilities(ctx: ProbeContext = {}): () => void {\n let pending = false;\n let lastPub = 0;\n\n const fire = async () => {\n if (pending) return;\n pending = true;\n try {\n const caps = await probeCapabilities(ctx);\n publishCapabilities(caps, ctx);\n lastPub = Date.now();\n } finally {\n pending = false;\n }\n };\n\n const schedule = () => {\n const elapsed = Date.now() - lastPub;\n if (elapsed >= PROBE_THROTTLE_MS) {\n void fire();\n } else {\n setTimeout(fire, PROBE_THROTTLE_MS - elapsed);\n }\n };\n\n // Initial probe.\n void fire();\n\n const observer = new MutationObserver((muts) => {\n for (const m of muts) {\n if (m.type === 'attributes' && m.attributeName === 'data-insp-path') {\n schedule();\n return;\n }\n if (m.type === 'childList' && (m.addedNodes.length || m.removedNodes.length)) {\n // Fast-path: only re-probe when an element we care about appeared.\n const added = Array.from(m.addedNodes).some(\n (n) => n instanceof Element && n.querySelector?.('[data-insp-path]'),\n );\n if (added) {\n schedule();\n return;\n }\n }\n }\n });\n observer.observe(document.documentElement, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: ['data-insp-path'],\n });\n\n return () => observer.disconnect();\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","// 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"],"mappings":"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A;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;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;AAAA;AAA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","names":["cache","parsed","Prism","parsed","getComponentName","getProps","import_dom","target","result","watchCapabilities"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InspektOptions, InspektInstance, InspektAction, InspektEventMap, InspectedElement } from './types.js';
|
|
2
|
+
export type { ComponentNode } from './adapters/index.js';
|
|
3
|
+
export type { InspektOptions, InspektInstance, InspektAction, InspektEventMap, InspectedElement, };
|
|
4
|
+
export type { ShortcutConfig, HighlightConfig, BadgeConfig, TreePanelConfig } from './types.js';
|
|
5
|
+
export { attachTooltip } from './components/tooltip.js';
|
|
6
|
+
export type { TooltipOptions } from './components/tooltip.js';
|
|
7
|
+
export { createRichSelect } from './components/rich-select.js';
|
|
8
|
+
export type { RichSelectItem, RichSelectController, RichSelectOptions } from './components/rich-select.js';
|
|
9
|
+
export { tokenizeToLines } from './highlight/prism.js';
|
|
10
|
+
export type { CodeToken, CodeLine } from './highlight/prism.js';
|
|
11
|
+
export declare function createInspekt(userOptions?: Partial<InspektOptions>): InspektInstance;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,aAAa,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAgBpB,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EACV,cAAc,EACd,eAAe,EACf,aAAa,EACb,eAAe,EACf,gBAAgB,GACjB,CAAC;AACF,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGhG,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAyChE,wBAAgB,aAAa,CAAC,WAAW,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,eAAe,CAkbxF"}
|