@agent-native/pinpoint 0.1.30 → 0.1.31-nightly-20260828023009

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.
@@ -419,7 +419,7 @@ function freezeMedia() {
419
419
  return () => {
420
420
  playing.forEach((media) => {
421
421
  try {
422
- media.play();
422
+ void media.play();
423
423
  } catch {
424
424
  }
425
425
  });
@@ -566,4 +566,4 @@ export {
566
566
  isFreezeActive,
567
567
  openFile
568
568
  };
569
- //# sourceMappingURL=chunk-PAXU7A5W.js.map
569
+ //# sourceMappingURL=chunk-7ZNIF5SV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storage/memory-store.ts","../src/detection/selector-builder.ts","../src/detection/element-info.ts","../src/frameworks/adapter.ts","../src/freeze/css-freeze.ts","../src/freeze/js-freeze.ts","../src/freeze/media-freeze.ts","../src/freeze/react-freeze.ts","../src/freeze/waapi-freeze.ts","../src/freeze/controller.ts","../src/utils/open-file.ts"],"sourcesContent":["// @agent-native/pinpoint — In-memory storage adapter\n// MIT License\n//\n// Used for standalone/clipboard-only mode. Pins live in memory for\n// the current session. NOT localStorage (violates agent-native Rule 1).\n// Pins are lost on page reload — intentional. Connect to a server for persistence.\n\nimport type { Pin, PinStatus, PinStorage } from \"../types/index.js\";\n\nexport class MemoryStore implements PinStorage {\n private pins: Map<string, Pin> = new Map();\n\n async load(pageUrl: string): Promise<Pin[]> {\n return Array.from(this.pins.values()).filter(\n (pin) => pin.pageUrl === pageUrl,\n );\n }\n\n async save(pin: Pin): Promise<void> {\n this.pins.set(pin.id, { ...pin });\n }\n\n async update(id: string, patch: Partial<Pin>): Promise<void> {\n const existing = this.pins.get(id);\n if (!existing) return;\n this.pins.set(id, {\n ...existing,\n ...patch,\n id: existing.id, // never overwrite ID\n updatedAt: new Date().toISOString(),\n });\n }\n\n async delete(id: string): Promise<void> {\n this.pins.delete(id);\n }\n\n async list(filter?: {\n pageUrl?: string;\n status?: PinStatus;\n }): Promise<Pin[]> {\n let result = Array.from(this.pins.values());\n if (filter?.pageUrl) {\n result = result.filter((pin) => pin.pageUrl === filter.pageUrl);\n }\n if (filter?.status) {\n result = result.filter((pin) => pin.status.state === filter.status);\n }\n return result;\n }\n\n async clear(pageUrl?: string): Promise<void> {\n if (pageUrl) {\n for (const [id, pin] of this.pins) {\n if (pin.pageUrl === pageUrl) {\n this.pins.delete(id);\n }\n }\n } else {\n this.pins.clear();\n }\n }\n}\n","// @agent-native/pinpoint — CSS selector generation using @medv/finder\n// MIT License\n\nimport { finder } from \"@medv/finder\";\n\nexport interface SelectorOptions {\n /** Timeout for selector generation (ms) */\n timeoutMs?: number;\n /** Additional class names to skip */\n skipClassPatterns?: RegExp[];\n}\n\nconst DEFAULT_SKIP_CLASSES = [\n /^css-/, // CSS-in-JS (Emotion, etc.)\n /^_/, // CSS Modules hashes\n /^sc-/, // styled-components\n /^go\\d/, // Goober\n /^tw-/, // Tailwind utilities (sometimes hashed)\n /^chakra-/, // Chakra UI internals\n];\n\nconst DEFAULT_SKIP_IDS = [\n /^:r[0-9]/, // React auto-generated IDs\n /^radix-/, // Radix UI auto IDs\n /^headlessui-/, // HeadlessUI auto IDs\n];\n\n/**\n * Generate a unique, human-readable CSS selector for an element.\n * Uses @medv/finder (MIT) with configuration to skip CSS-in-JS hashes.\n */\nexport function buildSelector(\n element: Element,\n options: SelectorOptions = {},\n): string {\n const { timeoutMs = 200, skipClassPatterns = [] } = options;\n\n const allSkipClasses = [...DEFAULT_SKIP_CLASSES, ...skipClassPatterns];\n\n try {\n return finder(element, {\n className: (name: string) =>\n !allSkipClasses.some((pattern) => pattern.test(name)),\n idName: (name: string) =>\n !DEFAULT_SKIP_IDS.some((pattern) => pattern.test(name)),\n attr: (name: string) =>\n name.startsWith(\"data-testid\") || name.startsWith(\"data-cy\"),\n timeoutMs,\n });\n } catch {\n // Fallback: build a basic selector from tag + classes\n return buildFallbackSelector(element);\n }\n}\n\nfunction buildFallbackSelector(element: Element): string {\n const parts: string[] = [];\n\n if (element.id) {\n return `#${CSS.escape(element.id)}`;\n }\n\n parts.push(element.tagName.toLowerCase());\n\n // Use data-testid if available\n const testId = element.getAttribute(\"data-testid\");\n if (testId) {\n return `[data-testid=\"${CSS.escape(testId)}\"]`;\n }\n\n // Add meaningful class names\n const classes = Array.from(element.classList).filter(\n (name) => !DEFAULT_SKIP_CLASSES.some((pattern) => pattern.test(name)),\n );\n if (classes.length > 0) {\n parts.push(`.${classes.map((c) => CSS.escape(c)).join(\".\")}`);\n }\n\n // Add nth-child for uniqueness\n const parent = element.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (child) => child.tagName === element.tagName,\n );\n if (siblings.length > 1) {\n const index = siblings.indexOf(element) + 1;\n parts.push(`:nth-child(${index})`);\n }\n }\n\n return parts.join(\"\");\n}\n","// @agent-native/pinpoint — Element metadata extraction\n// MIT License\n\nimport type {\n ElementInfo,\n ElementContext,\n FrameworkInfo,\n} from \"../types/index.js\";\nimport { buildSelector } from \"./selector-builder.js\";\n\n/** Relevant computed style properties to capture */\nconst STYLE_KEYS = [\n \"color\",\n \"backgroundColor\",\n \"fontSize\",\n \"fontFamily\",\n \"fontWeight\",\n \"lineHeight\",\n \"padding\",\n \"margin\",\n \"border\",\n \"borderRadius\",\n \"display\",\n \"position\",\n \"width\",\n \"height\",\n \"opacity\",\n \"zIndex\",\n \"overflow\",\n \"textAlign\",\n \"textDecoration\",\n] as const;\n\n/**\n * Extract comprehensive metadata from a DOM element.\n */\nexport function extractElementInfo(element: Element): ElementInfo {\n const rect = element.getBoundingClientRect();\n const computed = window.getComputedStyle(element);\n\n // Extract computed styles (relevant subset)\n const computedStyles: Record<string, string> = {};\n for (const key of STYLE_KEYS) {\n const value = computed.getPropertyValue(\n key.replace(/([A-Z])/g, \"-$1\").toLowerCase(),\n );\n if (value) {\n computedStyles[key] = value;\n }\n }\n\n // Extract ARIA attributes\n const ariaAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"aria-\") || attr.name === \"role\") {\n ariaAttributes[attr.name] = attr.value;\n }\n }\n\n // Extract data attributes\n const dataAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"data-\")) {\n dataAttributes[attr.name] = attr.value;\n }\n }\n\n // Build DOM path\n const domPath = buildDomPath(element);\n\n // Get text content (truncated)\n const textContent = getTextContent(element);\n\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || undefined,\n classNames: Array.from(element.classList),\n selector: buildSelector(element),\n textContent,\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n computedStyles,\n ariaAttributes:\n Object.keys(ariaAttributes).length > 0 ? ariaAttributes : undefined,\n dataAttributes:\n Object.keys(dataAttributes).length > 0 ? dataAttributes : undefined,\n domPath,\n };\n}\n\n/**\n * Build a full ElementContext including HTML snippet and framework info.\n */\nexport function buildElementContext(\n element: Element,\n frameworkInfo?: FrameworkInfo,\n): ElementContext {\n const info = extractElementInfo(element);\n const htmlSnippet = getCleanedHtml(element);\n\n return {\n element: info,\n framework: frameworkInfo,\n htmlSnippet,\n cssSelector: info.selector,\n computedStyles: info.computedStyles || {},\n };\n}\n\n/**\n * Get text content of an element, truncated to 200 characters.\n * Only includes direct text nodes, not deeply nested text.\n */\nfunction getTextContent(element: Element): string | undefined {\n // Get direct text content only (not children's text)\n let text = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent?.trim() || \"\";\n }\n }\n\n // Fallback to full textContent if no direct text\n if (!text) {\n text = element.textContent?.trim() || \"\";\n }\n\n if (!text) return undefined;\n return text.length > 200 ? text.slice(0, 200) + \"...\" : text;\n}\n\n/**\n * Build a DOM path string like: html > body > div#root > main > section.hero\n */\nfunction buildDomPath(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current !== document.documentElement) {\n let part = current.tagName.toLowerCase();\n if (current.id) {\n part += `#${current.id}`;\n } else if (current.classList.length > 0) {\n const firstClass = current.classList[0];\n if (firstClass && !/^(css-|_|sc-)/.test(firstClass)) {\n part += `.${firstClass}`;\n }\n }\n parts.unshift(part);\n current = current.parentElement;\n }\n\n return parts.join(\" > \");\n}\n\n/**\n * Get a cleaned HTML snippet of an element.\n * Removes inline event handlers and excessive whitespace.\n */\nfunction getCleanedHtml(element: Element, maxLength = 500): string {\n const clone = element.cloneNode(true) as Element;\n\n // Remove event handler attributes\n const allElements = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\n for (const el of allElements) {\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) {\n el.removeAttribute(attr.name);\n }\n }\n }\n\n let html = clone.outerHTML;\n // Collapse whitespace\n html = html.replace(/\\s+/g, \" \").trim();\n\n if (html.length > maxLength) {\n // Truncate but keep the opening tag intact\n const openTagEnd = html.indexOf(\">\") + 1;\n if (openTagEnd > 0 && openTagEnd < maxLength) {\n html = html.slice(0, maxLength) + \"...\";\n }\n }\n\n return html;\n}\n","// @agent-native/pinpoint — Framework adapter interface and auto-detection\n// MIT License\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\n/** Registry of framework adapters, tried in order */\nconst adapters: FrameworkAdapter[] = [];\n\n/** The currently detected adapter (cached after first detection) */\nlet detectedAdapter: FrameworkAdapter | null = null;\nlet detected = false;\n\n/**\n * Register a framework adapter. Adapters are tried in registration order.\n */\nexport function registerAdapter(adapter: FrameworkAdapter): void {\n adapters.push(adapter);\n // Reset detection cache when new adapters are registered\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Auto-detect the current framework by trying each adapter's detect() method.\n * Returns the first matching adapter, or the generic fallback.\n */\nexport function detectFramework(): FrameworkAdapter {\n if (detected && detectedAdapter) return detectedAdapter;\n\n for (const adapter of adapters) {\n try {\n if (adapter.detect()) {\n detectedAdapter = adapter;\n detected = true;\n return adapter;\n }\n } catch {\n // Adapter detection failed, try next\n }\n }\n\n // Return generic adapter as fallback\n detectedAdapter = genericAdapter;\n detected = true;\n return genericAdapter;\n}\n\n/**\n * Get component info for an element using the detected framework adapter.\n */\nexport function getComponentInfo(element: Element): ComponentInfo | null {\n const adapter = detectFramework();\n try {\n return adapter.getComponentInfo(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Get source location for an element using the detected framework adapter.\n */\nexport function getSourceLocation(element: Element): SourceLocation | null {\n const adapter = detectFramework();\n try {\n return adapter.getSourceLocation(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Reset detection cache. Useful for testing or when the page framework changes.\n */\nexport function resetDetection(): void {\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Get all registered adapters.\n */\nexport function getAdapters(): FrameworkAdapter[] {\n return [...adapters];\n}\n\n/** Generic fallback adapter for non-framework pages */\nconst genericAdapter: FrameworkAdapter = {\n name: \"generic\",\n detect: () => true, // Always matches as fallback\n getComponentInfo: () => null,\n getSourceLocation: () => null,\n};\n","// @agent-native/pinpoint — CSS animation freezing\n// MIT License\n\nconst FREEZE_STYLE_ID = \"__pinpoint-css-freeze\";\n\n/**\n * Freeze all CSS animations and transitions on the page.\n * Returns a cleanup function to restore.\n */\nexport function freezeCSS(): () => void {\n if (document.getElementById(FREEZE_STYLE_ID)) {\n return () => {}; // Already frozen\n }\n\n const style = document.createElement(\"style\");\n style.id = FREEZE_STYLE_ID;\n style.textContent = `*, *::before, *::after {\n animation-play-state: paused !important;\n transition-property: none !important;\n }`;\n document.head.appendChild(style);\n\n return () => {\n style.remove();\n };\n}\n","// @agent-native/pinpoint — JS timer monkey-patching (opt-in)\n// MIT License\n//\n// Opt-in: disabled by default, activated via options.freezeJSTimers: true\n// Bounded queue (max 1000), staggered replay, Symbol-based exclusion.\n\nconst PINPOINT_SYMBOL = Symbol.for(\"pinpoint-internal\");\nconst MAX_QUEUE = 1000;\n\ninterface QueuedTimer {\n type: \"timeout\" | \"interval\" | \"raf\";\n callback: Function;\n delay?: number;\n args?: any[];\n}\n\nlet frozen = false;\nlet queue: QueuedTimer[] = [];\nlet originals: {\n setTimeout: typeof setTimeout;\n setInterval: typeof setInterval;\n clearTimeout: typeof clearTimeout;\n clearInterval: typeof clearInterval;\n requestAnimationFrame: typeof requestAnimationFrame;\n} | null = null;\n\n/**\n * Freeze JS timers by monkey-patching setTimeout, setInterval, rAF.\n * Queued callbacks are replayed on unfreeze.\n *\n * **Opt-in only** — call this explicitly when config.freezeJSTimers is true.\n */\nexport function freezeJSTimers(): () => void {\n if (frozen) return () => {};\n\n frozen = true;\n queue = [];\n\n originals = {\n setTimeout: window.setTimeout.bind(window),\n setInterval: window.setInterval.bind(window),\n clearTimeout: window.clearTimeout.bind(window),\n clearInterval: window.clearInterval.bind(window),\n requestAnimationFrame: window.requestAnimationFrame.bind(window),\n };\n\n // Patch setTimeout\n (window as any).setTimeout = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n // Skip our own callbacks (Symbol-based filter)\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setTimeout(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"timeout\", callback, delay, args });\n }\n return 0; // Return fake timer ID\n };\n\n // Patch setInterval\n (window as any).setInterval = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setInterval(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"interval\", callback, delay, args });\n }\n return 0;\n };\n\n // Patch requestAnimationFrame\n (window as any).requestAnimationFrame = (callback: FrameRequestCallback) => {\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.requestAnimationFrame(callback);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"raf\", callback });\n }\n return 0;\n };\n\n return () => {\n if (!frozen || !originals) return;\n frozen = false;\n\n // Restore originals\n window.setTimeout = originals.setTimeout as any;\n window.setInterval = originals.setInterval as any;\n window.clearTimeout = originals.clearTimeout;\n window.clearInterval = originals.clearInterval;\n window.requestAnimationFrame = originals.requestAnimationFrame;\n\n // Staggered replay via requestIdleCallback\n const replayBatch = () => {\n const batch = queue.splice(0, 50);\n for (const item of batch) {\n try {\n if (item.type === \"raf\") {\n originals!.requestAnimationFrame(\n item.callback as FrameRequestCallback,\n );\n } else {\n originals!.setTimeout(\n item.callback as any,\n 0,\n ...(item.args || []),\n );\n }\n } catch {\n // Callback may no longer be valid\n }\n }\n if (queue.length > 0) {\n (window.requestIdleCallback || originals!.setTimeout)(replayBatch);\n }\n };\n\n if (queue.length > 0) {\n (window.requestIdleCallback || originals.setTimeout)(replayBatch);\n }\n\n originals = null;\n };\n}\n\n/**\n * Mark a callback as internal to Pinpoint, so it's not frozen.\n */\nexport function markInternal<T extends Function>(fn: T): T {\n (fn as any)[PINPOINT_SYMBOL] = true;\n return fn;\n}\n","// @agent-native/pinpoint — Media element freeze (video, audio, SVG SMIL)\n// MIT License\n\n/**\n * Pause all playing media elements on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeMedia(): () => void {\n const mediaElements = document.querySelectorAll(\"video, audio\");\n const playing: HTMLMediaElement[] = [];\n\n mediaElements.forEach((el) => {\n const media = el as HTMLMediaElement;\n if (!media.paused) {\n media.pause();\n playing.push(media);\n }\n });\n\n // Pause SVG SMIL animations\n const svgElements = document.querySelectorAll(\"svg\");\n const pausedSVGs: SVGSVGElement[] = [];\n svgElements.forEach((svg) => {\n if (typeof svg.pauseAnimations === \"function\") {\n try {\n svg.pauseAnimations();\n pausedSVGs.push(svg);\n } catch {\n // SVG may not support animation\n }\n }\n });\n\n return () => {\n playing.forEach((media) => {\n try {\n media.play();\n } catch {\n // Media may have been removed\n }\n });\n\n pausedSVGs.forEach((svg) => {\n try {\n svg.unpauseAnimations();\n } catch {\n // SVG may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — React update freezing\n// MIT License\n//\n// Patches React's dispatcher to queue state updates instead of applying them.\n// On unfreeze, flush queued updates. This prevents the host app from\n// re-rendering while the user is selecting an element.\n//\n// Based on react-grab pattern (MIT).\n\ninterface QueuedUpdate {\n fiber: any;\n queue: any;\n update: any;\n}\n\nlet frozen = false;\nlet originalDispatcher: any = null;\nlet queuedUpdates: QueuedUpdate[] = [];\n\nfunction getInternals(): any {\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) return null;\n\n // Get the first React renderer\n const renderers = hook.renderers;\n if (!renderers || renderers.size === 0) return null;\n\n const renderer = renderers.values().next().value;\n return renderer?.currentDispatcherRef || null;\n}\n\n/**\n * Freeze React state updates by patching the dispatcher.\n * Updates are queued and replayed on unfreeze.\n */\nexport function freezeReact(): () => void {\n if (frozen) return () => {};\n\n const internals = getInternals();\n if (!internals) return () => {};\n\n frozen = true;\n originalDispatcher = internals.current;\n queuedUpdates = [];\n\n // Create a proxy dispatcher that intercepts useState/useReducer\n const proxyDispatcher = new Proxy(originalDispatcher, {\n get(target, prop) {\n if (prop === \"useState\" || prop === \"useReducer\") {\n return (...args: any[]) => {\n const result = target[prop](...args);\n // Wrap the setter to queue updates\n if (Array.isArray(result) && typeof result[1] === \"function\") {\n const originalSetter = result[1];\n result[1] = (action: any) => {\n queuedUpdates.push({\n fiber: null,\n queue: null,\n update: { setter: originalSetter, action },\n });\n };\n }\n return result;\n };\n }\n return target[prop];\n },\n });\n\n internals.current = proxyDispatcher;\n\n return () => {\n if (!frozen) return;\n frozen = false;\n\n // Restore original dispatcher\n if (internals && originalDispatcher) {\n internals.current = originalDispatcher;\n }\n\n // Flush queued updates\n for (const { update } of queuedUpdates) {\n try {\n update.setter(update.action);\n } catch {\n // Update may no longer be valid\n }\n }\n\n queuedUpdates = [];\n originalDispatcher = null;\n };\n}\n\nexport function isReactFrozen(): boolean {\n return frozen;\n}\n","// @agent-native/pinpoint — Web Animations API freeze\n// MIT License\n\n/**\n * Pause all WAAPI animations on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeWAAPI(): () => void {\n const animations = document.getAnimations();\n const playing = animations.filter((a) => a.playState === \"running\");\n playing.forEach((a) => a.pause());\n\n return () => {\n playing.forEach((a) => {\n try {\n a.play();\n } catch {\n // Animation may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — Unified freeze controller\n// MIT License\n//\n// Lazy initialization — nothing is patched until first freeze() call.\n\nimport { freezeCSS } from \"./css-freeze.js\";\nimport { freezeJSTimers } from \"./js-freeze.js\";\nimport { freezeMedia } from \"./media-freeze.js\";\nimport { freezeReact } from \"./react-freeze.js\";\nimport { freezeWAAPI } from \"./waapi-freeze.js\";\n\nlet cleanups: Array<() => void> = [];\nlet active = false;\n\nexport interface FreezeOptions {\n /** Freeze JS timers (opt-in, disabled by default) */\n jsTimers?: boolean;\n}\n\n/**\n * Freeze all animations, transitions, React updates, and media.\n * Call unfreeze() to restore.\n */\nexport function freeze(\n _elements?: Element[],\n options: FreezeOptions = {},\n): void {\n if (active) return;\n active = true;\n\n cleanups = [freezeCSS(), freezeWAAPI(), freezeReact(), freezeMedia()];\n\n if (options.jsTimers) {\n cleanups.push(freezeJSTimers());\n }\n}\n\n/**\n * Unfreeze everything and restore normal behavior.\n */\nexport function unfreeze(): void {\n if (!active) return;\n active = false;\n\n for (const cleanup of cleanups) {\n try {\n cleanup();\n } catch {\n // Best-effort cleanup\n }\n }\n cleanups = [];\n}\n\n/**\n * Check if freeze is currently active.\n */\nexport function isFreezeActive(): boolean {\n return active;\n}\n","// @agent-native/pinpoint — Open file in editor\n// MIT License\n\n/**\n * Open a file in the user's editor. Tries vscode:// protocol first,\n * falls back to a fetch to /api/open-file.\n */\nexport async function openFile(\n filePath: string,\n lineNumber?: number,\n): Promise<void> {\n // Try VS Code protocol\n const vsCodeUrl = lineNumber\n ? `vscode://file/${filePath}:${lineNumber}`\n : `vscode://file/${filePath}`;\n\n try {\n window.open(vsCodeUrl, \"_blank\");\n return;\n } catch {\n // VS Code not available\n }\n\n // Fallback: POST to server endpoint\n try {\n await fetch(\"/api/open-file\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ filePath, lineNumber }),\n });\n } catch {\n // Server endpoint not available\n console.warn(\"[pinpoint] Could not open file:\", filePath);\n }\n}\n"],"mappings":"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","names":["frozen"]}
1
+ {"version":3,"sources":["../src/storage/memory-store.ts","../src/detection/selector-builder.ts","../src/detection/element-info.ts","../src/frameworks/adapter.ts","../src/freeze/css-freeze.ts","../src/freeze/js-freeze.ts","../src/freeze/media-freeze.ts","../src/freeze/react-freeze.ts","../src/freeze/waapi-freeze.ts","../src/freeze/controller.ts","../src/utils/open-file.ts"],"sourcesContent":["// @agent-native/pinpoint — In-memory storage adapter\n// MIT License\n//\n// Used for standalone/clipboard-only mode. Pins live in memory for\n// the current session. NOT localStorage (violates agent-native Rule 1).\n// Pins are lost on page reload — intentional. Connect to a server for persistence.\n\nimport type { Pin, PinStatus, PinStorage } from \"../types/index.js\";\n\nexport class MemoryStore implements PinStorage {\n private pins: Map<string, Pin> = new Map();\n\n async load(pageUrl: string): Promise<Pin[]> {\n return Array.from(this.pins.values()).filter(\n (pin) => pin.pageUrl === pageUrl,\n );\n }\n\n async save(pin: Pin): Promise<void> {\n this.pins.set(pin.id, { ...pin });\n }\n\n async update(id: string, patch: Partial<Pin>): Promise<void> {\n const existing = this.pins.get(id);\n if (!existing) return;\n this.pins.set(id, {\n ...existing,\n ...patch,\n id: existing.id, // never overwrite ID\n updatedAt: new Date().toISOString(),\n });\n }\n\n async delete(id: string): Promise<void> {\n this.pins.delete(id);\n }\n\n async list(filter?: {\n pageUrl?: string;\n status?: PinStatus;\n }): Promise<Pin[]> {\n let result = Array.from(this.pins.values());\n if (filter?.pageUrl) {\n result = result.filter((pin) => pin.pageUrl === filter.pageUrl);\n }\n if (filter?.status) {\n result = result.filter((pin) => pin.status.state === filter.status);\n }\n return result;\n }\n\n async clear(pageUrl?: string): Promise<void> {\n if (pageUrl) {\n for (const [id, pin] of this.pins) {\n if (pin.pageUrl === pageUrl) {\n this.pins.delete(id);\n }\n }\n } else {\n this.pins.clear();\n }\n }\n}\n","// @agent-native/pinpoint — CSS selector generation using @medv/finder\n// MIT License\n\nimport { finder } from \"@medv/finder\";\n\nexport interface SelectorOptions {\n /** Timeout for selector generation (ms) */\n timeoutMs?: number;\n /** Additional class names to skip */\n skipClassPatterns?: RegExp[];\n}\n\nconst DEFAULT_SKIP_CLASSES = [\n /^css-/, // CSS-in-JS (Emotion, etc.)\n /^_/, // CSS Modules hashes\n /^sc-/, // styled-components\n /^go\\d/, // Goober\n /^tw-/, // Tailwind utilities (sometimes hashed)\n /^chakra-/, // Chakra UI internals\n];\n\nconst DEFAULT_SKIP_IDS = [\n /^:r[0-9]/, // React auto-generated IDs\n /^radix-/, // Radix UI auto IDs\n /^headlessui-/, // HeadlessUI auto IDs\n];\n\n/**\n * Generate a unique, human-readable CSS selector for an element.\n * Uses @medv/finder (MIT) with configuration to skip CSS-in-JS hashes.\n */\nexport function buildSelector(\n element: Element,\n options: SelectorOptions = {},\n): string {\n const { timeoutMs = 200, skipClassPatterns = [] } = options;\n\n const allSkipClasses = [...DEFAULT_SKIP_CLASSES, ...skipClassPatterns];\n\n try {\n return finder(element, {\n className: (name: string) =>\n !allSkipClasses.some((pattern) => pattern.test(name)),\n idName: (name: string) =>\n !DEFAULT_SKIP_IDS.some((pattern) => pattern.test(name)),\n attr: (name: string) =>\n name.startsWith(\"data-testid\") || name.startsWith(\"data-cy\"),\n timeoutMs,\n });\n } catch {\n // Fallback: build a basic selector from tag + classes\n return buildFallbackSelector(element);\n }\n}\n\nfunction buildFallbackSelector(element: Element): string {\n const parts: string[] = [];\n\n if (element.id) {\n return `#${CSS.escape(element.id)}`;\n }\n\n parts.push(element.tagName.toLowerCase());\n\n // Use data-testid if available\n const testId = element.getAttribute(\"data-testid\");\n if (testId) {\n return `[data-testid=\"${CSS.escape(testId)}\"]`;\n }\n\n // Add meaningful class names\n const classes = Array.from(element.classList).filter(\n (name) => !DEFAULT_SKIP_CLASSES.some((pattern) => pattern.test(name)),\n );\n if (classes.length > 0) {\n parts.push(`.${classes.map((c) => CSS.escape(c)).join(\".\")}`);\n }\n\n // Add nth-child for uniqueness\n const parent = element.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (child) => child.tagName === element.tagName,\n );\n if (siblings.length > 1) {\n const index = siblings.indexOf(element) + 1;\n parts.push(`:nth-child(${index})`);\n }\n }\n\n return parts.join(\"\");\n}\n","// @agent-native/pinpoint — Element metadata extraction\n// MIT License\n\nimport type {\n ElementInfo,\n ElementContext,\n FrameworkInfo,\n} from \"../types/index.js\";\nimport { buildSelector } from \"./selector-builder.js\";\n\n/** Relevant computed style properties to capture */\nconst STYLE_KEYS = [\n \"color\",\n \"backgroundColor\",\n \"fontSize\",\n \"fontFamily\",\n \"fontWeight\",\n \"lineHeight\",\n \"padding\",\n \"margin\",\n \"border\",\n \"borderRadius\",\n \"display\",\n \"position\",\n \"width\",\n \"height\",\n \"opacity\",\n \"zIndex\",\n \"overflow\",\n \"textAlign\",\n \"textDecoration\",\n] as const;\n\n/**\n * Extract comprehensive metadata from a DOM element.\n */\nexport function extractElementInfo(element: Element): ElementInfo {\n const rect = element.getBoundingClientRect();\n const computed = window.getComputedStyle(element);\n\n // Extract computed styles (relevant subset)\n const computedStyles: Record<string, string> = {};\n for (const key of STYLE_KEYS) {\n const value = computed.getPropertyValue(\n key.replace(/([A-Z])/g, \"-$1\").toLowerCase(),\n );\n if (value) {\n computedStyles[key] = value;\n }\n }\n\n // Extract ARIA attributes\n const ariaAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"aria-\") || attr.name === \"role\") {\n ariaAttributes[attr.name] = attr.value;\n }\n }\n\n // Extract data attributes\n const dataAttributes: Record<string, string> = {};\n for (const attr of element.attributes) {\n if (attr.name.startsWith(\"data-\")) {\n dataAttributes[attr.name] = attr.value;\n }\n }\n\n // Build DOM path\n const domPath = buildDomPath(element);\n\n // Get text content (truncated)\n const textContent = getTextContent(element);\n\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || undefined,\n classNames: Array.from(element.classList),\n selector: buildSelector(element),\n textContent,\n boundingRect: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n computedStyles,\n ariaAttributes:\n Object.keys(ariaAttributes).length > 0 ? ariaAttributes : undefined,\n dataAttributes:\n Object.keys(dataAttributes).length > 0 ? dataAttributes : undefined,\n domPath,\n };\n}\n\n/**\n * Build a full ElementContext including HTML snippet and framework info.\n */\nexport function buildElementContext(\n element: Element,\n frameworkInfo?: FrameworkInfo,\n): ElementContext {\n const info = extractElementInfo(element);\n const htmlSnippet = getCleanedHtml(element);\n\n return {\n element: info,\n framework: frameworkInfo,\n htmlSnippet,\n cssSelector: info.selector,\n computedStyles: info.computedStyles || {},\n };\n}\n\n/**\n * Get text content of an element, truncated to 200 characters.\n * Only includes direct text nodes, not deeply nested text.\n */\nfunction getTextContent(element: Element): string | undefined {\n // Get direct text content only (not children's text)\n let text = \"\";\n for (const node of element.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent?.trim() || \"\";\n }\n }\n\n // Fallback to full textContent if no direct text\n if (!text) {\n text = element.textContent?.trim() || \"\";\n }\n\n if (!text) return undefined;\n return text.length > 200 ? text.slice(0, 200) + \"...\" : text;\n}\n\n/**\n * Build a DOM path string like: html > body > div#root > main > section.hero\n */\nfunction buildDomPath(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current !== document.documentElement) {\n let part = current.tagName.toLowerCase();\n if (current.id) {\n part += `#${current.id}`;\n } else if (current.classList.length > 0) {\n const firstClass = current.classList[0];\n if (firstClass && !/^(css-|_|sc-)/.test(firstClass)) {\n part += `.${firstClass}`;\n }\n }\n parts.unshift(part);\n current = current.parentElement;\n }\n\n return parts.join(\" > \");\n}\n\n/**\n * Get a cleaned HTML snippet of an element.\n * Removes inline event handlers and excessive whitespace.\n */\nfunction getCleanedHtml(element: Element, maxLength = 500): string {\n const clone = element.cloneNode(true) as Element;\n\n // Remove event handler attributes\n const allElements = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\n for (const el of allElements) {\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) {\n el.removeAttribute(attr.name);\n }\n }\n }\n\n let html = clone.outerHTML;\n // Collapse whitespace\n html = html.replace(/\\s+/g, \" \").trim();\n\n if (html.length > maxLength) {\n // Truncate but keep the opening tag intact\n const openTagEnd = html.indexOf(\">\") + 1;\n if (openTagEnd > 0 && openTagEnd < maxLength) {\n html = html.slice(0, maxLength) + \"...\";\n }\n }\n\n return html;\n}\n","// @agent-native/pinpoint — Framework adapter interface and auto-detection\n// MIT License\n\nimport type {\n FrameworkAdapter,\n ComponentInfo,\n SourceLocation,\n} from \"../types/index.js\";\n\n/** Registry of framework adapters, tried in order */\nconst adapters: FrameworkAdapter[] = [];\n\n/** The currently detected adapter (cached after first detection) */\nlet detectedAdapter: FrameworkAdapter | null = null;\nlet detected = false;\n\n/**\n * Register a framework adapter. Adapters are tried in registration order.\n */\nexport function registerAdapter(adapter: FrameworkAdapter): void {\n adapters.push(adapter);\n // Reset detection cache when new adapters are registered\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Auto-detect the current framework by trying each adapter's detect() method.\n * Returns the first matching adapter, or the generic fallback.\n */\nexport function detectFramework(): FrameworkAdapter {\n if (detected && detectedAdapter) return detectedAdapter;\n\n for (const adapter of adapters) {\n try {\n if (adapter.detect()) {\n detectedAdapter = adapter;\n detected = true;\n return adapter;\n }\n } catch {\n // Adapter detection failed, try next\n }\n }\n\n // Return generic adapter as fallback\n detectedAdapter = genericAdapter;\n detected = true;\n return genericAdapter;\n}\n\n/**\n * Get component info for an element using the detected framework adapter.\n */\nexport function getComponentInfo(element: Element): ComponentInfo | null {\n const adapter = detectFramework();\n try {\n return adapter.getComponentInfo(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Get source location for an element using the detected framework adapter.\n */\nexport function getSourceLocation(element: Element): SourceLocation | null {\n const adapter = detectFramework();\n try {\n return adapter.getSourceLocation(element);\n } catch {\n return null;\n }\n}\n\n/**\n * Reset detection cache. Useful for testing or when the page framework changes.\n */\nexport function resetDetection(): void {\n detected = false;\n detectedAdapter = null;\n}\n\n/**\n * Get all registered adapters.\n */\nexport function getAdapters(): FrameworkAdapter[] {\n return [...adapters];\n}\n\n/** Generic fallback adapter for non-framework pages */\nconst genericAdapter: FrameworkAdapter = {\n name: \"generic\",\n detect: () => true, // Always matches as fallback\n getComponentInfo: () => null,\n getSourceLocation: () => null,\n};\n","// @agent-native/pinpoint — CSS animation freezing\n// MIT License\n\nconst FREEZE_STYLE_ID = \"__pinpoint-css-freeze\";\n\n/**\n * Freeze all CSS animations and transitions on the page.\n * Returns a cleanup function to restore.\n */\nexport function freezeCSS(): () => void {\n if (document.getElementById(FREEZE_STYLE_ID)) {\n return () => {}; // Already frozen\n }\n\n const style = document.createElement(\"style\");\n style.id = FREEZE_STYLE_ID;\n style.textContent = `*, *::before, *::after {\n animation-play-state: paused !important;\n transition-property: none !important;\n }`;\n document.head.appendChild(style);\n\n return () => {\n style.remove();\n };\n}\n","// @agent-native/pinpoint — JS timer monkey-patching (opt-in)\n// MIT License\n//\n// Opt-in: disabled by default, activated via options.freezeJSTimers: true\n// Bounded queue (max 1000), staggered replay, Symbol-based exclusion.\n\nconst PINPOINT_SYMBOL = Symbol.for(\"pinpoint-internal\");\nconst MAX_QUEUE = 1000;\n\ninterface QueuedTimer {\n type: \"timeout\" | \"interval\" | \"raf\";\n callback: Function;\n delay?: number;\n args?: any[];\n}\n\nlet frozen = false;\nlet queue: QueuedTimer[] = [];\nlet originals: {\n setTimeout: typeof setTimeout;\n setInterval: typeof setInterval;\n clearTimeout: typeof clearTimeout;\n clearInterval: typeof clearInterval;\n requestAnimationFrame: typeof requestAnimationFrame;\n} | null = null;\n\n/**\n * Freeze JS timers by monkey-patching setTimeout, setInterval, rAF.\n * Queued callbacks are replayed on unfreeze.\n *\n * **Opt-in only** — call this explicitly when config.freezeJSTimers is true.\n */\nexport function freezeJSTimers(): () => void {\n if (frozen) return () => {};\n\n frozen = true;\n queue = [];\n\n originals = {\n setTimeout: window.setTimeout.bind(window),\n setInterval: window.setInterval.bind(window),\n clearTimeout: window.clearTimeout.bind(window),\n clearInterval: window.clearInterval.bind(window),\n requestAnimationFrame: window.requestAnimationFrame.bind(window),\n };\n\n // Patch setTimeout\n (window as any).setTimeout = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n // Skip our own callbacks (Symbol-based filter)\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setTimeout(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"timeout\", callback, delay, args });\n }\n return 0; // Return fake timer ID\n };\n\n // Patch setInterval\n (window as any).setInterval = (\n callback: Function | string,\n delay?: number,\n ...args: any[]\n ) => {\n if (typeof callback !== \"function\") return 0;\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.setInterval(callback, delay, ...args);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"interval\", callback, delay, args });\n }\n return 0;\n };\n\n // Patch requestAnimationFrame\n (window as any).requestAnimationFrame = (callback: FrameRequestCallback) => {\n if ((callback as any)[PINPOINT_SYMBOL]) {\n return originals!.requestAnimationFrame(callback);\n }\n if (queue.length < MAX_QUEUE) {\n queue.push({ type: \"raf\", callback });\n }\n return 0;\n };\n\n return () => {\n if (!frozen || !originals) return;\n frozen = false;\n\n // Restore originals\n window.setTimeout = originals.setTimeout as any;\n window.setInterval = originals.setInterval as any;\n window.clearTimeout = originals.clearTimeout;\n window.clearInterval = originals.clearInterval;\n window.requestAnimationFrame = originals.requestAnimationFrame;\n\n // Staggered replay via requestIdleCallback\n const replayBatch = () => {\n const batch = queue.splice(0, 50);\n for (const item of batch) {\n try {\n if (item.type === \"raf\") {\n originals!.requestAnimationFrame(\n item.callback as FrameRequestCallback,\n );\n } else {\n originals!.setTimeout(\n item.callback as any,\n 0,\n ...(item.args || []),\n );\n }\n } catch {\n // Callback may no longer be valid\n }\n }\n if (queue.length > 0) {\n (window.requestIdleCallback || originals!.setTimeout)(replayBatch);\n }\n };\n\n if (queue.length > 0) {\n (window.requestIdleCallback || originals.setTimeout)(replayBatch);\n }\n\n originals = null;\n };\n}\n\n/**\n * Mark a callback as internal to Pinpoint, so it's not frozen.\n */\nexport function markInternal<T extends Function>(fn: T): T {\n (fn as any)[PINPOINT_SYMBOL] = true;\n return fn;\n}\n","// @agent-native/pinpoint — Media element freeze (video, audio, SVG SMIL)\n// MIT License\n\n/**\n * Pause all playing media elements on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeMedia(): () => void {\n const mediaElements = document.querySelectorAll(\"video, audio\");\n const playing: HTMLMediaElement[] = [];\n\n mediaElements.forEach((el) => {\n const media = el as HTMLMediaElement;\n if (!media.paused) {\n media.pause();\n playing.push(media);\n }\n });\n\n // Pause SVG SMIL animations\n const svgElements = document.querySelectorAll(\"svg\");\n const pausedSVGs: SVGSVGElement[] = [];\n svgElements.forEach((svg) => {\n if (typeof svg.pauseAnimations === \"function\") {\n try {\n svg.pauseAnimations();\n pausedSVGs.push(svg);\n } catch {\n // SVG may not support animation\n }\n }\n });\n\n return () => {\n playing.forEach((media) => {\n try {\n void media.play();\n } catch {\n // Media may have been removed\n }\n });\n\n pausedSVGs.forEach((svg) => {\n try {\n svg.unpauseAnimations();\n } catch {\n // SVG may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — React update freezing\n// MIT License\n//\n// Patches React's dispatcher to queue state updates instead of applying them.\n// On unfreeze, flush queued updates. This prevents the host app from\n// re-rendering while the user is selecting an element.\n//\n// Based on react-grab pattern (MIT).\n\ninterface QueuedUpdate {\n fiber: any;\n queue: any;\n update: any;\n}\n\nlet frozen = false;\nlet originalDispatcher: any = null;\nlet queuedUpdates: QueuedUpdate[] = [];\n\nfunction getInternals(): any {\n const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) return null;\n\n // Get the first React renderer\n const renderers = hook.renderers;\n if (!renderers || renderers.size === 0) return null;\n\n const renderer = renderers.values().next().value;\n return renderer?.currentDispatcherRef || null;\n}\n\n/**\n * Freeze React state updates by patching the dispatcher.\n * Updates are queued and replayed on unfreeze.\n */\nexport function freezeReact(): () => void {\n if (frozen) return () => {};\n\n const internals = getInternals();\n if (!internals) return () => {};\n\n frozen = true;\n originalDispatcher = internals.current;\n queuedUpdates = [];\n\n // Create a proxy dispatcher that intercepts useState/useReducer\n const proxyDispatcher = new Proxy(originalDispatcher, {\n get(target, prop) {\n if (prop === \"useState\" || prop === \"useReducer\") {\n return (...args: any[]) => {\n const result = target[prop](...args);\n // Wrap the setter to queue updates\n if (Array.isArray(result) && typeof result[1] === \"function\") {\n const originalSetter = result[1];\n result[1] = (action: any) => {\n queuedUpdates.push({\n fiber: null,\n queue: null,\n update: { setter: originalSetter, action },\n });\n };\n }\n return result;\n };\n }\n return target[prop];\n },\n });\n\n internals.current = proxyDispatcher;\n\n return () => {\n if (!frozen) return;\n frozen = false;\n\n // Restore original dispatcher\n if (internals && originalDispatcher) {\n internals.current = originalDispatcher;\n }\n\n // Flush queued updates\n for (const { update } of queuedUpdates) {\n try {\n update.setter(update.action);\n } catch {\n // Update may no longer be valid\n }\n }\n\n queuedUpdates = [];\n originalDispatcher = null;\n };\n}\n\nexport function isReactFrozen(): boolean {\n return frozen;\n}\n","// @agent-native/pinpoint — Web Animations API freeze\n// MIT License\n\n/**\n * Pause all WAAPI animations on the page.\n * Returns a cleanup function to resume.\n */\nexport function freezeWAAPI(): () => void {\n const animations = document.getAnimations();\n const playing = animations.filter((a) => a.playState === \"running\");\n playing.forEach((a) => a.pause());\n\n return () => {\n playing.forEach((a) => {\n try {\n a.play();\n } catch {\n // Animation may have been removed\n }\n });\n };\n}\n","// @agent-native/pinpoint — Unified freeze controller\n// MIT License\n//\n// Lazy initialization — nothing is patched until first freeze() call.\n\nimport { freezeCSS } from \"./css-freeze.js\";\nimport { freezeJSTimers } from \"./js-freeze.js\";\nimport { freezeMedia } from \"./media-freeze.js\";\nimport { freezeReact } from \"./react-freeze.js\";\nimport { freezeWAAPI } from \"./waapi-freeze.js\";\n\nlet cleanups: Array<() => void> = [];\nlet active = false;\n\nexport interface FreezeOptions {\n /** Freeze JS timers (opt-in, disabled by default) */\n jsTimers?: boolean;\n}\n\n/**\n * Freeze all animations, transitions, React updates, and media.\n * Call unfreeze() to restore.\n */\nexport function freeze(\n _elements?: Element[],\n options: FreezeOptions = {},\n): void {\n if (active) return;\n active = true;\n\n cleanups = [freezeCSS(), freezeWAAPI(), freezeReact(), freezeMedia()];\n\n if (options.jsTimers) {\n cleanups.push(freezeJSTimers());\n }\n}\n\n/**\n * Unfreeze everything and restore normal behavior.\n */\nexport function unfreeze(): void {\n if (!active) return;\n active = false;\n\n for (const cleanup of cleanups) {\n try {\n cleanup();\n } catch {\n // Best-effort cleanup\n }\n }\n cleanups = [];\n}\n\n/**\n * Check if freeze is currently active.\n */\nexport function isFreezeActive(): boolean {\n return active;\n}\n","// @agent-native/pinpoint — Open file in editor\n// MIT License\n\n/**\n * Open a file in the user's editor. Tries vscode:// protocol first,\n * falls back to a fetch to /api/open-file.\n */\nexport async function openFile(\n filePath: string,\n lineNumber?: number,\n): Promise<void> {\n // Try VS Code protocol\n const vsCodeUrl = lineNumber\n ? `vscode://file/${filePath}:${lineNumber}`\n : `vscode://file/${filePath}`;\n\n try {\n window.open(vsCodeUrl, \"_blank\");\n return;\n } catch {\n // VS Code not available\n }\n\n // Fallback: POST to server endpoint\n try {\n await fetch(\"/api/open-file\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ filePath, lineNumber }),\n });\n } catch {\n // Server endpoint not available\n console.warn(\"[pinpoint] Could not open file:\", filePath);\n }\n}\n"],"mappings":"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","names":["frozen"]}
@@ -2120,7 +2120,7 @@ var icons = {
2120
2120
  // src/ui/components/ContextMenu.tsx
2121
2121
  var _tmpl$ = /* @__PURE__ */ template(`<div class=pp-context-menu><div class=pp-context-menu__item><span></span>Add Annotation</div><div class=pp-context-menu__item><span></span>Quick Prompt</div><div class=pp-context-menu__separator></div><div class=pp-context-menu__item><span></span>Copy Element Context</div><div class=pp-context-menu__item><span></span>Copy HTML Snippet</div><div class=pp-context-menu__item><span></span>Copy Computed Styles`);
2122
2122
  var ContextMenu = (props) => {
2123
- let menuRef;
2123
+ let menuRef = void 0;
2124
2124
  onMount(() => {
2125
2125
  const handleClick = (e) => {
2126
2126
  if (menuRef && !e.composedPath().includes(menuRef)) {
@@ -2187,7 +2187,7 @@ function lerp(start, end, t) {
2187
2187
  return start + (end - start) * t;
2188
2188
  }
2189
2189
  var OverlayCanvas = (props) => {
2190
- let canvasRef;
2190
+ let canvasRef = void 0;
2191
2191
  let animFrameId = null;
2192
2192
  let currentRect = {
2193
2193
  x: 0,
@@ -2451,7 +2451,7 @@ var PinPopup = (props) => {
2451
2451
  const {
2452
2452
  openFile
2453
2453
  } = await import("./open-file-RQVHOCXI.js");
2454
- openFile(file);
2454
+ void openFile(file);
2455
2455
  } catch {
2456
2456
  }
2457
2457
  }
@@ -2637,8 +2637,9 @@ var PinPopup = (props) => {
2637
2637
  })(), _el$2);
2638
2638
  addEventListener(_el$3, "keydown", handleKeyDown);
2639
2639
  addEventListener(_el$3, "input", handleAutoGrow);
2640
- var _ref$ = textareaRef;
2641
- typeof _ref$ === "function" ? use(_ref$, _el$3) : textareaRef = _el$3;
2640
+ use((element) => {
2641
+ textareaRef = element;
2642
+ }, _el$3);
2642
2643
  insert(_el$2, hasSpeechAPI && (() => {
2643
2644
  var _el$22 = _tmpl$7();
2644
2645
  addEventListener(_el$22, "click", toggleRecording);
@@ -2719,8 +2720,9 @@ var PromptMode = (props) => {
2719
2720
  if (e.key === "Escape") props.onCancel();
2720
2721
  };
2721
2722
  _el$2.$$input = (e) => setInstruction(e.currentTarget.value);
2722
- var _ref$ = inputRef;
2723
- typeof _ref$ === "function" ? use(_ref$, _el$2) : inputRef = _el$2;
2723
+ use((element) => {
2724
+ inputRef = element;
2725
+ }, _el$2);
2724
2726
  _el$3.$$click = handleSubmit;
2725
2727
  createRenderEffect(() => _el$4.innerHTML = icons.send);
2726
2728
  createRenderEffect(() => _el$2.value = instruction());
@@ -2777,8 +2779,9 @@ var TextInputPopup = (props) => {
2777
2779
  if (e.key === "Escape") props.onCancel();
2778
2780
  };
2779
2781
  _el$3.$$input = (e) => setText(e.currentTarget.value);
2780
- var _ref$ = inputRef;
2781
- typeof _ref$ === "function" ? use(_ref$, _el$3) : inputRef = _el$3;
2782
+ use((element) => {
2783
+ inputRef = element;
2784
+ }, _el$3);
2782
2785
  createRenderEffect((_$p) => setStyleProperty(_el$2, "background", props.color));
2783
2786
  createRenderEffect(() => _el$3.value = text());
2784
2787
  return _el$;
@@ -3439,17 +3442,17 @@ var PinpointApp = (props) => {
3439
3442
  if (!active()) return;
3440
3443
  if (mod && e.shiftKey && e.key === "C") {
3441
3444
  e.preventDefault();
3442
- copyPins();
3445
+ void copyPins();
3443
3446
  return;
3444
3447
  }
3445
3448
  if (mod && e.shiftKey && e.key === "Enter") {
3446
3449
  e.preventDefault();
3447
3450
  if (queue().length > 0) {
3448
- sendQueue();
3451
+ void sendQueue();
3449
3452
  } else if (selectedPinIds().size > 0) {
3450
- sendSelected();
3453
+ void sendSelected();
3451
3454
  } else {
3452
- sendPins();
3455
+ void sendPins();
3453
3456
  }
3454
3457
  return;
3455
3458
  }
@@ -3508,7 +3511,7 @@ var PinpointApp = (props) => {
3508
3511
  markerManager.setOnToggleSelect((pin) => togglePinSelect(pin));
3509
3512
  createEffect(() => {
3510
3513
  const pageUrl = window.location.pathname;
3511
- storage.load(pageUrl).then((loaded) => setPins(loaded));
3514
+ void storage.load(pageUrl).then((loaded) => setPins(loaded));
3512
3515
  });
3513
3516
  createEffect(() => {
3514
3517
  const currentPins = pins();
@@ -3745,7 +3748,7 @@ var PinpointApp = (props) => {
3745
3748
  }
3746
3749
  };
3747
3750
  setPins((prev) => [...prev, pin]);
3748
- storage.save(pin);
3751
+ void storage.save(pin);
3749
3752
  closePopup();
3750
3753
  return pin;
3751
3754
  }
@@ -3788,7 +3791,7 @@ var PinpointApp = (props) => {
3788
3791
  updatedAt: now
3789
3792
  };
3790
3793
  setPins((prev) => prev.map((p) => p.id === pin.id ? updated : p));
3791
- storage.update(pin.id, {
3794
+ void storage.update(pin.id, {
3792
3795
  comment,
3793
3796
  updatedAt: now
3794
3797
  });
@@ -3821,7 +3824,7 @@ var PinpointApp = (props) => {
3821
3824
  }
3822
3825
  function removePin(id) {
3823
3826
  setPins((prev) => prev.filter((p) => p.id !== id));
3824
- storage.delete(id);
3827
+ void storage.delete(id);
3825
3828
  setSelectedPinIds((prev) => {
3826
3829
  const next = new Set(prev);
3827
3830
  next.delete(id);
@@ -3830,7 +3833,7 @@ var PinpointApp = (props) => {
3830
3833
  }
3831
3834
  function clearPins() {
3832
3835
  const pageUrl = window.location.pathname;
3833
- storage.clear(pageUrl);
3836
+ void storage.clear(pageUrl);
3834
3837
  setPins([]);
3835
3838
  setSelectedPinIds(/* @__PURE__ */ new Set());
3836
3839
  }
@@ -4940,4 +4943,4 @@ export {
4940
4943
  mountPinpoint,
4941
4944
  unmountPinpoint
4942
4945
  };
4943
- //# sourceMappingURL=chunk-P4AZ2AAL.js.map
4946
+ //# sourceMappingURL=chunk-SMEGMREJ.js.map