@botbuddy/react 0.9.12 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,52 @@
1
+ # @botbuddy/react — Changelog
2
+
3
+ ## 0.9.14
4
+
5
+ ### Fixed
6
+
7
+ - **Do not sign the widget user out from the 2FA chip.** `401` and `403`
8
+ responses from `/widget/totp-code` now surface the server error without
9
+ removing `botbuddy-widget-auth-token`. This keeps staging testers signed in
10
+ when a widget session is expired, a seeded persona is not assigned to the
11
+ resolved run, or another authorization/configuration issue needs to be
12
+ fixed.
13
+
14
+ ## 0.9.13
15
+
16
+ ### Added
17
+
18
+ - **Local-only file-based TOTP secrets.** When `environment === "local"`,
19
+ the widget now reads `public/.botbuddy-totp.json` (a developer-owned
20
+ map of `seed_user_slug → base32 TOTP secret`) and computes 2FA codes
21
+ in-browser using RFC 6238 (HMAC-SHA1, 30 s, 6 digits). This removes
22
+ the need for `BOTBUDDY_API_KEY` + a `register_totp_seed` MCP call on
23
+ local development. The file is honored **only** for
24
+ `environment === "local"`; preview/staging/production continue to
25
+ fetch from `/widget/totp-code` so the secret never leaves the
26
+ developer's machine. If a slug isn't present in the local file, the
27
+ widget falls back to the server endpoint, so the feature is purely
28
+ additive. Devs **must** gitignore `public/.botbuddy-totp.json`.
29
+
30
+ ### Tests
31
+
32
+ - Added `localTotp.test.ts` covering RFC 6238 SHA-1 vectors
33
+ (`T=59 → 287082`, `T=1111111109 → 081804`, `T=1234567890 → 005924`),
34
+ Base32 rejection of invalid input, and `loadLocalTotpSecrets()`
35
+ behavior on 404, network error, non-object payloads, and cache reuse.
36
+
37
+ ## 0.9.12
38
+
39
+ - BOT-380 — widget popover via portal + UI polish.
40
+
41
+ ## 0.9.10 and earlier
42
+
43
+ See git history (`git log -- packages/react`) for changes prior to the
44
+ introduction of this CHANGELOG. Highlights:
45
+
46
+ - 0.9.10 — BOT-380 viewport clamping for the 2FA persona popover.
47
+ - 0.9.9 — BOT-380 widget clamps into viewport so "Sign in" stays reachable.
48
+ - 0.9.8 — BOT-380 2FA chip self-recovers from stale JWT + UI rework.
49
+ - 0.9.5 — BOT-380 Safari clipboard fix (user-gesture-after-await).
50
+ - 0.9.4 — BOT-380 stop remounting `TotpChip` on every parent render.
51
+ - 0.9.1 — BOT-380 widget-level 2FA chip with persona popover.
52
+ - 0.9.0 — BOT-380 initial 2FA control with `/widget/totp-code` endpoint.
package/README.md CHANGED
@@ -88,6 +88,35 @@ When no explicit `testRunToken` prop is passed, the widget automatically discove
88
88
 
89
89
  When a `ticket_id` is provided during `create_test_run`, the token is upserted on `ticket_id + environment`, so multiple agents or worktrees working on the same ticket share the same resolution context.
90
90
 
91
+ ### Local 2FA Secrets (no API key required)
92
+
93
+ When `environment === "local"`, the widget can compute TOTP codes
94
+ client-side from a developer-owned file at `public/.botbuddy-totp.json`:
95
+
96
+ ```json
97
+ {
98
+ "admin@myapp.test": "JBSWY3DPEHPK3PXP",
99
+ "viewer@myapp.test": "JBSWY3DPEHPK3PXQ"
100
+ }
101
+ ```
102
+
103
+ If a key in this file matches the case's `seed_user` slug, the widget
104
+ generates the code in-browser (RFC 6238, SHA-1, 30s, 6 digits) and skips
105
+ the server `/widget/totp-code` round-trip. This means local development
106
+ does **not** need `BOTBUDDY_API_KEY` or a `register_totp_seed` MCP call.
107
+
108
+ - Honored **only** when `environment === "local"`. Preview, staging,
109
+ and production always go through the server endpoint so the secret
110
+ never leaves the developer's machine.
111
+ - File **must** be gitignored — it contains the raw TOTP secret. Add
112
+ `public/.botbuddy-totp.json` to your repo's `.gitignore`.
113
+ - If a slug is missing from the file, the widget falls back to the
114
+ server endpoint as before — so the file is purely additive.
115
+ - The file is resolved against your app's `<base href>` if one is set
116
+ (Vite emits this automatically when `base` is configured), otherwise
117
+ it's fetched from the domain root. If you deploy to a subpath, make
118
+ sure your build emits `<base href>` so the lookup hits the right URL.
119
+
91
120
  ### Origin-Based Matching
92
121
 
93
122
  When `targetUrl` is provided, the server matches by **origin** (e.g. `http://localhost:5173`), not the full URL. Redirects, query params, and hash fragments won't break resolution. Pass `window.location.origin` for best results.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),reactDom=require('react-dom'),jsxRuntime=require('react/jsx-runtime');var re=8;function Te(t,r,s,f,y,c){let T=Math.max(re,y-s-re),w=Math.max(re,c-f-re);return {x:Math.min(Math.max(t,re),T),y:Math.min(Math.max(r,re),w)}}function Re(t,r){let[s,f]=react.useState({x:t,y:r}),y=react.useRef(false),c=react.useRef({x:0,y:0}),T=react.useRef(false),w=react.useCallback(u=>{y.current=true,T.current=false,c.current={x:u.clientX-s.x,y:u.clientY-s.y},u.target.setPointerCapture(u.pointerId);},[s]),_=react.useCallback(u=>{y.current&&(T.current=true,f({x:u.clientX-c.current.x,y:u.clientY-c.current.y}));},[]),d=react.useCallback(()=>{y.current=false;},[]);return {pos:s,setPos:f,onPointerDown:w,onPointerMove:_,onPointerUp:d,didDrag:T}}function ze(t,r,s){let f=react.useRef(s);f.current=s,react.useEffect(()=>{if(!r)return;if(t.supabaseUrl){let c=false,T=null,w=()=>{c||T||(T=setInterval(()=>f.current(),15e3));},_=null;try{let C=new URL(t.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(C.hostname);if(C.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");C.protocol=C.protocol==="https:"?"wss:":"ws:",_=C.toString().replace(/\/$/,"");}catch{w();}let d=null,u=null,M=null,W=0,R=()=>{if(!(c||!_)){try{d=new WebSocket(`${_}/realtime/v1/websocket?apikey=${t.anonKey}&vsn=1.0.0`);}catch{w();return}d.onopen=()=>{if(c||!d)return;let C={topic:`realtime:public:test_run_cases:test_run_id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_run_cases",filter:`test_run_id=eq.${r}`}]}},ref:String(++W)};d.send(JSON.stringify(C));let n={topic:`realtime:public:test_runs:id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_runs",filter:`id=eq.${r}`}]}},ref:String(++W)};d.send(JSON.stringify(n)),u=setInterval(()=>{d?.readyState===WebSocket.OPEN&&d.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++W)}));},3e4);},d.onmessage=C=>{try{JSON.parse(C.data).event==="postgres_changes"&&f.current();}catch{}},d.onclose=()=>{F(),c||(M=setTimeout(R,3e3));},d.onerror=()=>{d?.close();};}},F=()=>{u&&(clearInterval(u),u=null);};return R(),()=>{c=true,F(),M&&clearTimeout(M),T&&clearInterval(T),d&&(d.onclose=null,d.onerror=null,d.close());}}let y=setInterval(()=>f.current(),15e3);return ()=>clearInterval(y)},[t.supabaseUrl,t.anonKey,r]);}function ve(t,r){let s={apikey:t.anonKey};return r?s.Authorization=`Bearer ${r}`:t.apiKey?s.Authorization=`Bearer ${t.apiKey}`:s.Authorization=`Bearer ${t.anonKey}`,s}async function St(t){if(t)return t;try{let r=await fetch("/.botbuddy-token",{cache:"no-store"});if(r.ok){let s=(await r.text()).trim();if(s.startsWith("public_"))return s}}catch{}try{let r=undefined?.VITE_BOTBUDDY_TEST_RUN_TOKEN;if(r&&typeof r=="string"&&r.startsWith("public_"))return r}catch{}return null}function Pe(t){let[r,s]=react.useState(null),[f,y]=react.useState("loading"),c=react.useCallback(async()=>{try{let d=await St(t.testRunToken);if(!d){y("no-match"),s(null);return}if(!t.ticketId){y("no-match"),s(null);return}let u=new URLSearchParams;u.set("token",d),u.set("ticket_id",t.ticketId),u.set("app_slug",t.appSlug),t.environment&&u.set("environment",t.environment),t.testRunId&&u.set("test_run_id",t.testRunId),t.targetUrl&&u.set("target_url",t.targetUrl),t.version&&u.set("version",t.version),t.commitSha&&u.set("commit_sha",t.commitSha),t.prNumber&&u.set("pr_number",String(t.prNumber)),t.branchName&&u.set("branch_name",t.branchName);let M=await fetch(`${t.config.serverUrl}/widget/test-run?${u.toString()}`,{headers:ve(t.config,t.authToken)});if(M.status===404){y("no-match"),s(null);return}if(M.status===401||M.status===403){t.authToken&&t.onAuthExpired&&t.onAuthExpired(),y("error");return}if(!M.ok){y("error");return}let W=await M.json();s(W),y(W.status==="completed"?"completed":"ready");}catch{y("error");}},[t.config.serverUrl,t.config.anonKey,t.config.apiKey,t.authToken,t.appSlug,t.environment,t.ticketId,t.testRunId,t.testRunToken,t.targetUrl,t.version,t.commitSha,t.branchName,t.prNumber,t.onAuthExpired]);return react.useEffect(()=>{c();},[c]),ze(t.config,r?.id,c),{run:r,widgetState:f,fetchRun:c,setVerdict:async(d,u,M,W="human")=>(s(F=>{if(!F)return null;let C=F.test_cases.map(g=>g.id===d?{...g,verdict:u,fail_reason:u==="fail"&&M||null,verdict_by_display_name:W,verdict_at:new Date().toISOString()}:g),n={total:C.length,pending:0,pass:0,fail:0,skip:0};return C.forEach(g=>{g.verdict in n&&n[g.verdict]++;}),{...F,test_cases:C,summary:n}}),(await fetch(`${t.config.serverUrl}/widget/test-cases/${d}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...ve(t.config,t.authToken)},body:JSON.stringify({verdict:u,fail_reason:M,display_name:W})})).ok),markComplete:async()=>r?(s(u=>u?{...u,status:"completed"}:null),y("completed"),(await fetch(`${t.config.serverUrl}/widget/test-runs/${r.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...ve(t.config,t.authToken)}})).ok):false,resetRun:async()=>{if(!r)return false;let d=await fetch(`${t.config.serverUrl}/widget/test-runs/${r.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...ve(t.config,t.authToken)}});return d.ok&&c(),d.ok},setRun:s}}var $e="botbuddy-widget-auth-token",Be="botbuddy-widget-auth-name";function Ee(t){let[r,s]=react.useState(()=>{try{return localStorage.getItem($e)}catch(w){return console.warn("Unable to read BotBuddy widget auth token",w),null}}),[f,y]=react.useState(()=>{try{return localStorage.getItem(Be)}catch(w){return console.warn("Unable to read BotBuddy widget display name",w),null}});react.useEffect(()=>{let w=new URL(t).origin,_=d=>{if(d.origin===w&&d.data?.type==="botbuddy-widget-auth"&&d.data.token){let{token:u,displayName:M}=d.data;s(u),y(M||"human");try{localStorage.setItem($e,u),M&&localStorage.setItem(Be,M);}catch(W){console.warn("Unable to persist BotBuddy widget auth token",W);}}};return window.addEventListener("message",_),()=>window.removeEventListener("message",_)},[t]);let c=react.useCallback(()=>{let w=new URL("/widget-auth",t);w.searchParams.set("origin",window.location.origin);let _=420,d=520,u=window.screenX+(window.innerWidth-_)/2,M=window.screenY+(window.innerHeight-d)/2;window.open(w.toString(),"botbuddy-auth",`width=${_},height=${d},left=${u},top=${M},popup=yes`);},[t]),T=react.useCallback(()=>{s(null),y(null);try{localStorage.removeItem($e),localStorage.removeItem(Be);}catch(w){console.warn("Unable to clear BotBuddy widget auth token",w);}},[]);return {token:r,displayName:f,isAuthenticated:!!r,openLogin:c,logout:T}}function Ct(t){let r=new Date(t),f=Date.now()-r.getTime();if(f<6e4)return "just now";if(f<36e5)return `${Math.floor(f/6e4)}m ago`;if(f<864e5)return `${Math.floor(f/36e5)}h ago`;let y=r.getDate(),c=r.toLocaleString("en",{month:"short"}),T=r.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${c} ${y}, ${T}`}var x=({d:t,className:r,size:s=14})=>jsxRuntime.jsx("svg",{className:r,width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("path",{d:t})}),p={clipboard:"M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2",check:"M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3",x:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20M15 9l-6 6M9 9l6 6",circle:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20",skip:"M5 4l10 8-10 8V4M19 5v14",grip:"M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01",minus:"M5 12h14",chevronUp:"M18 15l-6-6-6 6",chevronDown:"M6 9l6 6 6-6",externalLink:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",pr:"M6 3v18M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6M18 9a9 9 0 0 1-9 9",ticket:"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z",loader:"M21 12a9 9 0 1 1-6.219-8.56",checkAll:"M18 6L7 17l-5-5M22 10l-7.5 7.5L13 16",alert:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0M12 9v4M12 17h.01",bot:"M12 8V4H8M2 14h2M20 14h2M15 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M9 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M18 10a6 6 0 0 0-12 0v4a6 6 0 0 0 12 0Z",terminal:"M4 17l6-6-6-6M12 19h8",key:"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4",shield:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10",copy:"M20 9h-9a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",search:"M11 17.25a6.25 6.25 0 1 1 0-12.5 6.25 6.25 0 0 1 0 12.5ZM16 16l4.5 4.5"};function Tt(){let[t,r]=react.useState(()=>typeof window>"u"||window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");return react.useEffect(()=>{if(typeof window>"u")return;let s=document.documentElement,f=()=>s.classList.contains("dark")?"dark":s.classList.contains("light")?"light":null,y=f();y&&r(y);let c=window.matchMedia("(prefers-color-scheme: dark)"),T=_=>{let d=f();r(d||(_.matches?"dark":"light"));};c.addEventListener("change",T);let w=new MutationObserver(()=>{let _=f();r(_||(c.matches?"dark":"light"));});return w.observe(s,{attributes:true,attributeFilter:["class"]}),()=>{c.removeEventListener("change",T),w.disconnect();}},[]),t}function Rt(t){let r=t==="dark";return {bg:r?"rgb(30,30,30)":"rgb(255,255,255)",bgSoft:r?"rgba(255,255,255,0.02)":"rgba(0,0,0,0.02)",text:r?"#e5e5e5":"#1a1a1a",textMuted:r?"rgba(255,255,255,0.4)":"rgba(0,0,0,0.45)",textFaint:r?"#555":"#999",border:r?"rgba(255,255,255,0.15)":"rgba(0,0,0,0.12)",borderSubtle:r?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",shadow:r?"rgba(0,0,0,0.4)":"rgba(0,0,0,0.12)",inputBg:r?"rgba(0,0,0,0.3)":"rgba(0,0,0,0.04)",inputBorder:r?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.12)",green:"#34d399",greenBg:r?"rgba(52,211,153,0.05)":"rgba(52,211,153,0.08)",greenBorder:r?"rgba(52,211,153,0.6)":"rgba(52,211,153,0.5)",greenBorderSubtle:r?"rgba(52,211,153,0.2)":"rgba(52,211,153,0.15)",red:"#f87171",amber:"#f59e0b",blue:"#60a5fa",purple:"#a78bfa",versionText:r?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",versionNum:r?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",gripColor:r?"#888":"#aaa",btnHover:r?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.06)"}}var zt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},Pt={pending:p.circle,pass:p.check,fail:p.x,skip:p.skip},et={local:{bg:"rgba(59,130,246,0.15)",text:"#60a5fa",border:"rgba(59,130,246,0.3)"},preview:{bg:"rgba(168,85,247,0.15)",text:"#c084fc",border:"rgba(168,85,247,0.3)"},staging:{bg:"rgba(245,158,11,0.15)",text:"#fbbf24",border:"rgba(245,158,11,0.3)"},production:{bg:"rgba(239,68,68,0.15)",text:"#f87171",border:"rgba(239,68,68,0.3)"},custom:{bg:"rgba(128,128,128,0.15)",text:"#888",border:"rgba(128,128,128,0.3)"}},$t=t=>({root:{position:"fixed",zIndex:9999,userSelect:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},pill:r=>({display:"inline-flex",alignItems:"center",gap:"6px",padding:"4px 8px",borderRadius:"9999px",background:t.bg,border:r?`1px solid ${t.greenBorder}`:`1px solid ${t.border}`,boxShadow:r?`0 4px 12px ${t.shadow}, 0 0 0 1px ${t.greenBorderSubtle}`:`0 4px 12px ${t.shadow}`,cursor:"pointer",fontSize:"9px",color:t.text}),card:(r,s)=>({width:`${r}px`,borderRadius:"8px",background:t.bg,border:s?`1px solid ${t.greenBorder}`:`1px solid ${t.border}`,boxShadow:s?`0 8px 24px ${t.shadow}, 0 0 0 1px ${t.greenBorderSubtle}`:`0 8px 24px ${t.shadow}`,overflow:"hidden",display:"flex",flexDirection:"column"}),handle:{padding:"8px 12px",display:"flex",alignItems:"center",gap:"8px",cursor:"grab",borderBottom:`1px solid ${t.borderSubtle}`},title:{fontSize:"10px",fontWeight:600,color:t.text,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},sub:{fontSize:"9px",color:t.textMuted,display:"flex",alignItems:"center",gap:"6px"},btn:{padding:"2px",borderRadius:"4px",background:"transparent",border:"none",cursor:"pointer",color:t.gripColor,display:"flex",flexShrink:0},stats:{padding:"4px 12px",display:"flex",alignItems:"center",gap:"8px",fontSize:"9px",borderBottom:`1px solid ${t.borderSubtle}`},badge:r=>{let s=et[r]||et.custom;return {fontSize:"8px",padding:"0 4px",borderRadius:"4px",background:s.bg,color:s.text,border:`1px solid ${s.border}`,lineHeight:"14px"}},progress:{height:"2px",background:t.borderSubtle,flexShrink:0},progressBar:r=>({height:"100%",width:`${r}%`,background:"linear-gradient(to right, #34d399, #3b82f6)",transition:"width 0.5s"}),link:r=>({display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${r}15`,color:r,textDecoration:"none",border:"none",cursor:"pointer"}),caseRow:{padding:"6px 12px",borderBottom:`1px solid ${t.borderSubtle}`,transition:"background 0.15s"},verdictBtn:(r,s)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:r?`${s}33`:"transparent",color:r?s:t.gripColor,transition:"all 0.15s"}),input:{flex:1,fontSize:"9px",background:t.inputBg,border:`1px solid ${t.inputBorder}`,borderRadius:"4px",padding:"2px 6px",color:t.text,outline:"none"},humanBanner:{padding:"6px 12px",fontSize:"11px",fontWeight:600,color:t.green,borderBottom:`1px solid ${t.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",background:t.greenBg,cursor:"pointer",textDecoration:"none"}});function Bt(t){return t.split("/")[0].trim()}async function Et(t){try{if(typeof navigator<"u"&&navigator.clipboard?.writeText)return await navigator.clipboard.writeText(t),!0}catch{}try{if(typeof document>"u")return !1;let r=document.createElement("textarea");r.value=t,r.setAttribute("readonly",""),r.style.position="fixed",r.style.top="0",r.style.left="0",r.style.opacity="0",r.style.pointerEvents="none",document.body.appendChild(r),r.focus(),r.select(),r.setSelectionRange(0,t.length);let s=document.execCommand("copy");return document.body.removeChild(r),s}catch{return false}}function tt({config:t,appSlug:r,environment:s,seededUsers:f,authToken:y,tk:c,compact:T=false,onExpand:w,onAuthExpired:_}){let[d,u]=react.useState(false),[M,W]=react.useState(null),[R,F]=react.useState(null),[C,n]=react.useState(null),[g,K]=react.useState(null),V=react.useCallback(m=>{W(m),n(null),K(null);let S=k=>{n(k),K(m),window.setTimeout(()=>{K(b=>b===m?null:b),n(b=>b===k?null:b);},3e3);},v=new URLSearchParams({app_slug:r,seed_user_slug:m,environment:s}),$={apikey:t.anonKey};$.Authorization=`Bearer ${y||t.anonKey}`;let L=(async()=>{try{let k=await fetch(`${t.serverUrl}/widget/totp-code?${v}`,{headers:$});if(!k.ok){let N=await k.json().catch(()=>({error:`HTTP ${k.status}`}));return {ok:!1,status:k.status,error:N.error||`HTTP ${k.status}`}}let b=await k.json();return {ok:!0,code:String(b.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),P=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let k=L.then(b=>{if(!b.ok)throw new Error(b.error);return new Blob([b.code],{type:"text/plain"})});P=navigator.clipboard.write([new ClipboardItem({"text/plain":k})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let k=await L;if(!k.ok){k.status===401||k.status===403?(_?.(),S("Signed out \u2014 please sign in again")):S(k.status===404?"No 2FA seed registered":k.error),W(null);return}let b=P?await P:false,N=b?true:await Et(k.code),G=b||N;F({slug:m,code:k.code,copied:G}),window.setTimeout(()=>F(te=>te?.slug===m?null:te),G?2500:6e3),u(false),W(null);})();},[t.serverUrl,t.anonKey,y,r,s]);if(f.length===0)return null;if(T){let m=f.length>1,S=b=>{if(b.stopPropagation(),m&&w){w();return}V(f[0]);},v=!!g,$=!!R,L=$&&R.copied,P=$&&!R.copied,k=v?c.red:L?c.green:P?c.amber:c.purple;return jsxRuntime.jsxs("span",{onPointerDown:b=>b.stopPropagation(),onPointerUp:b=>b.stopPropagation(),onPointerMove:b=>b.stopPropagation(),onClick:S,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:k,fontWeight:600,cursor:"pointer",letterSpacing:P?"0.08em":void 0},title:v?C||"Failed":P?`Clipboard blocked \u2014 code: ${R.code}`:m?`${f.length} 2FA personas`:`Copy 2FA code for ${f[0]}`,children:[jsxRuntime.jsx(x,{d:v?p.alert:L?p.check:P?p.copy:p.shield,size:10}),L?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Copied"}):P?jsxRuntime.jsx(jsxRuntime.Fragment,{children:R.code}):v?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Failed"}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:["2FA",m&&` \xB7${f.length}`]})]})}if(f.length===1){let m=f[0],S=M===m,v=R?.slug===m,$=v&&R.copied,L=v&&!R.copied,P=g===m,k=P?c.red:$?c.green:L?c.amber:c.purple;return jsxRuntime.jsxs("button",{onClick:b=>{b.stopPropagation(),V(m);},disabled:S,style:{...nt(k),cursor:S?"wait":"pointer",opacity:S?.6:1},title:P?C||"Failed":L?`Clipboard blocked \u2014 code: ${R.code}`:`Copy 2FA code for ${m}`,children:[jsxRuntime.jsx(x,{d:P?p.alert:$?p.check:L?p.copy:p.shield,size:12}),$?"Copied":L?R.code:P?"Failed":S?"\u2026":`2FA \xB7 ${m}`]})}let j=!!g&&!d,U=!!R&&R.copied,Y=!!R&&!R.copied,J=j?c.red:U?c.green:Y?c.amber:c.purple,ee=react.useRef(null),le=react.useRef(null);react.useLayoutEffect(()=>{if(!d)return;let m=ee.current,S=le.current;if(!m||!S||typeof window>"u")return;let v=()=>{let $=m.getBoundingClientRect(),L=S.getBoundingClientRect(),P=window.innerWidth,k=window.innerHeight,b=$.left,N=$.top-L.height-6;N<8&&(N=$.bottom+6);let G=Math.max(8,P-L.width-8),te=Math.max(8,k-L.height-8);b=Math.min(Math.max(b,8),G),N=Math.min(Math.max(N,8),te),S.style.left=`${Math.round(b)}px`,S.style.top=`${Math.round(N)}px`;};return v(),window.addEventListener("scroll",v,true),window.addEventListener("resize",v),()=>{window.removeEventListener("scroll",v,true),window.removeEventListener("resize",v);}},[d,f.length,C]),react.useEffect(()=>{if(!d)return;let m=S=>{let v=S.target;le.current?.contains(v)||ee.current?.contains(v)||u(false);};return document.addEventListener("mousedown",m),()=>document.removeEventListener("mousedown",m)},[d]);let z=d&&typeof document<"u"?reactDom.createPortal(jsxRuntime.jsxs("div",{ref:le,onPointerDown:m=>m.stopPropagation(),onMouseDown:m=>m.stopPropagation(),style:{position:"fixed",left:-9999,top:-9999,background:c.bg,border:`1px solid ${c.border}`,borderRadius:6,boxShadow:`0 8px 24px ${c.shadow}`,padding:4,minWidth:220,maxWidth:typeof window<"u"?Math.min(420,window.innerWidth-16):420,zIndex:1e5,fontFamily:"ui-monospace, SFMono-Regular, monospace"},children:[f.map(m=>{let S=M===m;return jsxRuntime.jsxs("button",{onClick:v=>{v.stopPropagation(),V(m);},disabled:S,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:S?"wait":"pointer",fontSize:"10px",color:c.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:v=>v.currentTarget.style.background=c.btnHover,onMouseLeave:v=>v.currentTarget.style.background="transparent",children:[jsxRuntime.jsx(x,{d:p.shield,size:10}),jsxRuntime.jsx("span",{style:{flex:1,overflowWrap:"anywhere",lineHeight:1.3},children:m}),S&&jsxRuntime.jsx("span",{style:{color:c.textMuted,fontSize:9},children:"\u2026"})]},m)}),C&&jsxRuntime.jsx("div",{style:{padding:"4px 8px",fontSize:9,color:c.red},children:C})]}),document.body):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("button",{ref:ee,onClick:m=>{m.stopPropagation(),u(S=>!S),n(null),K(null);},style:{...nt(J),cursor:"pointer"},title:j?C||"Failed":Y?`Clipboard blocked \u2014 code: ${R.code}`:"Choose a persona to copy a 2FA code for",children:[jsxRuntime.jsx(x,{d:j?p.alert:U?p.check:Y?p.copy:p.shield,size:12}),U?"Copied":Y?R.code:j?"Failed":`2FA \xB7 ${f.length}`,jsxRuntime.jsx(x,{d:d?p.chevronUp:p.chevronDown,size:8})]}),z]})}function nt(t){return {display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${t}15`,color:t,textDecoration:"none",border:`1px solid ${t}30`}}var ot="botbuddy-widget-state";function Lt({config:t,appSlug:r,environment:s,ticketId:f,testRunId:y,testRunToken:c,targetUrl:T,version:w,commitSha:_,prNumber:d,branchName:u,onNavigate:M,displayName:W="human",defaultMode:R="mini",defaultPosition:F}){let C=Tt(),n=react.useMemo(()=>Rt(C),[C]),g=react.useMemo(()=>$t(n),[n]),[K,V]=react.useState(false),[j,U]=react.useState(false),[Y,J]=react.useState(false),ee=react.useRef(false),le=t.dashboardUrl||"https://app.bot-buddy.ai",z=Ee(le),S=(()=>{try{let e=typeof window<"u"?localStorage.getItem(ot):null;if(e)return JSON.parse(e)}catch{}return null})(),[v,$]=react.useState(S?.mode||R),[L,P]=react.useState(""),[k,b]=react.useState(null),[N,G]=react.useState(null),[te,it]=react.useState(new Set),[ne,Le]=react.useState(""),st=react.useCallback(e=>{it(a=>{let h=new Set(a);return h.has(e)?h.delete(e):h.add(e),h});},[]),at=S?.x??F?.x??16,lt=S?.y??F?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:B,setPos:we,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,didDrag:ke}=Re(at,lt),ue=react.useRef(null);react.useEffect(()=>{try{localStorage.setItem(ot,JSON.stringify({mode:v,x:B.x,y:B.y}));}catch{}},[v,B.x,B.y]),react.useLayoutEffect(()=>{if(typeof window>"u")return;let e=ue.current;if(!e)return;let a=e.getBoundingClientRect(),h=Te(B.x,B.y,a.width,a.height,window.innerWidth,window.innerHeight);(h.x!==B.x||h.y!==B.y)&&we(h);}),react.useEffect(()=>{if(typeof window>"u")return;let e=()=>{let a=ue.current;if(!a)return;let h=a.getBoundingClientRect(),D=Te(B.x,B.y,h.width,h.height,window.innerWidth,window.innerHeight);(D.x!==B.x||D.y!==B.y)&&we(D);};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[B.x,B.y,we]);let We=react.useRef(z.isAuthenticated);react.useEffect(()=>{!We.current&&z.isAuthenticated&&$("max"),We.current=z.isAuthenticated;},[z.isAuthenticated]);let Ie="botbuddy-widget-max-size",dt=()=>{try{let e=localStorage.getItem(Ie);if(e)return JSON.parse(e)}catch{}return {w:340,h:500}},[ge,Ae]=react.useState(dt),fe=react.useRef(false),me=react.useRef({x:0,y:0,w:0,h:0}),ct=react.useCallback(e=>{e.stopPropagation(),fe.current=true,me.current={x:e.clientX,y:e.clientY,w:ge.w,h:ge.h},e.target.setPointerCapture(e.pointerId);},[ge]),pt=react.useCallback(e=>{if(!fe.current)return;let a=Math.max(280,Math.min(600,me.current.w+(e.clientX-me.current.x))),h=Math.max(300,Math.min(window.innerHeight*.9,me.current.h+(e.clientY-me.current.y)));Ae({w:a,h});},[]),ut=react.useCallback(()=>{fe.current&&(fe.current=false,Ae(e=>(localStorage.setItem(Ie,JSON.stringify(e)),e)));},[]),be=T??(typeof window<"u"?window.location.href:void 0),De=z.displayName||W,[O,Fe]=react.useState(null);react.useEffect(()=>{if(z.isAuthenticated)return;let e=new URLSearchParams;c&&e.set("token",c),f&&e.set("ticket_id",f),e.set("app_slug",r),s&&e.set("environment",s),y&&e.set("test_run_id",y),be&&e.set("target_url",be),w&&e.set("version",w),_&&e.set("commit_sha",_),d&&e.set("pr_number",String(d)),u&&e.set("branch_name",u),fetch(`${t.serverUrl}/widget/preview?${e}`,{headers:{apikey:t.anonKey}}).then(a=>a.json()).then(a=>Fe(a)).catch(()=>Fe(null));},[z.isAuthenticated,t.serverUrl,t.anonKey,r,s,f,y,c,be,w,_,d,u]);let{run:l,widgetState:q,fetchRun:gt,setVerdict:Ne,markComplete:ft,resetRun:mt}=Pe({config:t,appSlug:r,environment:s,ticketId:f,testRunId:y,testRunToken:c,targetUrl:be,version:w,commitSha:_,prNumber:d?String(d):void 0,branchName:u,authToken:z.token,onAuthExpired:z.logout}),xe=react.useCallback(async(e,a,h)=>{G(e);try{await Ne(e,a,h,De);}finally{G(null),b(null),P("");}},[Ne,De]),E=l?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},ht=E.total>0&&E.pending===0,oe=q==="completed",ye=react.useMemo(()=>{let e=l?.test_cases||[];if(!ne.trim())return e;let a=ne.toLowerCase();return e.filter(h=>h.title.toLowerCase().includes(a)||h.description&&h.description.toLowerCase().includes(a)||h.url_path&&h.url_path.toLowerCase().includes(a)||h.seed_user&&h.seed_user.toLowerCase().includes(a))},[l?.test_cases,ne]),Ue=react.useMemo(()=>{let e=ye,a=l?.test_cases||[];if(new Set(a.map(A=>A.source_pr_number)).size<=1)return null;let D=[],he=new Map;e.forEach(A=>{let H=A.source_pr_number;he.has(H)||he.set(H,[]),he.get(H).push(A);});let bt=[...he.keys()].sort((A,H)=>A===null?1:H===null?-1:H-A);for(let A of bt){let H=he.get(A),_e={total:H.length,pass:0,fail:0,skip:0,pending:0};H.forEach(qe=>{qe.verdict in _e&&_e[qe.verdict]++;}),D.push({key:A!=null?`pr-${A}`:"general",label:A!=null?`PR #${A}`:"General",cases:H,summary:_e});}return D.filter(A=>A.cases.length>0)},[ye,l?.test_cases]),He=E.total>0?(E.pass+E.fail)/E.total*100:0,X=s??l?.environment??null,Oe=react.useMemo(()=>{if(!X||X==="production")return [];let e=l?.test_cases||[],a=new Set;for(let h of e)h.seed_user&&a.add(Bt(h.seed_user));return [...a]},[l?.test_cases,X]),Se=react.useMemo(()=>{let e=l?.auto_tooltip_seconds??O?.auto_tooltip_seconds;return e!=null&&e>0?e*1e3:0},[l,O]),Ve=q==="ready"||q==="completed"||O?.enabled&&O.run;react.useEffect(()=>{if(!Ve||ee.current||Se<=0)return;ee.current=true,U(true);let e=window.setTimeout(()=>U(false),Se);return ()=>window.clearTimeout(e)},[Ve,Se]);let Ke=e=>jsxRuntime.jsxs("div",{style:g.caseRow,children:[jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"},children:[jsxRuntime.jsx("div",{style:{marginTop:"2px",flexShrink:0,color:zt[e.verdict]},children:N===e.id?jsxRuntime.jsx(x,{d:p.loader,className:""}):jsxRuntime.jsx(x,{d:Pt[e.verdict],className:""})}),jsxRuntime.jsxs("div",{style:{minWidth:0,flex:1},children:[jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.text,lineHeight:1.3},children:e.title}),e.description&&jsxRuntime.jsx("div",{style:{fontSize:"9px",color:n.gripColor,marginTop:"2px"},children:e.description}),e.seed_user&&jsxRuntime.jsxs("div",{style:{fontSize:"9px",color:n.amber,marginTop:"3px",display:"inline-flex",alignItems:"center",gap:"4px",padding:"2px 6px",borderRadius:"4px",background:`${n.amber}12`,border:`1px solid ${n.amber}30`},children:[jsxRuntime.jsx(x,{d:p.key,size:10}),jsxRuntime.jsx("span",{children:e.seed_user})]}),e.url_path&&jsxRuntime.jsxs("a",{href:e.url_path,target:"_blank",rel:"noopener noreferrer",onClick:a=>{a.stopPropagation(),M&&(a.preventDefault(),M(e.url_path));},style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginTop:"2px",display:"inline-flex",alignItems:"center",gap:"2px",textDecoration:"none",position:"relative",zIndex:1,pointerEvents:"auto"},children:[jsxRuntime.jsx(x,{d:p.externalLink,size:10}),e.url_path]}),e.verdict==="fail"&&e.fail_reason&&jsxRuntime.jsxs("div",{style:{fontSize:"9px",color:n.red,marginTop:"2px"},children:["\u2717 ",e.fail_reason]})]})]}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px",marginTop:"4px",marginLeft:"22px"},children:[["pass","fail","skip"].map(a=>jsxRuntime.jsx("button",{onClick:()=>{if(e.verdict===a){xe(e.id,"pending"),b(null);return}if(a==="fail"){b(e.id),P("");return}b(null),xe(e.id,a);},disabled:N!==null,style:g.verdictBtn(e.verdict===a,a==="pass"?n.green:a==="fail"?n.red:n.amber),children:a.toUpperCase()},a)),e.created_by_agent_name&&jsxRuntime.jsxs("span",{style:{fontSize:"8px",color:n.purple,marginLeft:"4px",display:"inline-flex",alignItems:"center",gap:"2px"},children:[jsxRuntime.jsx(x,{d:p.bot,size:8}),e.created_by_agent_name]}),e.verdict_by_display_name&&jsxRuntime.jsxs("span",{style:{fontSize:"8px",color:n.textFaint,marginLeft:"auto",display:"inline-flex",alignItems:"center",gap:"3px"},children:[e.verdict_by_display_name,e.verdict_at&&jsxRuntime.jsx("span",{style:{opacity:.7},children:Ct(e.verdict_at)})]})]}),k===e.id&&jsxRuntime.jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsxRuntime.jsx("input",{autoFocus:true,value:L,onChange:a=>P(a.target.value),onKeyDown:a=>{a.key==="Enter"&&xe(e.id,"fail",L.trim()||void 0),a.key==="Escape"&&(b(null),P(""));},placeholder:"Reason (optional)...",style:g.input}),jsxRuntime.jsx("button",{onClick:()=>{xe(e.id,"fail",L.trim()||void 0);},style:g.verdictBtn(true,n.red),children:"\u2713"})]})]},e.id);if((q==="no-match"||q==="loading")&&!(!z.isAuthenticated&&O?.enabled&&O.run))return null;if(!z.isAuthenticated&&O?.enabled&&O.run){let e=O.run,a=e.summary,h=e.status==="completed";return jsxRuntime.jsx("div",{ref:ue,style:{...g.root,left:B.x,top:B.y},children:jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>V(true),onMouseLeave:()=>{V(false),J(false),U(false);},children:[jsxRuntime.jsxs("div",{style:{...g.pill(h),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe();},children:[jsxRuntime.jsx(x,{d:p.grip,size:10,className:""}),e.ticket_id&&e.ticket_url?jsxRuntime.jsx("a",{href:e.ticket_url,target:"_blank",rel:"noopener noreferrer",onClick:D=>D.stopPropagation(),style:{color:n.amber,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:e.ticket_id}):null,e.pr_url?jsxRuntime.jsxs("a",{href:e.pr_url,target:"_blank",rel:"noopener noreferrer",onClick:D=>D.stopPropagation(),style:{color:n.blue,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:["PR#",e.pr_number??e.pr_id]}):null,e.created_by_agent_name?e.codex_thread_id?jsxRuntime.jsxs("a",{href:`codex://threads/${e.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",onClick:D=>D.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsxRuntime.jsx(x,{d:p.terminal,size:10}),e.created_by_agent_name]}):jsxRuntime.jsxs("span",{style:{color:n.purple,fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsxRuntime.jsx(x,{d:p.bot,size:10}),e.created_by_agent_name]}):null,jsxRuntime.jsxs("span",{style:h?{color:n.green}:void 0,children:[a.pass,"/",a.total]}),a.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[a.fail,"\u2717"]}),jsxRuntime.jsx("span",{onClick:D=>{D.stopPropagation(),z.openLogin();},style:{color:n.textMuted,fontWeight:400,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},children:"Sign in"})]}),!Y&&(K||j)&&e.title&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsxRuntime.jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:e.title}),(e.description||e.intro_notes)&&jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:e.description||e.intro_notes}),jsxRuntime.jsx("div",{style:{marginTop:"4px",fontSize:"9px",color:n.textFaint},children:'Click "Sign in" to start testing'})]})]})})}if(!z.isAuthenticated)return jsxRuntime.jsxs("div",{ref:ue,style:{...g.root,left:B.x,top:B.y,width:220,minHeight:0,cursor:"move",userSelect:"none",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`},onPointerDown:de,onPointerMove:ce,onPointerUp:pe,children:[jsxRuntime.jsx("div",{style:{...g.handle,borderBottom:"none"},children:jsxRuntime.jsxs("div",{style:g.sub,children:[jsxRuntime.jsx(x,{d:p.grip,size:10,className:""}),jsxRuntime.jsx(x,{d:p.clipboard,size:12,className:""}),jsxRuntime.jsx("span",{style:{fontWeight:600},children:"BotBuddy"})]})}),jsxRuntime.jsxs("div",{style:{padding:"12px 14px",textAlign:"center"},children:[jsxRuntime.jsx("div",{style:{fontSize:"9px",color:n.textMuted,marginBottom:"8px"},children:"Sign in to access test cases"}),jsxRuntime.jsx("button",{onClick:e=>{e.stopPropagation(),z.openLogin();},style:{fontSize:"10px",fontWeight:600,padding:"6px 16px",borderRadius:"6px",border:`1px solid ${n.green}`,background:`${n.green}22`,color:n.green,cursor:"pointer",width:"100%"},children:"Sign in to test"})]})]});let je=()=>{ke.current||(U(false),$(e=>{let a=e==="mini"?"max":"mini";return J(a==="mini"),a}));},Ye=({icon:e,onClick:a})=>jsxRuntime.jsx("button",{style:g.btn,onClick:h=>{h.stopPropagation(),a(h);},children:jsxRuntime.jsx(x,{d:e,className:""})}),Je=()=>jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",gap:"8px",flexWrap:"wrap",alignItems:"center",borderTop:`1px solid ${n.borderSubtle}`,flexShrink:0},children:[l?.pr_url&&jsxRuntime.jsxs("a",{href:l.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.blue),textDecoration:"none"},children:[jsxRuntime.jsx(x,{d:p.pr,size:12}),l.pr_number?`PR#${l.pr_number}`:l.pr_id||"PR",jsxRuntime.jsx(x,{d:p.externalLink,size:8})]}),l?.ticket_url&&jsxRuntime.jsxs("a",{href:l.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.amber),textDecoration:"none"},children:[jsxRuntime.jsx(x,{d:p.ticket,size:12}),l.ticket_id||"Ticket",jsxRuntime.jsx(x,{d:p.externalLink,size:8})]}),l?.created_by_agent_name&&(l.codex_thread_id?jsxRuntime.jsxs("a",{href:`codex://threads/${l.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.purple),textDecoration:"none"},children:[jsxRuntime.jsx(x,{d:p.bot,size:12}),l.created_by_agent_name,jsxRuntime.jsx(x,{d:p.externalLink,size:8})]}):jsxRuntime.jsxs("span",{style:{...g.link(n.purple)},children:[jsxRuntime.jsx(x,{d:p.bot,size:12}),l.created_by_agent_name]})),X&&jsxRuntime.jsx(tt,{config:t,appSlug:r,environment:X,seededUsers:Oe,authToken:z.token,tk:n,onAuthExpired:z.logout}),jsxRuntime.jsx("span",{style:{...g.badge(l?.environment||"custom"),marginLeft:"auto"},children:l?.environment})]}),Ge=()=>jsxRuntime.jsxs("div",{style:{padding:"4px 12px",display:"flex",alignItems:"center",justifyContent:"center",borderTop:`1px solid ${n.borderSubtle}`,background:n.bgSoft,flexShrink:0},children:[jsxRuntime.jsxs("button",{onClick:()=>{navigator.clipboard.writeText("0.9.12");},style:{fontSize:"9px",fontWeight:600,color:n.versionText,letterSpacing:"0.08em",background:"none",border:"none",cursor:"pointer",display:"inline-flex",alignItems:"center",gap:"4px",padding:0},title:"Copy version",children:["BotBuddy ",jsxRuntime.jsx("span",{style:{color:n.versionNum},children:"v0.9.12"})]}),z.isAuthenticated&&jsxRuntime.jsx("button",{onClick:e=>{e.stopPropagation(),z.logout();},style:{fontSize:"8px",color:n.textFaint,background:"none",border:"none",cursor:"pointer",marginLeft:"8px",padding:"0 4px",textDecoration:"underline"},title:"Sign out of widget",children:"sign out"})]});return jsxRuntime.jsxs("div",{ref:ue,style:{...g.root,left:B.x,top:B.y},children:[v==="mini"&&jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>V(true),onMouseLeave:()=>{V(false),J(false),U(false);},children:[jsxRuntime.jsxs("div",{style:{...g.pill(oe),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe(),ke.current||je();},children:[jsxRuntime.jsx(x,{d:p.grip,size:9,className:""}),l?.ticket_id&&jsxRuntime.jsx("span",{style:{color:n.amber,fontWeight:600},children:l.ticket_id}),l?.pr_number&&jsxRuntime.jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",l.pr_number]}),jsxRuntime.jsxs("span",{style:oe?{color:n.green}:void 0,children:[E.pass,"/",E.total]}),E.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[E.fail,"\u2717"]}),X&&jsxRuntime.jsx(tt,{config:t,appSlug:r,environment:X,seededUsers:Oe,authToken:z.token,tk:n,compact:true,onExpand:()=>$("expanded"),onAuthExpired:z.logout})]}),!Y&&(K||j)&&l?.title&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsxRuntime.jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:l.title}),(l.description||l.intro_notes)&&jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:l.description||l.intro_notes})]})]}),v==="expanded"&&jsxRuntime.jsxs("div",{style:g.card(300,oe),children:[jsxRuntime.jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:je,children:[jsxRuntime.jsx(x,{d:p.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:g.title,children:l?.title}),jsxRuntime.jsx("div",{style:g.sub,children:l?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",l.branch_name]})})]}),jsxRuntime.jsx(x,{d:p.chevronUp,className:""}),jsxRuntime.jsx(Ye,{icon:p.minus,onClick:()=>{U(false),J(true),$("mini");}})]}),jsxRuntime.jsxs("div",{style:g.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[E.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[E.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[E.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[E.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:E.total})]}),l?.description&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:l.description}),Je(),Ge(),jsxRuntime.jsx("div",{style:g.progress,children:jsxRuntime.jsx("div",{style:g.progressBar(He)})})]}),v==="max"&&jsxRuntime.jsxs("div",{style:{...g.card(ge.w,oe),height:ge.h,position:"relative"},children:[jsxRuntime.jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:()=>{ke.current||$("expanded");},children:[jsxRuntime.jsx(x,{d:p.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:g.title,children:l?.title}),jsxRuntime.jsx("div",{style:g.sub,children:l?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",l.branch_name]})})]}),jsxRuntime.jsx(x,{d:p.chevronDown,className:""}),jsxRuntime.jsx(Ye,{icon:p.minus,onClick:()=>{U(false),J(true),$("mini");}})]}),jsxRuntime.jsxs("div",{style:g.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[E.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[E.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[E.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[E.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:E.total})]}),l?.intro_notes&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:l.intro_notes}),(l?.test_cases||[]).length>5&&jsxRuntime.jsxs("div",{style:{padding:"4px 12px",borderBottom:`1px solid ${n.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",flexShrink:0},children:[jsxRuntime.jsx(x,{d:p.search,size:11,className:""}),jsxRuntime.jsx("input",{value:ne,onChange:e=>Le(e.target.value),placeholder:"Filter test cases...",style:{flex:1,fontSize:"10px",background:"transparent",border:"none",outline:"none",color:n.text,fontFamily:"monospace"}}),ne&&jsxRuntime.jsx("button",{onClick:()=>Le(""),style:{background:"none",border:"none",cursor:"pointer",color:n.textFaint,fontSize:"10px",padding:0},children:"\u2715"})]}),q==="error"&&jsxRuntime.jsxs("div",{style:{padding:"12px",textAlign:"center"},children:[jsxRuntime.jsx(x,{d:p.alert,className:""}),jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsxRuntime.jsx("button",{onClick:gt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),oe&&jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsxRuntime.jsx(x,{d:p.checkAll,className:""}),jsxRuntime.jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsxRuntime.jsx("button",{onClick:mt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),q!=="error"&&jsxRuntime.jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(l?.test_cases||[]).length===0?jsxRuntime.jsx("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:"No test cases"}):ye.length===0?jsxRuntime.jsxs("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:['No matches for "',ne,'"']}):Ue?Ue.map(e=>{let a=te.has(e.key);return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>st(e.key),style:{width:"100%",display:"flex",alignItems:"center",gap:"6px",padding:"5px 12px",background:n.bgSoft,cursor:"pointer",border:"none",borderLeft:"none",borderRight:"none",borderBottomStyle:"solid",borderTopStyle:"solid",borderBottomWidth:"1px",borderTopWidth:"1px",borderBottomColor:n.borderSubtle,borderTopColor:n.borderSubtle,backgroundColor:n.bgSoft},children:[jsxRuntime.jsx(x,{d:a?p.chevronDown:p.chevronUp,size:10,className:""}),jsxRuntime.jsx("span",{style:{fontSize:"10px",fontWeight:700,color:n.blue,flex:1,textAlign:"left"},children:e.label}),jsxRuntime.jsxs("span",{style:{fontSize:"9px",color:n.green},children:[e.summary.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{fontSize:"9px",color:n.red},children:[e.summary.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{fontSize:"9px",color:n.gripColor},children:[e.summary.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{fontSize:"9px",color:n.textFaint},children:e.summary.total})]}),!a&&e.cases.map(h=>Ke(h))]},e.key)}):ye.map(e=>Ke(e))}),ht&&!oe&&jsxRuntime.jsxs("div",{style:{padding:"6px 12px",borderTop:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg,display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:0},children:[jsxRuntime.jsx("span",{style:{fontSize:"9px",color:n.green},children:"All resolved"}),jsxRuntime.jsx("button",{onClick:ft,style:{fontSize:"8px",padding:"2px 8px",borderRadius:"4px",background:"rgba(52,211,153,0.15)",color:n.green,border:`1px solid ${n.greenBorderSubtle}`,cursor:"pointer"},children:"COMPLETE"})]}),Je(),Ge(),jsxRuntime.jsx("div",{style:g.progress,children:jsxRuntime.jsx("div",{style:g.progressBar(He)})}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:0,right:0,width:16,height:16,cursor:"se-resize",zIndex:10,display:"flex",alignItems:"flex-end",justifyContent:"flex-end",padding:"2px",opacity:.3},onPointerDown:ct,onPointerMove:pt,onPointerUp:ut,onPointerEnter:e=>e.currentTarget.style.opacity="0.7",onPointerLeave:e=>{fe.current||(e.currentTarget.style.opacity="0.3");},children:jsxRuntime.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",children:jsxRuntime.jsx("path",{d:"M7 1v6H1",fill:"none",stroke:n.gripColor,strokeWidth:"1.5",strokeLinecap:"round"})})})]})]})}
2
- exports.TestRunWidget=Lt;exports.useDraggable=Re;exports.useRealtimeRefresh=ze;exports.useTestRun=Pe;exports.useWidgetAuth=Ee;
1
+ 'use strict';var react=require('react'),reactDom=require('react-dom'),jsxRuntime=require('react/jsx-runtime');var me=8;function Ue(e,r,i,c,d,a){let M=Math.max(me,d-i-me),m=Math.max(me,a-c-me);return {x:Math.min(Math.max(e,me),M),y:Math.min(Math.max(r,me),m)}}function De(e,r){let[i,c]=react.useState({x:e,y:r}),d=react.useRef(false),a=react.useRef({x:0,y:0}),M=react.useRef(false),m=react.useCallback(h=>{d.current=true,M.current=false,a.current={x:h.clientX-i.x,y:h.clientY-i.y},h.target.setPointerCapture(h.pointerId);},[i]),v=react.useCallback(h=>{d.current&&(M.current=true,c({x:h.clientX-a.current.x,y:h.clientY-a.current.y}));},[]),u=react.useCallback(()=>{d.current=false;},[]);return {pos:i,setPos:c,onPointerDown:m,onPointerMove:v,onPointerUp:u,didDrag:M}}function Fe(e,r,i){let c=react.useRef(i);c.current=i,react.useEffect(()=>{if(!r)return;if(e.supabaseUrl){let a=false,M=null,m=()=>{a||M||(M=setInterval(()=>c.current(),15e3));},v=null;try{let w=new URL(e.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(w.hostname);if(w.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");w.protocol=w.protocol==="https:"?"wss:":"ws:",v=w.toString().replace(/\/$/,"");}catch{m();}let u=null,h=null,A=null,D=0,G=()=>{if(!(a||!v)){try{u=new WebSocket(`${v}/realtime/v1/websocket?apikey=${e.anonKey}&vsn=1.0.0`);}catch{m();return}u.onopen=()=>{if(a||!u)return;let w={topic:`realtime:public:test_run_cases:test_run_id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_run_cases",filter:`test_run_id=eq.${r}`}]}},ref:String(++D)};u.send(JSON.stringify(w));let n={topic:`realtime:public:test_runs:id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_runs",filter:`id=eq.${r}`}]}},ref:String(++D)};u.send(JSON.stringify(n)),h=setInterval(()=>{u?.readyState===WebSocket.OPEN&&u.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++D)}));},3e4);},u.onmessage=w=>{try{JSON.parse(w.data).event==="postgres_changes"&&c.current();}catch{}},u.onclose=()=>{P(),a||(A=setTimeout(G,3e3));},u.onerror=()=>{u?.close();};}},P=()=>{h&&(clearInterval(h),h=null);};return G(),()=>{a=true,P(),A&&clearTimeout(A),M&&clearInterval(M),u&&(u.onclose=null,u.onerror=null,u.close());}}let d=setInterval(()=>c.current(),15e3);return ()=>clearInterval(d)},[e.supabaseUrl,e.anonKey,r]);}var It="botbuddy:created-test-run:";function Ut(e){if(!e)return "";try{return new URL(e).origin}catch{return e}}function Dt(e){return `${It}${encodeURIComponent([e.appSlug,e.environment||"",e.ticketId||"",Ut(e.targetUrl),e.branchName||""].join("|"))}`}function Ce(e,r){let i={apikey:e.anonKey};return r?i.Authorization=`Bearer ${r}`:e.apiKey?i.Authorization=`Bearer ${e.apiKey}`:i.Authorization=`Bearer ${e.anonKey}`,i}async function Ft(e){if(e)return e;try{let r=await fetch("/.botbuddy-token",{cache:"no-store"});if(r.ok){let i=(await r.text()).trim();if(i.startsWith("public_"))return i}}catch{}try{let r=undefined?.VITE_BOTBUDDY_TEST_RUN_TOKEN;if(r&&typeof r=="string"&&r.startsWith("public_"))return r}catch{}return null}function He(e){let[r,i]=react.useState(null),[c,d]=react.useState("loading"),a=Dt(e),[M,m]=react.useState(()=>{if(e.testRunId)return e.testRunId;try{return localStorage.getItem(a)||void 0}catch{return}}),v=e.testRunId||M,u=react.useCallback(P=>{if(i(P),!!P?.id){m(P.id);try{localStorage.setItem(a,P.id);}catch{}}},[a]),h=react.useCallback(async()=>{try{let P=await Ft(e.testRunToken);if(!P&&!v){d("no-match"),i(null);return}if(P&&!e.ticketId){d("no-match"),i(null);return}let w=new URLSearchParams;P&&w.set("token",P),e.ticketId&&w.set("ticket_id",e.ticketId),w.set("app_slug",e.appSlug),e.environment&&w.set("environment",e.environment),v&&w.set("test_run_id",v),e.targetUrl&&w.set("target_url",e.targetUrl),e.version&&w.set("version",e.version),e.commitSha&&w.set("commit_sha",e.commitSha),e.prNumber&&w.set("pr_number",String(e.prNumber)),e.branchName&&w.set("branch_name",e.branchName);let n=await fetch(`${e.config.serverUrl}/widget/test-run?${w.toString()}`,{headers:Ce(e.config,e.authToken)});if(n.status===404){d("no-match"),i(null);return}if(n.status===401||n.status===403){e.authToken&&e.onAuthExpired&&e.onAuthExpired(),d("error");return}if(!n.ok){d("error");return}let g=await n.json();if(!g||g.run===null){d("no-match"),i(null);return}u(g),d(g.status==="completed"?"completed":"ready");}catch{d("error");}},[e.config.serverUrl,e.config.anonKey,e.config.apiKey,e.authToken,e.appSlug,e.environment,e.ticketId,v,e.testRunToken,e.targetUrl,e.version,e.commitSha,e.branchName,e.prNumber,e.onAuthExpired,u]);return react.useEffect(()=>{h();},[h]),Fe(e.config,r?.id,h),{run:r,widgetState:c,fetchRun:h,setVerdict:async(P,w,n,g="human")=>(i(K=>{if(!K)return null;let V=K.test_cases.map(N=>N.id===P?{...N,verdict:w,fail_reason:w==="fail"&&n||null,verdict_by_display_name:g,verdict_at:new Date().toISOString()}:N),C={total:V.length,pending:0,pass:0,fail:0,skip:0};return V.forEach(N=>{N.verdict in C&&C[N.verdict]++;}),{...K,test_cases:V,summary:C}}),(await fetch(`${e.config.serverUrl}/widget/test-cases/${P}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...Ce(e.config,e.authToken)},body:JSON.stringify({verdict:w,fail_reason:n,display_name:g})})).ok),markComplete:async()=>r?(i(w=>w?{...w,status:"completed"}:null),d("completed"),(await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...Ce(e.config,e.authToken)}})).ok):false,resetRun:async()=>{if(!r)return false;let P=await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...Ce(e.config,e.authToken)}});return P.ok&&h(),P.ok},setRun:u}}var Oe="botbuddy-widget-auth-token",Ke="botbuddy-widget-auth-name";function je(e){let[r,i]=react.useState(()=>{try{return localStorage.getItem(Oe)}catch(m){return console.warn("Unable to read BotBuddy widget auth token",m),null}}),[c,d]=react.useState(()=>{try{return localStorage.getItem(Ke)}catch(m){return console.warn("Unable to read BotBuddy widget display name",m),null}});react.useEffect(()=>{let m=new URL(e).origin,v=u=>{if(u.origin===m&&u.data?.type==="botbuddy-widget-auth"&&u.data.token){let{token:h,displayName:A}=u.data;i(h),d(A||"human");try{localStorage.setItem(Oe,h),A&&localStorage.setItem(Ke,A);}catch(D){console.warn("Unable to persist BotBuddy widget auth token",D);}}};return window.addEventListener("message",v),()=>window.removeEventListener("message",v)},[e]);let a=react.useCallback(()=>{let m=new URL("/widget-auth",e);m.searchParams.set("origin",window.location.origin);let v=420,u=520,h=window.screenX+(window.innerWidth-v)/2,A=window.screenY+(window.innerHeight-u)/2;window.open(m.toString(),"botbuddy-auth",`width=${v},height=${u},left=${h},top=${A},popup=yes`);},[e]),M=react.useCallback(()=>{i(null),d(null);try{localStorage.removeItem(Oe),localStorage.removeItem(Ke);}catch(m){console.warn("Unable to clear BotBuddy widget auth token",m);}},[]);return {token:r,displayName:c,isAuthenticated:!!r,openLogin:a,logout:M}}var Re=null;function Ht(){try{if(typeof document<"u"){let e=document.querySelector("base[href]");if(e)return new URL(".botbuddy-totp.json",e.href).toString()}}catch{}return "/.botbuddy-totp.json"}function Pe(){return Re||(Re=(async()=>{if(typeof fetch>"u")return null;try{let e=await fetch(Ht(),{cache:"no-store"});if(!e.ok)return null;let r=await e.json();if(!r||typeof r!="object"||Array.isArray(r))return null;let i={};for(let[c,d]of Object.entries(r))typeof d=="string"&&d.length>0&&(i[c]=d);return i}catch{return null}})(),Re)}async function mt(e){return (await Pe())?.[e]??null}function Ot(e){let r=e.replace(/=+$/,"").replace(/\s+/g,"").toUpperCase(),i="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",c=[],d=0,a=0;for(let M of r){let m=i.indexOf(M);if(m<0)throw new Error("Invalid Base32 character in TOTP secret");a=a<<5|m,d+=5,d>=8&&(d-=8,c.push(a>>>d&255));}return Uint8Array.from(c)}async function bt(e,r=Date.now()){if(typeof crypto>"u"||!crypto.subtle)throw new Error("Web Crypto unavailable");let i=Ot(e),c=Math.floor(r/1e3/30),d=new Uint8Array(8),a=Math.floor(c/4294967296),M=c>>>0;d[0]=a>>>24&255,d[1]=a>>>16&255,d[2]=a>>>8&255,d[3]=a&255,d[4]=M>>>24&255,d[5]=M>>>16&255,d[6]=M>>>8&255,d[7]=M&255;let m=await crypto.subtle.importKey("raw",i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength),{name:"HMAC",hash:"SHA-1"},false,["sign"]),v=await crypto.subtle.sign("HMAC",m,d.buffer),u=new Uint8Array(v),h=u[u.length-1]&15;return (((u[h]&127)<<24|(u[h+1]&255)<<16|(u[h+2]&255)<<8|u[h+3]&255)%1e6).toString().padStart(6,"0")}function jt(e){let r=new Date(e),c=Date.now()-r.getTime();if(c<6e4)return "just now";if(c<36e5)return `${Math.floor(c/6e4)}m ago`;if(c<864e5)return `${Math.floor(c/36e5)}h ago`;let d=r.getDate(),a=r.toLocaleString("en",{month:"short"}),M=r.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${a} ${d}, ${M}`}var y=({d:e,className:r,size:i=14})=>jsxRuntime.jsx("svg",{className:r,width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsxRuntime.jsx("path",{d:e})}),f={clipboard:"M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2",check:"M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3",x:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20M15 9l-6 6M9 9l6 6",circle:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20",skip:"M5 4l10 8-10 8V4M19 5v14",grip:"M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01",minus:"M5 12h14",chevronUp:"M18 15l-6-6-6 6",chevronDown:"M6 9l6 6 6-6",externalLink:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",pr:"M6 3v18M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6M18 9a9 9 0 0 1-9 9",ticket:"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z",loader:"M21 12a9 9 0 1 1-6.219-8.56",checkAll:"M18 6L7 17l-5-5M22 10l-7.5 7.5L13 16",alert:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0M12 9v4M12 17h.01",bot:"M12 8V4H8M2 14h2M20 14h2M15 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M9 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M18 10a6 6 0 0 0-12 0v4a6 6 0 0 0 12 0Z",terminal:"M4 17l6-6-6-6M12 19h8",key:"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4",shield:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10",copy:"M20 9h-9a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",search:"M11 17.25a6.25 6.25 0 1 1 0-12.5 6.25 6.25 0 0 1 0 12.5ZM16 16l4.5 4.5"};function Vt(){let[e,r]=react.useState(()=>typeof window>"u"||window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");return react.useEffect(()=>{if(typeof window>"u")return;let i=document.documentElement,c=()=>i.classList.contains("dark")?"dark":i.classList.contains("light")?"light":null,d=c();d&&r(d);let a=window.matchMedia("(prefers-color-scheme: dark)"),M=v=>{let u=c();r(u||(v.matches?"dark":"light"));};a.addEventListener("change",M);let m=new MutationObserver(()=>{let v=c();r(v||(a.matches?"dark":"light"));});return m.observe(i,{attributes:true,attributeFilter:["class"]}),()=>{a.removeEventListener("change",M),m.disconnect();}},[]),e}function Yt(e){let r=e==="dark";return {bg:r?"rgb(30,30,30)":"rgb(255,255,255)",bgSoft:r?"rgba(255,255,255,0.02)":"rgba(0,0,0,0.02)",text:r?"#e5e5e5":"#1a1a1a",textMuted:r?"rgba(255,255,255,0.4)":"rgba(0,0,0,0.45)",textFaint:r?"#555":"#999",border:r?"rgba(255,255,255,0.15)":"rgba(0,0,0,0.12)",borderSubtle:r?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",shadow:r?"rgba(0,0,0,0.4)":"rgba(0,0,0,0.12)",inputBg:r?"rgba(0,0,0,0.3)":"rgba(0,0,0,0.04)",inputBorder:r?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.12)",green:"#34d399",greenBg:r?"rgba(52,211,153,0.05)":"rgba(52,211,153,0.08)",greenBorder:r?"rgba(52,211,153,0.6)":"rgba(52,211,153,0.5)",greenBorderSubtle:r?"rgba(52,211,153,0.2)":"rgba(52,211,153,0.15)",red:"#f87171",amber:"#f59e0b",blue:"#60a5fa",purple:"#a78bfa",versionText:r?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",versionNum:r?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",gripColor:r?"#888":"#aaa",btnHover:r?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.06)"}}var Jt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},Gt={pending:f.circle,pass:f.check,fail:f.x,skip:f.skip},xt={local:{bg:"rgba(59,130,246,0.15)",text:"#60a5fa",border:"rgba(59,130,246,0.3)"},preview:{bg:"rgba(168,85,247,0.15)",text:"#c084fc",border:"rgba(168,85,247,0.3)"},staging:{bg:"rgba(245,158,11,0.15)",text:"#fbbf24",border:"rgba(245,158,11,0.3)"},production:{bg:"rgba(239,68,68,0.15)",text:"#f87171",border:"rgba(239,68,68,0.3)"},custom:{bg:"rgba(128,128,128,0.15)",text:"#888",border:"rgba(128,128,128,0.3)"}},Xt=["app.supply-guard.io"];function qt(e,r=[]){if(!e)return false;let i=e.toLowerCase();return [...Xt,...r].map(d=>d.toLowerCase()).includes(i)}var Zt=e=>({root:{position:"fixed",zIndex:9999,userSelect:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},pill:r=>({display:"inline-flex",alignItems:"center",gap:"6px",padding:"4px 8px",borderRadius:"9999px",background:e.bg,border:r?`1px solid ${e.greenBorder}`:`1px solid ${e.border}`,boxShadow:r?`0 4px 12px ${e.shadow}, 0 0 0 1px ${e.greenBorderSubtle}`:`0 4px 12px ${e.shadow}`,cursor:"pointer",fontSize:"9px",color:e.text}),card:(r,i)=>({width:`${r}px`,borderRadius:"8px",background:e.bg,border:i?`1px solid ${e.greenBorder}`:`1px solid ${e.border}`,boxShadow:i?`0 8px 24px ${e.shadow}, 0 0 0 1px ${e.greenBorderSubtle}`:`0 8px 24px ${e.shadow}`,overflow:"hidden",display:"flex",flexDirection:"column"}),handle:{padding:"8px 12px",display:"flex",alignItems:"center",gap:"8px",cursor:"grab",borderBottom:`1px solid ${e.borderSubtle}`},title:{fontSize:"10px",fontWeight:600,color:e.text,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},sub:{fontSize:"9px",color:e.textMuted,display:"flex",alignItems:"center",gap:"6px"},btn:{padding:"2px",borderRadius:"4px",background:"transparent",border:"none",cursor:"pointer",color:e.gripColor,display:"flex",flexShrink:0},stats:{padding:"4px 12px",display:"flex",alignItems:"center",gap:"8px",fontSize:"9px",borderBottom:`1px solid ${e.borderSubtle}`},badge:r=>{let i=xt[r]||xt.custom;return {fontSize:"8px",padding:"0 4px",borderRadius:"4px",background:i.bg,color:i.text,border:`1px solid ${i.border}`,lineHeight:"14px"}},progress:{height:"2px",background:e.borderSubtle,flexShrink:0},progressBar:r=>({height:"100%",width:`${r}%`,background:"linear-gradient(to right, #34d399, #3b82f6)",transition:"width 0.5s"}),link:r=>({display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${r}15`,color:r,textDecoration:"none",border:"none",cursor:"pointer"}),caseRow:{padding:"6px 12px",borderBottom:`1px solid ${e.borderSubtle}`,transition:"background 0.15s"},verdictBtn:(r,i)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:r?`${i}33`:"transparent",color:r?i:e.gripColor,transition:"all 0.15s"}),input:{flex:1,fontSize:"9px",background:e.inputBg,border:`1px solid ${e.inputBorder}`,borderRadius:"4px",padding:"2px 6px",color:e.text,outline:"none"},humanBanner:{padding:"6px 12px",fontSize:"11px",fontWeight:600,color:e.green,borderBottom:`1px solid ${e.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",background:e.greenBg,cursor:"pointer",textDecoration:"none"}});function yt(e){return e.split("/")[0].trim()}async function Qt(e){try{if(typeof navigator<"u"&&navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{if(typeof document>"u")return !1;let r=document.createElement("textarea");r.value=e,r.setAttribute("readonly",""),r.style.position="fixed",r.style.top="0",r.style.left="0",r.style.opacity="0",r.style.pointerEvents="none",document.body.appendChild(r),r.focus(),r.select(),r.setSelectionRange(0,e.length);let i=document.execCommand("copy");return document.body.removeChild(r),i}catch{return false}}function $e({config:e,appSlug:r,environment:i,seededUsers:c,authToken:d,tk:a,compact:M=false,onExpand:m,onAuthExpired:v,testRunId:u,testRunToken:h,ticketId:A,targetUrl:D,version:G,commitSha:P,prNumber:w,branchName:n}){let[g,te]=react.useState(false),[K,V]=react.useState(null),[C,N]=react.useState(null),[H,ne]=react.useState(null),[ye,S]=react.useState(null);react.useEffect(()=>{i==="local"&&Pe();},[i]);let _e=react.useCallback(b=>{V(b),ne(null),S(null);let $=T=>{ne(T),S(b),window.setTimeout(()=>{S(_=>_===b?null:_),ne(_=>_===T?null:_);},3e3);},k=new URLSearchParams({app_slug:r,seed_user_slug:b,environment:i});u&&k.set("test_run_id",u),h&&k.set("public_token",h),A&&k.set("ticket_id",A),D&&k.set("target_url",D),G&&k.set("version",G),P&&k.set("commit_sha",P),w&&k.set("pr_number",String(w)),n&&k.set("branch_name",n);let W={apikey:e.anonKey};W.Authorization=`Bearer ${d||e.anonKey}`;let z=(async()=>{if(i==="local"){let T=await mt(b);if(T)try{return {ok:!0,code:await bt(T)}}catch{}}try{let T=await fetch(`${e.serverUrl}/widget/totp-code?${k}`,{headers:W});if(!T.ok){let j=await T.json().catch(()=>({error:`HTTP ${T.status}`}));return {ok:!1,status:T.status,error:j.error||`HTTP ${T.status}`}}let _=await T.json();return {ok:!0,code:String(_.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),L=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let T=z.then(_=>{if(!_.ok)throw new Error(_.error);return new Blob([_.code],{type:"text/plain"})});L=navigator.clipboard.write([new ClipboardItem({"text/plain":T})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let T=await z;if(!T.ok){T.status===401?$("BotBuddy sign-in expired \u2014 sign out and sign in again"):$(T.status===404?"No 2FA seed registered":T.error),V(null);return}let _=L?await L:false,j=_?true:await Qt(T.code),R=_||j;N({slug:b,code:T.code,copied:R}),window.setTimeout(()=>N(ee=>ee?.slug===b?null:ee),R?2500:6e3),te(false),V(null);})();},[e.serverUrl,e.anonKey,d,r,i,u,h,A,D,G,P,w,n]),re=react.useRef(null),X=react.useRef(null);if(react.useLayoutEffect(()=>{if(!g)return;let b=re.current,$=X.current;if(!b||!$||typeof window>"u")return;let k=()=>{let W=b.getBoundingClientRect(),z=$.getBoundingClientRect(),L=window.innerWidth,T=window.innerHeight,_=W.left,j=W.top-z.height-6;j<8&&(j=W.bottom+6);let R=Math.max(8,L-z.width-8),ee=Math.max(8,T-z.height-8);_=Math.min(Math.max(_,8),R),j=Math.min(Math.max(j,8),ee),$.style.left=`${Math.round(_)}px`,$.style.top=`${Math.round(j)}px`;};return k(),window.addEventListener("scroll",k,true),window.addEventListener("resize",k),()=>{window.removeEventListener("scroll",k,true),window.removeEventListener("resize",k);}},[g,c.length,H]),react.useEffect(()=>{if(!g)return;let b=$=>{let k=$.target;X.current?.contains(k)||re.current?.contains(k)||te(false);};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[g]),c.length===0)return null;if(M){let b=c.length>1,$=_=>{if(_.stopPropagation(),b&&m){m();return}_e(c[0]);},k=!!ye,W=!!C,z=W&&C.copied,L=W&&!C.copied,T=k?a.red:z?a.green:L?a.amber:a.purple;return jsxRuntime.jsxs("span",{onPointerDown:_=>_.stopPropagation(),onPointerUp:_=>_.stopPropagation(),onPointerMove:_=>_.stopPropagation(),onClick:$,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:T,fontWeight:600,cursor:"pointer",letterSpacing:L?"0.08em":void 0},title:k?H||"Failed":L?`Clipboard blocked \u2014 code: ${C.code}`:b?`${c.length} 2FA personas`:`Copy 2FA code for ${c[0]}`,children:[jsxRuntime.jsx(y,{d:k?f.alert:z?f.check:L?f.copy:f.shield,size:10}),z?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Copied"}):L?jsxRuntime.jsx(jsxRuntime.Fragment,{children:C.code}):k?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Failed"}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:["2FA",b&&` \xB7${c.length}`]})]})}if(c.length===1){let b=c[0],$=K===b,k=C?.slug===b,W=k&&C.copied,z=k&&!C.copied,L=ye===b,T=L?a.red:W?a.green:z?a.amber:a.purple;return jsxRuntime.jsxs("button",{onClick:_=>{_.stopPropagation(),_e(b);},disabled:$,style:{...vt(T),cursor:$?"wait":"pointer",opacity:$?.6:1},title:L?H||"Failed":z?`Clipboard blocked \u2014 code: ${C.code}`:`Copy 2FA code for ${b}`,children:[jsxRuntime.jsx(y,{d:L?f.alert:W?f.check:z?f.copy:f.shield,size:12}),W?"Copied":z?C.code:L?"Failed":$?"\u2026":`2FA \xB7 ${b}`]})}let O=!!ye&&!g,oe=!!C&&C.copied,q=!!C&&!C.copied,ze=O?a.red:oe?a.green:q?a.amber:a.purple,ie=g&&typeof document<"u"?reactDom.createPortal(jsxRuntime.jsxs("div",{ref:X,onPointerDown:b=>b.stopPropagation(),onMouseDown:b=>b.stopPropagation(),style:{position:"fixed",left:-9999,top:-9999,background:a.bg,border:`1px solid ${a.border}`,borderRadius:6,boxShadow:`0 8px 24px ${a.shadow}`,padding:4,minWidth:220,maxWidth:typeof window<"u"?Math.min(420,window.innerWidth-16):420,zIndex:1e5,fontFamily:"ui-monospace, SFMono-Regular, monospace"},children:[c.map(b=>{let $=K===b;return jsxRuntime.jsxs("button",{onClick:k=>{k.stopPropagation(),_e(b);},disabled:$,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:$?"wait":"pointer",fontSize:"10px",color:a.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:k=>k.currentTarget.style.background=a.btnHover,onMouseLeave:k=>k.currentTarget.style.background="transparent",children:[jsxRuntime.jsx(y,{d:f.shield,size:10}),jsxRuntime.jsx("span",{style:{flex:1,overflowWrap:"anywhere",lineHeight:1.3},children:b}),$&&jsxRuntime.jsx("span",{style:{color:a.textMuted,fontSize:9},children:"\u2026"})]},b)}),H&&jsxRuntime.jsx("div",{style:{padding:"4px 8px",fontSize:9,color:a.red},children:H})]}),document.body):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("button",{ref:re,onClick:b=>{b.stopPropagation(),te($=>!$),ne(null),S(null);},style:{...vt(ze),cursor:"pointer"},title:O?H||"Failed":q?`Clipboard blocked \u2014 code: ${C.code}`:"Choose a persona to copy a 2FA code for",children:[jsxRuntime.jsx(y,{d:O?f.alert:oe?f.check:q?f.copy:f.shield,size:12}),oe?"Copied":q?C.code:O?"Failed":`2FA \xB7 ${c.length}`,jsxRuntime.jsx(y,{d:g?f.chevronUp:f.chevronDown,size:8})]}),ie]})}function vt(e){return {display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${e}15`,color:e,textDecoration:"none",border:`1px solid ${e}30`}}var wt="botbuddy-widget-state";function en({config:e,appSlug:r,environment:i,ticketId:c,testRunId:d,testRunToken:a,targetUrl:M,version:m,commitSha:v,prNumber:u,branchName:h,onNavigate:A,displayName:D="human",defaultMode:G="mini",defaultPosition:P}){let w=Vt(),n=react.useMemo(()=>Yt(w),[w]),g=react.useMemo(()=>Zt(n),[n]),[te,K]=react.useState(false),[V,C]=react.useState(false),[N,H]=react.useState(false),ne=react.useRef(false),ye=e.dashboardUrl||"https://app.bot-buddy.ai",S=je(ye),re=(()=>{try{let t=typeof window<"u"?localStorage.getItem(wt):null;if(t)return JSON.parse(t)}catch{}return null})(),[X,O]=react.useState(re?.mode||G),[oe,q]=react.useState(""),[ze,ie]=react.useState(null),[b,$]=react.useState(null),[k,W]=react.useState(new Set),[z,L]=react.useState(""),T=react.useCallback(t=>{W(l=>{let x=new Set(l);return x.has(t)?x.delete(t):x.add(t),x});},[]),_=re?.x??P?.x??16,j=re?.y??P?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:R,setPos:ee,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,didDrag:Be}=De(_,j),ue=react.useRef(null);react.useEffect(()=>{try{localStorage.setItem(wt,JSON.stringify({mode:X,x:R.x,y:R.y}));}catch{}},[X,R.x,R.y]),react.useLayoutEffect(()=>{if(typeof window>"u")return;let t=ue.current;if(!t)return;let l=t.getBoundingClientRect(),x=Ue(R.x,R.y,l.width,l.height,window.innerWidth,window.innerHeight);(x.x!==R.x||x.y!==R.y)&&ee(x);}),react.useEffect(()=>{if(typeof window>"u")return;let t=()=>{let l=ue.current;if(!l)return;let x=l.getBoundingClientRect(),U=Ue(R.x,R.y,x.width,x.height,window.innerWidth,window.innerHeight);(U.x!==R.x||U.y!==R.y)&&ee(U);};return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[R.x,R.y,ee]);let Ve=react.useRef(S.isAuthenticated);react.useEffect(()=>{!Ve.current&&S.isAuthenticated&&O("max"),Ve.current=S.isAuthenticated;},[S.isAuthenticated]);let Ye="botbuddy-widget-max-size",kt=()=>{try{let t=localStorage.getItem(Ye);if(t)return JSON.parse(t)}catch{}return {w:340,h:500}},[ve,Je]=react.useState(kt),we=react.useRef(false),Se=react.useRef({x:0,y:0,w:0,h:0}),_t=react.useCallback(t=>{t.stopPropagation(),we.current=true,Se.current={x:t.clientX,y:t.clientY,w:ve.w,h:ve.h},t.target.setPointerCapture(t.pointerId);},[ve]),Mt=react.useCallback(t=>{if(!we.current)return;let l=Math.max(280,Math.min(600,Se.current.w+(t.clientX-Se.current.x))),x=Math.max(300,Math.min(window.innerHeight*.9,Se.current.h+(t.clientY-Se.current.y)));Je({w:l,h:x});},[]),Tt=react.useCallback(()=>{we.current&&(we.current=false,Je(t=>(localStorage.setItem(Ye,JSON.stringify(t)),t)));},[]),Y=M??(typeof window<"u"?window.location.href:void 0),Ge=S.displayName||D,[Z,Xe]=react.useState(null);react.useEffect(()=>{if(S.isAuthenticated)return;let t=new URLSearchParams;a&&t.set("token",a),c&&t.set("ticket_id",c),t.set("app_slug",r),i&&t.set("environment",i),d&&t.set("test_run_id",d),Y&&t.set("target_url",Y),m&&t.set("version",m),v&&t.set("commit_sha",v),u&&t.set("pr_number",String(u)),h&&t.set("branch_name",h),fetch(`${e.serverUrl}/widget/preview?${t}`,{headers:{apikey:e.anonKey}}).then(l=>l.json()).then(l=>Xe(l)).catch(()=>Xe(null));},[S.isAuthenticated,e.serverUrl,e.anonKey,r,i,c,d,a,Y,m,v,u,h]);let{run:p,widgetState:se,fetchRun:Ct,setVerdict:qe,markComplete:Rt,resetRun:Pt,setRun:Ze}=He({config:e,appSlug:r,environment:i,ticketId:c,testRunId:d,testRunToken:a,targetUrl:Y,version:m,commitSha:v,prNumber:u?String(u):void 0,branchName:h,authToken:S.token,onAuthExpired:S.logout}),[Qe,et]=react.useState([]),[Ee,tt]=react.useState(false),[nt,rt]=react.useState(null),ge=qt(typeof window<"u"?window.location.hostname:void 0,e.productionHostnames||[]);react.useEffect(()=>{if((i??"local")!=="local"||ge){et([]);return}let t=true;return Pe().then(l=>{t&&et(Object.keys(l||{}));}),()=>{t=false;}},[i,ge]);let $t=react.useCallback(async()=>{if(!(!S.isAuthenticated||!S.token)){tt(true),rt(null);try{let t=await fetch(`${e.serverUrl}/widget/test-runs`,{method:"POST",headers:{"Content-Type":"application/json",apikey:e.anonKey,Authorization:`Bearer ${S.token}`},body:JSON.stringify({app_slug:r,environment:i||"local",target_url:Y,branch_name:h,commit_sha:v,pr_number:u,ticket_id:c,title:`${c||r} local validation`})}),l=await t.json().catch(()=>({}));if(!t.ok)throw new Error(l.error||`HTTP ${t.status}`);Ze(l),O("max");}catch(t){rt(t.message);}finally{tt(false);}}},[S.isAuthenticated,S.token,e.serverUrl,e.anonKey,r,i,Y,h,v,u,c,Ze]),Me=react.useCallback(async(t,l,x)=>{$(t);try{await qe(t,l,x,Ge);}finally{$(null),ie(null),q("");}},[qe,Ge]),B=p?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},zt=B.total>0&&B.pending===0,fe=se==="completed",Te=react.useMemo(()=>{let t=p?.test_cases||[];if(!z.trim())return t;let l=z.toLowerCase();return t.filter(x=>x.title.toLowerCase().includes(l)||x.description&&x.description.toLowerCase().includes(l)||x.url_path&&x.url_path.toLowerCase().includes(l)||x.seed_user&&x.seed_user.toLowerCase().includes(l))},[p?.test_cases,z]),ot=react.useMemo(()=>{let t=Te,l=p?.test_cases||[];if(new Set(l.map(I=>I.source_pr_number)).size<=1)return null;let U=[],ke=new Map;t.forEach(I=>{let J=I.source_pr_number;ke.has(J)||ke.set(J,[]),ke.get(J).push(I);});let Bt=[...ke.keys()].sort((I,J)=>I===null?1:J===null?-1:J-I);for(let I of Bt){let J=ke.get(I),Ae={total:J.length,pass:0,fail:0,skip:0,pending:0};J.forEach(ut=>{ut.verdict in Ae&&Ae[ut.verdict]++;}),U.push({key:I!=null?`pr-${I}`:"general",label:I!=null?`PR #${I}`:"General",cases:J,summary:Ae});}return U.filter(I=>I.cases.length>0)},[Te,p?.test_cases]),it=B.total>0?(B.pass+B.fail)/B.total*100:0,F=i??p?.environment??null,he=react.useMemo(()=>{if(!F||F==="production"||ge)return [];let t=p?.test_cases||[],l=new Set;for(let x of t)x.seed_user&&l.add(yt(x.seed_user));if(F==="local")for(let x of Qe)l.add(yt(x));return [...l]},[p?.test_cases,F,Qe,ge]),Le=react.useMemo(()=>{let t=p?.auto_tooltip_seconds??Z?.auto_tooltip_seconds;return t!=null&&t>0?t*1e3:0},[p,Z]),st=se==="ready"||se==="completed"||Z?.enabled&&Z.run;react.useEffect(()=>{if(!st||ne.current||Le<=0)return;ne.current=true,C(true);let t=window.setTimeout(()=>C(false),Le);return ()=>window.clearTimeout(t)},[st,Le]);let at=t=>jsxRuntime.jsxs("div",{style:g.caseRow,children:[jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"},children:[jsxRuntime.jsx("div",{style:{marginTop:"2px",flexShrink:0,color:Jt[t.verdict]},children:b===t.id?jsxRuntime.jsx(y,{d:f.loader,className:""}):jsxRuntime.jsx(y,{d:Gt[t.verdict],className:""})}),jsxRuntime.jsxs("div",{style:{minWidth:0,flex:1},children:[jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.text,lineHeight:1.3},children:t.title}),t.description&&jsxRuntime.jsx("div",{style:{fontSize:"9px",color:n.gripColor,marginTop:"2px"},children:t.description}),t.seed_user&&jsxRuntime.jsxs("div",{style:{fontSize:"9px",color:n.amber,marginTop:"3px",display:"inline-flex",alignItems:"center",gap:"4px",padding:"2px 6px",borderRadius:"4px",background:`${n.amber}12`,border:`1px solid ${n.amber}30`},children:[jsxRuntime.jsx(y,{d:f.key,size:10}),jsxRuntime.jsx("span",{children:t.seed_user})]}),t.url_path&&jsxRuntime.jsxs("a",{href:t.url_path,target:"_blank",rel:"noopener noreferrer",onClick:l=>{l.stopPropagation(),A&&(l.preventDefault(),A(t.url_path));},style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginTop:"2px",display:"inline-flex",alignItems:"center",gap:"2px",textDecoration:"none",position:"relative",zIndex:1,pointerEvents:"auto"},children:[jsxRuntime.jsx(y,{d:f.externalLink,size:10}),t.url_path]}),t.verdict==="fail"&&t.fail_reason&&jsxRuntime.jsxs("div",{style:{fontSize:"9px",color:n.red,marginTop:"2px"},children:["\u2717 ",t.fail_reason]})]})]}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px",marginTop:"4px",marginLeft:"22px"},children:[["pass","fail","skip"].map(l=>jsxRuntime.jsx("button",{onClick:()=>{if(t.verdict===l){Me(t.id,"pending"),ie(null);return}if(l==="fail"){ie(t.id),q("");return}ie(null),Me(t.id,l);},disabled:b!==null,style:g.verdictBtn(t.verdict===l,l==="pass"?n.green:l==="fail"?n.red:n.amber),children:l.toUpperCase()},l)),t.created_by_agent_name&&jsxRuntime.jsxs("span",{style:{fontSize:"8px",color:n.purple,marginLeft:"4px",display:"inline-flex",alignItems:"center",gap:"2px"},children:[jsxRuntime.jsx(y,{d:f.bot,size:8}),t.created_by_agent_name]}),t.verdict_by_display_name&&jsxRuntime.jsxs("span",{style:{fontSize:"8px",color:n.textFaint,marginLeft:"auto",display:"inline-flex",alignItems:"center",gap:"3px"},children:[t.verdict_by_display_name,t.verdict_at&&jsxRuntime.jsx("span",{style:{opacity:.7},children:jt(t.verdict_at)})]})]}),ze===t.id&&jsxRuntime.jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsxRuntime.jsx("input",{autoFocus:true,value:oe,onChange:l=>q(l.target.value),onKeyDown:l=>{l.key==="Enter"&&Me(t.id,"fail",oe.trim()||void 0),l.key==="Escape"&&(ie(null),q(""));},placeholder:"Reason (optional)...",style:g.input}),jsxRuntime.jsx("button",{onClick:()=>{Me(t.id,"fail",oe.trim()||void 0);},style:g.verdictBtn(true,n.red),children:"\u2713"})]})]},t.id);if((se==="no-match"||se==="loading")&&!(!S.isAuthenticated&&Z?.enabled&&Z.run)){if(!(F==="local"&&!ge))return null}if(!S.isAuthenticated&&Z?.enabled&&Z.run){let t=Z.run,l=t.summary,x=t.status==="completed";return jsxRuntime.jsx("div",{ref:ue,style:{...g.root,left:R.x,top:R.y},children:jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),H(false),C(false);},children:[jsxRuntime.jsxs("div",{style:{...g.pill(x),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe();},children:[jsxRuntime.jsx(y,{d:f.grip,size:10,className:""}),t.ticket_id&&t.ticket_url?jsxRuntime.jsx("a",{href:t.ticket_url,target:"_blank",rel:"noopener noreferrer",onClick:U=>U.stopPropagation(),style:{color:n.amber,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:t.ticket_id}):null,t.pr_url?jsxRuntime.jsxs("a",{href:t.pr_url,target:"_blank",rel:"noopener noreferrer",onClick:U=>U.stopPropagation(),style:{color:n.blue,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:["PR#",t.pr_number??t.pr_id]}):null,t.created_by_agent_name?t.codex_thread_id?jsxRuntime.jsxs("a",{href:`codex://threads/${t.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",onClick:U=>U.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsxRuntime.jsx(y,{d:f.terminal,size:10}),t.created_by_agent_name]}):jsxRuntime.jsxs("span",{style:{color:n.purple,fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsxRuntime.jsx(y,{d:f.bot,size:10}),t.created_by_agent_name]}):null,jsxRuntime.jsxs("span",{style:x?{color:n.green}:void 0,children:[l.pass,"/",l.total]}),l.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[l.fail,"\u2717"]}),jsxRuntime.jsx("span",{onClick:U=>{U.stopPropagation(),S.openLogin();},style:{color:n.textMuted,fontWeight:400,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},children:"Sign in"})]}),!N&&(te||V)&&t.title&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsxRuntime.jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:t.title}),(t.description||t.intro_notes)&&jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:t.description||t.intro_notes}),jsxRuntime.jsx("div",{style:{marginTop:"4px",fontSize:"9px",color:n.textFaint},children:'Click "Sign in" to start testing'})]})]})})}if(!S.isAuthenticated)return jsxRuntime.jsxs("div",{ref:ue,style:{...g.root,left:R.x,top:R.y,width:220,minHeight:0,cursor:"move",userSelect:"none",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`},onPointerDown:de,onPointerMove:ce,onPointerUp:pe,children:[jsxRuntime.jsx("div",{style:{...g.handle,borderBottom:"none"},children:jsxRuntime.jsxs("div",{style:g.sub,children:[jsxRuntime.jsx(y,{d:f.grip,size:10,className:""}),jsxRuntime.jsx(y,{d:f.clipboard,size:12,className:""}),jsxRuntime.jsx("span",{style:{fontWeight:600},children:"BotBuddy"})]})}),jsxRuntime.jsxs("div",{style:{padding:"12px 14px",textAlign:"center"},children:[jsxRuntime.jsx("div",{style:{fontSize:"9px",color:n.textMuted,marginBottom:"8px"},children:"Sign in to access test cases"}),F==="local"&&he.length>0&&jsxRuntime.jsx("div",{style:{display:"flex",justifyContent:"center",marginBottom:"8px"},children:jsxRuntime.jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,testRunId:p?.id||d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout})}),jsxRuntime.jsx("button",{onClick:t=>{t.stopPropagation(),S.openLogin();},style:{fontSize:"10px",fontWeight:600,padding:"6px 16px",borderRadius:"6px",border:`1px solid ${n.green}`,background:`${n.green}22`,color:n.green,cursor:"pointer",width:"100%"},children:"Sign in to test"})]})]});if(!p&&F==="local"&&!ge)return jsxRuntime.jsxs("div",{ref:ue,style:{...g.root,left:R.x,top:R.y,width:240,minHeight:0,cursor:"move",userSelect:"none",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`},onPointerDown:de,onPointerMove:ce,onPointerUp:pe,children:[jsxRuntime.jsx("div",{style:{...g.handle,borderBottom:`1px solid ${n.borderSubtle}`},children:jsxRuntime.jsxs("div",{style:g.sub,children:[jsxRuntime.jsx(y,{d:f.grip,size:10,className:""}),jsxRuntime.jsx(y,{d:f.clipboard,size:12,className:""}),jsxRuntime.jsx("span",{style:{fontWeight:600},children:"BotBuddy"})]})}),jsxRuntime.jsxs("div",{style:{padding:"12px 14px",textAlign:"center"},children:[he.length>0&&jsxRuntime.jsx("div",{style:{display:"flex",justifyContent:"center",marginBottom:"8px"},children:jsxRuntime.jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,testRunId:d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout})}),jsxRuntime.jsx("button",{onClick:t=>{t.stopPropagation(),$t();},disabled:Ee,style:{fontSize:"10px",fontWeight:600,padding:"6px 12px",borderRadius:"6px",border:`1px solid ${n.green}`,background:`${n.green}22`,color:n.green,cursor:Ee?"wait":"pointer",width:"100%"},children:Ee?"Creating...":"Create test run for this branch"}),nt&&jsxRuntime.jsx("div",{style:{fontSize:"9px",color:n.red,marginTop:"8px"},children:nt})]})]});let lt=()=>{Be.current||(C(false),O(t=>{let l=t==="mini"?"max":"mini";return H(l==="mini"),l}));},dt=({icon:t,onClick:l})=>jsxRuntime.jsx("button",{style:g.btn,onClick:x=>{x.stopPropagation(),l(x);},children:jsxRuntime.jsx(y,{d:t,className:""})}),ct=()=>jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",gap:"8px",flexWrap:"wrap",alignItems:"center",borderTop:`1px solid ${n.borderSubtle}`,flexShrink:0},children:[p?.pr_url&&jsxRuntime.jsxs("a",{href:p.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.blue),textDecoration:"none"},children:[jsxRuntime.jsx(y,{d:f.pr,size:12}),p.pr_number?`PR#${p.pr_number}`:p.pr_id||"PR",jsxRuntime.jsx(y,{d:f.externalLink,size:8})]}),p?.ticket_url&&jsxRuntime.jsxs("a",{href:p.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.amber),textDecoration:"none"},children:[jsxRuntime.jsx(y,{d:f.ticket,size:12}),p.ticket_id||"Ticket",jsxRuntime.jsx(y,{d:f.externalLink,size:8})]}),p?.created_by_agent_name&&(p.codex_thread_id?jsxRuntime.jsxs("a",{href:`codex://threads/${p.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.purple),textDecoration:"none"},children:[jsxRuntime.jsx(y,{d:f.bot,size:12}),p.created_by_agent_name,jsxRuntime.jsx(y,{d:f.externalLink,size:8})]}):jsxRuntime.jsxs("span",{style:{...g.link(n.purple)},children:[jsxRuntime.jsx(y,{d:f.bot,size:12}),p.created_by_agent_name]})),F&&jsxRuntime.jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,testRunId:p?.id||d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout}),jsxRuntime.jsx("span",{style:{...g.badge(p?.environment||"custom"),marginLeft:"auto"},children:p?.environment})]}),pt=()=>jsxRuntime.jsxs("div",{style:{padding:"4px 12px",display:"flex",alignItems:"center",justifyContent:"center",borderTop:`1px solid ${n.borderSubtle}`,background:n.bgSoft,flexShrink:0},children:[jsxRuntime.jsxs("button",{onClick:()=>{navigator.clipboard.writeText("0.9.14");},style:{fontSize:"9px",fontWeight:600,color:n.versionText,letterSpacing:"0.08em",background:"none",border:"none",cursor:"pointer",display:"inline-flex",alignItems:"center",gap:"4px",padding:0},title:"Copy version",children:["BotBuddy ",jsxRuntime.jsx("span",{style:{color:n.versionNum},children:"v0.9.14"})]}),S.isAuthenticated&&jsxRuntime.jsx("button",{onClick:t=>{t.stopPropagation(),S.logout();},style:{fontSize:"8px",color:n.textFaint,background:"none",border:"none",cursor:"pointer",marginLeft:"8px",padding:"0 4px",textDecoration:"underline"},title:"Sign out of widget",children:"sign out"})]});return jsxRuntime.jsxs("div",{ref:ue,style:{...g.root,left:R.x,top:R.y},children:[X==="mini"&&jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),H(false),C(false);},children:[jsxRuntime.jsxs("div",{style:{...g.pill(fe),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe(),Be.current||lt();},children:[jsxRuntime.jsx(y,{d:f.grip,size:9,className:""}),p?.ticket_id&&jsxRuntime.jsx("span",{style:{color:n.amber,fontWeight:600},children:p.ticket_id}),p?.pr_number&&jsxRuntime.jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",p.pr_number]}),jsxRuntime.jsxs("span",{style:fe?{color:n.green}:void 0,children:[B.pass,"/",B.total]}),B.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[B.fail,"\u2717"]}),F&&jsxRuntime.jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,compact:true,onExpand:()=>O("expanded"),testRunId:p?.id||d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout})]}),!N&&(te||V)&&p?.title&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsxRuntime.jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:p.title}),(p.description||p.intro_notes)&&jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:p.description||p.intro_notes})]})]}),X==="expanded"&&jsxRuntime.jsxs("div",{style:g.card(300,fe),children:[jsxRuntime.jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:lt,children:[jsxRuntime.jsx(y,{d:f.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:g.title,children:p?.title}),jsxRuntime.jsx("div",{style:g.sub,children:p?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",p.branch_name]})})]}),jsxRuntime.jsx(y,{d:f.chevronUp,className:""}),jsxRuntime.jsx(dt,{icon:f.minus,onClick:()=>{C(false),H(true),O("mini");}})]}),jsxRuntime.jsxs("div",{style:g.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[B.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[B.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[B.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[B.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:B.total})]}),p?.description&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:p.description}),ct(),pt(),jsxRuntime.jsx("div",{style:g.progress,children:jsxRuntime.jsx("div",{style:g.progressBar(it)})})]}),X==="max"&&jsxRuntime.jsxs("div",{style:{...g.card(ve.w,fe),height:ve.h,position:"relative"},children:[jsxRuntime.jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:()=>{Be.current||O("expanded");},children:[jsxRuntime.jsx(y,{d:f.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:g.title,children:p?.title}),jsxRuntime.jsx("div",{style:g.sub,children:p?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",p.branch_name]})})]}),jsxRuntime.jsx(y,{d:f.chevronDown,className:""}),jsxRuntime.jsx(dt,{icon:f.minus,onClick:()=>{C(false),H(true),O("mini");}})]}),jsxRuntime.jsxs("div",{style:g.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[B.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[B.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[B.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[B.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:B.total})]}),p?.intro_notes&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:p.intro_notes}),(p?.test_cases||[]).length>5&&jsxRuntime.jsxs("div",{style:{padding:"4px 12px",borderBottom:`1px solid ${n.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",flexShrink:0},children:[jsxRuntime.jsx(y,{d:f.search,size:11,className:""}),jsxRuntime.jsx("input",{value:z,onChange:t=>L(t.target.value),placeholder:"Filter test cases...",style:{flex:1,fontSize:"10px",background:"transparent",border:"none",outline:"none",color:n.text,fontFamily:"monospace"}}),z&&jsxRuntime.jsx("button",{onClick:()=>L(""),style:{background:"none",border:"none",cursor:"pointer",color:n.textFaint,fontSize:"10px",padding:0},children:"\u2715"})]}),se==="error"&&jsxRuntime.jsxs("div",{style:{padding:"12px",textAlign:"center"},children:[jsxRuntime.jsx(y,{d:f.alert,className:""}),jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsxRuntime.jsx("button",{onClick:Ct,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),fe&&jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsxRuntime.jsx(y,{d:f.checkAll,className:""}),jsxRuntime.jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsxRuntime.jsx("button",{onClick:Pt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),se!=="error"&&jsxRuntime.jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(p?.test_cases||[]).length===0?jsxRuntime.jsx("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:"No test cases"}):Te.length===0?jsxRuntime.jsxs("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:['No matches for "',z,'"']}):ot?ot.map(t=>{let l=k.has(t.key);return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>T(t.key),style:{width:"100%",display:"flex",alignItems:"center",gap:"6px",padding:"5px 12px",background:n.bgSoft,cursor:"pointer",border:"none",borderLeft:"none",borderRight:"none",borderBottomStyle:"solid",borderTopStyle:"solid",borderBottomWidth:"1px",borderTopWidth:"1px",borderBottomColor:n.borderSubtle,borderTopColor:n.borderSubtle,backgroundColor:n.bgSoft},children:[jsxRuntime.jsx(y,{d:l?f.chevronDown:f.chevronUp,size:10,className:""}),jsxRuntime.jsx("span",{style:{fontSize:"10px",fontWeight:700,color:n.blue,flex:1,textAlign:"left"},children:t.label}),jsxRuntime.jsxs("span",{style:{fontSize:"9px",color:n.green},children:[t.summary.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{fontSize:"9px",color:n.red},children:[t.summary.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{fontSize:"9px",color:n.gripColor},children:[t.summary.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{fontSize:"9px",color:n.textFaint},children:t.summary.total})]}),!l&&t.cases.map(x=>at(x))]},t.key)}):Te.map(t=>at(t))}),zt&&!fe&&jsxRuntime.jsxs("div",{style:{padding:"6px 12px",borderTop:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg,display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:0},children:[jsxRuntime.jsx("span",{style:{fontSize:"9px",color:n.green},children:"All resolved"}),jsxRuntime.jsx("button",{onClick:Rt,style:{fontSize:"8px",padding:"2px 8px",borderRadius:"4px",background:"rgba(52,211,153,0.15)",color:n.green,border:`1px solid ${n.greenBorderSubtle}`,cursor:"pointer"},children:"COMPLETE"})]}),ct(),pt(),jsxRuntime.jsx("div",{style:g.progress,children:jsxRuntime.jsx("div",{style:g.progressBar(it)})}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:0,right:0,width:16,height:16,cursor:"se-resize",zIndex:10,display:"flex",alignItems:"flex-end",justifyContent:"flex-end",padding:"2px",opacity:.3},onPointerDown:_t,onPointerMove:Mt,onPointerUp:Tt,onPointerEnter:t=>t.currentTarget.style.opacity="0.7",onPointerLeave:t=>{we.current||(t.currentTarget.style.opacity="0.3");},children:jsxRuntime.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",children:jsxRuntime.jsx("path",{d:"M7 1v6H1",fill:"none",stroke:n.gripColor,strokeWidth:"1.5",strokeLinecap:"round"})})})]})]})}
2
+ exports.TestRunWidget=en;exports.useDraggable=De;exports.useRealtimeRefresh=Fe;exports.useTestRun=He;exports.useWidgetAuth=je;
package/dist/index.d.cts CHANGED
@@ -63,6 +63,8 @@ interface BotBuddyConfig {
63
63
  dashboardUrl?: string;
64
64
  /** Supabase project URL for realtime subscriptions (optional) */
65
65
  supabaseUrl?: string;
66
+ /** Hostnames where test-only 2FA helpers must be suppressed regardless of environment string */
67
+ productionHostnames?: string[];
66
68
  }
67
69
  interface TestRunWidgetProps {
68
70
  /** BotBuddy configuration */
@@ -146,7 +148,7 @@ declare function useTestRun(opts: UseTestRunOptions): {
146
148
  setVerdict: (caseId: string, verdict: string, failReason?: string, displayName?: string) => Promise<boolean>;
147
149
  markComplete: () => Promise<boolean>;
148
150
  resetRun: () => Promise<boolean>;
149
- setRun: react.Dispatch<react.SetStateAction<TestRun | null>>;
151
+ setRun: (nextRun: TestRun | null) => void;
150
152
  };
151
153
 
152
154
  interface WidgetAuth {
package/dist/index.d.ts CHANGED
@@ -63,6 +63,8 @@ interface BotBuddyConfig {
63
63
  dashboardUrl?: string;
64
64
  /** Supabase project URL for realtime subscriptions (optional) */
65
65
  supabaseUrl?: string;
66
+ /** Hostnames where test-only 2FA helpers must be suppressed regardless of environment string */
67
+ productionHostnames?: string[];
66
68
  }
67
69
  interface TestRunWidgetProps {
68
70
  /** BotBuddy configuration */
@@ -146,7 +148,7 @@ declare function useTestRun(opts: UseTestRunOptions): {
146
148
  setVerdict: (caseId: string, verdict: string, failReason?: string, displayName?: string) => Promise<boolean>;
147
149
  markComplete: () => Promise<boolean>;
148
150
  resetRun: () => Promise<boolean>;
149
- setRun: react.Dispatch<react.SetStateAction<TestRun | null>>;
151
+ setRun: (nextRun: TestRun | null) => void;
150
152
  };
151
153
 
152
154
  interface WidgetAuth {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import {useState,useRef,useCallback,useEffect,useMemo,useLayoutEffect}from'react';import {createPortal}from'react-dom';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var re=8;function Te(t,r,s,f,y,c){let T=Math.max(re,y-s-re),w=Math.max(re,c-f-re);return {x:Math.min(Math.max(t,re),T),y:Math.min(Math.max(r,re),w)}}function Re(t,r){let[s,f]=useState({x:t,y:r}),y=useRef(false),c=useRef({x:0,y:0}),T=useRef(false),w=useCallback(u=>{y.current=true,T.current=false,c.current={x:u.clientX-s.x,y:u.clientY-s.y},u.target.setPointerCapture(u.pointerId);},[s]),_=useCallback(u=>{y.current&&(T.current=true,f({x:u.clientX-c.current.x,y:u.clientY-c.current.y}));},[]),d=useCallback(()=>{y.current=false;},[]);return {pos:s,setPos:f,onPointerDown:w,onPointerMove:_,onPointerUp:d,didDrag:T}}function ze(t,r,s){let f=useRef(s);f.current=s,useEffect(()=>{if(!r)return;if(t.supabaseUrl){let c=false,T=null,w=()=>{c||T||(T=setInterval(()=>f.current(),15e3));},_=null;try{let C=new URL(t.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(C.hostname);if(C.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");C.protocol=C.protocol==="https:"?"wss:":"ws:",_=C.toString().replace(/\/$/,"");}catch{w();}let d=null,u=null,M=null,W=0,R=()=>{if(!(c||!_)){try{d=new WebSocket(`${_}/realtime/v1/websocket?apikey=${t.anonKey}&vsn=1.0.0`);}catch{w();return}d.onopen=()=>{if(c||!d)return;let C={topic:`realtime:public:test_run_cases:test_run_id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_run_cases",filter:`test_run_id=eq.${r}`}]}},ref:String(++W)};d.send(JSON.stringify(C));let n={topic:`realtime:public:test_runs:id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_runs",filter:`id=eq.${r}`}]}},ref:String(++W)};d.send(JSON.stringify(n)),u=setInterval(()=>{d?.readyState===WebSocket.OPEN&&d.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++W)}));},3e4);},d.onmessage=C=>{try{JSON.parse(C.data).event==="postgres_changes"&&f.current();}catch{}},d.onclose=()=>{F(),c||(M=setTimeout(R,3e3));},d.onerror=()=>{d?.close();};}},F=()=>{u&&(clearInterval(u),u=null);};return R(),()=>{c=true,F(),M&&clearTimeout(M),T&&clearInterval(T),d&&(d.onclose=null,d.onerror=null,d.close());}}let y=setInterval(()=>f.current(),15e3);return ()=>clearInterval(y)},[t.supabaseUrl,t.anonKey,r]);}function ve(t,r){let s={apikey:t.anonKey};return r?s.Authorization=`Bearer ${r}`:t.apiKey?s.Authorization=`Bearer ${t.apiKey}`:s.Authorization=`Bearer ${t.anonKey}`,s}async function St(t){if(t)return t;try{let r=await fetch("/.botbuddy-token",{cache:"no-store"});if(r.ok){let s=(await r.text()).trim();if(s.startsWith("public_"))return s}}catch{}try{let r=import.meta?.env?.VITE_BOTBUDDY_TEST_RUN_TOKEN;if(r&&typeof r=="string"&&r.startsWith("public_"))return r}catch{}return null}function Pe(t){let[r,s]=useState(null),[f,y]=useState("loading"),c=useCallback(async()=>{try{let d=await St(t.testRunToken);if(!d){y("no-match"),s(null);return}if(!t.ticketId){y("no-match"),s(null);return}let u=new URLSearchParams;u.set("token",d),u.set("ticket_id",t.ticketId),u.set("app_slug",t.appSlug),t.environment&&u.set("environment",t.environment),t.testRunId&&u.set("test_run_id",t.testRunId),t.targetUrl&&u.set("target_url",t.targetUrl),t.version&&u.set("version",t.version),t.commitSha&&u.set("commit_sha",t.commitSha),t.prNumber&&u.set("pr_number",String(t.prNumber)),t.branchName&&u.set("branch_name",t.branchName);let M=await fetch(`${t.config.serverUrl}/widget/test-run?${u.toString()}`,{headers:ve(t.config,t.authToken)});if(M.status===404){y("no-match"),s(null);return}if(M.status===401||M.status===403){t.authToken&&t.onAuthExpired&&t.onAuthExpired(),y("error");return}if(!M.ok){y("error");return}let W=await M.json();s(W),y(W.status==="completed"?"completed":"ready");}catch{y("error");}},[t.config.serverUrl,t.config.anonKey,t.config.apiKey,t.authToken,t.appSlug,t.environment,t.ticketId,t.testRunId,t.testRunToken,t.targetUrl,t.version,t.commitSha,t.branchName,t.prNumber,t.onAuthExpired]);return useEffect(()=>{c();},[c]),ze(t.config,r?.id,c),{run:r,widgetState:f,fetchRun:c,setVerdict:async(d,u,M,W="human")=>(s(F=>{if(!F)return null;let C=F.test_cases.map(g=>g.id===d?{...g,verdict:u,fail_reason:u==="fail"&&M||null,verdict_by_display_name:W,verdict_at:new Date().toISOString()}:g),n={total:C.length,pending:0,pass:0,fail:0,skip:0};return C.forEach(g=>{g.verdict in n&&n[g.verdict]++;}),{...F,test_cases:C,summary:n}}),(await fetch(`${t.config.serverUrl}/widget/test-cases/${d}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...ve(t.config,t.authToken)},body:JSON.stringify({verdict:u,fail_reason:M,display_name:W})})).ok),markComplete:async()=>r?(s(u=>u?{...u,status:"completed"}:null),y("completed"),(await fetch(`${t.config.serverUrl}/widget/test-runs/${r.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...ve(t.config,t.authToken)}})).ok):false,resetRun:async()=>{if(!r)return false;let d=await fetch(`${t.config.serverUrl}/widget/test-runs/${r.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...ve(t.config,t.authToken)}});return d.ok&&c(),d.ok},setRun:s}}var $e="botbuddy-widget-auth-token",Be="botbuddy-widget-auth-name";function Ee(t){let[r,s]=useState(()=>{try{return localStorage.getItem($e)}catch(w){return console.warn("Unable to read BotBuddy widget auth token",w),null}}),[f,y]=useState(()=>{try{return localStorage.getItem(Be)}catch(w){return console.warn("Unable to read BotBuddy widget display name",w),null}});useEffect(()=>{let w=new URL(t).origin,_=d=>{if(d.origin===w&&d.data?.type==="botbuddy-widget-auth"&&d.data.token){let{token:u,displayName:M}=d.data;s(u),y(M||"human");try{localStorage.setItem($e,u),M&&localStorage.setItem(Be,M);}catch(W){console.warn("Unable to persist BotBuddy widget auth token",W);}}};return window.addEventListener("message",_),()=>window.removeEventListener("message",_)},[t]);let c=useCallback(()=>{let w=new URL("/widget-auth",t);w.searchParams.set("origin",window.location.origin);let _=420,d=520,u=window.screenX+(window.innerWidth-_)/2,M=window.screenY+(window.innerHeight-d)/2;window.open(w.toString(),"botbuddy-auth",`width=${_},height=${d},left=${u},top=${M},popup=yes`);},[t]),T=useCallback(()=>{s(null),y(null);try{localStorage.removeItem($e),localStorage.removeItem(Be);}catch(w){console.warn("Unable to clear BotBuddy widget auth token",w);}},[]);return {token:r,displayName:f,isAuthenticated:!!r,openLogin:c,logout:T}}function Ct(t){let r=new Date(t),f=Date.now()-r.getTime();if(f<6e4)return "just now";if(f<36e5)return `${Math.floor(f/6e4)}m ago`;if(f<864e5)return `${Math.floor(f/36e5)}h ago`;let y=r.getDate(),c=r.toLocaleString("en",{month:"short"}),T=r.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${c} ${y}, ${T}`}var x=({d:t,className:r,size:s=14})=>jsx("svg",{className:r,width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("path",{d:t})}),p={clipboard:"M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2",check:"M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3",x:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20M15 9l-6 6M9 9l6 6",circle:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20",skip:"M5 4l10 8-10 8V4M19 5v14",grip:"M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01",minus:"M5 12h14",chevronUp:"M18 15l-6-6-6 6",chevronDown:"M6 9l6 6 6-6",externalLink:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",pr:"M6 3v18M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6M18 9a9 9 0 0 1-9 9",ticket:"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z",loader:"M21 12a9 9 0 1 1-6.219-8.56",checkAll:"M18 6L7 17l-5-5M22 10l-7.5 7.5L13 16",alert:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0M12 9v4M12 17h.01",bot:"M12 8V4H8M2 14h2M20 14h2M15 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M9 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M18 10a6 6 0 0 0-12 0v4a6 6 0 0 0 12 0Z",terminal:"M4 17l6-6-6-6M12 19h8",key:"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4",shield:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10",copy:"M20 9h-9a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",search:"M11 17.25a6.25 6.25 0 1 1 0-12.5 6.25 6.25 0 0 1 0 12.5ZM16 16l4.5 4.5"};function Tt(){let[t,r]=useState(()=>typeof window>"u"||window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");return useEffect(()=>{if(typeof window>"u")return;let s=document.documentElement,f=()=>s.classList.contains("dark")?"dark":s.classList.contains("light")?"light":null,y=f();y&&r(y);let c=window.matchMedia("(prefers-color-scheme: dark)"),T=_=>{let d=f();r(d||(_.matches?"dark":"light"));};c.addEventListener("change",T);let w=new MutationObserver(()=>{let _=f();r(_||(c.matches?"dark":"light"));});return w.observe(s,{attributes:true,attributeFilter:["class"]}),()=>{c.removeEventListener("change",T),w.disconnect();}},[]),t}function Rt(t){let r=t==="dark";return {bg:r?"rgb(30,30,30)":"rgb(255,255,255)",bgSoft:r?"rgba(255,255,255,0.02)":"rgba(0,0,0,0.02)",text:r?"#e5e5e5":"#1a1a1a",textMuted:r?"rgba(255,255,255,0.4)":"rgba(0,0,0,0.45)",textFaint:r?"#555":"#999",border:r?"rgba(255,255,255,0.15)":"rgba(0,0,0,0.12)",borderSubtle:r?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",shadow:r?"rgba(0,0,0,0.4)":"rgba(0,0,0,0.12)",inputBg:r?"rgba(0,0,0,0.3)":"rgba(0,0,0,0.04)",inputBorder:r?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.12)",green:"#34d399",greenBg:r?"rgba(52,211,153,0.05)":"rgba(52,211,153,0.08)",greenBorder:r?"rgba(52,211,153,0.6)":"rgba(52,211,153,0.5)",greenBorderSubtle:r?"rgba(52,211,153,0.2)":"rgba(52,211,153,0.15)",red:"#f87171",amber:"#f59e0b",blue:"#60a5fa",purple:"#a78bfa",versionText:r?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",versionNum:r?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",gripColor:r?"#888":"#aaa",btnHover:r?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.06)"}}var zt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},Pt={pending:p.circle,pass:p.check,fail:p.x,skip:p.skip},et={local:{bg:"rgba(59,130,246,0.15)",text:"#60a5fa",border:"rgba(59,130,246,0.3)"},preview:{bg:"rgba(168,85,247,0.15)",text:"#c084fc",border:"rgba(168,85,247,0.3)"},staging:{bg:"rgba(245,158,11,0.15)",text:"#fbbf24",border:"rgba(245,158,11,0.3)"},production:{bg:"rgba(239,68,68,0.15)",text:"#f87171",border:"rgba(239,68,68,0.3)"},custom:{bg:"rgba(128,128,128,0.15)",text:"#888",border:"rgba(128,128,128,0.3)"}},$t=t=>({root:{position:"fixed",zIndex:9999,userSelect:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},pill:r=>({display:"inline-flex",alignItems:"center",gap:"6px",padding:"4px 8px",borderRadius:"9999px",background:t.bg,border:r?`1px solid ${t.greenBorder}`:`1px solid ${t.border}`,boxShadow:r?`0 4px 12px ${t.shadow}, 0 0 0 1px ${t.greenBorderSubtle}`:`0 4px 12px ${t.shadow}`,cursor:"pointer",fontSize:"9px",color:t.text}),card:(r,s)=>({width:`${r}px`,borderRadius:"8px",background:t.bg,border:s?`1px solid ${t.greenBorder}`:`1px solid ${t.border}`,boxShadow:s?`0 8px 24px ${t.shadow}, 0 0 0 1px ${t.greenBorderSubtle}`:`0 8px 24px ${t.shadow}`,overflow:"hidden",display:"flex",flexDirection:"column"}),handle:{padding:"8px 12px",display:"flex",alignItems:"center",gap:"8px",cursor:"grab",borderBottom:`1px solid ${t.borderSubtle}`},title:{fontSize:"10px",fontWeight:600,color:t.text,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},sub:{fontSize:"9px",color:t.textMuted,display:"flex",alignItems:"center",gap:"6px"},btn:{padding:"2px",borderRadius:"4px",background:"transparent",border:"none",cursor:"pointer",color:t.gripColor,display:"flex",flexShrink:0},stats:{padding:"4px 12px",display:"flex",alignItems:"center",gap:"8px",fontSize:"9px",borderBottom:`1px solid ${t.borderSubtle}`},badge:r=>{let s=et[r]||et.custom;return {fontSize:"8px",padding:"0 4px",borderRadius:"4px",background:s.bg,color:s.text,border:`1px solid ${s.border}`,lineHeight:"14px"}},progress:{height:"2px",background:t.borderSubtle,flexShrink:0},progressBar:r=>({height:"100%",width:`${r}%`,background:"linear-gradient(to right, #34d399, #3b82f6)",transition:"width 0.5s"}),link:r=>({display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${r}15`,color:r,textDecoration:"none",border:"none",cursor:"pointer"}),caseRow:{padding:"6px 12px",borderBottom:`1px solid ${t.borderSubtle}`,transition:"background 0.15s"},verdictBtn:(r,s)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:r?`${s}33`:"transparent",color:r?s:t.gripColor,transition:"all 0.15s"}),input:{flex:1,fontSize:"9px",background:t.inputBg,border:`1px solid ${t.inputBorder}`,borderRadius:"4px",padding:"2px 6px",color:t.text,outline:"none"},humanBanner:{padding:"6px 12px",fontSize:"11px",fontWeight:600,color:t.green,borderBottom:`1px solid ${t.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",background:t.greenBg,cursor:"pointer",textDecoration:"none"}});function Bt(t){return t.split("/")[0].trim()}async function Et(t){try{if(typeof navigator<"u"&&navigator.clipboard?.writeText)return await navigator.clipboard.writeText(t),!0}catch{}try{if(typeof document>"u")return !1;let r=document.createElement("textarea");r.value=t,r.setAttribute("readonly",""),r.style.position="fixed",r.style.top="0",r.style.left="0",r.style.opacity="0",r.style.pointerEvents="none",document.body.appendChild(r),r.focus(),r.select(),r.setSelectionRange(0,t.length);let s=document.execCommand("copy");return document.body.removeChild(r),s}catch{return false}}function tt({config:t,appSlug:r,environment:s,seededUsers:f,authToken:y,tk:c,compact:T=false,onExpand:w,onAuthExpired:_}){let[d,u]=useState(false),[M,W]=useState(null),[R,F]=useState(null),[C,n]=useState(null),[g,K]=useState(null),V=useCallback(m=>{W(m),n(null),K(null);let S=k=>{n(k),K(m),window.setTimeout(()=>{K(b=>b===m?null:b),n(b=>b===k?null:b);},3e3);},v=new URLSearchParams({app_slug:r,seed_user_slug:m,environment:s}),$={apikey:t.anonKey};$.Authorization=`Bearer ${y||t.anonKey}`;let L=(async()=>{try{let k=await fetch(`${t.serverUrl}/widget/totp-code?${v}`,{headers:$});if(!k.ok){let N=await k.json().catch(()=>({error:`HTTP ${k.status}`}));return {ok:!1,status:k.status,error:N.error||`HTTP ${k.status}`}}let b=await k.json();return {ok:!0,code:String(b.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),P=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let k=L.then(b=>{if(!b.ok)throw new Error(b.error);return new Blob([b.code],{type:"text/plain"})});P=navigator.clipboard.write([new ClipboardItem({"text/plain":k})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let k=await L;if(!k.ok){k.status===401||k.status===403?(_?.(),S("Signed out \u2014 please sign in again")):S(k.status===404?"No 2FA seed registered":k.error),W(null);return}let b=P?await P:false,N=b?true:await Et(k.code),G=b||N;F({slug:m,code:k.code,copied:G}),window.setTimeout(()=>F(te=>te?.slug===m?null:te),G?2500:6e3),u(false),W(null);})();},[t.serverUrl,t.anonKey,y,r,s]);if(f.length===0)return null;if(T){let m=f.length>1,S=b=>{if(b.stopPropagation(),m&&w){w();return}V(f[0]);},v=!!g,$=!!R,L=$&&R.copied,P=$&&!R.copied,k=v?c.red:L?c.green:P?c.amber:c.purple;return jsxs("span",{onPointerDown:b=>b.stopPropagation(),onPointerUp:b=>b.stopPropagation(),onPointerMove:b=>b.stopPropagation(),onClick:S,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:k,fontWeight:600,cursor:"pointer",letterSpacing:P?"0.08em":void 0},title:v?C||"Failed":P?`Clipboard blocked \u2014 code: ${R.code}`:m?`${f.length} 2FA personas`:`Copy 2FA code for ${f[0]}`,children:[jsx(x,{d:v?p.alert:L?p.check:P?p.copy:p.shield,size:10}),L?jsx(Fragment,{children:"Copied"}):P?jsx(Fragment,{children:R.code}):v?jsx(Fragment,{children:"Failed"}):jsxs(Fragment,{children:["2FA",m&&` \xB7${f.length}`]})]})}if(f.length===1){let m=f[0],S=M===m,v=R?.slug===m,$=v&&R.copied,L=v&&!R.copied,P=g===m,k=P?c.red:$?c.green:L?c.amber:c.purple;return jsxs("button",{onClick:b=>{b.stopPropagation(),V(m);},disabled:S,style:{...nt(k),cursor:S?"wait":"pointer",opacity:S?.6:1},title:P?C||"Failed":L?`Clipboard blocked \u2014 code: ${R.code}`:`Copy 2FA code for ${m}`,children:[jsx(x,{d:P?p.alert:$?p.check:L?p.copy:p.shield,size:12}),$?"Copied":L?R.code:P?"Failed":S?"\u2026":`2FA \xB7 ${m}`]})}let j=!!g&&!d,U=!!R&&R.copied,Y=!!R&&!R.copied,J=j?c.red:U?c.green:Y?c.amber:c.purple,ee=useRef(null),le=useRef(null);useLayoutEffect(()=>{if(!d)return;let m=ee.current,S=le.current;if(!m||!S||typeof window>"u")return;let v=()=>{let $=m.getBoundingClientRect(),L=S.getBoundingClientRect(),P=window.innerWidth,k=window.innerHeight,b=$.left,N=$.top-L.height-6;N<8&&(N=$.bottom+6);let G=Math.max(8,P-L.width-8),te=Math.max(8,k-L.height-8);b=Math.min(Math.max(b,8),G),N=Math.min(Math.max(N,8),te),S.style.left=`${Math.round(b)}px`,S.style.top=`${Math.round(N)}px`;};return v(),window.addEventListener("scroll",v,true),window.addEventListener("resize",v),()=>{window.removeEventListener("scroll",v,true),window.removeEventListener("resize",v);}},[d,f.length,C]),useEffect(()=>{if(!d)return;let m=S=>{let v=S.target;le.current?.contains(v)||ee.current?.contains(v)||u(false);};return document.addEventListener("mousedown",m),()=>document.removeEventListener("mousedown",m)},[d]);let z=d&&typeof document<"u"?createPortal(jsxs("div",{ref:le,onPointerDown:m=>m.stopPropagation(),onMouseDown:m=>m.stopPropagation(),style:{position:"fixed",left:-9999,top:-9999,background:c.bg,border:`1px solid ${c.border}`,borderRadius:6,boxShadow:`0 8px 24px ${c.shadow}`,padding:4,minWidth:220,maxWidth:typeof window<"u"?Math.min(420,window.innerWidth-16):420,zIndex:1e5,fontFamily:"ui-monospace, SFMono-Regular, monospace"},children:[f.map(m=>{let S=M===m;return jsxs("button",{onClick:v=>{v.stopPropagation(),V(m);},disabled:S,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:S?"wait":"pointer",fontSize:"10px",color:c.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:v=>v.currentTarget.style.background=c.btnHover,onMouseLeave:v=>v.currentTarget.style.background="transparent",children:[jsx(x,{d:p.shield,size:10}),jsx("span",{style:{flex:1,overflowWrap:"anywhere",lineHeight:1.3},children:m}),S&&jsx("span",{style:{color:c.textMuted,fontSize:9},children:"\u2026"})]},m)}),C&&jsx("div",{style:{padding:"4px 8px",fontSize:9,color:c.red},children:C})]}),document.body):null;return jsxs(Fragment,{children:[jsxs("button",{ref:ee,onClick:m=>{m.stopPropagation(),u(S=>!S),n(null),K(null);},style:{...nt(J),cursor:"pointer"},title:j?C||"Failed":Y?`Clipboard blocked \u2014 code: ${R.code}`:"Choose a persona to copy a 2FA code for",children:[jsx(x,{d:j?p.alert:U?p.check:Y?p.copy:p.shield,size:12}),U?"Copied":Y?R.code:j?"Failed":`2FA \xB7 ${f.length}`,jsx(x,{d:d?p.chevronUp:p.chevronDown,size:8})]}),z]})}function nt(t){return {display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${t}15`,color:t,textDecoration:"none",border:`1px solid ${t}30`}}var ot="botbuddy-widget-state";function Lt({config:t,appSlug:r,environment:s,ticketId:f,testRunId:y,testRunToken:c,targetUrl:T,version:w,commitSha:_,prNumber:d,branchName:u,onNavigate:M,displayName:W="human",defaultMode:R="mini",defaultPosition:F}){let C=Tt(),n=useMemo(()=>Rt(C),[C]),g=useMemo(()=>$t(n),[n]),[K,V]=useState(false),[j,U]=useState(false),[Y,J]=useState(false),ee=useRef(false),le=t.dashboardUrl||"https://app.bot-buddy.ai",z=Ee(le),S=(()=>{try{let e=typeof window<"u"?localStorage.getItem(ot):null;if(e)return JSON.parse(e)}catch{}return null})(),[v,$]=useState(S?.mode||R),[L,P]=useState(""),[k,b]=useState(null),[N,G]=useState(null),[te,it]=useState(new Set),[ne,Le]=useState(""),st=useCallback(e=>{it(a=>{let h=new Set(a);return h.has(e)?h.delete(e):h.add(e),h});},[]),at=S?.x??F?.x??16,lt=S?.y??F?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:B,setPos:we,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,didDrag:ke}=Re(at,lt),ue=useRef(null);useEffect(()=>{try{localStorage.setItem(ot,JSON.stringify({mode:v,x:B.x,y:B.y}));}catch{}},[v,B.x,B.y]),useLayoutEffect(()=>{if(typeof window>"u")return;let e=ue.current;if(!e)return;let a=e.getBoundingClientRect(),h=Te(B.x,B.y,a.width,a.height,window.innerWidth,window.innerHeight);(h.x!==B.x||h.y!==B.y)&&we(h);}),useEffect(()=>{if(typeof window>"u")return;let e=()=>{let a=ue.current;if(!a)return;let h=a.getBoundingClientRect(),D=Te(B.x,B.y,h.width,h.height,window.innerWidth,window.innerHeight);(D.x!==B.x||D.y!==B.y)&&we(D);};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[B.x,B.y,we]);let We=useRef(z.isAuthenticated);useEffect(()=>{!We.current&&z.isAuthenticated&&$("max"),We.current=z.isAuthenticated;},[z.isAuthenticated]);let Ie="botbuddy-widget-max-size",dt=()=>{try{let e=localStorage.getItem(Ie);if(e)return JSON.parse(e)}catch{}return {w:340,h:500}},[ge,Ae]=useState(dt),fe=useRef(false),me=useRef({x:0,y:0,w:0,h:0}),ct=useCallback(e=>{e.stopPropagation(),fe.current=true,me.current={x:e.clientX,y:e.clientY,w:ge.w,h:ge.h},e.target.setPointerCapture(e.pointerId);},[ge]),pt=useCallback(e=>{if(!fe.current)return;let a=Math.max(280,Math.min(600,me.current.w+(e.clientX-me.current.x))),h=Math.max(300,Math.min(window.innerHeight*.9,me.current.h+(e.clientY-me.current.y)));Ae({w:a,h});},[]),ut=useCallback(()=>{fe.current&&(fe.current=false,Ae(e=>(localStorage.setItem(Ie,JSON.stringify(e)),e)));},[]),be=T??(typeof window<"u"?window.location.href:void 0),De=z.displayName||W,[O,Fe]=useState(null);useEffect(()=>{if(z.isAuthenticated)return;let e=new URLSearchParams;c&&e.set("token",c),f&&e.set("ticket_id",f),e.set("app_slug",r),s&&e.set("environment",s),y&&e.set("test_run_id",y),be&&e.set("target_url",be),w&&e.set("version",w),_&&e.set("commit_sha",_),d&&e.set("pr_number",String(d)),u&&e.set("branch_name",u),fetch(`${t.serverUrl}/widget/preview?${e}`,{headers:{apikey:t.anonKey}}).then(a=>a.json()).then(a=>Fe(a)).catch(()=>Fe(null));},[z.isAuthenticated,t.serverUrl,t.anonKey,r,s,f,y,c,be,w,_,d,u]);let{run:l,widgetState:q,fetchRun:gt,setVerdict:Ne,markComplete:ft,resetRun:mt}=Pe({config:t,appSlug:r,environment:s,ticketId:f,testRunId:y,testRunToken:c,targetUrl:be,version:w,commitSha:_,prNumber:d?String(d):void 0,branchName:u,authToken:z.token,onAuthExpired:z.logout}),xe=useCallback(async(e,a,h)=>{G(e);try{await Ne(e,a,h,De);}finally{G(null),b(null),P("");}},[Ne,De]),E=l?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},ht=E.total>0&&E.pending===0,oe=q==="completed",ye=useMemo(()=>{let e=l?.test_cases||[];if(!ne.trim())return e;let a=ne.toLowerCase();return e.filter(h=>h.title.toLowerCase().includes(a)||h.description&&h.description.toLowerCase().includes(a)||h.url_path&&h.url_path.toLowerCase().includes(a)||h.seed_user&&h.seed_user.toLowerCase().includes(a))},[l?.test_cases,ne]),Ue=useMemo(()=>{let e=ye,a=l?.test_cases||[];if(new Set(a.map(A=>A.source_pr_number)).size<=1)return null;let D=[],he=new Map;e.forEach(A=>{let H=A.source_pr_number;he.has(H)||he.set(H,[]),he.get(H).push(A);});let bt=[...he.keys()].sort((A,H)=>A===null?1:H===null?-1:H-A);for(let A of bt){let H=he.get(A),_e={total:H.length,pass:0,fail:0,skip:0,pending:0};H.forEach(qe=>{qe.verdict in _e&&_e[qe.verdict]++;}),D.push({key:A!=null?`pr-${A}`:"general",label:A!=null?`PR #${A}`:"General",cases:H,summary:_e});}return D.filter(A=>A.cases.length>0)},[ye,l?.test_cases]),He=E.total>0?(E.pass+E.fail)/E.total*100:0,X=s??l?.environment??null,Oe=useMemo(()=>{if(!X||X==="production")return [];let e=l?.test_cases||[],a=new Set;for(let h of e)h.seed_user&&a.add(Bt(h.seed_user));return [...a]},[l?.test_cases,X]),Se=useMemo(()=>{let e=l?.auto_tooltip_seconds??O?.auto_tooltip_seconds;return e!=null&&e>0?e*1e3:0},[l,O]),Ve=q==="ready"||q==="completed"||O?.enabled&&O.run;useEffect(()=>{if(!Ve||ee.current||Se<=0)return;ee.current=true,U(true);let e=window.setTimeout(()=>U(false),Se);return ()=>window.clearTimeout(e)},[Ve,Se]);let Ke=e=>jsxs("div",{style:g.caseRow,children:[jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"},children:[jsx("div",{style:{marginTop:"2px",flexShrink:0,color:zt[e.verdict]},children:N===e.id?jsx(x,{d:p.loader,className:""}):jsx(x,{d:Pt[e.verdict],className:""})}),jsxs("div",{style:{minWidth:0,flex:1},children:[jsx("div",{style:{fontSize:"10px",color:n.text,lineHeight:1.3},children:e.title}),e.description&&jsx("div",{style:{fontSize:"9px",color:n.gripColor,marginTop:"2px"},children:e.description}),e.seed_user&&jsxs("div",{style:{fontSize:"9px",color:n.amber,marginTop:"3px",display:"inline-flex",alignItems:"center",gap:"4px",padding:"2px 6px",borderRadius:"4px",background:`${n.amber}12`,border:`1px solid ${n.amber}30`},children:[jsx(x,{d:p.key,size:10}),jsx("span",{children:e.seed_user})]}),e.url_path&&jsxs("a",{href:e.url_path,target:"_blank",rel:"noopener noreferrer",onClick:a=>{a.stopPropagation(),M&&(a.preventDefault(),M(e.url_path));},style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginTop:"2px",display:"inline-flex",alignItems:"center",gap:"2px",textDecoration:"none",position:"relative",zIndex:1,pointerEvents:"auto"},children:[jsx(x,{d:p.externalLink,size:10}),e.url_path]}),e.verdict==="fail"&&e.fail_reason&&jsxs("div",{style:{fontSize:"9px",color:n.red,marginTop:"2px"},children:["\u2717 ",e.fail_reason]})]})]}),jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px",marginTop:"4px",marginLeft:"22px"},children:[["pass","fail","skip"].map(a=>jsx("button",{onClick:()=>{if(e.verdict===a){xe(e.id,"pending"),b(null);return}if(a==="fail"){b(e.id),P("");return}b(null),xe(e.id,a);},disabled:N!==null,style:g.verdictBtn(e.verdict===a,a==="pass"?n.green:a==="fail"?n.red:n.amber),children:a.toUpperCase()},a)),e.created_by_agent_name&&jsxs("span",{style:{fontSize:"8px",color:n.purple,marginLeft:"4px",display:"inline-flex",alignItems:"center",gap:"2px"},children:[jsx(x,{d:p.bot,size:8}),e.created_by_agent_name]}),e.verdict_by_display_name&&jsxs("span",{style:{fontSize:"8px",color:n.textFaint,marginLeft:"auto",display:"inline-flex",alignItems:"center",gap:"3px"},children:[e.verdict_by_display_name,e.verdict_at&&jsx("span",{style:{opacity:.7},children:Ct(e.verdict_at)})]})]}),k===e.id&&jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsx("input",{autoFocus:true,value:L,onChange:a=>P(a.target.value),onKeyDown:a=>{a.key==="Enter"&&xe(e.id,"fail",L.trim()||void 0),a.key==="Escape"&&(b(null),P(""));},placeholder:"Reason (optional)...",style:g.input}),jsx("button",{onClick:()=>{xe(e.id,"fail",L.trim()||void 0);},style:g.verdictBtn(true,n.red),children:"\u2713"})]})]},e.id);if((q==="no-match"||q==="loading")&&!(!z.isAuthenticated&&O?.enabled&&O.run))return null;if(!z.isAuthenticated&&O?.enabled&&O.run){let e=O.run,a=e.summary,h=e.status==="completed";return jsx("div",{ref:ue,style:{...g.root,left:B.x,top:B.y},children:jsxs("div",{style:{position:"relative"},onMouseEnter:()=>V(true),onMouseLeave:()=>{V(false),J(false),U(false);},children:[jsxs("div",{style:{...g.pill(h),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe();},children:[jsx(x,{d:p.grip,size:10,className:""}),e.ticket_id&&e.ticket_url?jsx("a",{href:e.ticket_url,target:"_blank",rel:"noopener noreferrer",onClick:D=>D.stopPropagation(),style:{color:n.amber,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:e.ticket_id}):null,e.pr_url?jsxs("a",{href:e.pr_url,target:"_blank",rel:"noopener noreferrer",onClick:D=>D.stopPropagation(),style:{color:n.blue,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:["PR#",e.pr_number??e.pr_id]}):null,e.created_by_agent_name?e.codex_thread_id?jsxs("a",{href:`codex://threads/${e.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",onClick:D=>D.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsx(x,{d:p.terminal,size:10}),e.created_by_agent_name]}):jsxs("span",{style:{color:n.purple,fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsx(x,{d:p.bot,size:10}),e.created_by_agent_name]}):null,jsxs("span",{style:h?{color:n.green}:void 0,children:[a.pass,"/",a.total]}),a.fail>0&&jsxs("span",{style:{color:n.red},children:[a.fail,"\u2717"]}),jsx("span",{onClick:D=>{D.stopPropagation(),z.openLogin();},style:{color:n.textMuted,fontWeight:400,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},children:"Sign in"})]}),!Y&&(K||j)&&e.title&&jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:e.title}),(e.description||e.intro_notes)&&jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:e.description||e.intro_notes}),jsx("div",{style:{marginTop:"4px",fontSize:"9px",color:n.textFaint},children:'Click "Sign in" to start testing'})]})]})})}if(!z.isAuthenticated)return jsxs("div",{ref:ue,style:{...g.root,left:B.x,top:B.y,width:220,minHeight:0,cursor:"move",userSelect:"none",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`},onPointerDown:de,onPointerMove:ce,onPointerUp:pe,children:[jsx("div",{style:{...g.handle,borderBottom:"none"},children:jsxs("div",{style:g.sub,children:[jsx(x,{d:p.grip,size:10,className:""}),jsx(x,{d:p.clipboard,size:12,className:""}),jsx("span",{style:{fontWeight:600},children:"BotBuddy"})]})}),jsxs("div",{style:{padding:"12px 14px",textAlign:"center"},children:[jsx("div",{style:{fontSize:"9px",color:n.textMuted,marginBottom:"8px"},children:"Sign in to access test cases"}),jsx("button",{onClick:e=>{e.stopPropagation(),z.openLogin();},style:{fontSize:"10px",fontWeight:600,padding:"6px 16px",borderRadius:"6px",border:`1px solid ${n.green}`,background:`${n.green}22`,color:n.green,cursor:"pointer",width:"100%"},children:"Sign in to test"})]})]});let je=()=>{ke.current||(U(false),$(e=>{let a=e==="mini"?"max":"mini";return J(a==="mini"),a}));},Ye=({icon:e,onClick:a})=>jsx("button",{style:g.btn,onClick:h=>{h.stopPropagation(),a(h);},children:jsx(x,{d:e,className:""})}),Je=()=>jsxs("div",{style:{padding:"6px 12px",display:"flex",gap:"8px",flexWrap:"wrap",alignItems:"center",borderTop:`1px solid ${n.borderSubtle}`,flexShrink:0},children:[l?.pr_url&&jsxs("a",{href:l.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.blue),textDecoration:"none"},children:[jsx(x,{d:p.pr,size:12}),l.pr_number?`PR#${l.pr_number}`:l.pr_id||"PR",jsx(x,{d:p.externalLink,size:8})]}),l?.ticket_url&&jsxs("a",{href:l.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.amber),textDecoration:"none"},children:[jsx(x,{d:p.ticket,size:12}),l.ticket_id||"Ticket",jsx(x,{d:p.externalLink,size:8})]}),l?.created_by_agent_name&&(l.codex_thread_id?jsxs("a",{href:`codex://threads/${l.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.purple),textDecoration:"none"},children:[jsx(x,{d:p.bot,size:12}),l.created_by_agent_name,jsx(x,{d:p.externalLink,size:8})]}):jsxs("span",{style:{...g.link(n.purple)},children:[jsx(x,{d:p.bot,size:12}),l.created_by_agent_name]})),X&&jsx(tt,{config:t,appSlug:r,environment:X,seededUsers:Oe,authToken:z.token,tk:n,onAuthExpired:z.logout}),jsx("span",{style:{...g.badge(l?.environment||"custom"),marginLeft:"auto"},children:l?.environment})]}),Ge=()=>jsxs("div",{style:{padding:"4px 12px",display:"flex",alignItems:"center",justifyContent:"center",borderTop:`1px solid ${n.borderSubtle}`,background:n.bgSoft,flexShrink:0},children:[jsxs("button",{onClick:()=>{navigator.clipboard.writeText("0.9.12");},style:{fontSize:"9px",fontWeight:600,color:n.versionText,letterSpacing:"0.08em",background:"none",border:"none",cursor:"pointer",display:"inline-flex",alignItems:"center",gap:"4px",padding:0},title:"Copy version",children:["BotBuddy ",jsx("span",{style:{color:n.versionNum},children:"v0.9.12"})]}),z.isAuthenticated&&jsx("button",{onClick:e=>{e.stopPropagation(),z.logout();},style:{fontSize:"8px",color:n.textFaint,background:"none",border:"none",cursor:"pointer",marginLeft:"8px",padding:"0 4px",textDecoration:"underline"},title:"Sign out of widget",children:"sign out"})]});return jsxs("div",{ref:ue,style:{...g.root,left:B.x,top:B.y},children:[v==="mini"&&jsxs("div",{style:{position:"relative"},onMouseEnter:()=>V(true),onMouseLeave:()=>{V(false),J(false),U(false);},children:[jsxs("div",{style:{...g.pill(oe),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe(),ke.current||je();},children:[jsx(x,{d:p.grip,size:9,className:""}),l?.ticket_id&&jsx("span",{style:{color:n.amber,fontWeight:600},children:l.ticket_id}),l?.pr_number&&jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",l.pr_number]}),jsxs("span",{style:oe?{color:n.green}:void 0,children:[E.pass,"/",E.total]}),E.fail>0&&jsxs("span",{style:{color:n.red},children:[E.fail,"\u2717"]}),X&&jsx(tt,{config:t,appSlug:r,environment:X,seededUsers:Oe,authToken:z.token,tk:n,compact:true,onExpand:()=>$("expanded"),onAuthExpired:z.logout})]}),!Y&&(K||j)&&l?.title&&jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:l.title}),(l.description||l.intro_notes)&&jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:l.description||l.intro_notes})]})]}),v==="expanded"&&jsxs("div",{style:g.card(300,oe),children:[jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:je,children:[jsx(x,{d:p.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:g.title,children:l?.title}),jsx("div",{style:g.sub,children:l?.branch_name&&jsxs("span",{children:["\u2387 ",l.branch_name]})})]}),jsx(x,{d:p.chevronUp,className:""}),jsx(Ye,{icon:p.minus,onClick:()=>{U(false),J(true),$("mini");}})]}),jsxs("div",{style:g.stats,children:[jsxs("span",{style:{color:n.green},children:[E.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[E.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[E.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[E.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:E.total})]}),l?.description&&jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:l.description}),Je(),Ge(),jsx("div",{style:g.progress,children:jsx("div",{style:g.progressBar(He)})})]}),v==="max"&&jsxs("div",{style:{...g.card(ge.w,oe),height:ge.h,position:"relative"},children:[jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:()=>{ke.current||$("expanded");},children:[jsx(x,{d:p.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:g.title,children:l?.title}),jsx("div",{style:g.sub,children:l?.branch_name&&jsxs("span",{children:["\u2387 ",l.branch_name]})})]}),jsx(x,{d:p.chevronDown,className:""}),jsx(Ye,{icon:p.minus,onClick:()=>{U(false),J(true),$("mini");}})]}),jsxs("div",{style:g.stats,children:[jsxs("span",{style:{color:n.green},children:[E.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[E.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[E.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[E.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:E.total})]}),l?.intro_notes&&jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:l.intro_notes}),(l?.test_cases||[]).length>5&&jsxs("div",{style:{padding:"4px 12px",borderBottom:`1px solid ${n.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",flexShrink:0},children:[jsx(x,{d:p.search,size:11,className:""}),jsx("input",{value:ne,onChange:e=>Le(e.target.value),placeholder:"Filter test cases...",style:{flex:1,fontSize:"10px",background:"transparent",border:"none",outline:"none",color:n.text,fontFamily:"monospace"}}),ne&&jsx("button",{onClick:()=>Le(""),style:{background:"none",border:"none",cursor:"pointer",color:n.textFaint,fontSize:"10px",padding:0},children:"\u2715"})]}),q==="error"&&jsxs("div",{style:{padding:"12px",textAlign:"center"},children:[jsx(x,{d:p.alert,className:""}),jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsx("button",{onClick:gt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),oe&&jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsx(x,{d:p.checkAll,className:""}),jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsx("button",{onClick:mt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),q!=="error"&&jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(l?.test_cases||[]).length===0?jsx("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:"No test cases"}):ye.length===0?jsxs("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:['No matches for "',ne,'"']}):Ue?Ue.map(e=>{let a=te.has(e.key);return jsxs("div",{children:[jsxs("button",{onClick:()=>st(e.key),style:{width:"100%",display:"flex",alignItems:"center",gap:"6px",padding:"5px 12px",background:n.bgSoft,cursor:"pointer",border:"none",borderLeft:"none",borderRight:"none",borderBottomStyle:"solid",borderTopStyle:"solid",borderBottomWidth:"1px",borderTopWidth:"1px",borderBottomColor:n.borderSubtle,borderTopColor:n.borderSubtle,backgroundColor:n.bgSoft},children:[jsx(x,{d:a?p.chevronDown:p.chevronUp,size:10,className:""}),jsx("span",{style:{fontSize:"10px",fontWeight:700,color:n.blue,flex:1,textAlign:"left"},children:e.label}),jsxs("span",{style:{fontSize:"9px",color:n.green},children:[e.summary.pass,"\u2713"]}),jsxs("span",{style:{fontSize:"9px",color:n.red},children:[e.summary.fail,"\u2717"]}),jsxs("span",{style:{fontSize:"9px",color:n.gripColor},children:[e.summary.pending,"\u25CC"]}),jsx("span",{style:{fontSize:"9px",color:n.textFaint},children:e.summary.total})]}),!a&&e.cases.map(h=>Ke(h))]},e.key)}):ye.map(e=>Ke(e))}),ht&&!oe&&jsxs("div",{style:{padding:"6px 12px",borderTop:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg,display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:0},children:[jsx("span",{style:{fontSize:"9px",color:n.green},children:"All resolved"}),jsx("button",{onClick:ft,style:{fontSize:"8px",padding:"2px 8px",borderRadius:"4px",background:"rgba(52,211,153,0.15)",color:n.green,border:`1px solid ${n.greenBorderSubtle}`,cursor:"pointer"},children:"COMPLETE"})]}),Je(),Ge(),jsx("div",{style:g.progress,children:jsx("div",{style:g.progressBar(He)})}),jsx("div",{style:{position:"absolute",bottom:0,right:0,width:16,height:16,cursor:"se-resize",zIndex:10,display:"flex",alignItems:"flex-end",justifyContent:"flex-end",padding:"2px",opacity:.3},onPointerDown:ct,onPointerMove:pt,onPointerUp:ut,onPointerEnter:e=>e.currentTarget.style.opacity="0.7",onPointerLeave:e=>{fe.current||(e.currentTarget.style.opacity="0.3");},children:jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",children:jsx("path",{d:"M7 1v6H1",fill:"none",stroke:n.gripColor,strokeWidth:"1.5",strokeLinecap:"round"})})})]})]})}
2
- export{Lt as TestRunWidget,Re as useDraggable,ze as useRealtimeRefresh,Pe as useTestRun,Ee as useWidgetAuth};
1
+ import {useState,useRef,useCallback,useEffect,useMemo,useLayoutEffect}from'react';import {createPortal}from'react-dom';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var me=8;function Ue(e,r,i,c,d,a){let M=Math.max(me,d-i-me),m=Math.max(me,a-c-me);return {x:Math.min(Math.max(e,me),M),y:Math.min(Math.max(r,me),m)}}function De(e,r){let[i,c]=useState({x:e,y:r}),d=useRef(false),a=useRef({x:0,y:0}),M=useRef(false),m=useCallback(h=>{d.current=true,M.current=false,a.current={x:h.clientX-i.x,y:h.clientY-i.y},h.target.setPointerCapture(h.pointerId);},[i]),v=useCallback(h=>{d.current&&(M.current=true,c({x:h.clientX-a.current.x,y:h.clientY-a.current.y}));},[]),u=useCallback(()=>{d.current=false;},[]);return {pos:i,setPos:c,onPointerDown:m,onPointerMove:v,onPointerUp:u,didDrag:M}}function Fe(e,r,i){let c=useRef(i);c.current=i,useEffect(()=>{if(!r)return;if(e.supabaseUrl){let a=false,M=null,m=()=>{a||M||(M=setInterval(()=>c.current(),15e3));},v=null;try{let w=new URL(e.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(w.hostname);if(w.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");w.protocol=w.protocol==="https:"?"wss:":"ws:",v=w.toString().replace(/\/$/,"");}catch{m();}let u=null,h=null,A=null,D=0,G=()=>{if(!(a||!v)){try{u=new WebSocket(`${v}/realtime/v1/websocket?apikey=${e.anonKey}&vsn=1.0.0`);}catch{m();return}u.onopen=()=>{if(a||!u)return;let w={topic:`realtime:public:test_run_cases:test_run_id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_run_cases",filter:`test_run_id=eq.${r}`}]}},ref:String(++D)};u.send(JSON.stringify(w));let n={topic:`realtime:public:test_runs:id=eq.${r}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_runs",filter:`id=eq.${r}`}]}},ref:String(++D)};u.send(JSON.stringify(n)),h=setInterval(()=>{u?.readyState===WebSocket.OPEN&&u.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++D)}));},3e4);},u.onmessage=w=>{try{JSON.parse(w.data).event==="postgres_changes"&&c.current();}catch{}},u.onclose=()=>{P(),a||(A=setTimeout(G,3e3));},u.onerror=()=>{u?.close();};}},P=()=>{h&&(clearInterval(h),h=null);};return G(),()=>{a=true,P(),A&&clearTimeout(A),M&&clearInterval(M),u&&(u.onclose=null,u.onerror=null,u.close());}}let d=setInterval(()=>c.current(),15e3);return ()=>clearInterval(d)},[e.supabaseUrl,e.anonKey,r]);}var It="botbuddy:created-test-run:";function Ut(e){if(!e)return "";try{return new URL(e).origin}catch{return e}}function Dt(e){return `${It}${encodeURIComponent([e.appSlug,e.environment||"",e.ticketId||"",Ut(e.targetUrl),e.branchName||""].join("|"))}`}function Ce(e,r){let i={apikey:e.anonKey};return r?i.Authorization=`Bearer ${r}`:e.apiKey?i.Authorization=`Bearer ${e.apiKey}`:i.Authorization=`Bearer ${e.anonKey}`,i}async function Ft(e){if(e)return e;try{let r=await fetch("/.botbuddy-token",{cache:"no-store"});if(r.ok){let i=(await r.text()).trim();if(i.startsWith("public_"))return i}}catch{}try{let r=import.meta?.env?.VITE_BOTBUDDY_TEST_RUN_TOKEN;if(r&&typeof r=="string"&&r.startsWith("public_"))return r}catch{}return null}function He(e){let[r,i]=useState(null),[c,d]=useState("loading"),a=Dt(e),[M,m]=useState(()=>{if(e.testRunId)return e.testRunId;try{return localStorage.getItem(a)||void 0}catch{return}}),v=e.testRunId||M,u=useCallback(P=>{if(i(P),!!P?.id){m(P.id);try{localStorage.setItem(a,P.id);}catch{}}},[a]),h=useCallback(async()=>{try{let P=await Ft(e.testRunToken);if(!P&&!v){d("no-match"),i(null);return}if(P&&!e.ticketId){d("no-match"),i(null);return}let w=new URLSearchParams;P&&w.set("token",P),e.ticketId&&w.set("ticket_id",e.ticketId),w.set("app_slug",e.appSlug),e.environment&&w.set("environment",e.environment),v&&w.set("test_run_id",v),e.targetUrl&&w.set("target_url",e.targetUrl),e.version&&w.set("version",e.version),e.commitSha&&w.set("commit_sha",e.commitSha),e.prNumber&&w.set("pr_number",String(e.prNumber)),e.branchName&&w.set("branch_name",e.branchName);let n=await fetch(`${e.config.serverUrl}/widget/test-run?${w.toString()}`,{headers:Ce(e.config,e.authToken)});if(n.status===404){d("no-match"),i(null);return}if(n.status===401||n.status===403){e.authToken&&e.onAuthExpired&&e.onAuthExpired(),d("error");return}if(!n.ok){d("error");return}let g=await n.json();if(!g||g.run===null){d("no-match"),i(null);return}u(g),d(g.status==="completed"?"completed":"ready");}catch{d("error");}},[e.config.serverUrl,e.config.anonKey,e.config.apiKey,e.authToken,e.appSlug,e.environment,e.ticketId,v,e.testRunToken,e.targetUrl,e.version,e.commitSha,e.branchName,e.prNumber,e.onAuthExpired,u]);return useEffect(()=>{h();},[h]),Fe(e.config,r?.id,h),{run:r,widgetState:c,fetchRun:h,setVerdict:async(P,w,n,g="human")=>(i(K=>{if(!K)return null;let V=K.test_cases.map(N=>N.id===P?{...N,verdict:w,fail_reason:w==="fail"&&n||null,verdict_by_display_name:g,verdict_at:new Date().toISOString()}:N),C={total:V.length,pending:0,pass:0,fail:0,skip:0};return V.forEach(N=>{N.verdict in C&&C[N.verdict]++;}),{...K,test_cases:V,summary:C}}),(await fetch(`${e.config.serverUrl}/widget/test-cases/${P}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...Ce(e.config,e.authToken)},body:JSON.stringify({verdict:w,fail_reason:n,display_name:g})})).ok),markComplete:async()=>r?(i(w=>w?{...w,status:"completed"}:null),d("completed"),(await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...Ce(e.config,e.authToken)}})).ok):false,resetRun:async()=>{if(!r)return false;let P=await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...Ce(e.config,e.authToken)}});return P.ok&&h(),P.ok},setRun:u}}var Oe="botbuddy-widget-auth-token",Ke="botbuddy-widget-auth-name";function je(e){let[r,i]=useState(()=>{try{return localStorage.getItem(Oe)}catch(m){return console.warn("Unable to read BotBuddy widget auth token",m),null}}),[c,d]=useState(()=>{try{return localStorage.getItem(Ke)}catch(m){return console.warn("Unable to read BotBuddy widget display name",m),null}});useEffect(()=>{let m=new URL(e).origin,v=u=>{if(u.origin===m&&u.data?.type==="botbuddy-widget-auth"&&u.data.token){let{token:h,displayName:A}=u.data;i(h),d(A||"human");try{localStorage.setItem(Oe,h),A&&localStorage.setItem(Ke,A);}catch(D){console.warn("Unable to persist BotBuddy widget auth token",D);}}};return window.addEventListener("message",v),()=>window.removeEventListener("message",v)},[e]);let a=useCallback(()=>{let m=new URL("/widget-auth",e);m.searchParams.set("origin",window.location.origin);let v=420,u=520,h=window.screenX+(window.innerWidth-v)/2,A=window.screenY+(window.innerHeight-u)/2;window.open(m.toString(),"botbuddy-auth",`width=${v},height=${u},left=${h},top=${A},popup=yes`);},[e]),M=useCallback(()=>{i(null),d(null);try{localStorage.removeItem(Oe),localStorage.removeItem(Ke);}catch(m){console.warn("Unable to clear BotBuddy widget auth token",m);}},[]);return {token:r,displayName:c,isAuthenticated:!!r,openLogin:a,logout:M}}var Re=null;function Ht(){try{if(typeof document<"u"){let e=document.querySelector("base[href]");if(e)return new URL(".botbuddy-totp.json",e.href).toString()}}catch{}return "/.botbuddy-totp.json"}function Pe(){return Re||(Re=(async()=>{if(typeof fetch>"u")return null;try{let e=await fetch(Ht(),{cache:"no-store"});if(!e.ok)return null;let r=await e.json();if(!r||typeof r!="object"||Array.isArray(r))return null;let i={};for(let[c,d]of Object.entries(r))typeof d=="string"&&d.length>0&&(i[c]=d);return i}catch{return null}})(),Re)}async function mt(e){return (await Pe())?.[e]??null}function Ot(e){let r=e.replace(/=+$/,"").replace(/\s+/g,"").toUpperCase(),i="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",c=[],d=0,a=0;for(let M of r){let m=i.indexOf(M);if(m<0)throw new Error("Invalid Base32 character in TOTP secret");a=a<<5|m,d+=5,d>=8&&(d-=8,c.push(a>>>d&255));}return Uint8Array.from(c)}async function bt(e,r=Date.now()){if(typeof crypto>"u"||!crypto.subtle)throw new Error("Web Crypto unavailable");let i=Ot(e),c=Math.floor(r/1e3/30),d=new Uint8Array(8),a=Math.floor(c/4294967296),M=c>>>0;d[0]=a>>>24&255,d[1]=a>>>16&255,d[2]=a>>>8&255,d[3]=a&255,d[4]=M>>>24&255,d[5]=M>>>16&255,d[6]=M>>>8&255,d[7]=M&255;let m=await crypto.subtle.importKey("raw",i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength),{name:"HMAC",hash:"SHA-1"},false,["sign"]),v=await crypto.subtle.sign("HMAC",m,d.buffer),u=new Uint8Array(v),h=u[u.length-1]&15;return (((u[h]&127)<<24|(u[h+1]&255)<<16|(u[h+2]&255)<<8|u[h+3]&255)%1e6).toString().padStart(6,"0")}function jt(e){let r=new Date(e),c=Date.now()-r.getTime();if(c<6e4)return "just now";if(c<36e5)return `${Math.floor(c/6e4)}m ago`;if(c<864e5)return `${Math.floor(c/36e5)}h ago`;let d=r.getDate(),a=r.toLocaleString("en",{month:"short"}),M=r.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${a} ${d}, ${M}`}var y=({d:e,className:r,size:i=14})=>jsx("svg",{className:r,width:i,height:i,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:jsx("path",{d:e})}),f={clipboard:"M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2",check:"M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3",x:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20M15 9l-6 6M9 9l6 6",circle:"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20",skip:"M5 4l10 8-10 8V4M19 5v14",grip:"M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01",minus:"M5 12h14",chevronUp:"M18 15l-6-6-6 6",chevronDown:"M6 9l6 6 6-6",externalLink:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",pr:"M6 3v18M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6M18 9a9 9 0 0 1-9 9",ticket:"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z",loader:"M21 12a9 9 0 1 1-6.219-8.56",checkAll:"M18 6L7 17l-5-5M22 10l-7.5 7.5L13 16",alert:"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0M12 9v4M12 17h.01",bot:"M12 8V4H8M2 14h2M20 14h2M15 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M9 13a1 1 0 1 0 0 2 1 1 0 0 0 0-2M18 10a6 6 0 0 0-12 0v4a6 6 0 0 0 12 0Z",terminal:"M4 17l6-6-6-6M12 19h8",key:"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4",shield:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10",copy:"M20 9h-9a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",search:"M11 17.25a6.25 6.25 0 1 1 0-12.5 6.25 6.25 0 0 1 0 12.5ZM16 16l4.5 4.5"};function Vt(){let[e,r]=useState(()=>typeof window>"u"||window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");return useEffect(()=>{if(typeof window>"u")return;let i=document.documentElement,c=()=>i.classList.contains("dark")?"dark":i.classList.contains("light")?"light":null,d=c();d&&r(d);let a=window.matchMedia("(prefers-color-scheme: dark)"),M=v=>{let u=c();r(u||(v.matches?"dark":"light"));};a.addEventListener("change",M);let m=new MutationObserver(()=>{let v=c();r(v||(a.matches?"dark":"light"));});return m.observe(i,{attributes:true,attributeFilter:["class"]}),()=>{a.removeEventListener("change",M),m.disconnect();}},[]),e}function Yt(e){let r=e==="dark";return {bg:r?"rgb(30,30,30)":"rgb(255,255,255)",bgSoft:r?"rgba(255,255,255,0.02)":"rgba(0,0,0,0.02)",text:r?"#e5e5e5":"#1a1a1a",textMuted:r?"rgba(255,255,255,0.4)":"rgba(0,0,0,0.45)",textFaint:r?"#555":"#999",border:r?"rgba(255,255,255,0.15)":"rgba(0,0,0,0.12)",borderSubtle:r?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",shadow:r?"rgba(0,0,0,0.4)":"rgba(0,0,0,0.12)",inputBg:r?"rgba(0,0,0,0.3)":"rgba(0,0,0,0.04)",inputBorder:r?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.12)",green:"#34d399",greenBg:r?"rgba(52,211,153,0.05)":"rgba(52,211,153,0.08)",greenBorder:r?"rgba(52,211,153,0.6)":"rgba(52,211,153,0.5)",greenBorderSubtle:r?"rgba(52,211,153,0.2)":"rgba(52,211,153,0.15)",red:"#f87171",amber:"#f59e0b",blue:"#60a5fa",purple:"#a78bfa",versionText:r?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",versionNum:r?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",gripColor:r?"#888":"#aaa",btnHover:r?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.06)"}}var Jt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},Gt={pending:f.circle,pass:f.check,fail:f.x,skip:f.skip},xt={local:{bg:"rgba(59,130,246,0.15)",text:"#60a5fa",border:"rgba(59,130,246,0.3)"},preview:{bg:"rgba(168,85,247,0.15)",text:"#c084fc",border:"rgba(168,85,247,0.3)"},staging:{bg:"rgba(245,158,11,0.15)",text:"#fbbf24",border:"rgba(245,158,11,0.3)"},production:{bg:"rgba(239,68,68,0.15)",text:"#f87171",border:"rgba(239,68,68,0.3)"},custom:{bg:"rgba(128,128,128,0.15)",text:"#888",border:"rgba(128,128,128,0.3)"}},Xt=["app.supply-guard.io"];function qt(e,r=[]){if(!e)return false;let i=e.toLowerCase();return [...Xt,...r].map(d=>d.toLowerCase()).includes(i)}var Zt=e=>({root:{position:"fixed",zIndex:9999,userSelect:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},pill:r=>({display:"inline-flex",alignItems:"center",gap:"6px",padding:"4px 8px",borderRadius:"9999px",background:e.bg,border:r?`1px solid ${e.greenBorder}`:`1px solid ${e.border}`,boxShadow:r?`0 4px 12px ${e.shadow}, 0 0 0 1px ${e.greenBorderSubtle}`:`0 4px 12px ${e.shadow}`,cursor:"pointer",fontSize:"9px",color:e.text}),card:(r,i)=>({width:`${r}px`,borderRadius:"8px",background:e.bg,border:i?`1px solid ${e.greenBorder}`:`1px solid ${e.border}`,boxShadow:i?`0 8px 24px ${e.shadow}, 0 0 0 1px ${e.greenBorderSubtle}`:`0 8px 24px ${e.shadow}`,overflow:"hidden",display:"flex",flexDirection:"column"}),handle:{padding:"8px 12px",display:"flex",alignItems:"center",gap:"8px",cursor:"grab",borderBottom:`1px solid ${e.borderSubtle}`},title:{fontSize:"10px",fontWeight:600,color:e.text,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},sub:{fontSize:"9px",color:e.textMuted,display:"flex",alignItems:"center",gap:"6px"},btn:{padding:"2px",borderRadius:"4px",background:"transparent",border:"none",cursor:"pointer",color:e.gripColor,display:"flex",flexShrink:0},stats:{padding:"4px 12px",display:"flex",alignItems:"center",gap:"8px",fontSize:"9px",borderBottom:`1px solid ${e.borderSubtle}`},badge:r=>{let i=xt[r]||xt.custom;return {fontSize:"8px",padding:"0 4px",borderRadius:"4px",background:i.bg,color:i.text,border:`1px solid ${i.border}`,lineHeight:"14px"}},progress:{height:"2px",background:e.borderSubtle,flexShrink:0},progressBar:r=>({height:"100%",width:`${r}%`,background:"linear-gradient(to right, #34d399, #3b82f6)",transition:"width 0.5s"}),link:r=>({display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${r}15`,color:r,textDecoration:"none",border:"none",cursor:"pointer"}),caseRow:{padding:"6px 12px",borderBottom:`1px solid ${e.borderSubtle}`,transition:"background 0.15s"},verdictBtn:(r,i)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:r?`${i}33`:"transparent",color:r?i:e.gripColor,transition:"all 0.15s"}),input:{flex:1,fontSize:"9px",background:e.inputBg,border:`1px solid ${e.inputBorder}`,borderRadius:"4px",padding:"2px 6px",color:e.text,outline:"none"},humanBanner:{padding:"6px 12px",fontSize:"11px",fontWeight:600,color:e.green,borderBottom:`1px solid ${e.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",background:e.greenBg,cursor:"pointer",textDecoration:"none"}});function yt(e){return e.split("/")[0].trim()}async function Qt(e){try{if(typeof navigator<"u"&&navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{if(typeof document>"u")return !1;let r=document.createElement("textarea");r.value=e,r.setAttribute("readonly",""),r.style.position="fixed",r.style.top="0",r.style.left="0",r.style.opacity="0",r.style.pointerEvents="none",document.body.appendChild(r),r.focus(),r.select(),r.setSelectionRange(0,e.length);let i=document.execCommand("copy");return document.body.removeChild(r),i}catch{return false}}function $e({config:e,appSlug:r,environment:i,seededUsers:c,authToken:d,tk:a,compact:M=false,onExpand:m,onAuthExpired:v,testRunId:u,testRunToken:h,ticketId:A,targetUrl:D,version:G,commitSha:P,prNumber:w,branchName:n}){let[g,te]=useState(false),[K,V]=useState(null),[C,N]=useState(null),[H,ne]=useState(null),[ye,S]=useState(null);useEffect(()=>{i==="local"&&Pe();},[i]);let _e=useCallback(b=>{V(b),ne(null),S(null);let $=T=>{ne(T),S(b),window.setTimeout(()=>{S(_=>_===b?null:_),ne(_=>_===T?null:_);},3e3);},k=new URLSearchParams({app_slug:r,seed_user_slug:b,environment:i});u&&k.set("test_run_id",u),h&&k.set("public_token",h),A&&k.set("ticket_id",A),D&&k.set("target_url",D),G&&k.set("version",G),P&&k.set("commit_sha",P),w&&k.set("pr_number",String(w)),n&&k.set("branch_name",n);let W={apikey:e.anonKey};W.Authorization=`Bearer ${d||e.anonKey}`;let z=(async()=>{if(i==="local"){let T=await mt(b);if(T)try{return {ok:!0,code:await bt(T)}}catch{}}try{let T=await fetch(`${e.serverUrl}/widget/totp-code?${k}`,{headers:W});if(!T.ok){let j=await T.json().catch(()=>({error:`HTTP ${T.status}`}));return {ok:!1,status:T.status,error:j.error||`HTTP ${T.status}`}}let _=await T.json();return {ok:!0,code:String(_.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),L=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let T=z.then(_=>{if(!_.ok)throw new Error(_.error);return new Blob([_.code],{type:"text/plain"})});L=navigator.clipboard.write([new ClipboardItem({"text/plain":T})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let T=await z;if(!T.ok){T.status===401?$("BotBuddy sign-in expired \u2014 sign out and sign in again"):$(T.status===404?"No 2FA seed registered":T.error),V(null);return}let _=L?await L:false,j=_?true:await Qt(T.code),R=_||j;N({slug:b,code:T.code,copied:R}),window.setTimeout(()=>N(ee=>ee?.slug===b?null:ee),R?2500:6e3),te(false),V(null);})();},[e.serverUrl,e.anonKey,d,r,i,u,h,A,D,G,P,w,n]),re=useRef(null),X=useRef(null);if(useLayoutEffect(()=>{if(!g)return;let b=re.current,$=X.current;if(!b||!$||typeof window>"u")return;let k=()=>{let W=b.getBoundingClientRect(),z=$.getBoundingClientRect(),L=window.innerWidth,T=window.innerHeight,_=W.left,j=W.top-z.height-6;j<8&&(j=W.bottom+6);let R=Math.max(8,L-z.width-8),ee=Math.max(8,T-z.height-8);_=Math.min(Math.max(_,8),R),j=Math.min(Math.max(j,8),ee),$.style.left=`${Math.round(_)}px`,$.style.top=`${Math.round(j)}px`;};return k(),window.addEventListener("scroll",k,true),window.addEventListener("resize",k),()=>{window.removeEventListener("scroll",k,true),window.removeEventListener("resize",k);}},[g,c.length,H]),useEffect(()=>{if(!g)return;let b=$=>{let k=$.target;X.current?.contains(k)||re.current?.contains(k)||te(false);};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[g]),c.length===0)return null;if(M){let b=c.length>1,$=_=>{if(_.stopPropagation(),b&&m){m();return}_e(c[0]);},k=!!ye,W=!!C,z=W&&C.copied,L=W&&!C.copied,T=k?a.red:z?a.green:L?a.amber:a.purple;return jsxs("span",{onPointerDown:_=>_.stopPropagation(),onPointerUp:_=>_.stopPropagation(),onPointerMove:_=>_.stopPropagation(),onClick:$,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:T,fontWeight:600,cursor:"pointer",letterSpacing:L?"0.08em":void 0},title:k?H||"Failed":L?`Clipboard blocked \u2014 code: ${C.code}`:b?`${c.length} 2FA personas`:`Copy 2FA code for ${c[0]}`,children:[jsx(y,{d:k?f.alert:z?f.check:L?f.copy:f.shield,size:10}),z?jsx(Fragment,{children:"Copied"}):L?jsx(Fragment,{children:C.code}):k?jsx(Fragment,{children:"Failed"}):jsxs(Fragment,{children:["2FA",b&&` \xB7${c.length}`]})]})}if(c.length===1){let b=c[0],$=K===b,k=C?.slug===b,W=k&&C.copied,z=k&&!C.copied,L=ye===b,T=L?a.red:W?a.green:z?a.amber:a.purple;return jsxs("button",{onClick:_=>{_.stopPropagation(),_e(b);},disabled:$,style:{...vt(T),cursor:$?"wait":"pointer",opacity:$?.6:1},title:L?H||"Failed":z?`Clipboard blocked \u2014 code: ${C.code}`:`Copy 2FA code for ${b}`,children:[jsx(y,{d:L?f.alert:W?f.check:z?f.copy:f.shield,size:12}),W?"Copied":z?C.code:L?"Failed":$?"\u2026":`2FA \xB7 ${b}`]})}let O=!!ye&&!g,oe=!!C&&C.copied,q=!!C&&!C.copied,ze=O?a.red:oe?a.green:q?a.amber:a.purple,ie=g&&typeof document<"u"?createPortal(jsxs("div",{ref:X,onPointerDown:b=>b.stopPropagation(),onMouseDown:b=>b.stopPropagation(),style:{position:"fixed",left:-9999,top:-9999,background:a.bg,border:`1px solid ${a.border}`,borderRadius:6,boxShadow:`0 8px 24px ${a.shadow}`,padding:4,minWidth:220,maxWidth:typeof window<"u"?Math.min(420,window.innerWidth-16):420,zIndex:1e5,fontFamily:"ui-monospace, SFMono-Regular, monospace"},children:[c.map(b=>{let $=K===b;return jsxs("button",{onClick:k=>{k.stopPropagation(),_e(b);},disabled:$,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:$?"wait":"pointer",fontSize:"10px",color:a.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:k=>k.currentTarget.style.background=a.btnHover,onMouseLeave:k=>k.currentTarget.style.background="transparent",children:[jsx(y,{d:f.shield,size:10}),jsx("span",{style:{flex:1,overflowWrap:"anywhere",lineHeight:1.3},children:b}),$&&jsx("span",{style:{color:a.textMuted,fontSize:9},children:"\u2026"})]},b)}),H&&jsx("div",{style:{padding:"4px 8px",fontSize:9,color:a.red},children:H})]}),document.body):null;return jsxs(Fragment,{children:[jsxs("button",{ref:re,onClick:b=>{b.stopPropagation(),te($=>!$),ne(null),S(null);},style:{...vt(ze),cursor:"pointer"},title:O?H||"Failed":q?`Clipboard blocked \u2014 code: ${C.code}`:"Choose a persona to copy a 2FA code for",children:[jsx(y,{d:O?f.alert:oe?f.check:q?f.copy:f.shield,size:12}),oe?"Copied":q?C.code:O?"Failed":`2FA \xB7 ${c.length}`,jsx(y,{d:g?f.chevronUp:f.chevronDown,size:8})]}),ie]})}function vt(e){return {display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${e}15`,color:e,textDecoration:"none",border:`1px solid ${e}30`}}var wt="botbuddy-widget-state";function en({config:e,appSlug:r,environment:i,ticketId:c,testRunId:d,testRunToken:a,targetUrl:M,version:m,commitSha:v,prNumber:u,branchName:h,onNavigate:A,displayName:D="human",defaultMode:G="mini",defaultPosition:P}){let w=Vt(),n=useMemo(()=>Yt(w),[w]),g=useMemo(()=>Zt(n),[n]),[te,K]=useState(false),[V,C]=useState(false),[N,H]=useState(false),ne=useRef(false),ye=e.dashboardUrl||"https://app.bot-buddy.ai",S=je(ye),re=(()=>{try{let t=typeof window<"u"?localStorage.getItem(wt):null;if(t)return JSON.parse(t)}catch{}return null})(),[X,O]=useState(re?.mode||G),[oe,q]=useState(""),[ze,ie]=useState(null),[b,$]=useState(null),[k,W]=useState(new Set),[z,L]=useState(""),T=useCallback(t=>{W(l=>{let x=new Set(l);return x.has(t)?x.delete(t):x.add(t),x});},[]),_=re?.x??P?.x??16,j=re?.y??P?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:R,setPos:ee,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,didDrag:Be}=De(_,j),ue=useRef(null);useEffect(()=>{try{localStorage.setItem(wt,JSON.stringify({mode:X,x:R.x,y:R.y}));}catch{}},[X,R.x,R.y]),useLayoutEffect(()=>{if(typeof window>"u")return;let t=ue.current;if(!t)return;let l=t.getBoundingClientRect(),x=Ue(R.x,R.y,l.width,l.height,window.innerWidth,window.innerHeight);(x.x!==R.x||x.y!==R.y)&&ee(x);}),useEffect(()=>{if(typeof window>"u")return;let t=()=>{let l=ue.current;if(!l)return;let x=l.getBoundingClientRect(),U=Ue(R.x,R.y,x.width,x.height,window.innerWidth,window.innerHeight);(U.x!==R.x||U.y!==R.y)&&ee(U);};return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[R.x,R.y,ee]);let Ve=useRef(S.isAuthenticated);useEffect(()=>{!Ve.current&&S.isAuthenticated&&O("max"),Ve.current=S.isAuthenticated;},[S.isAuthenticated]);let Ye="botbuddy-widget-max-size",kt=()=>{try{let t=localStorage.getItem(Ye);if(t)return JSON.parse(t)}catch{}return {w:340,h:500}},[ve,Je]=useState(kt),we=useRef(false),Se=useRef({x:0,y:0,w:0,h:0}),_t=useCallback(t=>{t.stopPropagation(),we.current=true,Se.current={x:t.clientX,y:t.clientY,w:ve.w,h:ve.h},t.target.setPointerCapture(t.pointerId);},[ve]),Mt=useCallback(t=>{if(!we.current)return;let l=Math.max(280,Math.min(600,Se.current.w+(t.clientX-Se.current.x))),x=Math.max(300,Math.min(window.innerHeight*.9,Se.current.h+(t.clientY-Se.current.y)));Je({w:l,h:x});},[]),Tt=useCallback(()=>{we.current&&(we.current=false,Je(t=>(localStorage.setItem(Ye,JSON.stringify(t)),t)));},[]),Y=M??(typeof window<"u"?window.location.href:void 0),Ge=S.displayName||D,[Z,Xe]=useState(null);useEffect(()=>{if(S.isAuthenticated)return;let t=new URLSearchParams;a&&t.set("token",a),c&&t.set("ticket_id",c),t.set("app_slug",r),i&&t.set("environment",i),d&&t.set("test_run_id",d),Y&&t.set("target_url",Y),m&&t.set("version",m),v&&t.set("commit_sha",v),u&&t.set("pr_number",String(u)),h&&t.set("branch_name",h),fetch(`${e.serverUrl}/widget/preview?${t}`,{headers:{apikey:e.anonKey}}).then(l=>l.json()).then(l=>Xe(l)).catch(()=>Xe(null));},[S.isAuthenticated,e.serverUrl,e.anonKey,r,i,c,d,a,Y,m,v,u,h]);let{run:p,widgetState:se,fetchRun:Ct,setVerdict:qe,markComplete:Rt,resetRun:Pt,setRun:Ze}=He({config:e,appSlug:r,environment:i,ticketId:c,testRunId:d,testRunToken:a,targetUrl:Y,version:m,commitSha:v,prNumber:u?String(u):void 0,branchName:h,authToken:S.token,onAuthExpired:S.logout}),[Qe,et]=useState([]),[Ee,tt]=useState(false),[nt,rt]=useState(null),ge=qt(typeof window<"u"?window.location.hostname:void 0,e.productionHostnames||[]);useEffect(()=>{if((i??"local")!=="local"||ge){et([]);return}let t=true;return Pe().then(l=>{t&&et(Object.keys(l||{}));}),()=>{t=false;}},[i,ge]);let $t=useCallback(async()=>{if(!(!S.isAuthenticated||!S.token)){tt(true),rt(null);try{let t=await fetch(`${e.serverUrl}/widget/test-runs`,{method:"POST",headers:{"Content-Type":"application/json",apikey:e.anonKey,Authorization:`Bearer ${S.token}`},body:JSON.stringify({app_slug:r,environment:i||"local",target_url:Y,branch_name:h,commit_sha:v,pr_number:u,ticket_id:c,title:`${c||r} local validation`})}),l=await t.json().catch(()=>({}));if(!t.ok)throw new Error(l.error||`HTTP ${t.status}`);Ze(l),O("max");}catch(t){rt(t.message);}finally{tt(false);}}},[S.isAuthenticated,S.token,e.serverUrl,e.anonKey,r,i,Y,h,v,u,c,Ze]),Me=useCallback(async(t,l,x)=>{$(t);try{await qe(t,l,x,Ge);}finally{$(null),ie(null),q("");}},[qe,Ge]),B=p?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},zt=B.total>0&&B.pending===0,fe=se==="completed",Te=useMemo(()=>{let t=p?.test_cases||[];if(!z.trim())return t;let l=z.toLowerCase();return t.filter(x=>x.title.toLowerCase().includes(l)||x.description&&x.description.toLowerCase().includes(l)||x.url_path&&x.url_path.toLowerCase().includes(l)||x.seed_user&&x.seed_user.toLowerCase().includes(l))},[p?.test_cases,z]),ot=useMemo(()=>{let t=Te,l=p?.test_cases||[];if(new Set(l.map(I=>I.source_pr_number)).size<=1)return null;let U=[],ke=new Map;t.forEach(I=>{let J=I.source_pr_number;ke.has(J)||ke.set(J,[]),ke.get(J).push(I);});let Bt=[...ke.keys()].sort((I,J)=>I===null?1:J===null?-1:J-I);for(let I of Bt){let J=ke.get(I),Ae={total:J.length,pass:0,fail:0,skip:0,pending:0};J.forEach(ut=>{ut.verdict in Ae&&Ae[ut.verdict]++;}),U.push({key:I!=null?`pr-${I}`:"general",label:I!=null?`PR #${I}`:"General",cases:J,summary:Ae});}return U.filter(I=>I.cases.length>0)},[Te,p?.test_cases]),it=B.total>0?(B.pass+B.fail)/B.total*100:0,F=i??p?.environment??null,he=useMemo(()=>{if(!F||F==="production"||ge)return [];let t=p?.test_cases||[],l=new Set;for(let x of t)x.seed_user&&l.add(yt(x.seed_user));if(F==="local")for(let x of Qe)l.add(yt(x));return [...l]},[p?.test_cases,F,Qe,ge]),Le=useMemo(()=>{let t=p?.auto_tooltip_seconds??Z?.auto_tooltip_seconds;return t!=null&&t>0?t*1e3:0},[p,Z]),st=se==="ready"||se==="completed"||Z?.enabled&&Z.run;useEffect(()=>{if(!st||ne.current||Le<=0)return;ne.current=true,C(true);let t=window.setTimeout(()=>C(false),Le);return ()=>window.clearTimeout(t)},[st,Le]);let at=t=>jsxs("div",{style:g.caseRow,children:[jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"},children:[jsx("div",{style:{marginTop:"2px",flexShrink:0,color:Jt[t.verdict]},children:b===t.id?jsx(y,{d:f.loader,className:""}):jsx(y,{d:Gt[t.verdict],className:""})}),jsxs("div",{style:{minWidth:0,flex:1},children:[jsx("div",{style:{fontSize:"10px",color:n.text,lineHeight:1.3},children:t.title}),t.description&&jsx("div",{style:{fontSize:"9px",color:n.gripColor,marginTop:"2px"},children:t.description}),t.seed_user&&jsxs("div",{style:{fontSize:"9px",color:n.amber,marginTop:"3px",display:"inline-flex",alignItems:"center",gap:"4px",padding:"2px 6px",borderRadius:"4px",background:`${n.amber}12`,border:`1px solid ${n.amber}30`},children:[jsx(y,{d:f.key,size:10}),jsx("span",{children:t.seed_user})]}),t.url_path&&jsxs("a",{href:t.url_path,target:"_blank",rel:"noopener noreferrer",onClick:l=>{l.stopPropagation(),A&&(l.preventDefault(),A(t.url_path));},style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",padding:"2px 0",marginTop:"2px",display:"inline-flex",alignItems:"center",gap:"2px",textDecoration:"none",position:"relative",zIndex:1,pointerEvents:"auto"},children:[jsx(y,{d:f.externalLink,size:10}),t.url_path]}),t.verdict==="fail"&&t.fail_reason&&jsxs("div",{style:{fontSize:"9px",color:n.red,marginTop:"2px"},children:["\u2717 ",t.fail_reason]})]})]}),jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px",marginTop:"4px",marginLeft:"22px"},children:[["pass","fail","skip"].map(l=>jsx("button",{onClick:()=>{if(t.verdict===l){Me(t.id,"pending"),ie(null);return}if(l==="fail"){ie(t.id),q("");return}ie(null),Me(t.id,l);},disabled:b!==null,style:g.verdictBtn(t.verdict===l,l==="pass"?n.green:l==="fail"?n.red:n.amber),children:l.toUpperCase()},l)),t.created_by_agent_name&&jsxs("span",{style:{fontSize:"8px",color:n.purple,marginLeft:"4px",display:"inline-flex",alignItems:"center",gap:"2px"},children:[jsx(y,{d:f.bot,size:8}),t.created_by_agent_name]}),t.verdict_by_display_name&&jsxs("span",{style:{fontSize:"8px",color:n.textFaint,marginLeft:"auto",display:"inline-flex",alignItems:"center",gap:"3px"},children:[t.verdict_by_display_name,t.verdict_at&&jsx("span",{style:{opacity:.7},children:jt(t.verdict_at)})]})]}),ze===t.id&&jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsx("input",{autoFocus:true,value:oe,onChange:l=>q(l.target.value),onKeyDown:l=>{l.key==="Enter"&&Me(t.id,"fail",oe.trim()||void 0),l.key==="Escape"&&(ie(null),q(""));},placeholder:"Reason (optional)...",style:g.input}),jsx("button",{onClick:()=>{Me(t.id,"fail",oe.trim()||void 0);},style:g.verdictBtn(true,n.red),children:"\u2713"})]})]},t.id);if((se==="no-match"||se==="loading")&&!(!S.isAuthenticated&&Z?.enabled&&Z.run)){if(!(F==="local"&&!ge))return null}if(!S.isAuthenticated&&Z?.enabled&&Z.run){let t=Z.run,l=t.summary,x=t.status==="completed";return jsx("div",{ref:ue,style:{...g.root,left:R.x,top:R.y},children:jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),H(false),C(false);},children:[jsxs("div",{style:{...g.pill(x),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe();},children:[jsx(y,{d:f.grip,size:10,className:""}),t.ticket_id&&t.ticket_url?jsx("a",{href:t.ticket_url,target:"_blank",rel:"noopener noreferrer",onClick:U=>U.stopPropagation(),style:{color:n.amber,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:t.ticket_id}):null,t.pr_url?jsxs("a",{href:t.pr_url,target:"_blank",rel:"noopener noreferrer",onClick:U=>U.stopPropagation(),style:{color:n.blue,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:["PR#",t.pr_number??t.pr_id]}):null,t.created_by_agent_name?t.codex_thread_id?jsxs("a",{href:`codex://threads/${t.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",onClick:U=>U.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsx(y,{d:f.terminal,size:10}),t.created_by_agent_name]}):jsxs("span",{style:{color:n.purple,fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsx(y,{d:f.bot,size:10}),t.created_by_agent_name]}):null,jsxs("span",{style:x?{color:n.green}:void 0,children:[l.pass,"/",l.total]}),l.fail>0&&jsxs("span",{style:{color:n.red},children:[l.fail,"\u2717"]}),jsx("span",{onClick:U=>{U.stopPropagation(),S.openLogin();},style:{color:n.textMuted,fontWeight:400,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},children:"Sign in"})]}),!N&&(te||V)&&t.title&&jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:t.title}),(t.description||t.intro_notes)&&jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:t.description||t.intro_notes}),jsx("div",{style:{marginTop:"4px",fontSize:"9px",color:n.textFaint},children:'Click "Sign in" to start testing'})]})]})})}if(!S.isAuthenticated)return jsxs("div",{ref:ue,style:{...g.root,left:R.x,top:R.y,width:220,minHeight:0,cursor:"move",userSelect:"none",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`},onPointerDown:de,onPointerMove:ce,onPointerUp:pe,children:[jsx("div",{style:{...g.handle,borderBottom:"none"},children:jsxs("div",{style:g.sub,children:[jsx(y,{d:f.grip,size:10,className:""}),jsx(y,{d:f.clipboard,size:12,className:""}),jsx("span",{style:{fontWeight:600},children:"BotBuddy"})]})}),jsxs("div",{style:{padding:"12px 14px",textAlign:"center"},children:[jsx("div",{style:{fontSize:"9px",color:n.textMuted,marginBottom:"8px"},children:"Sign in to access test cases"}),F==="local"&&he.length>0&&jsx("div",{style:{display:"flex",justifyContent:"center",marginBottom:"8px"},children:jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,testRunId:p?.id||d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout})}),jsx("button",{onClick:t=>{t.stopPropagation(),S.openLogin();},style:{fontSize:"10px",fontWeight:600,padding:"6px 16px",borderRadius:"6px",border:`1px solid ${n.green}`,background:`${n.green}22`,color:n.green,cursor:"pointer",width:"100%"},children:"Sign in to test"})]})]});if(!p&&F==="local"&&!ge)return jsxs("div",{ref:ue,style:{...g.root,left:R.x,top:R.y,width:240,minHeight:0,cursor:"move",userSelect:"none",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`},onPointerDown:de,onPointerMove:ce,onPointerUp:pe,children:[jsx("div",{style:{...g.handle,borderBottom:`1px solid ${n.borderSubtle}`},children:jsxs("div",{style:g.sub,children:[jsx(y,{d:f.grip,size:10,className:""}),jsx(y,{d:f.clipboard,size:12,className:""}),jsx("span",{style:{fontWeight:600},children:"BotBuddy"})]})}),jsxs("div",{style:{padding:"12px 14px",textAlign:"center"},children:[he.length>0&&jsx("div",{style:{display:"flex",justifyContent:"center",marginBottom:"8px"},children:jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,testRunId:d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout})}),jsx("button",{onClick:t=>{t.stopPropagation(),$t();},disabled:Ee,style:{fontSize:"10px",fontWeight:600,padding:"6px 12px",borderRadius:"6px",border:`1px solid ${n.green}`,background:`${n.green}22`,color:n.green,cursor:Ee?"wait":"pointer",width:"100%"},children:Ee?"Creating...":"Create test run for this branch"}),nt&&jsx("div",{style:{fontSize:"9px",color:n.red,marginTop:"8px"},children:nt})]})]});let lt=()=>{Be.current||(C(false),O(t=>{let l=t==="mini"?"max":"mini";return H(l==="mini"),l}));},dt=({icon:t,onClick:l})=>jsx("button",{style:g.btn,onClick:x=>{x.stopPropagation(),l(x);},children:jsx(y,{d:t,className:""})}),ct=()=>jsxs("div",{style:{padding:"6px 12px",display:"flex",gap:"8px",flexWrap:"wrap",alignItems:"center",borderTop:`1px solid ${n.borderSubtle}`,flexShrink:0},children:[p?.pr_url&&jsxs("a",{href:p.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.blue),textDecoration:"none"},children:[jsx(y,{d:f.pr,size:12}),p.pr_number?`PR#${p.pr_number}`:p.pr_id||"PR",jsx(y,{d:f.externalLink,size:8})]}),p?.ticket_url&&jsxs("a",{href:p.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.amber),textDecoration:"none"},children:[jsx(y,{d:f.ticket,size:12}),p.ticket_id||"Ticket",jsx(y,{d:f.externalLink,size:8})]}),p?.created_by_agent_name&&(p.codex_thread_id?jsxs("a",{href:`codex://threads/${p.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.purple),textDecoration:"none"},children:[jsx(y,{d:f.bot,size:12}),p.created_by_agent_name,jsx(y,{d:f.externalLink,size:8})]}):jsxs("span",{style:{...g.link(n.purple)},children:[jsx(y,{d:f.bot,size:12}),p.created_by_agent_name]})),F&&jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,testRunId:p?.id||d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout}),jsx("span",{style:{...g.badge(p?.environment||"custom"),marginLeft:"auto"},children:p?.environment})]}),pt=()=>jsxs("div",{style:{padding:"4px 12px",display:"flex",alignItems:"center",justifyContent:"center",borderTop:`1px solid ${n.borderSubtle}`,background:n.bgSoft,flexShrink:0},children:[jsxs("button",{onClick:()=>{navigator.clipboard.writeText("0.9.14");},style:{fontSize:"9px",fontWeight:600,color:n.versionText,letterSpacing:"0.08em",background:"none",border:"none",cursor:"pointer",display:"inline-flex",alignItems:"center",gap:"4px",padding:0},title:"Copy version",children:["BotBuddy ",jsx("span",{style:{color:n.versionNum},children:"v0.9.14"})]}),S.isAuthenticated&&jsx("button",{onClick:t=>{t.stopPropagation(),S.logout();},style:{fontSize:"8px",color:n.textFaint,background:"none",border:"none",cursor:"pointer",marginLeft:"8px",padding:"0 4px",textDecoration:"underline"},title:"Sign out of widget",children:"sign out"})]});return jsxs("div",{ref:ue,style:{...g.root,left:R.x,top:R.y},children:[X==="mini"&&jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),H(false),C(false);},children:[jsxs("div",{style:{...g.pill(fe),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe(),Be.current||lt();},children:[jsx(y,{d:f.grip,size:9,className:""}),p?.ticket_id&&jsx("span",{style:{color:n.amber,fontWeight:600},children:p.ticket_id}),p?.pr_number&&jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",p.pr_number]}),jsxs("span",{style:fe?{color:n.green}:void 0,children:[B.pass,"/",B.total]}),B.fail>0&&jsxs("span",{style:{color:n.red},children:[B.fail,"\u2717"]}),F&&jsx($e,{config:e,appSlug:r,environment:F,seededUsers:he,authToken:S.token,tk:n,compact:true,onExpand:()=>O("expanded"),testRunId:p?.id||d,testRunToken:a,ticketId:c,targetUrl:Y,version:m,commitSha:v,prNumber:u,branchName:h,onAuthExpired:S.logout})]}),!N&&(te||V)&&p?.title&&jsxs("div",{style:{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"180px",maxWidth:"260px",padding:"8px 12px",borderRadius:"8px",background:n.bg,border:`1px solid ${n.border}`,boxShadow:`0 8px 24px ${n.shadow}`,pointerEvents:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},children:[jsx("div",{style:{fontSize:"11px",fontWeight:700,color:n.text,lineHeight:1.3,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical"},children:p.title}),(p.description||p.intro_notes)&&jsx("div",{style:{fontSize:"10px",color:n.textMuted,marginTop:"4px",lineHeight:1.35,overflow:"hidden",textOverflow:"ellipsis",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical"},children:p.description||p.intro_notes})]})]}),X==="expanded"&&jsxs("div",{style:g.card(300,fe),children:[jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:lt,children:[jsx(y,{d:f.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:g.title,children:p?.title}),jsx("div",{style:g.sub,children:p?.branch_name&&jsxs("span",{children:["\u2387 ",p.branch_name]})})]}),jsx(y,{d:f.chevronUp,className:""}),jsx(dt,{icon:f.minus,onClick:()=>{C(false),H(true),O("mini");}})]}),jsxs("div",{style:g.stats,children:[jsxs("span",{style:{color:n.green},children:[B.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[B.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[B.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[B.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:B.total})]}),p?.description&&jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:p.description}),ct(),pt(),jsx("div",{style:g.progress,children:jsx("div",{style:g.progressBar(it)})})]}),X==="max"&&jsxs("div",{style:{...g.card(ve.w,fe),height:ve.h,position:"relative"},children:[jsxs("div",{style:g.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:()=>{Be.current||O("expanded");},children:[jsx(y,{d:f.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:g.title,children:p?.title}),jsx("div",{style:g.sub,children:p?.branch_name&&jsxs("span",{children:["\u2387 ",p.branch_name]})})]}),jsx(y,{d:f.chevronDown,className:""}),jsx(dt,{icon:f.minus,onClick:()=>{C(false),H(true),O("mini");}})]}),jsxs("div",{style:g.stats,children:[jsxs("span",{style:{color:n.green},children:[B.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[B.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[B.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[B.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:B.total})]}),p?.intro_notes&&jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:p.intro_notes}),(p?.test_cases||[]).length>5&&jsxs("div",{style:{padding:"4px 12px",borderBottom:`1px solid ${n.borderSubtle}`,display:"flex",alignItems:"center",gap:"6px",flexShrink:0},children:[jsx(y,{d:f.search,size:11,className:""}),jsx("input",{value:z,onChange:t=>L(t.target.value),placeholder:"Filter test cases...",style:{flex:1,fontSize:"10px",background:"transparent",border:"none",outline:"none",color:n.text,fontFamily:"monospace"}}),z&&jsx("button",{onClick:()=>L(""),style:{background:"none",border:"none",cursor:"pointer",color:n.textFaint,fontSize:"10px",padding:0},children:"\u2715"})]}),se==="error"&&jsxs("div",{style:{padding:"12px",textAlign:"center"},children:[jsx(y,{d:f.alert,className:""}),jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsx("button",{onClick:Ct,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),fe&&jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsx(y,{d:f.checkAll,className:""}),jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsx("button",{onClick:Pt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),se!=="error"&&jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(p?.test_cases||[]).length===0?jsx("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:"No test cases"}):Te.length===0?jsxs("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:['No matches for "',z,'"']}):ot?ot.map(t=>{let l=k.has(t.key);return jsxs("div",{children:[jsxs("button",{onClick:()=>T(t.key),style:{width:"100%",display:"flex",alignItems:"center",gap:"6px",padding:"5px 12px",background:n.bgSoft,cursor:"pointer",border:"none",borderLeft:"none",borderRight:"none",borderBottomStyle:"solid",borderTopStyle:"solid",borderBottomWidth:"1px",borderTopWidth:"1px",borderBottomColor:n.borderSubtle,borderTopColor:n.borderSubtle,backgroundColor:n.bgSoft},children:[jsx(y,{d:l?f.chevronDown:f.chevronUp,size:10,className:""}),jsx("span",{style:{fontSize:"10px",fontWeight:700,color:n.blue,flex:1,textAlign:"left"},children:t.label}),jsxs("span",{style:{fontSize:"9px",color:n.green},children:[t.summary.pass,"\u2713"]}),jsxs("span",{style:{fontSize:"9px",color:n.red},children:[t.summary.fail,"\u2717"]}),jsxs("span",{style:{fontSize:"9px",color:n.gripColor},children:[t.summary.pending,"\u25CC"]}),jsx("span",{style:{fontSize:"9px",color:n.textFaint},children:t.summary.total})]}),!l&&t.cases.map(x=>at(x))]},t.key)}):Te.map(t=>at(t))}),zt&&!fe&&jsxs("div",{style:{padding:"6px 12px",borderTop:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg,display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:0},children:[jsx("span",{style:{fontSize:"9px",color:n.green},children:"All resolved"}),jsx("button",{onClick:Rt,style:{fontSize:"8px",padding:"2px 8px",borderRadius:"4px",background:"rgba(52,211,153,0.15)",color:n.green,border:`1px solid ${n.greenBorderSubtle}`,cursor:"pointer"},children:"COMPLETE"})]}),ct(),pt(),jsx("div",{style:g.progress,children:jsx("div",{style:g.progressBar(it)})}),jsx("div",{style:{position:"absolute",bottom:0,right:0,width:16,height:16,cursor:"se-resize",zIndex:10,display:"flex",alignItems:"flex-end",justifyContent:"flex-end",padding:"2px",opacity:.3},onPointerDown:_t,onPointerMove:Mt,onPointerUp:Tt,onPointerEnter:t=>t.currentTarget.style.opacity="0.7",onPointerLeave:t=>{we.current||(t.currentTarget.style.opacity="0.3");},children:jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",children:jsx("path",{d:"M7 1v6H1",fill:"none",stroke:n.gripColor,strokeWidth:"1.5",strokeLinecap:"round"})})})]})]})}
2
+ export{en as TestRunWidget,De as useDraggable,Fe as useRealtimeRefresh,He as useTestRun,je as useWidgetAuth};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbuddy/react",
3
- "version": "0.9.12",
3
+ "version": "0.9.14",
4
4
  "description": "BotBuddy test coordination widgets for React — draggable, translucent overlays for human-in-the-loop QA",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -15,7 +15,8 @@
15
15
  },
16
16
  "files": [
17
17
  "dist",
18
- "README.md"
18
+ "README.md",
19
+ "CHANGELOG.md"
19
20
  ],
20
21
  "sideEffects": false,
21
22
  "scripts": {