instruckt 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/instruckt.cjs.js +1450 -0
- package/dist/instruckt.cjs.js.map +1 -0
- package/dist/instruckt.d.mts +133 -0
- package/dist/instruckt.d.ts +133 -0
- package/dist/instruckt.esm.js +1430 -0
- package/dist/instruckt.esm.js.map +1 -0
- package/dist/instruckt.iife.js +301 -0
- package/dist/instruckt.iife.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/api.ts","../src/sse.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, Session, AnnotationIntent, AnnotationSeverity, AnnotationStatus, FrameworkContext } from './types'\nimport type { AnnotationPayload } from './api'\n\nexport { Instruckt }\nexport type { InstrucktConfig, Annotation, AnnotationPayload, Session, 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, Session } 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\nexport type AnnotationPayload = Omit<\n Annotation,\n 'id' | 'sessionId' | 'status' | 'thread' | 'createdAt' | '_syncedTo'\n>\n\nexport class InstrucktApi {\n constructor(private readonly endpoint: string) {}\n\n async createSession(url: string): Promise<Session> {\n const res = await fetch(`${this.endpoint}/sessions`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify({ url }),\n })\n if (!res.ok) throw new Error(`instruckt: failed to create session (${res.status})`)\n return res.json()\n }\n\n async getSession(sessionId: string): Promise<Session & { annotations: Annotation[] }> {\n const res = await fetch(`${this.endpoint}/sessions/${sessionId}`, {\n headers: { Accept: 'application/json' },\n })\n if (!res.ok) throw new Error(`instruckt: failed to get session (${res.status})`)\n return res.json()\n }\n\n async addAnnotation(sessionId: string, data: AnnotationPayload): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/sessions/${sessionId}/annotations`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify(data),\n })\n if (!res.ok) throw new Error(`instruckt: failed to add annotation (${res.status})`)\n return res.json()\n }\n\n async updateAnnotation(\n annotationId: string,\n data: Partial<Pick<Annotation, 'status' | 'comment' | 'intent' | 'severity'>>,\n ): Promise<Annotation> {\n const res = await fetch(`${this.endpoint}/annotations/${annotationId}`, {\n method: 'PATCH',\n headers: headers(),\n body: JSON.stringify(data),\n })\n if (!res.ok) throw new Error(`instruckt: failed to update annotation (${res.status})`)\n return res.json()\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 res.json()\n }\n}\n","import type { Annotation } from './types'\n\ntype AnnotationEventHandler = (annotation: Annotation) => void\n\nexport class InstrucktSSE {\n private source: EventSource | null = null\n\n constructor(\n private readonly endpoint: string,\n private readonly sessionId: string,\n private readonly onUpdate: AnnotationEventHandler,\n ) {}\n\n connect(): void {\n if (this.source) return\n\n this.source = new EventSource(`${this.endpoint}/sessions/${this.sessionId}/events`)\n\n this.source.addEventListener('annotation.updated', (e: MessageEvent) => {\n try {\n const annotation: Annotation = JSON.parse(e.data)\n this.onUpdate(annotation)\n } catch {\n // ignore malformed events\n }\n })\n\n this.source.onerror = () => {\n // SSE will auto-reconnect; nothing to do\n }\n }\n\n disconnect(): void {\n this.source?.close()\n this.source = null\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: #3a3a3c;\n --ik-text: #f4f4f5; --ik-muted: #a1a1aa;\n --ik-shadow: 0 4px 24px rgba(0,0,0,.5);\n }\n}\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}\n\n.toolbar {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n background: var(--ik-bg);\n border: 1px solid var(--ik-border);\n border-radius: 14px;\n padding: 8px 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: 36px;\n height: 36px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--ik-muted);\n cursor: pointer;\n padding: 0;\n font-size: 17px;\n line-height: 1;\n position: relative;\n transition: background .1s, color .1s;\n}\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: 20px; height: 1px; background: var(--ik-border); margin: 2px 0; }\n\n.badge {\n position: absolute;\n top: -4px; right: -4px;\n min-width: 16px; height: 16px;\n background: var(--ik-accent);\n color: #fff;\n border-radius: 8px;\n font-size: 10px; font-weight: 700;\n display: flex; align-items: center; justify-content: center;\n padding: 0 3px;\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/* 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}\n\nexport class Toolbar {\n private host!: HTMLElement\n private shadow!: ShadowRoot\n private annotateBtn!: HTMLButtonElement\n private freezeBtn!: HTMLButtonElement\n private copyBtn!: HTMLButtonElement\n private mode: ToolbarMode = 'idle'\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 // Inject styles inside shadow root — fully isolated from host page CSS\n const style = document.createElement('style')\n style.textContent = TOOLBAR_CSS\n this.shadow.appendChild(style)\n\n const toolbar = document.createElement('div')\n toolbar.className = 'toolbar'\n\n this.annotateBtn = this.makeBtn('✏️', 'Annotate elements (A)', () => {\n const next = this.mode !== 'annotating'\n this.setMode(next ? 'annotating' : 'idle')\n this.callbacks.onToggleAnnotate(next)\n })\n\n this.freezeBtn = this.makeBtn('⏸', 'Freeze animations (F)', () => {\n const next = this.mode !== 'frozen'\n this.setMode(next ? 'frozen' : 'idle')\n this.callbacks.onFreezeAnimations(next)\n })\n\n this.copyBtn = this.makeBtn('📋', 'Copy annotations as markdown', () => {\n this.callbacks.onCopy()\n // Flash the button to confirm copy\n this.copyBtn.textContent = '✓'\n setTimeout(() => { this.copyBtn.textContent = '📋' }, 1200)\n })\n\n const divider = document.createElement('div')\n divider.className = 'divider'\n const divider2 = document.createElement('div')\n divider2.className = 'divider'\n\n toolbar.append(this.annotateBtn, divider, this.freezeBtn, divider2, this.copyBtn)\n this.shadow.appendChild(toolbar)\n\n this.applyPosition()\n document.body.appendChild(this.host)\n }\n\n private makeBtn(icon: 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.textContent = icon\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 // Drag from the shadow root toolbar div (not buttons)\n this.shadow.addEventListener('mousedown', (e) => {\n if ((e.target as Element).closest('.btn')) 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 setMode(mode: ToolbarMode): void {\n this.mode = mode\n this.annotateBtn.classList.toggle('active', mode === 'annotating')\n this.freezeBtn.classList.toggle('active', mode === 'frozen')\n document.body.classList.toggle('ik-annotating', 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 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 document.body.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, AnnotationIntent, AnnotationSeverity, PendingAnnotation } from '../types'\nimport { POPUP_CSS } from './styles'\n\ninterface PopupResult {\n comment: string\n intent: AnnotationIntent\n severity: AnnotationSeverity\n}\n\ninterface PopupCallbacks {\n onSubmit: (result: PopupResult) => void\n onCancel: () => void\n}\n\ninterface ThreadCallbacks {\n onResolve: (annotation: Annotation) => void\n onReply: (annotation: Annotation, content: string) => void\n}\n\nfunction esc(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"')\n}\n\nfunction fwIcon(fw: string): string {\n return ({ livewire: '⚡', vue: '💚', svelte: '🧡' } as Record<string, string>)[fw] ?? '🔧'\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 private intent: AnnotationIntent = 'fix'\n private severity: AnnotationSeverity = 'important'\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.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\">${fwIcon(pending.framework.framework)} ${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.elementName)}</span>\n <button class=\"close-btn\" title=\"Cancel (Esc)\">✕</button>\n </div>\n ${fwBadge}${selText}\n <div class=\"label\">Intent</div>\n <div class=\"row\">\n <div class=\"chips\" data-group=\"intent\">\n <button class=\"chip sel\" data-value=\"fix\">Fix</button>\n <button class=\"chip\" data-value=\"change\">Change</button>\n <button class=\"chip\" data-value=\"question\">Question</button>\n <button class=\"chip\" data-value=\"approve\">Approve</button>\n </div>\n </div>\n <div class=\"label\">Severity</div>\n <div class=\"row\">\n <div class=\"chips\" data-group=\"severity\">\n <button class=\"chip blocking\" data-value=\"blocking\">Blocking</button>\n <button class=\"chip important sel\" data-value=\"important\">Important</button>\n <button class=\"chip suggestion\" data-value=\"suggestion\">Suggestion</button>\n </div>\n </div>\n <textarea placeholder=\"Describe what you'd like changed…\" 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 this.wireChips(popup, 'intent', (v) => { this.intent = v as AnnotationIntent })\n this.wireChips(popup, 'severity', (v) => { this.severity = v as AnnotationSeverity })\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, intent: this.intent, severity: this.severity })\n this.destroy()\n })\n\n this.shadow.appendChild(popup)\n document.body.appendChild(this.host)\n\n this.positionHost(pending.x, pending.y)\n this.setupOutsideClick()\n textarea.focus()\n }\n\n // ── Thread / existing annotation popup ───────────────────────\n\n showThread(annotation: Annotation, callbacks: ThreadCallbacks): void {\n this.destroy()\n this.host = document.createElement('div')\n this.host.setAttribute('data-instruckt', 'popup')\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 statusLabel = (s: string) => `<span class=\"status-badge ${esc(s)}\">${esc(s)}</span>`\n const thread = (annotation.thread ?? []).map(m => `\n <div class=\"msg\">\n <div class=\"msg-role ${esc(m.role)}\">${m.role === 'agent' ? '🤖 Agent' : '👤 You'}</div>\n <div class=\"msg-content\">${esc(m.content)}</div>\n </div>\n `).join('')\n\n const isPending = ['pending', 'acknowledged'].includes(annotation.status)\n\n popup.innerHTML = `\n <div class=\"header\">\n <span class=\"element-tag\">${esc(annotation.element)}</span>\n <button class=\"close-btn\">✕</button>\n </div>\n ${statusLabel(annotation.status)}\n <div class=\"selected-text\" style=\"margin-top:8px;\">${esc(annotation.comment)}</div>\n ${thread ? `<div class=\"thread\">${thread}</div>` : ''}\n ${isPending ? `\n <div class=\"thread\" style=\"margin-top:8px;\">\n <textarea placeholder=\"Add a reply…\" rows=\"2\"></textarea>\n <div class=\"actions\" style=\"margin-top:6px;\">\n <button class=\"btn-secondary\" data-action=\"resolve\">Mark resolved</button>\n <button class=\"btn-primary\" data-action=\"reply\" disabled>Reply</button>\n </div>\n </div>\n ` : ''}\n `\n\n popup.querySelector('.close-btn')!.addEventListener('click', () => this.destroy())\n\n if (isPending) {\n const textarea = popup.querySelector('textarea')!\n const replyBtn = popup.querySelector<HTMLButtonElement>('[data-action=\"reply\"]')!\n textarea.addEventListener('input', () => {\n replyBtn.disabled = textarea.value.trim().length === 0\n })\n replyBtn.addEventListener('click', () => {\n const content = textarea.value.trim()\n if (!content) return\n callbacks.onReply(annotation, content)\n this.destroy()\n })\n popup.querySelector('[data-action=\"resolve\"]')!.addEventListener('click', () => {\n callbacks.onResolve(annotation)\n this.destroy()\n })\n }\n\n this.shadow.appendChild(popup)\n document.body.appendChild(this.host)\n\n // Position near center of screen for thread view\n this.positionHost(window.innerWidth / 2 - 170, window.innerHeight / 2 - 150)\n this.setupOutsideClick()\n }\n\n // ── Helpers ───────────────────────────────────────────────────\n\n private wireChips(container: HTMLElement, group: string, onChange: (v: string) => void): void {\n container.querySelectorAll<HTMLButtonElement>(`[data-group=\"${group}\"] .chip`).forEach(btn => {\n btn.addEventListener('click', () => {\n container.querySelectorAll(`[data-group=\"${group}\"] .chip`).forEach(b => b.classList.remove('sel'))\n btn.classList.add('sel')\n onChange(btn.dataset.value!)\n })\n })\n }\n\n private positionHost(x: number, y: number): void {\n if (!this.host) return\n // Temporarily visible to measure\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 // Use setTimeout so this click event doesn't immediately fire for the triggering click\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 document.body.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 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 = 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 => 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/** Human-readable element name for display in the popup */\nexport function getElementName(el: Element): string {\n // Prefer component-level labels\n const wireModel = el.getAttribute('wire:model') || el.getAttribute('wire:click')\n if (wireModel) return `wire:${wireModel.split('.')[0]}`\n\n const ariaLabel = el.getAttribute('aria-label')\n if (ariaLabel) return ariaLabel\n\n const id = el.id\n if (id) return `#${id}`\n\n const tag = el.tagName.toLowerCase()\n const role = el.getAttribute('role')\n if (role) return `${tag}[${role}]`\n\n const firstClass = el.classList[0]\n if (firstClass) return `${tag}.${firstClass}`\n\n return tag\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\ninterface LivewireComponent {\n name: string\n id: string\n get(key: string): unknown\n snapshot?: {\n data?: Record<string, unknown>\n }\n}\n\ninterface LivewireGlobal {\n find(id: string): LivewireComponent | undefined\n all(): LivewireComponent[]\n}\n\ndeclare global {\n interface Window {\n Livewire?: LivewireGlobal\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): string | null {\n let node: Element | null = el\n while (node && node !== document.documentElement) {\n const wireId = node.getAttribute('wire:id')\n if (wireId) return wireId\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 wireId = detect(el)\n if (!wireId) return null\n\n const component = window.Livewire!.find(wireId)\n if (!component) return null\n\n // Snapshot data holds the current public properties\n const snapshotData = component.snapshot?.data ?? {}\n const data: Record<string, unknown> = {}\n\n for (const key of Object.keys(snapshotData)) {\n try {\n data[key] = component.get(key)\n } catch {\n // property may not be readable\n }\n }\n\n return {\n framework: 'livewire',\n component: component.name,\n wire_id: wireId,\n data,\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, Session } from './types'\nimport { InstrucktApi } from './api'\nimport type { AnnotationPayload } from './api'\nimport { InstrucktSSE } from './sse'\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, 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\nconst SESSION_KEY = 'instruckt_session'\n\nexport class Instruckt {\n private config: Required<Pick<InstrucktConfig, 'endpoint' | 'theme' | 'position'>> & InstrucktConfig\n private api: InstrucktApi\n private sse: InstrucktSSE | null = null\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 session: Session | null = null\n private isAnnotating = false\n private isFrozen = false\n private frozenStyleEl: HTMLStyleElement | null = null\n private rafId: number | null = null\n private pendingMouseTarget: Element | null = null\n private mutationObserver: MutationObserver | null = null\n private boundKeydown: (e: KeyboardEvent) => void\n private boundScroll: () => void\n private boundResize: () => void\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.boundScroll = this.onScrollResize.bind(this)\n this.boundResize = this.onScrollResize.bind(this)\n this.init()\n }\n\n private async init(): Promise<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) => this.setAnnotating(active),\n onFreezeAnimations: (frozen) => this.setFrozen(frozen),\n onCopy: () => this.copyAnnotations(),\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.boundScroll, { passive: true })\n window.addEventListener('resize', this.boundResize, { passive: true })\n\n this.setupMutationObserver()\n await this.connectSession()\n }\n\n // ── Session ───────────────────────────────────────────────────\n\n private async connectSession(): Promise<void> {\n const stored = sessionStorage.getItem(SESSION_KEY)\n if (stored) {\n try {\n const data = await this.api.getSession(stored)\n this.session = data\n this.annotations = data.annotations ?? []\n this.syncMarkersFromAnnotations()\n this.toolbar?.setAnnotationCount(this.pendingCount())\n this.connectSSE(stored)\n return\n } catch {\n sessionStorage.removeItem(SESSION_KEY)\n }\n }\n try {\n this.session = await this.api.createSession(window.location.href)\n sessionStorage.setItem(SESSION_KEY, this.session.id)\n this.config.onSessionCreate?.(this.session)\n this.connectSSE(this.session.id)\n } catch {\n console.warn('[instruckt] Could not connect to server — running offline.')\n }\n }\n\n private connectSSE(sessionId: string): void {\n this.sse = new InstrucktSSE(this.config.endpoint, sessionId, (annotation) => {\n this.onAnnotationUpdated(annotation)\n })\n this.sse.connect()\n }\n\n // ── Annotate mode ─────────────────────────────────────────────\n\n private setAnnotating(active: boolean): void {\n if (active && this.isFrozen) {\n // Mutually exclusive — turn off freeze first\n this.setFrozen(false)\n }\n this.isAnnotating = 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 }\n\n private setFrozen(frozen: boolean): void {\n if (frozen && this.isAnnotating) {\n this.setAnnotating(false)\n this.toolbar?.setMode('idle')\n }\n this.isFrozen = frozen\n if (frozen) {\n this.frozenStyleEl = document.createElement('style')\n this.frozenStyleEl.id = 'instruckt-freeze'\n this.frozenStyleEl.textContent = `\n *, *::before, *::after { animation-play-state: paused !important; transition: none !important; }\n video { filter: none !important; }\n `\n document.head.appendChild(this.frozenStyleEl)\n } else {\n this.frozenStyleEl?.remove()\n this.frozenStyleEl = null\n }\n }\n\n // ── Event listeners ───────────────────────────────────────────\n\n private boundMouseMove = (e: MouseEvent): void => {\n this.pendingMouseTarget = e.target as Element\n if (this.rafId === null) {\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\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 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\n // Capture selection BEFORE the click can clear it\n const selectedText = window.getSelection()?.toString().trim() || undefined\n\n const elementPath = getElementSelector(target)\n const elementName = getElementName(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 cssClasses,\n boundingBox,\n x: e.clientX,\n y: e.clientY,\n selectedText,\n nearbyText,\n framework,\n }\n\n this.popup?.showNew(pending, {\n onSubmit: (result) => this.submitAnnotation(pending, result),\n onCancel: () => {},\n })\n }\n\n private attachAnnotateListeners(): void {\n document.addEventListener('mousemove', this.boundMouseMove)\n document.addEventListener('mouseleave', this.boundMouseLeave)\n document.addEventListener('click', this.boundClick, true)\n }\n\n private detachAnnotateListeners(): void {\n document.removeEventListener('mousemove', this.boundMouseMove)\n document.removeEventListener('mouseleave', this.boundMouseLeave)\n document.removeEventListener('click', this.boundClick, true)\n }\n\n private isInstruckt(el: Element): boolean {\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(\n pending: PendingAnnotation,\n result: { comment: string; intent: Annotation['intent']; severity: Annotation['severity'] },\n ): Promise<void> {\n if (!this.session) {\n await this.connectSession()\n if (!this.session) {\n console.warn('[instruckt] No session — annotation not saved.')\n return\n }\n }\n\n const payload: AnnotationPayload = {\n x: (pending.x / window.innerWidth) * 100,\n y: pending.y + window.scrollY,\n comment: result.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: result.intent,\n severity: result.severity,\n framework: pending.framework,\n url: window.location.href,\n }\n\n try {\n const annotation = await this.api.addAnnotation(this.session.id, payload)\n this.annotations.push(annotation)\n this.markers?.upsert(annotation, this.annotations.length)\n this.toolbar?.setAnnotationCount(this.pendingCount())\n this.config.onAnnotationAdd?.(annotation)\n } catch (err) {\n console.error('[instruckt] Failed to save annotation:', err)\n }\n }\n\n // ── Marker click — show thread ────────────────────────────────\n\n private onMarkerClick(annotation: Annotation): void {\n this.popup?.showThread(annotation, {\n onResolve: async (a) => {\n try {\n const updated = await this.api.updateAnnotation(a.id, { status: 'resolved' })\n this.onAnnotationUpdated(updated)\n } catch (err) {\n console.error('[instruckt] Failed to resolve annotation:', err)\n }\n },\n onReply: async (a, content) => {\n try {\n const updated = await this.api.addReply(a.id, content, 'human')\n this.onAnnotationUpdated(updated)\n } catch (err) {\n console.error('[instruckt] Failed to add reply:', err)\n }\n },\n })\n }\n\n // ── SSE updates ───────────────────────────────────────────────\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 this.markers?.update(updated)\n } else {\n this.annotations.push(updated)\n this.markers?.upsert(updated, this.annotations.length)\n }\n this.toolbar?.setAnnotationCount(this.pendingCount())\n this.config.onAnnotationResolve?.(updated)\n }\n\n // ── MutationObserver — handles Livewire/Vue DOM teardown ──────\n\n private setupMutationObserver(): void {\n this.mutationObserver = new MutationObserver((mutations) => {\n // When nodes are removed, check if any annotation's element path is gone\n const anyRemoved = mutations.some(m => m.removedNodes.length > 0)\n if (!anyRemoved) return\n\n // Reposition markers since DOM changed (Livewire re-render shifts layout)\n this.markers?.reposition(this.annotations)\n })\n\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n })\n }\n\n // ── Scroll/resize — reposition markers ───────────────────────\n\n private onScrollResize(): void {\n this.markers?.reposition(this.annotations)\n }\n\n // ── Keyboard ──────────────────────────────────────────────────\n\n private onKeydown(e: KeyboardEvent): void {\n const target = e.target as HTMLElement\n // Skip inputs, textareas, selects, and any contenteditable\n if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) return\n if (target.closest('[contenteditable=\"true\"]')) return\n\n if (e.key === 'a' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n const next = !this.isAnnotating\n this.toolbar?.setMode(next ? 'annotating' : 'idle')\n this.setAnnotating(next)\n }\n if (e.key === 'f' && !e.metaKey && !e.ctrlKey && !e.altKey) {\n const next = !this.isFrozen\n this.toolbar?.setMode(next ? 'frozen' : 'idle')\n this.setFrozen(next)\n }\n if (e.key === 'Escape') {\n if (this.isAnnotating) {\n this.toolbar?.setMode('idle')\n this.setAnnotating(false)\n }\n }\n }\n\n // ── Helpers ───────────────────────────────────────────────────\n\n private pendingCount(): number {\n return this.annotations.filter(a => a.status === 'pending' || a.status === 'acknowledged').length\n }\n\n private syncMarkersFromAnnotations(): void {\n this.annotations.forEach((a, i) => this.markers?.upsert(a, i + 1))\n }\n\n // ── Copy / export ─────────────────────────────────────────────\n\n private copyAnnotations(): void {\n const md = this.exportMarkdown()\n navigator.clipboard.writeText(md).catch(() => {\n // Fallback for browsers that don't support clipboard API\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 === 'pending' || a.status === 'acknowledged')\n if (pending.length === 0) {\n return `## Instruckt Feedback — ${window.location.href}\\n\\nNo open annotations.`\n }\n\n const lines: string[] = [\n `## Instruckt Feedback — ${window.location.href}`,\n `> ${pending.length} open annotation${pending.length === 1 ? '' : 's'}`,\n '',\n ]\n\n pending.forEach((a, i) => {\n const severityIcon = a.severity === 'blocking' ? '🔴' : a.severity === 'important' ? '🟠' : '🟡'\n const intentLabel = a.intent === 'fix' ? 'Fix' : a.intent === 'change' ? 'Change' : a.intent === 'question' ? 'Question' : 'Approve'\n lines.push(`### ${i + 1}. ${a.element} — ${intentLabel} ${severityIcon}`)\n lines.push('')\n lines.push(a.comment)\n lines.push('')\n lines.push(`**Selector**: \\`${a.elementPath}\\``)\n if (a.framework) {\n const fw = a.framework\n const label = fw.framework === 'livewire' ? `Livewire — ${fw.component}` : fw.framework === 'vue' ? `Vue — ${fw.component}` : fw.framework === 'react' ? `React — ${fw.component}` : fw.component\n lines.push(`**Component**: ${label}`)\n }\n if (a.selectedText) lines.push(`**Selected text**: \"${a.selectedText}\"`)\n if (a.thread && a.thread.length > 0) {\n lines.push('')\n lines.push('**Thread:**')\n a.thread.forEach(m => {\n lines.push(`- **${m.role === 'agent' ? 'Agent' : 'You'}**: ${m.content}`)\n })\n }\n lines.push('')\n lines.push('---')\n lines.push('')\n })\n\n return lines.join('\\n')\n }\n\n // ── Public API ────────────────────────────────────────────────\n\n getAnnotations(): Annotation[] { return [...this.annotations] }\n getSession(): Session | null { return this.session }\n\n destroy(): void {\n this.setAnnotating(false)\n this.setFrozen(false)\n document.removeEventListener('keydown', this.boundKeydown)\n window.removeEventListener('scroll', this.boundScroll)\n window.removeEventListener('resize', this.boundResize)\n this.mutationObserver?.disconnect()\n this.sse?.disconnect()\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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","names":["src_exports","__export","Instruckt","init","getCsrfToken","match","headers","h","csrf","InstrucktApi","endpoint","url","res","sessionId","data","annotationId","content","role","InstrucktSSE","endpoint","sessionId","onUpdate","e","annotation","_a","GLOBAL_CSS","TOOLBAR_CSS","POPUP_CSS","MARKER_CSS","injectGlobalStyles","style","Toolbar","position","callbacks","style","TOOLBAR_CSS","toolbar","next","divider","divider2","icon","title","onClick","btn","e","m","rect","mode","count","badge","ElementHighlight","el","rect","esc","s","fwIcon","fw","_a","AnnotationPopup","e","pending","callbacks","style","POPUP_CSS","popup","fwBadge","selText","v","textarea","submitBtn","comment","annotation","statusLabel","thread","m","isPending","replyBtn","content","container","group","onChange","btn","b","x","y","_b","w","h","vw","vh","left","top","AnnotationMarkers","onClick","annotation","index","existing","el","e","marker","status","annotations","annotationId","getElementSelector","el","path","current","tag","parent","classes","c","classSelector","siblings","index","getElementName","wireModel","ariaLabel","id","role","firstClass","getNearbyText","getCssClasses","getPageBoundingBox","rect","isAvailable","detect","el","node","wireId","getContext","_a","_b","component","snapshotData","data","key","e","detect","el","_a","node","instance","getContext","_b","_c","_d","_e","_f","_g","_h","name","data","key","value","e","detect","el","node","getContext","_a","_b","_c","_d","meta","filePath","getFiberKey","el","key","getComponentName","fiber","node","type","name","getProps","_a","_b","props","result","k","v","e","getContext","el","node","key","getFiberKey","fiber","component","getComponentName","data","getProps","SESSION_KEY","Instruckt","config","e","_a","_b","_c","target","selectedText","elementPath","getElementSelector","elementName","getElementName","cssClasses","getCssClasses","nearbyText","getNearbyText","boundingBox","getPageBoundingBox","framework","pending","result","__spreadValues","InstrucktApi","injectGlobalStyles","Toolbar","active","frozen","ElementHighlight","AnnotationPopup","AnnotationMarkers","annotation","_d","stored","data","sessionId","InstrucktSSE","el","adapters","ctx","getContext","payload","err","a","updated","content","_e","idx","mutations","m","next","i","md","lines","severityIcon","intentLabel","fw","label","_f","init","config","Instruckt"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "instruckt",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Visual feedback tool for AI coding agents — framework-agnostic, Livewire-first",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "instruckt",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/joshcirre/instruckt"
|
|
10
|
+
},
|
|
11
|
+
"main": "dist/instruckt.cjs.js",
|
|
12
|
+
"module": "dist/instruckt.esm.js",
|
|
13
|
+
"types": "dist/instruckt.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/instruckt.d.ts",
|
|
17
|
+
"require": "./dist/instruckt.cjs.js",
|
|
18
|
+
"import": "./dist/instruckt.esm.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"dev": "tsup --watch",
|
|
27
|
+
"typecheck": "tsc --noEmit"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"tsup": "^8.0.0",
|
|
31
|
+
"typescript": "^5.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|