@jami-studio/pinpoint 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.agents/skills/pinpoint/SKILL.md +77 -0
  2. package/README.md +412 -0
  3. package/dist/agent-context-HBCZ4MBN.js +13 -0
  4. package/dist/agent-context-HBCZ4MBN.js.map +1 -0
  5. package/dist/chunk-B7TY4FPP.js +569 -0
  6. package/dist/chunk-B7TY4FPP.js.map +1 -0
  7. package/dist/chunk-CGJZ7BOM.js +88 -0
  8. package/dist/chunk-CGJZ7BOM.js.map +1 -0
  9. package/dist/chunk-DGUM43GV.js +11 -0
  10. package/dist/chunk-DGUM43GV.js.map +1 -0
  11. package/dist/chunk-HAEYE6KB.js +25 -0
  12. package/dist/chunk-HAEYE6KB.js.map +1 -0
  13. package/dist/chunk-J5PXKVTM.js +53 -0
  14. package/dist/chunk-J5PXKVTM.js.map +1 -0
  15. package/dist/chunk-XBX2J7WU.js +94 -0
  16. package/dist/chunk-XBX2J7WU.js.map +1 -0
  17. package/dist/chunk-ZW7IO3EW.js +4927 -0
  18. package/dist/chunk-ZW7IO3EW.js.map +1 -0
  19. package/dist/cli.js +71 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/formatter-CR4COA5Z.js +8 -0
  22. package/dist/formatter-CR4COA5Z.js.map +1 -0
  23. package/dist/index-NvFcZ4SO.d.ts +200 -0
  24. package/dist/index.browser.d.ts +377 -0
  25. package/dist/index.browser.js +620 -0
  26. package/dist/index.browser.js.map +1 -0
  27. package/dist/index.js +936 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/open-file-WR2JHI4P.js +8 -0
  30. package/dist/open-file-WR2JHI4P.js.map +1 -0
  31. package/dist/primitives/index.js +28 -0
  32. package/dist/primitives/index.js.map +1 -0
  33. package/dist/react.d.ts +23 -0
  34. package/dist/react.js +20 -0
  35. package/dist/react.js.map +1 -0
  36. package/dist/server/index.js +457 -0
  37. package/dist/server/index.js.map +1 -0
  38. package/dist/types/index.js +1 -0
  39. package/dist/types/index.js.map +1 -0
  40. package/package.json +88 -0
  41. package/src/scripts/create-pin.ts +43 -0
  42. package/src/scripts/delete-pin.ts +16 -0
  43. package/src/scripts/get-pins.ts +36 -0
  44. package/src/scripts/list-sessions.ts +33 -0
  45. package/src/scripts/resolve-pin.ts +27 -0
  46. package/src/scripts/run.ts +8 -0
  47. package/src/scripts/update-pin.ts +32 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/rest-client.ts","../src/detection/element-picker.ts","../src/detection/drag-select.ts","../src/detection/text-select.ts","../src/frameworks/react-adapter.ts","../src/frameworks/vue-adapter.ts","../src/frameworks/generic-adapter.ts","../src/output/formatter.ts","../src/output/agent-context.ts","../src/plugins/registry.ts","../src/plugins/agent-native-plugin.ts","../src/security/input-sanitization.ts","../src/security/origin-validation.ts"],"sourcesContent":["// @agent-native/pinpoint — Browser-side REST client storage adapter\r\n// MIT License\r\n//\r\n// The browser never writes files directly — it always goes through the server.\r\n// This is the default adapter when a server endpoint is available.\r\n\r\nimport type { Pin, PinStatus, PinStorage } from \"../types/index.js\";\r\nimport { PinSchema } from \"./schemas.js\";\r\n\r\nexport class RestClient implements PinStorage {\r\n constructor(private endpoint: string) {\r\n // Normalize: remove trailing slash\r\n this.endpoint = endpoint.replace(/\\/+$/, \"\");\r\n }\r\n\r\n async load(pageUrl: string): Promise<Pin[]> {\r\n const params = new URLSearchParams({ pageUrl });\r\n const res = await fetch(`${this.endpoint}?${params}`);\r\n if (!res.ok) return [];\r\n const data = await res.json();\r\n return Array.isArray(data)\r\n ? data.filter((item) => PinSchema.safeParse(item).success)\r\n : [];\r\n }\r\n\r\n async save(pin: Pin): Promise<void> {\r\n const res = await fetch(this.endpoint, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify(pin),\r\n });\r\n if (!res.ok) throw new Error(`Failed to save pin: ${res.status}`);\r\n }\r\n\r\n async update(id: string, patch: Partial<Pin>): Promise<void> {\r\n const res = await fetch(`${this.endpoint}/${encodeURIComponent(id)}`, {\r\n method: \"PATCH\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify(patch),\r\n });\r\n if (!res.ok) throw new Error(`Failed to update pin: ${res.status}`);\r\n }\r\n\r\n async delete(id: string): Promise<void> {\r\n const res = await fetch(`${this.endpoint}/${encodeURIComponent(id)}`, {\r\n method: \"DELETE\",\r\n });\r\n if (!res.ok) throw new Error(`Failed to delete pin: ${res.status}`);\r\n }\r\n\r\n async list(filter?: {\r\n pageUrl?: string;\r\n status?: PinStatus;\r\n }): Promise<Pin[]> {\r\n const params = new URLSearchParams();\r\n if (filter?.pageUrl) params.set(\"pageUrl\", filter.pageUrl);\r\n if (filter?.status) params.set(\"status\", filter.status);\r\n const res = await fetch(`${this.endpoint}?${params}`);\r\n if (!res.ok) return [];\r\n const data = await res.json();\r\n return Array.isArray(data)\r\n ? data.filter((item) => PinSchema.safeParse(item).success)\r\n : [];\r\n }\r\n\r\n async clear(pageUrl?: string): Promise<void> {\r\n const params = new URLSearchParams();\r\n if (pageUrl) params.set(\"pageUrl\", pageUrl);\r\n const res = await fetch(`${this.endpoint}?${params}`, { method: \"DELETE\" });\r\n if (!res.ok) throw new Error(`Failed to clear pins: ${res.status}`);\r\n }\r\n}\r\n","// @agent-native/pinpoint — Element selection via document.elementFromPoint()\r\n// MIT License\r\n//\r\n// rAF-gated throttling (60fps). Target-identity short-circuit.\r\n// Two-tier hover: fast path (highlight rect) + deferred path (component info after 100ms).\r\n// Stash hovered element ref to prevent ghost-element race on click.\r\n\r\nexport interface ElementPickerOptions {\r\n /** Called on hover with the element under the cursor */\r\n onHover?: (element: Element | null, rect: DOMRect | null) => void;\r\n /** Called after stable hover (100ms) with full element context */\r\n onStableHover?: (element: Element) => void;\r\n /** Called when an element is clicked/selected */\r\n onSelect?: (element: Element) => void;\r\n /** Elements to ignore (e.g., pinpoint's own UI) */\r\n ignoreSelector?: string;\r\n /** Whether to block page interactions during selection */\r\n blockInteractions?: boolean;\r\n}\r\n\r\nexport class ElementPicker {\r\n private active = false;\r\n private paused = false;\r\n private hoveredElement: Element | null = null;\r\n private rafId: number | null = null;\r\n private stableTimeout: ReturnType<typeof setTimeout> | null = null;\r\n private lastTarget: Element | null = null;\r\n private options: ElementPickerOptions;\r\n\r\n private handleMouseMove: (e: MouseEvent) => void;\r\n private handleClick: (e: MouseEvent) => void;\r\n private handleKeyDown: (e: KeyboardEvent) => void;\r\n\r\n constructor(options: ElementPickerOptions = {}) {\r\n this.options = options;\r\n\r\n this.handleMouseMove = (e: MouseEvent) => {\r\n if (!this.active || this.paused) return;\r\n if (this.isOwnUI(e)) return;\r\n // rAF-gated throttling for 60fps\r\n if (this.rafId !== null) return;\r\n this.rafId = requestAnimationFrame(() => {\r\n this.rafId = null;\r\n this.processHover(e.clientX, e.clientY);\r\n });\r\n };\r\n\r\n this.handleClick = (e: MouseEvent) => {\r\n if (!this.active || this.paused) return;\r\n\r\n // Don't intercept clicks on our own UI (Shadow DOM overlay)\r\n if (this.isOwnUI(e)) return;\r\n\r\n e.preventDefault();\r\n e.stopPropagation();\r\n e.stopImmediatePropagation();\r\n\r\n // Use the stashed hovered element to prevent ghost-element race\r\n const target = this.hoveredElement;\r\n if (target && !this.shouldIgnore(target)) {\r\n this.options.onSelect?.(target);\r\n }\r\n };\r\n\r\n this.handleKeyDown = (e: KeyboardEvent) => {\r\n if (!this.active) return;\r\n if (e.key === \"Escape\") {\r\n this.deactivate();\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Check if an event originates from Pinpoint's own UI.\r\n * Uses composedPath() to cross Shadow DOM boundaries.\r\n */\r\n private isOwnUI(e: Event): boolean {\r\n const path = e.composedPath();\r\n for (const node of path) {\r\n if (node instanceof HTMLElement) {\r\n if (node.id === \"pinpoint-root\") return true;\r\n if (node.hasAttribute?.(\"data-pinpoint-marker\")) return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private shouldIgnore(element: Element): boolean {\r\n // Check if element is inside our Shadow DOM\r\n const root = element.getRootNode();\r\n if (root instanceof ShadowRoot) {\r\n const host = root.host;\r\n if (host.id === \"pinpoint-root\") return true;\r\n }\r\n\r\n // Check if it's a pinpoint marker\r\n if (element.hasAttribute(\"data-pinpoint-marker\")) return true;\r\n if (element.closest?.(\"[data-pinpoint-marker]\")) return true;\r\n\r\n if (!this.options.ignoreSelector) return false;\r\n return (\r\n element.closest(this.options.ignoreSelector) !== null ||\r\n element.matches(this.options.ignoreSelector)\r\n );\r\n }\r\n\r\n private pierceElementFromPoint(x: number, y: number): Element | null {\r\n let element = document.elementFromPoint(x, y);\r\n if (!element) return null;\r\n\r\n // Pierce through Shadow DOM\r\n while (element?.shadowRoot) {\r\n const inner = element.shadowRoot.elementFromPoint(x, y);\r\n if (!inner || inner === element) break;\r\n element = inner;\r\n }\r\n\r\n return element;\r\n }\r\n\r\n private processHover(x: number, y: number): void {\r\n const element = this.pierceElementFromPoint(x, y);\r\n\r\n if (!element || this.shouldIgnore(element)) {\r\n if (this.hoveredElement) {\r\n this.hoveredElement = null;\r\n this.lastTarget = null;\r\n this.clearStableTimeout();\r\n this.options.onHover?.(null, null);\r\n }\r\n return;\r\n }\r\n\r\n // Target-identity short-circuit: skip processing if same element\r\n if (element === this.lastTarget) return;\r\n this.lastTarget = element;\r\n this.hoveredElement = element;\r\n\r\n // Fast path: immediate highlight rect\r\n const rect = element.getBoundingClientRect();\r\n this.options.onHover?.(element, rect);\r\n\r\n // Deferred path: component info after 100ms stable hover\r\n this.clearStableTimeout();\r\n this.stableTimeout = setTimeout(() => {\r\n if (this.hoveredElement === element) {\r\n this.options.onStableHover?.(element);\r\n }\r\n }, 100);\r\n }\r\n\r\n private clearStableTimeout(): void {\r\n if (this.stableTimeout !== null) {\r\n clearTimeout(this.stableTimeout);\r\n this.stableTimeout = null;\r\n }\r\n }\r\n\r\n activate(): void {\r\n if (this.active) return;\r\n this.active = true;\r\n\r\n // Use capture to intercept before any element handlers\r\n document.addEventListener(\"mousemove\", this.handleMouseMove, true);\r\n document.addEventListener(\"click\", this.handleClick, true);\r\n document.addEventListener(\"keydown\", this.handleKeyDown, true);\r\n\r\n if (this.options.blockInteractions) {\r\n document.body.style.pointerEvents = \"none\";\r\n // Re-enable pointer events on our own overlay\r\n const overlay = document.getElementById(\"pinpoint-root\");\r\n if (overlay) overlay.style.pointerEvents = \"auto\";\r\n }\r\n }\r\n\r\n deactivate(): void {\r\n if (!this.active) return;\r\n this.active = false;\r\n\r\n document.removeEventListener(\"mousemove\", this.handleMouseMove, true);\r\n document.removeEventListener(\"click\", this.handleClick, true);\r\n document.removeEventListener(\"keydown\", this.handleKeyDown, true);\r\n\r\n if (this.rafId !== null) {\r\n cancelAnimationFrame(this.rafId);\r\n this.rafId = null;\r\n }\r\n this.clearStableTimeout();\r\n this.hoveredElement = null;\r\n this.lastTarget = null;\r\n\r\n if (this.options.blockInteractions) {\r\n document.body.style.pointerEvents = \"\";\r\n }\r\n\r\n this.options.onHover?.(null, null);\r\n }\r\n\r\n /** Update blockInteractions at runtime (called from settings toggle) */\r\n setBlockInteractions(value: boolean): void {\r\n const wasBlocking = this.options.blockInteractions;\r\n this.options.blockInteractions = value;\r\n\r\n if (this.active) {\r\n if (value && !wasBlocking) {\r\n document.body.style.pointerEvents = \"none\";\r\n const overlay = document.getElementById(\"pinpoint-root\");\r\n if (overlay) overlay.style.pointerEvents = \"auto\";\r\n } else if (!value && wasBlocking) {\r\n document.body.style.pointerEvents = \"\";\r\n }\r\n }\r\n }\r\n\r\n /** Pause picking without removing listeners (e.g., while popup is open) */\r\n pause(): void {\r\n this.paused = true;\r\n this.hoveredElement = null;\r\n this.lastTarget = null;\r\n this.clearStableTimeout();\r\n this.options.onHover?.(null, null);\r\n }\r\n\r\n /** Resume picking after pause */\r\n resume(): void {\r\n this.paused = false;\r\n }\r\n\r\n isPaused(): boolean {\r\n return this.paused;\r\n }\r\n\r\n isActive(): boolean {\r\n return this.active;\r\n }\r\n\r\n /** Get the currently hovered element */\r\n getHoveredElement(): Element | null {\r\n return this.hoveredElement;\r\n }\r\n\r\n dispose(): void {\r\n this.deactivate();\r\n }\r\n}\r\n","// @agent-native/pinpoint — Click-and-drag multi-element selection\r\n// MIT License\r\n//\r\n// Inspired by react-grab pattern: 75% coverage threshold.\r\n// Collect elements within selection rectangle via bounding rect comparison.\r\n\r\nexport interface DragSelectOptions {\r\n /** Minimum coverage threshold (0-1) for an element to be considered selected */\r\n coverageThreshold?: number;\r\n /** Called when drag starts */\r\n onDragStart?: (rect: DOMRect) => void;\r\n /** Called during drag with the current selection rectangle */\r\n onDragMove?: (rect: DOMRect) => void;\r\n /** Called when drag ends with selected elements */\r\n onDragEnd?: (elements: Element[]) => void;\r\n /** Elements to ignore */\r\n ignoreSelector?: string;\r\n}\r\n\r\nexport interface SelectionRect {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport class DragSelect {\r\n private active = false;\r\n private dragging = false;\r\n private startX = 0;\r\n private startY = 0;\r\n private options: DragSelectOptions;\r\n\r\n private handleMouseDown: (e: MouseEvent) => void;\r\n private handleMouseMove: (e: MouseEvent) => void;\r\n private handleMouseUp: (e: MouseEvent) => void;\r\n\r\n constructor(options: DragSelectOptions = {}) {\r\n this.options = { coverageThreshold: 0.75, ...options };\r\n\r\n this.handleMouseDown = (e: MouseEvent) => {\r\n if (!this.active || e.button !== 0) return;\r\n // Only start drag if holding Shift (to distinguish from single click)\r\n if (!e.shiftKey) return;\r\n\r\n e.preventDefault();\r\n this.dragging = true;\r\n this.startX = e.clientX;\r\n this.startY = e.clientY;\r\n\r\n const rect = this.buildRect(e.clientX, e.clientY);\r\n this.options.onDragStart?.(\r\n new DOMRect(rect.x, rect.y, rect.width, rect.height),\r\n );\r\n };\r\n\r\n this.handleMouseMove = (e: MouseEvent) => {\r\n if (!this.dragging) return;\r\n e.preventDefault();\r\n const rect = this.buildRect(e.clientX, e.clientY);\r\n this.options.onDragMove?.(\r\n new DOMRect(rect.x, rect.y, rect.width, rect.height),\r\n );\r\n };\r\n\r\n this.handleMouseUp = (e: MouseEvent) => {\r\n if (!this.dragging) return;\r\n this.dragging = false;\r\n const selectionRect = this.buildRect(e.clientX, e.clientY);\r\n\r\n // Skip tiny drags (accidental)\r\n if (selectionRect.width < 5 && selectionRect.height < 5) return;\r\n\r\n const selected = this.getElementsInRect(selectionRect);\r\n this.options.onDragEnd?.(selected);\r\n };\r\n }\r\n\r\n private buildRect(currentX: number, currentY: number): SelectionRect {\r\n return {\r\n x: Math.min(this.startX, currentX),\r\n y: Math.min(this.startY, currentY),\r\n width: Math.abs(currentX - this.startX),\r\n height: Math.abs(currentY - this.startY),\r\n };\r\n }\r\n\r\n private getElementsInRect(selectionRect: SelectionRect): Element[] {\r\n const threshold = this.options.coverageThreshold!;\r\n const elements: Element[] = [];\r\n\r\n // Walk all visible elements\r\n const walker = document.createTreeWalker(\r\n document.body,\r\n NodeFilter.SHOW_ELEMENT,\r\n {\r\n acceptNode: (node) => {\r\n const el = node as Element;\r\n if (\r\n this.options.ignoreSelector &&\r\n el.matches(this.options.ignoreSelector)\r\n ) {\r\n return NodeFilter.FILTER_REJECT;\r\n }\r\n return NodeFilter.FILTER_ACCEPT;\r\n },\r\n },\r\n );\r\n\r\n let node: Node | null;\r\n while ((node = walker.nextNode())) {\r\n const el = node as Element;\r\n const rect = el.getBoundingClientRect();\r\n\r\n // Skip invisible elements\r\n if (rect.width === 0 || rect.height === 0) continue;\r\n\r\n // Calculate overlap\r\n const overlapX = Math.max(\r\n 0,\r\n Math.min(rect.right, selectionRect.x + selectionRect.width) -\r\n Math.max(rect.left, selectionRect.x),\r\n );\r\n const overlapY = Math.max(\r\n 0,\r\n Math.min(rect.bottom, selectionRect.y + selectionRect.height) -\r\n Math.max(rect.top, selectionRect.y),\r\n );\r\n const overlapArea = overlapX * overlapY;\r\n const elementArea = rect.width * rect.height;\r\n const coverage = overlapArea / elementArea;\r\n\r\n if (coverage >= threshold) {\r\n // Only add leaf-ish elements (avoid selecting huge containers)\r\n if (el.children.length === 0 || rect.width < 400) {\r\n elements.push(el);\r\n }\r\n }\r\n }\r\n\r\n return elements;\r\n }\r\n\r\n activate(): void {\r\n if (this.active) return;\r\n this.active = true;\r\n document.addEventListener(\"mousedown\", this.handleMouseDown, true);\r\n document.addEventListener(\"mousemove\", this.handleMouseMove, true);\r\n document.addEventListener(\"mouseup\", this.handleMouseUp, true);\r\n }\r\n\r\n deactivate(): void {\r\n if (!this.active) return;\r\n this.active = false;\r\n this.dragging = false;\r\n document.removeEventListener(\"mousedown\", this.handleMouseDown, true);\r\n document.removeEventListener(\"mousemove\", this.handleMouseMove, true);\r\n document.removeEventListener(\"mouseup\", this.handleMouseUp, true);\r\n }\r\n\r\n isDragging(): boolean {\r\n return this.dragging;\r\n }\r\n\r\n dispose(): void {\r\n this.deactivate();\r\n }\r\n}\r\n","// @agent-native/pinpoint — Text range selection\r\n// MIT License\r\n//\r\n// Listens for selectionchange, captures Selection.getRangeAt(0),\r\n// extracts container element and surrounding context.\r\n\r\nexport interface TextSelection {\r\n /** The selected text */\r\n text: string;\r\n /** The container element */\r\n container: Element;\r\n /** Start offset within the container */\r\n startOffset: number;\r\n /** End offset within the container */\r\n endOffset: number;\r\n /** Surrounding context (text before + selected + text after) */\r\n context: string;\r\n /** Bounding rect of the selection */\r\n rect: DOMRect;\r\n}\r\n\r\nexport interface TextSelectOptions {\r\n /** Called when text selection changes */\r\n onSelect?: (selection: TextSelection | null) => void;\r\n /** Minimum characters to trigger selection callback */\r\n minLength?: number;\r\n}\r\n\r\nexport class TextSelect {\r\n private active = false;\r\n private options: TextSelectOptions;\r\n private handleSelectionChange: () => void;\r\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n constructor(options: TextSelectOptions = {}) {\r\n this.options = { minLength: 3, ...options };\r\n\r\n this.handleSelectionChange = () => {\r\n if (!this.active) return;\r\n\r\n // Debounce to avoid excessive callbacks during selection\r\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\r\n this.debounceTimer = setTimeout(() => {\r\n const selection = this.getTextSelection();\r\n this.options.onSelect?.(selection);\r\n }, 150);\r\n };\r\n }\r\n\r\n private getTextSelection(): TextSelection | null {\r\n const selection = window.getSelection();\r\n if (!selection || selection.isCollapsed || selection.rangeCount === 0) {\r\n return null;\r\n }\r\n\r\n const text = selection.toString().trim();\r\n if (text.length < (this.options.minLength ?? 3)) {\r\n return null;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const container =\r\n range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE\r\n ? (range.commonAncestorContainer as Element)\r\n : range.commonAncestorContainer.parentElement;\r\n\r\n if (!container) return null;\r\n\r\n // Get surrounding context\r\n const fullText = container.textContent || \"\";\r\n const startOffset = range.startOffset;\r\n const endOffset = range.endOffset;\r\n const contextBefore = fullText.slice(\r\n Math.max(0, startOffset - 50),\r\n startOffset,\r\n );\r\n const contextAfter = fullText.slice(endOffset, endOffset + 50);\r\n const context = `...${contextBefore}[${text}]${contextAfter}...`;\r\n\r\n const rect = range.getBoundingClientRect();\r\n\r\n return {\r\n text,\r\n container,\r\n startOffset,\r\n endOffset,\r\n context,\r\n rect,\r\n };\r\n }\r\n\r\n activate(): void {\r\n if (this.active) return;\r\n this.active = true;\r\n document.addEventListener(\"selectionchange\", this.handleSelectionChange);\r\n }\r\n\r\n deactivate(): void {\r\n if (!this.active) return;\r\n this.active = false;\r\n document.removeEventListener(\"selectionchange\", this.handleSelectionChange);\r\n if (this.debounceTimer) {\r\n clearTimeout(this.debounceTimer);\r\n this.debounceTimer = null;\r\n }\r\n }\r\n\r\n /** Get the current text selection, if any */\r\n getCurrentSelection(): TextSelection | null {\r\n return this.getTextSelection();\r\n }\r\n\r\n dispose(): void {\r\n this.deactivate();\r\n }\r\n}\r\n","// @agent-native/pinpoint — React adapter using bippy + element-source\r\n// MIT License\r\n\r\nimport type {\r\n FrameworkAdapter,\r\n ComponentInfo,\r\n SourceLocation,\r\n} from \"../types/index.js\";\r\n\r\n// bippy provides React fiber introspection (MIT)\r\n// These are imported dynamically to avoid hard dependency when React isn't present\r\nlet bippy: typeof import(\"bippy\") | null = null;\r\nlet elementSource: typeof import(\"element-source\") | null = null;\r\n\r\nasync function loadBippy() {\r\n if (!bippy) {\r\n try {\r\n bippy = await import(\"bippy\");\r\n } catch {\r\n bippy = null;\r\n }\r\n }\r\n return bippy;\r\n}\r\n\r\nasync function loadElementSource() {\r\n if (!elementSource) {\r\n try {\r\n elementSource = await import(\"element-source\");\r\n } catch {\r\n elementSource = null;\r\n }\r\n }\r\n return elementSource;\r\n}\r\n\r\n/** React internal component names to filter from the component path */\r\nconst FRAMEWORK_INTERNALS = new Set([\r\n \"Fragment\",\r\n \"Suspense\",\r\n \"StrictMode\",\r\n \"Profiler\",\r\n \"Provider\",\r\n \"Consumer\",\r\n \"ForwardRef\",\r\n \"Memo\",\r\n // Next.js internals\r\n \"InnerLayoutRouter\",\r\n \"OuterLayoutRouter\",\r\n \"RenderFromTemplateContext\",\r\n \"ScrollAndFocusHandler\",\r\n \"RedirectBoundary\",\r\n \"NotFoundBoundary\",\r\n \"LoadingBoundary\",\r\n \"ErrorBoundary\",\r\n \"HotReload\",\r\n \"Router\",\r\n \"ServerRoot\",\r\n \"AppRouter\",\r\n \"ServerInsertedHTMLProvider\",\r\n // React Router internals\r\n \"Routes\",\r\n \"RenderedRoute\",\r\n \"Navigate\",\r\n \"Outlet\",\r\n]);\r\n\r\nfunction getRDTHook(): any {\r\n return typeof window !== \"undefined\"\r\n ? (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__\r\n : null;\r\n}\r\n\r\nexport const reactAdapter: FrameworkAdapter = {\r\n name: \"react\",\r\n\r\n detect(): boolean {\r\n return !!getRDTHook();\r\n },\r\n\r\n getComponentInfo(element: Element): ComponentInfo | null {\r\n const b = bippy;\r\n if (!b) return null;\r\n\r\n try {\r\n const fiber = b.getFiberFromHostInstance(element);\r\n if (!fiber) return null;\r\n\r\n // Build component path by traversing up the fiber tree\r\n const components: string[] = [];\r\n let current: any = fiber;\r\n\r\n while (current) {\r\n const name = b.getDisplayName(current);\r\n if (name && !FRAMEWORK_INTERNALS.has(name)) {\r\n components.unshift(name);\r\n }\r\n current = current.return ?? null;\r\n if (components.length > 20) break;\r\n }\r\n\r\n // Get the immediate component name\r\n let componentFiber: any = fiber;\r\n while (componentFiber && typeof componentFiber.type === \"string\") {\r\n componentFiber = componentFiber.return ?? null;\r\n }\r\n\r\n const displayName = componentFiber\r\n ? b.getDisplayName(componentFiber)\r\n : null;\r\n\r\n const sourceInfo = getSourceFromFiber(componentFiber);\r\n\r\n return {\r\n name: displayName || components[components.length - 1] || \"Unknown\",\r\n displayName: displayName || undefined,\r\n filePath: sourceInfo?.file,\r\n lineNumber: sourceInfo?.line,\r\n };\r\n } catch {\r\n return null;\r\n }\r\n },\r\n\r\n getSourceLocation(element: Element): SourceLocation | null {\r\n const b = bippy;\r\n if (!b) return null;\r\n\r\n try {\r\n const fiber = b.getFiberFromHostInstance(element);\r\n if (!fiber) return null;\r\n\r\n let componentFiber: any = fiber;\r\n while (componentFiber && typeof componentFiber.type === \"string\") {\r\n componentFiber = componentFiber.return ?? null;\r\n }\r\n\r\n return getSourceFromFiber(componentFiber);\r\n } catch {\r\n return null;\r\n }\r\n },\r\n\r\n freeze(): void {\r\n // React update freezing handled by freeze/react-freeze.ts\r\n },\r\n\r\n unfreeze(): void {\r\n // Restore handled by freeze/react-freeze.ts\r\n },\r\n};\r\n\r\nfunction getSourceFromFiber(fiber: any): SourceLocation | null {\r\n if (!fiber) return null;\r\n\r\n // React 18: _debugSource contains file/line info\r\n if (fiber._debugSource) {\r\n return {\r\n file: fiber._debugSource.fileName,\r\n line: fiber._debugSource.lineNumber,\r\n column: fiber._debugSource.columnNumber,\r\n };\r\n }\r\n\r\n // React 19: _debugSource was removed, use element-source library\r\n // element-source returns Promise<ElementSourceInfo[]> — we use it sync from cache if available\r\n // For synchronous adapter API, we only use _debugSource. Async source resolution\r\n // is handled at a higher level when building ElementContext.\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Build a component path string like: <App> <Layout> <Sidebar> <NavLink>\r\n */\r\nexport function buildComponentPath(element: Element): string {\r\n const b = bippy;\r\n if (!b) return \"\";\r\n\r\n try {\r\n const fiber = b.getFiberFromHostInstance(element);\r\n if (!fiber) return \"\";\r\n\r\n const components: string[] = [];\r\n let current: any = fiber;\r\n\r\n while (current) {\r\n const name = b.getDisplayName(current);\r\n if (name && !FRAMEWORK_INTERNALS.has(name)) {\r\n components.unshift(`<${name}>`);\r\n }\r\n current = current.return ?? null;\r\n if (components.length > 10) break;\r\n }\r\n\r\n return components.join(\" \");\r\n } catch {\r\n return \"\";\r\n }\r\n}\r\n\r\n// Initialize bippy and element-source lazily\r\nif (typeof window !== \"undefined\") {\r\n const init = () => {\r\n loadBippy();\r\n loadElementSource();\r\n };\r\n if (typeof requestIdleCallback !== \"undefined\") {\r\n requestIdleCallback(init);\r\n } else {\r\n setTimeout(init, 100);\r\n }\r\n}\r\n","// @agent-native/pinpoint — Vue 3 adapter\r\n// MIT License\r\n//\r\n// Detects Vue 3 apps via window.__VUE__ or [data-v-] attributes.\r\n// Walks component tree via __vueParentComponent DOM properties.\r\n\r\nimport type {\r\n FrameworkAdapter,\r\n ComponentInfo,\r\n SourceLocation,\r\n} from \"../types/index.js\";\r\n\r\nexport const vueAdapter: FrameworkAdapter = {\r\n name: \"vue\",\r\n\r\n detect(): boolean {\r\n if (typeof window === \"undefined\") return false;\r\n // Vue 3 devtools hook\r\n if ((window as any).__VUE__) return true;\r\n // Vue 3 scoped style attributes\r\n if (document.querySelector(\"[data-v-]\")) return true;\r\n // Check for Vue 3 app instance\r\n return !!document.querySelector(\"[__vue_app__]\");\r\n },\r\n\r\n getComponentInfo(element: Element): ComponentInfo | null {\r\n const instance = getVueInstance(element);\r\n if (!instance) return null;\r\n\r\n const name = getComponentName(instance);\r\n\r\n return {\r\n name: name || \"Unknown\",\r\n displayName: name || undefined,\r\n filePath: instance.$options?.__file || instance.type?.__file,\r\n lineNumber: undefined, // Vue doesn't expose line numbers like React\r\n };\r\n },\r\n\r\n getSourceLocation(element: Element): SourceLocation | null {\r\n const instance = getVueInstance(element);\r\n if (!instance) return null;\r\n\r\n const file =\r\n instance.$options?.__file ||\r\n instance.type?.__file ||\r\n instance.type?.__name;\r\n\r\n if (!file) return null;\r\n\r\n return { file };\r\n },\r\n};\r\n\r\n/**\r\n * Get the Vue component instance associated with a DOM element.\r\n */\r\nfunction getVueInstance(element: Element): any {\r\n // Vue 3: __vueParentComponent or __vue_app__\r\n const el = element as any;\r\n\r\n if (el.__vueParentComponent) {\r\n return el.__vueParentComponent;\r\n }\r\n\r\n // Walk up to find the nearest Vue component\r\n let current: Element | null = element;\r\n while (current) {\r\n if ((current as any).__vueParentComponent) {\r\n return (current as any).__vueParentComponent;\r\n }\r\n // Vue 2 compatibility\r\n if ((current as any).__vue__) {\r\n return (current as any).__vue__;\r\n }\r\n current = current.parentElement;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Get the display name of a Vue component instance.\r\n */\r\nfunction getComponentName(instance: any): string | null {\r\n if (!instance) return null;\r\n\r\n // Vue 3 Composition API\r\n if (instance.type?.name) return instance.type.name;\r\n if (instance.type?.__name) return instance.type.__name;\r\n\r\n // Vue 3 Options API\r\n if (instance.$options?.name) return instance.$options.name;\r\n\r\n // Infer from __file\r\n const file = instance.type?.__file || instance.$options?.__file;\r\n if (file) {\r\n const match = file.match(/([^/\\\\]+)\\.\\w+$/);\r\n if (match) return match[1];\r\n }\r\n\r\n return null;\r\n}\r\n","// @agent-native/pinpoint — Generic fallback adapter\r\n// MIT License\r\n//\r\n// For non-framework pages. DOM-only info, no component tree, no source files.\r\n\r\nimport type {\r\n FrameworkAdapter,\r\n ComponentInfo,\r\n SourceLocation,\r\n} from \"../types/index.js\";\r\n\r\nexport const genericAdapter: FrameworkAdapter = {\r\n name: \"generic\",\r\n\r\n detect(): boolean {\r\n // Always matches as the last resort\r\n return true;\r\n },\r\n\r\n getComponentInfo(_element: Element): ComponentInfo | null {\r\n // No framework = no component info\r\n return null;\r\n },\r\n\r\n getSourceLocation(_element: Element): SourceLocation | null {\r\n // No framework = no source location\r\n return null;\r\n },\r\n};\r\n","// @agent-native/pinpoint — Output formatting (compact/standard/detailed)\r\n// MIT License\r\n\r\nimport type { Pin, OutputFormat } from \"../types/index.js\";\r\n\r\n/**\r\n * Format pins into a human/agent-readable markdown string.\r\n */\r\nexport function formatPins(\r\n pins: Pin[],\r\n format: OutputFormat = \"standard\",\r\n): string {\r\n if (pins.length === 0) return \"No annotations.\";\r\n\r\n const pageUrl = pins[0].pageUrl;\r\n\r\n switch (format) {\r\n case \"compact\":\r\n return formatCompact(pins, pageUrl);\r\n case \"standard\":\r\n return formatStandard(pins, pageUrl);\r\n case \"detailed\":\r\n return formatDetailed(pins, pageUrl);\r\n default:\r\n return formatStandard(pins, pageUrl);\r\n }\r\n}\r\n\r\nfunction formatCompact(pins: Pin[], pageUrl: string): string {\r\n const lines = [`## Page Feedback: ${pageUrl} (${pins.length} annotations)`];\r\n for (let i = 0; i < pins.length; i++) {\r\n const pin = pins[i];\r\n lines.push(`${i + 1}. \\`${pin.element.selector}\\` — \"${pin.comment}\"`);\r\n }\r\n return lines.join(\"\\n\");\r\n}\r\n\r\nfunction formatStandard(pins: Pin[], pageUrl: string): string {\r\n const lines = [\r\n `## Page Feedback: ${pageUrl}`,\r\n `${pins.length} annotation${pins.length === 1 ? \"\" : \"s\"} | ${new Date().toISOString()}`,\r\n \"\",\r\n ];\r\n\r\n for (let i = 0; i < pins.length; i++) {\r\n const pin = pins[i];\r\n lines.push(`### ${i + 1}: \\`${pin.element.selector}\\``);\r\n lines.push(`**Comment:** ${pin.comment}`);\r\n lines.push(\r\n `**Element:** \\`<${pin.element.tagName}>\\`${pin.element.classNames.length > 0 ? ` with classes \\`.${pin.element.classNames.join(\" .\")}\\`` : \"\"}`,\r\n );\r\n\r\n if (pin.framework) {\r\n lines.push(\r\n `**Component:** ${pin.framework.componentPath} (${pin.framework.framework})`,\r\n );\r\n if (pin.framework.sourceFile) {\r\n lines.push(`**Source:** \\`${pin.framework.sourceFile}\\``);\r\n }\r\n }\r\n\r\n const rect = pin.element.boundingRect;\r\n lines.push(\r\n `**Position:** (${rect.x}, ${rect.y}) ${rect.width}x${rect.height}`,\r\n );\r\n lines.push(`**Status:** ${pin.status.state}`);\r\n\r\n if (pin.author) {\r\n lines.push(`**Author:** ${pin.author}`);\r\n }\r\n lines.push(\"\");\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\nfunction formatDetailed(pins: Pin[], pageUrl: string): string {\r\n const lines = [formatStandard(pins, pageUrl)];\r\n\r\n // Append detailed info for each pin\r\n for (let i = 0; i < pins.length; i++) {\r\n const pin = pins[i];\r\n const detailLines: string[] = [];\r\n\r\n if (pin.element.domPath) {\r\n detailLines.push(`**DOM Path:** ${pin.element.domPath}`);\r\n }\r\n\r\n if (\r\n pin.element.computedStyles &&\r\n Object.keys(pin.element.computedStyles).length > 0\r\n ) {\r\n const styles = Object.entries(pin.element.computedStyles)\r\n .map(([key, value]) => `${key}: ${value}`)\r\n .join(\", \");\r\n detailLines.push(`**Computed Styles:** ${styles}`);\r\n }\r\n\r\n if (\r\n pin.element.ariaAttributes &&\r\n Object.keys(pin.element.ariaAttributes).length > 0\r\n ) {\r\n const aria = Object.entries(pin.element.ariaAttributes)\r\n .map(([key, value]) => `${key}=\"${value}\"`)\r\n .join(\", \");\r\n detailLines.push(`**Accessibility:** ${aria}`);\r\n }\r\n\r\n if (pin.element.textContent) {\r\n detailLines.push(`**Text Content:** \"${pin.element.textContent}\"`);\r\n }\r\n\r\n if (\r\n pin.element.dataAttributes &&\r\n Object.keys(pin.element.dataAttributes).length > 0\r\n ) {\r\n const data = Object.entries(pin.element.dataAttributes)\r\n .map(([key, value]) => `${key}=\"${value}\"`)\r\n .join(\", \");\r\n detailLines.push(`**Data Attributes:** ${data}`);\r\n }\r\n\r\n if (detailLines.length > 0) {\r\n lines.push(`#### Details for #${i + 1}:`);\r\n lines.push(detailLines.join(\"\\n\"));\r\n lines.push(\"\");\r\n }\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n","// @agent-native/pinpoint — Split output for sendToAgentChat()\r\n// MIT License\r\n//\r\n// Splits annotation output into { message, context } for the agent chat bridge.\r\n// The message is shown in chat UI. The context is hidden, appended for the agent.\r\n\r\nimport type {\r\n AgentOutput,\r\n Pin,\r\n OutputFormat,\r\n QueuedAnnotation,\r\n} from \"../types/index.js\";\r\nimport { formatPins } from \"./formatter.js\";\r\n\r\nexport type { AgentOutput } from \"../types/index.js\";\r\n\r\n/**\r\n * Format a single pin into rich context for the agent.\r\n *\r\n * ```\r\n * [Annotation on <button class=\"primary\"> in <Header> component]\r\n * Comment: \"This button should be blue instead of gray\"\r\n * Element: button.primary at (120, 45)\r\n * Source: src/components/Header.tsx:42\r\n * ```\r\n */\r\nexport function formatRichPinContext(pin: Pin): string {\r\n const lines: string[] = [];\r\n\r\n // Build element descriptor\r\n const tagName = pin.element.tagName.toLowerCase();\r\n const classes =\r\n pin.element.classNames.length > 0\r\n ? ` class=\"${pin.element.classNames.join(\" \")}\"`\r\n : \"\";\r\n const component = pin.framework?.componentPath\r\n ? ` in ${pin.framework.componentPath} component`\r\n : \"\";\r\n\r\n lines.push(`[Annotation on <${tagName}${classes}>${component}]`);\r\n lines.push(`Comment: \"${pin.comment}\"`);\r\n\r\n const rect = pin.element.boundingRect;\r\n const classStr =\r\n pin.element.classNames.length > 0\r\n ? `.${pin.element.classNames.join(\".\")}`\r\n : \"\";\r\n lines.push(\r\n `Element: ${tagName}${classStr} at (${Math.round(rect.x)}, ${Math.round(rect.y)})`,\r\n );\r\n\r\n if (pin.framework?.sourceFile) {\r\n lines.push(`Source: ${pin.framework.sourceFile}`);\r\n }\r\n\r\n if (pin.element.textContent) {\r\n const truncated = pin.element.textContent.slice(0, 80);\r\n lines.push(\r\n `Text: \"${truncated}${pin.element.textContent.length > 80 ? \"...\" : \"\"}\"`,\r\n );\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Format pins for agent chat.\r\n * The full formatted output goes into message (visible in chat UI) so the user\r\n * can see exactly what context the agent is working with.\r\n */\r\nexport function formatPinsForAgent(\r\n pins: Pin[],\r\n format: OutputFormat = \"standard\",\r\n): AgentOutput {\r\n if (pins.length === 0) {\r\n return { message: \"No annotations to send.\", context: \"\" };\r\n }\r\n\r\n // Use rich context format for each pin\r\n const richAnnotations = pins\r\n .map((pin) => formatRichPinContext(pin))\r\n .join(\"\\n\\n\");\r\n\r\n const instruction = `The user has annotated ${pins.length} element${pins.length === 1 ? \"\" : \"s\"} on the page with visual feedback. Review each annotation and make the requested changes.\\n\\n`;\r\n\r\n // Also include the structured format as context for the agent\r\n const details = formatPins(pins, format);\r\n const message = instruction + richAnnotations;\r\n\r\n return { message, context: details };\r\n}\r\n\r\n/**\r\n * Format queued annotations for batch sending.\r\n */\r\nexport function formatQueueForAgent(\r\n queue: QueuedAnnotation[],\r\n format: OutputFormat = \"standard\",\r\n): AgentOutput {\r\n if (queue.length === 0) {\r\n return { message: \"No queued annotations to send.\", context: \"\" };\r\n }\r\n\r\n const parts: string[] = [];\r\n const pins: Pin[] = [];\r\n\r\n parts.push(\r\n `The user has queued ${queue.length} annotation${queue.length === 1 ? \"\" : \"s\"} for batch review. Process each one:\\n`,\r\n );\r\n\r\n for (let i = 0; i < queue.length; i++) {\r\n const item = queue[i];\r\n parts.push(`--- Item ${i + 1} ---`);\r\n\r\n if (item.pin) {\r\n parts.push(formatRichPinContext(item.pin));\r\n pins.push(item.pin);\r\n }\r\n\r\n if (item.drawings && item.drawings.length > 0) {\r\n parts.push(`[Drawing: ${item.drawings.length} stroke(s) on the page]`);\r\n for (const stroke of item.drawings) {\r\n const startPt = stroke.points[0];\r\n const endPt = stroke.points[stroke.points.length - 1];\r\n parts.push(\r\n ` ${stroke.type} from (${Math.round(startPt.x)}, ${Math.round(startPt.y)}) to (${Math.round(endPt.x)}, ${Math.round(endPt.y)}) [${stroke.color}]`,\r\n );\r\n }\r\n }\r\n\r\n if (item.textNotes && item.textNotes.length > 0) {\r\n for (const note of item.textNotes) {\r\n parts.push(\r\n `[Text note at (${Math.round(note.x)}, ${Math.round(note.y)}): \"${note.text}\"]`,\r\n );\r\n }\r\n }\r\n\r\n parts.push(\"\");\r\n }\r\n\r\n const message = parts.join(\"\\n\");\r\n const context = pins.length > 0 ? formatPins(pins, format) : \"\";\r\n\r\n return { message, context };\r\n}\r\n","// @agent-native/pinpoint — Plugin registration and hook dispatch\r\n// MIT License\r\n\r\nimport type {\r\n Plugin,\r\n PluginHooks,\r\n PinpointAPI,\r\n PluginHookRegistry,\r\n} from \"../types/index.js\";\r\n\r\nconst plugins: Map<string, Plugin> = new Map();\r\nconst hookHandlers: Map<keyof PluginHooks, Set<Function>> = new Map();\r\n\r\n/**\r\n * Register a plugin.\r\n */\r\nexport function registerPlugin(plugin: Plugin, api?: PinpointAPI): void {\r\n if (plugins.has(plugin.name)) {\r\n unregisterPlugin(plugin.name);\r\n }\r\n\r\n plugins.set(plugin.name, plugin);\r\n\r\n // Register hook handlers\r\n if (plugin.hooks) {\r\n for (const [hookName, handler] of Object.entries(plugin.hooks)) {\r\n if (typeof handler === \"function\") {\r\n const key = hookName as keyof PluginHooks;\r\n if (!hookHandlers.has(key)) {\r\n hookHandlers.set(key, new Set());\r\n }\r\n hookHandlers.get(key)!.add(handler);\r\n }\r\n }\r\n }\r\n\r\n // Call setup if provided\r\n if (plugin.setup && api) {\r\n const registry: PluginHookRegistry = {\r\n register(hookName, handler) {\r\n if (!hookHandlers.has(hookName)) {\r\n hookHandlers.set(hookName, new Set());\r\n }\r\n hookHandlers.get(hookName)!.add(handler);\r\n },\r\n unregister(hookName, handler) {\r\n hookHandlers.get(hookName)?.delete(handler);\r\n },\r\n };\r\n plugin.setup(api, registry);\r\n }\r\n}\r\n\r\n/**\r\n * Unregister a plugin by name.\r\n */\r\nexport function unregisterPlugin(name: string): void {\r\n const plugin = plugins.get(name);\r\n if (!plugin) return;\r\n\r\n // Remove hook handlers\r\n if (plugin.hooks) {\r\n for (const [hookName, handler] of Object.entries(plugin.hooks)) {\r\n if (typeof handler === \"function\") {\r\n hookHandlers.get(hookName as keyof PluginHooks)?.delete(handler);\r\n }\r\n }\r\n }\r\n\r\n plugins.delete(name);\r\n}\r\n\r\n/**\r\n * Get all registered plugin names.\r\n */\r\nexport function getPlugins(): string[] {\r\n return Array.from(plugins.keys());\r\n}\r\n\r\n/**\r\n * Dispatch a hook to all registered handlers.\r\n */\r\nexport function dispatchHook(\r\n name: keyof PluginHooks,\r\n ...args: unknown[]\r\n): void {\r\n const handlers = hookHandlers.get(name);\r\n if (!handlers) return;\r\n\r\n for (const handler of handlers) {\r\n try {\r\n handler(...args);\r\n } catch (err) {\r\n console.warn(`[pinpoint] Plugin hook ${name} error:`, err);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Dispatch a hook that can transform data (pipeline pattern).\r\n * Returns the transformed value, or false to cancel.\r\n */\r\nexport function dispatchTransformHook<T>(\r\n name: keyof PluginHooks,\r\n initial: T,\r\n): T | false {\r\n const handlers = hookHandlers.get(name);\r\n if (!handlers) return initial;\r\n\r\n let current: T | false = initial;\r\n for (const handler of handlers) {\r\n try {\r\n const result = handler(current) as T | false | undefined;\r\n if (result === false) return false;\r\n if (result !== undefined) current = result;\r\n } catch (err) {\r\n console.warn(`[pinpoint] Plugin hook ${name} error:`, err);\r\n }\r\n }\r\n\r\n return current;\r\n}\r\n\r\n/**\r\n * Get context menu actions from all plugins.\r\n */\r\nexport function getPluginActions() {\r\n const actions = [];\r\n for (const plugin of plugins.values()) {\r\n if (plugin.actions) {\r\n actions.push(...plugin.actions);\r\n }\r\n }\r\n return actions;\r\n}\r\n","import type { Plugin } from \"../types/index.js\";\r\n\r\nexport const agentNativePlugin: Plugin = {\r\n name: \"agent-native\",\r\n};\r\n","// @agent-native/pinpoint — Input sanitization for DOM-derived strings\r\n// MIT License\r\n\r\nconst HTML_ENTITIES: Record<string, string> = {\r\n \"&\": \"&amp;\",\r\n \"<\": \"&lt;\",\r\n \">\": \"&gt;\",\r\n '\"': \"&quot;\",\r\n \"'\": \"&#39;\",\r\n};\r\n\r\n/**\r\n * Escape HTML entities in a string.\r\n * Use on all DOM-derived strings before rendering or including in output.\r\n */\r\nexport function escapeHtml(str: string): string {\r\n return str.replace(/[&<>\"']/g, (char) => HTML_ENTITIES[char] || char);\r\n}\r\n\r\n/**\r\n * Sanitize a string by removing control characters and limiting length.\r\n */\r\nexport function sanitizeString(str: string, maxLength = 1000): string {\r\n // Remove control characters (except newline, tab)\r\n const cleaned = str.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, \"\");\r\n return cleaned.slice(0, maxLength);\r\n}\r\n\r\n/**\r\n * Sanitize an object's string values recursively.\r\n */\r\nexport function sanitizeObject<T extends Record<string, any>>(\r\n obj: T,\r\n maxStringLength = 1000,\r\n): T {\r\n const result: any = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (typeof value === \"string\") {\r\n result[key] = sanitizeString(value, maxStringLength);\r\n } else if (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n !Array.isArray(value)\r\n ) {\r\n result[key] = sanitizeObject(value, maxStringLength);\r\n } else if (Array.isArray(value)) {\r\n result[key] = value.map((item) =>\r\n typeof item === \"string\"\r\n ? sanitizeString(item, maxStringLength)\r\n : typeof item === \"object\" && item !== null\r\n ? sanitizeObject(item, maxStringLength)\r\n : item,\r\n );\r\n } else {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n","// @agent-native/pinpoint — Origin validation for cross-frame communication\r\n// MIT License\r\n\r\n/**\r\n * Validate that a message origin is allowed.\r\n * Used for postMessage security when communicating with frames.\r\n */\r\nexport function isAllowedOrigin(\r\n origin: string,\r\n allowedOrigins?: string[],\r\n): boolean {\r\n // Always allow same-origin\r\n if (origin === window.location.origin) return true;\r\n\r\n // Always allow localhost variants\r\n if (\r\n origin.startsWith(\"http://localhost\") ||\r\n origin.startsWith(\"http://127.0.0.1\") ||\r\n origin.startsWith(\"https://localhost\")\r\n ) {\r\n return true;\r\n }\r\n\r\n // Check explicit allowlist\r\n if (allowedOrigins && allowedOrigins.length > 0) {\r\n return allowedOrigins.includes(origin);\r\n }\r\n\r\n // Default: deny unknown origins\r\n return false;\r\n}\r\n\r\n/**\r\n * Create a MessageChannel port pair for secure bi-directional communication.\r\n * Avoids broadcasting via postMessage('*').\r\n */\r\nexport function createSecureChannel(): {\r\n port: MessagePort;\r\n remotePort: MessagePort;\r\n} {\r\n const channel = new MessageChannel();\r\n return {\r\n port: channel.port1,\r\n remotePort: channel.port2,\r\n };\r\n}\r\n"],"mappings":"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","names":["node"]}
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import {
3
+ openFile
4
+ } from "./chunk-HAEYE6KB.js";
5
+ export {
6
+ openFile
7
+ };
8
+ //# sourceMappingURL=open-file-WR2JHI4P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,28 @@
1
+ import {
2
+ MemoryStore,
3
+ buildElementContext,
4
+ buildSelector,
5
+ detectFramework,
6
+ extractElementInfo,
7
+ freeze,
8
+ getComponentInfo,
9
+ getSourceLocation,
10
+ isFreezeActive,
11
+ openFile,
12
+ unfreeze
13
+ } from "../chunk-B7TY4FPP.js";
14
+ import "../chunk-DGUM43GV.js";
15
+ export {
16
+ MemoryStore,
17
+ buildSelector,
18
+ detectFramework,
19
+ extractElementInfo,
20
+ freeze,
21
+ getComponentInfo,
22
+ buildElementContext as getElementContext,
23
+ getSourceLocation,
24
+ isFreezeActive,
25
+ openFile,
26
+ unfreeze
27
+ };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,23 @@
1
+ import { h as PinpointConfig } from './index-NvFcZ4SO.js';
2
+
3
+ /** Props for the <Pinpoint /> component. Same as PinpointConfig minus target. */
4
+ type PinpointProps = Omit<PinpointConfig, "target">;
5
+ /**
6
+ * Mount the Pinpoint overlay as a React component.
7
+ *
8
+ * ```tsx
9
+ * import { Pinpoint } from "@agent-native/pinpoint/react";
10
+ *
11
+ * function App() {
12
+ * return (
13
+ * <>
14
+ * <Pinpoint author="Designer" endpoint="/api/pins" autoSubmit />
15
+ * <YourApp />
16
+ * </>
17
+ * );
18
+ * }
19
+ * ```
20
+ */
21
+ declare function Pinpoint(props: PinpointProps): null;
22
+
23
+ export { Pinpoint, type PinpointProps };
package/dist/react.js ADDED
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import {
3
+ mountPinpoint
4
+ } from "./chunk-ZW7IO3EW.js";
5
+
6
+ // src/react.tsx
7
+ import { useEffect } from "react";
8
+ function Pinpoint(props) {
9
+ useEffect(() => {
10
+ const {
11
+ dispose
12
+ } = mountPinpoint(props);
13
+ return dispose;
14
+ }, []);
15
+ return null;
16
+ }
17
+ export {
18
+ Pinpoint
19
+ };
20
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["// @agent-native/pinpoint — React component wrapper\r\n// MIT License\r\n//\r\n// Thin lifecycle wrapper around mountPinpoint(). Renders nothing —\r\n// the SolidJS overlay is mounted imperatively in Shadow DOM.\r\n// Props are read on mount only ([] dependency).\r\n\r\nimport { useEffect } from \"react\";\r\n\r\nimport type { PinpointConfig } from \"./types/index.js\";\r\nimport { mountPinpoint } from \"./ui/mount.js\";\r\n\r\n/** Props for the <Pinpoint /> component. Same as PinpointConfig minus target. */\r\nexport type PinpointProps = Omit<PinpointConfig, \"target\">;\r\n\r\n/**\r\n * Mount the Pinpoint overlay as a React component.\r\n *\r\n * ```tsx\r\n * import { Pinpoint } from \"@agent-native/pinpoint/react\";\r\n *\r\n * function App() {\r\n * return (\r\n * <>\r\n * <Pinpoint author=\"Designer\" endpoint=\"/api/pins\" autoSubmit />\r\n * <YourApp />\r\n * </>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function Pinpoint(props: PinpointProps) {\r\n useEffect(() => {\r\n const { dispose } = mountPinpoint(props);\r\n return dispose;\r\n }, []);\r\n return null;\r\n}\r\n"],"mappings":";;;;;;AAOA,SAASA,iBAAiB;AAwBnB,SAASC,SAASC,OAAsB;AAC7CC,YAAU,MAAM;AACd,UAAM;MAAEC;IAAQ,IAAIC,cAAcH,KAAK;AACvC,WAAOE;EACT,GAAG,CAAA,CAAE;AACL,SAAO;AACT;","names":["useEffect","Pinpoint","props","useEffect","dispose","mountPinpoint"]}