instruckt 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/instruckt.cjs.js +24 -0
- package/dist/instruckt.cjs.js.map +1 -1
- package/dist/instruckt.d.mts +3 -0
- package/dist/instruckt.d.ts +3 -0
- package/dist/instruckt.esm.js +24 -0
- package/dist/instruckt.esm.js.map +1 -1
- package/dist/instruckt.iife.js +3 -3
- package/dist/instruckt.iife.js.map +1 -1
- package/package.json +1 -1
package/dist/instruckt.cjs.js
CHANGED
|
@@ -1212,6 +1212,7 @@ var _Instruckt = class _Instruckt {
|
|
|
1212
1212
|
this.rafId = null;
|
|
1213
1213
|
this.pendingMouseTarget = null;
|
|
1214
1214
|
this.highlightLocked = false;
|
|
1215
|
+
this.pollTimer = null;
|
|
1215
1216
|
this.boundReposition = () => {
|
|
1216
1217
|
var _a;
|
|
1217
1218
|
(_a = this.markers) == null ? void 0 : _a.reposition(this.annotations);
|
|
@@ -1342,6 +1343,7 @@ var _Instruckt = class _Instruckt {
|
|
|
1342
1343
|
setTimeout(() => this.reattach(), 0);
|
|
1343
1344
|
});
|
|
1344
1345
|
this.loadAnnotations();
|
|
1346
|
+
this.pollTimer = setInterval(() => this.pollForChanges(), 3e3);
|
|
1345
1347
|
this.syncMarkers();
|
|
1346
1348
|
}
|
|
1347
1349
|
makeToolbarCallbacks() {
|
|
@@ -1420,6 +1422,27 @@ var _Instruckt = class _Instruckt {
|
|
|
1420
1422
|
} catch (e) {
|
|
1421
1423
|
}
|
|
1422
1424
|
}
|
|
1425
|
+
/** Poll API for status changes (e.g. agent resolved via MCP) */
|
|
1426
|
+
async pollForChanges() {
|
|
1427
|
+
try {
|
|
1428
|
+
const remote = await this.api.getAnnotations();
|
|
1429
|
+
let changed = false;
|
|
1430
|
+
for (const r of remote) {
|
|
1431
|
+
const local = this.annotations.find((a) => a.id === r.id);
|
|
1432
|
+
if (local && local.status !== r.status) {
|
|
1433
|
+
local.status = r.status;
|
|
1434
|
+
local.resolvedAt = r.resolvedAt;
|
|
1435
|
+
local.resolvedBy = r.resolvedBy;
|
|
1436
|
+
changed = true;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
if (changed) {
|
|
1440
|
+
this.saveToStorage();
|
|
1441
|
+
this.syncMarkers();
|
|
1442
|
+
}
|
|
1443
|
+
} catch (e) {
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1423
1446
|
// ── Page-scoped markers ─────────────────────────────────────────
|
|
1424
1447
|
syncMarkers() {
|
|
1425
1448
|
var _a, _b, _c, _d;
|
|
@@ -1793,6 +1816,7 @@ No open annotations.`;
|
|
|
1793
1816
|
(_c = this.popup) == null ? void 0 : _c.destroy();
|
|
1794
1817
|
(_d = this.markers) == null ? void 0 : _d.destroy();
|
|
1795
1818
|
if (this.rafId !== null) cancelAnimationFrame(this.rafId);
|
|
1819
|
+
if (this.pollTimer !== null) clearInterval(this.pollTimer);
|
|
1796
1820
|
}
|
|
1797
1821
|
};
|
|
1798
1822
|
// ── Persistence ─────────────────────────────────────────────────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/api.ts","../src/ui/styles.ts","../src/ui/toolbar.ts","../src/ui/highlight.ts","../src/ui/popup.ts","../src/ui/markers.ts","../src/selector.ts","../src/adapters/livewire.ts","../src/adapters/vue.ts","../src/adapters/svelte.ts","../src/adapters/react.ts","../src/instruckt.ts"],"sourcesContent":["import { Instruckt } from './instruckt'\nimport type { InstrucktConfig, Annotation, AnnotationIntent, AnnotationSeverity, AnnotationStatus, FrameworkContext } from './types'\nimport type { AnnotationPayload } from './api'\n\nexport { Instruckt }\nexport type { InstrucktConfig, Annotation, AnnotationPayload, AnnotationIntent, AnnotationSeverity, AnnotationStatus, FrameworkContext }\n\n/**\n * Initialize instruckt.\n *\n * @example\n * instruckt.init({ endpoint: '/instruckt' })\n *\n * @example CDN\n * <script src=\"instruckt.iife.js\"></script>\n * <script>Instruckt.init({ endpoint: '/instruckt' })</script>\n */\nexport function init(config: InstrucktConfig): Instruckt {\n return new Instruckt(config)\n}\n","import type { Annotation } from './types'\n\n/** Read Laravel's XSRF-TOKEN cookie for CSRF protection */\nfunction getCsrfToken(): string {\n const match = document.cookie.match(/(?:^|;\\s*)XSRF-TOKEN=([^;]+)/)\n return match ? decodeURIComponent(match[1]) : ''\n}\n\nfunction headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n const csrf = getCsrfToken()\n if (csrf) h['X-XSRF-TOKEN'] = csrf\n return h\n}\n\n/** Convert snake_case API response to camelCase for JS types */\nexport function toCamelCase(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n const camel = k.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n out[camel] = Array.isArray(v)\n ? v.map(item => (item && typeof item === 'object' && !Array.isArray(item)) ? toCamelCase(item as Record<string, unknown>) : item)\n : (v && typeof v === 'object' && !Array.isArray(v)) ? toCamelCase(v as Record<string, unknown>) : v\n }\n return out\n}\n\n/** Convert camelCase JS payload to snake_case for Laravel API */\nfunction toSnake(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n const snake = k.replace(/[A-Z]/g, c => `_${c.toLowerCase()}`)\n out[snake] = (v && typeof v === 'object' && !Array.isArray(v)) ? toSnake(v as Record<string, unknown>) : v\n }\n return out\n}\n\nexport type AnnotationPayload = Omit<\n Annotation,\n 'id' | 'status' | 'thread' | 'createdAt'\n>\n\nexport class InstrucktApi {\n constructor(private readonly endpoint: string) {}\n\n async getAnnotations(): Promise<Annotation[]> {\n const res = await fetch(`${this.endpoint}/annotations`, {\n headers: headers(),\n })\n if (!res.ok) throw new Error(`instruckt: failed to load annotations (${res.status})`)\n const raw: Record<string, unknown>[] = await res.json()\n return raw.map(r => toCamelCase(r) as unknown as Annotation)\n }\n\n async addAnnotation(data: AnnotationPayload): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify(toSnake(data as unknown as Record<string, unknown>)),\n })\n if (!res.ok) throw new Error(`instruckt: failed to add annotation (${res.status})`)\n return toCamelCase(await res.json()) as unknown as Annotation\n }\n\n async updateAnnotation(\n annotationId: string,\n data: Partial<Pick<Annotation, 'status' | 'comment'>>,\n ): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations/${annotationId}`, {\n method: 'PATCH',\n headers: headers(),\n body: JSON.stringify(toSnake(data as unknown as Record<string, unknown>)),\n })\n if (!res.ok) throw new Error(`instruckt: failed to update annotation (${res.status})`)\n return toCamelCase(await res.json()) as unknown as Annotation\n }\n\n async addReply(annotationId: string, content: string, role: 'human' | 'agent' = 'human'): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations/${annotationId}/reply`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify({ role, content }),\n })\n if (!res.ok) throw new Error(`instruckt: failed to add reply (${res.status})`)\n return toCamelCase(await res.json()) as unknown as Annotation\n }\n}\n","/** Global styles injected into document.head — ONLY what must affect the host page */\nexport const GLOBAL_CSS = /* css */ `\nbody.ik-annotating,\nbody.ik-annotating * { cursor: crosshair !important; }\n`\n\n/** Toolbar shadow DOM styles — fully isolated */\nexport const TOOLBAR_CSS = /* css */ `\n:host {\n all: initial;\n display: block;\n position: fixed;\n z-index: 2147483646;\n}\n\n* { box-sizing: border-box; }\n\n:host-context([data-instruckt-theme=\"dark\"]),\n@media (prefers-color-scheme: dark) {\n :host {\n --ik-bg: #1c1c1e; --ik-bg2: #2c2c2e; --ik-border: #38383a;\n --ik-text: #f4f4f5; --ik-muted: #a1a1aa;\n --ik-shadow: 0 8px 32px rgba(0,0,0,.4), 0 0 0 1px rgba(255,255,255,.06);\n }\n}\n\n:host {\n --ik-accent: #6366f1;\n --ik-accent-h: #4f46e5;\n --ik-bg: #ffffff;\n --ik-bg2: #f4f4f5;\n --ik-border: #e4e4e7;\n --ik-text: #18181b;\n --ik-muted: #a1a1aa;\n --ik-shadow: 0 8px 32px rgba(0,0,0,.08), 0 0 0 1px rgba(0,0,0,.04);\n}\n\n.toolbar {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n background: var(--ik-bg);\n border-radius: 12px;\n padding: 6px;\n box-shadow: var(--ik-shadow);\n user-select: none;\n touch-action: none;\n cursor: grab;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n.toolbar:active { cursor: grabbing; }\n\n.btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 34px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--ik-muted);\n cursor: pointer;\n padding: 0;\n position: relative;\n transition: background .15s ease, color .15s ease;\n}\n.btn svg { display: block; }\n.btn:hover { background: var(--ik-bg2); color: var(--ik-text); }\n.btn.active { background: var(--ik-accent); color: #fff; }\n.btn.active:hover { background: var(--ik-accent-h); }\n\n.divider { width: 18px; height: 1px; background: var(--ik-border); margin: 3px 0; }\n\n.badge {\n position: absolute;\n top: -3px; right: -3px;\n min-width: 16px; height: 16px;\n background: #ef4444;\n color: #fff;\n border-radius: 8px;\n font-size: 10px; font-weight: 600;\n display: flex; align-items: center; justify-content: center;\n padding: 0 4px;\n line-height: 1;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n.minimize-btn { color: var(--ik-muted); opacity: .6; }\n.minimize-btn:hover { opacity: 1; }\n\n.danger-btn { color: var(--ik-muted); opacity: .6; }\n.danger-btn:hover { opacity: 1; color: #ef4444; }\n\n.clear-wrap {\n position: relative;\n display: flex;\n align-items: center;\n}\n.clear-all-btn {\n display: none;\n position: absolute;\n right: 100%;\n top: 0;\n background: var(--ik-bg);\n box-shadow: var(--ik-shadow);\n border-radius: 8px;\n}\n/* Invisible bridge so hover doesn't break crossing the gap */\n.clear-all-btn::after {\n content: '';\n position: absolute;\n top: 0;\n left: 100%;\n width: 6px;\n height: 100%;\n}\n.clear-wrap:hover .clear-all-btn { display: flex; align-items: center; justify-content: center; }\n\n.fab {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: none;\n background: var(--ik-bg);\n color: var(--ik-muted);\n box-shadow: var(--ik-shadow);\n cursor: pointer;\n padding: 0;\n transition: color .15s ease, transform .15s ease;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n.fab:hover { color: var(--ik-accent); transform: scale(1.1); }\n.fab { position: relative; }\n\n.fab-badge {\n position: absolute;\n top: -4px; right: -4px;\n min-width: 16px; height: 16px;\n background: #6366f1;\n color: #fff;\n border-radius: 8px;\n font-size: 9px; font-weight: 700;\n display: flex; align-items: center; justify-content: center;\n padding: 0 3px;\n line-height: 1;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n`\n\n/** Popup shadow DOM styles — fully isolated */\nexport const POPUP_CSS = /* css */ `\n:host {\n all: initial;\n display: block;\n position: fixed;\n z-index: 2147483647;\n}\n\n* { box-sizing: border-box; }\n\n:host {\n --ik-accent: #6366f1;\n --ik-accent-h: #4f46e5;\n --ik-bg: #ffffff;\n --ik-bg2: #f8f8f8;\n --ik-border: #e4e4e7;\n --ik-text: #18181b;\n --ik-muted: #71717a;\n --ik-shadow: 0 4px 24px rgba(0,0,0,.12);\n --ik-radius: 10px;\n --ik-hl: rgba(99,102,241,.15);\n}\n\n@media (prefers-color-scheme: dark) {\n :host {\n --ik-bg: #1c1c1e; --ik-bg2: #2c2c2e; --ik-border: #3a3a3c;\n --ik-text: #f4f4f5; --ik-muted: #a1a1aa;\n --ik-shadow: 0 4px 24px rgba(0,0,0,.5);\n --ik-hl: rgba(99,102,241,.2);\n }\n}\n\n.popup {\n width: 340px;\n background: var(--ik-bg);\n border: 1px solid var(--ik-border);\n border-radius: var(--ik-radius);\n box-shadow: var(--ik-shadow);\n padding: 14px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 13px;\n color: var(--ik-text);\n animation: pop-in .12s ease;\n}\n@keyframes pop-in {\n from { opacity:0; transform: scale(.95) translateY(4px); }\n to { opacity:1; transform: scale(1) translateY(0); }\n}\n\n.header { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }\n.element-tag {\n font-size:11px; font-family:ui-monospace,monospace; color:var(--ik-muted);\n background:var(--ik-bg2); border-radius:4px; padding:2px 6px;\n max-width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;\n}\n.close-btn {\n background:none; border:none; color:var(--ik-muted);\n cursor:pointer; font-size:18px; line-height:1; padding:0;\n}\n\n.fw-badge {\n display:inline-flex; align-items:center; gap:4px;\n font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;\n color:var(--ik-accent); background:var(--ik-hl); border-radius:4px;\n padding:2px 6px; margin-bottom:8px;\n}\n.selected-text {\n font-size:12px; color:var(--ik-muted); background:var(--ik-bg2);\n border-left:3px solid var(--ik-accent); padding:4px 8px;\n border-radius:0 4px 4px 0; margin-bottom:10px;\n overflow:hidden; text-overflow:ellipsis; white-space:nowrap;\n}\n\n.label {\n font-size:10px; font-weight:700; text-transform:uppercase;\n letter-spacing:.05em; color:var(--ik-muted); margin-bottom:4px;\n}\n.row { display:flex; gap:6px; margin-bottom:10px; }\n.chips { display:flex; gap:4px; flex-wrap:wrap; }\n\n.chip {\n font-size:11px; padding:3px 8px; border-radius:12px;\n border:1px solid var(--ik-border); background:transparent;\n color:var(--ik-muted); cursor:pointer; transition:all .1s;\n}\n.chip:hover { border-color:var(--ik-accent); color:var(--ik-accent); }\n.chip.sel { background:var(--ik-accent); border-color:var(--ik-accent); color:#fff; }\n.chip.blocking.sel { background:#ef4444; border-color:#ef4444; }\n.chip.important.sel { background:#f97316; border-color:#f97316; }\n.chip.suggestion.sel{ background:#22c55e; border-color:#22c55e; }\n\ntextarea {\n width:100%; min-height:80px; resize:vertical;\n border:1px solid var(--ik-border); border-radius:6px;\n background:var(--ik-bg2); color:var(--ik-text);\n font-family:inherit; font-size:13px; padding:8px 10px;\n outline:none; transition:border-color .15s; margin-bottom:10px;\n}\ntextarea:focus { border-color:var(--ik-accent); }\ntextarea::placeholder { color:var(--ik-muted); }\n\n.actions { display:flex; justify-content:flex-end; gap:6px; }\n\n.btn-secondary {\n padding:6px 14px; border-radius:6px; border:1px solid var(--ik-border);\n background:transparent; color:var(--ik-muted); font-size:12px; cursor:pointer; transition:all .1s;\n}\n.btn-secondary:hover { border-color:var(--ik-muted); color:var(--ik-text); }\n\n.btn-primary {\n padding:6px 14px; border-radius:6px; border:none;\n background:var(--ik-accent); color:#fff;\n font-size:12px; font-weight:700; cursor:pointer; transition:background .1s;\n}\n.btn-primary:hover { background:var(--ik-accent-h); }\n.btn-primary:disabled { opacity:.5; cursor:not-allowed; }\n\n.btn-danger {\n padding:6px 14px; border-radius:6px; border:1px solid #ef4444;\n background:transparent; color:#ef4444;\n font-size:12px; cursor:pointer; transition:all .1s;\n}\n.btn-danger:hover { background:#ef4444; color:#fff; }\n\n/* Thread view */\n.thread { margin-top:10px; border-top:1px solid var(--ik-border); padding-top:10px; }\n.msg { margin-bottom:8px; }\n.msg-role {\n font-size:10px; font-weight:700; text-transform:uppercase;\n letter-spacing:.05em; margin-bottom:2px;\n}\n.msg-role.human { color:var(--ik-accent); }\n.msg-role.agent { color:#22c55e; }\n.msg-content { font-size:12px; line-height:1.5; }\n\n.status-badge {\n display:inline-flex; align-items:center; gap:4px;\n font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;\n border-radius:4px; padding:2px 6px;\n}\n.status-badge.pending { background:rgba(99,102,241,.15); color:var(--ik-accent); }\n.status-badge.acknowledged { background:rgba(249,115,22,.15); color:#f97316; }\n.status-badge.resolved { background:rgba(34,197,94,.15); color:#22c55e; }\n.status-badge.dismissed { background:var(--ik-bg2); color:var(--ik-muted); }\n`\n\n/** Marker pin styles injected into document.head — pins overlay the page */\nexport const MARKER_CSS = /* css */ `\n.ik-marker {\n position: absolute;\n z-index: 2147483645;\n width: 24px; height: 24px;\n border-radius: 50%;\n background: #6366f1;\n color: #fff;\n font-size: 11px; font-weight: 700;\n display: flex; align-items: center; justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(99,102,241,.4);\n transition: transform .15s ease;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n pointer-events: all;\n user-select: none;\n}\n.ik-marker:hover { transform: scale(1.15); }\n.ik-marker.resolved { background: #22c55e; box-shadow: 0 2px 8px rgba(34,197,94,.4); }\n.ik-marker.dismissed { background: #71717a; box-shadow: 0 2px 8px rgba(0,0,0,.2); }\n.ik-marker.acknowledged { background: #f97316; box-shadow: 0 2px 8px rgba(249,115,22,.4); }\n`\n\n/** Inject styles into document.head (idempotent) */\nexport function injectGlobalStyles(): void {\n if (document.getElementById('instruckt-global')) return\n const style = document.createElement('style')\n style.id = 'instruckt-global'\n style.textContent = GLOBAL_CSS + MARKER_CSS\n document.head.appendChild(style)\n}\n","import { TOOLBAR_CSS } from './styles'\n\nexport type ToolbarMode = 'idle' | 'annotating' | 'frozen'\n\ninterface ToolbarCallbacks {\n onToggleAnnotate: (active: boolean) => void\n onFreezeAnimations: (frozen: boolean) => void\n onCopy: () => void\n onClearPage?: () => void\n onClearAll?: () => void\n onMinimize?: (minimized: boolean) => void\n}\n\n// ── Inline SVG icons (24x24, 2px stroke) ─────────────────────\n\nconst ICONS = {\n annotate: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z\"/></svg>`,\n freeze: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/></svg>`,\n copy: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"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 check: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`,\n clear: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"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 minimize: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"7 13 12 18 17 13\"/><line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"18\"/></svg>`,\n logo: `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z\"/></svg>`,\n} as const\n\nexport class Toolbar {\n private host!: HTMLElement\n private shadow!: ShadowRoot\n private toolbarEl!: HTMLDivElement\n private fab!: HTMLButtonElement\n private fabBadge: HTMLSpanElement | null = null\n private annotateBtn!: HTMLButtonElement\n private freezeBtn!: HTMLButtonElement\n private copyBtn!: HTMLButtonElement\n private annotateActive = false\n private freezeActive = false\n private minimized = false\n private totalCount = 0\n private dragging = false\n private dragOffset = { x: 0, y: 0 }\n\n constructor(\n private readonly position: string,\n private readonly callbacks: ToolbarCallbacks,\n ) {\n this.build()\n this.setupDrag()\n }\n\n private build(): void {\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'toolbar')\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = TOOLBAR_CSS\n this.shadow.appendChild(style)\n\n // Full toolbar\n this.toolbarEl = document.createElement('div')\n this.toolbarEl.className = 'toolbar'\n\n this.annotateBtn = this.makeBtn(ICONS.annotate, 'Annotate elements (A)', () => {\n const next = !this.annotateActive\n this.setAnnotateActive(next)\n this.callbacks.onToggleAnnotate(next)\n })\n\n this.freezeBtn = this.makeBtn(ICONS.freeze, 'Freeze page (F)', () => {\n const next = !this.freezeActive\n this.setFreezeActive(next)\n this.callbacks.onFreezeAnimations(next)\n })\n\n this.copyBtn = this.makeBtn(ICONS.copy, 'Copy annotations as markdown', () => {\n this.callbacks.onCopy()\n this.copyBtn.innerHTML = ICONS.check\n setTimeout(() => { this.copyBtn.innerHTML = ICONS.copy }, 1200)\n })\n\n const clearWrap = document.createElement('div')\n clearWrap.className = 'clear-wrap'\n\n const clearBtn = this.makeBtn(ICONS.clear, 'Clear this page (X)', () => {\n this.callbacks.onClearPage?.()\n })\n clearBtn.classList.add('danger-btn')\n\n const clearAllBtn = this.makeBtn(\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2\"/><line x1=\"4.93\" y1=\"4.93\" x2=\"19.07\" y2=\"19.07\"/></svg>`,\n 'Clear ALL annotations across every page',\n () => this.callbacks.onClearAll?.(),\n )\n clearAllBtn.classList.add('danger-btn', 'clear-all-btn')\n\n clearWrap.appendChild(clearBtn)\n clearWrap.appendChild(clearAllBtn)\n\n const minimizeBtn = this.makeBtn(ICONS.minimize, 'Minimize toolbar', () => {\n this.setMinimized(true)\n })\n minimizeBtn.classList.add('minimize-btn')\n\n const mkDiv = () => { const d = document.createElement('div'); d.className = 'divider'; return d }\n\n this.toolbarEl.append(\n this.annotateBtn, mkDiv(), this.freezeBtn, mkDiv(),\n this.copyBtn, clearWrap, mkDiv(), minimizeBtn,\n )\n this.shadow.appendChild(this.toolbarEl)\n\n // Floating action button (minimized state)\n this.fab = document.createElement('button')\n this.fab.className = 'fab'\n this.fab.title = 'Open instruckt toolbar'\n this.fab.setAttribute('aria-label', 'Open instruckt toolbar')\n this.fab.innerHTML = ICONS.logo\n this.fab.style.display = 'none'\n this.fab.addEventListener('click', (e) => {\n e.stopPropagation()\n this.setMinimized(false)\n })\n this.shadow.appendChild(this.fab)\n\n // Prevent toolbar clicks from reaching page handlers (e.g. Alpine @click.outside)\n // Shadow DOM stopPropagation only works within the shadow tree — clicks still\n // re-dispatch from the host element into the regular DOM.\n this.host.addEventListener('click', (e) => e.stopPropagation())\n this.host.addEventListener('mousedown', (e) => e.stopPropagation())\n this.host.addEventListener('pointerdown', (e) => e.stopPropagation())\n\n this.applyPosition()\n const root = document.getElementById('instruckt-root') ?? document.body\n root.appendChild(this.host)\n }\n\n private makeBtn(iconHtml: string, title: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.className = 'btn'\n btn.title = title\n btn.setAttribute('aria-label', title)\n btn.innerHTML = iconHtml\n btn.addEventListener('click', (e) => {\n e.stopPropagation()\n onClick()\n })\n return btn\n }\n\n private applyPosition(): void {\n const m = '16px'\n Object.assign(this.host.style, {\n position: 'fixed',\n zIndex: '2147483646',\n bottom: this.position.includes('bottom') ? m : 'auto',\n top: this.position.includes('top') ? m : 'auto',\n right: this.position.includes('right') ? m : 'auto',\n left: this.position.includes('left') ? m : 'auto',\n })\n }\n\n private setupDrag(): void {\n this.shadow.addEventListener('mousedown', (evt) => {\n const e = evt as MouseEvent\n if ((e.target as Element).closest('.btn') || (e.target as Element).closest('.fab')) return\n this.dragging = true\n const rect = this.host.getBoundingClientRect()\n this.dragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top }\n e.preventDefault()\n })\n\n document.addEventListener('mousemove', (e) => {\n if (!this.dragging) return\n Object.assign(this.host.style, {\n left: `${e.clientX - this.dragOffset.x}px`,\n top: `${e.clientY - this.dragOffset.y}px`,\n right: 'auto',\n bottom: 'auto',\n })\n })\n\n document.addEventListener('mouseup', () => { this.dragging = false })\n }\n\n private setMinimized(min: boolean): void {\n this.minimized = min\n this.toolbarEl.style.display = min ? 'none' : ''\n this.fab.style.display = min ? '' : 'none'\n this.updateFabBadge()\n this.callbacks.onMinimize?.(min)\n }\n\n private updateFabBadge(): void {\n if (this.totalCount > 0 && this.minimized) {\n if (!this.fabBadge) {\n this.fabBadge = document.createElement('span')\n this.fabBadge.className = 'fab-badge'\n this.fab.appendChild(this.fabBadge)\n }\n this.fabBadge.textContent = this.totalCount > 99 ? '99+' : String(this.totalCount)\n } else {\n this.fabBadge?.remove()\n this.fabBadge = null\n }\n }\n\n isMinimized(): boolean {\n return this.minimized\n }\n\n /** Programmatically minimize without firing callback */\n minimize(): void {\n this.minimized = true\n this.toolbarEl.style.display = 'none'\n this.fab.style.display = ''\n this.updateFabBadge()\n }\n\n setAnnotateActive(active: boolean): void {\n this.annotateActive = active\n this.annotateBtn.classList.toggle('active', active)\n document.body.classList.toggle('ik-annotating', active)\n }\n\n setFreezeActive(active: boolean): void {\n this.freezeActive = active\n this.freezeBtn.classList.toggle('active', active)\n }\n\n // Keep for compatibility — resolves visual mode from instruckt.ts\n setMode(mode: ToolbarMode): void {\n this.setAnnotateActive(mode === 'annotating')\n }\n\n setAnnotationCount(count: number): void {\n let badge = this.annotateBtn.querySelector('.badge')\n if (count > 0) {\n if (!badge) {\n badge = document.createElement('span')\n badge.className = 'badge'\n this.annotateBtn.appendChild(badge)\n }\n badge.textContent = count > 99 ? '99+' : String(count)\n } else {\n badge?.remove()\n }\n }\n\n setTotalCount(count: number): void {\n this.totalCount = count\n this.updateFabBadge()\n }\n\n destroy(): void {\n this.host.remove()\n document.body.classList.remove('ik-annotating')\n }\n}\n","/** Hover highlight overlay — uses all inline styles, no CSS class needed */\nexport class ElementHighlight {\n private el: HTMLElement\n\n constructor() {\n this.el = document.createElement('div')\n // All styling inline to avoid any host-page CSS interference\n Object.assign(this.el.style, {\n position: 'fixed',\n pointerEvents: 'none', // MUST be none — prevents swallowing clicks\n zIndex: '2147483644',\n border: '2px solid rgba(99,102,241,0.7)',\n background: 'rgba(99,102,241,0.1)',\n borderRadius: '3px',\n transition: 'all 0.06s ease',\n display: 'none',\n })\n this.el.setAttribute('data-instruckt', 'highlight')\n const root = document.getElementById('instruckt-root') ?? document.body\n root.appendChild(this.el)\n }\n\n show(el: Element): void {\n const rect = el.getBoundingClientRect()\n if (rect.width === 0 && rect.height === 0) {\n this.hide()\n return\n }\n Object.assign(this.el.style, {\n display: 'block',\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n })\n }\n\n hide(): void {\n this.el.style.display = 'none'\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","import type { Annotation, PendingAnnotation } from '../types'\nimport { POPUP_CSS } from './styles'\n\ninterface PopupResult {\n comment: string\n}\n\ninterface PopupCallbacks {\n onSubmit: (result: PopupResult) => void\n onCancel: () => void\n}\n\ninterface EditCallbacks {\n onSave: (annotation: Annotation, newComment: string) => void\n onDelete: (annotation: Annotation) => void\n}\n\nfunction esc(s: string): string {\n return String(s ?? '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"')\n}\n\n/** Annotation popup — rendered in its own shadow DOM for CSS isolation */\nexport class AnnotationPopup {\n private host: HTMLElement | null = null\n private shadow: ShadowRoot | null = null\n\n // ── New annotation popup ──────────────────────────────────────\n\n showNew(pending: PendingAnnotation, callbacks: PopupCallbacks): void {\n this.destroy()\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'popup')\n this.stopHostPropagation(this.host)\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = POPUP_CSS\n this.shadow.appendChild(style)\n\n const popup = document.createElement('div')\n popup.className = 'popup'\n\n const fwBadge = pending.framework\n ? `<div class=\"fw-badge\">${esc(pending.framework.component)}</div>`\n : ''\n const selText = pending.selectedText\n ? `<div class=\"selected-text\">\"${esc(pending.selectedText.slice(0, 80))}\"</div>`\n : ''\n\n popup.innerHTML = `\n <div class=\"header\">\n <span class=\"element-tag\" title=\"${esc(pending.elementPath)}\">${esc(pending.elementLabel)}</span>\n <button class=\"close-btn\" title=\"Cancel (Esc)\">✕</button>\n </div>\n ${fwBadge}${selText}\n <textarea placeholder=\"What needs to change here?\" rows=\"3\"></textarea>\n <div class=\"actions\">\n <button class=\"btn-secondary\" data-action=\"cancel\">Cancel</button>\n <button class=\"btn-primary\" data-action=\"submit\" disabled>Add note</button>\n </div>\n `\n\n const textarea = popup.querySelector('textarea')!\n const submitBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"submit\"]')!\n\n textarea.addEventListener('input', () => {\n submitBtn.disabled = textarea.value.trim().length === 0\n })\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n if (!submitBtn.disabled) submitBtn.click()\n }\n if (e.key === 'Escape') { callbacks.onCancel(); this.destroy() }\n })\n\n popup.querySelector('[data-action=\"cancel\"]')!.addEventListener('click', () => {\n callbacks.onCancel(); this.destroy()\n })\n popup.querySelector('.close-btn')!.addEventListener('click', () => {\n callbacks.onCancel(); this.destroy()\n })\n submitBtn.addEventListener('click', () => {\n const comment = textarea.value.trim()\n if (!comment) return\n callbacks.onSubmit({ comment })\n this.destroy()\n })\n\n this.shadow.appendChild(popup)\n ;(document.getElementById('instruckt-root') ?? document.body).appendChild(this.host)\n\n this.positionHost(pending.x, pending.y)\n this.setupOutsideClick()\n textarea.focus()\n }\n\n // ── Edit existing annotation ──────────────────────────────────\n\n showEdit(annotation: Annotation, callbacks: EditCallbacks): void {\n this.destroy()\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'popup')\n this.stopHostPropagation(this.host)\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = POPUP_CSS\n this.shadow.appendChild(style)\n\n const popup = document.createElement('div')\n popup.className = 'popup'\n\n const fwBadge = annotation.framework\n ? `<div class=\"fw-badge\">${esc(annotation.framework.component)}</div>`\n : ''\n\n popup.innerHTML = `\n <div class=\"header\">\n <span class=\"element-tag\" title=\"${esc(annotation.elementPath)}\">${esc(annotation.element)}</span>\n <button class=\"close-btn\">✕</button>\n </div>\n ${fwBadge}\n <textarea rows=\"3\">${esc(annotation.comment)}</textarea>\n <div class=\"actions\">\n <button class=\"btn-danger\" data-action=\"delete\">Remove</button>\n <button class=\"btn-primary\" data-action=\"save\">Save</button>\n </div>\n `\n\n popup.querySelector('.close-btn')!.addEventListener('click', () => this.destroy())\n\n const textarea = popup.querySelector('textarea')!\n const saveBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"save\"]')!\n const deleteBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"delete\"]')!\n\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n saveBtn.click()\n }\n if (e.key === 'Escape') this.destroy()\n })\n\n saveBtn.addEventListener('click', () => {\n const newComment = textarea.value.trim()\n if (!newComment) return\n callbacks.onSave(annotation, newComment)\n this.destroy()\n })\n\n deleteBtn.addEventListener('click', () => {\n callbacks.onDelete(annotation)\n this.destroy()\n })\n\n this.shadow.appendChild(popup)\n ;(document.getElementById('instruckt-root') ?? document.body).appendChild(this.host)\n\n // Position near the marker\n const markerX = (annotation.x / 100) * window.innerWidth\n const markerY = annotation.y - window.scrollY\n this.positionHost(markerX, markerY)\n this.setupOutsideClick()\n textarea.focus()\n textarea.setSelectionRange(textarea.value.length, textarea.value.length)\n }\n\n // ── Helpers ───────────────────────────────────────────────────\n\n /** Prevent popup interactions from reaching page handlers (e.g. @click.outside) */\n private stopHostPropagation(host: HTMLElement): void {\n for (const evt of ['click', 'mousedown', 'pointerdown'] as const) {\n host.addEventListener(evt, (e) => e.stopPropagation())\n }\n }\n\n private positionHost(x: number, y: number): void {\n if (!this.host) return\n // Use popover=\"manual\" to render in the top layer (above native popovers)\n this.host.setAttribute('popover', 'manual')\n try { this.host.showPopover() } catch { /* fallback to z-index */ }\n Object.assign(this.host.style, { position: 'fixed', zIndex: '2147483647', left: '-9999px', top: '0' })\n\n requestAnimationFrame(() => {\n if (!this.host) return\n const w = 340 + 20\n const h = this.host.querySelector('.popup')?.getBoundingClientRect().height ?? 300\n const vw = window.innerWidth\n const vh = window.innerHeight\n const left = Math.max(10, Math.min(x + 10, vw - w))\n const top = Math.max(10, Math.min(y + 10, vh - h - 10))\n Object.assign(this.host.style, { left: `${left}px`, top: `${top}px` })\n })\n }\n\n private boundOutside = (e: MouseEvent): void => {\n if (this.host && !this.host.contains(e.target as Node)) {\n this.destroy()\n }\n }\n\n private setupOutsideClick(): void {\n setTimeout(() => document.addEventListener('mousedown', this.boundOutside), 0)\n }\n\n destroy(): void {\n this.host?.remove()\n this.host = null\n this.shadow = null\n document.removeEventListener('mousedown', this.boundOutside)\n }\n}\n","import type { Annotation } from '../types'\n\ntype MarkerClickHandler = (annotation: Annotation) => void\n\ninterface MarkerEl {\n el: HTMLElement\n annotationId: string\n}\n\n/** Manages numbered annotation pins rendered directly on the page */\nexport class AnnotationMarkers {\n private container: HTMLElement\n private markers: Map<string, MarkerEl> = new Map()\n\n constructor(private readonly onClick: MarkerClickHandler) {\n // Fixed-position container over the page, pointer-events passthrough\n this.container = document.createElement('div')\n Object.assign(this.container.style, {\n position: 'fixed',\n inset: '0',\n pointerEvents: 'none',\n zIndex: '2147483645',\n })\n this.container.setAttribute('data-instruckt', 'markers')\n const root = document.getElementById('instruckt-root') ?? document.body\n root.appendChild(this.container)\n }\n\n /** Add or update a marker for an annotation */\n upsert(annotation: Annotation, index: number): void {\n const existing = this.markers.get(annotation.id)\n\n if (existing) {\n this.updateStyle(existing.el, annotation)\n return\n }\n\n const el = document.createElement('div')\n el.className = `ik-marker ${this.statusClass(annotation.status)}`\n el.textContent = String(index)\n el.title = annotation.comment.slice(0, 60)\n el.style.pointerEvents = 'all'\n\n // Position: annotation.x is % of viewport width, annotation.y is px from top (scroll-adjusted)\n // Convert back to viewport-relative for fixed positioning\n el.style.left = `${(annotation.x / 100) * window.innerWidth}px`\n el.style.top = `${annotation.y - window.scrollY}px`\n\n el.addEventListener('click', (e) => {\n e.stopPropagation()\n this.onClick(annotation)\n })\n\n this.container.appendChild(el)\n this.markers.set(annotation.id, { el, annotationId: annotation.id })\n }\n\n /** Update an existing marker after its annotation status changed */\n update(annotation: Annotation): void {\n const marker = this.markers.get(annotation.id)\n if (!marker) return\n this.updateStyle(marker.el, annotation)\n }\n\n private updateStyle(el: HTMLElement, annotation: Annotation): void {\n el.className = `ik-marker ${this.statusClass(annotation.status)}`\n el.title = annotation.comment.slice(0, 60)\n }\n\n private statusClass(status: string): string {\n if (status === 'resolved') return 'resolved'\n if (status === 'dismissed') return 'dismissed'\n if (status === 'acknowledged') return 'acknowledged'\n return ''\n }\n\n /** Reposition all markers (e.g. after scroll or resize) */\n reposition(annotations: Annotation[]): void {\n annotations.forEach(annotation => {\n const marker = this.markers.get(annotation.id)\n if (!marker) return\n marker.el.style.left = `${(annotation.x / 100) * window.innerWidth}px`\n marker.el.style.top = `${annotation.y - window.scrollY}px`\n })\n }\n\n remove(annotationId: string): void {\n const marker = this.markers.get(annotationId)\n if (!marker) return\n marker.el.remove()\n this.markers.delete(annotationId)\n }\n\n /** Show or hide all markers */\n setVisible(visible: boolean): void {\n this.container.style.display = visible ? '' : 'none'\n }\n\n /** Remove all markers without destroying the container */\n clear(): void {\n for (const { el } of this.markers.values()) {\n el.remove()\n }\n this.markers.clear()\n }\n\n destroy(): void {\n this.container.remove()\n this.markers.clear()\n }\n}\n","/**\n * CSS selector and element path generation.\n * Produces unique, grep-able selectors for any DOM element.\n */\n\n/** Build a unique CSS selector for an element */\nexport function getElementSelector(el: Element): string {\n if (el.id) {\n return `#${CSS.escape(el.id)}`\n }\n\n const path: 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 (!parent) {\n path.unshift(tag)\n break\n }\n\n // Try unique class combo\n const classes = Array.from(current.classList)\n .filter(c => !c.match(/^(hover|focus|active|visited|is-|has-)/)) // skip state classes\n .slice(0, 3)\n\n if (classes.length > 0) {\n const classSelector = `${tag}.${classes.map(CSS.escape).join('.')}`\n const matches = parent.querySelectorAll(classSelector)\n if (matches.length === 1) {\n path.unshift(classSelector)\n break\n }\n }\n\n // Fall back to nth-child\n const siblings = Array.from(parent.children).filter((c: Element) => c.tagName === current!.tagName)\n if (siblings.length === 1) {\n path.unshift(tag)\n } else {\n const index = siblings.indexOf(current) + 1\n path.unshift(`${tag}:nth-of-type(${index})`)\n }\n\n current = parent\n }\n\n return path.join(' > ')\n}\n\n/** Short element identifier for markdown output (grep-friendly) */\nexport function getElementName(el: Element): string {\n const tag = el.tagName.toLowerCase()\n\n const wireModel = el.getAttribute('wire:model') || el.getAttribute('wire:click')\n if (wireModel) return `${tag}[wire:${wireModel.split('.')[0]}]`\n\n if (el.id) return `${tag}#${el.id}`\n\n const firstClass = el.classList[0]\n if (firstClass) return `${tag}.${firstClass}`\n\n return tag\n}\n\n/** Human-readable HTML-like label for the popup UI */\nexport function getElementLabel(el: Element): string {\n const tag = el.tagName.toLowerCase()\n const text = (el.textContent || '').trim().replace(/\\s+/g, ' ').slice(0, 40)\n\n // Build a short opening tag with key attributes\n const attrs: string[] = []\n if (el.id) attrs.push(`id=\"${el.id}\"`)\n const role = el.getAttribute('role')\n if (role) attrs.push(`role=\"${role}\"`)\n const wireAttr = el.getAttribute('wire:model') || el.getAttribute('wire:click')\n if (wireAttr) attrs.push(`wire:${el.hasAttribute('wire:model') ? 'model' : 'click'}=\"${wireAttr}\"`)\n\n const attrStr = attrs.length ? ' ' + attrs.join(' ') : ''\n const openTag = `<${tag}${attrStr}>`\n\n if (text) return `${openTag} ${text}`\n return openTag\n}\n\n/** Get nearby readable text for context */\nexport function getNearbyText(el: Element): string {\n const text = (el.textContent || '').trim().replace(/\\s+/g, ' ')\n return text.slice(0, 120)\n}\n\n/** CSS classes as a space-separated string, filtering noise */\nexport function getCssClasses(el: Element): string {\n return Array.from(el.classList)\n .filter(c => !c.match(/^(instruckt-)/)) // exclude our own classes\n .join(' ')\n}\n\n/** Get bounding box relative to the page */\nexport function getPageBoundingBox(el: Element): { x: number; y: number; width: number; height: number } {\n const rect = el.getBoundingClientRect()\n return {\n x: rect.left + window.scrollX,\n y: rect.top + window.scrollY,\n width: rect.width,\n height: rect.height,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ndeclare global {\n interface Window {\n Livewire?: { find(id: string): unknown }\n }\n}\n\nexport function isAvailable(): boolean {\n return typeof window.Livewire !== 'undefined'\n}\n\n/** Walk up the DOM from el to find the nearest wire:id ancestor */\nexport function detect(el: Element): Element | null {\n let node: Element | null = el\n while (node && node !== document.documentElement) {\n if (node.getAttribute('wire:id')) return node\n node = node.parentElement\n }\n return null\n}\n\n/** Get Livewire component context for an element */\nexport function getContext(el: Element): FrameworkContext | null {\n if (!isAvailable()) return null\n\n const wireEl = detect(el)\n if (!wireEl) return null\n\n const wireId = wireEl.getAttribute('wire:id')!\n\n // In Livewire v3, the component name lives in the wire:snapshot attribute\n let componentName = 'Unknown'\n const snapshotAttr = wireEl.getAttribute('wire:snapshot')\n if (snapshotAttr) {\n try {\n const snapshot = JSON.parse(snapshotAttr)\n componentName = snapshot?.memo?.name ?? 'Unknown'\n } catch {\n // malformed snapshot\n }\n }\n\n return {\n framework: 'livewire',\n component: componentName,\n wire_id: wireId,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ninterface VueInstance {\n $options?: { name?: string; __name?: string }\n type?: { name?: string; __name?: string }\n uid?: number\n props?: Record<string, unknown>\n setupState?: Record<string, unknown>\n}\n\ninterface VueElement extends Element {\n __vue__?: VueInstance\n __vueParentComponent?: VueInstance\n _vei?: unknown\n}\n\nexport function isAvailable(): boolean {\n // Vue 3: mounts with data-v-app attribute; Vue 2: exposes global Vue constructor\n return !!(document.querySelector('[data-v-app]') || (window as unknown as Record<string, unknown>)['Vue'])\n}\n\n/** Walk up the DOM to find the nearest Vue component */\nexport function detect(el: Element): VueInstance | null {\n let node: VueElement | null = el as VueElement\n while (node && node !== document.documentElement) {\n const instance = node.__vueParentComponent ?? node.__vue__\n if (instance) return instance\n node = node.parentElement as VueElement | null\n }\n return null\n}\n\n/** Get Vue component context for an element */\nexport function getContext(el: Element): FrameworkContext | null {\n const instance = detect(el)\n if (!instance) return null\n\n // Support Vue 2 ($options.name) and Vue 3 (type.name or type.__name)\n const name =\n instance.$options?.name ??\n instance.$options?.__name ??\n instance.type?.name ??\n instance.type?.__name ??\n 'Anonymous'\n\n const data: Record<string, unknown> = {}\n\n // Vue 3 props\n if (instance.props) {\n Object.assign(data, instance.props)\n }\n\n // Vue 3 setup state (public reactive refs)\n if (instance.setupState) {\n for (const [key, value] of Object.entries(instance.setupState)) {\n if (!key.startsWith('_') && typeof value !== 'function') {\n try {\n data[key] = JSON.parse(JSON.stringify(value))\n } catch {\n data[key] = String(value)\n }\n }\n }\n }\n\n return {\n framework: 'vue',\n component: name,\n component_uid: instance.uid !== undefined ? String(instance.uid) : undefined,\n data,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ninterface SvelteMeta {\n loc?: { file?: string }\n ctx?: unknown[]\n}\n\ninterface SvelteElement extends Element {\n __svelte_meta?: SvelteMeta\n __svelte?: unknown\n}\n\n/** Walk up DOM to find nearest Svelte component element */\nexport function detect(el: Element): SvelteMeta | null {\n let node: SvelteElement | null = el as SvelteElement\n while (node && node !== document.documentElement) {\n if (node.__svelte_meta) return node.__svelte_meta\n node = node.parentElement as SvelteElement | null\n }\n return null\n}\n\n/** Get Svelte component context for an element */\nexport function getContext(el: Element): FrameworkContext | null {\n const meta = detect(el)\n if (!meta) return null\n\n // Extract component name from file path e.g. \"/src/components/Button.svelte\" → \"Button\"\n const filePath = meta.loc?.file ?? ''\n const component = filePath\n ? filePath.split('/').pop()?.replace(/\\.svelte$/, '') ?? 'Unknown'\n : 'Unknown'\n\n return {\n framework: 'svelte',\n component,\n data: filePath ? { file: filePath } : undefined,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ninterface ReactFiber {\n type: unknown\n memoizedProps: Record<string, unknown> | null\n pendingProps: Record<string, unknown> | null\n return: ReactFiber | null\n key: string | null\n}\n\ninterface ReactElement extends Element {\n [key: string]: unknown\n}\n\nfunction getFiberKey(el: Element): string | null {\n for (const key of Object.keys(el)) {\n if (key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$')) {\n return key\n }\n }\n return null\n}\n\nfunction getComponentName(fiber: ReactFiber): string {\n let node: ReactFiber | null = fiber\n while (node) {\n const { type } = node\n if (typeof type === 'function' && (type as { name?: string }).name) {\n const name = (type as { name: string }).name\n // Skip React internals (start with lowercase = intrinsic HTML element function)\n if (name[0] === name[0].toUpperCase() && name.length > 1) return name\n }\n if (typeof type === 'object' && type !== null && (type as { displayName?: string }).displayName) {\n return (type as { displayName: string }).displayName\n }\n node = node.return\n }\n return 'Component'\n}\n\nfunction getProps(fiber: ReactFiber): Record<string, unknown> {\n const props = fiber.memoizedProps ?? fiber.pendingProps ?? {}\n const result: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(props)) {\n if (k === 'children' || typeof v === 'function') continue\n try {\n result[k] = JSON.parse(JSON.stringify(v))\n } catch {\n result[k] = String(v)\n }\n }\n return result\n}\n\nexport function isAvailable(): boolean {\n // React attaches fiber data to DOM nodes with __reactFiber$ prefix\n const root = document.getElementById('root') ?? document.getElementById('app') ?? document.body.firstElementChild\n if (!root) return false\n return getFiberKey(root) !== null\n}\n\nexport function getContext(el: Element): FrameworkContext | null {\n let node: Element | null = el\n while (node && node !== document.documentElement) {\n const key = getFiberKey(node)\n if (key) {\n const fiber = (node as ReactElement)[key] as ReactFiber\n if (fiber) {\n const component = getComponentName(fiber)\n const data = getProps(fiber)\n return { framework: 'react', component, data }\n }\n }\n node = node.parentElement\n }\n return null\n}\n","import type { Annotation, InstrucktConfig, PendingAnnotation } from './types'\nimport { InstrucktApi } from './api'\nimport type { AnnotationPayload } from './api'\nimport { Toolbar } from './ui/toolbar'\nimport { ElementHighlight } from './ui/highlight'\nimport { AnnotationPopup } from './ui/popup'\nimport { AnnotationMarkers } from './ui/markers'\nimport { injectGlobalStyles } from './ui/styles'\nimport { getElementSelector, getElementName, getElementLabel, getNearbyText, getCssClasses, getPageBoundingBox } from './selector'\nimport * as livewireAdapter from './adapters/livewire'\nimport * as vueAdapter from './adapters/vue'\nimport * as svelteAdapter from './adapters/svelte'\nimport * as reactAdapter from './adapters/react'\n\n// Re-export for api.ts consumers\nexport type { AnnotationPayload }\n\n/** Normalize URL to pathname for page-scoping (ignore query/hash) */\nfunction pageKey(): string {\n return window.location.pathname\n}\n\nexport class Instruckt {\n private config: Required<Pick<InstrucktConfig, 'endpoint' | 'theme' | 'position'>> & InstrucktConfig\n private api: InstrucktApi\n private toolbar: Toolbar | null = null\n private highlight: ElementHighlight | null = null\n private popup: AnnotationPopup | null = null\n private markers: AnnotationMarkers | null = null\n private annotations: Annotation[] = []\n private isAnnotating = false\n private isFrozen = false\n private frozenStyleEl: HTMLStyleElement | null = null\n private frozenPopovers: { el: HTMLElement; original: string }[] = []\n private rafId: number | null = null\n private pendingMouseTarget: Element | null = null\n private highlightLocked = false\n private boundKeydown: (e: KeyboardEvent) => void\n private boundReposition = (): void => {\n this.markers?.reposition(this.annotations)\n }\n\n constructor(config: InstrucktConfig) {\n this.config = {\n adapters: ['livewire', 'vue', 'svelte', 'react'],\n theme: 'auto',\n position: 'bottom-right',\n ...config,\n }\n this.api = new InstrucktApi(config.endpoint)\n this.boundKeydown = this.onKeydown.bind(this)\n this.init()\n }\n\n private init(): void {\n injectGlobalStyles()\n\n if (this.config.theme !== 'auto') {\n document.documentElement.setAttribute('data-instruckt-theme', this.config.theme)\n }\n\n this.toolbar = new Toolbar(this.config.position, {\n onToggleAnnotate: (active) => {\n this.setAnnotating(active)\n },\n onFreezeAnimations: (frozen) => {\n this.setFrozen(frozen)\n },\n onCopy: () => this.copyAnnotations(),\n onClearPage: () => this.clearPage(),\n onClearAll: () => this.clearEverything(),\n onMinimize: (min) => this.onMinimize(min),\n })\n\n this.highlight = new ElementHighlight()\n this.popup = new AnnotationPopup()\n this.markers = new AnnotationMarkers((annotation) => this.onMarkerClick(annotation))\n\n document.addEventListener('keydown', this.boundKeydown)\n window.addEventListener('scroll', this.boundReposition, { passive: true })\n window.addEventListener('resize', this.boundReposition, { passive: true })\n\n // Survive Livewire wire:navigate (forward nav and back/forward button)\n document.addEventListener('livewire:navigated', () => this.reattach())\n // For non-Livewire SPAs (Vue Router, React Router, SvelteKit, etc.)\n // Use a microtask delay so the new DOM is in place before we reattach\n window.addEventListener('popstate', () => {\n setTimeout(() => this.reattach(), 0)\n })\n\n // Load persisted annotations from the backend\n this.loadAnnotations()\n\n this.syncMarkers()\n }\n\n private makeToolbarCallbacks() {\n return {\n onToggleAnnotate: (active: boolean) => {\n this.setAnnotating(active)\n },\n onFreezeAnimations: (frozen: boolean) => {\n this.setFrozen(frozen)\n },\n onCopy: () => this.copyAnnotations(),\n onClearPage: () => this.clearPage(),\n onClearAll: () => this.clearEverything(),\n onMinimize: (min: boolean) => this.onMinimize(min),\n }\n }\n\n private reattach(): void {\n const wasAnnotating = this.isAnnotating\n const wasFrozen = this.isFrozen\n const wasMinimized = this.toolbar?.isMinimized() ?? false\n\n // Detach current listeners before rebuilding\n if (this.isAnnotating) this.detachAnnotateListeners()\n if (this.isFrozen) this.setFrozen(false)\n this.isAnnotating = false\n this.isFrozen = false\n\n // Remove any stale instruckt DOM (Livewire caches and restores old HTML on back nav)\n document.querySelectorAll('[data-instruckt]').forEach(el => el.remove())\n\n // Rebuild everything fresh\n this.toolbar = new Toolbar(this.config.position, this.makeToolbarCallbacks())\n if (wasMinimized) this.toolbar.minimize()\n\n this.markers = new AnnotationMarkers((annotation) => this.onMarkerClick(annotation))\n this.highlight = new ElementHighlight()\n\n if (wasMinimized) this.markers.setVisible(false)\n\n // Re-inject global styles (Livewire may have swapped <head> content)\n const existing = document.getElementById('instruckt-global')\n if (existing) existing.remove()\n injectGlobalStyles()\n\n this.syncMarkers()\n\n // Restore active modes\n if (wasAnnotating && !wasMinimized) this.setAnnotating(true)\n }\n\n // ── Minimize ────────────────────────────────────────────────────\n\n private onMinimize(minimized: boolean): void {\n if (minimized) {\n // Deactivate everything when minimized\n if (this.isAnnotating) this.setAnnotating(false)\n if (this.isFrozen) this.setFrozen(false)\n this.toolbar?.setAnnotateActive(false)\n this.toolbar?.setFreezeActive(false)\n this.markers?.setVisible(false)\n this.popup?.destroy()\n } else {\n // Show markers again when restored\n this.markers?.setVisible(true)\n }\n }\n\n // ── Persistence ─────────────────────────────────────────────────\n\n private static STORAGE_KEY = 'instruckt:annotations'\n\n private async loadAnnotations(): Promise<void> {\n // Always load localStorage first as baseline\n this.loadFromStorage()\n\n try {\n const remote = await this.api.getAnnotations()\n if (remote.length > 0) {\n // Merge: remote is source of truth, but keep any local-only annotations\n const remoteIds = new Set(remote.map(a => a.id))\n const localOnly = this.annotations.filter(a => !remoteIds.has(a.id))\n this.annotations = [...remote, ...localOnly]\n this.saveToStorage()\n }\n } catch {\n // No backend — localStorage already loaded above\n }\n this.syncMarkers()\n }\n\n private saveToStorage(): void {\n try {\n localStorage.setItem(Instruckt.STORAGE_KEY, JSON.stringify(this.annotations))\n } catch { /* storage full or unavailable */ }\n }\n\n private loadFromStorage(): void {\n try {\n const raw = localStorage.getItem(Instruckt.STORAGE_KEY)\n if (raw) this.annotations = JSON.parse(raw)\n } catch { /* corrupt or unavailable */ }\n }\n\n // ── Page-scoped markers ─────────────────────────────────────────\n\n private syncMarkers(): void {\n this.markers?.clear()\n const current = pageKey()\n let idx = 0\n for (const a of this.annotations) {\n if (a.status === 'resolved' || a.status === 'dismissed') continue\n if (this.annotationPageKey(a) === current) {\n idx++\n this.markers?.upsert(a, idx)\n }\n }\n this.toolbar?.setAnnotationCount(this.pageAnnotations().length)\n this.toolbar?.setTotalCount(this.totalActiveCount())\n }\n\n private annotationPageKey(a: Annotation): string {\n try {\n return new URL(a.url).pathname\n } catch {\n return a.url\n }\n }\n\n private pageAnnotations(): Annotation[] {\n const current = pageKey()\n return this.annotations.filter(a =>\n this.annotationPageKey(a) === current &&\n a.status !== 'resolved' && a.status !== 'dismissed'\n )\n }\n\n private totalActiveCount(): number {\n return this.annotations.filter(a => a.status !== 'resolved' && a.status !== 'dismissed').length\n }\n\n // ── Annotate mode ─────────────────────────────────────────────\n\n private setAnnotating(active: boolean): void {\n this.isAnnotating = active\n this.toolbar?.setAnnotateActive(active)\n if (active) {\n this.attachAnnotateListeners()\n } else {\n this.detachAnnotateListeners()\n this.highlight?.hide()\n if (this.rafId !== null) { cancelAnimationFrame(this.rafId); this.rafId = null }\n }\n // When frozen, toggle pointer-events based on annotate state\n this.updateFreezeStyles()\n }\n\n // ── Freeze mode ──────────────────────────────────────────────\n\n private setFrozen(frozen: boolean): void {\n this.isFrozen = frozen\n this.toolbar?.setFreezeActive(frozen)\n if (frozen) {\n this.updateFreezeStyles()\n this.freezePopovers()\n // Use window (not document) so we intercept before Livewire/Alpine handlers\n // on document. Capture on window fires before capture on document.\n for (const evt of this.freezeBlockEvents) {\n window.addEventListener(evt, this.boundFreezeClick, true)\n }\n window.addEventListener('submit', this.boundFreezeSubmit, true)\n // Block events that close dropdowns/popovers (window capture to beat frameworks)\n for (const evt of this.freezePassiveEvents) {\n window.addEventListener(evt, this.boundFreezePassive, true)\n }\n } else {\n this.frozenStyleEl?.remove()\n this.frozenStyleEl = null\n this.unfreezePopovers()\n for (const evt of this.freezeBlockEvents) {\n window.removeEventListener(evt, this.boundFreezeClick, true)\n }\n window.removeEventListener('submit', this.boundFreezeSubmit, true)\n for (const evt of this.freezePassiveEvents) {\n window.removeEventListener(evt, this.boundFreezePassive, true)\n }\n }\n }\n\n /** Pull open popovers out of the top layer so the rest of the page is clickable */\n private freezePopovers(): void {\n this.frozenPopovers = []\n const openSelector = ':popover-open, .\\\\:popover-open'\n document.querySelectorAll('[popover]').forEach((el) => {\n const htmlEl = el as HTMLElement\n const val = htmlEl.getAttribute('popover') ?? ''\n let isOpen = false\n try { isOpen = htmlEl.matches(openSelector) } catch {\n try { isOpen = htmlEl.matches('.\\\\:popover-open') } catch { /* ignore */ }\n }\n if (!isOpen) return\n // Save position before removing popover attribute\n const rect = htmlEl.getBoundingClientRect()\n this.frozenPopovers.push({ el: htmlEl, original: val })\n // Remove popover attribute — pulls element out of top layer\n htmlEl.removeAttribute('popover')\n // Keep it visible with inline styles\n htmlEl.style.setProperty('display', 'block', 'important')\n htmlEl.style.setProperty('position', 'fixed', 'important')\n htmlEl.style.setProperty('z-index', '2147483644', 'important')\n htmlEl.style.setProperty('top', `${rect.top}px`, 'important')\n htmlEl.style.setProperty('left', `${rect.left}px`, 'important')\n htmlEl.style.setProperty('width', `${rect.width}px`, 'important')\n // Add the polyfill class so Flux thinks it's still open\n htmlEl.classList.add(':popover-open')\n })\n }\n\n /** Restore popover attributes */\n private unfreezePopovers(): void {\n for (const { el, original } of this.frozenPopovers) {\n // Remove inline overrides\n for (const prop of ['display', 'position', 'z-index', 'top', 'left', 'width']) {\n el.style.removeProperty(prop)\n }\n el.classList.remove(':popover-open')\n el.setAttribute('popover', original || 'auto')\n }\n this.frozenPopovers = []\n }\n\n private freezeBlockEvents = ['click', 'mousedown', 'pointerdown', 'pointerup', 'mouseup', 'touchstart', 'touchend', 'auxclick'] as const\n private freezePassiveEvents = ['focusin', 'focusout', 'blur', 'pointerleave', 'mouseleave', 'mouseout'] as const\n\n /** Update freeze CSS — pointer-events only blocked when NOT annotating */\n private updateFreezeStyles(): void {\n if (!this.isFrozen) return\n this.frozenStyleEl?.remove()\n this.frozenStyleEl = document.createElement('style')\n this.frozenStyleEl.id = 'instruckt-freeze'\n const pointerBlock = this.isAnnotating ? '' : `\n a[href], a[wire\\\\:navigate], [wire\\\\:click], [wire\\\\:navigate],\n [x-on\\\\:click], [@click], [v-on\\\\:click], [onclick],\n button, input[type=\"submit\"], select, [role=\"button\"], [role=\"link\"],\n [tabindex] {\n pointer-events: none !important;\n cursor: not-allowed !important;\n }\n `\n this.frozenStyleEl.textContent = `\n *, *::before, *::after {\n animation-play-state: paused !important;\n transition: none !important;\n }\n video { filter: none !important; }\n ${pointerBlock}\n `\n document.head.appendChild(this.frozenStyleEl)\n }\n\n /** Block interactions on the page when frozen (except instruckt UI) */\n private boundFreezeClick = (e: Event): void => {\n if (this.isInstruckt(e.target)) return\n // When annotating, only let 'click' through (annotate handler needs it).\n // Always block mousedown/pointerdown/touchstart to prevent framework\n // handlers (Alpine @click.outside, Livewire wire:navigate) from firing.\n if (this.isAnnotating && e.type === 'click') return\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n private boundFreezeSubmit = (e: Event): void => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n /** Block focus/hover events that JS dropdowns use to auto-close.\n * Block ALL of these — even on instruckt elements — because frameworks\n * like Flux check if focusin target is contained in the popover and\n * close it if it's not (e.g. focus moved to our popup textarea). */\n private boundFreezePassive = (e: Event): void => {\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n // ── Event listeners ───────────────────────────────────────────\n\n private boundMouseMove = (e: MouseEvent): void => {\n if (this.highlightLocked) return\n this.pendingMouseTarget = e.target as Element\n if (this.rafId === null) {\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (this.highlightLocked) return\n if (this.pendingMouseTarget && !this.isInstruckt(this.pendingMouseTarget)) {\n this.highlight?.show(this.pendingMouseTarget)\n } else {\n this.highlight?.hide()\n }\n })\n }\n }\n\n private boundMouseLeave = (): void => {\n if (this.highlightLocked) return\n this.highlight?.hide()\n }\n\n private boundClick = (e: MouseEvent): void => {\n const target = e.target as Element\n if (this.isInstruckt(target)) return\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n\n const selectedText = window.getSelection()?.toString().trim() || undefined\n const elementPath = getElementSelector(target)\n const elementName = getElementName(target)\n const elementLabel = getElementLabel(target)\n const cssClasses = getCssClasses(target)\n const nearbyText = getNearbyText(target) || undefined\n const boundingBox = getPageBoundingBox(target)\n const framework = this.detectFramework(target) ?? undefined\n\n const pending: PendingAnnotation = {\n element: target,\n elementPath,\n elementName,\n elementLabel,\n cssClasses,\n boundingBox,\n x: e.clientX,\n y: e.clientY,\n selectedText,\n nearbyText,\n framework,\n }\n\n this.highlight?.show(target)\n this.highlightLocked = true\n\n this.popup?.showNew(pending, {\n onSubmit: (result) => {\n this.highlightLocked = false\n this.highlight?.hide()\n this.submitAnnotation(pending, result.comment)\n },\n onCancel: () => {\n this.highlightLocked = false\n this.highlight?.hide()\n },\n })\n }\n\n private attachAnnotateListeners(): void {\n document.addEventListener('mousemove', this.boundMouseMove)\n document.addEventListener('mouseleave', this.boundMouseLeave)\n // Use window capture to fire before framework handlers on document\n window.addEventListener('click', this.boundClick, true)\n }\n\n private detachAnnotateListeners(): void {\n document.removeEventListener('mousemove', this.boundMouseMove)\n document.removeEventListener('mouseleave', this.boundMouseLeave)\n window.removeEventListener('click', this.boundClick, true)\n }\n\n private isInstruckt(el: EventTarget | null): boolean {\n if (!el || !(el instanceof Element)) return false\n return el.closest('[data-instruckt]') !== null\n }\n\n // ── Framework detection ───────────────────────────────────────\n\n private detectFramework(el: Element) {\n const adapters = this.config.adapters ?? []\n if (adapters.includes('livewire')) {\n const ctx = livewireAdapter.getContext(el)\n if (ctx) return ctx\n }\n if (adapters.includes('vue')) {\n const ctx = vueAdapter.getContext(el)\n if (ctx) return ctx\n }\n if (adapters.includes('svelte')) {\n const ctx = svelteAdapter.getContext(el)\n if (ctx) return ctx\n }\n if (adapters.includes('react')) {\n const ctx = reactAdapter.getContext(el)\n if (ctx) return ctx\n }\n return null\n }\n\n // ── Submit ────────────────────────────────────────────────────\n\n private async submitAnnotation(pending: PendingAnnotation, comment: string): Promise<void> {\n const payload: AnnotationPayload = {\n x: (pending.x / window.innerWidth) * 100,\n y: pending.y + window.scrollY,\n comment,\n element: pending.elementName,\n elementPath: pending.elementPath,\n cssClasses: pending.cssClasses,\n boundingBox: pending.boundingBox,\n selectedText: pending.selectedText,\n nearbyText: pending.nearbyText,\n intent: 'fix',\n severity: 'important',\n framework: pending.framework,\n url: window.location.href,\n }\n\n let annotation: Annotation\n try {\n annotation = await this.api.addAnnotation(payload)\n } catch {\n // No backend — create a local-only annotation\n annotation = {\n ...payload,\n id: crypto.randomUUID(),\n status: 'pending',\n thread: [],\n createdAt: new Date().toISOString(),\n }\n }\n this.annotations.push(annotation)\n this.saveToStorage()\n this.syncMarkers()\n this.config.onAnnotationAdd?.(annotation)\n this.copyAnnotations()\n }\n\n // ── Marker click — edit or delete ─────────────────────────────\n\n private onMarkerClick(annotation: Annotation): void {\n this.popup?.showEdit(annotation, {\n onSave: async (a, newComment) => {\n try {\n const updated = await this.api.updateAnnotation(a.id, { comment: newComment })\n this.onAnnotationUpdated(updated)\n } catch {\n // No backend — update locally\n this.onAnnotationUpdated({ ...a, comment: newComment, updatedAt: new Date().toISOString() })\n }\n },\n onDelete: async (a) => {\n try {\n await this.api.updateAnnotation(a.id, { status: 'dismissed' })\n } catch { /* no backend — just remove locally */ }\n this.removeAnnotation(a.id)\n },\n })\n }\n\n private onAnnotationUpdated(updated: Annotation): void {\n const idx = this.annotations.findIndex(a => a.id === updated.id)\n if (idx >= 0) {\n this.annotations[idx] = updated\n }\n this.saveToStorage()\n this.syncMarkers()\n }\n\n private removeAnnotation(id: string): void {\n this.annotations = this.annotations.filter(a => a.id !== id)\n this.saveToStorage()\n this.syncMarkers()\n }\n\n // ── Clear ───────────────────────────────────────────────────────\n\n private async clearPage(): Promise<void> {\n const page = this.pageAnnotations()\n for (const a of page) {\n try {\n await this.api.updateAnnotation(a.id, { status: 'dismissed' })\n } catch { /* best effort */ }\n }\n this.annotations = this.annotations.filter(a => !page.includes(a))\n this.saveToStorage()\n this.syncMarkers()\n }\n\n private async clearEverything(): Promise<void> {\n const active = this.annotations.filter(a => a.status !== 'resolved' && a.status !== 'dismissed')\n for (const a of active) {\n try {\n await this.api.updateAnnotation(a.id, { status: 'dismissed' })\n } catch { /* best effort */ }\n }\n this.annotations = []\n this.saveToStorage()\n this.syncMarkers()\n }\n\n // ── Keyboard ──────────────────────────────────────────────────\n\n private onKeydown(e: KeyboardEvent): void {\n if (this.toolbar?.isMinimized()) return\n const target = e.target as HTMLElement\n if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) return\n if (target.closest('[contenteditable=\"true\"]')) return\n // Shadow DOM retargets e.target to the host element — check if a popup is open\n if (this.isInstruckt(target)) return\n\n if (e.key === 'a' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n this.setAnnotating(!this.isAnnotating)\n }\n if (e.key === 'f' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n this.setFrozen(!this.isFrozen)\n }\n if (e.key === 'x' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n this.clearPage()\n }\n if (e.key === 'Escape') {\n if (this.isAnnotating) this.setAnnotating(false)\n if (this.isFrozen) this.setFrozen(false)\n }\n }\n\n // ── Copy / export ─────────────────────────────────────────────\n\n private copyAnnotations(): void {\n const md = this.exportMarkdown()\n navigator.clipboard.writeText(md).catch(() => {\n const el = document.createElement('textarea')\n el.value = md\n el.style.cssText = 'position:fixed;left:-9999px'\n document.body.appendChild(el)\n el.select()\n document.execCommand('copy')\n el.remove()\n })\n }\n\n exportMarkdown(): string {\n const pending = this.annotations.filter(a => a.status !== 'resolved' && a.status !== 'dismissed')\n if (pending.length === 0) {\n return `# UI Feedback\\n\\nNo open annotations.`\n }\n\n // Group by page\n const byPage = new Map<string, Annotation[]>()\n for (const a of pending) {\n const key = this.annotationPageKey(a)\n if (!byPage.has(key)) byPage.set(key, [])\n byPage.get(key)!.push(a)\n }\n\n const multiPage = byPage.size > 1\n const lines: string[] = []\n\n if (multiPage) {\n lines.push(`# UI Feedback`)\n lines.push('')\n }\n\n for (const [path, annotations] of byPage) {\n if (multiPage) {\n lines.push(`## ${path}`)\n } else {\n lines.push(`# UI Feedback: ${path}`)\n }\n lines.push('')\n\n const hPrefix = multiPage ? '###' : '##'\n\n annotations.forEach((a, i) => {\n // Feedback-first heading with element context\n const componentSuffix = a.framework?.component ? ` in \\`${a.framework.component}\\`` : ''\n lines.push(`${hPrefix} ${i + 1}. ${a.comment}`)\n lines.push(`- Element: \\`${a.element}\\`${componentSuffix}`)\n\n // File path if available (e.g. Svelte)\n if (a.framework?.data?.file) {\n lines.push(`- File: \\`${a.framework.data.file}\\``)\n }\n\n if (a.cssClasses) {\n lines.push(`- Classes: \\`${a.cssClasses}\\``)\n }\n if (a.selectedText) {\n lines.push(`- Text: \"${a.selectedText}\"`)\n } else if (a.nearbyText) {\n lines.push(`- Text: \"${a.nearbyText.slice(0, 100)}\"`)\n }\n lines.push('')\n })\n }\n\n return lines.join('\\n').trim()\n }\n\n // ── Public API ────────────────────────────────────────────────\n\n getAnnotations(): Annotation[] { return [...this.annotations] }\n\n destroy(): void {\n this.setAnnotating(false)\n this.setFrozen(false)\n document.removeEventListener('keydown', this.boundKeydown)\n window.removeEventListener('scroll', this.boundReposition)\n window.removeEventListener('resize', this.boundReposition)\n this.toolbar?.destroy()\n this.highlight?.destroy()\n this.popup?.destroy()\n this.markers?.destroy()\n if (this.rafId !== null) cancelAnimationFrame(this.rafId)\n }\n}\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoJ9B,IAAM;AAAA;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["_a","detect","getContext","detect","getContext","getContext","_a","e","getContext"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/api.ts","../src/ui/styles.ts","../src/ui/toolbar.ts","../src/ui/highlight.ts","../src/ui/popup.ts","../src/ui/markers.ts","../src/selector.ts","../src/adapters/livewire.ts","../src/adapters/vue.ts","../src/adapters/svelte.ts","../src/adapters/react.ts","../src/instruckt.ts"],"sourcesContent":["import { Instruckt } from './instruckt'\nimport type { InstrucktConfig, Annotation, AnnotationIntent, AnnotationSeverity, AnnotationStatus, FrameworkContext } from './types'\nimport type { AnnotationPayload } from './api'\n\nexport { Instruckt }\nexport type { InstrucktConfig, Annotation, AnnotationPayload, AnnotationIntent, AnnotationSeverity, AnnotationStatus, FrameworkContext }\n\n/**\n * Initialize instruckt.\n *\n * @example\n * instruckt.init({ endpoint: '/instruckt' })\n *\n * @example CDN\n * <script src=\"instruckt.iife.js\"></script>\n * <script>Instruckt.init({ endpoint: '/instruckt' })</script>\n */\nexport function init(config: InstrucktConfig): Instruckt {\n return new Instruckt(config)\n}\n","import type { Annotation } from './types'\n\n/** Read Laravel's XSRF-TOKEN cookie for CSRF protection */\nfunction getCsrfToken(): string {\n const match = document.cookie.match(/(?:^|;\\s*)XSRF-TOKEN=([^;]+)/)\n return match ? decodeURIComponent(match[1]) : ''\n}\n\nfunction headers(): Record<string, string> {\n const h: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n const csrf = getCsrfToken()\n if (csrf) h['X-XSRF-TOKEN'] = csrf\n return h\n}\n\n/** Convert snake_case API response to camelCase for JS types */\nexport function toCamelCase(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n const camel = k.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n out[camel] = Array.isArray(v)\n ? v.map(item => (item && typeof item === 'object' && !Array.isArray(item)) ? toCamelCase(item as Record<string, unknown>) : item)\n : (v && typeof v === 'object' && !Array.isArray(v)) ? toCamelCase(v as Record<string, unknown>) : v\n }\n return out\n}\n\n/** Convert camelCase JS payload to snake_case for Laravel API */\nfunction toSnake(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n const snake = k.replace(/[A-Z]/g, c => `_${c.toLowerCase()}`)\n out[snake] = (v && typeof v === 'object' && !Array.isArray(v)) ? toSnake(v as Record<string, unknown>) : v\n }\n return out\n}\n\nexport type AnnotationPayload = Omit<\n Annotation,\n 'id' | 'status' | 'thread' | 'createdAt'\n>\n\nexport class InstrucktApi {\n constructor(private readonly endpoint: string) {}\n\n async getAnnotations(): Promise<Annotation[]> {\n const res = await fetch(`${this.endpoint}/annotations`, {\n headers: headers(),\n })\n if (!res.ok) throw new Error(`instruckt: failed to load annotations (${res.status})`)\n const raw: Record<string, unknown>[] = await res.json()\n return raw.map(r => toCamelCase(r) as unknown as Annotation)\n }\n\n async addAnnotation(data: AnnotationPayload): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify(toSnake(data as unknown as Record<string, unknown>)),\n })\n if (!res.ok) throw new Error(`instruckt: failed to add annotation (${res.status})`)\n return toCamelCase(await res.json()) as unknown as Annotation\n }\n\n async updateAnnotation(\n annotationId: string,\n data: Partial<Pick<Annotation, 'status' | 'comment'>>,\n ): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations/${annotationId}`, {\n method: 'PATCH',\n headers: headers(),\n body: JSON.stringify(toSnake(data as unknown as Record<string, unknown>)),\n })\n if (!res.ok) throw new Error(`instruckt: failed to update annotation (${res.status})`)\n return toCamelCase(await res.json()) as unknown as Annotation\n }\n\n async addReply(annotationId: string, content: string, role: 'human' | 'agent' = 'human'): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations/${annotationId}/reply`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify({ role, content }),\n })\n if (!res.ok) throw new Error(`instruckt: failed to add reply (${res.status})`)\n return toCamelCase(await res.json()) as unknown as Annotation\n }\n}\n","/** Global styles injected into document.head — ONLY what must affect the host page */\nexport const GLOBAL_CSS = /* css */ `\nbody.ik-annotating,\nbody.ik-annotating * { cursor: crosshair !important; }\n`\n\n/** Toolbar shadow DOM styles — fully isolated */\nexport const TOOLBAR_CSS = /* css */ `\n:host {\n all: initial;\n display: block;\n position: fixed;\n z-index: 2147483646;\n}\n\n* { box-sizing: border-box; }\n\n:host-context([data-instruckt-theme=\"dark\"]),\n@media (prefers-color-scheme: dark) {\n :host {\n --ik-bg: #1c1c1e; --ik-bg2: #2c2c2e; --ik-border: #38383a;\n --ik-text: #f4f4f5; --ik-muted: #a1a1aa;\n --ik-shadow: 0 8px 32px rgba(0,0,0,.4), 0 0 0 1px rgba(255,255,255,.06);\n }\n}\n\n:host {\n --ik-accent: #6366f1;\n --ik-accent-h: #4f46e5;\n --ik-bg: #ffffff;\n --ik-bg2: #f4f4f5;\n --ik-border: #e4e4e7;\n --ik-text: #18181b;\n --ik-muted: #a1a1aa;\n --ik-shadow: 0 8px 32px rgba(0,0,0,.08), 0 0 0 1px rgba(0,0,0,.04);\n}\n\n.toolbar {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n background: var(--ik-bg);\n border-radius: 12px;\n padding: 6px;\n box-shadow: var(--ik-shadow);\n user-select: none;\n touch-action: none;\n cursor: grab;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n.toolbar:active { cursor: grabbing; }\n\n.btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 34px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--ik-muted);\n cursor: pointer;\n padding: 0;\n position: relative;\n transition: background .15s ease, color .15s ease;\n}\n.btn svg { display: block; }\n.btn:hover { background: var(--ik-bg2); color: var(--ik-text); }\n.btn.active { background: var(--ik-accent); color: #fff; }\n.btn.active:hover { background: var(--ik-accent-h); }\n\n.divider { width: 18px; height: 1px; background: var(--ik-border); margin: 3px 0; }\n\n.badge {\n position: absolute;\n top: -3px; right: -3px;\n min-width: 16px; height: 16px;\n background: #ef4444;\n color: #fff;\n border-radius: 8px;\n font-size: 10px; font-weight: 600;\n display: flex; align-items: center; justify-content: center;\n padding: 0 4px;\n line-height: 1;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n.minimize-btn { color: var(--ik-muted); opacity: .6; }\n.minimize-btn:hover { opacity: 1; }\n\n.danger-btn { color: var(--ik-muted); opacity: .6; }\n.danger-btn:hover { opacity: 1; color: #ef4444; }\n\n.clear-wrap {\n position: relative;\n display: flex;\n align-items: center;\n}\n.clear-all-btn {\n display: none;\n position: absolute;\n right: 100%;\n top: 0;\n background: var(--ik-bg);\n box-shadow: var(--ik-shadow);\n border-radius: 8px;\n}\n/* Invisible bridge so hover doesn't break crossing the gap */\n.clear-all-btn::after {\n content: '';\n position: absolute;\n top: 0;\n left: 100%;\n width: 6px;\n height: 100%;\n}\n.clear-wrap:hover .clear-all-btn { display: flex; align-items: center; justify-content: center; }\n\n.fab {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: none;\n background: var(--ik-bg);\n color: var(--ik-muted);\n box-shadow: var(--ik-shadow);\n cursor: pointer;\n padding: 0;\n transition: color .15s ease, transform .15s ease;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n.fab:hover { color: var(--ik-accent); transform: scale(1.1); }\n.fab { position: relative; }\n\n.fab-badge {\n position: absolute;\n top: -4px; right: -4px;\n min-width: 16px; height: 16px;\n background: #6366f1;\n color: #fff;\n border-radius: 8px;\n font-size: 9px; font-weight: 700;\n display: flex; align-items: center; justify-content: center;\n padding: 0 3px;\n line-height: 1;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n`\n\n/** Popup shadow DOM styles — fully isolated */\nexport const POPUP_CSS = /* css */ `\n:host {\n all: initial;\n display: block;\n position: fixed;\n z-index: 2147483647;\n}\n\n* { box-sizing: border-box; }\n\n:host {\n --ik-accent: #6366f1;\n --ik-accent-h: #4f46e5;\n --ik-bg: #ffffff;\n --ik-bg2: #f8f8f8;\n --ik-border: #e4e4e7;\n --ik-text: #18181b;\n --ik-muted: #71717a;\n --ik-shadow: 0 4px 24px rgba(0,0,0,.12);\n --ik-radius: 10px;\n --ik-hl: rgba(99,102,241,.15);\n}\n\n@media (prefers-color-scheme: dark) {\n :host {\n --ik-bg: #1c1c1e; --ik-bg2: #2c2c2e; --ik-border: #3a3a3c;\n --ik-text: #f4f4f5; --ik-muted: #a1a1aa;\n --ik-shadow: 0 4px 24px rgba(0,0,0,.5);\n --ik-hl: rgba(99,102,241,.2);\n }\n}\n\n.popup {\n width: 340px;\n background: var(--ik-bg);\n border: 1px solid var(--ik-border);\n border-radius: var(--ik-radius);\n box-shadow: var(--ik-shadow);\n padding: 14px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 13px;\n color: var(--ik-text);\n animation: pop-in .12s ease;\n}\n@keyframes pop-in {\n from { opacity:0; transform: scale(.95) translateY(4px); }\n to { opacity:1; transform: scale(1) translateY(0); }\n}\n\n.header { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }\n.element-tag {\n font-size:11px; font-family:ui-monospace,monospace; color:var(--ik-muted);\n background:var(--ik-bg2); border-radius:4px; padding:2px 6px;\n max-width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;\n}\n.close-btn {\n background:none; border:none; color:var(--ik-muted);\n cursor:pointer; font-size:18px; line-height:1; padding:0;\n}\n\n.fw-badge {\n display:inline-flex; align-items:center; gap:4px;\n font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;\n color:var(--ik-accent); background:var(--ik-hl); border-radius:4px;\n padding:2px 6px; margin-bottom:8px;\n}\n.selected-text {\n font-size:12px; color:var(--ik-muted); background:var(--ik-bg2);\n border-left:3px solid var(--ik-accent); padding:4px 8px;\n border-radius:0 4px 4px 0; margin-bottom:10px;\n overflow:hidden; text-overflow:ellipsis; white-space:nowrap;\n}\n\n.label {\n font-size:10px; font-weight:700; text-transform:uppercase;\n letter-spacing:.05em; color:var(--ik-muted); margin-bottom:4px;\n}\n.row { display:flex; gap:6px; margin-bottom:10px; }\n.chips { display:flex; gap:4px; flex-wrap:wrap; }\n\n.chip {\n font-size:11px; padding:3px 8px; border-radius:12px;\n border:1px solid var(--ik-border); background:transparent;\n color:var(--ik-muted); cursor:pointer; transition:all .1s;\n}\n.chip:hover { border-color:var(--ik-accent); color:var(--ik-accent); }\n.chip.sel { background:var(--ik-accent); border-color:var(--ik-accent); color:#fff; }\n.chip.blocking.sel { background:#ef4444; border-color:#ef4444; }\n.chip.important.sel { background:#f97316; border-color:#f97316; }\n.chip.suggestion.sel{ background:#22c55e; border-color:#22c55e; }\n\ntextarea {\n width:100%; min-height:80px; resize:vertical;\n border:1px solid var(--ik-border); border-radius:6px;\n background:var(--ik-bg2); color:var(--ik-text);\n font-family:inherit; font-size:13px; padding:8px 10px;\n outline:none; transition:border-color .15s; margin-bottom:10px;\n}\ntextarea:focus { border-color:var(--ik-accent); }\ntextarea::placeholder { color:var(--ik-muted); }\n\n.actions { display:flex; justify-content:flex-end; gap:6px; }\n\n.btn-secondary {\n padding:6px 14px; border-radius:6px; border:1px solid var(--ik-border);\n background:transparent; color:var(--ik-muted); font-size:12px; cursor:pointer; transition:all .1s;\n}\n.btn-secondary:hover { border-color:var(--ik-muted); color:var(--ik-text); }\n\n.btn-primary {\n padding:6px 14px; border-radius:6px; border:none;\n background:var(--ik-accent); color:#fff;\n font-size:12px; font-weight:700; cursor:pointer; transition:background .1s;\n}\n.btn-primary:hover { background:var(--ik-accent-h); }\n.btn-primary:disabled { opacity:.5; cursor:not-allowed; }\n\n.btn-danger {\n padding:6px 14px; border-radius:6px; border:1px solid #ef4444;\n background:transparent; color:#ef4444;\n font-size:12px; cursor:pointer; transition:all .1s;\n}\n.btn-danger:hover { background:#ef4444; color:#fff; }\n\n/* Thread view */\n.thread { margin-top:10px; border-top:1px solid var(--ik-border); padding-top:10px; }\n.msg { margin-bottom:8px; }\n.msg-role {\n font-size:10px; font-weight:700; text-transform:uppercase;\n letter-spacing:.05em; margin-bottom:2px;\n}\n.msg-role.human { color:var(--ik-accent); }\n.msg-role.agent { color:#22c55e; }\n.msg-content { font-size:12px; line-height:1.5; }\n\n.status-badge {\n display:inline-flex; align-items:center; gap:4px;\n font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;\n border-radius:4px; padding:2px 6px;\n}\n.status-badge.pending { background:rgba(99,102,241,.15); color:var(--ik-accent); }\n.status-badge.acknowledged { background:rgba(249,115,22,.15); color:#f97316; }\n.status-badge.resolved { background:rgba(34,197,94,.15); color:#22c55e; }\n.status-badge.dismissed { background:var(--ik-bg2); color:var(--ik-muted); }\n`\n\n/** Marker pin styles injected into document.head — pins overlay the page */\nexport const MARKER_CSS = /* css */ `\n.ik-marker {\n position: absolute;\n z-index: 2147483645;\n width: 24px; height: 24px;\n border-radius: 50%;\n background: #6366f1;\n color: #fff;\n font-size: 11px; font-weight: 700;\n display: flex; align-items: center; justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(99,102,241,.4);\n transition: transform .15s ease;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n pointer-events: all;\n user-select: none;\n}\n.ik-marker:hover { transform: scale(1.15); }\n.ik-marker.resolved { background: #22c55e; box-shadow: 0 2px 8px rgba(34,197,94,.4); }\n.ik-marker.dismissed { background: #71717a; box-shadow: 0 2px 8px rgba(0,0,0,.2); }\n.ik-marker.acknowledged { background: #f97316; box-shadow: 0 2px 8px rgba(249,115,22,.4); }\n`\n\n/** Inject styles into document.head (idempotent) */\nexport function injectGlobalStyles(): void {\n if (document.getElementById('instruckt-global')) return\n const style = document.createElement('style')\n style.id = 'instruckt-global'\n style.textContent = GLOBAL_CSS + MARKER_CSS\n document.head.appendChild(style)\n}\n","import { TOOLBAR_CSS } from './styles'\n\nexport type ToolbarMode = 'idle' | 'annotating' | 'frozen'\n\ninterface ToolbarCallbacks {\n onToggleAnnotate: (active: boolean) => void\n onFreezeAnimations: (frozen: boolean) => void\n onCopy: () => void\n onClearPage?: () => void\n onClearAll?: () => void\n onMinimize?: (minimized: boolean) => void\n}\n\n// ── Inline SVG icons (24x24, 2px stroke) ─────────────────────\n\nconst ICONS = {\n annotate: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z\"/></svg>`,\n freeze: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/></svg>`,\n copy: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"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 check: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`,\n clear: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"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 minimize: `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"7 13 12 18 17 13\"/><line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"18\"/></svg>`,\n logo: `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9\"/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z\"/></svg>`,\n} as const\n\nexport class Toolbar {\n private host!: HTMLElement\n private shadow!: ShadowRoot\n private toolbarEl!: HTMLDivElement\n private fab!: HTMLButtonElement\n private fabBadge: HTMLSpanElement | null = null\n private annotateBtn!: HTMLButtonElement\n private freezeBtn!: HTMLButtonElement\n private copyBtn!: HTMLButtonElement\n private annotateActive = false\n private freezeActive = false\n private minimized = false\n private totalCount = 0\n private dragging = false\n private dragOffset = { x: 0, y: 0 }\n\n constructor(\n private readonly position: string,\n private readonly callbacks: ToolbarCallbacks,\n ) {\n this.build()\n this.setupDrag()\n }\n\n private build(): void {\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'toolbar')\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = TOOLBAR_CSS\n this.shadow.appendChild(style)\n\n // Full toolbar\n this.toolbarEl = document.createElement('div')\n this.toolbarEl.className = 'toolbar'\n\n this.annotateBtn = this.makeBtn(ICONS.annotate, 'Annotate elements (A)', () => {\n const next = !this.annotateActive\n this.setAnnotateActive(next)\n this.callbacks.onToggleAnnotate(next)\n })\n\n this.freezeBtn = this.makeBtn(ICONS.freeze, 'Freeze page (F)', () => {\n const next = !this.freezeActive\n this.setFreezeActive(next)\n this.callbacks.onFreezeAnimations(next)\n })\n\n this.copyBtn = this.makeBtn(ICONS.copy, 'Copy annotations as markdown', () => {\n this.callbacks.onCopy()\n this.copyBtn.innerHTML = ICONS.check\n setTimeout(() => { this.copyBtn.innerHTML = ICONS.copy }, 1200)\n })\n\n const clearWrap = document.createElement('div')\n clearWrap.className = 'clear-wrap'\n\n const clearBtn = this.makeBtn(ICONS.clear, 'Clear this page (X)', () => {\n this.callbacks.onClearPage?.()\n })\n clearBtn.classList.add('danger-btn')\n\n const clearAllBtn = this.makeBtn(\n `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2\"/><line x1=\"4.93\" y1=\"4.93\" x2=\"19.07\" y2=\"19.07\"/></svg>`,\n 'Clear ALL annotations across every page',\n () => this.callbacks.onClearAll?.(),\n )\n clearAllBtn.classList.add('danger-btn', 'clear-all-btn')\n\n clearWrap.appendChild(clearBtn)\n clearWrap.appendChild(clearAllBtn)\n\n const minimizeBtn = this.makeBtn(ICONS.minimize, 'Minimize toolbar', () => {\n this.setMinimized(true)\n })\n minimizeBtn.classList.add('minimize-btn')\n\n const mkDiv = () => { const d = document.createElement('div'); d.className = 'divider'; return d }\n\n this.toolbarEl.append(\n this.annotateBtn, mkDiv(), this.freezeBtn, mkDiv(),\n this.copyBtn, clearWrap, mkDiv(), minimizeBtn,\n )\n this.shadow.appendChild(this.toolbarEl)\n\n // Floating action button (minimized state)\n this.fab = document.createElement('button')\n this.fab.className = 'fab'\n this.fab.title = 'Open instruckt toolbar'\n this.fab.setAttribute('aria-label', 'Open instruckt toolbar')\n this.fab.innerHTML = ICONS.logo\n this.fab.style.display = 'none'\n this.fab.addEventListener('click', (e) => {\n e.stopPropagation()\n this.setMinimized(false)\n })\n this.shadow.appendChild(this.fab)\n\n // Prevent toolbar clicks from reaching page handlers (e.g. Alpine @click.outside)\n // Shadow DOM stopPropagation only works within the shadow tree — clicks still\n // re-dispatch from the host element into the regular DOM.\n this.host.addEventListener('click', (e) => e.stopPropagation())\n this.host.addEventListener('mousedown', (e) => e.stopPropagation())\n this.host.addEventListener('pointerdown', (e) => e.stopPropagation())\n\n this.applyPosition()\n const root = document.getElementById('instruckt-root') ?? document.body\n root.appendChild(this.host)\n }\n\n private makeBtn(iconHtml: string, title: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.className = 'btn'\n btn.title = title\n btn.setAttribute('aria-label', title)\n btn.innerHTML = iconHtml\n btn.addEventListener('click', (e) => {\n e.stopPropagation()\n onClick()\n })\n return btn\n }\n\n private applyPosition(): void {\n const m = '16px'\n Object.assign(this.host.style, {\n position: 'fixed',\n zIndex: '2147483646',\n bottom: this.position.includes('bottom') ? m : 'auto',\n top: this.position.includes('top') ? m : 'auto',\n right: this.position.includes('right') ? m : 'auto',\n left: this.position.includes('left') ? m : 'auto',\n })\n }\n\n private setupDrag(): void {\n this.shadow.addEventListener('mousedown', (evt) => {\n const e = evt as MouseEvent\n if ((e.target as Element).closest('.btn') || (e.target as Element).closest('.fab')) return\n this.dragging = true\n const rect = this.host.getBoundingClientRect()\n this.dragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top }\n e.preventDefault()\n })\n\n document.addEventListener('mousemove', (e) => {\n if (!this.dragging) return\n Object.assign(this.host.style, {\n left: `${e.clientX - this.dragOffset.x}px`,\n top: `${e.clientY - this.dragOffset.y}px`,\n right: 'auto',\n bottom: 'auto',\n })\n })\n\n document.addEventListener('mouseup', () => { this.dragging = false })\n }\n\n private setMinimized(min: boolean): void {\n this.minimized = min\n this.toolbarEl.style.display = min ? 'none' : ''\n this.fab.style.display = min ? '' : 'none'\n this.updateFabBadge()\n this.callbacks.onMinimize?.(min)\n }\n\n private updateFabBadge(): void {\n if (this.totalCount > 0 && this.minimized) {\n if (!this.fabBadge) {\n this.fabBadge = document.createElement('span')\n this.fabBadge.className = 'fab-badge'\n this.fab.appendChild(this.fabBadge)\n }\n this.fabBadge.textContent = this.totalCount > 99 ? '99+' : String(this.totalCount)\n } else {\n this.fabBadge?.remove()\n this.fabBadge = null\n }\n }\n\n isMinimized(): boolean {\n return this.minimized\n }\n\n /** Programmatically minimize without firing callback */\n minimize(): void {\n this.minimized = true\n this.toolbarEl.style.display = 'none'\n this.fab.style.display = ''\n this.updateFabBadge()\n }\n\n setAnnotateActive(active: boolean): void {\n this.annotateActive = active\n this.annotateBtn.classList.toggle('active', active)\n document.body.classList.toggle('ik-annotating', active)\n }\n\n setFreezeActive(active: boolean): void {\n this.freezeActive = active\n this.freezeBtn.classList.toggle('active', active)\n }\n\n // Keep for compatibility — resolves visual mode from instruckt.ts\n setMode(mode: ToolbarMode): void {\n this.setAnnotateActive(mode === 'annotating')\n }\n\n setAnnotationCount(count: number): void {\n let badge = this.annotateBtn.querySelector('.badge')\n if (count > 0) {\n if (!badge) {\n badge = document.createElement('span')\n badge.className = 'badge'\n this.annotateBtn.appendChild(badge)\n }\n badge.textContent = count > 99 ? '99+' : String(count)\n } else {\n badge?.remove()\n }\n }\n\n setTotalCount(count: number): void {\n this.totalCount = count\n this.updateFabBadge()\n }\n\n destroy(): void {\n this.host.remove()\n document.body.classList.remove('ik-annotating')\n }\n}\n","/** Hover highlight overlay — uses all inline styles, no CSS class needed */\nexport class ElementHighlight {\n private el: HTMLElement\n\n constructor() {\n this.el = document.createElement('div')\n // All styling inline to avoid any host-page CSS interference\n Object.assign(this.el.style, {\n position: 'fixed',\n pointerEvents: 'none', // MUST be none — prevents swallowing clicks\n zIndex: '2147483644',\n border: '2px solid rgba(99,102,241,0.7)',\n background: 'rgba(99,102,241,0.1)',\n borderRadius: '3px',\n transition: 'all 0.06s ease',\n display: 'none',\n })\n this.el.setAttribute('data-instruckt', 'highlight')\n const root = document.getElementById('instruckt-root') ?? document.body\n root.appendChild(this.el)\n }\n\n show(el: Element): void {\n const rect = el.getBoundingClientRect()\n if (rect.width === 0 && rect.height === 0) {\n this.hide()\n return\n }\n Object.assign(this.el.style, {\n display: 'block',\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n })\n }\n\n hide(): void {\n this.el.style.display = 'none'\n }\n\n destroy(): void {\n this.el.remove()\n }\n}\n","import type { Annotation, PendingAnnotation } from '../types'\nimport { POPUP_CSS } from './styles'\n\ninterface PopupResult {\n comment: string\n}\n\ninterface PopupCallbacks {\n onSubmit: (result: PopupResult) => void\n onCancel: () => void\n}\n\ninterface EditCallbacks {\n onSave: (annotation: Annotation, newComment: string) => void\n onDelete: (annotation: Annotation) => void\n}\n\nfunction esc(s: string): string {\n return String(s ?? '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"')\n}\n\n/** Annotation popup — rendered in its own shadow DOM for CSS isolation */\nexport class AnnotationPopup {\n private host: HTMLElement | null = null\n private shadow: ShadowRoot | null = null\n\n // ── New annotation popup ──────────────────────────────────────\n\n showNew(pending: PendingAnnotation, callbacks: PopupCallbacks): void {\n this.destroy()\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'popup')\n this.stopHostPropagation(this.host)\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = POPUP_CSS\n this.shadow.appendChild(style)\n\n const popup = document.createElement('div')\n popup.className = 'popup'\n\n const fwBadge = pending.framework\n ? `<div class=\"fw-badge\">${esc(pending.framework.component)}</div>`\n : ''\n const selText = pending.selectedText\n ? `<div class=\"selected-text\">\"${esc(pending.selectedText.slice(0, 80))}\"</div>`\n : ''\n\n popup.innerHTML = `\n <div class=\"header\">\n <span class=\"element-tag\" title=\"${esc(pending.elementPath)}\">${esc(pending.elementLabel)}</span>\n <button class=\"close-btn\" title=\"Cancel (Esc)\">✕</button>\n </div>\n ${fwBadge}${selText}\n <textarea placeholder=\"What needs to change here?\" rows=\"3\"></textarea>\n <div class=\"actions\">\n <button class=\"btn-secondary\" data-action=\"cancel\">Cancel</button>\n <button class=\"btn-primary\" data-action=\"submit\" disabled>Add note</button>\n </div>\n `\n\n const textarea = popup.querySelector('textarea')!\n const submitBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"submit\"]')!\n\n textarea.addEventListener('input', () => {\n submitBtn.disabled = textarea.value.trim().length === 0\n })\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n if (!submitBtn.disabled) submitBtn.click()\n }\n if (e.key === 'Escape') { callbacks.onCancel(); this.destroy() }\n })\n\n popup.querySelector('[data-action=\"cancel\"]')!.addEventListener('click', () => {\n callbacks.onCancel(); this.destroy()\n })\n popup.querySelector('.close-btn')!.addEventListener('click', () => {\n callbacks.onCancel(); this.destroy()\n })\n submitBtn.addEventListener('click', () => {\n const comment = textarea.value.trim()\n if (!comment) return\n callbacks.onSubmit({ comment })\n this.destroy()\n })\n\n this.shadow.appendChild(popup)\n ;(document.getElementById('instruckt-root') ?? document.body).appendChild(this.host)\n\n this.positionHost(pending.x, pending.y)\n this.setupOutsideClick()\n textarea.focus()\n }\n\n // ── Edit existing annotation ──────────────────────────────────\n\n showEdit(annotation: Annotation, callbacks: EditCallbacks): void {\n this.destroy()\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'popup')\n this.stopHostPropagation(this.host)\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = POPUP_CSS\n this.shadow.appendChild(style)\n\n const popup = document.createElement('div')\n popup.className = 'popup'\n\n const fwBadge = annotation.framework\n ? `<div class=\"fw-badge\">${esc(annotation.framework.component)}</div>`\n : ''\n\n popup.innerHTML = `\n <div class=\"header\">\n <span class=\"element-tag\" title=\"${esc(annotation.elementPath)}\">${esc(annotation.element)}</span>\n <button class=\"close-btn\">✕</button>\n </div>\n ${fwBadge}\n <textarea rows=\"3\">${esc(annotation.comment)}</textarea>\n <div class=\"actions\">\n <button class=\"btn-danger\" data-action=\"delete\">Remove</button>\n <button class=\"btn-primary\" data-action=\"save\">Save</button>\n </div>\n `\n\n popup.querySelector('.close-btn')!.addEventListener('click', () => this.destroy())\n\n const textarea = popup.querySelector('textarea')!\n const saveBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"save\"]')!\n const deleteBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"delete\"]')!\n\n textarea.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n saveBtn.click()\n }\n if (e.key === 'Escape') this.destroy()\n })\n\n saveBtn.addEventListener('click', () => {\n const newComment = textarea.value.trim()\n if (!newComment) return\n callbacks.onSave(annotation, newComment)\n this.destroy()\n })\n\n deleteBtn.addEventListener('click', () => {\n callbacks.onDelete(annotation)\n this.destroy()\n })\n\n this.shadow.appendChild(popup)\n ;(document.getElementById('instruckt-root') ?? document.body).appendChild(this.host)\n\n // Position near the marker\n const markerX = (annotation.x / 100) * window.innerWidth\n const markerY = annotation.y - window.scrollY\n this.positionHost(markerX, markerY)\n this.setupOutsideClick()\n textarea.focus()\n textarea.setSelectionRange(textarea.value.length, textarea.value.length)\n }\n\n // ── Helpers ───────────────────────────────────────────────────\n\n /** Prevent popup interactions from reaching page handlers (e.g. @click.outside) */\n private stopHostPropagation(host: HTMLElement): void {\n for (const evt of ['click', 'mousedown', 'pointerdown'] as const) {\n host.addEventListener(evt, (e) => e.stopPropagation())\n }\n }\n\n private positionHost(x: number, y: number): void {\n if (!this.host) return\n // Use popover=\"manual\" to render in the top layer (above native popovers)\n this.host.setAttribute('popover', 'manual')\n try { this.host.showPopover() } catch { /* fallback to z-index */ }\n Object.assign(this.host.style, { position: 'fixed', zIndex: '2147483647', left: '-9999px', top: '0' })\n\n requestAnimationFrame(() => {\n if (!this.host) return\n const w = 340 + 20\n const h = this.host.querySelector('.popup')?.getBoundingClientRect().height ?? 300\n const vw = window.innerWidth\n const vh = window.innerHeight\n const left = Math.max(10, Math.min(x + 10, vw - w))\n const top = Math.max(10, Math.min(y + 10, vh - h - 10))\n Object.assign(this.host.style, { left: `${left}px`, top: `${top}px` })\n })\n }\n\n private boundOutside = (e: MouseEvent): void => {\n if (this.host && !this.host.contains(e.target as Node)) {\n this.destroy()\n }\n }\n\n private setupOutsideClick(): void {\n setTimeout(() => document.addEventListener('mousedown', this.boundOutside), 0)\n }\n\n destroy(): void {\n this.host?.remove()\n this.host = null\n this.shadow = null\n document.removeEventListener('mousedown', this.boundOutside)\n }\n}\n","import type { Annotation } from '../types'\n\ntype MarkerClickHandler = (annotation: Annotation) => void\n\ninterface MarkerEl {\n el: HTMLElement\n annotationId: string\n}\n\n/** Manages numbered annotation pins rendered directly on the page */\nexport class AnnotationMarkers {\n private container: HTMLElement\n private markers: Map<string, MarkerEl> = new Map()\n\n constructor(private readonly onClick: MarkerClickHandler) {\n // Fixed-position container over the page, pointer-events passthrough\n this.container = document.createElement('div')\n Object.assign(this.container.style, {\n position: 'fixed',\n inset: '0',\n pointerEvents: 'none',\n zIndex: '2147483645',\n })\n this.container.setAttribute('data-instruckt', 'markers')\n const root = document.getElementById('instruckt-root') ?? document.body\n root.appendChild(this.container)\n }\n\n /** Add or update a marker for an annotation */\n upsert(annotation: Annotation, index: number): void {\n const existing = this.markers.get(annotation.id)\n\n if (existing) {\n this.updateStyle(existing.el, annotation)\n return\n }\n\n const el = document.createElement('div')\n el.className = `ik-marker ${this.statusClass(annotation.status)}`\n el.textContent = String(index)\n el.title = annotation.comment.slice(0, 60)\n el.style.pointerEvents = 'all'\n\n // Position: annotation.x is % of viewport width, annotation.y is px from top (scroll-adjusted)\n // Convert back to viewport-relative for fixed positioning\n el.style.left = `${(annotation.x / 100) * window.innerWidth}px`\n el.style.top = `${annotation.y - window.scrollY}px`\n\n el.addEventListener('click', (e) => {\n e.stopPropagation()\n this.onClick(annotation)\n })\n\n this.container.appendChild(el)\n this.markers.set(annotation.id, { el, annotationId: annotation.id })\n }\n\n /** Update an existing marker after its annotation status changed */\n update(annotation: Annotation): void {\n const marker = this.markers.get(annotation.id)\n if (!marker) return\n this.updateStyle(marker.el, annotation)\n }\n\n private updateStyle(el: HTMLElement, annotation: Annotation): void {\n el.className = `ik-marker ${this.statusClass(annotation.status)}`\n el.title = annotation.comment.slice(0, 60)\n }\n\n private statusClass(status: string): string {\n if (status === 'resolved') return 'resolved'\n if (status === 'dismissed') return 'dismissed'\n if (status === 'acknowledged') return 'acknowledged'\n return ''\n }\n\n /** Reposition all markers (e.g. after scroll or resize) */\n reposition(annotations: Annotation[]): void {\n annotations.forEach(annotation => {\n const marker = this.markers.get(annotation.id)\n if (!marker) return\n marker.el.style.left = `${(annotation.x / 100) * window.innerWidth}px`\n marker.el.style.top = `${annotation.y - window.scrollY}px`\n })\n }\n\n remove(annotationId: string): void {\n const marker = this.markers.get(annotationId)\n if (!marker) return\n marker.el.remove()\n this.markers.delete(annotationId)\n }\n\n /** Show or hide all markers */\n setVisible(visible: boolean): void {\n this.container.style.display = visible ? '' : 'none'\n }\n\n /** Remove all markers without destroying the container */\n clear(): void {\n for (const { el } of this.markers.values()) {\n el.remove()\n }\n this.markers.clear()\n }\n\n destroy(): void {\n this.container.remove()\n this.markers.clear()\n }\n}\n","/**\n * CSS selector and element path generation.\n * Produces unique, grep-able selectors for any DOM element.\n */\n\n/** Build a unique CSS selector for an element */\nexport function getElementSelector(el: Element): string {\n if (el.id) {\n return `#${CSS.escape(el.id)}`\n }\n\n const path: 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 (!parent) {\n path.unshift(tag)\n break\n }\n\n // Try unique class combo\n const classes = Array.from(current.classList)\n .filter(c => !c.match(/^(hover|focus|active|visited|is-|has-)/)) // skip state classes\n .slice(0, 3)\n\n if (classes.length > 0) {\n const classSelector = `${tag}.${classes.map(CSS.escape).join('.')}`\n const matches = parent.querySelectorAll(classSelector)\n if (matches.length === 1) {\n path.unshift(classSelector)\n break\n }\n }\n\n // Fall back to nth-child\n const siblings = Array.from(parent.children).filter((c: Element) => c.tagName === current!.tagName)\n if (siblings.length === 1) {\n path.unshift(tag)\n } else {\n const index = siblings.indexOf(current) + 1\n path.unshift(`${tag}:nth-of-type(${index})`)\n }\n\n current = parent\n }\n\n return path.join(' > ')\n}\n\n/** Short element identifier for markdown output (grep-friendly) */\nexport function getElementName(el: Element): string {\n const tag = el.tagName.toLowerCase()\n\n const wireModel = el.getAttribute('wire:model') || el.getAttribute('wire:click')\n if (wireModel) return `${tag}[wire:${wireModel.split('.')[0]}]`\n\n if (el.id) return `${tag}#${el.id}`\n\n const firstClass = el.classList[0]\n if (firstClass) return `${tag}.${firstClass}`\n\n return tag\n}\n\n/** Human-readable HTML-like label for the popup UI */\nexport function getElementLabel(el: Element): string {\n const tag = el.tagName.toLowerCase()\n const text = (el.textContent || '').trim().replace(/\\s+/g, ' ').slice(0, 40)\n\n // Build a short opening tag with key attributes\n const attrs: string[] = []\n if (el.id) attrs.push(`id=\"${el.id}\"`)\n const role = el.getAttribute('role')\n if (role) attrs.push(`role=\"${role}\"`)\n const wireAttr = el.getAttribute('wire:model') || el.getAttribute('wire:click')\n if (wireAttr) attrs.push(`wire:${el.hasAttribute('wire:model') ? 'model' : 'click'}=\"${wireAttr}\"`)\n\n const attrStr = attrs.length ? ' ' + attrs.join(' ') : ''\n const openTag = `<${tag}${attrStr}>`\n\n if (text) return `${openTag} ${text}`\n return openTag\n}\n\n/** Get nearby readable text for context */\nexport function getNearbyText(el: Element): string {\n const text = (el.textContent || '').trim().replace(/\\s+/g, ' ')\n return text.slice(0, 120)\n}\n\n/** CSS classes as a space-separated string, filtering noise */\nexport function getCssClasses(el: Element): string {\n return Array.from(el.classList)\n .filter(c => !c.match(/^(instruckt-)/)) // exclude our own classes\n .join(' ')\n}\n\n/** Get bounding box relative to the page */\nexport function getPageBoundingBox(el: Element): { x: number; y: number; width: number; height: number } {\n const rect = el.getBoundingClientRect()\n return {\n x: rect.left + window.scrollX,\n y: rect.top + window.scrollY,\n width: rect.width,\n height: rect.height,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ndeclare global {\n interface Window {\n Livewire?: { find(id: string): unknown }\n }\n}\n\nexport function isAvailable(): boolean {\n return typeof window.Livewire !== 'undefined'\n}\n\n/** Walk up the DOM from el to find the nearest wire:id ancestor */\nexport function detect(el: Element): Element | null {\n let node: Element | null = el\n while (node && node !== document.documentElement) {\n if (node.getAttribute('wire:id')) return node\n node = node.parentElement\n }\n return null\n}\n\n/** Get Livewire component context for an element */\nexport function getContext(el: Element): FrameworkContext | null {\n if (!isAvailable()) return null\n\n const wireEl = detect(el)\n if (!wireEl) return null\n\n const wireId = wireEl.getAttribute('wire:id')!\n\n // In Livewire v3, the component name lives in the wire:snapshot attribute\n let componentName = 'Unknown'\n const snapshotAttr = wireEl.getAttribute('wire:snapshot')\n if (snapshotAttr) {\n try {\n const snapshot = JSON.parse(snapshotAttr)\n componentName = snapshot?.memo?.name ?? 'Unknown'\n } catch {\n // malformed snapshot\n }\n }\n\n return {\n framework: 'livewire',\n component: componentName,\n wire_id: wireId,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ninterface VueInstance {\n $options?: { name?: string; __name?: string }\n type?: { name?: string; __name?: string }\n uid?: number\n props?: Record<string, unknown>\n setupState?: Record<string, unknown>\n}\n\ninterface VueElement extends Element {\n __vue__?: VueInstance\n __vueParentComponent?: VueInstance\n _vei?: unknown\n}\n\nexport function isAvailable(): boolean {\n // Vue 3: mounts with data-v-app attribute; Vue 2: exposes global Vue constructor\n return !!(document.querySelector('[data-v-app]') || (window as unknown as Record<string, unknown>)['Vue'])\n}\n\n/** Walk up the DOM to find the nearest Vue component */\nexport function detect(el: Element): VueInstance | null {\n let node: VueElement | null = el as VueElement\n while (node && node !== document.documentElement) {\n const instance = node.__vueParentComponent ?? node.__vue__\n if (instance) return instance\n node = node.parentElement as VueElement | null\n }\n return null\n}\n\n/** Get Vue component context for an element */\nexport function getContext(el: Element): FrameworkContext | null {\n const instance = detect(el)\n if (!instance) return null\n\n // Support Vue 2 ($options.name) and Vue 3 (type.name or type.__name)\n const name =\n instance.$options?.name ??\n instance.$options?.__name ??\n instance.type?.name ??\n instance.type?.__name ??\n 'Anonymous'\n\n const data: Record<string, unknown> = {}\n\n // Vue 3 props\n if (instance.props) {\n Object.assign(data, instance.props)\n }\n\n // Vue 3 setup state (public reactive refs)\n if (instance.setupState) {\n for (const [key, value] of Object.entries(instance.setupState)) {\n if (!key.startsWith('_') && typeof value !== 'function') {\n try {\n data[key] = JSON.parse(JSON.stringify(value))\n } catch {\n data[key] = String(value)\n }\n }\n }\n }\n\n return {\n framework: 'vue',\n component: name,\n component_uid: instance.uid !== undefined ? String(instance.uid) : undefined,\n data,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ninterface SvelteMeta {\n loc?: { file?: string }\n ctx?: unknown[]\n}\n\ninterface SvelteElement extends Element {\n __svelte_meta?: SvelteMeta\n __svelte?: unknown\n}\n\n/** Walk up DOM to find nearest Svelte component element */\nexport function detect(el: Element): SvelteMeta | null {\n let node: SvelteElement | null = el as SvelteElement\n while (node && node !== document.documentElement) {\n if (node.__svelte_meta) return node.__svelte_meta\n node = node.parentElement as SvelteElement | null\n }\n return null\n}\n\n/** Get Svelte component context for an element */\nexport function getContext(el: Element): FrameworkContext | null {\n const meta = detect(el)\n if (!meta) return null\n\n // Extract component name from file path e.g. \"/src/components/Button.svelte\" → \"Button\"\n const filePath = meta.loc?.file ?? ''\n const component = filePath\n ? filePath.split('/').pop()?.replace(/\\.svelte$/, '') ?? 'Unknown'\n : 'Unknown'\n\n return {\n framework: 'svelte',\n component,\n data: filePath ? { file: filePath } : undefined,\n }\n}\n","import type { FrameworkContext } from '../types'\n\ninterface ReactFiber {\n type: unknown\n memoizedProps: Record<string, unknown> | null\n pendingProps: Record<string, unknown> | null\n return: ReactFiber | null\n key: string | null\n}\n\ninterface ReactElement extends Element {\n [key: string]: unknown\n}\n\nfunction getFiberKey(el: Element): string | null {\n for (const key of Object.keys(el)) {\n if (key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$')) {\n return key\n }\n }\n return null\n}\n\nfunction getComponentName(fiber: ReactFiber): string {\n let node: ReactFiber | null = fiber\n while (node) {\n const { type } = node\n if (typeof type === 'function' && (type as { name?: string }).name) {\n const name = (type as { name: string }).name\n // Skip React internals (start with lowercase = intrinsic HTML element function)\n if (name[0] === name[0].toUpperCase() && name.length > 1) return name\n }\n if (typeof type === 'object' && type !== null && (type as { displayName?: string }).displayName) {\n return (type as { displayName: string }).displayName\n }\n node = node.return\n }\n return 'Component'\n}\n\nfunction getProps(fiber: ReactFiber): Record<string, unknown> {\n const props = fiber.memoizedProps ?? fiber.pendingProps ?? {}\n const result: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(props)) {\n if (k === 'children' || typeof v === 'function') continue\n try {\n result[k] = JSON.parse(JSON.stringify(v))\n } catch {\n result[k] = String(v)\n }\n }\n return result\n}\n\nexport function isAvailable(): boolean {\n // React attaches fiber data to DOM nodes with __reactFiber$ prefix\n const root = document.getElementById('root') ?? document.getElementById('app') ?? document.body.firstElementChild\n if (!root) return false\n return getFiberKey(root) !== null\n}\n\nexport function getContext(el: Element): FrameworkContext | null {\n let node: Element | null = el\n while (node && node !== document.documentElement) {\n const key = getFiberKey(node)\n if (key) {\n const fiber = (node as ReactElement)[key] as ReactFiber\n if (fiber) {\n const component = getComponentName(fiber)\n const data = getProps(fiber)\n return { framework: 'react', component, data }\n }\n }\n node = node.parentElement\n }\n return null\n}\n","import type { Annotation, InstrucktConfig, PendingAnnotation } from './types'\nimport { InstrucktApi } from './api'\nimport type { AnnotationPayload } from './api'\nimport { Toolbar } from './ui/toolbar'\nimport { ElementHighlight } from './ui/highlight'\nimport { AnnotationPopup } from './ui/popup'\nimport { AnnotationMarkers } from './ui/markers'\nimport { injectGlobalStyles } from './ui/styles'\nimport { getElementSelector, getElementName, getElementLabel, getNearbyText, getCssClasses, getPageBoundingBox } from './selector'\nimport * as livewireAdapter from './adapters/livewire'\nimport * as vueAdapter from './adapters/vue'\nimport * as svelteAdapter from './adapters/svelte'\nimport * as reactAdapter from './adapters/react'\n\n// Re-export for api.ts consumers\nexport type { AnnotationPayload }\n\n/** Normalize URL to pathname for page-scoping (ignore query/hash) */\nfunction pageKey(): string {\n return window.location.pathname\n}\n\nexport class Instruckt {\n private config: Required<Pick<InstrucktConfig, 'endpoint' | 'theme' | 'position'>> & InstrucktConfig\n private api: InstrucktApi\n private toolbar: Toolbar | null = null\n private highlight: ElementHighlight | null = null\n private popup: AnnotationPopup | null = null\n private markers: AnnotationMarkers | null = null\n private annotations: Annotation[] = []\n private isAnnotating = false\n private isFrozen = false\n private frozenStyleEl: HTMLStyleElement | null = null\n private frozenPopovers: { el: HTMLElement; original: string }[] = []\n private rafId: number | null = null\n private pendingMouseTarget: Element | null = null\n private highlightLocked = false\n private pollTimer: ReturnType<typeof setInterval> | null = null\n private boundKeydown: (e: KeyboardEvent) => void\n private boundReposition = (): void => {\n this.markers?.reposition(this.annotations)\n }\n\n constructor(config: InstrucktConfig) {\n this.config = {\n adapters: ['livewire', 'vue', 'svelte', 'react'],\n theme: 'auto',\n position: 'bottom-right',\n ...config,\n }\n this.api = new InstrucktApi(config.endpoint)\n this.boundKeydown = this.onKeydown.bind(this)\n this.init()\n }\n\n private init(): void {\n injectGlobalStyles()\n\n if (this.config.theme !== 'auto') {\n document.documentElement.setAttribute('data-instruckt-theme', this.config.theme)\n }\n\n this.toolbar = new Toolbar(this.config.position, {\n onToggleAnnotate: (active) => {\n this.setAnnotating(active)\n },\n onFreezeAnimations: (frozen) => {\n this.setFrozen(frozen)\n },\n onCopy: () => this.copyAnnotations(),\n onClearPage: () => this.clearPage(),\n onClearAll: () => this.clearEverything(),\n onMinimize: (min) => this.onMinimize(min),\n })\n\n this.highlight = new ElementHighlight()\n this.popup = new AnnotationPopup()\n this.markers = new AnnotationMarkers((annotation) => this.onMarkerClick(annotation))\n\n document.addEventListener('keydown', this.boundKeydown)\n window.addEventListener('scroll', this.boundReposition, { passive: true })\n window.addEventListener('resize', this.boundReposition, { passive: true })\n\n // Survive Livewire wire:navigate (forward nav and back/forward button)\n document.addEventListener('livewire:navigated', () => this.reattach())\n // For non-Livewire SPAs (Vue Router, React Router, SvelteKit, etc.)\n // Use a microtask delay so the new DOM is in place before we reattach\n window.addEventListener('popstate', () => {\n setTimeout(() => this.reattach(), 0)\n })\n\n // Load persisted annotations from the backend\n this.loadAnnotations()\n // Poll for changes (e.g. agent resolved via MCP)\n this.pollTimer = setInterval(() => this.pollForChanges(), 3000)\n\n this.syncMarkers()\n }\n\n private makeToolbarCallbacks() {\n return {\n onToggleAnnotate: (active: boolean) => {\n this.setAnnotating(active)\n },\n onFreezeAnimations: (frozen: boolean) => {\n this.setFrozen(frozen)\n },\n onCopy: () => this.copyAnnotations(),\n onClearPage: () => this.clearPage(),\n onClearAll: () => this.clearEverything(),\n onMinimize: (min: boolean) => this.onMinimize(min),\n }\n }\n\n private reattach(): void {\n const wasAnnotating = this.isAnnotating\n const wasFrozen = this.isFrozen\n const wasMinimized = this.toolbar?.isMinimized() ?? false\n\n // Detach current listeners before rebuilding\n if (this.isAnnotating) this.detachAnnotateListeners()\n if (this.isFrozen) this.setFrozen(false)\n this.isAnnotating = false\n this.isFrozen = false\n\n // Remove any stale instruckt DOM (Livewire caches and restores old HTML on back nav)\n document.querySelectorAll('[data-instruckt]').forEach(el => el.remove())\n\n // Rebuild everything fresh\n this.toolbar = new Toolbar(this.config.position, this.makeToolbarCallbacks())\n if (wasMinimized) this.toolbar.minimize()\n\n this.markers = new AnnotationMarkers((annotation) => this.onMarkerClick(annotation))\n this.highlight = new ElementHighlight()\n\n if (wasMinimized) this.markers.setVisible(false)\n\n // Re-inject global styles (Livewire may have swapped <head> content)\n const existing = document.getElementById('instruckt-global')\n if (existing) existing.remove()\n injectGlobalStyles()\n\n this.syncMarkers()\n\n // Restore active modes\n if (wasAnnotating && !wasMinimized) this.setAnnotating(true)\n }\n\n // ── Minimize ────────────────────────────────────────────────────\n\n private onMinimize(minimized: boolean): void {\n if (minimized) {\n // Deactivate everything when minimized\n if (this.isAnnotating) this.setAnnotating(false)\n if (this.isFrozen) this.setFrozen(false)\n this.toolbar?.setAnnotateActive(false)\n this.toolbar?.setFreezeActive(false)\n this.markers?.setVisible(false)\n this.popup?.destroy()\n } else {\n // Show markers again when restored\n this.markers?.setVisible(true)\n }\n }\n\n // ── Persistence ─────────────────────────────────────────────────\n\n private static STORAGE_KEY = 'instruckt:annotations'\n\n private async loadAnnotations(): Promise<void> {\n // Always load localStorage first as baseline\n this.loadFromStorage()\n\n try {\n const remote = await this.api.getAnnotations()\n if (remote.length > 0) {\n // Merge: remote is source of truth, but keep any local-only annotations\n const remoteIds = new Set(remote.map(a => a.id))\n const localOnly = this.annotations.filter(a => !remoteIds.has(a.id))\n this.annotations = [...remote, ...localOnly]\n this.saveToStorage()\n }\n } catch {\n // No backend — localStorage already loaded above\n }\n this.syncMarkers()\n }\n\n private saveToStorage(): void {\n try {\n localStorage.setItem(Instruckt.STORAGE_KEY, JSON.stringify(this.annotations))\n } catch { /* storage full or unavailable */ }\n }\n\n private loadFromStorage(): void {\n try {\n const raw = localStorage.getItem(Instruckt.STORAGE_KEY)\n if (raw) this.annotations = JSON.parse(raw)\n } catch { /* corrupt or unavailable */ }\n }\n\n /** Poll API for status changes (e.g. agent resolved via MCP) */\n private async pollForChanges(): Promise<void> {\n try {\n const remote = await this.api.getAnnotations()\n let changed = false\n for (const r of remote) {\n const local = this.annotations.find(a => a.id === r.id)\n if (local && local.status !== r.status) {\n local.status = r.status\n local.resolvedAt = r.resolvedAt\n local.resolvedBy = r.resolvedBy\n changed = true\n }\n }\n if (changed) {\n this.saveToStorage()\n this.syncMarkers()\n }\n } catch { /* no backend or network error — skip */ }\n }\n\n // ── Page-scoped markers ─────────────────────────────────────────\n\n private syncMarkers(): void {\n this.markers?.clear()\n const current = pageKey()\n let idx = 0\n for (const a of this.annotations) {\n if (a.status === 'resolved' || a.status === 'dismissed') continue\n if (this.annotationPageKey(a) === current) {\n idx++\n this.markers?.upsert(a, idx)\n }\n }\n this.toolbar?.setAnnotationCount(this.pageAnnotations().length)\n this.toolbar?.setTotalCount(this.totalActiveCount())\n }\n\n private annotationPageKey(a: Annotation): string {\n try {\n return new URL(a.url).pathname\n } catch {\n return a.url\n }\n }\n\n private pageAnnotations(): Annotation[] {\n const current = pageKey()\n return this.annotations.filter(a =>\n this.annotationPageKey(a) === current &&\n a.status !== 'resolved' && a.status !== 'dismissed'\n )\n }\n\n private totalActiveCount(): number {\n return this.annotations.filter(a => a.status !== 'resolved' && a.status !== 'dismissed').length\n }\n\n // ── Annotate mode ─────────────────────────────────────────────\n\n private setAnnotating(active: boolean): void {\n this.isAnnotating = active\n this.toolbar?.setAnnotateActive(active)\n if (active) {\n this.attachAnnotateListeners()\n } else {\n this.detachAnnotateListeners()\n this.highlight?.hide()\n if (this.rafId !== null) { cancelAnimationFrame(this.rafId); this.rafId = null }\n }\n // When frozen, toggle pointer-events based on annotate state\n this.updateFreezeStyles()\n }\n\n // ── Freeze mode ──────────────────────────────────────────────\n\n private setFrozen(frozen: boolean): void {\n this.isFrozen = frozen\n this.toolbar?.setFreezeActive(frozen)\n if (frozen) {\n this.updateFreezeStyles()\n this.freezePopovers()\n // Use window (not document) so we intercept before Livewire/Alpine handlers\n // on document. Capture on window fires before capture on document.\n for (const evt of this.freezeBlockEvents) {\n window.addEventListener(evt, this.boundFreezeClick, true)\n }\n window.addEventListener('submit', this.boundFreezeSubmit, true)\n // Block events that close dropdowns/popovers (window capture to beat frameworks)\n for (const evt of this.freezePassiveEvents) {\n window.addEventListener(evt, this.boundFreezePassive, true)\n }\n } else {\n this.frozenStyleEl?.remove()\n this.frozenStyleEl = null\n this.unfreezePopovers()\n for (const evt of this.freezeBlockEvents) {\n window.removeEventListener(evt, this.boundFreezeClick, true)\n }\n window.removeEventListener('submit', this.boundFreezeSubmit, true)\n for (const evt of this.freezePassiveEvents) {\n window.removeEventListener(evt, this.boundFreezePassive, true)\n }\n }\n }\n\n /** Pull open popovers out of the top layer so the rest of the page is clickable */\n private freezePopovers(): void {\n this.frozenPopovers = []\n const openSelector = ':popover-open, .\\\\:popover-open'\n document.querySelectorAll('[popover]').forEach((el) => {\n const htmlEl = el as HTMLElement\n const val = htmlEl.getAttribute('popover') ?? ''\n let isOpen = false\n try { isOpen = htmlEl.matches(openSelector) } catch {\n try { isOpen = htmlEl.matches('.\\\\:popover-open') } catch { /* ignore */ }\n }\n if (!isOpen) return\n // Save position before removing popover attribute\n const rect = htmlEl.getBoundingClientRect()\n this.frozenPopovers.push({ el: htmlEl, original: val })\n // Remove popover attribute — pulls element out of top layer\n htmlEl.removeAttribute('popover')\n // Keep it visible with inline styles\n htmlEl.style.setProperty('display', 'block', 'important')\n htmlEl.style.setProperty('position', 'fixed', 'important')\n htmlEl.style.setProperty('z-index', '2147483644', 'important')\n htmlEl.style.setProperty('top', `${rect.top}px`, 'important')\n htmlEl.style.setProperty('left', `${rect.left}px`, 'important')\n htmlEl.style.setProperty('width', `${rect.width}px`, 'important')\n // Add the polyfill class so Flux thinks it's still open\n htmlEl.classList.add(':popover-open')\n })\n }\n\n /** Restore popover attributes */\n private unfreezePopovers(): void {\n for (const { el, original } of this.frozenPopovers) {\n // Remove inline overrides\n for (const prop of ['display', 'position', 'z-index', 'top', 'left', 'width']) {\n el.style.removeProperty(prop)\n }\n el.classList.remove(':popover-open')\n el.setAttribute('popover', original || 'auto')\n }\n this.frozenPopovers = []\n }\n\n private freezeBlockEvents = ['click', 'mousedown', 'pointerdown', 'pointerup', 'mouseup', 'touchstart', 'touchend', 'auxclick'] as const\n private freezePassiveEvents = ['focusin', 'focusout', 'blur', 'pointerleave', 'mouseleave', 'mouseout'] as const\n\n /** Update freeze CSS — pointer-events only blocked when NOT annotating */\n private updateFreezeStyles(): void {\n if (!this.isFrozen) return\n this.frozenStyleEl?.remove()\n this.frozenStyleEl = document.createElement('style')\n this.frozenStyleEl.id = 'instruckt-freeze'\n const pointerBlock = this.isAnnotating ? '' : `\n a[href], a[wire\\\\:navigate], [wire\\\\:click], [wire\\\\:navigate],\n [x-on\\\\:click], [@click], [v-on\\\\:click], [onclick],\n button, input[type=\"submit\"], select, [role=\"button\"], [role=\"link\"],\n [tabindex] {\n pointer-events: none !important;\n cursor: not-allowed !important;\n }\n `\n this.frozenStyleEl.textContent = `\n *, *::before, *::after {\n animation-play-state: paused !important;\n transition: none !important;\n }\n video { filter: none !important; }\n ${pointerBlock}\n `\n document.head.appendChild(this.frozenStyleEl)\n }\n\n /** Block interactions on the page when frozen (except instruckt UI) */\n private boundFreezeClick = (e: Event): void => {\n if (this.isInstruckt(e.target)) return\n // When annotating, only let 'click' through (annotate handler needs it).\n // Always block mousedown/pointerdown/touchstart to prevent framework\n // handlers (Alpine @click.outside, Livewire wire:navigate) from firing.\n if (this.isAnnotating && e.type === 'click') return\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n private boundFreezeSubmit = (e: Event): void => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n /** Block focus/hover events that JS dropdowns use to auto-close.\n * Block ALL of these — even on instruckt elements — because frameworks\n * like Flux check if focusin target is contained in the popover and\n * close it if it's not (e.g. focus moved to our popup textarea). */\n private boundFreezePassive = (e: Event): void => {\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n // ── Event listeners ───────────────────────────────────────────\n\n private boundMouseMove = (e: MouseEvent): void => {\n if (this.highlightLocked) return\n this.pendingMouseTarget = e.target as Element\n if (this.rafId === null) {\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n if (this.highlightLocked) return\n if (this.pendingMouseTarget && !this.isInstruckt(this.pendingMouseTarget)) {\n this.highlight?.show(this.pendingMouseTarget)\n } else {\n this.highlight?.hide()\n }\n })\n }\n }\n\n private boundMouseLeave = (): void => {\n if (this.highlightLocked) return\n this.highlight?.hide()\n }\n\n private boundClick = (e: MouseEvent): void => {\n const target = e.target as Element\n if (this.isInstruckt(target)) return\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n\n const selectedText = window.getSelection()?.toString().trim() || undefined\n const elementPath = getElementSelector(target)\n const elementName = getElementName(target)\n const elementLabel = getElementLabel(target)\n const cssClasses = getCssClasses(target)\n const nearbyText = getNearbyText(target) || undefined\n const boundingBox = getPageBoundingBox(target)\n const framework = this.detectFramework(target) ?? undefined\n\n const pending: PendingAnnotation = {\n element: target,\n elementPath,\n elementName,\n elementLabel,\n cssClasses,\n boundingBox,\n x: e.clientX,\n y: e.clientY,\n selectedText,\n nearbyText,\n framework,\n }\n\n this.highlight?.show(target)\n this.highlightLocked = true\n\n this.popup?.showNew(pending, {\n onSubmit: (result) => {\n this.highlightLocked = false\n this.highlight?.hide()\n this.submitAnnotation(pending, result.comment)\n },\n onCancel: () => {\n this.highlightLocked = false\n this.highlight?.hide()\n },\n })\n }\n\n private attachAnnotateListeners(): void {\n document.addEventListener('mousemove', this.boundMouseMove)\n document.addEventListener('mouseleave', this.boundMouseLeave)\n // Use window capture to fire before framework handlers on document\n window.addEventListener('click', this.boundClick, true)\n }\n\n private detachAnnotateListeners(): void {\n document.removeEventListener('mousemove', this.boundMouseMove)\n document.removeEventListener('mouseleave', this.boundMouseLeave)\n window.removeEventListener('click', this.boundClick, true)\n }\n\n private isInstruckt(el: EventTarget | null): boolean {\n if (!el || !(el instanceof Element)) return false\n return el.closest('[data-instruckt]') !== null\n }\n\n // ── Framework detection ───────────────────────────────────────\n\n private detectFramework(el: Element) {\n const adapters = this.config.adapters ?? []\n if (adapters.includes('livewire')) {\n const ctx = livewireAdapter.getContext(el)\n if (ctx) return ctx\n }\n if (adapters.includes('vue')) {\n const ctx = vueAdapter.getContext(el)\n if (ctx) return ctx\n }\n if (adapters.includes('svelte')) {\n const ctx = svelteAdapter.getContext(el)\n if (ctx) return ctx\n }\n if (adapters.includes('react')) {\n const ctx = reactAdapter.getContext(el)\n if (ctx) return ctx\n }\n return null\n }\n\n // ── Submit ────────────────────────────────────────────────────\n\n private async submitAnnotation(pending: PendingAnnotation, comment: string): Promise<void> {\n const payload: AnnotationPayload = {\n x: (pending.x / window.innerWidth) * 100,\n y: pending.y + window.scrollY,\n comment,\n element: pending.elementName,\n elementPath: pending.elementPath,\n cssClasses: pending.cssClasses,\n boundingBox: pending.boundingBox,\n selectedText: pending.selectedText,\n nearbyText: pending.nearbyText,\n intent: 'fix',\n severity: 'important',\n framework: pending.framework,\n url: window.location.href,\n }\n\n let annotation: Annotation\n try {\n annotation = await this.api.addAnnotation(payload)\n } catch {\n // No backend — create a local-only annotation\n annotation = {\n ...payload,\n id: crypto.randomUUID(),\n status: 'pending',\n thread: [],\n createdAt: new Date().toISOString(),\n }\n }\n this.annotations.push(annotation)\n this.saveToStorage()\n this.syncMarkers()\n this.config.onAnnotationAdd?.(annotation)\n this.copyAnnotations()\n }\n\n // ── Marker click — edit or delete ─────────────────────────────\n\n private onMarkerClick(annotation: Annotation): void {\n this.popup?.showEdit(annotation, {\n onSave: async (a, newComment) => {\n try {\n const updated = await this.api.updateAnnotation(a.id, { comment: newComment })\n this.onAnnotationUpdated(updated)\n } catch {\n // No backend — update locally\n this.onAnnotationUpdated({ ...a, comment: newComment, updatedAt: new Date().toISOString() })\n }\n },\n onDelete: async (a) => {\n try {\n await this.api.updateAnnotation(a.id, { status: 'dismissed' })\n } catch { /* no backend — just remove locally */ }\n this.removeAnnotation(a.id)\n },\n })\n }\n\n private onAnnotationUpdated(updated: Annotation): void {\n const idx = this.annotations.findIndex(a => a.id === updated.id)\n if (idx >= 0) {\n this.annotations[idx] = updated\n }\n this.saveToStorage()\n this.syncMarkers()\n }\n\n private removeAnnotation(id: string): void {\n this.annotations = this.annotations.filter(a => a.id !== id)\n this.saveToStorage()\n this.syncMarkers()\n }\n\n // ── Clear ───────────────────────────────────────────────────────\n\n private async clearPage(): Promise<void> {\n const page = this.pageAnnotations()\n for (const a of page) {\n try {\n await this.api.updateAnnotation(a.id, { status: 'dismissed' })\n } catch { /* best effort */ }\n }\n this.annotations = this.annotations.filter(a => !page.includes(a))\n this.saveToStorage()\n this.syncMarkers()\n }\n\n private async clearEverything(): Promise<void> {\n const active = this.annotations.filter(a => a.status !== 'resolved' && a.status !== 'dismissed')\n for (const a of active) {\n try {\n await this.api.updateAnnotation(a.id, { status: 'dismissed' })\n } catch { /* best effort */ }\n }\n this.annotations = []\n this.saveToStorage()\n this.syncMarkers()\n }\n\n // ── Keyboard ──────────────────────────────────────────────────\n\n private onKeydown(e: KeyboardEvent): void {\n if (this.toolbar?.isMinimized()) return\n const target = e.target as HTMLElement\n if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) return\n if (target.closest('[contenteditable=\"true\"]')) return\n // Shadow DOM retargets e.target to the host element — check if a popup is open\n if (this.isInstruckt(target)) return\n\n if (e.key === 'a' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n this.setAnnotating(!this.isAnnotating)\n }\n if (e.key === 'f' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n this.setFrozen(!this.isFrozen)\n }\n if (e.key === 'x' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n this.clearPage()\n }\n if (e.key === 'Escape') {\n if (this.isAnnotating) this.setAnnotating(false)\n if (this.isFrozen) this.setFrozen(false)\n }\n }\n\n // ── Copy / export ─────────────────────────────────────────────\n\n private copyAnnotations(): void {\n const md = this.exportMarkdown()\n navigator.clipboard.writeText(md).catch(() => {\n const el = document.createElement('textarea')\n el.value = md\n el.style.cssText = 'position:fixed;left:-9999px'\n document.body.appendChild(el)\n el.select()\n document.execCommand('copy')\n el.remove()\n })\n }\n\n exportMarkdown(): string {\n const pending = this.annotations.filter(a => a.status !== 'resolved' && a.status !== 'dismissed')\n if (pending.length === 0) {\n return `# UI Feedback\\n\\nNo open annotations.`\n }\n\n // Group by page\n const byPage = new Map<string, Annotation[]>()\n for (const a of pending) {\n const key = this.annotationPageKey(a)\n if (!byPage.has(key)) byPage.set(key, [])\n byPage.get(key)!.push(a)\n }\n\n const multiPage = byPage.size > 1\n const lines: string[] = []\n\n if (multiPage) {\n lines.push(`# UI Feedback`)\n lines.push('')\n }\n\n for (const [path, annotations] of byPage) {\n if (multiPage) {\n lines.push(`## ${path}`)\n } else {\n lines.push(`# UI Feedback: ${path}`)\n }\n lines.push('')\n\n const hPrefix = multiPage ? '###' : '##'\n\n annotations.forEach((a, i) => {\n // Feedback-first heading with element context\n const componentSuffix = a.framework?.component ? ` in \\`${a.framework.component}\\`` : ''\n lines.push(`${hPrefix} ${i + 1}. ${a.comment}`)\n lines.push(`- Element: \\`${a.element}\\`${componentSuffix}`)\n\n // File path if available (e.g. Svelte)\n if (a.framework?.data?.file) {\n lines.push(`- File: \\`${a.framework.data.file}\\``)\n }\n\n if (a.cssClasses) {\n lines.push(`- Classes: \\`${a.cssClasses}\\``)\n }\n if (a.selectedText) {\n lines.push(`- Text: \"${a.selectedText}\"`)\n } else if (a.nearbyText) {\n lines.push(`- Text: \"${a.nearbyText.slice(0, 100)}\"`)\n }\n lines.push('')\n })\n }\n\n return lines.join('\\n').trim()\n }\n\n // ── Public API ────────────────────────────────────────────────\n\n getAnnotations(): Annotation[] { return [...this.annotations] }\n\n destroy(): void {\n this.setAnnotating(false)\n this.setFrozen(false)\n document.removeEventListener('keydown', this.boundKeydown)\n window.removeEventListener('scroll', this.boundReposition)\n window.removeEventListener('resize', this.boundReposition)\n this.toolbar?.destroy()\n this.highlight?.destroy()\n this.popup?.destroy()\n this.markers?.destroy()\n if (this.rafId !== null) cancelAnimationFrame(this.rafId)\n if (this.pollTimer !== null) clearInterval(this.pollTimer)\n }\n}\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoJ9B,IAAM;AAAA;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["_a","detect","getContext","detect","getContext","getContext","_a","e","getContext"]}
|