@sightspool/sdk 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/privacy.ts","../src/prompt.ts","../src/capture.ts","../src/harvest.ts","../src/egress.ts","../src/triggers.ts","../src/env.ts","../src/index.ts"],"names":["redactText","input","EMAIL_RE","LONG_DIGITS_RE","safeClosest","el","selector","e","isIgnoredElement","blockSelectors","IGNORE_ATTR","sel","matchesRedactSelector","redactSelectors","ATTACH_DISCLOSURE","REDACTED","init_privacy","__esmMin","prompt_exports","__export","showPrompt","opts","resolve","settled","host","shadow","finish","result","style","STYLE","wrap","render","node","card","x","disc","stateA","q","row","yes","no","stateB","c","b","se","stateText","submit","init_prompt","TRAIL_MAX","DEAD_CLICK_MS","RAGE_WINDOW_MS","RAGE_COUNT","hasDom","createCapture","_a","_b","buf","lastError","started","subs","cleanups","recentClicks","notify","cb","push","type","label","currentRoute","currentLabel","onClick","ev","target","text","t","ts","isRage","routeBefore","mutated","observer","onError","onRejection","reason","installRouteTracking","fire","origPush","origReplace","args","r","installFetchTracking","orig","res","err","query","zeroResult","SEARCH_HINT_RE","DEBOUNCE_MS","looksLikeSearch","role","hay","createHarvest","capture","hint","timer","onInput","value","createEgress","queue","identity","interval","url","send","signals","body","json","blob","onVisibility","flush","batch","signal","next","detectFriction","trail","now","windowMs","recent","clicks","i","byLabel","n","DEFAULT_CAPS","canPrompt","state","caps","LOCAL_HOSTS","isLocalhost","hostname","h","DEFAULT_ENDPOINT","FRICTION_EMIT_COOLDOWN_MS","EVENT_DEBOUNCE_MS","currentHostname","ctrl","uuid","deriveCandidates","out","buildSignal","trigger","extra","maybePrompt","onCaptureEvent","onExitIntent","startRuntime","init","config","endpoint","privacyOpts","harvest","egress","identify","userId","traits","start","consent","granted","stop","api","src_default","key","list","attr","raw","s"],"mappings":"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","file":"sdk.global.js","sourcesContent":["// Redaction — mask sensitive text before it ever leaves the page (GOV-3). The\n// pure string helpers are unit-tested; the DOM-querying part (selector masking)\n// lives in capture.ts and calls in here.\n\nconst EMAIL_RE = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g;\nconst LONG_DIGITS_RE = /\\d{6,}/g; // card / account-number-ish runs\n\nexport const MAX_LABEL_LEN = 280;\n\n/**\n * Mask PII-ish substrings in a captured label/verbatim and clamp length.\n * Conservative: emails and long digit runs become placeholders. Never throws.\n */\nexport function redactText(input: string | null | undefined): string {\n if (!input) return \"\";\n try {\n return String(input)\n .replace(EMAIL_RE, \"‹email›\")\n .replace(LONG_DIGITS_RE, \"‹num›\")\n .replace(/\\s+/g, \" \")\n .trim()\n .slice(0, MAX_LABEL_LEN);\n } catch {\n return \"\";\n }\n}\n\n/** Should a captured element's value be dropped entirely (not just masked)? */\nexport function isSensitiveInput(type: string | null | undefined): boolean {\n const t = (type ?? \"\").toLowerCase();\n return t === \"password\" || t === \"email\" || t === \"tel\" || t === \"creditcard\";\n}\n\nexport const ATTACH_DISCLOSURE = \"Session and account attached automatically.\";\n\n/** Placeholder substituted for the text of a `redact`-matched element (GOV-3). */\nexport const REDACTED = \"‹redacted›\";\n\n/** The per-element opt-out attribute: a click/input inside `[data-sightspool-ignore]` is dropped entirely. */\nexport const IGNORE_ATTR = \"data-sightspool-ignore\";\n\n/** Anything with a `.closest(selector)` — the bit of Element we depend on (kept DOM-free for unit tests). */\ntype Closeable = { closest?: (selectors: string) => unknown };\n\nfunction safeClosest(el: Closeable, selector: string): boolean {\n try {\n return typeof el.closest === \"function\" && el.closest(selector) != null;\n } catch {\n // An invalid selector (host misconfig) must never throw into capture — and must\n // never *accidentally capture* what was meant to be excluded: treat as no-match\n // for that one selector and let the others decide.\n return false;\n }\n}\n\n/**\n * Should this element's events be dropped entirely (not just masked)? True when the\n * element — or any ancestor — carries `data-sightspool-ignore` or matches one of the\n * configured `block` selectors. The host's hard privacy opt-out (GOV-3).\n */\nexport function isIgnoredElement(\n el: Closeable | null | undefined,\n blockSelectors: readonly string[] = [],\n): boolean {\n if (!el || typeof el.closest !== \"function\") return false;\n if (safeClosest(el, `[${IGNORE_ATTR}]`)) return true;\n for (const sel of blockSelectors) {\n if (sel && safeClosest(el, sel)) return true;\n }\n return false;\n}\n\n/**\n * Should this element's captured text be masked wholesale? True when the element —\n * or any ancestor — matches one of the configured `redact` selectors. (The event is\n * still recorded; only its label becomes {@link REDACTED}.)\n */\nexport function matchesRedactSelector(\n el: Closeable | null | undefined,\n redactSelectors: readonly string[] = [],\n): boolean {\n if (!el || typeof el.closest !== \"function\") return false;\n for (const sel of redactSelectors) {\n if (sel && safeClosest(el, sel)) return true;\n }\n return false;\n}\n","// The prompt UI (FR-5/6, the §16.2 blend) — rendered in a shadow root so the host\n// app's CSS can't style-break it and it leaks zero styles back. This module is\n// dynamically imported by index.ts only when a trigger fires, so it splits into a\n// lazily-loaded chunk and adds nothing to the host bundle until needed.\n//\n// State A — \"Were you able to do what you came here to do today?\" [Yes][Not really]\n// State B — (after \"Not really\") top candidate goals + an always-present\n// \"Something else\" → optional free text only after that.\n\nimport type { SignalAnswer } from \"./types\";\nimport { ATTACH_DISCLOSURE } from \"./privacy\";\n\nexport type PromptResult = {\n answer: SignalAnswer;\n intent?: string; // a tapped candidate\n verbatim?: string; // free text from \"Something else\"\n};\n\nexport type PromptOptions = {\n /** Locally-derived candidate goals (FR-5 State B). May be empty → generic ask. */\n candidates: string[];\n};\n\nconst STYLE = `\n:host { all: initial; }\n.wrap { position: fixed; bottom: 20px; right: 20px; z-index: 2147483000;\n width: 320px; max-width: calc(100vw - 32px); font-family: system-ui, -apple-system, sans-serif; }\n.card { background: #fff; color: #18181b; border: 1px solid #e4e4e7; border-radius: 12px;\n box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 16px; }\n.q { font-size: 14px; font-weight: 600; margin: 0 0 12px; line-height: 1.35; }\n.row { display: flex; gap: 8px; flex-wrap: wrap; }\nbutton { font: inherit; font-size: 13px; cursor: pointer; border-radius: 8px; padding: 8px 12px;\n border: 1px solid #e4e4e7; background: #fafafa; color: #18181b; }\nbutton:hover { background: #f4f4f5; }\nbutton.primary { background: #18181b; color: #fff; border-color: #18181b; }\n.cand { display: block; width: 100%; text-align: left; margin-bottom: 6px; }\n.disc { font-size: 11px; color: #71717a; margin: 12px 0 0; }\n.x { position: absolute; top: 8px; right: 10px; border: none; background: none; font-size: 16px;\n color: #a1a1aa; padding: 2px 6px; }\ninput { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; padding: 8px 10px;\n border: 1px solid #e4e4e7; border-radius: 8px; margin-bottom: 8px; }\n`;\n\nexport function showPrompt(opts: PromptOptions): Promise<PromptResult> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\") {\n resolve({ answer: \"dismissed\" });\n return;\n }\n\n let settled = false;\n const host = document.createElement(\"div\");\n const shadow = host.attachShadow({ mode: \"open\" });\n\n function finish(result: PromptResult) {\n if (settled) return;\n settled = true;\n try {\n host.remove();\n } catch {\n /* swallow */\n }\n resolve(result);\n }\n\n const style = document.createElement(\"style\");\n style.textContent = STYLE;\n shadow.appendChild(style);\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n shadow.appendChild(wrap);\n\n function render(node: HTMLElement) {\n wrap.innerHTML = \"\";\n const card = document.createElement(\"div\");\n card.className = \"card\";\n card.style.position = \"relative\";\n const x = document.createElement(\"button\");\n x.className = \"x\";\n x.textContent = \"×\";\n x.setAttribute(\"aria-label\", \"Dismiss\");\n x.onclick = () => finish({ answer: \"dismissed\" });\n card.appendChild(x);\n card.appendChild(node);\n const disc = document.createElement(\"p\");\n disc.className = \"disc\";\n disc.textContent = ATTACH_DISCLOSURE;\n card.appendChild(disc);\n wrap.appendChild(card);\n }\n\n // --- State A ---\n function stateA() {\n const node = document.createElement(\"div\");\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = \"Were you able to do what you came here to do today?\";\n node.appendChild(q);\n const row = document.createElement(\"div\");\n row.className = \"row\";\n const yes = document.createElement(\"button\");\n yes.className = \"primary\";\n yes.textContent = \"Yes\";\n yes.onclick = () => finish({ answer: \"yes\" });\n const no = document.createElement(\"button\");\n no.textContent = \"Not really\";\n no.onclick = () => stateB();\n row.append(yes, no);\n node.appendChild(row);\n render(node);\n }\n\n // --- State B ---\n function stateB() {\n const node = document.createElement(\"div\");\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = \"What were you trying to do?\";\n node.appendChild(q);\n for (const c of opts.candidates.slice(0, 4)) {\n const b = document.createElement(\"button\");\n b.className = \"cand\";\n b.textContent = c;\n b.onclick = () => finish({ answer: \"not_really\", intent: c });\n node.appendChild(b);\n }\n const se = document.createElement(\"button\");\n se.className = \"cand\";\n se.textContent = \"Something else…\";\n se.onclick = () => stateText();\n node.appendChild(se);\n render(node);\n }\n\n // --- \"Something else\" free text ---\n function stateText() {\n const node = document.createElement(\"div\");\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = \"What were you trying to do?\";\n node.appendChild(q);\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.placeholder = \"In your own words…\";\n node.appendChild(input);\n const row = document.createElement(\"div\");\n row.className = \"row\";\n const submit = document.createElement(\"button\");\n submit.className = \"primary\";\n submit.textContent = \"Send\";\n submit.onclick = () =>\n finish({ answer: \"not_really\", verbatim: input.value.trim() || undefined });\n row.appendChild(submit);\n node.appendChild(row);\n render(node);\n try {\n input.focus();\n } catch {\n /* swallow */\n }\n }\n\n try {\n document.body.appendChild(host);\n stateA();\n } catch {\n finish({ answer: \"dismissed\" });\n }\n });\n}\n","// Passive context capture (FR-2) — the buffer of route/click/error events the\n// rest of the runtime reads. All DOM access is guarded and wrapped: this module\n// must never throw into the host app (NFR-3).\n\nimport type { TrailEvent, TrailEventType } from \"./types\";\nimport { redactText, isIgnoredElement, matchesRedactSelector, REDACTED } from \"./privacy\";\n\nconst TRAIL_MAX = 30;\nconst DEAD_CLICK_MS = 700; // a click with no DOM/route change after this = dead-click\nconst RAGE_WINDOW_MS = 1_000;\nconst RAGE_COUNT = 3;\n\nexport type CaptureHandle = {\n start(): void;\n stop(): void;\n trail(): TrailEvent[];\n route(): string;\n label(): string;\n error(): string | undefined;\n /** Subscribe to \"a meaningful event happened\" (the trigger engine polls off this). */\n onEvent(cb: () => void): void;\n /** Called by harvest.ts when a search/filter query is typed. */\n recordSearch(query: string, zeroResult?: boolean): void;\n};\n\nfunction hasDom(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nexport function createCapture(opts: {\n debug: boolean;\n redact?: readonly string[];\n block?: readonly string[];\n}): CaptureHandle {\n const redactSelectors = opts.redact ?? [];\n const blockSelectors = opts.block ?? [];\n let buf: TrailEvent[] = [];\n let lastError: string | undefined;\n let started = false;\n const subs: Array<() => void> = [];\n const cleanups: Array<() => void> = [];\n let recentClicks: number[] = []; // timestamps, for rage detection\n\n function notify() {\n for (const cb of subs) {\n try {\n cb();\n } catch {\n /* a subscriber must never break capture */\n }\n }\n }\n\n function push(type: TrailEventType, label?: string) {\n try {\n buf.push({ t: Date.now(), type, label: label ? redactText(label) : undefined });\n if (buf.length > TRAIL_MAX) buf = buf.slice(-TRAIL_MAX);\n if (opts.debug) console.debug(\"[sightspool] event\", type, label);\n notify();\n } catch {\n /* swallow */\n }\n }\n\n function currentRoute(): string {\n try {\n return location.pathname + location.search;\n } catch {\n return \"\";\n }\n }\n\n function currentLabel(): string {\n try {\n return document.title || \"\";\n } catch {\n return \"\";\n }\n }\n\n function onClick(ev: MouseEvent) {\n try {\n const target = ev.target as Element | null;\n // Hard opt-out: a click inside [data-sightspool-ignore] or a `block` selector is\n // never recorded — not even as an unlabelled event (GOV-3).\n if (isIgnoredElement(target, blockSelectors)) return;\n const text =\n (target && (target.getAttribute?.(\"aria-label\") || target.textContent)) || \"\";\n // `redact` selectors mask the label wholesale; emails/digits in any label are\n // also masked by push() → redactText.\n const label = matchesRedactSelector(target, redactSelectors)\n ? REDACTED\n : text.trim().slice(0, 60);\n const t = Date.now();\n\n recentClicks = recentClicks.filter((ts) => t - ts <= RAGE_WINDOW_MS);\n recentClicks.push(t);\n const isRage = recentClicks.length >= RAGE_COUNT;\n push(isRage ? \"rage_click\" : \"click\", label);\n\n // dead-click: did anything change shortly after? watch for a DOM mutation or\n // a route change; if neither, record a dead_click.\n const routeBefore = currentRoute();\n let mutated = false;\n let observer: MutationObserver | null = null;\n try {\n observer = new MutationObserver(() => {\n mutated = true;\n });\n observer.observe(document.body, { childList: true, subtree: true, attributes: true });\n } catch {\n /* no MutationObserver — skip dead-click detection */\n }\n window.setTimeout(() => {\n try {\n observer?.disconnect();\n if (!mutated && currentRoute() === routeBefore && label) {\n push(\"dead_click\", label);\n }\n } catch {\n /* swallow */\n }\n }, DEAD_CLICK_MS);\n } catch {\n /* swallow */\n }\n }\n\n function onError(ev: ErrorEvent) {\n try {\n lastError = String(ev.message || \"error\");\n push(\"error\", lastError);\n } catch {\n /* swallow */\n }\n }\n\n function onRejection(ev: PromiseRejectionEvent) {\n try {\n const reason = ev.reason;\n lastError = reason instanceof Error ? reason.message : String(reason);\n push(\"error\", lastError);\n } catch {\n /* swallow */\n }\n }\n\n // Route changes: patch history.pushState/replaceState + listen for popstate.\n function installRouteTracking() {\n try {\n const fire = () => push(\"route\", currentRoute());\n const origPush = history.pushState;\n const origReplace = history.replaceState;\n history.pushState = function (this: History, ...args: Parameters<History[\"pushState\"]>) {\n const r = origPush.apply(this, args);\n fire();\n return r;\n };\n history.replaceState = function (\n this: History,\n ...args: Parameters<History[\"replaceState\"]>\n ) {\n const r = origReplace.apply(this, args);\n fire();\n return r;\n };\n window.addEventListener(\"popstate\", fire);\n cleanups.push(() => {\n history.pushState = origPush;\n history.replaceState = origReplace;\n window.removeEventListener(\"popstate\", fire);\n });\n push(\"route\", currentRoute()); // seed with the entry route\n } catch {\n /* swallow */\n }\n }\n\n // Light fetch wrapper to catch failed/4xx-5xx requests as request_error events.\n function installFetchTracking() {\n try {\n if (typeof window.fetch !== \"function\") return;\n const orig = window.fetch.bind(window);\n window.fetch = async (...args: Parameters<typeof fetch>) => {\n try {\n const res = await orig(...args);\n if (!res.ok) push(\"request_error\", `HTTP ${res.status}`);\n return res;\n } catch (err) {\n push(\"request_error\", err instanceof Error ? err.message : \"network error\");\n throw err;\n }\n };\n cleanups.push(() => {\n window.fetch = orig;\n });\n } catch {\n /* swallow */\n }\n }\n\n return {\n start() {\n if (started || !hasDom()) return;\n started = true;\n try {\n document.addEventListener(\"click\", onClick, true);\n window.addEventListener(\"error\", onError);\n window.addEventListener(\"unhandledrejection\", onRejection);\n cleanups.push(() => {\n document.removeEventListener(\"click\", onClick, true);\n window.removeEventListener(\"error\", onError);\n window.removeEventListener(\"unhandledrejection\", onRejection);\n });\n installRouteTracking();\n installFetchTracking();\n } catch {\n /* swallow */\n }\n },\n stop() {\n started = false;\n for (const c of cleanups.splice(0)) {\n try {\n c();\n } catch {\n /* swallow */\n }\n }\n },\n trail() {\n return buf.slice();\n },\n route: currentRoute,\n label: currentLabel,\n error() {\n return lastError;\n },\n onEvent(cb) {\n subs.push(cb);\n },\n recordSearch(query, zeroResult) {\n const q = query.trim();\n if (!q) return;\n push(zeroResult ? \"zero_result\" : \"search\", q);\n },\n };\n}\n","// Intent harvest (FR-3) — treat typed queries in search / filter / command-palette\n// / empty-state inputs as STATED intent (the highest-signal intent, no question\n// needed). Harvesting precedes any inference. Defensive throughout (NFR-3).\n//\n// Zero-result detection is genuinely cross-app-specific and best-effort in v1: we\n// capture the query as a search event; flagging it as zero-result reliably is a\n// follow-up (it needs per-app empty-state hints). The query itself is the value.\n\nimport type { CaptureHandle } from \"./capture\";\nimport { isIgnoredElement, matchesRedactSelector } from \"./privacy\";\n\nconst SEARCH_HINT_RE = /search|filter|find|query|command|lookup/i;\nconst DEBOUNCE_MS = 800;\n\nexport type HarvestHandle = {\n start(): void;\n stop(): void;\n /** The most recent stated intent (last search/filter query), for State-B candidates. */\n lastIntentHint(): string | undefined;\n};\n\nfunction looksLikeSearch(el: Element): boolean {\n try {\n const input = el as HTMLInputElement;\n if (input.type === \"search\") return true;\n const role = el.getAttribute(\"role\") || \"\";\n if (role === \"searchbox\" || role === \"combobox\") return true;\n const hay = [\n input.name,\n input.placeholder,\n el.getAttribute(\"aria-label\"),\n el.id,\n el.className,\n ]\n .filter(Boolean)\n .join(\" \");\n return SEARCH_HINT_RE.test(hay);\n } catch {\n return false;\n }\n}\n\nexport function createHarvest(\n capture: CaptureHandle,\n opts: { debug: boolean; redact?: readonly string[]; block?: readonly string[] },\n): HarvestHandle {\n let hint: string | undefined;\n let timer: number | null = null;\n let started = false;\n const redactSelectors = opts.redact ?? [];\n const blockSelectors = opts.block ?? [];\n\n function onInput(ev: Event) {\n try {\n const target = ev.target as HTMLInputElement | null;\n if (!target || (target.tagName !== \"INPUT\" && target.tagName !== \"TEXTAREA\")) return;\n if (!looksLikeSearch(target)) return;\n // A masked query is useless intent, so a `redact`-matched search box is treated\n // as a hard opt-out here (same as `block`/ignore): don't harvest the value at all.\n if (isIgnoredElement(target, blockSelectors) || matchesRedactSelector(target, redactSelectors))\n return;\n const value = (target.value || \"\").trim();\n if (value.length < 2) return;\n\n if (timer !== null) window.clearTimeout(timer);\n timer = window.setTimeout(() => {\n hint = value;\n capture.recordSearch(value);\n if (opts.debug) console.debug(\"[sightspool] harvested intent\", value);\n }, DEBOUNCE_MS);\n } catch {\n /* swallow */\n }\n }\n\n return {\n start() {\n if (started || typeof document === \"undefined\") return;\n started = true;\n try {\n document.addEventListener(\"input\", onInput, true);\n } catch {\n /* swallow */\n }\n },\n stop() {\n started = false;\n try {\n document.removeEventListener(\"input\", onInput, true);\n if (timer !== null) window.clearTimeout(timer);\n } catch {\n /* swallow */\n }\n },\n lastIntentHint() {\n return hint;\n },\n };\n}\n","// Egress — batch captured Signals and ship them to /api/sdk/ingest, preferring\n// navigator.sendBeacon (survives page unload) with a fetch+keepalive fallback.\n// Every path is wrapped: a failed send must never surface in the host app (NFR-3),\n// and a Signal already records its why/cost passively, so a dropped beacon just\n// loses enrichment, not the capture's value (FR-7).\n\nimport type { CapturedSignal, Identity, IngestBody } from \"./types\";\n\nconst FLUSH_BATCH = 10; // flush when this many Signals are queued\nconst FLUSH_INTERVAL_MS = 15_000;\n\nexport type EgressHandle = {\n start(): void;\n stop(): void;\n enqueue(signal: CapturedSignal): void;\n flush(): void;\n setIdentity(identity: Identity): void;\n};\n\nexport function createEgress(opts: {\n key: string;\n endpoint: string;\n debug: boolean;\n}): EgressHandle {\n let queue: CapturedSignal[] = [];\n let identity: Identity | undefined;\n let interval: number | null = null;\n let started = false;\n\n const url = `${opts.endpoint.replace(/\\/+$/, \"\")}/api/sdk/ingest`;\n\n function send(signals: CapturedSignal[]) {\n if (signals.length === 0) return;\n const body: IngestBody = { key: opts.key, identity, signals };\n const json = JSON.stringify(body);\n try {\n // text/plain is a CORS-safelisted content type, so a cross-origin beacon\n // skips the preflight entirely (the host app's domain ≠ ours). The server\n // parses the text as JSON regardless.\n if (typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const blob = new Blob([json], { type: \"text/plain\" });\n const ok = navigator.sendBeacon(url, blob);\n if (ok) {\n if (opts.debug) console.debug(\"[sightspool] beacon\", signals.length);\n return;\n }\n }\n // Fallback: fetch with keepalive so it can outlive the page.\n void fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain\" },\n body: json,\n keepalive: true,\n mode: \"cors\",\n credentials: \"omit\",\n }).catch(() => {\n /* swallow — drop on failure */\n });\n } catch {\n /* swallow */\n }\n }\n\n function onVisibility() {\n try {\n if (document.visibilityState === \"hidden\") flush();\n } catch {\n /* swallow */\n }\n }\n\n function flush() {\n if (queue.length === 0) return;\n const batch = queue;\n queue = [];\n send(batch);\n }\n\n return {\n start() {\n if (started || typeof window === \"undefined\") return;\n started = true;\n try {\n document.addEventListener(\"visibilitychange\", onVisibility);\n window.addEventListener(\"pagehide\", flush);\n interval = window.setInterval(flush, FLUSH_INTERVAL_MS);\n } catch {\n /* swallow */\n }\n },\n stop() {\n started = false;\n try {\n document.removeEventListener(\"visibilitychange\", onVisibility);\n window.removeEventListener(\"pagehide\", flush);\n if (interval !== null) window.clearInterval(interval);\n } catch {\n /* swallow */\n }\n flush();\n },\n enqueue(signal) {\n queue.push(signal);\n if (queue.length >= FLUSH_BATCH) flush();\n },\n flush,\n setIdentity(next) {\n identity = next;\n },\n };\n}\n","// Trigger + fatigue logic (FR-4, NFR-2) — the make-or-break craft surface.\n//\n// Kept PURE (no DOM) so it unit-tests cleanly under `node --test` and so the\n// heuristics can be tuned against real traffic later without touching the capture\n// wiring. Detection quality is the primary failure mode (false positives that\n// pester users), so the defaults are deliberately conservative.\n\nimport type { TrailEvent } from \"./types\";\n\nexport const RAGE_CLICK_COUNT = 3; // clicks…\nexport const RAGE_WINDOW_MS = 1_000; // …within this window form a rage cluster\nexport const FRICTION_RETRY_COUNT = 3; // repeated identical actions = retry frustration\nexport const FRICTION_WINDOW_MS = 8_000; // how far back a friction scan looks\n\nexport type FrictionKind = \"error\" | \"rage\" | \"dead_end\" | \"retry\";\n\n/**\n * Scan the recent trail for a friction moment. Returns the strongest kind found,\n * or null. Order = severity: a real error beats a rage cluster beats a dead-end\n * beats repeated retries.\n */\nexport function detectFriction(\n trail: TrailEvent[],\n now: number,\n windowMs = FRICTION_WINDOW_MS,\n): FrictionKind | null {\n const recent = trail.filter((e) => now - e.t <= windowMs);\n\n if (recent.some((e) => e.type === \"error\" || e.type === \"request_error\")) return \"error\";\n\n const clicks = recent.filter((e) => e.type === \"click\" || e.type === \"rage_click\");\n for (let i = 0; i < clicks.length; i++) {\n const burst = clicks.filter(\n (e) => e.t >= clicks[i].t && e.t - clicks[i].t <= RAGE_WINDOW_MS,\n );\n if (burst.length >= RAGE_CLICK_COUNT) return \"rage\";\n }\n\n if (recent.some((e) => e.type === \"dead_click\")) return \"dead_end\";\n\n const byLabel = new Map<string, number>();\n for (const e of clicks) {\n if (!e.label) continue;\n const n = (byLabel.get(e.label) ?? 0) + 1;\n byLabel.set(e.label, n);\n if (n >= FRICTION_RETRY_COUNT) return \"retry\";\n }\n\n return null;\n}\n\n// --- Fatigue caps (NFR-2): never pester. Conservative by default. ------------\n\nexport type FatigueCaps = {\n maxPromptsPerSession: number;\n cooldownMs: number; // min gap between prompts\n};\n\nexport const DEFAULT_CAPS: FatigueCaps = {\n maxPromptsPerSession: 1,\n cooldownMs: 5 * 60_000,\n};\n\nexport type FatigueState = {\n promptsShown: number;\n lastPromptAt: number | null;\n};\n\n/** May we show a prompt right now, given how many we've shown and when? */\nexport function canPrompt(\n state: FatigueState,\n now: number,\n caps: FatigueCaps = DEFAULT_CAPS,\n): boolean {\n if (state.promptsShown >= caps.maxPromptsPerSession) return false;\n if (state.lastPromptAt !== null && now - state.lastPromptAt < caps.cooldownMs) return false;\n return true;\n}\n","// Environment guards. Kept pure (a hostname string in, a boolean out) so the\n// no-op-on-localhost decision is unit-testable without a DOM.\n\nconst LOCAL_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"0.0.0.0\", \"::1\", \"\"]);\n\n/**\n * Is this a local-development hostname? Capture is suppressed on these by default so\n * a client's `npm run dev` traffic never pollutes their Sightspool workspace (override\n * with `captureOnLocalhost: true`). Covers the common dev hosts + the `.local` /\n * `.localhost` TLDs (e.g. `myapp.local`, `app.localhost`).\n */\nexport function isLocalhost(hostname: string | null | undefined): boolean {\n const h = (hostname ?? \"\").trim().toLowerCase();\n if (LOCAL_HOSTS.has(h)) return true;\n return h.endsWith(\".local\") || h.endsWith(\".localhost\");\n}\n","// @sightspool/sdk — the in-product capture runtime (public surface).\n//\n// Ties the pieces together: passive capture + intent harvest feed a conservative\n// trigger engine; on a friction moment or a session boundary we (fatigue\n// permitting) show the one-tap prompt, then emit one Signal via batched sendBeacon.\n// Every public method is wrapped — the SDK must never throw into the host (NFR-3).\n\nimport type { SightspoolConfig, Identity, CapturedSignal } from \"./types\";\nimport { createCapture, type CaptureHandle } from \"./capture\";\nimport { createHarvest, type HarvestHandle } from \"./harvest\";\nimport { createEgress, type EgressHandle } from \"./egress\";\nimport {\n detectFriction,\n canPrompt,\n DEFAULT_CAPS,\n type FatigueState,\n} from \"./triggers\";\nimport { isLocalhost } from \"./env\";\n\nexport type { SightspoolConfig, Identity } from \"./types\";\n\nconst DEFAULT_ENDPOINT = \"https://app.sightspool.com\";\nconst FRICTION_EMIT_COOLDOWN_MS = 30_000;\nconst EVENT_DEBOUNCE_MS = 600;\n\ntype Controller = {\n config: Required<Pick<SightspoolConfig, \"key\" | \"endpoint\" | \"boundaryAsk\" | \"debug\">> &\n SightspoolConfig;\n capture: CaptureHandle;\n harvest: HarvestHandle;\n egress: EgressHandle;\n identity: Identity;\n sessionRef: string;\n fatigue: FatigueState;\n lastFrictionEmitAt: number;\n eventTimer: number | null;\n running: boolean;\n /** Environmental kill-switch: on localhost without `captureOnLocalhost`, never start. */\n suppressed: boolean;\n};\n\nfunction currentHostname(): string {\n try {\n return typeof location !== \"undefined\" ? location.hostname : \"\";\n } catch {\n return \"\";\n }\n}\n\nlet ctrl: Controller | null = null;\n\nfunction uuid(): string {\n try {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n } catch {\n /* fall through */\n }\n return \"s-\" + Math.random().toString(36).slice(2) + Date.now().toString(36);\n}\n\n// Locally-derived candidate goals for State B (FR-5). v1 leans on harvested intent\n// (a recent search) + the page label; server-LLM enrichment is a follow-up.\nfunction deriveCandidates(c: Controller): string[] {\n const out: string[] = [];\n const hint = c.harvest.lastIntentHint();\n if (hint) out.push(`Searching for “${hint}”`);\n const label = c.capture.label();\n if (label) out.push(`Something on “${label.slice(0, 40)}”`);\n return out;\n}\n\nfunction buildSignal(\n c: Controller,\n trigger: \"boundary\" | \"friction\",\n extra: Partial<CapturedSignal> = {},\n): CapturedSignal {\n const err = c.capture.error();\n return {\n captured_at: new Date().toISOString(),\n route: c.capture.route(),\n client_label: c.capture.label(),\n trail: c.capture.trail(),\n session_ref: c.sessionRef,\n trigger,\n intent_hint: c.harvest.lastIntentHint(),\n error: err,\n outcome: err || trigger === \"friction\" ? \"failed\" : \"unknown\",\n ...extra,\n };\n}\n\nasync function maybePrompt(c: Controller, trigger: \"boundary\" | \"friction\") {\n const now = Date.now();\n if (canPrompt(c.fatigue, now, DEFAULT_CAPS)) {\n c.fatigue.promptsShown += 1;\n c.fatigue.lastPromptAt = now;\n try {\n const { showPrompt } = await import(\"./prompt\");\n const result = await showPrompt({ candidates: deriveCandidates(c) });\n c.egress.enqueue(\n buildSignal(c, trigger, {\n answer: result.answer,\n verbatim: result.verbatim,\n intent_hint: result.intent ?? c.harvest.lastIntentHint(),\n outcome: result.answer === \"yes\" ? \"achieved\" : \"failed\",\n }),\n );\n } catch {\n // Prompt failed to load/show — still emit the passive Signal (FR-7).\n c.egress.enqueue(buildSignal(c, trigger));\n }\n } else {\n // Fatigued: keep the silent-capture property — emit without asking (FR-7).\n c.egress.enqueue(buildSignal(c, trigger));\n }\n}\n\nfunction onCaptureEvent() {\n const c = ctrl;\n if (!c || !c.running) return;\n if (c.eventTimer !== null) return; // debounce a burst of events into one check\n c.eventTimer = (typeof window !== \"undefined\" ? window.setTimeout : setTimeout)(() => {\n c.eventTimer = null;\n try {\n const now = Date.now();\n if (now - c.lastFrictionEmitAt < FRICTION_EMIT_COOLDOWN_MS) return;\n const kind = detectFriction(c.capture.trail(), now);\n if (!kind) return;\n c.lastFrictionEmitAt = now;\n void maybePrompt(c, \"friction\");\n } catch {\n /* swallow */\n }\n }, EVENT_DEBOUNCE_MS) as unknown as number;\n}\n\nfunction onExitIntent(ev: MouseEvent) {\n const c = ctrl;\n if (!c || !c.running || !c.config.boundaryAsk) return;\n try {\n if (ev.clientY <= 0) void maybePrompt(c, \"boundary\");\n } catch {\n /* swallow */\n }\n}\n\nfunction startRuntime(c: Controller) {\n if (c.running) return;\n if (c.suppressed) {\n if (c.config.debug)\n console.debug(\n \"[sightspool] capture suppressed on localhost (set captureOnLocalhost:true to override)\",\n );\n return;\n }\n c.running = true;\n c.capture.start();\n c.harvest.start();\n c.egress.start();\n c.capture.onEvent(onCaptureEvent);\n try {\n document.addEventListener(\"mouseout\", onExitIntent);\n } catch {\n /* swallow */\n }\n if (c.config.debug) console.debug(\"[sightspool] started\", c.sessionRef);\n}\n\n// --- public API --------------------------------------------------------------\n\nexport function init(config: SightspoolConfig): void {\n try {\n if (!config || !config.key) {\n console.warn(\"[sightspool] init: a `key` is required\");\n return;\n }\n if (ctrl) return; // already initialised\n const endpoint = config.endpoint || DEFAULT_ENDPOINT;\n const privacyOpts = { redact: config.redact, block: config.block };\n const capture = createCapture({ debug: !!config.debug, ...privacyOpts });\n const harvest = createHarvest(capture, { debug: !!config.debug, ...privacyOpts });\n const egress = createEgress({ key: config.key, endpoint, debug: !!config.debug });\n ctrl = {\n config: {\n ...config,\n key: config.key,\n endpoint,\n boundaryAsk: config.boundaryAsk !== false,\n debug: !!config.debug,\n },\n capture,\n harvest,\n egress,\n identity: {},\n sessionRef: uuid(),\n fatigue: { promptsShown: 0, lastPromptAt: null },\n lastFrictionEmitAt: 0,\n eventTimer: null,\n running: false,\n suppressed: isLocalhost(currentHostname()) && config.captureOnLocalhost !== true,\n };\n if (config.consent !== false) startRuntime(ctrl);\n } catch (err) {\n // init itself must never throw into the host.\n try {\n console.warn(\"[sightspool] init failed\", err);\n } catch {\n /* swallow */\n }\n }\n}\n\nexport function identify(userId: string, traits?: { account?: string; plan?: string }): void {\n try {\n if (!ctrl) return;\n ctrl.identity = { userId, account: traits?.account, plan: traits?.plan };\n ctrl.egress.setIdentity(ctrl.identity);\n } catch {\n /* swallow */\n }\n}\n\n/** Begin capture if init was called with { consent: false }. */\nexport function start(): void {\n try {\n if (ctrl) startRuntime(ctrl);\n } catch {\n /* swallow */\n }\n}\n\n/**\n * Runtime consent gate (a clean toggle over start()/stop()) — wire it to your cookie\n * banner: `Sightspool.consent(true)` resumes capture, `Sightspool.consent(false)`\n * pauses and flushes. Pairs with init `{ consent: false }` to stay dark until granted.\n */\nexport function consent(granted: boolean): void {\n try {\n if (!ctrl) return;\n if (granted) startRuntime(ctrl);\n else stop();\n } catch {\n /* swallow */\n }\n}\n\n/** Pause capture and flush whatever's queued. */\nexport function stop(): void {\n try {\n if (!ctrl) return;\n ctrl.running = false;\n ctrl.capture.stop();\n ctrl.harvest.stop();\n ctrl.egress.stop();\n try {\n document.removeEventListener(\"mouseout\", onExitIntent);\n } catch {\n /* swallow */\n }\n } catch {\n /* swallow */\n }\n}\n\nconst api = { init, identify, start, stop, consent };\nexport default api;\n\n// --- script-tag auto-init ----------------------------------------------------\n// The standalone <script data-sightspool-key=\"pk_…\"> install auto-boots from its\n// own tag's data attributes. (No-op for the ESM build: module scripts have no\n// document.currentScript, so bundler consumers always call init() themselves.)\ntry {\n if (typeof document !== \"undefined\") {\n // currentScript is null for async/defer/dynamically-injected scripts (e.g.\n // Next's <Script> component), so fall back to finding our tag by attribute.\n const el =\n (document.currentScript as HTMLScriptElement | null) ??\n document.querySelector<HTMLScriptElement>(\"script[data-sightspool-key]\");\n const key = el?.getAttribute(\"data-sightspool-key\");\n if (key) {\n // Default the ingest endpoint to where the bundle was served from — the app\n // serves /sdk.global.js, so a same-origin script install needs only the key.\n // An explicit data-sightspool-endpoint still wins (e.g. a CDN-hosted bundle).\n let endpoint = el?.getAttribute(\"data-sightspool-endpoint\") || undefined;\n if (!endpoint && el?.src) {\n try {\n endpoint = new URL(el.src).origin;\n } catch {\n /* keep the built-in default */\n }\n }\n // Comma-separated CSS selectors → string[] (the script-tag equivalent of the\n // init() arrays; bundler users pass arrays directly).\n const list = (attr: string): string[] | undefined => {\n const raw = el?.getAttribute(attr);\n if (!raw) return undefined;\n const out = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return out.length ? out : undefined;\n };\n init({\n key,\n endpoint,\n redact: list(\"data-sightspool-redact\"),\n block: list(\"data-sightspool-block\"),\n captureOnLocalhost: el?.hasAttribute(\"data-sightspool-capture-localhost\") || undefined,\n debug: el?.hasAttribute(\"data-sightspool-debug\") || undefined,\n });\n }\n }\n} catch {\n /* swallow */\n}\n"]}
1
+ {"version":3,"sources":["../src/privacy.ts","../src/prompt.ts","../src/survey.ts","../src/capture.ts","../src/harvest.ts","../src/egress.ts","../src/triggers.ts","../src/intervention.ts","../src/env.ts","../src/index.ts"],"names":["redactText","input","EMAIL_RE","LONG_DIGITS_RE","safeClosest","el","selector","e","isIgnoredElement","blockSelectors","IGNORE_ATTR","sel","matchesRedactSelector","redactSelectors","ATTACH_DISCLOSURE","REDACTED","init_privacy","__esmMin","prompt_exports","__export","showPrompt","opts","resolve","settled","host","shadow","finish","result","style","STYLE","wrap","render","node","card","x","disc","stateA","q","row","yes","no","stateB","c","b","se","stateText","submit","init_prompt","survey_exports","showSurvey","config","teardown","thank","thankYou","withClose","question","_a","_b","_c","opt","freeText","send","text","p","init_survey","TRAIL_MAX","DEAD_CLICK_MS","RAGE_WINDOW_MS","RAGE_COUNT","hasDom","createCapture","buf","lastError","started","subs","cleanups","recentClicks","notify","cb","push","type","label","currentRoute","currentLabel","onClick","ev","target","t","ts","isRage","routeBefore","mutated","observer","onError","onRejection","reason","installRouteTracking","fire","origPush","origReplace","args","r","installFetchTracking","orig","res","err","query","zeroResult","SEARCH_HINT_RE","DEBOUNCE_MS","looksLikeSearch","role","hay","createHarvest","capture","hint","timer","onInput","value","createEgress","queue","identity","interval","url","signals","body","json","blob","onVisibility","flush","batch","signal","next","detectFriction","trail","now","windowMs","recent","clicks","i","byLabel","n","DEFAULT_CAPS","canPrompt","state","caps","RENDERABLE","str","v","max","buildServeContext","route","ctx","account","plan","normalizeServed","raw","id","cfg","options","o","pickRespondentKey","userId","persisted","sessionRef","uid","RK_STORAGE_KEY","getRespondentKey","serveUrl","endpoint","path","fetchIntervention","data","served","submitResponse","LOCAL_HOSTS","isLocalhost","hostname","h","DEFAULT_ENDPOINT","FRICTION_EMIT_COOLDOWN_MS","EVENT_DEBOUNCE_MS","SERVE_SETTLE_MS","MAX_INTERVENTIONS_PER_SESSION","currentHostname","ctrl","uuid","deriveCandidates","out","buildSignal","trigger","extra","maybePrompt","maybeServeIntervention","respondentKey","onCaptureEvent","onExitIntent","startRuntime","init","privacyOpts","harvest","egress","identify","traits","start","consent","granted","stop","api","src_default","key","list","attr","s"],"mappings":"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","file":"sdk.global.js","sourcesContent":["// Redaction — mask sensitive text before it ever leaves the page (GOV-3). The\n// pure string helpers are unit-tested; the DOM-querying part (selector masking)\n// lives in capture.ts and calls in here.\n\nconst EMAIL_RE = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g;\nconst LONG_DIGITS_RE = /\\d{6,}/g; // card / account-number-ish runs\n\nexport const MAX_LABEL_LEN = 280;\n\n/**\n * Mask PII-ish substrings in a captured label/verbatim and clamp length.\n * Conservative: emails and long digit runs become placeholders. Never throws.\n */\nexport function redactText(input: string | null | undefined): string {\n if (!input) return \"\";\n try {\n return String(input)\n .replace(EMAIL_RE, \"‹email›\")\n .replace(LONG_DIGITS_RE, \"‹num›\")\n .replace(/\\s+/g, \" \")\n .trim()\n .slice(0, MAX_LABEL_LEN);\n } catch {\n return \"\";\n }\n}\n\n/** Should a captured element's value be dropped entirely (not just masked)? */\nexport function isSensitiveInput(type: string | null | undefined): boolean {\n const t = (type ?? \"\").toLowerCase();\n return t === \"password\" || t === \"email\" || t === \"tel\" || t === \"creditcard\";\n}\n\nexport const ATTACH_DISCLOSURE = \"Session and account attached automatically.\";\n\n/** Placeholder substituted for the text of a `redact`-matched element (GOV-3). */\nexport const REDACTED = \"‹redacted›\";\n\n/** The per-element opt-out attribute: a click/input inside `[data-sightspool-ignore]` is dropped entirely. */\nexport const IGNORE_ATTR = \"data-sightspool-ignore\";\n\n/** Anything with a `.closest(selector)` — the bit of Element we depend on (kept DOM-free for unit tests). */\ntype Closeable = { closest?: (selectors: string) => unknown };\n\nfunction safeClosest(el: Closeable, selector: string): boolean {\n try {\n return typeof el.closest === \"function\" && el.closest(selector) != null;\n } catch {\n // An invalid selector (host misconfig) must never throw into capture — and must\n // never *accidentally capture* what was meant to be excluded: treat as no-match\n // for that one selector and let the others decide.\n return false;\n }\n}\n\n/**\n * Should this element's events be dropped entirely (not just masked)? True when the\n * element — or any ancestor — carries `data-sightspool-ignore` or matches one of the\n * configured `block` selectors. The host's hard privacy opt-out (GOV-3).\n */\nexport function isIgnoredElement(\n el: Closeable | null | undefined,\n blockSelectors: readonly string[] = [],\n): boolean {\n if (!el || typeof el.closest !== \"function\") return false;\n if (safeClosest(el, `[${IGNORE_ATTR}]`)) return true;\n for (const sel of blockSelectors) {\n if (sel && safeClosest(el, sel)) return true;\n }\n return false;\n}\n\n/**\n * Should this element's captured text be masked wholesale? True when the element —\n * or any ancestor — matches one of the configured `redact` selectors. (The event is\n * still recorded; only its label becomes {@link REDACTED}.)\n */\nexport function matchesRedactSelector(\n el: Closeable | null | undefined,\n redactSelectors: readonly string[] = [],\n): boolean {\n if (!el || typeof el.closest !== \"function\") return false;\n for (const sel of redactSelectors) {\n if (sel && safeClosest(el, sel)) return true;\n }\n return false;\n}\n","// The prompt UI (FR-5/6, the §16.2 blend) — rendered in a shadow root so the host\n// app's CSS can't style-break it and it leaks zero styles back. This module is\n// dynamically imported by index.ts only when a trigger fires, so it splits into a\n// lazily-loaded chunk and adds nothing to the host bundle until needed.\n//\n// State A — \"Were you able to do what you came here to do today?\" [Yes][Not really]\n// State B — (after \"Not really\") top candidate goals + an always-present\n// \"Something else\" → optional free text only after that.\n\nimport type { SignalAnswer } from \"./types\";\nimport { ATTACH_DISCLOSURE } from \"./privacy\";\n\nexport type PromptResult = {\n answer: SignalAnswer;\n intent?: string; // a tapped candidate\n verbatim?: string; // free text from \"Something else\"\n};\n\nexport type PromptOptions = {\n /** Locally-derived candidate goals (FR-5 State B). May be empty → generic ask. */\n candidates: string[];\n};\n\nconst STYLE = `\n:host { all: initial; }\n.wrap { position: fixed; bottom: 20px; right: 20px; z-index: 2147483000;\n width: 320px; max-width: calc(100vw - 32px); font-family: system-ui, -apple-system, sans-serif; }\n.card { background: #fff; color: #18181b; border: 1px solid #e4e4e7; border-radius: 12px;\n box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 16px; }\n.q { font-size: 14px; font-weight: 600; margin: 0 0 12px; line-height: 1.35; }\n.row { display: flex; gap: 8px; flex-wrap: wrap; }\nbutton { font: inherit; font-size: 13px; cursor: pointer; border-radius: 8px; padding: 8px 12px;\n border: 1px solid #e4e4e7; background: #fafafa; color: #18181b; }\nbutton:hover { background: #f4f4f5; }\nbutton.primary { background: #18181b; color: #fff; border-color: #18181b; }\n.cand { display: block; width: 100%; text-align: left; margin-bottom: 6px; }\n.disc { font-size: 11px; color: #71717a; margin: 12px 0 0; }\n.x { position: absolute; top: 8px; right: 10px; border: none; background: none; font-size: 16px;\n color: #a1a1aa; padding: 2px 6px; }\ninput { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; padding: 8px 10px;\n border: 1px solid #e4e4e7; border-radius: 8px; margin-bottom: 8px; }\n`;\n\nexport function showPrompt(opts: PromptOptions): Promise<PromptResult> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\") {\n resolve({ answer: \"dismissed\" });\n return;\n }\n\n let settled = false;\n const host = document.createElement(\"div\");\n const shadow = host.attachShadow({ mode: \"open\" });\n\n function finish(result: PromptResult) {\n if (settled) return;\n settled = true;\n try {\n host.remove();\n } catch {\n /* swallow */\n }\n resolve(result);\n }\n\n const style = document.createElement(\"style\");\n style.textContent = STYLE;\n shadow.appendChild(style);\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n shadow.appendChild(wrap);\n\n function render(node: HTMLElement) {\n wrap.innerHTML = \"\";\n const card = document.createElement(\"div\");\n card.className = \"card\";\n card.style.position = \"relative\";\n const x = document.createElement(\"button\");\n x.className = \"x\";\n x.textContent = \"×\";\n x.setAttribute(\"aria-label\", \"Dismiss\");\n x.onclick = () => finish({ answer: \"dismissed\" });\n card.appendChild(x);\n card.appendChild(node);\n const disc = document.createElement(\"p\");\n disc.className = \"disc\";\n disc.textContent = ATTACH_DISCLOSURE;\n card.appendChild(disc);\n wrap.appendChild(card);\n }\n\n // --- State A ---\n function stateA() {\n const node = document.createElement(\"div\");\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = \"Were you able to do what you came here to do today?\";\n node.appendChild(q);\n const row = document.createElement(\"div\");\n row.className = \"row\";\n const yes = document.createElement(\"button\");\n yes.className = \"primary\";\n yes.textContent = \"Yes\";\n yes.onclick = () => finish({ answer: \"yes\" });\n const no = document.createElement(\"button\");\n no.textContent = \"Not really\";\n no.onclick = () => stateB();\n row.append(yes, no);\n node.appendChild(row);\n render(node);\n }\n\n // --- State B ---\n function stateB() {\n const node = document.createElement(\"div\");\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = \"What were you trying to do?\";\n node.appendChild(q);\n for (const c of opts.candidates.slice(0, 4)) {\n const b = document.createElement(\"button\");\n b.className = \"cand\";\n b.textContent = c;\n b.onclick = () => finish({ answer: \"not_really\", intent: c });\n node.appendChild(b);\n }\n const se = document.createElement(\"button\");\n se.className = \"cand\";\n se.textContent = \"Something else…\";\n se.onclick = () => stateText();\n node.appendChild(se);\n render(node);\n }\n\n // --- \"Something else\" free text ---\n function stateText() {\n const node = document.createElement(\"div\");\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = \"What were you trying to do?\";\n node.appendChild(q);\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.placeholder = \"In your own words…\";\n node.appendChild(input);\n const row = document.createElement(\"div\");\n row.className = \"row\";\n const submit = document.createElement(\"button\");\n submit.className = \"primary\";\n submit.textContent = \"Send\";\n submit.onclick = () =>\n finish({ answer: \"not_really\", verbatim: input.value.trim() || undefined });\n row.appendChild(submit);\n node.appendChild(row);\n render(node);\n try {\n input.focus();\n } catch {\n /* swallow */\n }\n }\n\n try {\n document.body.appendChild(host);\n stateA();\n } catch {\n finish({ answer: \"dismissed\" });\n }\n });\n}\n","// The intervention survey widget (Wave 0005 slice B — the client half). Renders a\n// human-approved one-tap survey served by /api/sdk/serve, in a shadow root so the\n// host app's CSS can't style-break it and it leaks zero styles back. Dynamically\n// imported by index.ts only when the serve endpoint actually returns something, so\n// it splits into its own lazily-loaded chunk and adds nothing to the host bundle\n// until a survey is shown. Mirrors prompt.ts (the passive ask) deliberately.\n//\n// question + [option] [option] … (tap an option → choice)\n// + \"Something else…\" → free text (only when allow_text)\n\nexport type SurveyConfig = {\n question: string;\n options?: string[];\n allow_text?: boolean;\n};\n\nexport type SurveyResult = {\n choice?: string;\n text?: string;\n dismissed?: boolean;\n};\n\nconst STYLE = `\n:host { all: initial; }\n.wrap { position: fixed; bottom: 20px; right: 20px; z-index: 2147483000;\n width: 340px; max-width: calc(100vw - 32px); font-family: system-ui, -apple-system, sans-serif; }\n.card { position: relative; background: #fff; color: #18181b; border: 1px solid #e4e4e7;\n border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 16px; }\n.q { font-size: 14px; font-weight: 600; margin: 0 0 12px; line-height: 1.35; padding-right: 16px; }\n.row { display: flex; gap: 8px; flex-wrap: wrap; }\nbutton { font: inherit; font-size: 13px; cursor: pointer; border-radius: 8px; padding: 8px 12px;\n border: 1px solid #e4e4e7; background: #fafafa; color: #18181b; }\nbutton:hover { background: #f4f4f5; }\nbutton.primary { background: #18181b; color: #fff; border-color: #18181b; }\n.opt { display: block; width: 100%; text-align: left; margin-bottom: 6px; }\n.x { position: absolute; top: 8px; right: 10px; border: none; background: none; font-size: 16px;\n color: #a1a1aa; padding: 2px 6px; cursor: pointer; }\n.done { font-size: 13px; color: #18181b; margin: 0; }\ninput { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; padding: 8px 10px;\n border: 1px solid #e4e4e7; border-radius: 8px; margin-bottom: 8px; }\n`;\n\nconst THANKS_MS = 1100; // brief acknowledgement, then auto-close\n\nexport function showSurvey(config: SurveyConfig): Promise<SurveyResult> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\") {\n resolve({ dismissed: true });\n return;\n }\n\n let settled = false;\n const host = document.createElement(\"div\");\n const shadow = host.attachShadow({ mode: \"open\" });\n\n function teardown() {\n try {\n host.remove();\n } catch {\n /* swallow */\n }\n }\n\n // Resolve immediately (so the answer is sent without delay) but leave a short\n // \"Thanks\" on screen before removing the node.\n function finish(result: SurveyResult, thank: boolean) {\n if (settled) return;\n settled = true;\n resolve(result);\n if (thank) {\n thankYou();\n setTimeout(teardown, THANKS_MS);\n } else {\n teardown();\n }\n }\n\n const style = document.createElement(\"style\");\n style.textContent = STYLE;\n shadow.appendChild(style);\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n shadow.appendChild(wrap);\n\n function card(): HTMLElement {\n wrap.innerHTML = \"\";\n const c = document.createElement(\"div\");\n c.className = \"card\";\n wrap.appendChild(c);\n return c;\n }\n\n function withClose(c: HTMLElement) {\n const x = document.createElement(\"button\");\n x.className = \"x\";\n x.textContent = \"×\";\n x.setAttribute(\"aria-label\", \"Dismiss\");\n x.onclick = () => finish({ dismissed: true }, false);\n c.appendChild(x);\n }\n\n function question() {\n const c = card();\n withClose(c);\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = config.question;\n c.appendChild(q);\n\n for (const opt of (config.options ?? []).slice(0, 6)) {\n const b = document.createElement(\"button\");\n b.className = \"opt\";\n b.textContent = opt;\n b.onclick = () => finish({ choice: opt }, true);\n c.appendChild(b);\n }\n\n if (config.allow_text) {\n const se = document.createElement(\"button\");\n se.className = \"opt\";\n // If there were no options, this is the only path — label it plainly.\n se.textContent = (config.options?.length ?? 0) > 0 ? \"Something else…\" : \"Answer…\";\n se.onclick = freeText;\n c.appendChild(se);\n }\n }\n\n function freeText() {\n const c = card();\n withClose(c);\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = config.question;\n c.appendChild(q);\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.placeholder = \"In your own words…\";\n c.appendChild(input);\n const row = document.createElement(\"div\");\n row.className = \"row\";\n const send = document.createElement(\"button\");\n send.className = \"primary\";\n send.textContent = \"Send\";\n const submit = () => {\n const text = input.value.trim();\n if (!text) {\n finish({ dismissed: true }, false);\n return;\n }\n finish({ text }, true);\n };\n send.onclick = submit;\n input.onkeydown = (e) => {\n if ((e as KeyboardEvent).key === \"Enter\") submit();\n };\n row.appendChild(send);\n c.appendChild(row);\n try {\n input.focus();\n } catch {\n /* swallow */\n }\n }\n\n function thankYou() {\n const c = card();\n const p = document.createElement(\"p\");\n p.className = \"done\";\n p.textContent = \"Thanks — that helps.\";\n c.appendChild(p);\n }\n\n try {\n document.body.appendChild(host);\n question();\n } catch {\n finish({ dismissed: true }, false);\n }\n });\n}\n","// Passive context capture (FR-2) — the buffer of route/click/error events the\n// rest of the runtime reads. All DOM access is guarded and wrapped: this module\n// must never throw into the host app (NFR-3).\n\nimport type { TrailEvent, TrailEventType } from \"./types\";\nimport { redactText, isIgnoredElement, matchesRedactSelector, REDACTED } from \"./privacy\";\n\nconst TRAIL_MAX = 30;\nconst DEAD_CLICK_MS = 700; // a click with no DOM/route change after this = dead-click\nconst RAGE_WINDOW_MS = 1_000;\nconst RAGE_COUNT = 3;\n\nexport type CaptureHandle = {\n start(): void;\n stop(): void;\n trail(): TrailEvent[];\n route(): string;\n label(): string;\n error(): string | undefined;\n /** Subscribe to \"a meaningful event happened\" (the trigger engine polls off this). */\n onEvent(cb: () => void): void;\n /** Called by harvest.ts when a search/filter query is typed. */\n recordSearch(query: string, zeroResult?: boolean): void;\n};\n\nfunction hasDom(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nexport function createCapture(opts: {\n debug: boolean;\n redact?: readonly string[];\n block?: readonly string[];\n}): CaptureHandle {\n const redactSelectors = opts.redact ?? [];\n const blockSelectors = opts.block ?? [];\n let buf: TrailEvent[] = [];\n let lastError: string | undefined;\n let started = false;\n const subs: Array<() => void> = [];\n const cleanups: Array<() => void> = [];\n let recentClicks: number[] = []; // timestamps, for rage detection\n\n function notify() {\n for (const cb of subs) {\n try {\n cb();\n } catch {\n /* a subscriber must never break capture */\n }\n }\n }\n\n function push(type: TrailEventType, label?: string) {\n try {\n buf.push({ t: Date.now(), type, label: label ? redactText(label) : undefined });\n if (buf.length > TRAIL_MAX) buf = buf.slice(-TRAIL_MAX);\n if (opts.debug) console.debug(\"[sightspool] event\", type, label);\n notify();\n } catch {\n /* swallow */\n }\n }\n\n function currentRoute(): string {\n try {\n return location.pathname + location.search;\n } catch {\n return \"\";\n }\n }\n\n function currentLabel(): string {\n try {\n return document.title || \"\";\n } catch {\n return \"\";\n }\n }\n\n function onClick(ev: MouseEvent) {\n try {\n const target = ev.target as Element | null;\n // Hard opt-out: a click inside [data-sightspool-ignore] or a `block` selector is\n // never recorded — not even as an unlabelled event (GOV-3).\n if (isIgnoredElement(target, blockSelectors)) return;\n const text =\n (target && (target.getAttribute?.(\"aria-label\") || target.textContent)) || \"\";\n // `redact` selectors mask the label wholesale; emails/digits in any label are\n // also masked by push() → redactText.\n const label = matchesRedactSelector(target, redactSelectors)\n ? REDACTED\n : text.trim().slice(0, 60);\n const t = Date.now();\n\n recentClicks = recentClicks.filter((ts) => t - ts <= RAGE_WINDOW_MS);\n recentClicks.push(t);\n const isRage = recentClicks.length >= RAGE_COUNT;\n push(isRage ? \"rage_click\" : \"click\", label);\n\n // dead-click: did anything change shortly after? watch for a DOM mutation or\n // a route change; if neither, record a dead_click.\n const routeBefore = currentRoute();\n let mutated = false;\n let observer: MutationObserver | null = null;\n try {\n observer = new MutationObserver(() => {\n mutated = true;\n });\n observer.observe(document.body, { childList: true, subtree: true, attributes: true });\n } catch {\n /* no MutationObserver — skip dead-click detection */\n }\n window.setTimeout(() => {\n try {\n observer?.disconnect();\n if (!mutated && currentRoute() === routeBefore && label) {\n push(\"dead_click\", label);\n }\n } catch {\n /* swallow */\n }\n }, DEAD_CLICK_MS);\n } catch {\n /* swallow */\n }\n }\n\n function onError(ev: ErrorEvent) {\n try {\n lastError = String(ev.message || \"error\");\n push(\"error\", lastError);\n } catch {\n /* swallow */\n }\n }\n\n function onRejection(ev: PromiseRejectionEvent) {\n try {\n const reason = ev.reason;\n lastError = reason instanceof Error ? reason.message : String(reason);\n push(\"error\", lastError);\n } catch {\n /* swallow */\n }\n }\n\n // Route changes: patch history.pushState/replaceState + listen for popstate.\n function installRouteTracking() {\n try {\n const fire = () => push(\"route\", currentRoute());\n const origPush = history.pushState;\n const origReplace = history.replaceState;\n history.pushState = function (this: History, ...args: Parameters<History[\"pushState\"]>) {\n const r = origPush.apply(this, args);\n fire();\n return r;\n };\n history.replaceState = function (\n this: History,\n ...args: Parameters<History[\"replaceState\"]>\n ) {\n const r = origReplace.apply(this, args);\n fire();\n return r;\n };\n window.addEventListener(\"popstate\", fire);\n cleanups.push(() => {\n history.pushState = origPush;\n history.replaceState = origReplace;\n window.removeEventListener(\"popstate\", fire);\n });\n push(\"route\", currentRoute()); // seed with the entry route\n } catch {\n /* swallow */\n }\n }\n\n // Light fetch wrapper to catch failed/4xx-5xx requests as request_error events.\n function installFetchTracking() {\n try {\n if (typeof window.fetch !== \"function\") return;\n const orig = window.fetch.bind(window);\n window.fetch = async (...args: Parameters<typeof fetch>) => {\n try {\n const res = await orig(...args);\n if (!res.ok) push(\"request_error\", `HTTP ${res.status}`);\n return res;\n } catch (err) {\n push(\"request_error\", err instanceof Error ? err.message : \"network error\");\n throw err;\n }\n };\n cleanups.push(() => {\n window.fetch = orig;\n });\n } catch {\n /* swallow */\n }\n }\n\n return {\n start() {\n if (started || !hasDom()) return;\n started = true;\n try {\n document.addEventListener(\"click\", onClick, true);\n window.addEventListener(\"error\", onError);\n window.addEventListener(\"unhandledrejection\", onRejection);\n cleanups.push(() => {\n document.removeEventListener(\"click\", onClick, true);\n window.removeEventListener(\"error\", onError);\n window.removeEventListener(\"unhandledrejection\", onRejection);\n });\n installRouteTracking();\n installFetchTracking();\n } catch {\n /* swallow */\n }\n },\n stop() {\n started = false;\n for (const c of cleanups.splice(0)) {\n try {\n c();\n } catch {\n /* swallow */\n }\n }\n },\n trail() {\n return buf.slice();\n },\n route: currentRoute,\n label: currentLabel,\n error() {\n return lastError;\n },\n onEvent(cb) {\n subs.push(cb);\n },\n recordSearch(query, zeroResult) {\n const q = query.trim();\n if (!q) return;\n push(zeroResult ? \"zero_result\" : \"search\", q);\n },\n };\n}\n","// Intent harvest (FR-3) — treat typed queries in search / filter / command-palette\n// / empty-state inputs as STATED intent (the highest-signal intent, no question\n// needed). Harvesting precedes any inference. Defensive throughout (NFR-3).\n//\n// Zero-result detection is genuinely cross-app-specific and best-effort in v1: we\n// capture the query as a search event; flagging it as zero-result reliably is a\n// follow-up (it needs per-app empty-state hints). The query itself is the value.\n\nimport type { CaptureHandle } from \"./capture\";\nimport { isIgnoredElement, matchesRedactSelector } from \"./privacy\";\n\nconst SEARCH_HINT_RE = /search|filter|find|query|command|lookup/i;\nconst DEBOUNCE_MS = 800;\n\nexport type HarvestHandle = {\n start(): void;\n stop(): void;\n /** The most recent stated intent (last search/filter query), for State-B candidates. */\n lastIntentHint(): string | undefined;\n};\n\nfunction looksLikeSearch(el: Element): boolean {\n try {\n const input = el as HTMLInputElement;\n if (input.type === \"search\") return true;\n const role = el.getAttribute(\"role\") || \"\";\n if (role === \"searchbox\" || role === \"combobox\") return true;\n const hay = [\n input.name,\n input.placeholder,\n el.getAttribute(\"aria-label\"),\n el.id,\n el.className,\n ]\n .filter(Boolean)\n .join(\" \");\n return SEARCH_HINT_RE.test(hay);\n } catch {\n return false;\n }\n}\n\nexport function createHarvest(\n capture: CaptureHandle,\n opts: { debug: boolean; redact?: readonly string[]; block?: readonly string[] },\n): HarvestHandle {\n let hint: string | undefined;\n let timer: number | null = null;\n let started = false;\n const redactSelectors = opts.redact ?? [];\n const blockSelectors = opts.block ?? [];\n\n function onInput(ev: Event) {\n try {\n const target = ev.target as HTMLInputElement | null;\n if (!target || (target.tagName !== \"INPUT\" && target.tagName !== \"TEXTAREA\")) return;\n if (!looksLikeSearch(target)) return;\n // A masked query is useless intent, so a `redact`-matched search box is treated\n // as a hard opt-out here (same as `block`/ignore): don't harvest the value at all.\n if (isIgnoredElement(target, blockSelectors) || matchesRedactSelector(target, redactSelectors))\n return;\n const value = (target.value || \"\").trim();\n if (value.length < 2) return;\n\n if (timer !== null) window.clearTimeout(timer);\n timer = window.setTimeout(() => {\n hint = value;\n capture.recordSearch(value);\n if (opts.debug) console.debug(\"[sightspool] harvested intent\", value);\n }, DEBOUNCE_MS);\n } catch {\n /* swallow */\n }\n }\n\n return {\n start() {\n if (started || typeof document === \"undefined\") return;\n started = true;\n try {\n document.addEventListener(\"input\", onInput, true);\n } catch {\n /* swallow */\n }\n },\n stop() {\n started = false;\n try {\n document.removeEventListener(\"input\", onInput, true);\n if (timer !== null) window.clearTimeout(timer);\n } catch {\n /* swallow */\n }\n },\n lastIntentHint() {\n return hint;\n },\n };\n}\n","// Egress — batch captured Signals and ship them to /api/sdk/ingest, preferring\n// navigator.sendBeacon (survives page unload) with a fetch+keepalive fallback.\n// Every path is wrapped: a failed send must never surface in the host app (NFR-3),\n// and a Signal already records its why/cost passively, so a dropped beacon just\n// loses enrichment, not the capture's value (FR-7).\n\nimport type { CapturedSignal, Identity, IngestBody } from \"./types\";\n\nconst FLUSH_BATCH = 10; // flush when this many Signals are queued\nconst FLUSH_INTERVAL_MS = 15_000;\n\nexport type EgressHandle = {\n start(): void;\n stop(): void;\n enqueue(signal: CapturedSignal): void;\n flush(): void;\n setIdentity(identity: Identity): void;\n};\n\nexport function createEgress(opts: {\n key: string;\n endpoint: string;\n debug: boolean;\n}): EgressHandle {\n let queue: CapturedSignal[] = [];\n let identity: Identity | undefined;\n let interval: number | null = null;\n let started = false;\n\n const url = `${opts.endpoint.replace(/\\/+$/, \"\")}/api/sdk/ingest`;\n\n function send(signals: CapturedSignal[]) {\n if (signals.length === 0) return;\n const body: IngestBody = { key: opts.key, identity, signals };\n const json = JSON.stringify(body);\n try {\n // text/plain is a CORS-safelisted content type, so a cross-origin beacon\n // skips the preflight entirely (the host app's domain ≠ ours). The server\n // parses the text as JSON regardless.\n if (typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const blob = new Blob([json], { type: \"text/plain\" });\n const ok = navigator.sendBeacon(url, blob);\n if (ok) {\n if (opts.debug) console.debug(\"[sightspool] beacon\", signals.length);\n return;\n }\n }\n // Fallback: fetch with keepalive so it can outlive the page.\n void fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain\" },\n body: json,\n keepalive: true,\n mode: \"cors\",\n credentials: \"omit\",\n }).catch(() => {\n /* swallow — drop on failure */\n });\n } catch {\n /* swallow */\n }\n }\n\n function onVisibility() {\n try {\n if (document.visibilityState === \"hidden\") flush();\n } catch {\n /* swallow */\n }\n }\n\n function flush() {\n if (queue.length === 0) return;\n const batch = queue;\n queue = [];\n send(batch);\n }\n\n return {\n start() {\n if (started || typeof window === \"undefined\") return;\n started = true;\n try {\n document.addEventListener(\"visibilitychange\", onVisibility);\n window.addEventListener(\"pagehide\", flush);\n interval = window.setInterval(flush, FLUSH_INTERVAL_MS);\n } catch {\n /* swallow */\n }\n },\n stop() {\n started = false;\n try {\n document.removeEventListener(\"visibilitychange\", onVisibility);\n window.removeEventListener(\"pagehide\", flush);\n if (interval !== null) window.clearInterval(interval);\n } catch {\n /* swallow */\n }\n flush();\n },\n enqueue(signal) {\n queue.push(signal);\n if (queue.length >= FLUSH_BATCH) flush();\n },\n flush,\n setIdentity(next) {\n identity = next;\n },\n };\n}\n","// Trigger + fatigue logic (FR-4, NFR-2) — the make-or-break craft surface.\n//\n// Kept PURE (no DOM) so it unit-tests cleanly under `node --test` and so the\n// heuristics can be tuned against real traffic later without touching the capture\n// wiring. Detection quality is the primary failure mode (false positives that\n// pester users), so the defaults are deliberately conservative.\n\nimport type { TrailEvent } from \"./types\";\n\nexport const RAGE_CLICK_COUNT = 3; // clicks…\nexport const RAGE_WINDOW_MS = 1_000; // …within this window form a rage cluster\nexport const FRICTION_RETRY_COUNT = 3; // repeated identical actions = retry frustration\nexport const FRICTION_WINDOW_MS = 8_000; // how far back a friction scan looks\n\nexport type FrictionKind = \"error\" | \"rage\" | \"dead_end\" | \"retry\";\n\n/**\n * Scan the recent trail for a friction moment. Returns the strongest kind found,\n * or null. Order = severity: a real error beats a rage cluster beats a dead-end\n * beats repeated retries.\n */\nexport function detectFriction(\n trail: TrailEvent[],\n now: number,\n windowMs = FRICTION_WINDOW_MS,\n): FrictionKind | null {\n const recent = trail.filter((e) => now - e.t <= windowMs);\n\n if (recent.some((e) => e.type === \"error\" || e.type === \"request_error\")) return \"error\";\n\n const clicks = recent.filter((e) => e.type === \"click\" || e.type === \"rage_click\");\n for (let i = 0; i < clicks.length; i++) {\n const burst = clicks.filter(\n (e) => e.t >= clicks[i].t && e.t - clicks[i].t <= RAGE_WINDOW_MS,\n );\n if (burst.length >= RAGE_CLICK_COUNT) return \"rage\";\n }\n\n if (recent.some((e) => e.type === \"dead_click\")) return \"dead_end\";\n\n const byLabel = new Map<string, number>();\n for (const e of clicks) {\n if (!e.label) continue;\n const n = (byLabel.get(e.label) ?? 0) + 1;\n byLabel.set(e.label, n);\n if (n >= FRICTION_RETRY_COUNT) return \"retry\";\n }\n\n return null;\n}\n\n// --- Fatigue caps (NFR-2): never pester. Conservative by default. ------------\n\nexport type FatigueCaps = {\n maxPromptsPerSession: number;\n cooldownMs: number; // min gap between prompts\n};\n\nexport const DEFAULT_CAPS: FatigueCaps = {\n maxPromptsPerSession: 1,\n cooldownMs: 5 * 60_000,\n};\n\nexport type FatigueState = {\n promptsShown: number;\n lastPromptAt: number | null;\n};\n\n/** May we show a prompt right now, given how many we've shown and when? */\nexport function canPrompt(\n state: FatigueState,\n now: number,\n caps: FatigueCaps = DEFAULT_CAPS,\n): boolean {\n if (state.promptsShown >= caps.maxPromptsPerSession) return false;\n if (state.lastPromptAt !== null && now - state.lastPromptAt < caps.cooldownMs) return false;\n return true;\n}\n","// Intervention serve/respond (Wave 0005 slice B — the client half). The two-way\n// SDK: besides emitting Signals, the SDK asks \"is there anything to show this user\n// here?\" (/api/sdk/serve) and posts the answer (/api/sdk/respond). Both halves are\n// wrapped — a serve/respond failure must never surface in the host app (NFR-3); the\n// worst case is simply no survey shown.\n//\n// Pure helpers (buildServeContext / normalizeServed / pickRespondentKey) are split\n// out so the contract is unit-testable without a DOM, like triggers.ts.\n\nimport type { Identity } from \"./types\";\nimport type { SurveyConfig } from \"./survey\";\n\nexport type ServeContext = { route?: string; account?: string; plan?: string };\n\nexport type ServedIntervention = {\n id: string;\n type: string; // 'survey' renders today; others ignored until their widget ships\n config: SurveyConfig;\n};\n\nexport type InterventionAnswer = { choice?: string; text?: string };\n\n// Types the SDK can actually render. Mirrors the server's RENDERABLE_TYPES; if the\n// server ever serves an un-renderable type we drop it rather than show a blank.\nconst RENDERABLE = new Set([\"survey\"]);\n\nfunction str(v: unknown, max: number): string | undefined {\n if (typeof v !== \"string\") return undefined;\n const t = v.trim();\n return t ? t.slice(0, max) : undefined;\n}\n\n/** The serve context from the current route + the identified account/plan. Only\n * defined fields are included (an absent field = unconstrained on the server). */\nexport function buildServeContext(\n route: string | undefined,\n identity: Identity | undefined,\n): ServeContext {\n const ctx: ServeContext = {};\n const r = str(route, 500);\n if (r) ctx.route = r;\n const account = str(identity?.account, 200);\n if (account) ctx.account = account;\n const plan = str(identity?.plan, 80);\n if (plan) ctx.plan = plan;\n return ctx;\n}\n\n/** Validate + normalise what /serve returned — never trust the wire blindly. Returns\n * a clean ServedIntervention or null (unknown shape / un-renderable type / no\n * question). */\nexport function normalizeServed(raw: unknown): ServedIntervention | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n const id = str(r.id, 64);\n const type = str(r.type, 40);\n if (!id || !type || !RENDERABLE.has(type)) return null;\n\n const cfg =\n r.config && typeof r.config === \"object\" ? (r.config as Record<string, unknown>) : {};\n const question = str(cfg.question, 500);\n if (!question) return null;\n\n const options = Array.isArray(cfg.options)\n ? (cfg.options as unknown[])\n .map((o) => str(o, 200))\n .filter((o): o is string => !!o)\n .slice(0, 6)\n : undefined;\n\n const config: SurveyConfig = {\n question,\n ...(options && options.length ? { options } : {}),\n allow_text: cfg.allow_text === true,\n };\n return { id, type, config };\n}\n\n/** Stable id for serve-time de-dup (so a tapped survey doesn't reappear). The\n * identified user wins; else a persisted anon id; else the per-session ref. Pure\n * so it's testable — the localStorage read lives in getRespondentKey. */\nexport function pickRespondentKey(\n userId: string | undefined,\n persisted: string | null,\n sessionRef: string,\n): string {\n const uid = str(userId, 200);\n if (uid) return uid;\n const p = str(persisted, 200);\n if (p) return p;\n return sessionRef;\n}\n\nconst RK_STORAGE_KEY = \"sightspool_rk\";\n\n/** Resolve the respondent key, persisting an anonymous one in localStorage so\n * de-dup survives reloads. Falls back to the session ref if storage is blocked. */\nexport function getRespondentKey(\n identity: Identity | undefined,\n sessionRef: string,\n): string {\n const uid = str(identity?.userId, 200);\n if (uid) return uid;\n try {\n let v = localStorage.getItem(RK_STORAGE_KEY);\n if (!v) {\n v = \"anon-\" + Math.random().toString(36).slice(2) + Date.now().toString(36);\n localStorage.setItem(RK_STORAGE_KEY, v);\n }\n return pickRespondentKey(undefined, v, sessionRef);\n } catch {\n return sessionRef;\n }\n}\n\nfunction serveUrl(endpoint: string, path: string): string {\n return `${endpoint.replace(/\\/+$/, \"\")}/api/sdk/${path}`;\n}\n\n/** Ask the serve endpoint for an intervention to show, or null. Uses a text/plain\n * POST (CORS-safelisted → no preflight) and reads the JSON response (the serve\n * route sets Access-Control-Allow-Origin). */\nexport async function fetchIntervention(opts: {\n endpoint: string;\n key: string;\n ctx: ServeContext;\n respondentKey: string;\n debug?: boolean;\n}): Promise<ServedIntervention | null> {\n try {\n if (typeof fetch !== \"function\") return null;\n const res = await fetch(serveUrl(opts.endpoint, \"serve\"), {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain\" },\n body: JSON.stringify({\n key: opts.key,\n context: opts.ctx,\n respondent_key: opts.respondentKey,\n }),\n mode: \"cors\",\n credentials: \"omit\",\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { intervention?: unknown };\n const served = normalizeServed(data?.intervention);\n if (opts.debug) console.debug(\"[sightspool] serve\", served?.id ?? \"(none)\");\n return served;\n } catch {\n return null;\n }\n}\n\n/** Post a user's answer. Fire-and-forget (sendBeacon, fetch+keepalive fallback) —\n * the response is a 204 we don't need to read. */\nexport function submitResponse(opts: {\n endpoint: string;\n key: string;\n interventionId: string;\n response: InterventionAnswer;\n respondentKey: string;\n}): void {\n try {\n const url = serveUrl(opts.endpoint, \"respond\");\n const json = JSON.stringify({\n key: opts.key,\n intervention_id: opts.interventionId,\n response: opts.response,\n respondent_key: opts.respondentKey,\n });\n if (typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n const blob = new Blob([json], { type: \"text/plain\" });\n if (navigator.sendBeacon(url, blob)) return;\n }\n if (typeof fetch === \"function\") {\n void fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain\" },\n body: json,\n keepalive: true,\n mode: \"cors\",\n credentials: \"omit\",\n }).catch(() => {\n /* swallow */\n });\n }\n } catch {\n /* swallow */\n }\n}\n","// Environment guards. Kept pure (a hostname string in, a boolean out) so the\n// no-op-on-localhost decision is unit-testable without a DOM.\n\nconst LOCAL_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"0.0.0.0\", \"::1\", \"\"]);\n\n/**\n * Is this a local-development hostname? Capture is suppressed on these by default so\n * a client's `npm run dev` traffic never pollutes their Sightspool workspace (override\n * with `captureOnLocalhost: true`). Covers the common dev hosts + the `.local` /\n * `.localhost` TLDs (e.g. `myapp.local`, `app.localhost`).\n */\nexport function isLocalhost(hostname: string | null | undefined): boolean {\n const h = (hostname ?? \"\").trim().toLowerCase();\n if (LOCAL_HOSTS.has(h)) return true;\n return h.endsWith(\".local\") || h.endsWith(\".localhost\");\n}\n","// @sightspool/sdk — the in-product capture runtime (public surface).\n//\n// Ties the pieces together: passive capture + intent harvest feed a conservative\n// trigger engine; on a friction moment or a session boundary we (fatigue\n// permitting) show the one-tap prompt, then emit one Signal via batched sendBeacon.\n// Every public method is wrapped — the SDK must never throw into the host (NFR-3).\n\nimport type { SightspoolConfig, Identity, CapturedSignal } from \"./types\";\nimport { createCapture, type CaptureHandle } from \"./capture\";\nimport { createHarvest, type HarvestHandle } from \"./harvest\";\nimport { createEgress, type EgressHandle } from \"./egress\";\nimport {\n detectFriction,\n canPrompt,\n DEFAULT_CAPS,\n type FatigueState,\n} from \"./triggers\";\nimport {\n buildServeContext,\n fetchIntervention,\n submitResponse,\n getRespondentKey,\n} from \"./intervention\";\nimport { isLocalhost } from \"./env\";\n\nexport type { SightspoolConfig, Identity } from \"./types\";\n\nconst DEFAULT_ENDPOINT = \"https://www.sightspool.com\";\nconst FRICTION_EMIT_COOLDOWN_MS = 30_000;\nconst EVENT_DEBOUNCE_MS = 600;\n// Let the page settle before the first serve check (don't race the initial render).\nconst SERVE_SETTLE_MS = 2_500;\n// Conservative client cap; the server also de-dups (answered) + targets + bounds by\n// response_target, so this just stops a dismissed survey re-nagging within a session.\nconst MAX_INTERVENTIONS_PER_SESSION = 1;\n\ntype Controller = {\n config: Required<Pick<SightspoolConfig, \"key\" | \"endpoint\" | \"boundaryAsk\" | \"debug\">> &\n SightspoolConfig;\n capture: CaptureHandle;\n harvest: HarvestHandle;\n egress: EgressHandle;\n identity: Identity;\n sessionRef: string;\n fatigue: FatigueState;\n lastFrictionEmitAt: number;\n eventTimer: number | null;\n running: boolean;\n /** Environmental kill-switch: on localhost without `captureOnLocalhost`, never start. */\n suppressed: boolean;\n // --- interventions (slice B serve loop) ---\n interventionsEnabled: boolean;\n lastServeRoute: string | null; // re-check serve when the route changes\n surveyOnScreen: boolean;\n interventionsShown: number;\n};\n\nfunction currentHostname(): string {\n try {\n return typeof location !== \"undefined\" ? location.hostname : \"\";\n } catch {\n return \"\";\n }\n}\n\nlet ctrl: Controller | null = null;\n\nfunction uuid(): string {\n try {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n } catch {\n /* fall through */\n }\n return \"s-\" + Math.random().toString(36).slice(2) + Date.now().toString(36);\n}\n\n// Locally-derived candidate goals for State B (FR-5). v1 leans on harvested intent\n// (a recent search) + the page label; server-LLM enrichment is a follow-up.\nfunction deriveCandidates(c: Controller): string[] {\n const out: string[] = [];\n const hint = c.harvest.lastIntentHint();\n if (hint) out.push(`Searching for “${hint}”`);\n const label = c.capture.label();\n if (label) out.push(`Something on “${label.slice(0, 40)}”`);\n return out;\n}\n\nfunction buildSignal(\n c: Controller,\n trigger: \"boundary\" | \"friction\",\n extra: Partial<CapturedSignal> = {},\n): CapturedSignal {\n const err = c.capture.error();\n return {\n captured_at: new Date().toISOString(),\n route: c.capture.route(),\n client_label: c.capture.label(),\n trail: c.capture.trail(),\n session_ref: c.sessionRef,\n trigger,\n intent_hint: c.harvest.lastIntentHint(),\n error: err,\n outcome: err || trigger === \"friction\" ? \"failed\" : \"unknown\",\n ...extra,\n };\n}\n\nasync function maybePrompt(c: Controller, trigger: \"boundary\" | \"friction\") {\n const now = Date.now();\n if (canPrompt(c.fatigue, now, DEFAULT_CAPS)) {\n c.fatigue.promptsShown += 1;\n c.fatigue.lastPromptAt = now;\n try {\n const { showPrompt } = await import(\"./prompt\");\n const result = await showPrompt({ candidates: deriveCandidates(c) });\n c.egress.enqueue(\n buildSignal(c, trigger, {\n answer: result.answer,\n verbatim: result.verbatim,\n intent_hint: result.intent ?? c.harvest.lastIntentHint(),\n outcome: result.answer === \"yes\" ? \"achieved\" : \"failed\",\n }),\n );\n } catch {\n // Prompt failed to load/show — still emit the passive Signal (FR-7).\n c.egress.enqueue(buildSignal(c, trigger));\n }\n } else {\n // Fatigued: keep the silent-capture property — emit without asking (FR-7).\n c.egress.enqueue(buildSignal(c, trigger));\n }\n}\n\n// Ask the serve endpoint whether there's a human-approved survey to show this user\n// here, and if so render it + post the answer. Server-gated (targeting, approval,\n// de-dup, response_target); the client guards are just \"don't pester\": one on\n// screen at a time, a per-session cap, and the shared prompt cooldown so a survey\n// and the passive ask never stack back-to-back.\nasync function maybeServeIntervention(c: Controller) {\n if (!c.running || !c.interventionsEnabled || c.suppressed) return;\n if (c.surveyOnScreen) return;\n if (c.interventionsShown >= MAX_INTERVENTIONS_PER_SESSION) return;\n const now = Date.now();\n if (c.fatigue.lastPromptAt !== null && now - c.fatigue.lastPromptAt < DEFAULT_CAPS.cooldownMs)\n return;\n\n const respondentKey = getRespondentKey(c.identity, c.sessionRef);\n const served = await fetchIntervention({\n endpoint: c.config.endpoint,\n key: c.config.key,\n ctx: buildServeContext(c.capture.route(), c.identity),\n respondentKey,\n debug: c.config.debug,\n });\n if (!served || !c.running) return;\n\n c.surveyOnScreen = true;\n c.interventionsShown += 1;\n c.fatigue.lastPromptAt = Date.now(); // share the cooldown with the passive prompt\n try {\n const { showSurvey } = await import(\"./survey\");\n const result = await showSurvey(served.config);\n if (!result.dismissed && (result.choice || result.text)) {\n submitResponse({\n endpoint: c.config.endpoint,\n key: c.config.key,\n interventionId: served.id,\n response: { choice: result.choice, text: result.text },\n respondentKey,\n });\n }\n } catch {\n /* swallow — a render/import failure must not surface in the host */\n } finally {\n c.surveyOnScreen = false;\n }\n}\n\nfunction onCaptureEvent() {\n const c = ctrl;\n if (!c || !c.running) return;\n\n // Re-check for a servable intervention when the route changes (SPA navigation).\n try {\n const route = c.capture.route();\n if (route && route !== c.lastServeRoute) {\n c.lastServeRoute = route;\n void maybeServeIntervention(c);\n }\n } catch {\n /* swallow */\n }\n\n if (c.eventTimer !== null) return; // debounce a burst of events into one check\n c.eventTimer = (typeof window !== \"undefined\" ? window.setTimeout : setTimeout)(() => {\n c.eventTimer = null;\n try {\n const now = Date.now();\n if (now - c.lastFrictionEmitAt < FRICTION_EMIT_COOLDOWN_MS) return;\n const kind = detectFriction(c.capture.trail(), now);\n if (!kind) return;\n c.lastFrictionEmitAt = now;\n void maybePrompt(c, \"friction\");\n } catch {\n /* swallow */\n }\n }, EVENT_DEBOUNCE_MS) as unknown as number;\n}\n\nfunction onExitIntent(ev: MouseEvent) {\n const c = ctrl;\n if (!c || !c.running || !c.config.boundaryAsk) return;\n try {\n if (ev.clientY <= 0) void maybePrompt(c, \"boundary\");\n } catch {\n /* swallow */\n }\n}\n\nfunction startRuntime(c: Controller) {\n if (c.running) return;\n if (c.suppressed) {\n if (c.config.debug)\n console.debug(\n \"[sightspool] capture suppressed on localhost (set captureOnLocalhost:true to override)\",\n );\n return;\n }\n c.running = true;\n c.capture.start();\n c.harvest.start();\n c.egress.start();\n c.capture.onEvent(onCaptureEvent);\n try {\n document.addEventListener(\"mouseout\", onExitIntent);\n } catch {\n /* swallow */\n }\n // First serve check once the page has settled (route-change checks happen in\n // onCaptureEvent thereafter).\n if (c.interventionsEnabled) {\n c.lastServeRoute = (() => {\n try {\n return c.capture.route();\n } catch {\n return null;\n }\n })();\n (typeof window !== \"undefined\" ? window.setTimeout : setTimeout)(() => {\n void maybeServeIntervention(c);\n }, SERVE_SETTLE_MS);\n }\n if (c.config.debug) console.debug(\"[sightspool] started\", c.sessionRef);\n}\n\n// --- public API --------------------------------------------------------------\n\nexport function init(config: SightspoolConfig): void {\n try {\n if (!config || !config.key) {\n console.warn(\"[sightspool] init: a `key` is required\");\n return;\n }\n if (ctrl) return; // already initialised\n const endpoint = config.endpoint || DEFAULT_ENDPOINT;\n const privacyOpts = { redact: config.redact, block: config.block };\n const capture = createCapture({ debug: !!config.debug, ...privacyOpts });\n const harvest = createHarvest(capture, { debug: !!config.debug, ...privacyOpts });\n const egress = createEgress({ key: config.key, endpoint, debug: !!config.debug });\n ctrl = {\n config: {\n ...config,\n key: config.key,\n endpoint,\n boundaryAsk: config.boundaryAsk !== false,\n debug: !!config.debug,\n },\n capture,\n harvest,\n egress,\n identity: {},\n sessionRef: uuid(),\n fatigue: { promptsShown: 0, lastPromptAt: null },\n lastFrictionEmitAt: 0,\n eventTimer: null,\n running: false,\n suppressed: isLocalhost(currentHostname()) && config.captureOnLocalhost !== true,\n interventionsEnabled: config.interventions !== false,\n lastServeRoute: null,\n surveyOnScreen: false,\n interventionsShown: 0,\n };\n if (config.consent !== false) startRuntime(ctrl);\n } catch (err) {\n // init itself must never throw into the host.\n try {\n console.warn(\"[sightspool] init failed\", err);\n } catch {\n /* swallow */\n }\n }\n}\n\nexport function identify(userId: string, traits?: { account?: string; plan?: string }): void {\n try {\n if (!ctrl) return;\n ctrl.identity = { userId, account: traits?.account, plan: traits?.plan };\n ctrl.egress.setIdentity(ctrl.identity);\n } catch {\n /* swallow */\n }\n}\n\n/** Begin capture if init was called with { consent: false }. */\nexport function start(): void {\n try {\n if (ctrl) startRuntime(ctrl);\n } catch {\n /* swallow */\n }\n}\n\n/**\n * Runtime consent gate (a clean toggle over start()/stop()) — wire it to your cookie\n * banner: `Sightspool.consent(true)` resumes capture, `Sightspool.consent(false)`\n * pauses and flushes. Pairs with init `{ consent: false }` to stay dark until granted.\n */\nexport function consent(granted: boolean): void {\n try {\n if (!ctrl) return;\n if (granted) startRuntime(ctrl);\n else stop();\n } catch {\n /* swallow */\n }\n}\n\n/** Pause capture and flush whatever's queued. */\nexport function stop(): void {\n try {\n if (!ctrl) return;\n ctrl.running = false;\n ctrl.capture.stop();\n ctrl.harvest.stop();\n ctrl.egress.stop();\n try {\n document.removeEventListener(\"mouseout\", onExitIntent);\n } catch {\n /* swallow */\n }\n } catch {\n /* swallow */\n }\n}\n\nconst api = { init, identify, start, stop, consent };\nexport default api;\n\n// --- script-tag auto-init ----------------------------------------------------\n// The standalone <script data-sightspool-key=\"pk_…\"> install auto-boots from its\n// own tag's data attributes. (No-op for the ESM build: module scripts have no\n// document.currentScript, so bundler consumers always call init() themselves.)\ntry {\n if (typeof document !== \"undefined\") {\n // currentScript is null for async/defer/dynamically-injected scripts (e.g.\n // Next's <Script> component), so fall back to finding our tag by attribute.\n const el =\n (document.currentScript as HTMLScriptElement | null) ??\n document.querySelector<HTMLScriptElement>(\"script[data-sightspool-key]\");\n const key = el?.getAttribute(\"data-sightspool-key\");\n if (key) {\n // Default the ingest endpoint to where the bundle was served from — the app\n // serves /sdk.global.js, so a same-origin script install needs only the key.\n // An explicit data-sightspool-endpoint still wins (e.g. a CDN-hosted bundle).\n let endpoint = el?.getAttribute(\"data-sightspool-endpoint\") || undefined;\n if (!endpoint && el?.src) {\n try {\n endpoint = new URL(el.src).origin;\n } catch {\n /* keep the built-in default */\n }\n }\n // Comma-separated CSS selectors → string[] (the script-tag equivalent of the\n // init() arrays; bundler users pass arrays directly).\n const list = (attr: string): string[] | undefined => {\n const raw = el?.getAttribute(attr);\n if (!raw) return undefined;\n const out = raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return out.length ? out : undefined;\n };\n init({\n key,\n endpoint,\n redact: list(\"data-sightspool-redact\"),\n block: list(\"data-sightspool-block\"),\n captureOnLocalhost: el?.hasAttribute(\"data-sightspool-capture-localhost\") || undefined,\n interventions: el?.hasAttribute(\"data-sightspool-no-interventions\") ? false : undefined,\n debug: el?.hasAttribute(\"data-sightspool-debug\") || undefined,\n });\n }\n }\n} catch {\n /* swallow */\n}\n"]}
@@ -0,0 +1,145 @@
1
+ // src/survey.ts
2
+ var STYLE = `
3
+ :host { all: initial; }
4
+ .wrap { position: fixed; bottom: 20px; right: 20px; z-index: 2147483000;
5
+ width: 340px; max-width: calc(100vw - 32px); font-family: system-ui, -apple-system, sans-serif; }
6
+ .card { position: relative; background: #fff; color: #18181b; border: 1px solid #e4e4e7;
7
+ border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 16px; }
8
+ .q { font-size: 14px; font-weight: 600; margin: 0 0 12px; line-height: 1.35; padding-right: 16px; }
9
+ .row { display: flex; gap: 8px; flex-wrap: wrap; }
10
+ button { font: inherit; font-size: 13px; cursor: pointer; border-radius: 8px; padding: 8px 12px;
11
+ border: 1px solid #e4e4e7; background: #fafafa; color: #18181b; }
12
+ button:hover { background: #f4f4f5; }
13
+ button.primary { background: #18181b; color: #fff; border-color: #18181b; }
14
+ .opt { display: block; width: 100%; text-align: left; margin-bottom: 6px; }
15
+ .x { position: absolute; top: 8px; right: 10px; border: none; background: none; font-size: 16px;
16
+ color: #a1a1aa; padding: 2px 6px; cursor: pointer; }
17
+ .done { font-size: 13px; color: #18181b; margin: 0; }
18
+ input { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; padding: 8px 10px;
19
+ border: 1px solid #e4e4e7; border-radius: 8px; margin-bottom: 8px; }
20
+ `;
21
+ var THANKS_MS = 1100;
22
+ function showSurvey(config) {
23
+ return new Promise((resolve) => {
24
+ if (typeof document === "undefined") {
25
+ resolve({ dismissed: true });
26
+ return;
27
+ }
28
+ let settled = false;
29
+ const host = document.createElement("div");
30
+ const shadow = host.attachShadow({ mode: "open" });
31
+ function teardown() {
32
+ try {
33
+ host.remove();
34
+ } catch (e) {
35
+ }
36
+ }
37
+ function finish(result, thank) {
38
+ if (settled) return;
39
+ settled = true;
40
+ resolve(result);
41
+ if (thank) {
42
+ thankYou();
43
+ setTimeout(teardown, THANKS_MS);
44
+ } else {
45
+ teardown();
46
+ }
47
+ }
48
+ const style = document.createElement("style");
49
+ style.textContent = STYLE;
50
+ shadow.appendChild(style);
51
+ const wrap = document.createElement("div");
52
+ wrap.className = "wrap";
53
+ shadow.appendChild(wrap);
54
+ function card() {
55
+ wrap.innerHTML = "";
56
+ const c = document.createElement("div");
57
+ c.className = "card";
58
+ wrap.appendChild(c);
59
+ return c;
60
+ }
61
+ function withClose(c) {
62
+ const x = document.createElement("button");
63
+ x.className = "x";
64
+ x.textContent = "\xD7";
65
+ x.setAttribute("aria-label", "Dismiss");
66
+ x.onclick = () => finish({ dismissed: true }, false);
67
+ c.appendChild(x);
68
+ }
69
+ function question() {
70
+ var _a, _b, _c;
71
+ const c = card();
72
+ withClose(c);
73
+ const q = document.createElement("p");
74
+ q.className = "q";
75
+ q.textContent = config.question;
76
+ c.appendChild(q);
77
+ for (const opt of ((_a = config.options) != null ? _a : []).slice(0, 6)) {
78
+ const b = document.createElement("button");
79
+ b.className = "opt";
80
+ b.textContent = opt;
81
+ b.onclick = () => finish({ choice: opt }, true);
82
+ c.appendChild(b);
83
+ }
84
+ if (config.allow_text) {
85
+ const se = document.createElement("button");
86
+ se.className = "opt";
87
+ se.textContent = ((_c = (_b = config.options) == null ? void 0 : _b.length) != null ? _c : 0) > 0 ? "Something else\u2026" : "Answer\u2026";
88
+ se.onclick = freeText;
89
+ c.appendChild(se);
90
+ }
91
+ }
92
+ function freeText() {
93
+ const c = card();
94
+ withClose(c);
95
+ const q = document.createElement("p");
96
+ q.className = "q";
97
+ q.textContent = config.question;
98
+ c.appendChild(q);
99
+ const input = document.createElement("input");
100
+ input.type = "text";
101
+ input.placeholder = "In your own words\u2026";
102
+ c.appendChild(input);
103
+ const row = document.createElement("div");
104
+ row.className = "row";
105
+ const send = document.createElement("button");
106
+ send.className = "primary";
107
+ send.textContent = "Send";
108
+ const submit = () => {
109
+ const text = input.value.trim();
110
+ if (!text) {
111
+ finish({ dismissed: true }, false);
112
+ return;
113
+ }
114
+ finish({ text }, true);
115
+ };
116
+ send.onclick = submit;
117
+ input.onkeydown = (e) => {
118
+ if (e.key === "Enter") submit();
119
+ };
120
+ row.appendChild(send);
121
+ c.appendChild(row);
122
+ try {
123
+ input.focus();
124
+ } catch (e) {
125
+ }
126
+ }
127
+ function thankYou() {
128
+ const c = card();
129
+ const p = document.createElement("p");
130
+ p.className = "done";
131
+ p.textContent = "Thanks \u2014 that helps.";
132
+ c.appendChild(p);
133
+ }
134
+ try {
135
+ document.body.appendChild(host);
136
+ question();
137
+ } catch (e) {
138
+ finish({ dismissed: true }, false);
139
+ }
140
+ });
141
+ }
142
+
143
+ export { showSurvey };
144
+ //# sourceMappingURL=survey-CICJQ5VI.js.map
145
+ //# sourceMappingURL=survey-CICJQ5VI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/survey.ts"],"names":[],"mappings":"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","file":"survey-CICJQ5VI.js","sourcesContent":["// The intervention survey widget (Wave 0005 slice B — the client half). Renders a\n// human-approved one-tap survey served by /api/sdk/serve, in a shadow root so the\n// host app's CSS can't style-break it and it leaks zero styles back. Dynamically\n// imported by index.ts only when the serve endpoint actually returns something, so\n// it splits into its own lazily-loaded chunk and adds nothing to the host bundle\n// until a survey is shown. Mirrors prompt.ts (the passive ask) deliberately.\n//\n// question + [option] [option] … (tap an option → choice)\n// + \"Something else…\" → free text (only when allow_text)\n\nexport type SurveyConfig = {\n question: string;\n options?: string[];\n allow_text?: boolean;\n};\n\nexport type SurveyResult = {\n choice?: string;\n text?: string;\n dismissed?: boolean;\n};\n\nconst STYLE = `\n:host { all: initial; }\n.wrap { position: fixed; bottom: 20px; right: 20px; z-index: 2147483000;\n width: 340px; max-width: calc(100vw - 32px); font-family: system-ui, -apple-system, sans-serif; }\n.card { position: relative; background: #fff; color: #18181b; border: 1px solid #e4e4e7;\n border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 16px; }\n.q { font-size: 14px; font-weight: 600; margin: 0 0 12px; line-height: 1.35; padding-right: 16px; }\n.row { display: flex; gap: 8px; flex-wrap: wrap; }\nbutton { font: inherit; font-size: 13px; cursor: pointer; border-radius: 8px; padding: 8px 12px;\n border: 1px solid #e4e4e7; background: #fafafa; color: #18181b; }\nbutton:hover { background: #f4f4f5; }\nbutton.primary { background: #18181b; color: #fff; border-color: #18181b; }\n.opt { display: block; width: 100%; text-align: left; margin-bottom: 6px; }\n.x { position: absolute; top: 8px; right: 10px; border: none; background: none; font-size: 16px;\n color: #a1a1aa; padding: 2px 6px; cursor: pointer; }\n.done { font-size: 13px; color: #18181b; margin: 0; }\ninput { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; padding: 8px 10px;\n border: 1px solid #e4e4e7; border-radius: 8px; margin-bottom: 8px; }\n`;\n\nconst THANKS_MS = 1100; // brief acknowledgement, then auto-close\n\nexport function showSurvey(config: SurveyConfig): Promise<SurveyResult> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\") {\n resolve({ dismissed: true });\n return;\n }\n\n let settled = false;\n const host = document.createElement(\"div\");\n const shadow = host.attachShadow({ mode: \"open\" });\n\n function teardown() {\n try {\n host.remove();\n } catch {\n /* swallow */\n }\n }\n\n // Resolve immediately (so the answer is sent without delay) but leave a short\n // \"Thanks\" on screen before removing the node.\n function finish(result: SurveyResult, thank: boolean) {\n if (settled) return;\n settled = true;\n resolve(result);\n if (thank) {\n thankYou();\n setTimeout(teardown, THANKS_MS);\n } else {\n teardown();\n }\n }\n\n const style = document.createElement(\"style\");\n style.textContent = STYLE;\n shadow.appendChild(style);\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n shadow.appendChild(wrap);\n\n function card(): HTMLElement {\n wrap.innerHTML = \"\";\n const c = document.createElement(\"div\");\n c.className = \"card\";\n wrap.appendChild(c);\n return c;\n }\n\n function withClose(c: HTMLElement) {\n const x = document.createElement(\"button\");\n x.className = \"x\";\n x.textContent = \"×\";\n x.setAttribute(\"aria-label\", \"Dismiss\");\n x.onclick = () => finish({ dismissed: true }, false);\n c.appendChild(x);\n }\n\n function question() {\n const c = card();\n withClose(c);\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = config.question;\n c.appendChild(q);\n\n for (const opt of (config.options ?? []).slice(0, 6)) {\n const b = document.createElement(\"button\");\n b.className = \"opt\";\n b.textContent = opt;\n b.onclick = () => finish({ choice: opt }, true);\n c.appendChild(b);\n }\n\n if (config.allow_text) {\n const se = document.createElement(\"button\");\n se.className = \"opt\";\n // If there were no options, this is the only path — label it plainly.\n se.textContent = (config.options?.length ?? 0) > 0 ? \"Something else…\" : \"Answer…\";\n se.onclick = freeText;\n c.appendChild(se);\n }\n }\n\n function freeText() {\n const c = card();\n withClose(c);\n const q = document.createElement(\"p\");\n q.className = \"q\";\n q.textContent = config.question;\n c.appendChild(q);\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.placeholder = \"In your own words…\";\n c.appendChild(input);\n const row = document.createElement(\"div\");\n row.className = \"row\";\n const send = document.createElement(\"button\");\n send.className = \"primary\";\n send.textContent = \"Send\";\n const submit = () => {\n const text = input.value.trim();\n if (!text) {\n finish({ dismissed: true }, false);\n return;\n }\n finish({ text }, true);\n };\n send.onclick = submit;\n input.onkeydown = (e) => {\n if ((e as KeyboardEvent).key === \"Enter\") submit();\n };\n row.appendChild(send);\n c.appendChild(row);\n try {\n input.focus();\n } catch {\n /* swallow */\n }\n }\n\n function thankYou() {\n const c = card();\n const p = document.createElement(\"p\");\n p.className = \"done\";\n p.textContent = \"Thanks — that helps.\";\n c.appendChild(p);\n }\n\n try {\n document.body.appendChild(host);\n question();\n } catch {\n finish({ dismissed: true }, false);\n }\n });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sightspool/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Sightspool in-product capture SDK — captures user intent, effort, and account at the moment of friction.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",