refinekit 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -61
- package/dist/overlay.d.ts +1 -0
- package/dist/refiner.js +1 -1
- package/dist/refiner.js.map +1 -1
- package/dist/refiner.mjs +1 -1
- package/dist/refiner.mjs.map +1 -1
- package/dist/toolbar.d.ts +1 -0
- package/package.json +1 -1
package/dist/refiner.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refiner.mjs","sources":["../src/annotation-store.ts","../src/toolbar.ts","../src/overlay.ts","../src/annotation-dialog.ts","../src/annotation-marker.ts","../src/settings.ts","../src/mcp-bridge.ts","../src/refiner.ts","../src/styles.ts","../src/selector.ts","../src/index.ts"],"sourcesContent":["import { Annotation } from './types';\n\ntype Listener = (annotation: Annotation) => void;\n\nexport class AnnotationStore {\n private annotations: Map<string, Annotation> = new Map();\n private listeners: Map<string, Set<Listener>> = new Map();\n\n add(targetSelector: string, targetRect: DOMRect, text: string): Annotation {\n const annotation: Annotation = {\n id: crypto.randomUUID(),\n targetSelector,\n targetRect: {\n x: targetRect.x,\n y: targetRect.y,\n width: targetRect.width,\n height: targetRect.height,\n },\n text,\n timestamp: Date.now(),\n resolved: false,\n };\n this.annotations.set(annotation.id, annotation);\n this.emit('add', annotation);\n return annotation;\n }\n\n resolve(id: string): void {\n const annotation = this.annotations.get(id);\n if (annotation) {\n annotation.resolved = true;\n this.emit('resolve', annotation);\n }\n }\n\n remove(id: string): void {\n const annotation = this.annotations.get(id);\n if (annotation) {\n this.annotations.delete(id);\n this.emit('remove', annotation);\n }\n }\n\n get(id: string): Annotation | undefined {\n return this.annotations.get(id);\n }\n\n getAll(): Annotation[] {\n return Array.from(this.annotations.values());\n }\n\n getPending(): Annotation[] {\n return this.getAll().filter((a) => !a.resolved);\n }\n\n getCount(): number {\n return this.annotations.size;\n }\n\n exportJSON(): string {\n return JSON.stringify(this.getAll(), null, 2);\n }\n\n on(event: string, listener: Listener): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n off(event: string, listener: Listener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: string, annotation: Annotation): void {\n this.listeners.get(event)?.forEach((fn) => fn(annotation));\n }\n}\n","export class Toolbar {\n readonly el: HTMLElement;\n private collapsed = true;\n private countBadge!: HTMLElement;\n private expandBadge!: HTMLElement;\n private innerEl!: HTMLElement;\n private copyBtn!: HTMLElement;\n private clearBtn!: HTMLElement;\n private toggleBtn!: HTMLElement;\n private settingsOpen = false;\n\n onCopy?: () => void;\n onClear?: () => void;\n onSettings?: () => void;\n onCollapse?: () => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'refiner-toolbar';\n this.el.setAttribute('data-refiner-toolbar', '');\n this.el.setAttribute('data-collapsed', 'true');\n this.render();\n root.appendChild(this.el);\n\n // Expand on first load after a short delay\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.collapsed = false;\n this.el.setAttribute('data-collapsed', 'false');\n this.updateBadgeVisibility();\n });\n });\n }\n\n private render(): void {\n const pill = document.createElement('div');\n pill.className = 'toolbar-pill';\n\n // Inner (collapsible buttons)\n this.innerEl = document.createElement('div');\n this.innerEl.className = 'toolbar-inner';\n\n // Note count\n this.countBadge = document.createElement('span');\n this.countBadge.className = 'toolbar-count';\n this.countBadge.textContent = '0';\n this.innerEl.appendChild(this.createBtn(\n this.countBadge,\n 'Annotations',\n null,\n ));\n\n // Copy\n const copyIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`;\n const checkIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n this.copyBtn = this.createBtn(\n copyIcon,\n 'Copy annotations',\n () => {\n if (this.copyBtn.classList.contains('disabled')) return;\n this.onCopy?.();\n this.copyBtn.querySelector('.toolbar-icon')!.innerHTML = checkIcon;\n setTimeout(() => {\n this.copyBtn.querySelector('.toolbar-icon')!.innerHTML = copyIcon;\n }, 1500);\n },\n );\n this.copyBtn.classList.add('disabled');\n this.innerEl.appendChild(this.copyBtn);\n\n // Clear all\n this.clearBtn = this.createBtn(\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n 'Clear all',\n () => {\n if (this.clearBtn.classList.contains('disabled')) return;\n this.onClear?.();\n },\n );\n this.clearBtn.classList.add('disabled');\n this.innerEl.appendChild(this.clearBtn);\n\n // Settings\n this.innerEl.appendChild(this.createBtn(\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\"/></svg>`,\n 'Settings',\n () => this.onSettings?.(),\n ));\n\n // Divider\n const divider = document.createElement('div');\n divider.className = 'toolbar-divider';\n this.innerEl.appendChild(divider);\n\n pill.appendChild(this.innerEl);\n\n // Toggle button (always visible — pen when collapsed, X when expanded)\n const penIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"/></svg>`;\n const xIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\n\n this.toggleBtn = this.createBtn(\n penIcon,\n '',\n () => this.toggleCollapse(),\n );\n this.toggleBtn.classList.add('toolbar-toggle-btn');\n pill.appendChild(this.toggleBtn);\n\n // Badge for collapsed state\n this.expandBadge = document.createElement('span');\n this.expandBadge.className = 'toolbar-expand-badge hidden';\n this.expandBadge.textContent = '0';\n pill.appendChild(this.expandBadge);\n\n this.el.appendChild(pill);\n\n // Update toggle icon on transition end\n this.el.addEventListener('transitionend', () => {\n const icon = this.toggleBtn.querySelector('.toolbar-icon')!;\n icon.innerHTML = this.collapsed ? penIcon : xIcon;\n });\n }\n\n private createBtn(content: string | HTMLElement, tooltip: string, onClick: (() => void) | null): HTMLElement {\n const btn = document.createElement('button');\n btn.className = 'toolbar-btn';\n\n const iconWrap = document.createElement('span');\n iconWrap.className = 'toolbar-icon';\n if (typeof content === 'string') {\n iconWrap.innerHTML = content;\n } else {\n iconWrap.appendChild(content);\n }\n btn.appendChild(iconWrap);\n\n if (tooltip) {\n const tip = document.createElement('span');\n tip.className = 'toolbar-tooltip';\n tip.textContent = tooltip;\n btn.appendChild(tip);\n }\n\n if (onClick) {\n btn.addEventListener('click', onClick);\n }\n\n return btn;\n }\n\n private toggleCollapse(): void {\n this.collapsed = !this.collapsed;\n this.el.setAttribute('data-collapsed', String(this.collapsed));\n this.updateBadgeVisibility();\n if (this.collapsed) {\n this.onCollapse?.();\n }\n }\n\n setSettingsOpen(open: boolean): void {\n this.settingsOpen = open;\n this.el.classList.toggle('tooltips-hidden', open);\n }\n\n updateCount(count: number): void {\n this.countBadge.textContent = String(count);\n this.expandBadge.textContent = String(count);\n this.updateBadgeVisibility(count);\n\n const empty = count === 0;\n this.copyBtn.classList.toggle('disabled', empty);\n this.clearBtn.classList.toggle('disabled', empty);\n }\n\n private updateBadgeVisibility(count?: number): void {\n const c = count ?? parseInt(this.expandBadge.textContent || '0', 10);\n this.expandBadge.classList.toggle('hidden', c === 0 || !this.collapsed);\n }\n}\n","export class Overlay {\n readonly el: HTMLElement;\n private highlight: HTMLElement;\n private enabled = true;\n private blocking = true;\n private currentTarget: Element | null = null;\n private highlightColor = '#7C3AED';\n\n onClick?: (target: Element, rect: DOMRect) => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'refiner-overlay';\n this.el.setAttribute('data-blocking', 'true');\n\n this.highlight = document.createElement('div');\n this.highlight.className = 'refiner-highlight';\n this.highlight.style.display = 'none';\n\n root.appendChild(this.highlight);\n root.appendChild(this.el);\n\n this.el.addEventListener('mousemove', this.handleMouseMove);\n this.el.addEventListener('click', this.handleClick);\n this.el.addEventListener('mouseleave', () => this.hideHighlight());\n }\n\n private isOverOwnUI(x: number, y: number): boolean {\n const shadowEl = this.root.elementFromPoint(x, y);\n if (!shadowEl) return false;\n if (shadowEl === this.el || shadowEl === this.highlight) return false;\n return true;\n }\n\n private handleMouseMove = (e: MouseEvent): void => {\n if (!this.enabled) return;\n if (this.isOverOwnUI(e.clientX, e.clientY)) {\n this.hideHighlight();\n return;\n }\n\n const target = this.getElementAt(e.clientX, e.clientY);\n if (target && target !== this.currentTarget) {\n this.currentTarget = target;\n this.showHighlight(target);\n }\n };\n\n private handleClick = (e: MouseEvent): void => {\n if (!this.enabled) return;\n if (this.isOverOwnUI(e.clientX, e.clientY)) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const target = this.getElementAt(e.clientX, e.clientY);\n if (target) {\n const rect = target.getBoundingClientRect();\n this.onClick?.(target, rect);\n }\n };\n\n private getElementAt(x: number, y: number): Element | null {\n this.el.style.pointerEvents = 'none';\n this.highlight.style.pointerEvents = 'none';\n\n const el = document.elementFromPoint(x, y);\n\n this.el.style.pointerEvents = '';\n this.highlight.style.pointerEvents = '';\n\n if (el && el === this.root.host) return null;\n return el;\n }\n\n private showHighlight(target: Element): void {\n const rect = target.getBoundingClientRect();\n this.highlight.style.display = 'block';\n this.highlight.style.top = `${rect.top - 2}px`;\n this.highlight.style.left = `${rect.left - 2}px`;\n this.highlight.style.width = `${rect.width + 4}px`;\n this.highlight.style.height = `${rect.height + 4}px`;\n this.highlight.style.borderColor = this.highlightColor;\n }\n\n private hideHighlight(): void {\n this.highlight.style.display = 'none';\n this.currentTarget = null;\n }\n\n setHighlightColor(color: string): void {\n this.highlightColor = color;\n }\n\n setBlocking(blocking: boolean): void {\n this.blocking = blocking;\n this.el.setAttribute('data-blocking', String(blocking));\n if (!blocking) {\n this.hideHighlight();\n }\n }\n\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n this.el.classList.toggle('hidden', !enabled);\n if (!enabled) this.hideHighlight();\n }\n}\n","export class AnnotationDialog {\n readonly el: HTMLElement;\n private textarea!: HTMLTextAreaElement;\n private addBtn!: HTMLButtonElement;\n\n onSubmit?: (text: string) => void;\n onCancel?: () => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'refiner-dialog hidden';\n this.render();\n root.appendChild(this.el);\n }\n\n private render(): void {\n // Header\n const header = document.createElement('div');\n header.className = 'dialog-header';\n const label = document.createElement('span');\n label.textContent = 'What should change?';\n header.appendChild(label);\n this.el.appendChild(header);\n\n // Textarea\n this.textarea = document.createElement('textarea');\n this.textarea.className = 'dialog-textarea';\n this.textarea.placeholder = 'Describe the issue or improvement...';\n this.textarea.addEventListener('input', () => {\n this.addBtn.disabled = this.textarea.value.trim().length === 0;\n });\n this.textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && this.textarea.value.trim()) {\n this.submit();\n }\n if (e.key === 'Escape') {\n this.hide();\n this.onCancel?.();\n }\n });\n this.el.appendChild(this.textarea);\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'dialog-actions';\n\n const cancelBtn = document.createElement('button');\n cancelBtn.className = 'dialog-btn dialog-btn-cancel';\n cancelBtn.textContent = 'Cancel';\n cancelBtn.addEventListener('click', () => {\n this.hide();\n this.onCancel?.();\n });\n\n this.addBtn = document.createElement('button');\n this.addBtn.className = 'dialog-btn dialog-btn-add';\n this.addBtn.textContent = 'Add';\n this.addBtn.disabled = true;\n this.addBtn.addEventListener('click', () => this.submit());\n\n actions.appendChild(cancelBtn);\n actions.appendChild(this.addBtn);\n this.el.appendChild(actions);\n }\n\n private submit(): void {\n const text = this.textarea.value.trim();\n if (text) {\n this.onSubmit?.(text);\n this.hide();\n }\n }\n\n show(x: number, y: number): void {\n // Position: prefer below-right of click, but keep on screen\n const dialogW = 320;\n const dialogH = 200;\n let left = x + 12;\n let top = y + 12;\n\n if (left + dialogW > window.innerWidth - 16) {\n left = x - dialogW - 12;\n }\n if (top + dialogH > window.innerHeight - 16) {\n top = y - dialogH - 12;\n }\n\n this.el.style.left = `${Math.max(16, left)}px`;\n this.el.style.top = `${Math.max(16, top)}px`;\n this.el.classList.remove('hidden');\n\n this.textarea.value = '';\n this.addBtn.disabled = true;\n requestAnimationFrame(() => this.textarea.focus());\n }\n\n hide(): void {\n this.el.classList.add('hidden');\n this.textarea.value = '';\n }\n\n isVisible(): boolean {\n return !this.el.classList.contains('hidden');\n }\n}\n","import { Annotation } from './types';\nimport { AnnotationStore } from './annotation-store';\n\ninterface MarkerElement {\n el: HTMLElement;\n annotation: Annotation;\n}\n\nexport class AnnotationMarkers {\n private markers: Map<string, MarkerElement> = new Map();\n private container: HTMLElement;\n private rafId: number | null = null;\n private color = '#7C3AED';\n\n constructor(private root: ShadowRoot, private store: AnnotationStore) {\n this.container = document.createElement('div');\n this.container.className = 'refiner-markers';\n root.appendChild(this.container);\n\n store.on('add', (annotation) => this.addMarker(annotation));\n store.on('resolve', (annotation) => this.updateMarker(annotation));\n store.on('remove', (annotation) => this.removeMarker(annotation.id));\n\n const reposition = () => this.repositionAll();\n window.addEventListener('scroll', reposition, { passive: true });\n window.addEventListener('resize', reposition, { passive: true });\n }\n\n private addMarker(annotation: Annotation): void {\n const el = document.createElement('div');\n el.className = 'refiner-marker';\n el.setAttribute('data-annotation-marker', annotation.id);\n el.setAttribute('data-resolved', String(annotation.resolved));\n el.style.background = this.color;\n\n const index = this.markers.size + 1;\n el.textContent = String(index);\n\n // Tooltip\n const tooltip = document.createElement('div');\n tooltip.className = 'marker-tooltip';\n\n const tooltipText = document.createElement('div');\n tooltipText.textContent = annotation.text;\n tooltip.appendChild(tooltipText);\n\n const tooltipActions = document.createElement('div');\n tooltipActions.className = 'marker-tooltip-actions';\n\n const resolveBtn = document.createElement('button');\n resolveBtn.className = 'marker-tooltip-btn resolve';\n resolveBtn.textContent = 'Resolve';\n resolveBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.store.resolve(annotation.id);\n });\n\n const deleteBtn = document.createElement('button');\n deleteBtn.className = 'marker-tooltip-btn delete';\n deleteBtn.textContent = 'Delete';\n deleteBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.store.remove(annotation.id);\n });\n\n tooltipActions.appendChild(resolveBtn);\n tooltipActions.appendChild(deleteBtn);\n tooltip.appendChild(tooltipActions);\n el.appendChild(tooltip);\n\n this.positionMarker(el, annotation);\n this.container.appendChild(el);\n this.markers.set(annotation.id, { el, annotation });\n }\n\n private updateMarker(annotation: Annotation): void {\n const marker = this.markers.get(annotation.id);\n if (marker) {\n marker.annotation = annotation;\n marker.el.setAttribute('data-resolved', String(annotation.resolved));\n }\n }\n\n private removeMarker(id: string): void {\n const marker = this.markers.get(id);\n if (marker) {\n marker.el.remove();\n this.markers.delete(id);\n this.renumber();\n }\n }\n\n private renumber(): void {\n let i = 1;\n for (const [, marker] of this.markers) {\n const firstText = marker.el.childNodes[0];\n if (firstText && firstText.nodeType === Node.TEXT_NODE) {\n firstText.textContent = String(i);\n }\n i++;\n }\n }\n\n private positionMarker(el: HTMLElement, annotation: Annotation): void {\n const target = this.queryTarget(annotation.targetSelector);\n if (target) {\n const rect = target.getBoundingClientRect();\n el.style.top = `${rect.top - 8}px`;\n el.style.left = `${rect.right - 8}px`;\n } else {\n el.style.top = `${annotation.targetRect.y - 8}px`;\n el.style.left = `${annotation.targetRect.x + annotation.targetRect.width - 8}px`;\n }\n }\n\n private queryTarget(selector: string): Element | null {\n try {\n return document.querySelector(selector);\n } catch {\n return null;\n }\n }\n\n setColor(color: string): void {\n this.color = color;\n for (const [, marker] of this.markers) {\n marker.el.style.background = color;\n }\n }\n\n clearAll(): void {\n for (const [id] of this.markers) {\n this.removeMarker(id);\n }\n }\n\n private repositionAll(): void {\n if (this.rafId !== null) return;\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n for (const [, marker] of this.markers) {\n this.positionMarker(marker.el, marker.annotation);\n }\n });\n }\n}\n","const MARKER_COLORS = [\n { id: 'purple', color: '#7C3AED' },\n { id: 'blue', color: '#2563EB' },\n { id: 'green', color: '#059669' },\n { id: 'yellow', color: '#D97706' },\n { id: 'orange', color: '#EA580C' },\n { id: 'red', color: '#DC2626' },\n { id: 'pink', color: '#DB2777' },\n];\n\nexport interface Settings {\n clearOnCopy: boolean;\n blockInteractions: boolean;\n markerColor: string;\n}\n\nexport class SettingsPanel {\n readonly el: HTMLElement;\n private visible = false;\n private mcpDot!: HTMLElement;\n private mcpLabel!: HTMLElement;\n private settings: Settings = {\n clearOnCopy: false,\n blockInteractions: true,\n markerColor: '#7C3AED',\n };\n\n onChange?: (settings: Settings) => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'settings-panel hidden';\n this.render();\n root.appendChild(this.el);\n }\n\n private render(): void {\n // Header\n const header = document.createElement('div');\n header.className = 'settings-header';\n const title = document.createElement('span');\n title.className = 'settings-title';\n title.textContent = 'reFiner';\n const version = document.createElement('span');\n version.className = 'settings-version';\n version.textContent = 'v0.1.0';\n header.appendChild(title);\n header.appendChild(version);\n this.el.appendChild(header);\n\n this.el.appendChild(this.createDivider());\n\n // Marker color\n const colorSection = document.createElement('div');\n colorSection.className = 'settings-section';\n const colorLabel = document.createElement('span');\n colorLabel.className = 'settings-label';\n colorLabel.textContent = 'Marker Colour';\n colorSection.appendChild(colorLabel);\n\n const colorRow = document.createElement('div');\n colorRow.className = 'settings-color-row';\n for (const mc of MARKER_COLORS) {\n const swatch = document.createElement('button');\n swatch.className = 'settings-swatch';\n swatch.style.background = mc.color;\n swatch.setAttribute('data-color', mc.color);\n if (mc.color === this.settings.markerColor) {\n swatch.classList.add('selected');\n }\n swatch.addEventListener('click', () => {\n colorRow.querySelectorAll('.settings-swatch').forEach((s) =>\n s.classList.remove('selected')\n );\n swatch.classList.add('selected');\n this.settings.markerColor = mc.color;\n this.emitChange();\n });\n colorRow.appendChild(swatch);\n }\n colorSection.appendChild(colorRow);\n this.el.appendChild(colorSection);\n\n this.el.appendChild(this.createDivider());\n\n // Clear on copy\n this.el.appendChild(this.createCheckbox(\n 'Clear on copy',\n this.settings.clearOnCopy,\n (checked) => {\n this.settings.clearOnCopy = checked;\n this.emitChange();\n },\n ));\n\n // Block page interactions\n this.el.appendChild(this.createCheckbox(\n 'Block page interactions',\n this.settings.blockInteractions,\n (checked) => {\n this.settings.blockInteractions = checked;\n this.emitChange();\n },\n ));\n\n this.el.appendChild(this.createDivider());\n\n // MCP status\n const mcpRow = document.createElement('div');\n mcpRow.className = 'settings-mcp-row';\n\n this.mcpDot = document.createElement('span');\n this.mcpDot.className = 'settings-mcp-dot disconnected';\n\n this.mcpLabel = document.createElement('span');\n this.mcpLabel.className = 'settings-check-label';\n this.mcpLabel.textContent = 'MCP Disconnected';\n\n mcpRow.appendChild(this.mcpDot);\n mcpRow.appendChild(this.mcpLabel);\n this.el.appendChild(mcpRow);\n }\n\n private createCheckbox(label: string, initial: boolean, onChange: (v: boolean) => void): HTMLElement {\n const row = document.createElement('label');\n row.className = 'settings-check-row';\n\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'settings-checkbox';\n checkbox.checked = initial;\n checkbox.addEventListener('change', () => onChange(checkbox.checked));\n\n const text = document.createElement('span');\n text.className = 'settings-check-label';\n text.textContent = label;\n\n row.appendChild(checkbox);\n row.appendChild(text);\n return row;\n }\n\n private createDivider(): HTMLElement {\n const div = document.createElement('div');\n div.className = 'settings-divider';\n return div;\n }\n\n private emitChange(): void {\n this.onChange?.({ ...this.settings });\n }\n\n toggle(): void {\n this.visible = !this.visible;\n this.el.classList.toggle('hidden', !this.visible);\n }\n\n hide(): void {\n this.visible = false;\n this.el.classList.add('hidden');\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n setMcpStatus(connected: boolean): void {\n this.mcpDot.className = `settings-mcp-dot ${connected ? 'connected' : 'disconnected'}`;\n this.mcpLabel.textContent = connected ? 'MCP Connected' : 'MCP Disconnected';\n }\n\n getSettings(): Settings {\n return { ...this.settings };\n }\n}\n","import { AnnotationStore } from './annotation-store';\nimport { Annotation } from './types';\n\nexport class McpBridge {\n private baseUrl: string;\n private sessionId: string | null = null;\n private connected = false;\n private retryTimer: ReturnType<typeof setInterval> | null = null;\n\n onChange?: (connected: boolean) => void;\n\n constructor(\n private store: AnnotationStore,\n port: number = 4848,\n ) {\n this.baseUrl = `http://localhost:${port}`;\n this.discover();\n\n // Wire up store events\n this.store.on('add', (annotation) => this.postAnnotation(annotation));\n this.store.on('resolve', (annotation) => this.patchAnnotation(annotation));\n }\n\n private async discover(): Promise<void> {\n try {\n const res = await fetch(`${this.baseUrl}/health`);\n const data = await res.json();\n if (data && typeof data === 'object' && 'status' in data && data.status === 'ok') {\n this.connected = true;\n this.onChange?.(true);\n await this.createSession();\n this.stopRetry();\n }\n } catch {\n this.connected = false;\n this.onChange?.(false);\n this.startRetry();\n }\n }\n\n private startRetry(): void {\n if (this.retryTimer) return;\n this.retryTimer = setInterval(() => this.discover(), 5000);\n }\n\n private stopRetry(): void {\n if (this.retryTimer) {\n clearInterval(this.retryTimer);\n this.retryTimer = null;\n }\n }\n\n private async createSession(): Promise<void> {\n try {\n const res = await fetch(`${this.baseUrl}/sessions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n url: window.location.href,\n title: document.title || window.location.pathname,\n }),\n });\n const session = await res.json();\n this.sessionId = session.id;\n } catch {\n // Session creation failed — annotations won't sync but local still works\n }\n }\n\n private async postAnnotation(annotation: Annotation): Promise<void> {\n if (!this.connected || !this.sessionId) return;\n\n try {\n await fetch(`${this.baseUrl}/sessions/${this.sessionId}/annotations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n targetSelector: annotation.targetSelector,\n targetRect: annotation.targetRect,\n text: annotation.text,\n }),\n });\n } catch {\n // Silently fail — local annotation still exists\n }\n }\n\n private async patchAnnotation(annotation: Annotation): Promise<void> {\n if (!this.connected) return;\n\n try {\n await fetch(`${this.baseUrl}/annotations/${annotation.id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n resolved: true,\n summary: 'Resolved from browser',\n }),\n });\n } catch {\n // Silently fail\n }\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n destroy(): void {\n this.stopRetry();\n }\n}\n","import { RefinerOptions } from './types';\nimport { STYLES } from './styles';\nimport { AnnotationStore } from './annotation-store';\nimport { Toolbar } from './toolbar';\nimport { Overlay } from './overlay';\nimport { AnnotationDialog } from './annotation-dialog';\nimport { AnnotationMarkers } from './annotation-marker';\nimport { SettingsPanel } from './settings';\nimport { generateSelector } from './selector';\nimport { McpBridge } from './mcp-bridge';\n\nexport class Refiner {\n private host: HTMLDivElement;\n private shadow: ShadowRoot;\n private store: AnnotationStore;\n private toolbar: Toolbar;\n private overlay: Overlay;\n private dialog: AnnotationDialog;\n private markers: AnnotationMarkers;\n private settings: SettingsPanel;\n private mcpBridge: McpBridge | null = null;\n private currentTarget: Element | null = null;\n private currentRect: DOMRect | null = null;\n private clearOnCopy = false;\n\n constructor(options: RefinerOptions = {}) {\n // Create shadow host\n this.host = document.createElement('div');\n this.host.id = 'refiner-host';\n this.shadow = this.host.attachShadow({ mode: 'open' });\n\n // Inject styles\n const style = document.createElement('style');\n style.textContent = STYLES;\n this.shadow.appendChild(style);\n\n // Initialize components\n this.store = new AnnotationStore();\n this.toolbar = new Toolbar(this.shadow);\n this.settings = new SettingsPanel(this.shadow);\n this.overlay = new Overlay(this.shadow);\n this.dialog = new AnnotationDialog(this.shadow);\n this.markers = new AnnotationMarkers(this.shadow, this.store);\n\n // Wire up toolbar\n this.toolbar.onCopy = () => this.copyAnnotations();\n this.toolbar.onClear = () => this.clearAnnotations();\n this.toolbar.onSettings = () => {\n this.settings.toggle();\n this.toolbar.setSettingsOpen(this.settings.isVisible());\n };\n\n this.toolbar.onCollapse = () => {\n this.settings.hide();\n this.toolbar.setSettingsOpen(false);\n };\n\n // Wire up settings\n this.settings.onChange = (s) => {\n this.clearOnCopy = s.clearOnCopy;\n this.overlay.setBlocking(s.blockInteractions);\n this.markers.setColor(s.markerColor);\n this.overlay.setHighlightColor(s.markerColor);\n };\n\n // Wire up overlay click\n this.overlay.onClick = (target, rect) => {\n if (this.settings.isVisible()) {\n this.settings.hide();\n return;\n }\n if (this.dialog.isVisible()) {\n this.dialog.hide();\n return;\n }\n this.currentTarget = target;\n this.currentRect = rect;\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n this.dialog.show(centerX, centerY);\n };\n\n // Wire up dialog submit\n this.dialog.onSubmit = (text) => {\n if (this.currentTarget && this.currentRect) {\n const selector = generateSelector(this.currentTarget);\n this.store.add(selector, this.currentRect, text);\n this.toolbar.updateCount(this.store.getCount());\n }\n this.currentTarget = null;\n this.currentRect = null;\n };\n\n this.dialog.onCancel = () => {\n this.currentTarget = null;\n this.currentRect = null;\n };\n\n // Update count on resolve/remove\n this.store.on('resolve', () => this.toolbar.updateCount(this.store.getCount()));\n this.store.on('remove', () => this.toolbar.updateCount(this.store.getCount()));\n\n // MCP bridge (auto-discover by default)\n if (options.mcpEnabled !== false) {\n this.mcpBridge = new McpBridge(this.store, options.mcpPort);\n this.mcpBridge.onChange = (connected) => {\n this.settings.setMcpStatus(connected);\n };\n }\n\n // Mount\n document.body.appendChild(this.host);\n\n if (options.enabled === false) {\n this.disable();\n }\n }\n\n enable(): void {\n this.host.style.display = '';\n this.overlay.setEnabled(true);\n }\n\n disable(): void {\n this.host.style.display = 'none';\n this.overlay.setEnabled(false);\n }\n\n destroy(): void {\n this.mcpBridge?.destroy();\n this.host.remove();\n }\n\n getAnnotations() {\n return this.store.getAll();\n }\n\n getAnnotationCount(): number {\n return this.store.getCount();\n }\n\n formatForAgent(): string {\n const annotations = this.store.getAll();\n if (annotations.length === 0) return 'No annotations.';\n\n const pageTitle = document.title || window.location.pathname;\n const lines: string[] = [`# Design Annotations — ${pageTitle}`, ''];\n\n for (let i = 0; i < annotations.length; i++) {\n const a = annotations[i];\n const status = a.resolved ? ' (resolved)' : '';\n lines.push(`## ${i + 1}.${status}`);\n lines.push(`**Element:** \\`${a.targetSelector}\\``);\n lines.push(`**Issue:** ${a.text}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n }\n\n clearAnnotations(): void {\n const all = this.store.getAll();\n for (const a of all) {\n this.store.remove(a.id);\n }\n this.toolbar.updateCount(0);\n }\n\n copyAnnotations(): void {\n const text = this.formatForAgent();\n navigator.clipboard.writeText(text);\n\n if (this.clearOnCopy) {\n this.clearAnnotations();\n }\n }\n}\n","export const STYLES = `\n :host {\n all: initial;\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n color: #1a1a2e;\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ── Toolbar ── */\n\n .refiner-toolbar {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10;\n user-select: none;\n }\n\n .toolbar-pill {\n display: flex;\n align-items: center;\n position: relative;\n background: #1a1a2e;\n border-radius: 100px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15);\n padding: 6px;\n transform: scale(1);\n transform-origin: right center;\n transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .refiner-toolbar[data-collapsed=\"true\"] .toolbar-pill {\n transform: scale(0.92);\n }\n\n .toolbar-inner {\n display: flex;\n align-items: center;\n gap: 2px;\n overflow: hidden;\n clip-path: inset(0);\n max-width: 300px;\n opacity: 1;\n padding-right: 2px;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s ease 0.1s,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .refiner-toolbar[data-collapsed=\"true\"] .toolbar-inner {\n max-width: 0;\n opacity: 0;\n padding-right: 0;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.15s ease,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .toolbar-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: #a0a0b8;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.15s, background 0.15s;\n }\n\n .toolbar-btn:hover {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .toolbar-btn.active {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n }\n\n .toolbar-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .toolbar-count {\n font-size: 14px;\n font-weight: 700;\n min-width: 18px;\n text-align: center;\n }\n\n .toolbar-divider {\n width: 1px;\n height: 20px;\n background: rgba(255, 255, 255, 0.15);\n margin: 0 4px;\n flex-shrink: 0;\n }\n\n /* Tooltip */\n .toolbar-tooltip {\n position: absolute;\n bottom: calc(100% + 10px);\n left: 50%;\n transform: translateX(-50%);\n padding: 6px 10px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n }\n\n .toolbar-tooltip::after {\n content: '';\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 5px solid transparent;\n border-top-color: #1a1a2e;\n }\n\n .toolbar-btn:hover .toolbar-tooltip {\n opacity: 1;\n }\n\n .tooltips-hidden .toolbar-tooltip {\n display: none;\n }\n\n .toolbar-btn.disabled {\n opacity: 0.3;\n cursor: default;\n }\n\n .toolbar-btn.disabled:hover {\n color: #a0a0b8;\n background: transparent;\n }\n\n /* Toggle button (always visible) */\n .toolbar-toggle-btn {\n flex-shrink: 0;\n }\n\n /* Badge for collapsed state */\n .toolbar-expand-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 20px;\n height: 20px;\n padding: 0 5px;\n border-radius: 10px;\n background: #DC2626;\n color: #ffffff;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n }\n\n .toolbar-expand-badge.hidden {\n display: none;\n }\n\n /* ── Settings Panel ── */\n\n .settings-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 300px;\n z-index: 12;\n background: #1a1a2e;\n border-radius: 16px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 20px;\n color: #e8e8f0;\n transform-origin: bottom right;\n transition: transform 0.25s ease, opacity 0.1s ease;\n transform: scale(1);\n opacity: 1;\n }\n\n .settings-panel.hidden {\n transform: scale(0.4);\n opacity: 0;\n pointer-events: none;\n }\n\n .settings-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 4px;\n }\n\n .settings-title {\n font-size: 16px;\n font-weight: 700;\n font-style: normal;\n color: #ffffff;\n }\n\n .settings-version {\n font-size: 12px;\n color: #6b6b80;\n font-weight: 500;\n }\n\n .settings-divider {\n height: 1px;\n background: rgba(255, 255, 255, 0.08);\n margin: 16px 0;\n }\n\n .settings-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .settings-label {\n font-size: 14px;\n font-weight: 500;\n color: #c0c0d0;\n }\n\n .settings-color-row {\n display: flex;\n gap: 8px;\n }\n\n .settings-swatch {\n width: 24px;\n height: 24px;\n border-radius: 4px;\n border: 2px solid transparent;\n cursor: pointer;\n transition: transform 0.15s, border-color 0.15s;\n outline: none;\n }\n\n .settings-swatch:hover {\n transform: scale(1.1);\n }\n\n .settings-swatch.selected {\n border-color: #ffffff;\n transform: scale(1.1);\n }\n\n .settings-check-row {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n padding: 2px 0;\n }\n\n .settings-checkbox {\n appearance: none;\n -webkit-appearance: none;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 2px solid #4a4a60;\n background: transparent;\n cursor: pointer;\n position: relative;\n flex-shrink: 0;\n transition: background 0.15s, border-color 0.15s;\n }\n\n .settings-checkbox:checked {\n background: #2563EB;\n border-color: #2563EB;\n }\n\n .settings-checkbox:checked::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 5px;\n width: 5px;\n height: 9px;\n border: solid #ffffff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .settings-check-label {\n font-size: 14px;\n font-weight: 500;\n color: #e8e8f0;\n }\n\n /* ── Overlay ── */\n\n .refiner-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n cursor: crosshair;\n z-index: 1;\n }\n\n .refiner-overlay[data-blocking=\"true\"] {\n pointer-events: all;\n }\n\n .refiner-overlay[data-blocking=\"false\"] {\n pointer-events: none;\n }\n\n .refiner-overlay.hidden {\n display: none;\n }\n\n /* ── Highlight ── */\n\n .refiner-highlight {\n position: fixed;\n pointer-events: none;\n border: 2px dashed;\n border-radius: 3px;\n z-index: 2;\n transition: all 0.1s ease;\n }\n\n /* ── Dialog ── */\n\n .refiner-dialog {\n position: fixed;\n width: 320px;\n background: #1a1a2e;\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 14px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 11;\n color: #e8e8f0;\n animation: dialog-in 0.2s ease;\n }\n\n @keyframes dialog-in {\n from { opacity: 0; transform: translateY(4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .refiner-dialog.hidden {\n display: none;\n }\n\n .dialog-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .dialog-header span {\n font-size: 12px;\n font-weight: 600;\n color: #c0c0d0;\n }\n\n .dialog-textarea {\n width: 100%;\n min-height: 72px;\n padding: 10px 12px;\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 10px;\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: #e8e8f0;\n background: rgba(255, 255, 255, 0.06);\n resize: vertical;\n outline: none;\n transition: border-color 0.15s;\n }\n\n .dialog-textarea:focus {\n border-color: rgba(255, 255, 255, 0.25);\n }\n\n .dialog-textarea::placeholder {\n color: #6b6b80;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n }\n\n .dialog-btn {\n height: 32px;\n padding: 0 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .dialog-btn-cancel {\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.12);\n color: #a0a0b8;\n }\n\n .dialog-btn-cancel:hover {\n background: rgba(255, 255, 255, 0.08);\n color: #e8e8f0;\n }\n\n .dialog-btn-add {\n background: #2563EB;\n border: none;\n color: #ffffff;\n }\n\n .dialog-btn-add:hover {\n background: #3B82F6;\n }\n\n .dialog-btn-add:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n /* ── Markers ── */\n\n .refiner-marker {\n position: fixed;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n color: #ffffff;\n cursor: pointer;\n z-index: 10;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n transition: transform 0.15s;\n pointer-events: all;\n }\n\n .refiner-marker:hover {\n transform: scale(1.2);\n }\n\n .refiner-marker[data-resolved=\"true\"] {\n opacity: 0.4;\n }\n\n .marker-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n width: 220px;\n padding: 10px 12px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n line-height: 1.4;\n border-radius: 10px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .refiner-marker:hover .marker-tooltip {\n opacity: 1;\n }\n\n .marker-tooltip-actions {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n border-top: 1px solid rgba(255,255,255,0.1);\n padding-top: 8px;\n }\n\n .marker-tooltip-btn {\n height: 22px;\n padding: 0 8px;\n border-radius: 5px;\n border: none;\n font-size: 10px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .marker-tooltip-btn.resolve {\n background: #34D399;\n color: #0a2e1f;\n }\n\n .marker-tooltip-btn.resolve:hover {\n background: #4ade80;\n }\n\n .marker-tooltip-btn.delete {\n background: rgba(255,255,255,0.1);\n color: #e8e8f0;\n }\n\n .marker-tooltip-btn.delete:hover {\n background: #FF6B6B;\n color: #fff;\n }\n\n /* MCP status */\n .settings-mcp-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n }\n\n .settings-mcp-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .settings-mcp-dot.connected {\n background: #34D399;\n box-shadow: 0 0 6px #34D39980;\n }\n\n .settings-mcp-dot.disconnected {\n background: #6B7280;\n }\n`;\n","/**\n * Generate a stable CSS selector for a DOM element.\n * Priority: #id > tag.class > nth-child path\n */\nexport function generateSelector(el: Element): string {\n if (el.id) {\n return `#${CSS.escape(el.id)}`;\n }\n\n // Try tag + distinctive class\n if (el.classList.length > 0) {\n const tag = el.tagName.toLowerCase();\n const classSelector = `${tag}.${Array.from(el.classList).map(CSS.escape).join('.')}`;\n if (document.querySelectorAll(classSelector).length === 1) {\n return classSelector;\n }\n }\n\n // Build nth-child path\n const parts: string[] = [];\n let current: Element | null = el;\n\n while (current && current !== document.documentElement) {\n const tag = current.tagName.toLowerCase();\n const parent: Element | null = current.parentElement;\n\n if (current.id) {\n parts.unshift(`#${CSS.escape(current.id)}`);\n break;\n }\n\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (c: Element) => c.tagName === current!.tagName\n );\n if (siblings.length === 1) {\n parts.unshift(tag);\n } else {\n const index = siblings.indexOf(current) + 1;\n parts.unshift(`${tag}:nth-child(${index})`);\n }\n } else {\n parts.unshift(tag);\n }\n\n current = parent;\n }\n\n return parts.join(' > ');\n}\n","import { Refiner } from './refiner';\nimport type { Annotation, RefinerOptions } from './types';\n\nexport { Refiner };\nexport type { Annotation, RefinerOptions };\n\n// Auto-initialize when loaded via script tag\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n const init = () => {\n // Skip if already initialized (e.g. bookmarklet + script tag both present)\n if ((window as any).__refiner) return;\n\n // Read config from script tag data attributes\n const script = document.currentScript as HTMLScriptElement | null;\n const position = (script?.dataset.refinerPosition as 'left' | 'right') ?? 'right';\n const enabled = script?.dataset.refinerEnabled !== 'false';\n const mcpPort = script?.dataset.refinerMcpPort ? parseInt(script.dataset.refinerMcpPort, 10) : undefined;\n const mcpEnabled = script?.dataset.refinerMcpEnabled !== 'false';\n\n const refiner = new Refiner({ position, enabled, mcpPort, mcpEnabled });\n (window as any).__refiner = refiner;\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', init);\n } else {\n init();\n }\n}\n"],"names":["AnnotationStore","constructor","this","annotations","Map","listeners","add","targetSelector","targetRect","text","annotation","id","crypto","randomUUID","x","y","width","height","timestamp","Date","now","resolved","set","emit","resolve","get","remove","delete","getAll","Array","from","values","getPending","filter","a","getCount","size","exportJSON","JSON","stringify","on","event","listener","has","Set","off","forEach","fn","Toolbar","root","collapsed","settingsOpen","el","document","createElement","className","setAttribute","render","appendChild","requestAnimationFrame","updateBadgeVisibility","pill","innerEl","countBadge","textContent","createBtn","copyIcon","copyBtn","classList","contains","onCopy","querySelector","innerHTML","setTimeout","clearBtn","onClear","onSettings","divider","penIcon","toggleBtn","toggleCollapse","expandBadge","addEventListener","content","tooltip","onClick","btn","iconWrap","tip","String","onCollapse","setSettingsOpen","open","toggle","updateCount","count","empty","c","parseInt","Overlay","enabled","blocking","currentTarget","highlightColor","handleMouseMove","e","isOverOwnUI","clientX","clientY","hideHighlight","target","getElementAt","showHighlight","handleClick","preventDefault","stopPropagation","rect","getBoundingClientRect","highlight","style","display","shadowEl","elementFromPoint","pointerEvents","host","top","left","borderColor","setHighlightColor","color","setBlocking","setEnabled","AnnotationDialog","header","label","textarea","placeholder","addBtn","disabled","value","trim","length","key","metaKey","ctrlKey","submit","hide","onCancel","actions","cancelBtn","onSubmit","show","window","innerWidth","innerHeight","Math","max","focus","isVisible","AnnotationMarkers","store","markers","rafId","container","addMarker","updateMarker","removeMarker","reposition","repositionAll","passive","background","index","tooltipText","tooltipActions","resolveBtn","deleteBtn","positionMarker","marker","renumber","i","firstText","childNodes","nodeType","Node","TEXT_NODE","queryTarget","right","selector","setColor","clearAll","MARKER_COLORS","SettingsPanel","visible","settings","clearOnCopy","blockInteractions","markerColor","title","version","createDivider","colorSection","colorLabel","colorRow","mc","swatch","querySelectorAll","s","emitChange","createCheckbox","checked","mcpRow","mcpDot","mcpLabel","initial","onChange","row","checkbox","type","div","setMcpStatus","connected","getSettings","McpBridge","port","sessionId","retryTimer","baseUrl","discover","postAnnotation","patchAnnotation","res","fetch","data","json","status","createSession","stopRetry","startRetry","setInterval","clearInterval","method","headers","body","url","location","href","pathname","session","summary","isConnected","destroy","Refiner","options","mcpBridge","currentRect","shadow","attachShadow","mode","toolbar","overlay","dialog","copyAnnotations","clearAnnotations","centerX","centerY","CSS","escape","classSelector","tagName","toLowerCase","map","join","parts","current","documentElement","tag","parent","parentElement","unshift","siblings","children","indexOf","generateSelector","mcpEnabled","mcpPort","disable","enable","getAnnotations","getAnnotationCount","formatForAgent","lines","push","all","navigator","clipboard","writeText","init","__refiner","script","currentScript","position","dataset","refinerPosition","refinerEnabled","refinerMcpPort","undefined","refinerMcpEnabled","refiner","readyState"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"refiner.mjs","sources":["../src/annotation-store.ts","../src/toolbar.ts","../src/overlay.ts","../src/annotation-dialog.ts","../src/annotation-marker.ts","../src/settings.ts","../src/mcp-bridge.ts","../src/refiner.ts","../src/styles.ts","../src/selector.ts","../src/index.ts"],"sourcesContent":["import { Annotation } from './types';\n\ntype Listener = (annotation: Annotation) => void;\n\nexport class AnnotationStore {\n private annotations: Map<string, Annotation> = new Map();\n private listeners: Map<string, Set<Listener>> = new Map();\n\n add(targetSelector: string, targetRect: DOMRect, text: string): Annotation {\n const annotation: Annotation = {\n id: crypto.randomUUID(),\n targetSelector,\n targetRect: {\n x: targetRect.x,\n y: targetRect.y,\n width: targetRect.width,\n height: targetRect.height,\n },\n text,\n timestamp: Date.now(),\n resolved: false,\n };\n this.annotations.set(annotation.id, annotation);\n this.emit('add', annotation);\n return annotation;\n }\n\n resolve(id: string): void {\n const annotation = this.annotations.get(id);\n if (annotation) {\n annotation.resolved = true;\n this.emit('resolve', annotation);\n }\n }\n\n remove(id: string): void {\n const annotation = this.annotations.get(id);\n if (annotation) {\n this.annotations.delete(id);\n this.emit('remove', annotation);\n }\n }\n\n get(id: string): Annotation | undefined {\n return this.annotations.get(id);\n }\n\n getAll(): Annotation[] {\n return Array.from(this.annotations.values());\n }\n\n getPending(): Annotation[] {\n return this.getAll().filter((a) => !a.resolved);\n }\n\n getCount(): number {\n return this.annotations.size;\n }\n\n exportJSON(): string {\n return JSON.stringify(this.getAll(), null, 2);\n }\n\n on(event: string, listener: Listener): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n }\n\n off(event: string, listener: Listener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: string, annotation: Annotation): void {\n this.listeners.get(event)?.forEach((fn) => fn(annotation));\n }\n}\n","export class Toolbar {\n readonly el: HTMLElement;\n private collapsed = true;\n private countBadge!: HTMLElement;\n private expandBadge!: HTMLElement;\n private innerEl!: HTMLElement;\n private copyBtn!: HTMLElement;\n private clearBtn!: HTMLElement;\n private toggleBtn!: HTMLElement;\n private settingsOpen = false;\n\n onCopy?: () => void;\n onClear?: () => void;\n onSettings?: () => void;\n onCollapse?: () => void;\n onExpand?: () => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'refiner-toolbar';\n this.el.setAttribute('data-refiner-toolbar', '');\n this.el.setAttribute('data-collapsed', 'true');\n this.render();\n root.appendChild(this.el);\n\n // Expand on first load after a short delay\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.collapsed = false;\n this.el.setAttribute('data-collapsed', 'false');\n this.updateBadgeVisibility();\n });\n });\n }\n\n private render(): void {\n const pill = document.createElement('div');\n pill.className = 'toolbar-pill';\n\n // Inner (collapsible buttons)\n this.innerEl = document.createElement('div');\n this.innerEl.className = 'toolbar-inner';\n\n // Note count\n this.countBadge = document.createElement('span');\n this.countBadge.className = 'toolbar-count';\n this.countBadge.textContent = '0';\n this.innerEl.appendChild(this.createBtn(\n this.countBadge,\n 'Annotations',\n null,\n ));\n\n // Copy\n const copyIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`;\n const checkIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n this.copyBtn = this.createBtn(\n copyIcon,\n 'Copy annotations',\n () => {\n if (this.copyBtn.classList.contains('disabled')) return;\n this.onCopy?.();\n this.copyBtn.querySelector('.toolbar-icon')!.innerHTML = checkIcon;\n setTimeout(() => {\n this.copyBtn.querySelector('.toolbar-icon')!.innerHTML = copyIcon;\n }, 1500);\n },\n );\n this.copyBtn.classList.add('disabled');\n this.innerEl.appendChild(this.copyBtn);\n\n // Clear all\n this.clearBtn = this.createBtn(\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n 'Clear all',\n () => {\n if (this.clearBtn.classList.contains('disabled')) return;\n this.onClear?.();\n },\n );\n this.clearBtn.classList.add('disabled');\n this.innerEl.appendChild(this.clearBtn);\n\n // Settings\n this.innerEl.appendChild(this.createBtn(\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\"/></svg>`,\n 'Settings',\n () => this.onSettings?.(),\n ));\n\n // Divider\n const divider = document.createElement('div');\n divider.className = 'toolbar-divider';\n this.innerEl.appendChild(divider);\n\n pill.appendChild(this.innerEl);\n\n // Toggle button (always visible — pen when collapsed, X when expanded)\n const penIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"/></svg>`;\n const xIcon = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`;\n\n this.toggleBtn = this.createBtn(\n penIcon,\n '',\n () => this.toggleCollapse(),\n );\n this.toggleBtn.classList.add('toolbar-toggle-btn');\n pill.appendChild(this.toggleBtn);\n\n // Badge for collapsed state\n this.expandBadge = document.createElement('span');\n this.expandBadge.className = 'toolbar-expand-badge hidden';\n this.expandBadge.textContent = '0';\n pill.appendChild(this.expandBadge);\n\n this.el.appendChild(pill);\n\n // Update toggle icon on transition end\n this.el.addEventListener('transitionend', () => {\n const icon = this.toggleBtn.querySelector('.toolbar-icon')!;\n icon.innerHTML = this.collapsed ? penIcon : xIcon;\n });\n }\n\n private createBtn(content: string | HTMLElement, tooltip: string, onClick: (() => void) | null): HTMLElement {\n const btn = document.createElement('button');\n btn.className = 'toolbar-btn';\n\n const iconWrap = document.createElement('span');\n iconWrap.className = 'toolbar-icon';\n if (typeof content === 'string') {\n iconWrap.innerHTML = content;\n } else {\n iconWrap.appendChild(content);\n }\n btn.appendChild(iconWrap);\n\n if (tooltip) {\n const tip = document.createElement('span');\n tip.className = 'toolbar-tooltip';\n tip.textContent = tooltip;\n btn.appendChild(tip);\n }\n\n if (onClick) {\n btn.addEventListener('click', onClick);\n }\n\n return btn;\n }\n\n private toggleCollapse(): void {\n this.collapsed = !this.collapsed;\n this.el.setAttribute('data-collapsed', String(this.collapsed));\n this.updateBadgeVisibility();\n if (this.collapsed) {\n this.onCollapse?.();\n } else {\n this.onExpand?.();\n }\n }\n\n setSettingsOpen(open: boolean): void {\n this.settingsOpen = open;\n this.el.classList.toggle('tooltips-hidden', open);\n }\n\n updateCount(count: number): void {\n this.countBadge.textContent = String(count);\n this.expandBadge.textContent = String(count);\n this.updateBadgeVisibility(count);\n\n const empty = count === 0;\n this.copyBtn.classList.toggle('disabled', empty);\n this.clearBtn.classList.toggle('disabled', empty);\n }\n\n private updateBadgeVisibility(count?: number): void {\n const c = count ?? parseInt(this.expandBadge.textContent || '0', 10);\n this.expandBadge.classList.toggle('hidden', c === 0 || !this.collapsed);\n }\n}\n","export class Overlay {\n readonly el: HTMLElement;\n private highlight: HTMLElement;\n private enabled = true;\n private blocking = true;\n private currentTarget: Element | null = null;\n private highlightColor = '#7C3AED';\n\n onClick?: (target: Element, rect: DOMRect) => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'refiner-overlay';\n this.el.setAttribute('data-blocking', 'true');\n\n this.highlight = document.createElement('div');\n this.highlight.className = 'refiner-highlight';\n this.highlight.style.display = 'none';\n\n root.appendChild(this.highlight);\n root.appendChild(this.el);\n\n this.el.addEventListener('mousemove', this.handleMouseMove);\n this.el.addEventListener('click', this.handleClick);\n this.el.addEventListener('mouseleave', () => this.hideHighlight());\n\n document.addEventListener('keydown', this.handleKeyBlock, true);\n }\n\n private isOverOwnUI(x: number, y: number): boolean {\n const shadowEl = this.root.elementFromPoint(x, y);\n if (!shadowEl) return false;\n if (shadowEl === this.el || shadowEl === this.highlight) return false;\n return true;\n }\n\n private handleMouseMove = (e: MouseEvent): void => {\n if (!this.enabled) return;\n if (this.isOverOwnUI(e.clientX, e.clientY)) {\n this.hideHighlight();\n return;\n }\n\n const target = this.getElementAt(e.clientX, e.clientY);\n if (target && target !== this.currentTarget) {\n this.currentTarget = target;\n this.showHighlight(target);\n }\n };\n\n private handleClick = (e: MouseEvent): void => {\n if (!this.enabled) return;\n if (this.isOverOwnUI(e.clientX, e.clientY)) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const target = this.getElementAt(e.clientX, e.clientY);\n if (target) {\n const rect = target.getBoundingClientRect();\n this.onClick?.(target, rect);\n }\n };\n\n private handleKeyBlock = (e: KeyboardEvent): void => {\n if (!this.enabled || !this.blocking) return;\n // Allow keys when focus is inside refiner's own UI (e.g. annotation dialog textarea)\n const target = e.target as Element;\n if (target && (target === this.root.host || this.root.host.contains(target))) return;\n\n e.preventDefault();\n e.stopPropagation();\n };\n\n private getElementAt(x: number, y: number): Element | null {\n this.el.style.pointerEvents = 'none';\n this.highlight.style.pointerEvents = 'none';\n\n const el = document.elementFromPoint(x, y);\n\n this.el.style.pointerEvents = '';\n this.highlight.style.pointerEvents = '';\n\n if (el && el === this.root.host) return null;\n return el;\n }\n\n private showHighlight(target: Element): void {\n const rect = target.getBoundingClientRect();\n this.highlight.style.display = 'block';\n this.highlight.style.top = `${rect.top - 2}px`;\n this.highlight.style.left = `${rect.left - 2}px`;\n this.highlight.style.width = `${rect.width + 4}px`;\n this.highlight.style.height = `${rect.height + 4}px`;\n this.highlight.style.borderColor = this.highlightColor;\n }\n\n private hideHighlight(): void {\n this.highlight.style.display = 'none';\n this.currentTarget = null;\n }\n\n setHighlightColor(color: string): void {\n this.highlightColor = color;\n }\n\n setBlocking(blocking: boolean): void {\n this.blocking = blocking;\n this.el.setAttribute('data-blocking', String(blocking));\n if (!blocking) {\n this.hideHighlight();\n }\n }\n\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n this.el.classList.toggle('hidden', !enabled);\n if (!enabled) this.hideHighlight();\n }\n}\n","export class AnnotationDialog {\n readonly el: HTMLElement;\n private textarea!: HTMLTextAreaElement;\n private addBtn!: HTMLButtonElement;\n\n onSubmit?: (text: string) => void;\n onCancel?: () => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'refiner-dialog hidden';\n this.render();\n root.appendChild(this.el);\n }\n\n private render(): void {\n // Header\n const header = document.createElement('div');\n header.className = 'dialog-header';\n const label = document.createElement('span');\n label.textContent = 'What should change?';\n header.appendChild(label);\n this.el.appendChild(header);\n\n // Textarea\n this.textarea = document.createElement('textarea');\n this.textarea.className = 'dialog-textarea';\n this.textarea.placeholder = 'Describe the issue or improvement...';\n this.textarea.addEventListener('input', () => {\n this.addBtn.disabled = this.textarea.value.trim().length === 0;\n });\n this.textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && this.textarea.value.trim()) {\n this.submit();\n }\n if (e.key === 'Escape') {\n this.hide();\n this.onCancel?.();\n }\n });\n this.el.appendChild(this.textarea);\n\n // Actions\n const actions = document.createElement('div');\n actions.className = 'dialog-actions';\n\n const cancelBtn = document.createElement('button');\n cancelBtn.className = 'dialog-btn dialog-btn-cancel';\n cancelBtn.textContent = 'Cancel';\n cancelBtn.addEventListener('click', () => {\n this.hide();\n this.onCancel?.();\n });\n\n this.addBtn = document.createElement('button');\n this.addBtn.className = 'dialog-btn dialog-btn-add';\n this.addBtn.textContent = 'Add';\n this.addBtn.disabled = true;\n this.addBtn.addEventListener('click', () => this.submit());\n\n actions.appendChild(cancelBtn);\n actions.appendChild(this.addBtn);\n this.el.appendChild(actions);\n }\n\n private submit(): void {\n const text = this.textarea.value.trim();\n if (text) {\n this.onSubmit?.(text);\n this.hide();\n }\n }\n\n show(x: number, y: number): void {\n // Position: prefer below-right of click, but keep on screen\n const dialogW = 320;\n const dialogH = 200;\n let left = x + 12;\n let top = y + 12;\n\n if (left + dialogW > window.innerWidth - 16) {\n left = x - dialogW - 12;\n }\n if (top + dialogH > window.innerHeight - 16) {\n top = y - dialogH - 12;\n }\n\n this.el.style.left = `${Math.max(16, left)}px`;\n this.el.style.top = `${Math.max(16, top)}px`;\n this.el.classList.remove('hidden');\n\n this.textarea.value = '';\n this.addBtn.disabled = true;\n requestAnimationFrame(() => this.textarea.focus());\n }\n\n hide(): void {\n this.el.classList.add('hidden');\n this.textarea.value = '';\n }\n\n isVisible(): boolean {\n return !this.el.classList.contains('hidden');\n }\n}\n","import { Annotation } from './types';\nimport { AnnotationStore } from './annotation-store';\n\ninterface MarkerElement {\n el: HTMLElement;\n annotation: Annotation;\n}\n\nexport class AnnotationMarkers {\n private markers: Map<string, MarkerElement> = new Map();\n private container: HTMLElement;\n private rafId: number | null = null;\n private color = '#7C3AED';\n\n constructor(private root: ShadowRoot, private store: AnnotationStore) {\n this.container = document.createElement('div');\n this.container.className = 'refiner-markers';\n root.appendChild(this.container);\n\n store.on('add', (annotation) => this.addMarker(annotation));\n store.on('resolve', (annotation) => this.updateMarker(annotation));\n store.on('remove', (annotation) => this.removeMarker(annotation.id));\n\n const reposition = () => this.repositionAll();\n window.addEventListener('scroll', reposition, { passive: true });\n window.addEventListener('resize', reposition, { passive: true });\n }\n\n private addMarker(annotation: Annotation): void {\n const el = document.createElement('div');\n el.className = 'refiner-marker';\n el.setAttribute('data-annotation-marker', annotation.id);\n el.setAttribute('data-resolved', String(annotation.resolved));\n el.style.background = this.color;\n\n const index = this.markers.size + 1;\n el.textContent = String(index);\n\n // Tooltip\n const tooltip = document.createElement('div');\n tooltip.className = 'marker-tooltip';\n\n const tooltipText = document.createElement('div');\n tooltipText.textContent = annotation.text;\n tooltip.appendChild(tooltipText);\n\n const tooltipActions = document.createElement('div');\n tooltipActions.className = 'marker-tooltip-actions';\n\n const resolveBtn = document.createElement('button');\n resolveBtn.className = 'marker-tooltip-btn resolve';\n resolveBtn.textContent = 'Resolve';\n resolveBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.store.resolve(annotation.id);\n });\n\n const deleteBtn = document.createElement('button');\n deleteBtn.className = 'marker-tooltip-btn delete';\n deleteBtn.textContent = 'Delete';\n deleteBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.store.remove(annotation.id);\n });\n\n tooltipActions.appendChild(resolveBtn);\n tooltipActions.appendChild(deleteBtn);\n tooltip.appendChild(tooltipActions);\n el.appendChild(tooltip);\n\n this.positionMarker(el, annotation);\n this.container.appendChild(el);\n this.markers.set(annotation.id, { el, annotation });\n }\n\n private updateMarker(annotation: Annotation): void {\n const marker = this.markers.get(annotation.id);\n if (marker) {\n marker.annotation = annotation;\n marker.el.setAttribute('data-resolved', String(annotation.resolved));\n }\n }\n\n private removeMarker(id: string): void {\n const marker = this.markers.get(id);\n if (marker) {\n marker.el.remove();\n this.markers.delete(id);\n this.renumber();\n }\n }\n\n private renumber(): void {\n let i = 1;\n for (const [, marker] of this.markers) {\n const firstText = marker.el.childNodes[0];\n if (firstText && firstText.nodeType === Node.TEXT_NODE) {\n firstText.textContent = String(i);\n }\n i++;\n }\n }\n\n private positionMarker(el: HTMLElement, annotation: Annotation): void {\n const target = this.queryTarget(annotation.targetSelector);\n if (target) {\n const rect = target.getBoundingClientRect();\n el.style.top = `${rect.top - 8}px`;\n el.style.left = `${rect.right - 8}px`;\n } else {\n el.style.top = `${annotation.targetRect.y - 8}px`;\n el.style.left = `${annotation.targetRect.x + annotation.targetRect.width - 8}px`;\n }\n }\n\n private queryTarget(selector: string): Element | null {\n try {\n return document.querySelector(selector);\n } catch {\n return null;\n }\n }\n\n setColor(color: string): void {\n this.color = color;\n for (const [, marker] of this.markers) {\n marker.el.style.background = color;\n }\n }\n\n clearAll(): void {\n for (const [id] of this.markers) {\n this.removeMarker(id);\n }\n }\n\n private repositionAll(): void {\n if (this.rafId !== null) return;\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n for (const [, marker] of this.markers) {\n this.positionMarker(marker.el, marker.annotation);\n }\n });\n }\n}\n","const MARKER_COLORS = [\n { id: 'purple', color: '#7C3AED' },\n { id: 'blue', color: '#2563EB' },\n { id: 'green', color: '#059669' },\n { id: 'yellow', color: '#D97706' },\n { id: 'orange', color: '#EA580C' },\n { id: 'red', color: '#DC2626' },\n { id: 'pink', color: '#DB2777' },\n];\n\nexport interface Settings {\n clearOnCopy: boolean;\n blockInteractions: boolean;\n markerColor: string;\n}\n\nexport class SettingsPanel {\n readonly el: HTMLElement;\n private visible = false;\n private mcpDot!: HTMLElement;\n private mcpLabel!: HTMLElement;\n private settings: Settings = {\n clearOnCopy: false,\n blockInteractions: true,\n markerColor: '#7C3AED',\n };\n\n onChange?: (settings: Settings) => void;\n\n constructor(private root: ShadowRoot) {\n this.el = document.createElement('div');\n this.el.className = 'settings-panel hidden';\n this.render();\n root.appendChild(this.el);\n }\n\n private render(): void {\n // Header\n const header = document.createElement('div');\n header.className = 'settings-header';\n const title = document.createElement('span');\n title.className = 'settings-title';\n title.textContent = 'reFiner';\n const version = document.createElement('span');\n version.className = 'settings-version';\n version.textContent = 'v0.1.0';\n header.appendChild(title);\n header.appendChild(version);\n this.el.appendChild(header);\n\n this.el.appendChild(this.createDivider());\n\n // Marker color\n const colorSection = document.createElement('div');\n colorSection.className = 'settings-section';\n const colorLabel = document.createElement('span');\n colorLabel.className = 'settings-label';\n colorLabel.textContent = 'Marker Colour';\n colorSection.appendChild(colorLabel);\n\n const colorRow = document.createElement('div');\n colorRow.className = 'settings-color-row';\n for (const mc of MARKER_COLORS) {\n const swatch = document.createElement('button');\n swatch.className = 'settings-swatch';\n swatch.style.background = mc.color;\n swatch.setAttribute('data-color', mc.color);\n if (mc.color === this.settings.markerColor) {\n swatch.classList.add('selected');\n }\n swatch.addEventListener('click', () => {\n colorRow.querySelectorAll('.settings-swatch').forEach((s) =>\n s.classList.remove('selected')\n );\n swatch.classList.add('selected');\n this.settings.markerColor = mc.color;\n this.emitChange();\n });\n colorRow.appendChild(swatch);\n }\n colorSection.appendChild(colorRow);\n this.el.appendChild(colorSection);\n\n this.el.appendChild(this.createDivider());\n\n // Clear on copy\n this.el.appendChild(this.createCheckbox(\n 'Clear on copy',\n this.settings.clearOnCopy,\n (checked) => {\n this.settings.clearOnCopy = checked;\n this.emitChange();\n },\n ));\n\n // Block page interactions\n this.el.appendChild(this.createCheckbox(\n 'Block page interactions',\n this.settings.blockInteractions,\n (checked) => {\n this.settings.blockInteractions = checked;\n this.emitChange();\n },\n ));\n\n this.el.appendChild(this.createDivider());\n\n // MCP status\n const mcpRow = document.createElement('div');\n mcpRow.className = 'settings-mcp-row';\n\n this.mcpDot = document.createElement('span');\n this.mcpDot.className = 'settings-mcp-dot disconnected';\n\n this.mcpLabel = document.createElement('span');\n this.mcpLabel.className = 'settings-check-label';\n this.mcpLabel.textContent = 'MCP Disconnected';\n\n mcpRow.appendChild(this.mcpDot);\n mcpRow.appendChild(this.mcpLabel);\n this.el.appendChild(mcpRow);\n }\n\n private createCheckbox(label: string, initial: boolean, onChange: (v: boolean) => void): HTMLElement {\n const row = document.createElement('label');\n row.className = 'settings-check-row';\n\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'settings-checkbox';\n checkbox.checked = initial;\n checkbox.addEventListener('change', () => onChange(checkbox.checked));\n\n const text = document.createElement('span');\n text.className = 'settings-check-label';\n text.textContent = label;\n\n row.appendChild(checkbox);\n row.appendChild(text);\n return row;\n }\n\n private createDivider(): HTMLElement {\n const div = document.createElement('div');\n div.className = 'settings-divider';\n return div;\n }\n\n private emitChange(): void {\n this.onChange?.({ ...this.settings });\n }\n\n toggle(): void {\n this.visible = !this.visible;\n this.el.classList.toggle('hidden', !this.visible);\n }\n\n hide(): void {\n this.visible = false;\n this.el.classList.add('hidden');\n }\n\n isVisible(): boolean {\n return this.visible;\n }\n\n setMcpStatus(connected: boolean): void {\n this.mcpDot.className = `settings-mcp-dot ${connected ? 'connected' : 'disconnected'}`;\n this.mcpLabel.textContent = connected ? 'MCP Connected' : 'MCP Disconnected';\n }\n\n getSettings(): Settings {\n return { ...this.settings };\n }\n}\n","import { AnnotationStore } from './annotation-store';\nimport { Annotation } from './types';\n\nexport class McpBridge {\n private baseUrl: string;\n private sessionId: string | null = null;\n private connected = false;\n private retryTimer: ReturnType<typeof setInterval> | null = null;\n\n onChange?: (connected: boolean) => void;\n\n constructor(\n private store: AnnotationStore,\n port: number = 4848,\n ) {\n this.baseUrl = `http://localhost:${port}`;\n this.discover();\n\n // Wire up store events\n this.store.on('add', (annotation) => this.postAnnotation(annotation));\n this.store.on('resolve', (annotation) => this.patchAnnotation(annotation));\n }\n\n private async discover(): Promise<void> {\n try {\n const res = await fetch(`${this.baseUrl}/health`);\n const data = await res.json();\n if (data && typeof data === 'object' && 'status' in data && data.status === 'ok') {\n this.connected = true;\n this.onChange?.(true);\n await this.createSession();\n this.stopRetry();\n }\n } catch {\n this.connected = false;\n this.onChange?.(false);\n this.startRetry();\n }\n }\n\n private startRetry(): void {\n if (this.retryTimer) return;\n this.retryTimer = setInterval(() => this.discover(), 5000);\n }\n\n private stopRetry(): void {\n if (this.retryTimer) {\n clearInterval(this.retryTimer);\n this.retryTimer = null;\n }\n }\n\n private async createSession(): Promise<void> {\n try {\n const res = await fetch(`${this.baseUrl}/sessions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n url: window.location.href,\n title: document.title || window.location.pathname,\n }),\n });\n const session = await res.json();\n this.sessionId = session.id;\n } catch {\n // Session creation failed — annotations won't sync but local still works\n }\n }\n\n private async postAnnotation(annotation: Annotation): Promise<void> {\n if (!this.connected || !this.sessionId) return;\n\n try {\n await fetch(`${this.baseUrl}/sessions/${this.sessionId}/annotations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n targetSelector: annotation.targetSelector,\n targetRect: annotation.targetRect,\n text: annotation.text,\n }),\n });\n } catch {\n // Silently fail — local annotation still exists\n }\n }\n\n private async patchAnnotation(annotation: Annotation): Promise<void> {\n if (!this.connected) return;\n\n try {\n await fetch(`${this.baseUrl}/annotations/${annotation.id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n resolved: true,\n summary: 'Resolved from browser',\n }),\n });\n } catch {\n // Silently fail\n }\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n destroy(): void {\n this.stopRetry();\n }\n}\n","import { RefinerOptions } from './types';\nimport { STYLES } from './styles';\nimport { AnnotationStore } from './annotation-store';\nimport { Toolbar } from './toolbar';\nimport { Overlay } from './overlay';\nimport { AnnotationDialog } from './annotation-dialog';\nimport { AnnotationMarkers } from './annotation-marker';\nimport { SettingsPanel } from './settings';\nimport { generateSelector } from './selector';\nimport { McpBridge } from './mcp-bridge';\n\nexport class Refiner {\n private host: HTMLDivElement;\n private shadow: ShadowRoot;\n private store: AnnotationStore;\n private toolbar: Toolbar;\n private overlay: Overlay;\n private dialog: AnnotationDialog;\n private markers: AnnotationMarkers;\n private settings: SettingsPanel;\n private mcpBridge: McpBridge | null = null;\n private currentTarget: Element | null = null;\n private currentRect: DOMRect | null = null;\n private clearOnCopy = false;\n\n constructor(options: RefinerOptions = {}) {\n // Create shadow host\n this.host = document.createElement('div');\n this.host.id = 'refiner-host';\n this.shadow = this.host.attachShadow({ mode: 'open' });\n\n // Inject styles\n const style = document.createElement('style');\n style.textContent = STYLES;\n this.shadow.appendChild(style);\n\n // Initialize components\n this.store = new AnnotationStore();\n this.toolbar = new Toolbar(this.shadow);\n this.settings = new SettingsPanel(this.shadow);\n this.overlay = new Overlay(this.shadow);\n this.dialog = new AnnotationDialog(this.shadow);\n this.markers = new AnnotationMarkers(this.shadow, this.store);\n\n // Wire up toolbar\n this.toolbar.onCopy = () => this.copyAnnotations();\n this.toolbar.onClear = () => this.clearAnnotations();\n this.toolbar.onSettings = () => {\n this.settings.toggle();\n this.toolbar.setSettingsOpen(this.settings.isVisible());\n };\n\n this.toolbar.onCollapse = () => {\n this.settings.hide();\n this.toolbar.setSettingsOpen(false);\n this.overlay.setEnabled(false);\n };\n\n this.toolbar.onExpand = () => {\n this.overlay.setEnabled(true);\n };\n\n // Wire up settings\n this.settings.onChange = (s) => {\n this.clearOnCopy = s.clearOnCopy;\n this.overlay.setBlocking(s.blockInteractions);\n this.markers.setColor(s.markerColor);\n this.overlay.setHighlightColor(s.markerColor);\n };\n\n // Wire up overlay click\n this.overlay.onClick = (target, rect) => {\n if (this.settings.isVisible()) {\n this.settings.hide();\n return;\n }\n if (this.dialog.isVisible()) {\n this.dialog.hide();\n return;\n }\n this.currentTarget = target;\n this.currentRect = rect;\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n this.dialog.show(centerX, centerY);\n };\n\n // Wire up dialog submit\n this.dialog.onSubmit = (text) => {\n if (this.currentTarget && this.currentRect) {\n const selector = generateSelector(this.currentTarget);\n this.store.add(selector, this.currentRect, text);\n this.toolbar.updateCount(this.store.getCount());\n }\n this.currentTarget = null;\n this.currentRect = null;\n };\n\n this.dialog.onCancel = () => {\n this.currentTarget = null;\n this.currentRect = null;\n };\n\n // Update count on resolve/remove\n this.store.on('resolve', () => this.toolbar.updateCount(this.store.getCount()));\n this.store.on('remove', () => this.toolbar.updateCount(this.store.getCount()));\n\n // MCP bridge (auto-discover by default)\n if (options.mcpEnabled !== false) {\n this.mcpBridge = new McpBridge(this.store, options.mcpPort);\n this.mcpBridge.onChange = (connected) => {\n this.settings.setMcpStatus(connected);\n };\n }\n\n // Mount\n document.body.appendChild(this.host);\n\n if (options.enabled === false) {\n this.disable();\n }\n }\n\n enable(): void {\n this.host.style.display = '';\n this.overlay.setEnabled(true);\n }\n\n disable(): void {\n this.host.style.display = 'none';\n this.overlay.setEnabled(false);\n }\n\n destroy(): void {\n this.mcpBridge?.destroy();\n this.host.remove();\n }\n\n getAnnotations() {\n return this.store.getAll();\n }\n\n getAnnotationCount(): number {\n return this.store.getCount();\n }\n\n formatForAgent(): string {\n const annotations = this.store.getAll();\n if (annotations.length === 0) return 'No annotations.';\n\n const pageTitle = document.title || window.location.pathname;\n const pathname = window.location.pathname;\n const filename = pathname.substring(pathname.lastIndexOf('/') + 1) || 'index.html';\n const lines: string[] = [\n `# Design Annotations — ${pageTitle}`,\n `**File:** \\`${filename}\\``,\n '',\n ];\n\n for (let i = 0; i < annotations.length; i++) {\n const a = annotations[i];\n const status = a.resolved ? ' (resolved)' : '';\n lines.push(`## ${i + 1}.${status}`);\n lines.push(`**Element:** \\`${a.targetSelector}\\``);\n lines.push(`**Issue:** ${a.text}`);\n lines.push('');\n }\n\n return lines.join('\\n');\n }\n\n clearAnnotations(): void {\n const all = this.store.getAll();\n for (const a of all) {\n this.store.remove(a.id);\n }\n this.toolbar.updateCount(0);\n }\n\n copyAnnotations(): void {\n const text = this.formatForAgent();\n navigator.clipboard.writeText(text);\n\n if (this.clearOnCopy) {\n this.clearAnnotations();\n }\n }\n}\n","export const STYLES = `\n :host {\n all: initial;\n position: fixed;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n color: #1a1a2e;\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ── Toolbar ── */\n\n .refiner-toolbar {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10;\n user-select: none;\n }\n\n .toolbar-pill {\n display: flex;\n align-items: center;\n position: relative;\n background: #1a1a2e;\n border-radius: 100px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15);\n padding: 6px;\n transform: scale(1);\n transform-origin: right center;\n transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .refiner-toolbar[data-collapsed=\"true\"] .toolbar-pill {\n transform: scale(0.92);\n }\n\n .toolbar-inner {\n display: flex;\n align-items: center;\n gap: 2px;\n overflow: hidden;\n clip-path: inset(0);\n max-width: 300px;\n opacity: 1;\n padding-right: 2px;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s ease 0.1s,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .refiner-toolbar[data-collapsed=\"true\"] .toolbar-inner {\n max-width: 0;\n opacity: 0;\n padding-right: 0;\n transition: max-width 0.35s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.15s ease,\n padding 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .toolbar-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: #a0a0b8;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.15s, background 0.15s;\n }\n\n .toolbar-btn:hover {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .toolbar-btn.active {\n color: #ffffff;\n background: rgba(255, 255, 255, 0.15);\n }\n\n .toolbar-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .toolbar-count {\n font-size: 14px;\n font-weight: 700;\n min-width: 18px;\n text-align: center;\n }\n\n .toolbar-divider {\n width: 1px;\n height: 20px;\n background: rgba(255, 255, 255, 0.15);\n margin: 0 4px;\n flex-shrink: 0;\n }\n\n /* Tooltip */\n .toolbar-tooltip {\n position: absolute;\n bottom: calc(100% + 10px);\n left: 50%;\n transform: translateX(-50%);\n padding: 6px 10px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n font-weight: 500;\n white-space: nowrap;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n }\n\n .toolbar-tooltip::after {\n content: '';\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 5px solid transparent;\n border-top-color: #1a1a2e;\n }\n\n .toolbar-btn:hover .toolbar-tooltip {\n opacity: 1;\n }\n\n .tooltips-hidden .toolbar-tooltip {\n display: none;\n }\n\n .toolbar-btn.disabled {\n opacity: 0.3;\n cursor: default;\n }\n\n .toolbar-btn.disabled:hover {\n color: #a0a0b8;\n background: transparent;\n }\n\n /* Toggle button (always visible) */\n .toolbar-toggle-btn {\n flex-shrink: 0;\n }\n\n /* Badge for collapsed state */\n .toolbar-expand-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 20px;\n height: 20px;\n padding: 0 5px;\n border-radius: 10px;\n background: #DC2626;\n color: #ffffff;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n }\n\n .toolbar-expand-badge.hidden {\n display: none;\n }\n\n /* ── Settings Panel ── */\n\n .settings-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 300px;\n z-index: 12;\n background: #1a1a2e;\n border-radius: 16px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 20px;\n color: #e8e8f0;\n transform-origin: bottom right;\n transition: transform 0.25s ease, opacity 0.1s ease;\n transform: scale(1);\n opacity: 1;\n }\n\n .settings-panel.hidden {\n transform: scale(0.4);\n opacity: 0;\n pointer-events: none;\n }\n\n .settings-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 4px;\n }\n\n .settings-title {\n font-size: 16px;\n font-weight: 700;\n font-style: normal;\n color: #ffffff;\n }\n\n .settings-version {\n font-size: 12px;\n color: #6b6b80;\n font-weight: 500;\n }\n\n .settings-divider {\n height: 1px;\n background: rgba(255, 255, 255, 0.08);\n margin: 16px 0;\n }\n\n .settings-section {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .settings-label {\n font-size: 14px;\n font-weight: 500;\n color: #c0c0d0;\n }\n\n .settings-color-row {\n display: flex;\n gap: 8px;\n }\n\n .settings-swatch {\n width: 24px;\n height: 24px;\n border-radius: 4px;\n border: 2px solid transparent;\n cursor: pointer;\n transition: transform 0.15s, border-color 0.15s;\n outline: none;\n }\n\n .settings-swatch:hover {\n transform: scale(1.1);\n }\n\n .settings-swatch.selected {\n border-color: #ffffff;\n transform: scale(1.1);\n }\n\n .settings-check-row {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n padding: 2px 0;\n }\n\n .settings-checkbox {\n appearance: none;\n -webkit-appearance: none;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 2px solid #4a4a60;\n background: transparent;\n cursor: pointer;\n position: relative;\n flex-shrink: 0;\n transition: background 0.15s, border-color 0.15s;\n }\n\n .settings-checkbox:checked {\n background: #2563EB;\n border-color: #2563EB;\n }\n\n .settings-checkbox:checked::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 5px;\n width: 5px;\n height: 9px;\n border: solid #ffffff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .settings-check-label {\n font-size: 14px;\n font-weight: 500;\n color: #e8e8f0;\n }\n\n /* ── Overlay ── */\n\n .refiner-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n cursor: crosshair;\n z-index: 1;\n }\n\n .refiner-overlay[data-blocking=\"true\"] {\n pointer-events: all;\n }\n\n .refiner-overlay[data-blocking=\"false\"] {\n pointer-events: none;\n }\n\n .refiner-overlay.hidden {\n display: none;\n }\n\n /* ── Highlight ── */\n\n .refiner-highlight {\n position: fixed;\n pointer-events: none;\n border: 2px dashed;\n border-radius: 3px;\n z-index: 2;\n transition: all 0.1s ease;\n }\n\n /* ── Dialog ── */\n\n .refiner-dialog {\n position: fixed;\n width: 320px;\n background: #1a1a2e;\n border: 1px solid rgba(255, 255, 255, 0.08);\n border-radius: 14px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 11;\n color: #e8e8f0;\n animation: dialog-in 0.2s ease;\n }\n\n @keyframes dialog-in {\n from { opacity: 0; transform: translateY(4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .refiner-dialog.hidden {\n display: none;\n }\n\n .dialog-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n }\n\n .dialog-header span {\n font-size: 12px;\n font-weight: 600;\n color: #c0c0d0;\n }\n\n .dialog-textarea {\n width: 100%;\n min-height: 72px;\n padding: 10px 12px;\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 10px;\n font-family: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: #e8e8f0;\n background: rgba(255, 255, 255, 0.06);\n resize: vertical;\n outline: none;\n transition: border-color 0.15s;\n }\n\n .dialog-textarea:focus {\n border-color: rgba(255, 255, 255, 0.25);\n }\n\n .dialog-textarea::placeholder {\n color: #6b6b80;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n }\n\n .dialog-btn {\n height: 32px;\n padding: 0 14px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n }\n\n .dialog-btn-cancel {\n background: transparent;\n border: 1px solid rgba(255, 255, 255, 0.12);\n color: #a0a0b8;\n }\n\n .dialog-btn-cancel:hover {\n background: rgba(255, 255, 255, 0.08);\n color: #e8e8f0;\n }\n\n .dialog-btn-add {\n background: #2563EB;\n border: none;\n color: #ffffff;\n }\n\n .dialog-btn-add:hover {\n background: #3B82F6;\n }\n\n .dialog-btn-add:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n /* ── Markers ── */\n\n .refiner-marker {\n position: fixed;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n color: #ffffff;\n cursor: pointer;\n z-index: 10;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n transition: transform 0.15s;\n pointer-events: all;\n }\n\n .refiner-marker:hover {\n transform: scale(1.2);\n }\n\n .refiner-marker[data-resolved=\"true\"] {\n opacity: 0.4;\n }\n\n .marker-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n width: 220px;\n padding: 10px 12px;\n background: #1a1a2e;\n color: #e8e8f0;\n font-size: 12px;\n line-height: 1.4;\n border-radius: 10px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .refiner-marker:hover .marker-tooltip {\n opacity: 1;\n }\n\n .marker-tooltip-actions {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n border-top: 1px solid rgba(255,255,255,0.1);\n padding-top: 8px;\n }\n\n .marker-tooltip-btn {\n height: 22px;\n padding: 0 8px;\n border-radius: 5px;\n border: none;\n font-size: 10px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .marker-tooltip-btn.resolve {\n background: #34D399;\n color: #0a2e1f;\n }\n\n .marker-tooltip-btn.resolve:hover {\n background: #4ade80;\n }\n\n .marker-tooltip-btn.delete {\n background: rgba(255,255,255,0.1);\n color: #e8e8f0;\n }\n\n .marker-tooltip-btn.delete:hover {\n background: #FF6B6B;\n color: #fff;\n }\n\n /* MCP status */\n .settings-mcp-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n }\n\n .settings-mcp-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .settings-mcp-dot.connected {\n background: #34D399;\n box-shadow: 0 0 6px #34D39980;\n }\n\n .settings-mcp-dot.disconnected {\n background: #6B7280;\n }\n`;\n","/**\n * Generate a stable CSS selector for a DOM element.\n * Priority: #id > tag.class > nth-child path\n */\nexport function generateSelector(el: Element): string {\n if (el.id) {\n return `#${CSS.escape(el.id)}`;\n }\n\n // Try tag + distinctive class\n if (el.classList.length > 0) {\n const tag = el.tagName.toLowerCase();\n const classSelector = `${tag}.${Array.from(el.classList).map(CSS.escape).join('.')}`;\n if (document.querySelectorAll(classSelector).length === 1) {\n return classSelector;\n }\n }\n\n // Build nth-child path\n const parts: string[] = [];\n let current: Element | null = el;\n\n while (current && current !== document.documentElement) {\n const tag = current.tagName.toLowerCase();\n const parent: Element | null = current.parentElement;\n\n if (current.id) {\n parts.unshift(`#${CSS.escape(current.id)}`);\n break;\n }\n\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n (c: Element) => c.tagName === current!.tagName\n );\n if (siblings.length === 1) {\n parts.unshift(tag);\n } else {\n const index = siblings.indexOf(current) + 1;\n parts.unshift(`${tag}:nth-child(${index})`);\n }\n } else {\n parts.unshift(tag);\n }\n\n current = parent;\n }\n\n return parts.join(' > ');\n}\n","import { Refiner } from './refiner';\nimport type { Annotation, RefinerOptions } from './types';\n\nexport { Refiner };\nexport type { Annotation, RefinerOptions };\n\n// Auto-initialize when loaded via script tag\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n const init = () => {\n // Skip if already initialized (e.g. bookmarklet + script tag both present)\n if ((window as any).__refiner) return;\n\n // Read config from script tag data attributes\n const script = document.currentScript as HTMLScriptElement | null;\n const position = (script?.dataset.refinerPosition as 'left' | 'right') ?? 'right';\n const enabled = script?.dataset.refinerEnabled !== 'false';\n const mcpPort = script?.dataset.refinerMcpPort ? parseInt(script.dataset.refinerMcpPort, 10) : undefined;\n const mcpEnabled = script?.dataset.refinerMcpEnabled !== 'false';\n\n const refiner = new Refiner({ position, enabled, mcpPort, mcpEnabled });\n (window as any).__refiner = refiner;\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', init);\n } else {\n init();\n }\n}\n"],"names":["AnnotationStore","constructor","this","annotations","Map","listeners","add","targetSelector","targetRect","text","annotation","id","crypto","randomUUID","x","y","width","height","timestamp","Date","now","resolved","set","emit","resolve","get","remove","delete","getAll","Array","from","values","getPending","filter","a","getCount","size","exportJSON","JSON","stringify","on","event","listener","has","Set","off","forEach","fn","Toolbar","root","collapsed","settingsOpen","el","document","createElement","className","setAttribute","render","appendChild","requestAnimationFrame","updateBadgeVisibility","pill","innerEl","countBadge","textContent","createBtn","copyIcon","copyBtn","classList","contains","onCopy","querySelector","innerHTML","setTimeout","clearBtn","onClear","onSettings","divider","penIcon","toggleBtn","toggleCollapse","expandBadge","addEventListener","content","tooltip","onClick","btn","iconWrap","tip","String","onCollapse","onExpand","setSettingsOpen","open","toggle","updateCount","count","empty","c","parseInt","Overlay","enabled","blocking","currentTarget","highlightColor","handleMouseMove","e","isOverOwnUI","clientX","clientY","hideHighlight","target","getElementAt","showHighlight","handleClick","preventDefault","stopPropagation","rect","getBoundingClientRect","handleKeyBlock","host","highlight","style","display","shadowEl","elementFromPoint","pointerEvents","top","left","borderColor","setHighlightColor","color","setBlocking","setEnabled","AnnotationDialog","header","label","textarea","placeholder","addBtn","disabled","value","trim","length","key","metaKey","ctrlKey","submit","hide","onCancel","actions","cancelBtn","onSubmit","show","window","innerWidth","innerHeight","Math","max","focus","isVisible","AnnotationMarkers","store","markers","rafId","container","addMarker","updateMarker","removeMarker","reposition","repositionAll","passive","background","index","tooltipText","tooltipActions","resolveBtn","deleteBtn","positionMarker","marker","renumber","i","firstText","childNodes","nodeType","Node","TEXT_NODE","queryTarget","right","selector","setColor","clearAll","MARKER_COLORS","SettingsPanel","visible","settings","clearOnCopy","blockInteractions","markerColor","title","version","createDivider","colorSection","colorLabel","colorRow","mc","swatch","querySelectorAll","s","emitChange","createCheckbox","checked","mcpRow","mcpDot","mcpLabel","initial","onChange","row","checkbox","type","div","setMcpStatus","connected","getSettings","McpBridge","port","sessionId","retryTimer","baseUrl","discover","postAnnotation","patchAnnotation","res","fetch","data","json","status","createSession","stopRetry","startRetry","setInterval","clearInterval","method","headers","body","url","location","href","pathname","session","summary","isConnected","destroy","Refiner","options","mcpBridge","currentRect","shadow","attachShadow","mode","toolbar","overlay","dialog","copyAnnotations","clearAnnotations","centerX","centerY","CSS","escape","classSelector","tagName","toLowerCase","map","join","parts","current","documentElement","tag","parent","parentElement","unshift","siblings","children","indexOf","generateSelector","mcpEnabled","mcpPort","disable","enable","getAnnotations","getAnnotationCount","formatForAgent","pageTitle","lines","substring","lastIndexOf","push","all","navigator","clipboard","writeText","init","__refiner","script","currentScript","position","dataset","refinerPosition","refinerEnabled","refinerMcpPort","undefined","refinerMcpEnabled","refiner","readyState"],"mappings":"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"}
|
package/dist/toolbar.d.ts
CHANGED