@botbuddy/react 0.9.10 → 0.9.13

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,41 @@
1
+ # @botbuddy/react — Changelog
2
+
3
+ ## 0.9.13
4
+
5
+ ### Added
6
+
7
+ - **Local-only file-based TOTP secrets.** When `environment === "local"`,
8
+ the widget now reads `public/.botbuddy-totp.json` (a developer-owned
9
+ map of `seed_user_slug → base32 TOTP secret`) and computes 2FA codes
10
+ in-browser using RFC 6238 (HMAC-SHA1, 30 s, 6 digits). This removes
11
+ the need for `BOTBUDDY_API_KEY` + a `register_totp_seed` MCP call on
12
+ local development. The file is honored **only** for
13
+ `environment === "local"`; preview/staging/production continue to
14
+ fetch from `/widget/totp-code` so the secret never leaves the
15
+ developer's machine. If a slug isn't present in the local file, the
16
+ widget falls back to the server endpoint, so the feature is purely
17
+ additive. Devs **must** gitignore `public/.botbuddy-totp.json`.
18
+
19
+ ### Tests
20
+
21
+ - Added `localTotp.test.ts` covering RFC 6238 SHA-1 vectors
22
+ (`T=59 → 287082`, `T=1111111109 → 081804`, `T=1234567890 → 005924`),
23
+ Base32 rejection of invalid input, and `loadLocalTotpSecrets()`
24
+ behavior on 404, network error, non-object payloads, and cache reuse.
25
+
26
+ ## 0.9.12
27
+
28
+ - BOT-380 — widget popover via portal + UI polish.
29
+
30
+ ## 0.9.10 and earlier
31
+
32
+ See git history (`git log -- packages/react`) for changes prior to the
33
+ introduction of this CHANGELOG. Highlights:
34
+
35
+ - 0.9.10 — BOT-380 viewport clamping for the 2FA persona popover.
36
+ - 0.9.9 — BOT-380 widget clamps into viewport so "Sign in" stays reachable.
37
+ - 0.9.8 — BOT-380 2FA chip self-recovers from stale JWT + UI rework.
38
+ - 0.9.5 — BOT-380 Safari clipboard fix (user-gesture-after-await).
39
+ - 0.9.4 — BOT-380 stop remounting `TotpChip` on every parent render.
40
+ - 0.9.1 — BOT-380 widget-level 2FA chip with persona popover.
41
+ - 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'),jsxRuntime=require('react/jsx-runtime');var Q=8;function qe(t,o,s,f,h,d){let M=Math.max(Q,h-s-Q),v=Math.max(Q,d-f-Q);return {x:Math.min(Math.max(t,Q),M),y:Math.min(Math.max(o,Q),v)}}function _e(t,o){let[s,f]=react.useState({x:t,y:o}),h=react.useRef(false),d=react.useRef({x:0,y:0}),M=react.useRef(false),v=react.useCallback(u=>{h.current=true,M.current=false,d.current={x:u.clientX-s.x,y:u.clientY-s.y},u.target.setPointerCapture(u.pointerId);},[s]),S=react.useCallback(u=>{h.current&&(M.current=true,f({x:u.clientX-d.current.x,y:u.clientY-d.current.y}));},[]),c=react.useCallback(()=>{h.current=false;},[]);return {pos:s,setPos:f,onPointerDown:v,onPointerMove:S,onPointerUp:c,didDrag:M}}function Me(t,o,s){let f=react.useRef(s);f.current=s,react.useEffect(()=>{if(!o)return;if(t.supabaseUrl){let d=false,M=null,v=()=>{d||M||(M=setInterval(()=>f.current(),15e3));},S=null;try{let T=new URL(t.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(T.hostname);if(T.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");T.protocol=T.protocol==="https:"?"wss:":"ws:",S=T.toString().replace(/\/$/,"");}catch{v();}let c=null,u=null,_=null,B=0,C=()=>{if(!(d||!S)){try{c=new WebSocket(`${S}/realtime/v1/websocket?apikey=${t.anonKey}&vsn=1.0.0`);}catch{v();return}c.onopen=()=>{if(d||!c)return;let T={topic:`realtime:public:test_run_cases:test_run_id=eq.${o}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_run_cases",filter:`test_run_id=eq.${o}`}]}},ref:String(++B)};c.send(JSON.stringify(T));let n={topic:`realtime:public:test_runs:id=eq.${o}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_runs",filter:`id=eq.${o}`}]}},ref:String(++B)};c.send(JSON.stringify(n)),u=setInterval(()=>{c?.readyState===WebSocket.OPEN&&c.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++B)}));},3e4);},c.onmessage=T=>{try{JSON.parse(T.data).event==="postgres_changes"&&f.current();}catch{}},c.onclose=()=>{F(),d||(_=setTimeout(C,3e3));},c.onerror=()=>{c?.close();};}},F=()=>{u&&(clearInterval(u),u=null);};return C(),()=>{d=true,F(),_&&clearTimeout(_),M&&clearInterval(M),c&&(c.onclose=null,c.onerror=null,c.close());}}let h=setInterval(()=>f.current(),15e3);return ()=>clearInterval(h)},[t.supabaseUrl,t.anonKey,o]);}function he(t,o){let s={apikey:t.anonKey};return o?s.Authorization=`Bearer ${o}`:t.apiKey?s.Authorization=`Bearer ${t.apiKey}`:s.Authorization=`Bearer ${t.anonKey}`,s}async function kt(t){if(t)return t;try{let o=await fetch("/.botbuddy-token",{cache:"no-store"});if(o.ok){let s=(await o.text()).trim();if(s.startsWith("public_"))return s}}catch{}try{let o=undefined?.VITE_BOTBUDDY_TEST_RUN_TOKEN;if(o&&typeof o=="string"&&o.startsWith("public_"))return o}catch{}return null}function Ce(t){let[o,s]=react.useState(null),[f,h]=react.useState("loading"),d=react.useCallback(async()=>{try{let c=await kt(t.testRunToken);if(!c){h("no-match"),s(null);return}if(!t.ticketId){h("no-match"),s(null);return}let u=new URLSearchParams;u.set("token",c),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 _=await fetch(`${t.config.serverUrl}/widget/test-run?${u.toString()}`,{headers:he(t.config,t.authToken)});if(_.status===404){h("no-match"),s(null);return}if(_.status===401||_.status===403){t.authToken&&t.onAuthExpired&&t.onAuthExpired(),h("error");return}if(!_.ok){h("error");return}let B=await _.json();s(B),h(B.status==="completed"?"completed":"ready");}catch{h("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(()=>{d();},[d]),Me(t.config,o?.id,d),{run:o,widgetState:f,fetchRun:d,setVerdict:async(c,u,_,B="human")=>(s(F=>{if(!F)return null;let T=F.test_cases.map(g=>g.id===c?{...g,verdict:u,fail_reason:u==="fail"&&_||null,verdict_by_display_name:B,verdict_at:new Date().toISOString()}:g),n={total:T.length,pending:0,pass:0,fail:0,skip:0};return T.forEach(g=>{g.verdict in n&&n[g.verdict]++;}),{...F,test_cases:T,summary:n}}),(await fetch(`${t.config.serverUrl}/widget/test-cases/${c}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...he(t.config,t.authToken)},body:JSON.stringify({verdict:u,fail_reason:_,display_name:B})})).ok),markComplete:async()=>o?(s(u=>u?{...u,status:"completed"}:null),h("completed"),(await fetch(`${t.config.serverUrl}/widget/test-runs/${o.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...he(t.config,t.authToken)}})).ok):false,resetRun:async()=>{if(!o)return false;let c=await fetch(`${t.config.serverUrl}/widget/test-runs/${o.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...he(t.config,t.authToken)}});return c.ok&&d(),c.ok},setRun:s}}var Te="botbuddy-widget-auth-token",Re="botbuddy-widget-auth-name";function ze(t){let[o,s]=react.useState(()=>{try{return localStorage.getItem(Te)}catch(v){return console.warn("Unable to read BotBuddy widget auth token",v),null}}),[f,h]=react.useState(()=>{try{return localStorage.getItem(Re)}catch(v){return console.warn("Unable to read BotBuddy widget display name",v),null}});react.useEffect(()=>{let v=new URL(t).origin,S=c=>{if(c.origin===v&&c.data?.type==="botbuddy-widget-auth"&&c.data.token){let{token:u,displayName:_}=c.data;s(u),h(_||"human");try{localStorage.setItem(Te,u),_&&localStorage.setItem(Re,_);}catch(B){console.warn("Unable to persist BotBuddy widget auth token",B);}}};return window.addEventListener("message",S),()=>window.removeEventListener("message",S)},[t]);let d=react.useCallback(()=>{let v=new URL("/widget-auth",t);v.searchParams.set("origin",window.location.origin);let S=420,c=520,u=window.screenX+(window.innerWidth-S)/2,_=window.screenY+(window.innerHeight-c)/2;window.open(v.toString(),"botbuddy-auth",`width=${S},height=${c},left=${u},top=${_},popup=yes`);},[t]),M=react.useCallback(()=>{s(null),h(null);try{localStorage.removeItem(Te),localStorage.removeItem(Re);}catch(v){console.warn("Unable to clear BotBuddy widget auth token",v);}},[]);return {token:o,displayName:f,isAuthenticated:!!o,openLogin:d,logout:M}}function Mt(t){let o=new Date(t),f=Date.now()-o.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 h=o.getDate(),d=o.toLocaleString("en",{month:"short"}),M=o.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${d} ${h}, ${M}`}var b=({d:t,className:o,size:s=14})=>jsxRuntime.jsx("svg",{className:o,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 Ct(){let[t,o]=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,h=f();h&&o(h);let d=window.matchMedia("(prefers-color-scheme: dark)"),M=S=>{let c=f();o(c||(S.matches?"dark":"light"));};d.addEventListener("change",M);let v=new MutationObserver(()=>{let S=f();o(S||(d.matches?"dark":"light"));});return v.observe(s,{attributes:true,attributeFilter:["class"]}),()=>{d.removeEventListener("change",M),v.disconnect();}},[]),t}function Tt(t){let o=t==="dark";return {bg:o?"rgb(30,30,30)":"rgb(255,255,255)",bgSoft:o?"rgba(255,255,255,0.02)":"rgba(0,0,0,0.02)",text:o?"#e5e5e5":"#1a1a1a",textMuted:o?"rgba(255,255,255,0.4)":"rgba(0,0,0,0.45)",textFaint:o?"#555":"#999",border:o?"rgba(255,255,255,0.15)":"rgba(0,0,0,0.12)",borderSubtle:o?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",shadow:o?"rgba(0,0,0,0.4)":"rgba(0,0,0,0.12)",inputBg:o?"rgba(0,0,0,0.3)":"rgba(0,0,0,0.04)",inputBorder:o?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.12)",green:"#34d399",greenBg:o?"rgba(52,211,153,0.05)":"rgba(52,211,153,0.08)",greenBorder:o?"rgba(52,211,153,0.6)":"rgba(52,211,153,0.5)",greenBorderSubtle:o?"rgba(52,211,153,0.2)":"rgba(52,211,153,0.15)",red:"#f87171",amber:"#f59e0b",blue:"#60a5fa",purple:"#a78bfa",versionText:o?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",versionNum:o?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",gripColor:o?"#888":"#aaa",btnHover:o?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.06)"}}var Rt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},zt={pending:p.circle,pass:p.check,fail:p.x,skip:p.skip},Qe={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)"}},Pt=t=>({root:{position:"fixed",zIndex:9999,userSelect:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},pill:o=>({display:"inline-flex",alignItems:"center",gap:"6px",padding:"4px 8px",borderRadius:"9999px",background:t.bg,border:o?`1px solid ${t.greenBorder}`:`1px solid ${t.border}`,boxShadow:o?`0 4px 12px ${t.shadow}, 0 0 0 1px ${t.greenBorderSubtle}`:`0 4px 12px ${t.shadow}`,cursor:"pointer",fontSize:"9px",color:t.text}),card:(o,s)=>({width:`${o}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:o=>{let s=Qe[o]||Qe.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:o=>({height:"100%",width:`${o}%`,background:"linear-gradient(to right, #34d399, #3b82f6)",transition:"width 0.5s"}),link:o=>({display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${o}15`,color:o,textDecoration:"none",border:"none",cursor:"pointer"}),caseRow:{padding:"6px 12px",borderBottom:`1px solid ${t.borderSubtle}`,transition:"background 0.15s"},verdictBtn:(o,s)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:o?`${s}33`:"transparent",color:o?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 $t(t){return t.split("/")[0].trim()}async function Bt(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 o=document.createElement("textarea");o.value=t,o.setAttribute("readonly",""),o.style.position="fixed",o.style.top="0",o.style.left="0",o.style.opacity="0",o.style.pointerEvents="none",document.body.appendChild(o),o.focus(),o.select(),o.setSelectionRange(0,t.length);let s=document.execCommand("copy");return document.body.removeChild(o),s}catch{return false}}function et({config:t,appSlug:o,environment:s,seededUsers:f,authToken:h,tk:d,compact:M=false,onExpand:v,onAuthExpired:S}){let[c,u]=react.useState(false),[_,B]=react.useState(null),[C,F]=react.useState(null),[T,n]=react.useState(null),[g,K]=react.useState(null),H=react.useCallback(x=>{B(x),n(null),K(null);let m=k=>{n(k),K(x),window.setTimeout(()=>{K(w=>w===x?null:w),n(w=>w===k?null:w);},3e3);},P=new URLSearchParams({app_slug:o,seed_user_slug:x,environment:s}),I={apikey:t.anonKey};I.Authorization=`Bearer ${h||t.anonKey}`;let $=(async()=>{try{let k=await fetch(`${t.serverUrl}/widget/totp-code?${P}`,{headers:I});if(!k.ok){let ie=await k.json().catch(()=>({error:`HTTP ${k.status}`}));return {ok:!1,status:k.status,error:ie.error||`HTTP ${k.status}`}}let w=await k.json();return {ok:!0,code:String(w.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),R=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let k=$.then(w=>{if(!w.ok)throw new Error(w.error);return new Blob([w.code],{type:"text/plain"})});R=navigator.clipboard.write([new ClipboardItem({"text/plain":k})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let k=await $;if(!k.ok){k.status===401||k.status===403?(S?.(),m("Signed out \u2014 please sign in again")):m(k.status===404?"No 2FA seed registered":k.error),B(null);return}let w=R?await R:false,ie=w?true:await Bt(k.code),V=w||ie;F({slug:x,code:k.code,copied:V}),window.setTimeout(()=>F(se=>se?.slug===x?null:se),V?2500:6e3),u(false),B(null);})();},[t.serverUrl,t.anonKey,h,o,s]);if(f.length===0)return null;if(M){let x=f.length>1,m=w=>{if(w.stopPropagation(),x&&v){v();return}H(f[0]);},P=!!g,I=!!C,$=I&&C.copied,R=I&&!C.copied,k=P?d.red:$?d.green:R?d.amber:d.purple;return jsxRuntime.jsxs("span",{onPointerDown:w=>w.stopPropagation(),onPointerUp:w=>w.stopPropagation(),onPointerMove:w=>w.stopPropagation(),onClick:m,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:k,fontWeight:600,cursor:"pointer",letterSpacing:R?"0.08em":void 0},title:P?T||"Failed":R?`Clipboard blocked \u2014 code: ${C.code}`:x?`${f.length} 2FA personas`:`Copy 2FA code for ${f[0]}`,children:[jsxRuntime.jsx(b,{d:P?p.alert:$?p.check:R?p.copy:p.shield,size:10}),$?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Copied"}):R?jsxRuntime.jsx(jsxRuntime.Fragment,{children:C.code}):P?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Failed"}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:["2FA",x&&` \xB7${f.length}`]})]})}if(f.length===1){let x=f[0],m=_===x,P=C?.slug===x,I=P&&C.copied,$=P&&!C.copied,R=g===x,k=R?d.red:I?d.green:$?d.amber:d.purple;return jsxRuntime.jsxs("button",{onClick:w=>{w.stopPropagation(),H(x);},disabled:m,style:{...tt(k),cursor:m?"wait":"pointer",opacity:m?.6:1},title:R?T||"Failed":$?`Clipboard blocked \u2014 code: ${C.code}`:`Copy 2FA code for ${x}`,children:[jsxRuntime.jsx(b,{d:R?p.alert:I?p.check:$?p.copy:p.shield,size:12}),I?"Copied":$?C.code:R?"Failed":m?"\u2026":`2FA \xB7 ${x}`]})}let j=!!g&&!c,D=!!C&&C.copied,Y=!!C&&!C.copied,J=j?d.red:D?d.green:Y?d.amber:d.purple,oe=react.useRef(null);return react.useLayoutEffect(()=>{if(!c)return;let x=oe.current;if(!x||typeof window>"u")return;let P=x.getBoundingClientRect().right-(window.innerWidth-8);P>0?x.style.left=`-${P}px`:x.style.left="0px";},[c]),jsxRuntime.jsxs("span",{style:{position:"relative"},children:[jsxRuntime.jsxs("button",{onClick:x=>{x.stopPropagation(),u(m=>!m),n(null),K(null);},style:{...tt(J),cursor:"pointer"},title:j?T||"Failed":Y?`Clipboard blocked \u2014 code: ${C.code}`:"Choose a persona to copy a 2FA code for",children:[jsxRuntime.jsx(b,{d:j?p.alert:D?p.check:Y?p.copy:p.shield,size:12}),D?"Copied":Y?C.code:j?"Failed":`2FA \xB7 ${f.length}`,jsxRuntime.jsx(b,{d:c?p.chevronUp:p.chevronDown,size:8})]}),c&&jsxRuntime.jsxs("div",{ref:oe,onPointerDown:x=>x.stopPropagation(),style:{position:"absolute",bottom:"100%",left:0,marginBottom:4,background:d.bg,border:`1px solid ${d.border}`,borderRadius:6,boxShadow:`0 8px 24px ${d.shadow}`,padding:4,minWidth:180,maxWidth:typeof window<"u"?Math.min(280,window.innerWidth-16):280,zIndex:10},children:[f.map(x=>{let m=_===x;return jsxRuntime.jsxs("button",{onClick:P=>{P.stopPropagation(),H(x);},disabled:m,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:m?"wait":"pointer",fontSize:"10px",color:d.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:P=>P.currentTarget.style.background=d.btnHover,onMouseLeave:P=>P.currentTarget.style.background="transparent",children:[jsxRuntime.jsx(b,{d:p.shield,size:10}),jsxRuntime.jsx("span",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:x}),m&&jsxRuntime.jsx("span",{style:{color:d.textMuted,fontSize:9},children:"\u2026"})]},x)}),T&&jsxRuntime.jsx("div",{style:{padding:"4px 8px",fontSize:9,color:d.red},children:T})]})]})}function tt(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 nt="botbuddy-widget-state";function Et({config:t,appSlug:o,environment:s,ticketId:f,testRunId:h,testRunToken:d,targetUrl:M,version:v,commitSha:S,prNumber:c,branchName:u,onNavigate:_,displayName:B="human",defaultMode:C="mini",defaultPosition:F}){let T=Ct(),n=react.useMemo(()=>Tt(T),[T]),g=react.useMemo(()=>Pt(n),[n]),[K,H]=react.useState(false),[j,D]=react.useState(false),[Y,J]=react.useState(false),oe=react.useRef(false),x=t.dashboardUrl||"https://app.bot-buddy.ai",m=ze(x),I=(()=>{try{let e=typeof window<"u"?localStorage.getItem(nt):null;if(e)return JSON.parse(e)}catch{}return null})(),[$,R]=react.useState(I?.mode||C),[k,w]=react.useState(""),[ie,V]=react.useState(null),[se,Pe]=react.useState(null),[rt,ot]=react.useState(new Set),[X,$e]=react.useState(""),it=react.useCallback(e=>{ot(l=>{let y=new Set(l);return y.has(e)?y.delete(e):y.add(e),y});},[]),st=I?.x??F?.x??16,at=I?.y??F?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:L,setPos:Be,onPointerDown:ae,onPointerMove:le,onPointerUp:de,didDrag:ye}=_e(st,at),fe=react.useRef(null);react.useEffect(()=>{try{localStorage.setItem(nt,JSON.stringify({mode:$,x:L.x,y:L.y}));}catch{}},[$,L.x,L.y]),react.useEffect(()=>{if(typeof window>"u")return;let e=()=>{let y=fe.current;if(!y)return;let A=y.getBoundingClientRect(),O=qe(L.x,L.y,A.width,A.height,window.innerWidth,window.innerHeight);(O.x!==L.x||O.y!==L.y)&&Be(O);},l=window.requestAnimationFrame(e);return window.addEventListener("resize",e),()=>{window.cancelAnimationFrame(l),window.removeEventListener("resize",e);}},[$,L.x,L.y,Be]);let Ee=react.useRef(m.isAuthenticated);react.useEffect(()=>{!Ee.current&&m.isAuthenticated&&R("max"),Ee.current=m.isAuthenticated;},[m.isAuthenticated]);let Le="botbuddy-widget-max-size",lt=()=>{try{let e=localStorage.getItem(Le);if(e)return JSON.parse(e)}catch{}return {w:340,h:500}},[ce,We]=react.useState(lt),pe=react.useRef(false),ue=react.useRef({x:0,y:0,w:0,h:0}),dt=react.useCallback(e=>{e.stopPropagation(),pe.current=true,ue.current={x:e.clientX,y:e.clientY,w:ce.w,h:ce.h},e.target.setPointerCapture(e.pointerId);},[ce]),ct=react.useCallback(e=>{if(!pe.current)return;let l=Math.max(280,Math.min(600,ue.current.w+(e.clientX-ue.current.x))),y=Math.max(300,Math.min(window.innerHeight*.9,ue.current.h+(e.clientY-ue.current.y)));We({w:l,h:y});},[]),pt=react.useCallback(()=>{pe.current&&(pe.current=false,We(e=>(localStorage.setItem(Le,JSON.stringify(e)),e)));},[]),me=M??(typeof window<"u"?window.location.href:void 0),Ie=m.displayName||B,[N,Ae]=react.useState(null);react.useEffect(()=>{if(m.isAuthenticated)return;let e=new URLSearchParams;d&&e.set("token",d),f&&e.set("ticket_id",f),e.set("app_slug",o),s&&e.set("environment",s),h&&e.set("test_run_id",h),me&&e.set("target_url",me),v&&e.set("version",v),S&&e.set("commit_sha",S),c&&e.set("pr_number",String(c)),u&&e.set("branch_name",u),fetch(`${t.serverUrl}/widget/preview?${e}`,{headers:{apikey:t.anonKey}}).then(l=>l.json()).then(l=>Ae(l)).catch(()=>Ae(null));},[m.isAuthenticated,t.serverUrl,t.anonKey,o,s,f,h,d,me,v,S,c,u]);let{run:a,widgetState:q,fetchRun:ut,setVerdict:Fe,markComplete:gt,resetRun:ft}=Ce({config:t,appSlug:o,environment:s,ticketId:f,testRunId:h,testRunToken:d,targetUrl:me,version:v,commitSha:S,prNumber:c?String(c):void 0,branchName:u,authToken:m.token,onAuthExpired:m.logout}),be=react.useCallback(async(e,l,y)=>{Pe(e);try{await Fe(e,l,y,Ie);}finally{Pe(null),V(null),w("");}},[Fe,Ie]),z=a?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},mt=z.total>0&&z.pending===0,Z=q==="completed",xe=react.useMemo(()=>{let e=a?.test_cases||[];if(!X.trim())return e;let l=X.toLowerCase();return e.filter(y=>y.title.toLowerCase().includes(l)||y.description&&y.description.toLowerCase().includes(l)||y.url_path&&y.url_path.toLowerCase().includes(l)||y.seed_user&&y.seed_user.toLowerCase().includes(l))},[a?.test_cases,X]),De=react.useMemo(()=>{let e=xe,l=a?.test_cases||[];if(new Set(l.map(W=>W.source_pr_number)).size<=1)return null;let A=[],O=new Map;e.forEach(W=>{let U=W.source_pr_number;O.has(U)||O.set(U,[]),O.get(U).push(W);});let bt=[...O.keys()].sort((W,U)=>W===null?1:U===null?-1:U-W);for(let W of bt){let U=O.get(W),we={total:U.length,pass:0,fail:0,skip:0,pending:0};U.forEach(Je=>{Je.verdict in we&&we[Je.verdict]++;}),A.push({key:W!=null?`pr-${W}`:"general",label:W!=null?`PR #${W}`:"General",cases:U,summary:we});}return A.filter(W=>W.cases.length>0)},[xe,a?.test_cases]),Ue=z.total>0?(z.pass+z.fail)/z.total*100:0,G=s??a?.environment??null,Ne=react.useMemo(()=>{if(!G||G==="production")return [];let e=a?.test_cases||[],l=new Set;for(let y of e)y.seed_user&&l.add($t(y.seed_user));return [...l]},[a?.test_cases,G]),ve=react.useMemo(()=>{let e=a?.auto_tooltip_seconds??N?.auto_tooltip_seconds;return e!=null&&e>0?e*1e3:0},[a,N]),Oe=q==="ready"||q==="completed"||N?.enabled&&N.run;react.useEffect(()=>{if(!Oe||oe.current||ve<=0)return;oe.current=true,D(true);let e=window.setTimeout(()=>D(false),ve);return ()=>window.clearTimeout(e)},[Oe,ve]);let He=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:Rt[e.verdict]},children:se===e.id?jsxRuntime.jsx(b,{d:p.loader,className:""}):jsxRuntime.jsx(b,{d:zt[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(b,{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:l=>{l.stopPropagation(),_&&(l.preventDefault(),_(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(b,{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(l=>jsxRuntime.jsx("button",{onClick:()=>{if(e.verdict===l){be(e.id,"pending"),V(null);return}if(l==="fail"){V(e.id),w("");return}V(null),be(e.id,l);},disabled:se!==null,style:g.verdictBtn(e.verdict===l,l==="pass"?n.green:l==="fail"?n.red:n.amber),children:l.toUpperCase()},l)),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(b,{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:Mt(e.verdict_at)})]})]}),ie===e.id&&jsxRuntime.jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsxRuntime.jsx("input",{autoFocus:true,value:k,onChange:l=>w(l.target.value),onKeyDown:l=>{l.key==="Enter"&&be(e.id,"fail",k.trim()||void 0),l.key==="Escape"&&(V(null),w(""));},placeholder:"Reason (optional)...",style:g.input}),jsxRuntime.jsx("button",{onClick:()=>{be(e.id,"fail",k.trim()||void 0);},style:g.verdictBtn(true,n.red),children:"\u2713"})]})]},e.id);if((q==="no-match"||q==="loading")&&!(!m.isAuthenticated&&N?.enabled&&N.run))return null;if(!m.isAuthenticated&&N?.enabled&&N.run){let e=N.run,l=e.summary,y=e.status==="completed";return jsxRuntime.jsx("div",{ref:fe,style:{...g.root,left:L.x,top:L.y},children:jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>H(true),onMouseLeave:()=>{H(false),J(false),D(false);},children:[jsxRuntime.jsxs("div",{style:{...g.pill(y),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:ae,onPointerMove:le,onPointerUp:()=>{de();},children:[jsxRuntime.jsx(b,{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:A=>A.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:A=>A.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:A=>A.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsxRuntime.jsx(b,{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(b,{d:p.bot,size:10}),e.created_by_agent_name]}):null,jsxRuntime.jsxs("span",{style:y?{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:A=>{A.stopPropagation(),m.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(!m.isAuthenticated)return jsxRuntime.jsxs("div",{ref:fe,style:{...g.root,left:L.x,top:L.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:ae,onPointerMove:le,onPointerUp:de,children:[jsxRuntime.jsx("div",{style:{...g.handle,borderBottom:"none"},children:jsxRuntime.jsxs("div",{style:g.sub,children:[jsxRuntime.jsx(b,{d:p.grip,size:10,className:""}),jsxRuntime.jsx(b,{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(),m.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 Ve=()=>{ye.current||(D(false),R(e=>{let l=e==="mini"?"max":"mini";return J(l==="mini"),l}));},Ke=({icon:e,onClick:l})=>jsxRuntime.jsx("button",{style:g.btn,onClick:y=>{y.stopPropagation(),l(y);},children:jsxRuntime.jsx(b,{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:[a?.pr_url&&jsxRuntime.jsxs("a",{href:a.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.blue),textDecoration:"none"},children:[jsxRuntime.jsx(b,{d:p.pr,size:12}),a.pr_number?`PR#${a.pr_number}`:a.pr_id||"PR",jsxRuntime.jsx(b,{d:p.externalLink,size:8})]}),a?.ticket_url&&jsxRuntime.jsxs("a",{href:a.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.amber),textDecoration:"none"},children:[jsxRuntime.jsx(b,{d:p.ticket,size:12}),a.ticket_id||"Ticket",jsxRuntime.jsx(b,{d:p.externalLink,size:8})]}),a?.created_by_agent_name&&(a.codex_thread_id?jsxRuntime.jsxs("a",{href:`codex://threads/${a.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.purple),textDecoration:"none"},children:[jsxRuntime.jsx(b,{d:p.bot,size:12}),a.created_by_agent_name,jsxRuntime.jsx(b,{d:p.externalLink,size:8})]}):jsxRuntime.jsxs("span",{style:{...g.link(n.purple)},children:[jsxRuntime.jsx(b,{d:p.bot,size:12}),a.created_by_agent_name]})),G&&jsxRuntime.jsx(et,{config:t,appSlug:o,environment:G,seededUsers:Ne,authToken:m.token,tk:n,onAuthExpired:m.logout}),jsxRuntime.jsx("span",{style:{...g.badge(a?.environment||"custom"),marginLeft:"auto"},children:a?.environment})]}),Ye=()=>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.10");},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.10"})]}),m.isAuthenticated&&jsxRuntime.jsx("button",{onClick:e=>{e.stopPropagation(),m.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:fe,style:{...g.root,left:L.x,top:L.y},children:[$==="mini"&&jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>H(true),onMouseLeave:()=>{H(false),J(false),D(false);},children:[jsxRuntime.jsxs("div",{style:{...g.pill(Z),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:ae,onPointerMove:le,onPointerUp:()=>{de(),ye.current||Ve();},children:[jsxRuntime.jsx(b,{d:p.grip,size:9,className:""}),a?.ticket_id&&jsxRuntime.jsx("span",{style:{color:n.amber,fontWeight:600},children:a.ticket_id}),a?.pr_number&&jsxRuntime.jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",a.pr_number]}),jsxRuntime.jsxs("span",{style:Z?{color:n.green}:void 0,children:[z.pass,"/",z.total]}),z.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[z.fail,"\u2717"]}),G&&jsxRuntime.jsx(et,{config:t,appSlug:o,environment:G,seededUsers:Ne,authToken:m.token,tk:n,compact:true,onExpand:()=>R("expanded"),onAuthExpired:m.logout})]}),!Y&&(K||j)&&a?.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:a.title}),(a.description||a.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:a.description||a.intro_notes})]})]}),$==="expanded"&&jsxRuntime.jsxs("div",{style:g.card(300,Z),children:[jsxRuntime.jsxs("div",{style:g.handle,onPointerDown:ae,onPointerMove:le,onPointerUp:de,onClick:Ve,children:[jsxRuntime.jsx(b,{d:p.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:g.title,children:a?.title}),jsxRuntime.jsx("div",{style:g.sub,children:a?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",a.branch_name]})})]}),jsxRuntime.jsx(b,{d:p.chevronUp,className:""}),jsxRuntime.jsx(Ke,{icon:p.minus,onClick:()=>{D(false),J(true),R("mini");}})]}),jsxRuntime.jsxs("div",{style:g.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[z.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[z.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[z.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[z.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:z.total})]}),a?.description&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:a.description}),je(),Ye(),jsxRuntime.jsx("div",{style:g.progress,children:jsxRuntime.jsx("div",{style:g.progressBar(Ue)})})]}),$==="max"&&jsxRuntime.jsxs("div",{style:{...g.card(ce.w,Z),height:ce.h,position:"relative"},children:[jsxRuntime.jsxs("div",{style:g.handle,onPointerDown:ae,onPointerMove:le,onPointerUp:de,onClick:()=>{ye.current||R("expanded");},children:[jsxRuntime.jsx(b,{d:p.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:g.title,children:a?.title}),jsxRuntime.jsx("div",{style:g.sub,children:a?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",a.branch_name]})})]}),jsxRuntime.jsx(b,{d:p.chevronDown,className:""}),jsxRuntime.jsx(Ke,{icon:p.minus,onClick:()=>{D(false),J(true),R("mini");}})]}),jsxRuntime.jsxs("div",{style:g.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[z.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[z.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[z.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[z.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:z.total})]}),(a?.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(b,{d:p.search,size:11,className:""}),jsxRuntime.jsx("input",{value:X,onChange:e=>$e(e.target.value),placeholder:"Filter test cases...",style:{flex:1,fontSize:"10px",background:"transparent",border:"none",outline:"none",color:n.text,fontFamily:"monospace"}}),X&&jsxRuntime.jsx("button",{onClick:()=>$e(""),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(b,{d:p.alert,className:""}),jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsxRuntime.jsx("button",{onClick:ut,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),Z&&jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsxRuntime.jsx(b,{d:p.checkAll,className:""}),jsxRuntime.jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsxRuntime.jsx("button",{onClick:ft,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),a?.intro_notes&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:a.intro_notes}),q!=="error"&&jsxRuntime.jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(a?.test_cases||[]).length===0?jsxRuntime.jsx("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:"No test cases"}):xe.length===0?jsxRuntime.jsxs("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:['No matches for "',X,'"']}):De?De.map(e=>{let l=rt.has(e.key);return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>it(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(b,{d:l?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})]}),!l&&e.cases.map(y=>He(y))]},e.key)}):xe.map(e=>He(e))}),mt&&!Z&&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:gt,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(),Ye(),jsxRuntime.jsx("div",{style:g.progress,children:jsxRuntime.jsx("div",{style:g.progressBar(Ue)})}),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:dt,onPointerMove:ct,onPointerUp:pt,onPointerEnter:e=>e.currentTarget.style.opacity="0.7",onPointerLeave:e=>{pe.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=Et;exports.useDraggable=_e;exports.useRealtimeRefresh=Me;exports.useTestRun=Ce;exports.useWidgetAuth=ze;
1
+ 'use strict';var react=require('react'),reactDom=require('react-dom'),jsxRuntime=require('react/jsx-runtime');var oe=8;function Re(e,r,s,f,p,a){let k=Math.max(oe,p-s-oe),y=Math.max(oe,a-f-oe);return {x:Math.min(Math.max(e,oe),k),y:Math.min(Math.max(r,oe),y)}}function Pe(e,r){let[s,f]=react.useState({x:e,y:r}),p=react.useRef(false),a=react.useRef({x:0,y:0}),k=react.useRef(false),y=react.useCallback(u=>{p.current=true,k.current=false,a.current={x:u.clientX-s.x,y:u.clientY-s.y},u.target.setPointerCapture(u.pointerId);},[s]),_=react.useCallback(u=>{p.current&&(k.current=true,f({x:u.clientX-a.current.x,y:u.clientY-a.current.y}));},[]),l=react.useCallback(()=>{p.current=false;},[]);return {pos:s,setPos:f,onPointerDown:y,onPointerMove:_,onPointerUp:l,didDrag:k}}function ze(e,r,s){let f=react.useRef(s);f.current=s,react.useEffect(()=>{if(!r)return;if(e.supabaseUrl){let a=false,k=null,y=()=>{a||k||(k=setInterval(()=>f.current(),15e3));},_=null;try{let T=new URL(e.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(T.hostname);if(T.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");T.protocol=T.protocol==="https:"?"wss:":"ws:",_=T.toString().replace(/\/$/,"");}catch{y();}let l=null,u=null,C=null,W=0,R=()=>{if(!(a||!_)){try{l=new WebSocket(`${_}/realtime/v1/websocket?apikey=${e.anonKey}&vsn=1.0.0`);}catch{y();return}l.onopen=()=>{if(a||!l)return;let T={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)};l.send(JSON.stringify(T));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)};l.send(JSON.stringify(n)),u=setInterval(()=>{l?.readyState===WebSocket.OPEN&&l.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++W)}));},3e4);},l.onmessage=T=>{try{JSON.parse(T.data).event==="postgres_changes"&&f.current();}catch{}},l.onclose=()=>{F(),a||(C=setTimeout(R,3e3));},l.onerror=()=>{l?.close();};}},F=()=>{u&&(clearInterval(u),u=null);};return R(),()=>{a=true,F(),C&&clearTimeout(C),k&&clearInterval(k),l&&(l.onclose=null,l.onerror=null,l.close());}}let p=setInterval(()=>f.current(),15e3);return ()=>clearInterval(p)},[e.supabaseUrl,e.anonKey,r]);}function ve(e,r){let s={apikey:e.anonKey};return r?s.Authorization=`Bearer ${r}`:e.apiKey?s.Authorization=`Bearer ${e.apiKey}`:s.Authorization=`Bearer ${e.anonKey}`,s}async function Tt(e){if(e)return e;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 $e(e){let[r,s]=react.useState(null),[f,p]=react.useState("loading"),a=react.useCallback(async()=>{try{let l=await Tt(e.testRunToken);if(!l){p("no-match"),s(null);return}if(!e.ticketId){p("no-match"),s(null);return}let u=new URLSearchParams;u.set("token",l),u.set("ticket_id",e.ticketId),u.set("app_slug",e.appSlug),e.environment&&u.set("environment",e.environment),e.testRunId&&u.set("test_run_id",e.testRunId),e.targetUrl&&u.set("target_url",e.targetUrl),e.version&&u.set("version",e.version),e.commitSha&&u.set("commit_sha",e.commitSha),e.prNumber&&u.set("pr_number",String(e.prNumber)),e.branchName&&u.set("branch_name",e.branchName);let C=await fetch(`${e.config.serverUrl}/widget/test-run?${u.toString()}`,{headers:ve(e.config,e.authToken)});if(C.status===404){p("no-match"),s(null);return}if(C.status===401||C.status===403){e.authToken&&e.onAuthExpired&&e.onAuthExpired(),p("error");return}if(!C.ok){p("error");return}let W=await C.json();s(W),p(W.status==="completed"?"completed":"ready");}catch{p("error");}},[e.config.serverUrl,e.config.anonKey,e.config.apiKey,e.authToken,e.appSlug,e.environment,e.ticketId,e.testRunId,e.testRunToken,e.targetUrl,e.version,e.commitSha,e.branchName,e.prNumber,e.onAuthExpired]);return react.useEffect(()=>{a();},[a]),ze(e.config,r?.id,a),{run:r,widgetState:f,fetchRun:a,setVerdict:async(l,u,C,W="human")=>(s(F=>{if(!F)return null;let T=F.test_cases.map(m=>m.id===l?{...m,verdict:u,fail_reason:u==="fail"&&C||null,verdict_by_display_name:W,verdict_at:new Date().toISOString()}:m),n={total:T.length,pending:0,pass:0,fail:0,skip:0};return T.forEach(m=>{m.verdict in n&&n[m.verdict]++;}),{...F,test_cases:T,summary:n}}),(await fetch(`${e.config.serverUrl}/widget/test-cases/${l}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...ve(e.config,e.authToken)},body:JSON.stringify({verdict:u,fail_reason:C,display_name:W})})).ok),markComplete:async()=>r?(s(u=>u?{...u,status:"completed"}:null),p("completed"),(await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...ve(e.config,e.authToken)}})).ok):false,resetRun:async()=>{if(!r)return false;let l=await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...ve(e.config,e.authToken)}});return l.ok&&a(),l.ok},setRun:s}}var Be="botbuddy-widget-auth-token",Le="botbuddy-widget-auth-name";function Ee(e){let[r,s]=react.useState(()=>{try{return localStorage.getItem(Be)}catch(y){return console.warn("Unable to read BotBuddy widget auth token",y),null}}),[f,p]=react.useState(()=>{try{return localStorage.getItem(Le)}catch(y){return console.warn("Unable to read BotBuddy widget display name",y),null}});react.useEffect(()=>{let y=new URL(e).origin,_=l=>{if(l.origin===y&&l.data?.type==="botbuddy-widget-auth"&&l.data.token){let{token:u,displayName:C}=l.data;s(u),p(C||"human");try{localStorage.setItem(Be,u),C&&localStorage.setItem(Le,C);}catch(W){console.warn("Unable to persist BotBuddy widget auth token",W);}}};return window.addEventListener("message",_),()=>window.removeEventListener("message",_)},[e]);let a=react.useCallback(()=>{let y=new URL("/widget-auth",e);y.searchParams.set("origin",window.location.origin);let _=420,l=520,u=window.screenX+(window.innerWidth-_)/2,C=window.screenY+(window.innerHeight-l)/2;window.open(y.toString(),"botbuddy-auth",`width=${_},height=${l},left=${u},top=${C},popup=yes`);},[e]),k=react.useCallback(()=>{s(null),p(null);try{localStorage.removeItem(Be),localStorage.removeItem(Le);}catch(y){console.warn("Unable to clear BotBuddy widget auth token",y);}},[]);return {token:r,displayName:f,isAuthenticated:!!r,openLogin:a,logout:k}}var we=null;function Pt(){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 We(){return we||(we=(async()=>{if(typeof fetch>"u")return null;try{let e=await fetch(Pt(),{cache:"no-store"});if(!e.ok)return null;let r=await e.json();if(!r||typeof r!="object"||Array.isArray(r))return null;let s={};for(let[f,p]of Object.entries(r))typeof p=="string"&&p.length>0&&(s[f]=p);return s}catch{return null}})(),we)}async function nt(e){return (await We())?.[e]??null}function zt(e){let r=e.replace(/=+$/,"").replace(/\s+/g,"").toUpperCase(),s="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",f=[],p=0,a=0;for(let k of r){let y=s.indexOf(k);if(y<0)throw new Error("Invalid Base32 character in TOTP secret");a=a<<5|y,p+=5,p>=8&&(p-=8,f.push(a>>>p&255));}return Uint8Array.from(f)}async function rt(e,r=Date.now()){if(typeof crypto>"u"||!crypto.subtle)throw new Error("Web Crypto unavailable");let s=zt(e),f=Math.floor(r/1e3/30),p=new Uint8Array(8),a=Math.floor(f/4294967296),k=f>>>0;p[0]=a>>>24&255,p[1]=a>>>16&255,p[2]=a>>>8&255,p[3]=a&255,p[4]=k>>>24&255,p[5]=k>>>16&255,p[6]=k>>>8&255,p[7]=k&255;let y=await crypto.subtle.importKey("raw",s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength),{name:"HMAC",hash:"SHA-1"},false,["sign"]),_=await crypto.subtle.sign("HMAC",y,p.buffer),l=new Uint8Array(_),u=l[l.length-1]&15;return (((l[u]&127)<<24|(l[u+1]&255)<<16|(l[u+2]&255)<<8|l[u+3]&255)%1e6).toString().padStart(6,"0")}function Bt(e){let r=new Date(e),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 p=r.getDate(),a=r.toLocaleString("en",{month:"short"}),k=r.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${a} ${p}, ${k}`}var v=({d:e,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:e})}),g={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 Lt(){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 s=document.documentElement,f=()=>s.classList.contains("dark")?"dark":s.classList.contains("light")?"light":null,p=f();p&&r(p);let a=window.matchMedia("(prefers-color-scheme: dark)"),k=_=>{let l=f();r(l||(_.matches?"dark":"light"));};a.addEventListener("change",k);let y=new MutationObserver(()=>{let _=f();r(_||(a.matches?"dark":"light"));});return y.observe(s,{attributes:true,attributeFilter:["class"]}),()=>{a.removeEventListener("change",k),y.disconnect();}},[]),e}function Et(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 Wt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},At={pending:g.circle,pass:g.check,fail:g.x,skip:g.skip},ot={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)"}},It=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,s)=>({width:`${r}px`,borderRadius:"8px",background:e.bg,border:s?`1px solid ${e.greenBorder}`:`1px solid ${e.border}`,boxShadow:s?`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 s=ot[r]||ot.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: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,s)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:r?`${s}33`:"transparent",color:r?s: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 Dt(e){return e.split("/")[0].trim()}async function Ft(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 s=document.execCommand("copy");return document.body.removeChild(r),s}catch{return false}}function it({config:e,appSlug:r,environment:s,seededUsers:f,authToken:p,tk:a,compact:k=false,onExpand:y,onAuthExpired:_}){let[l,u]=react.useState(false),[C,W]=react.useState(null),[R,F]=react.useState(null),[T,n]=react.useState(null),[m,j]=react.useState(null);react.useEffect(()=>{s==="local"&&We();},[s]);let K=react.useCallback(h=>{W(h),n(null),j(null);let M=S=>{n(S),j(h),window.setTimeout(()=>{j(b=>b===h?null:b),n(b=>b===S?null:b);},3e3);},w=new URLSearchParams({app_slug:r,seed_user_slug:h,environment:s}),$={apikey:e.anonKey};$.Authorization=`Bearer ${p||e.anonKey}`;let E=(async()=>{if(s==="local"){let S=await nt(h);if(S)try{return {ok:!0,code:await rt(S)}}catch{}}try{let S=await fetch(`${e.serverUrl}/widget/totp-code?${w}`,{headers:$});if(!S.ok){let U=await S.json().catch(()=>({error:`HTTP ${S.status}`}));return {ok:!1,status:S.status,error:U.error||`HTTP ${S.status}`}}let b=await S.json();return {ok:!0,code:String(b.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),z=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let S=E.then(b=>{if(!b.ok)throw new Error(b.error);return new Blob([b.code],{type:"text/plain"})});z=navigator.clipboard.write([new ClipboardItem({"text/plain":S})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let S=await E;if(!S.ok){S.status===401||S.status===403?(_?.(),M("Signed out \u2014 please sign in again")):M(S.status===404?"No 2FA seed registered":S.error),W(null);return}let b=z?await z:false,U=b?true:await Ft(S.code),q=b||U;F({slug:h,code:S.code,copied:q}),window.setTimeout(()=>F(te=>te?.slug===h?null:te),q?2500:6e3),u(false),W(null);})();},[e.serverUrl,e.anonKey,p,r,s]);if(f.length===0)return null;if(k){let h=f.length>1,M=b=>{if(b.stopPropagation(),h&&y){y();return}K(f[0]);},w=!!m,$=!!R,E=$&&R.copied,z=$&&!R.copied,S=w?a.red:E?a.green:z?a.amber:a.purple;return jsxRuntime.jsxs("span",{onPointerDown:b=>b.stopPropagation(),onPointerUp:b=>b.stopPropagation(),onPointerMove:b=>b.stopPropagation(),onClick:M,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:S,fontWeight:600,cursor:"pointer",letterSpacing:z?"0.08em":void 0},title:w?T||"Failed":z?`Clipboard blocked \u2014 code: ${R.code}`:h?`${f.length} 2FA personas`:`Copy 2FA code for ${f[0]}`,children:[jsxRuntime.jsx(v,{d:w?g.alert:E?g.check:z?g.copy:g.shield,size:10}),E?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Copied"}):z?jsxRuntime.jsx(jsxRuntime.Fragment,{children:R.code}):w?jsxRuntime.jsx(jsxRuntime.Fragment,{children:"Failed"}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:["2FA",h&&` \xB7${f.length}`]})]})}if(f.length===1){let h=f[0],M=C===h,w=R?.slug===h,$=w&&R.copied,E=w&&!R.copied,z=m===h,S=z?a.red:$?a.green:E?a.amber:a.purple;return jsxRuntime.jsxs("button",{onClick:b=>{b.stopPropagation(),K(h);},disabled:M,style:{...st(S),cursor:M?"wait":"pointer",opacity:M?.6:1},title:z?T||"Failed":E?`Clipboard blocked \u2014 code: ${R.code}`:`Copy 2FA code for ${h}`,children:[jsxRuntime.jsx(v,{d:z?g.alert:$?g.check:E?g.copy:g.shield,size:12}),$?"Copied":E?R.code:z?"Failed":M?"\u2026":`2FA \xB7 ${h}`]})}let Y=!!m&&!l,N=!!R&&R.copied,J=!!R&&!R.copied,G=Y?a.red:N?a.green:J?a.amber:a.purple,ee=react.useRef(null),le=react.useRef(null);react.useLayoutEffect(()=>{if(!l)return;let h=ee.current,M=le.current;if(!h||!M||typeof window>"u")return;let w=()=>{let $=h.getBoundingClientRect(),E=M.getBoundingClientRect(),z=window.innerWidth,S=window.innerHeight,b=$.left,U=$.top-E.height-6;U<8&&(U=$.bottom+6);let q=Math.max(8,z-E.width-8),te=Math.max(8,S-E.height-8);b=Math.min(Math.max(b,8),q),U=Math.min(Math.max(U,8),te),M.style.left=`${Math.round(b)}px`,M.style.top=`${Math.round(U)}px`;};return w(),window.addEventListener("scroll",w,true),window.addEventListener("resize",w),()=>{window.removeEventListener("scroll",w,true),window.removeEventListener("resize",w);}},[l,f.length,T]),react.useEffect(()=>{if(!l)return;let h=M=>{let w=M.target;le.current?.contains(w)||ee.current?.contains(w)||u(false);};return document.addEventListener("mousedown",h),()=>document.removeEventListener("mousedown",h)},[l]);let P=l&&typeof document<"u"?reactDom.createPortal(jsxRuntime.jsxs("div",{ref:le,onPointerDown:h=>h.stopPropagation(),onMouseDown:h=>h.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:[f.map(h=>{let M=C===h;return jsxRuntime.jsxs("button",{onClick:w=>{w.stopPropagation(),K(h);},disabled:M,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:M?"wait":"pointer",fontSize:"10px",color:a.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:w=>w.currentTarget.style.background=a.btnHover,onMouseLeave:w=>w.currentTarget.style.background="transparent",children:[jsxRuntime.jsx(v,{d:g.shield,size:10}),jsxRuntime.jsx("span",{style:{flex:1,overflowWrap:"anywhere",lineHeight:1.3},children:h}),M&&jsxRuntime.jsx("span",{style:{color:a.textMuted,fontSize:9},children:"\u2026"})]},h)}),T&&jsxRuntime.jsx("div",{style:{padding:"4px 8px",fontSize:9,color:a.red},children:T})]}),document.body):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("button",{ref:ee,onClick:h=>{h.stopPropagation(),u(M=>!M),n(null),j(null);},style:{...st(G),cursor:"pointer"},title:Y?T||"Failed":J?`Clipboard blocked \u2014 code: ${R.code}`:"Choose a persona to copy a 2FA code for",children:[jsxRuntime.jsx(v,{d:Y?g.alert:N?g.check:J?g.copy:g.shield,size:12}),N?"Copied":J?R.code:Y?"Failed":`2FA \xB7 ${f.length}`,jsxRuntime.jsx(v,{d:l?g.chevronUp:g.chevronDown,size:8})]}),P]})}function st(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 at="botbuddy-widget-state";function Ut({config:e,appSlug:r,environment:s,ticketId:f,testRunId:p,testRunToken:a,targetUrl:k,version:y,commitSha:_,prNumber:l,branchName:u,onNavigate:C,displayName:W="human",defaultMode:R="mini",defaultPosition:F}){let T=Lt(),n=react.useMemo(()=>Et(T),[T]),m=react.useMemo(()=>It(n),[n]),[j,K]=react.useState(false),[Y,N]=react.useState(false),[J,G]=react.useState(false),ee=react.useRef(false),le=e.dashboardUrl||"https://app.bot-buddy.ai",P=Ee(le),M=(()=>{try{let t=typeof window<"u"?localStorage.getItem(at):null;if(t)return JSON.parse(t)}catch{}return null})(),[w,$]=react.useState(M?.mode||R),[E,z]=react.useState(""),[S,b]=react.useState(null),[U,q]=react.useState(null),[te,dt]=react.useState(new Set),[ne,Ae]=react.useState(""),ct=react.useCallback(t=>{dt(d=>{let x=new Set(d);return x.has(t)?x.delete(t):x.add(t),x});},[]),pt=M?.x??F?.x??16,ut=M?.y??F?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:B,setPos:Se,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,didDrag:ke}=Pe(pt,ut),ue=react.useRef(null);react.useEffect(()=>{try{localStorage.setItem(at,JSON.stringify({mode:w,x:B.x,y:B.y}));}catch{}},[w,B.x,B.y]),react.useLayoutEffect(()=>{if(typeof window>"u")return;let t=ue.current;if(!t)return;let d=t.getBoundingClientRect(),x=Re(B.x,B.y,d.width,d.height,window.innerWidth,window.innerHeight);(x.x!==B.x||x.y!==B.y)&&Se(x);}),react.useEffect(()=>{if(typeof window>"u")return;let t=()=>{let d=ue.current;if(!d)return;let x=d.getBoundingClientRect(),D=Re(B.x,B.y,x.width,x.height,window.innerWidth,window.innerHeight);(D.x!==B.x||D.y!==B.y)&&Se(D);};return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[B.x,B.y,Se]);let Ie=react.useRef(P.isAuthenticated);react.useEffect(()=>{!Ie.current&&P.isAuthenticated&&$("max"),Ie.current=P.isAuthenticated;},[P.isAuthenticated]);let De="botbuddy-widget-max-size",gt=()=>{try{let t=localStorage.getItem(De);if(t)return JSON.parse(t)}catch{}return {w:340,h:500}},[ge,Fe]=react.useState(gt),fe=react.useRef(false),me=react.useRef({x:0,y:0,w:0,h:0}),ft=react.useCallback(t=>{t.stopPropagation(),fe.current=true,me.current={x:t.clientX,y:t.clientY,w:ge.w,h:ge.h},t.target.setPointerCapture(t.pointerId);},[ge]),mt=react.useCallback(t=>{if(!fe.current)return;let d=Math.max(280,Math.min(600,me.current.w+(t.clientX-me.current.x))),x=Math.max(300,Math.min(window.innerHeight*.9,me.current.h+(t.clientY-me.current.y)));Fe({w:d,h:x});},[]),ht=react.useCallback(()=>{fe.current&&(fe.current=false,Fe(t=>(localStorage.setItem(De,JSON.stringify(t)),t)));},[]),be=k??(typeof window<"u"?window.location.href:void 0),Ue=P.displayName||W,[O,Ne]=react.useState(null);react.useEffect(()=>{if(P.isAuthenticated)return;let t=new URLSearchParams;a&&t.set("token",a),f&&t.set("ticket_id",f),t.set("app_slug",r),s&&t.set("environment",s),p&&t.set("test_run_id",p),be&&t.set("target_url",be),y&&t.set("version",y),_&&t.set("commit_sha",_),l&&t.set("pr_number",String(l)),u&&t.set("branch_name",u),fetch(`${e.serverUrl}/widget/preview?${t}`,{headers:{apikey:e.anonKey}}).then(d=>d.json()).then(d=>Ne(d)).catch(()=>Ne(null));},[P.isAuthenticated,e.serverUrl,e.anonKey,r,s,f,p,a,be,y,_,l,u]);let{run:c,widgetState:X,fetchRun:bt,setVerdict:He,markComplete:xt,resetRun:yt}=$e({config:e,appSlug:r,environment:s,ticketId:f,testRunId:p,testRunToken:a,targetUrl:be,version:y,commitSha:_,prNumber:l?String(l):void 0,branchName:u,authToken:P.token,onAuthExpired:P.logout}),xe=react.useCallback(async(t,d,x)=>{q(t);try{await He(t,d,x,Ue);}finally{q(null),b(null),z("");}},[He,Ue]),L=c?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},vt=L.total>0&&L.pending===0,re=X==="completed",ye=react.useMemo(()=>{let t=c?.test_cases||[];if(!ne.trim())return t;let d=ne.toLowerCase();return t.filter(x=>x.title.toLowerCase().includes(d)||x.description&&x.description.toLowerCase().includes(d)||x.url_path&&x.url_path.toLowerCase().includes(d)||x.seed_user&&x.seed_user.toLowerCase().includes(d))},[c?.test_cases,ne]),Oe=react.useMemo(()=>{let t=ye,d=c?.test_cases||[];if(new Set(d.map(I=>I.source_pr_number)).size<=1)return null;let D=[],he=new Map;t.forEach(I=>{let H=I.source_pr_number;he.has(H)||he.set(H,[]),he.get(H).push(I);});let wt=[...he.keys()].sort((I,H)=>I===null?1:H===null?-1:H-I);for(let I of wt){let H=he.get(I),Me={total:H.length,pass:0,fail:0,skip:0,pending:0};H.forEach(Ze=>{Ze.verdict in Me&&Me[Ze.verdict]++;}),D.push({key:I!=null?`pr-${I}`:"general",label:I!=null?`PR #${I}`:"General",cases:H,summary:Me});}return D.filter(I=>I.cases.length>0)},[ye,c?.test_cases]),Ke=L.total>0?(L.pass+L.fail)/L.total*100:0,Z=s??c?.environment??null,Ve=react.useMemo(()=>{if(!Z||Z==="production")return [];let t=c?.test_cases||[],d=new Set;for(let x of t)x.seed_user&&d.add(Dt(x.seed_user));return [...d]},[c?.test_cases,Z]),_e=react.useMemo(()=>{let t=c?.auto_tooltip_seconds??O?.auto_tooltip_seconds;return t!=null&&t>0?t*1e3:0},[c,O]),je=X==="ready"||X==="completed"||O?.enabled&&O.run;react.useEffect(()=>{if(!je||ee.current||_e<=0)return;ee.current=true,N(true);let t=window.setTimeout(()=>N(false),_e);return ()=>window.clearTimeout(t)},[je,_e]);let Ye=t=>jsxRuntime.jsxs("div",{style:m.caseRow,children:[jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"},children:[jsxRuntime.jsx("div",{style:{marginTop:"2px",flexShrink:0,color:Wt[t.verdict]},children:U===t.id?jsxRuntime.jsx(v,{d:g.loader,className:""}):jsxRuntime.jsx(v,{d:At[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(v,{d:g.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:d=>{d.stopPropagation(),C&&(d.preventDefault(),C(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(v,{d:g.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(d=>jsxRuntime.jsx("button",{onClick:()=>{if(t.verdict===d){xe(t.id,"pending"),b(null);return}if(d==="fail"){b(t.id),z("");return}b(null),xe(t.id,d);},disabled:U!==null,style:m.verdictBtn(t.verdict===d,d==="pass"?n.green:d==="fail"?n.red:n.amber),children:d.toUpperCase()},d)),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(v,{d:g.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:Bt(t.verdict_at)})]})]}),S===t.id&&jsxRuntime.jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsxRuntime.jsx("input",{autoFocus:true,value:E,onChange:d=>z(d.target.value),onKeyDown:d=>{d.key==="Enter"&&xe(t.id,"fail",E.trim()||void 0),d.key==="Escape"&&(b(null),z(""));},placeholder:"Reason (optional)...",style:m.input}),jsxRuntime.jsx("button",{onClick:()=>{xe(t.id,"fail",E.trim()||void 0);},style:m.verdictBtn(true,n.red),children:"\u2713"})]})]},t.id);if((X==="no-match"||X==="loading")&&!(!P.isAuthenticated&&O?.enabled&&O.run))return null;if(!P.isAuthenticated&&O?.enabled&&O.run){let t=O.run,d=t.summary,x=t.status==="completed";return jsxRuntime.jsx("div",{ref:ue,style:{...m.root,left:B.x,top:B.y},children:jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),G(false),N(false);},children:[jsxRuntime.jsxs("div",{style:{...m.pill(x),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe();},children:[jsxRuntime.jsx(v,{d:g.grip,size:10,className:""}),t.ticket_id&&t.ticket_url?jsxRuntime.jsx("a",{href:t.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:t.ticket_id}):null,t.pr_url?jsxRuntime.jsxs("a",{href:t.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#",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:D=>D.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsxRuntime.jsx(v,{d:g.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(v,{d:g.bot,size:10}),t.created_by_agent_name]}):null,jsxRuntime.jsxs("span",{style:x?{color:n.green}:void 0,children:[d.pass,"/",d.total]}),d.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[d.fail,"\u2717"]}),jsxRuntime.jsx("span",{onClick:D=>{D.stopPropagation(),P.openLogin();},style:{color:n.textMuted,fontWeight:400,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},children:"Sign in"})]}),!J&&(j||Y)&&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(!P.isAuthenticated)return jsxRuntime.jsxs("div",{ref:ue,style:{...m.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:{...m.handle,borderBottom:"none"},children:jsxRuntime.jsxs("div",{style:m.sub,children:[jsxRuntime.jsx(v,{d:g.grip,size:10,className:""}),jsxRuntime.jsx(v,{d:g.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:t=>{t.stopPropagation(),P.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||(N(false),$(t=>{let d=t==="mini"?"max":"mini";return G(d==="mini"),d}));},Ge=({icon:t,onClick:d})=>jsxRuntime.jsx("button",{style:m.btn,onClick:x=>{x.stopPropagation(),d(x);},children:jsxRuntime.jsx(v,{d:t,className:""})}),qe=()=>jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",gap:"8px",flexWrap:"wrap",alignItems:"center",borderTop:`1px solid ${n.borderSubtle}`,flexShrink:0},children:[c?.pr_url&&jsxRuntime.jsxs("a",{href:c.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...m.link(n.blue),textDecoration:"none"},children:[jsxRuntime.jsx(v,{d:g.pr,size:12}),c.pr_number?`PR#${c.pr_number}`:c.pr_id||"PR",jsxRuntime.jsx(v,{d:g.externalLink,size:8})]}),c?.ticket_url&&jsxRuntime.jsxs("a",{href:c.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...m.link(n.amber),textDecoration:"none"},children:[jsxRuntime.jsx(v,{d:g.ticket,size:12}),c.ticket_id||"Ticket",jsxRuntime.jsx(v,{d:g.externalLink,size:8})]}),c?.created_by_agent_name&&(c.codex_thread_id?jsxRuntime.jsxs("a",{href:`codex://threads/${c.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...m.link(n.purple),textDecoration:"none"},children:[jsxRuntime.jsx(v,{d:g.bot,size:12}),c.created_by_agent_name,jsxRuntime.jsx(v,{d:g.externalLink,size:8})]}):jsxRuntime.jsxs("span",{style:{...m.link(n.purple)},children:[jsxRuntime.jsx(v,{d:g.bot,size:12}),c.created_by_agent_name]})),Z&&jsxRuntime.jsx(it,{config:e,appSlug:r,environment:Z,seededUsers:Ve,authToken:P.token,tk:n,onAuthExpired:P.logout}),jsxRuntime.jsx("span",{style:{...m.badge(c?.environment||"custom"),marginLeft:"auto"},children:c?.environment})]}),Xe=()=>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"})]}),P.isAuthenticated&&jsxRuntime.jsx("button",{onClick:t=>{t.stopPropagation(),P.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:{...m.root,left:B.x,top:B.y},children:[w==="mini"&&jsxRuntime.jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),G(false),N(false);},children:[jsxRuntime.jsxs("div",{style:{...m.pill(re),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe(),ke.current||Je();},children:[jsxRuntime.jsx(v,{d:g.grip,size:9,className:""}),c?.ticket_id&&jsxRuntime.jsx("span",{style:{color:n.amber,fontWeight:600},children:c.ticket_id}),c?.pr_number&&jsxRuntime.jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",c.pr_number]}),jsxRuntime.jsxs("span",{style:re?{color:n.green}:void 0,children:[L.pass,"/",L.total]}),L.fail>0&&jsxRuntime.jsxs("span",{style:{color:n.red},children:[L.fail,"\u2717"]}),Z&&jsxRuntime.jsx(it,{config:e,appSlug:r,environment:Z,seededUsers:Ve,authToken:P.token,tk:n,compact:true,onExpand:()=>$("expanded"),onAuthExpired:P.logout})]}),!J&&(j||Y)&&c?.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:c.title}),(c.description||c.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:c.description||c.intro_notes})]})]}),w==="expanded"&&jsxRuntime.jsxs("div",{style:m.card(300,re),children:[jsxRuntime.jsxs("div",{style:m.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:Je,children:[jsxRuntime.jsx(v,{d:g.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:m.title,children:c?.title}),jsxRuntime.jsx("div",{style:m.sub,children:c?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",c.branch_name]})})]}),jsxRuntime.jsx(v,{d:g.chevronUp,className:""}),jsxRuntime.jsx(Ge,{icon:g.minus,onClick:()=>{N(false),G(true),$("mini");}})]}),jsxRuntime.jsxs("div",{style:m.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[L.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[L.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[L.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[L.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:L.total})]}),c?.description&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:c.description}),qe(),Xe(),jsxRuntime.jsx("div",{style:m.progress,children:jsxRuntime.jsx("div",{style:m.progressBar(Ke)})})]}),w==="max"&&jsxRuntime.jsxs("div",{style:{...m.card(ge.w,re),height:ge.h,position:"relative"},children:[jsxRuntime.jsxs("div",{style:m.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:()=>{ke.current||$("expanded");},children:[jsxRuntime.jsx(v,{d:g.grip,className:""}),jsxRuntime.jsxs("div",{style:{flex:1,minWidth:0},children:[jsxRuntime.jsx("div",{style:m.title,children:c?.title}),jsxRuntime.jsx("div",{style:m.sub,children:c?.branch_name&&jsxRuntime.jsxs("span",{children:["\u2387 ",c.branch_name]})})]}),jsxRuntime.jsx(v,{d:g.chevronDown,className:""}),jsxRuntime.jsx(Ge,{icon:g.minus,onClick:()=>{N(false),G(true),$("mini");}})]}),jsxRuntime.jsxs("div",{style:m.stats,children:[jsxRuntime.jsxs("span",{style:{color:n.green},children:[L.pass,"\u2713"]}),jsxRuntime.jsxs("span",{style:{color:n.red},children:[L.fail,"\u2717"]}),jsxRuntime.jsxs("span",{style:{color:n.amber},children:[L.skip,"\u23ED"]}),jsxRuntime.jsxs("span",{style:{color:n.gripColor},children:[L.pending,"\u25CC"]}),jsxRuntime.jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:L.total})]}),c?.intro_notes&&jsxRuntime.jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:c.intro_notes}),(c?.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(v,{d:g.search,size:11,className:""}),jsxRuntime.jsx("input",{value:ne,onChange:t=>Ae(t.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:()=>Ae(""),style:{background:"none",border:"none",cursor:"pointer",color:n.textFaint,fontSize:"10px",padding:0},children:"\u2715"})]}),X==="error"&&jsxRuntime.jsxs("div",{style:{padding:"12px",textAlign:"center"},children:[jsxRuntime.jsx(v,{d:g.alert,className:""}),jsxRuntime.jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsxRuntime.jsx("button",{onClick:bt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),re&&jsxRuntime.jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsxRuntime.jsx(v,{d:g.checkAll,className:""}),jsxRuntime.jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsxRuntime.jsx("button",{onClick:yt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),X!=="error"&&jsxRuntime.jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(c?.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,'"']}):Oe?Oe.map(t=>{let d=te.has(t.key);return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>ct(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(v,{d:d?g.chevronDown:g.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})]}),!d&&t.cases.map(x=>Ye(x))]},t.key)}):ye.map(t=>Ye(t))}),vt&&!re&&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:xt,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"})]}),qe(),Xe(),jsxRuntime.jsx("div",{style:m.progress,children:jsxRuntime.jsx("div",{style:m.progressBar(Ke)})}),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:ft,onPointerMove:mt,onPointerUp:ht,onPointerEnter:t=>t.currentTarget.style.opacity="0.7",onPointerLeave:t=>{fe.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=Ut;exports.useDraggable=Pe;exports.useRealtimeRefresh=ze;exports.useTestRun=$e;exports.useWidgetAuth=Ee;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import {useState,useRef,useCallback,useEffect,useMemo,useLayoutEffect}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var Q=8;function qe(t,o,s,f,h,d){let M=Math.max(Q,h-s-Q),v=Math.max(Q,d-f-Q);return {x:Math.min(Math.max(t,Q),M),y:Math.min(Math.max(o,Q),v)}}function _e(t,o){let[s,f]=useState({x:t,y:o}),h=useRef(false),d=useRef({x:0,y:0}),M=useRef(false),v=useCallback(u=>{h.current=true,M.current=false,d.current={x:u.clientX-s.x,y:u.clientY-s.y},u.target.setPointerCapture(u.pointerId);},[s]),S=useCallback(u=>{h.current&&(M.current=true,f({x:u.clientX-d.current.x,y:u.clientY-d.current.y}));},[]),c=useCallback(()=>{h.current=false;},[]);return {pos:s,setPos:f,onPointerDown:v,onPointerMove:S,onPointerUp:c,didDrag:M}}function Me(t,o,s){let f=useRef(s);f.current=s,useEffect(()=>{if(!o)return;if(t.supabaseUrl){let d=false,M=null,v=()=>{d||M||(M=setInterval(()=>f.current(),15e3));},S=null;try{let T=new URL(t.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(T.hostname);if(T.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");T.protocol=T.protocol==="https:"?"wss:":"ws:",S=T.toString().replace(/\/$/,"");}catch{v();}let c=null,u=null,_=null,B=0,C=()=>{if(!(d||!S)){try{c=new WebSocket(`${S}/realtime/v1/websocket?apikey=${t.anonKey}&vsn=1.0.0`);}catch{v();return}c.onopen=()=>{if(d||!c)return;let T={topic:`realtime:public:test_run_cases:test_run_id=eq.${o}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_run_cases",filter:`test_run_id=eq.${o}`}]}},ref:String(++B)};c.send(JSON.stringify(T));let n={topic:`realtime:public:test_runs:id=eq.${o}`,event:"phx_join",payload:{config:{postgres_changes:[{event:"*",schema:"public",table:"test_runs",filter:`id=eq.${o}`}]}},ref:String(++B)};c.send(JSON.stringify(n)),u=setInterval(()=>{c?.readyState===WebSocket.OPEN&&c.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++B)}));},3e4);},c.onmessage=T=>{try{JSON.parse(T.data).event==="postgres_changes"&&f.current();}catch{}},c.onclose=()=>{F(),d||(_=setTimeout(C,3e3));},c.onerror=()=>{c?.close();};}},F=()=>{u&&(clearInterval(u),u=null);};return C(),()=>{d=true,F(),_&&clearTimeout(_),M&&clearInterval(M),c&&(c.onclose=null,c.onerror=null,c.close());}}let h=setInterval(()=>f.current(),15e3);return ()=>clearInterval(h)},[t.supabaseUrl,t.anonKey,o]);}function he(t,o){let s={apikey:t.anonKey};return o?s.Authorization=`Bearer ${o}`:t.apiKey?s.Authorization=`Bearer ${t.apiKey}`:s.Authorization=`Bearer ${t.anonKey}`,s}async function kt(t){if(t)return t;try{let o=await fetch("/.botbuddy-token",{cache:"no-store"});if(o.ok){let s=(await o.text()).trim();if(s.startsWith("public_"))return s}}catch{}try{let o=import.meta?.env?.VITE_BOTBUDDY_TEST_RUN_TOKEN;if(o&&typeof o=="string"&&o.startsWith("public_"))return o}catch{}return null}function Ce(t){let[o,s]=useState(null),[f,h]=useState("loading"),d=useCallback(async()=>{try{let c=await kt(t.testRunToken);if(!c){h("no-match"),s(null);return}if(!t.ticketId){h("no-match"),s(null);return}let u=new URLSearchParams;u.set("token",c),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 _=await fetch(`${t.config.serverUrl}/widget/test-run?${u.toString()}`,{headers:he(t.config,t.authToken)});if(_.status===404){h("no-match"),s(null);return}if(_.status===401||_.status===403){t.authToken&&t.onAuthExpired&&t.onAuthExpired(),h("error");return}if(!_.ok){h("error");return}let B=await _.json();s(B),h(B.status==="completed"?"completed":"ready");}catch{h("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(()=>{d();},[d]),Me(t.config,o?.id,d),{run:o,widgetState:f,fetchRun:d,setVerdict:async(c,u,_,B="human")=>(s(F=>{if(!F)return null;let T=F.test_cases.map(g=>g.id===c?{...g,verdict:u,fail_reason:u==="fail"&&_||null,verdict_by_display_name:B,verdict_at:new Date().toISOString()}:g),n={total:T.length,pending:0,pass:0,fail:0,skip:0};return T.forEach(g=>{g.verdict in n&&n[g.verdict]++;}),{...F,test_cases:T,summary:n}}),(await fetch(`${t.config.serverUrl}/widget/test-cases/${c}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...he(t.config,t.authToken)},body:JSON.stringify({verdict:u,fail_reason:_,display_name:B})})).ok),markComplete:async()=>o?(s(u=>u?{...u,status:"completed"}:null),h("completed"),(await fetch(`${t.config.serverUrl}/widget/test-runs/${o.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...he(t.config,t.authToken)}})).ok):false,resetRun:async()=>{if(!o)return false;let c=await fetch(`${t.config.serverUrl}/widget/test-runs/${o.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...he(t.config,t.authToken)}});return c.ok&&d(),c.ok},setRun:s}}var Te="botbuddy-widget-auth-token",Re="botbuddy-widget-auth-name";function ze(t){let[o,s]=useState(()=>{try{return localStorage.getItem(Te)}catch(v){return console.warn("Unable to read BotBuddy widget auth token",v),null}}),[f,h]=useState(()=>{try{return localStorage.getItem(Re)}catch(v){return console.warn("Unable to read BotBuddy widget display name",v),null}});useEffect(()=>{let v=new URL(t).origin,S=c=>{if(c.origin===v&&c.data?.type==="botbuddy-widget-auth"&&c.data.token){let{token:u,displayName:_}=c.data;s(u),h(_||"human");try{localStorage.setItem(Te,u),_&&localStorage.setItem(Re,_);}catch(B){console.warn("Unable to persist BotBuddy widget auth token",B);}}};return window.addEventListener("message",S),()=>window.removeEventListener("message",S)},[t]);let d=useCallback(()=>{let v=new URL("/widget-auth",t);v.searchParams.set("origin",window.location.origin);let S=420,c=520,u=window.screenX+(window.innerWidth-S)/2,_=window.screenY+(window.innerHeight-c)/2;window.open(v.toString(),"botbuddy-auth",`width=${S},height=${c},left=${u},top=${_},popup=yes`);},[t]),M=useCallback(()=>{s(null),h(null);try{localStorage.removeItem(Te),localStorage.removeItem(Re);}catch(v){console.warn("Unable to clear BotBuddy widget auth token",v);}},[]);return {token:o,displayName:f,isAuthenticated:!!o,openLogin:d,logout:M}}function Mt(t){let o=new Date(t),f=Date.now()-o.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 h=o.getDate(),d=o.toLocaleString("en",{month:"short"}),M=o.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${d} ${h}, ${M}`}var b=({d:t,className:o,size:s=14})=>jsx("svg",{className:o,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 Ct(){let[t,o]=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,h=f();h&&o(h);let d=window.matchMedia("(prefers-color-scheme: dark)"),M=S=>{let c=f();o(c||(S.matches?"dark":"light"));};d.addEventListener("change",M);let v=new MutationObserver(()=>{let S=f();o(S||(d.matches?"dark":"light"));});return v.observe(s,{attributes:true,attributeFilter:["class"]}),()=>{d.removeEventListener("change",M),v.disconnect();}},[]),t}function Tt(t){let o=t==="dark";return {bg:o?"rgb(30,30,30)":"rgb(255,255,255)",bgSoft:o?"rgba(255,255,255,0.02)":"rgba(0,0,0,0.02)",text:o?"#e5e5e5":"#1a1a1a",textMuted:o?"rgba(255,255,255,0.4)":"rgba(0,0,0,0.45)",textFaint:o?"#555":"#999",border:o?"rgba(255,255,255,0.15)":"rgba(0,0,0,0.12)",borderSubtle:o?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",shadow:o?"rgba(0,0,0,0.4)":"rgba(0,0,0,0.12)",inputBg:o?"rgba(0,0,0,0.3)":"rgba(0,0,0,0.04)",inputBorder:o?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.12)",green:"#34d399",greenBg:o?"rgba(52,211,153,0.05)":"rgba(52,211,153,0.08)",greenBorder:o?"rgba(52,211,153,0.6)":"rgba(52,211,153,0.5)",greenBorderSubtle:o?"rgba(52,211,153,0.2)":"rgba(52,211,153,0.15)",red:"#f87171",amber:"#f59e0b",blue:"#60a5fa",purple:"#a78bfa",versionText:o?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",versionNum:o?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",gripColor:o?"#888":"#aaa",btnHover:o?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.06)"}}var Rt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},zt={pending:p.circle,pass:p.check,fail:p.x,skip:p.skip},Qe={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)"}},Pt=t=>({root:{position:"fixed",zIndex:9999,userSelect:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"},pill:o=>({display:"inline-flex",alignItems:"center",gap:"6px",padding:"4px 8px",borderRadius:"9999px",background:t.bg,border:o?`1px solid ${t.greenBorder}`:`1px solid ${t.border}`,boxShadow:o?`0 4px 12px ${t.shadow}, 0 0 0 1px ${t.greenBorderSubtle}`:`0 4px 12px ${t.shadow}`,cursor:"pointer",fontSize:"9px",color:t.text}),card:(o,s)=>({width:`${o}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:o=>{let s=Qe[o]||Qe.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:o=>({height:"100%",width:`${o}%`,background:"linear-gradient(to right, #34d399, #3b82f6)",transition:"width 0.5s"}),link:o=>({display:"inline-flex",alignItems:"center",gap:"4px",fontSize:"9px",padding:"2px 6px",borderRadius:"4px",background:`${o}15`,color:o,textDecoration:"none",border:"none",cursor:"pointer"}),caseRow:{padding:"6px 12px",borderBottom:`1px solid ${t.borderSubtle}`,transition:"background 0.15s"},verdictBtn:(o,s)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:o?`${s}33`:"transparent",color:o?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 $t(t){return t.split("/")[0].trim()}async function Bt(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 o=document.createElement("textarea");o.value=t,o.setAttribute("readonly",""),o.style.position="fixed",o.style.top="0",o.style.left="0",o.style.opacity="0",o.style.pointerEvents="none",document.body.appendChild(o),o.focus(),o.select(),o.setSelectionRange(0,t.length);let s=document.execCommand("copy");return document.body.removeChild(o),s}catch{return false}}function et({config:t,appSlug:o,environment:s,seededUsers:f,authToken:h,tk:d,compact:M=false,onExpand:v,onAuthExpired:S}){let[c,u]=useState(false),[_,B]=useState(null),[C,F]=useState(null),[T,n]=useState(null),[g,K]=useState(null),H=useCallback(x=>{B(x),n(null),K(null);let m=k=>{n(k),K(x),window.setTimeout(()=>{K(w=>w===x?null:w),n(w=>w===k?null:w);},3e3);},P=new URLSearchParams({app_slug:o,seed_user_slug:x,environment:s}),I={apikey:t.anonKey};I.Authorization=`Bearer ${h||t.anonKey}`;let $=(async()=>{try{let k=await fetch(`${t.serverUrl}/widget/totp-code?${P}`,{headers:I});if(!k.ok){let ie=await k.json().catch(()=>({error:`HTTP ${k.status}`}));return {ok:!1,status:k.status,error:ie.error||`HTTP ${k.status}`}}let w=await k.json();return {ok:!0,code:String(w.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),R=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let k=$.then(w=>{if(!w.ok)throw new Error(w.error);return new Blob([w.code],{type:"text/plain"})});R=navigator.clipboard.write([new ClipboardItem({"text/plain":k})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let k=await $;if(!k.ok){k.status===401||k.status===403?(S?.(),m("Signed out \u2014 please sign in again")):m(k.status===404?"No 2FA seed registered":k.error),B(null);return}let w=R?await R:false,ie=w?true:await Bt(k.code),V=w||ie;F({slug:x,code:k.code,copied:V}),window.setTimeout(()=>F(se=>se?.slug===x?null:se),V?2500:6e3),u(false),B(null);})();},[t.serverUrl,t.anonKey,h,o,s]);if(f.length===0)return null;if(M){let x=f.length>1,m=w=>{if(w.stopPropagation(),x&&v){v();return}H(f[0]);},P=!!g,I=!!C,$=I&&C.copied,R=I&&!C.copied,k=P?d.red:$?d.green:R?d.amber:d.purple;return jsxs("span",{onPointerDown:w=>w.stopPropagation(),onPointerUp:w=>w.stopPropagation(),onPointerMove:w=>w.stopPropagation(),onClick:m,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:k,fontWeight:600,cursor:"pointer",letterSpacing:R?"0.08em":void 0},title:P?T||"Failed":R?`Clipboard blocked \u2014 code: ${C.code}`:x?`${f.length} 2FA personas`:`Copy 2FA code for ${f[0]}`,children:[jsx(b,{d:P?p.alert:$?p.check:R?p.copy:p.shield,size:10}),$?jsx(Fragment,{children:"Copied"}):R?jsx(Fragment,{children:C.code}):P?jsx(Fragment,{children:"Failed"}):jsxs(Fragment,{children:["2FA",x&&` \xB7${f.length}`]})]})}if(f.length===1){let x=f[0],m=_===x,P=C?.slug===x,I=P&&C.copied,$=P&&!C.copied,R=g===x,k=R?d.red:I?d.green:$?d.amber:d.purple;return jsxs("button",{onClick:w=>{w.stopPropagation(),H(x);},disabled:m,style:{...tt(k),cursor:m?"wait":"pointer",opacity:m?.6:1},title:R?T||"Failed":$?`Clipboard blocked \u2014 code: ${C.code}`:`Copy 2FA code for ${x}`,children:[jsx(b,{d:R?p.alert:I?p.check:$?p.copy:p.shield,size:12}),I?"Copied":$?C.code:R?"Failed":m?"\u2026":`2FA \xB7 ${x}`]})}let j=!!g&&!c,D=!!C&&C.copied,Y=!!C&&!C.copied,J=j?d.red:D?d.green:Y?d.amber:d.purple,oe=useRef(null);return useLayoutEffect(()=>{if(!c)return;let x=oe.current;if(!x||typeof window>"u")return;let P=x.getBoundingClientRect().right-(window.innerWidth-8);P>0?x.style.left=`-${P}px`:x.style.left="0px";},[c]),jsxs("span",{style:{position:"relative"},children:[jsxs("button",{onClick:x=>{x.stopPropagation(),u(m=>!m),n(null),K(null);},style:{...tt(J),cursor:"pointer"},title:j?T||"Failed":Y?`Clipboard blocked \u2014 code: ${C.code}`:"Choose a persona to copy a 2FA code for",children:[jsx(b,{d:j?p.alert:D?p.check:Y?p.copy:p.shield,size:12}),D?"Copied":Y?C.code:j?"Failed":`2FA \xB7 ${f.length}`,jsx(b,{d:c?p.chevronUp:p.chevronDown,size:8})]}),c&&jsxs("div",{ref:oe,onPointerDown:x=>x.stopPropagation(),style:{position:"absolute",bottom:"100%",left:0,marginBottom:4,background:d.bg,border:`1px solid ${d.border}`,borderRadius:6,boxShadow:`0 8px 24px ${d.shadow}`,padding:4,minWidth:180,maxWidth:typeof window<"u"?Math.min(280,window.innerWidth-16):280,zIndex:10},children:[f.map(x=>{let m=_===x;return jsxs("button",{onClick:P=>{P.stopPropagation(),H(x);},disabled:m,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:m?"wait":"pointer",fontSize:"10px",color:d.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:P=>P.currentTarget.style.background=d.btnHover,onMouseLeave:P=>P.currentTarget.style.background="transparent",children:[jsx(b,{d:p.shield,size:10}),jsx("span",{style:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:x}),m&&jsx("span",{style:{color:d.textMuted,fontSize:9},children:"\u2026"})]},x)}),T&&jsx("div",{style:{padding:"4px 8px",fontSize:9,color:d.red},children:T})]})]})}function tt(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 nt="botbuddy-widget-state";function Et({config:t,appSlug:o,environment:s,ticketId:f,testRunId:h,testRunToken:d,targetUrl:M,version:v,commitSha:S,prNumber:c,branchName:u,onNavigate:_,displayName:B="human",defaultMode:C="mini",defaultPosition:F}){let T=Ct(),n=useMemo(()=>Tt(T),[T]),g=useMemo(()=>Pt(n),[n]),[K,H]=useState(false),[j,D]=useState(false),[Y,J]=useState(false),oe=useRef(false),x=t.dashboardUrl||"https://app.bot-buddy.ai",m=ze(x),I=(()=>{try{let e=typeof window<"u"?localStorage.getItem(nt):null;if(e)return JSON.parse(e)}catch{}return null})(),[$,R]=useState(I?.mode||C),[k,w]=useState(""),[ie,V]=useState(null),[se,Pe]=useState(null),[rt,ot]=useState(new Set),[X,$e]=useState(""),it=useCallback(e=>{ot(l=>{let y=new Set(l);return y.has(e)?y.delete(e):y.add(e),y});},[]),st=I?.x??F?.x??16,at=I?.y??F?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:L,setPos:Be,onPointerDown:ae,onPointerMove:le,onPointerUp:de,didDrag:ye}=_e(st,at),fe=useRef(null);useEffect(()=>{try{localStorage.setItem(nt,JSON.stringify({mode:$,x:L.x,y:L.y}));}catch{}},[$,L.x,L.y]),useEffect(()=>{if(typeof window>"u")return;let e=()=>{let y=fe.current;if(!y)return;let A=y.getBoundingClientRect(),O=qe(L.x,L.y,A.width,A.height,window.innerWidth,window.innerHeight);(O.x!==L.x||O.y!==L.y)&&Be(O);},l=window.requestAnimationFrame(e);return window.addEventListener("resize",e),()=>{window.cancelAnimationFrame(l),window.removeEventListener("resize",e);}},[$,L.x,L.y,Be]);let Ee=useRef(m.isAuthenticated);useEffect(()=>{!Ee.current&&m.isAuthenticated&&R("max"),Ee.current=m.isAuthenticated;},[m.isAuthenticated]);let Le="botbuddy-widget-max-size",lt=()=>{try{let e=localStorage.getItem(Le);if(e)return JSON.parse(e)}catch{}return {w:340,h:500}},[ce,We]=useState(lt),pe=useRef(false),ue=useRef({x:0,y:0,w:0,h:0}),dt=useCallback(e=>{e.stopPropagation(),pe.current=true,ue.current={x:e.clientX,y:e.clientY,w:ce.w,h:ce.h},e.target.setPointerCapture(e.pointerId);},[ce]),ct=useCallback(e=>{if(!pe.current)return;let l=Math.max(280,Math.min(600,ue.current.w+(e.clientX-ue.current.x))),y=Math.max(300,Math.min(window.innerHeight*.9,ue.current.h+(e.clientY-ue.current.y)));We({w:l,h:y});},[]),pt=useCallback(()=>{pe.current&&(pe.current=false,We(e=>(localStorage.setItem(Le,JSON.stringify(e)),e)));},[]),me=M??(typeof window<"u"?window.location.href:void 0),Ie=m.displayName||B,[N,Ae]=useState(null);useEffect(()=>{if(m.isAuthenticated)return;let e=new URLSearchParams;d&&e.set("token",d),f&&e.set("ticket_id",f),e.set("app_slug",o),s&&e.set("environment",s),h&&e.set("test_run_id",h),me&&e.set("target_url",me),v&&e.set("version",v),S&&e.set("commit_sha",S),c&&e.set("pr_number",String(c)),u&&e.set("branch_name",u),fetch(`${t.serverUrl}/widget/preview?${e}`,{headers:{apikey:t.anonKey}}).then(l=>l.json()).then(l=>Ae(l)).catch(()=>Ae(null));},[m.isAuthenticated,t.serverUrl,t.anonKey,o,s,f,h,d,me,v,S,c,u]);let{run:a,widgetState:q,fetchRun:ut,setVerdict:Fe,markComplete:gt,resetRun:ft}=Ce({config:t,appSlug:o,environment:s,ticketId:f,testRunId:h,testRunToken:d,targetUrl:me,version:v,commitSha:S,prNumber:c?String(c):void 0,branchName:u,authToken:m.token,onAuthExpired:m.logout}),be=useCallback(async(e,l,y)=>{Pe(e);try{await Fe(e,l,y,Ie);}finally{Pe(null),V(null),w("");}},[Fe,Ie]),z=a?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},mt=z.total>0&&z.pending===0,Z=q==="completed",xe=useMemo(()=>{let e=a?.test_cases||[];if(!X.trim())return e;let l=X.toLowerCase();return e.filter(y=>y.title.toLowerCase().includes(l)||y.description&&y.description.toLowerCase().includes(l)||y.url_path&&y.url_path.toLowerCase().includes(l)||y.seed_user&&y.seed_user.toLowerCase().includes(l))},[a?.test_cases,X]),De=useMemo(()=>{let e=xe,l=a?.test_cases||[];if(new Set(l.map(W=>W.source_pr_number)).size<=1)return null;let A=[],O=new Map;e.forEach(W=>{let U=W.source_pr_number;O.has(U)||O.set(U,[]),O.get(U).push(W);});let bt=[...O.keys()].sort((W,U)=>W===null?1:U===null?-1:U-W);for(let W of bt){let U=O.get(W),we={total:U.length,pass:0,fail:0,skip:0,pending:0};U.forEach(Je=>{Je.verdict in we&&we[Je.verdict]++;}),A.push({key:W!=null?`pr-${W}`:"general",label:W!=null?`PR #${W}`:"General",cases:U,summary:we});}return A.filter(W=>W.cases.length>0)},[xe,a?.test_cases]),Ue=z.total>0?(z.pass+z.fail)/z.total*100:0,G=s??a?.environment??null,Ne=useMemo(()=>{if(!G||G==="production")return [];let e=a?.test_cases||[],l=new Set;for(let y of e)y.seed_user&&l.add($t(y.seed_user));return [...l]},[a?.test_cases,G]),ve=useMemo(()=>{let e=a?.auto_tooltip_seconds??N?.auto_tooltip_seconds;return e!=null&&e>0?e*1e3:0},[a,N]),Oe=q==="ready"||q==="completed"||N?.enabled&&N.run;useEffect(()=>{if(!Oe||oe.current||ve<=0)return;oe.current=true,D(true);let e=window.setTimeout(()=>D(false),ve);return ()=>window.clearTimeout(e)},[Oe,ve]);let He=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:Rt[e.verdict]},children:se===e.id?jsx(b,{d:p.loader,className:""}):jsx(b,{d:zt[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(b,{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:l=>{l.stopPropagation(),_&&(l.preventDefault(),_(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(b,{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(l=>jsx("button",{onClick:()=>{if(e.verdict===l){be(e.id,"pending"),V(null);return}if(l==="fail"){V(e.id),w("");return}V(null),be(e.id,l);},disabled:se!==null,style:g.verdictBtn(e.verdict===l,l==="pass"?n.green:l==="fail"?n.red:n.amber),children:l.toUpperCase()},l)),e.created_by_agent_name&&jsxs("span",{style:{fontSize:"8px",color:n.purple,marginLeft:"4px",display:"inline-flex",alignItems:"center",gap:"2px"},children:[jsx(b,{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:Mt(e.verdict_at)})]})]}),ie===e.id&&jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsx("input",{autoFocus:true,value:k,onChange:l=>w(l.target.value),onKeyDown:l=>{l.key==="Enter"&&be(e.id,"fail",k.trim()||void 0),l.key==="Escape"&&(V(null),w(""));},placeholder:"Reason (optional)...",style:g.input}),jsx("button",{onClick:()=>{be(e.id,"fail",k.trim()||void 0);},style:g.verdictBtn(true,n.red),children:"\u2713"})]})]},e.id);if((q==="no-match"||q==="loading")&&!(!m.isAuthenticated&&N?.enabled&&N.run))return null;if(!m.isAuthenticated&&N?.enabled&&N.run){let e=N.run,l=e.summary,y=e.status==="completed";return jsx("div",{ref:fe,style:{...g.root,left:L.x,top:L.y},children:jsxs("div",{style:{position:"relative"},onMouseEnter:()=>H(true),onMouseLeave:()=>{H(false),J(false),D(false);},children:[jsxs("div",{style:{...g.pill(y),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:ae,onPointerMove:le,onPointerUp:()=>{de();},children:[jsx(b,{d:p.grip,size:10,className:""}),e.ticket_id&&e.ticket_url?jsx("a",{href:e.ticket_url,target:"_blank",rel:"noopener noreferrer",onClick:A=>A.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:A=>A.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:A=>A.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsx(b,{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(b,{d:p.bot,size:10}),e.created_by_agent_name]}):null,jsxs("span",{style:y?{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:A=>{A.stopPropagation(),m.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(!m.isAuthenticated)return jsxs("div",{ref:fe,style:{...g.root,left:L.x,top:L.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:ae,onPointerMove:le,onPointerUp:de,children:[jsx("div",{style:{...g.handle,borderBottom:"none"},children:jsxs("div",{style:g.sub,children:[jsx(b,{d:p.grip,size:10,className:""}),jsx(b,{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(),m.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 Ve=()=>{ye.current||(D(false),R(e=>{let l=e==="mini"?"max":"mini";return J(l==="mini"),l}));},Ke=({icon:e,onClick:l})=>jsx("button",{style:g.btn,onClick:y=>{y.stopPropagation(),l(y);},children:jsx(b,{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:[a?.pr_url&&jsxs("a",{href:a.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.blue),textDecoration:"none"},children:[jsx(b,{d:p.pr,size:12}),a.pr_number?`PR#${a.pr_number}`:a.pr_id||"PR",jsx(b,{d:p.externalLink,size:8})]}),a?.ticket_url&&jsxs("a",{href:a.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.amber),textDecoration:"none"},children:[jsx(b,{d:p.ticket,size:12}),a.ticket_id||"Ticket",jsx(b,{d:p.externalLink,size:8})]}),a?.created_by_agent_name&&(a.codex_thread_id?jsxs("a",{href:`codex://threads/${a.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...g.link(n.purple),textDecoration:"none"},children:[jsx(b,{d:p.bot,size:12}),a.created_by_agent_name,jsx(b,{d:p.externalLink,size:8})]}):jsxs("span",{style:{...g.link(n.purple)},children:[jsx(b,{d:p.bot,size:12}),a.created_by_agent_name]})),G&&jsx(et,{config:t,appSlug:o,environment:G,seededUsers:Ne,authToken:m.token,tk:n,onAuthExpired:m.logout}),jsx("span",{style:{...g.badge(a?.environment||"custom"),marginLeft:"auto"},children:a?.environment})]}),Ye=()=>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.10");},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.10"})]}),m.isAuthenticated&&jsx("button",{onClick:e=>{e.stopPropagation(),m.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:fe,style:{...g.root,left:L.x,top:L.y},children:[$==="mini"&&jsxs("div",{style:{position:"relative"},onMouseEnter:()=>H(true),onMouseLeave:()=>{H(false),J(false),D(false);},children:[jsxs("div",{style:{...g.pill(Z),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:ae,onPointerMove:le,onPointerUp:()=>{de(),ye.current||Ve();},children:[jsx(b,{d:p.grip,size:9,className:""}),a?.ticket_id&&jsx("span",{style:{color:n.amber,fontWeight:600},children:a.ticket_id}),a?.pr_number&&jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",a.pr_number]}),jsxs("span",{style:Z?{color:n.green}:void 0,children:[z.pass,"/",z.total]}),z.fail>0&&jsxs("span",{style:{color:n.red},children:[z.fail,"\u2717"]}),G&&jsx(et,{config:t,appSlug:o,environment:G,seededUsers:Ne,authToken:m.token,tk:n,compact:true,onExpand:()=>R("expanded"),onAuthExpired:m.logout})]}),!Y&&(K||j)&&a?.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:a.title}),(a.description||a.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:a.description||a.intro_notes})]})]}),$==="expanded"&&jsxs("div",{style:g.card(300,Z),children:[jsxs("div",{style:g.handle,onPointerDown:ae,onPointerMove:le,onPointerUp:de,onClick:Ve,children:[jsx(b,{d:p.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:g.title,children:a?.title}),jsx("div",{style:g.sub,children:a?.branch_name&&jsxs("span",{children:["\u2387 ",a.branch_name]})})]}),jsx(b,{d:p.chevronUp,className:""}),jsx(Ke,{icon:p.minus,onClick:()=>{D(false),J(true),R("mini");}})]}),jsxs("div",{style:g.stats,children:[jsxs("span",{style:{color:n.green},children:[z.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[z.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[z.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[z.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:z.total})]}),a?.description&&jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:a.description}),je(),Ye(),jsx("div",{style:g.progress,children:jsx("div",{style:g.progressBar(Ue)})})]}),$==="max"&&jsxs("div",{style:{...g.card(ce.w,Z),height:ce.h,position:"relative"},children:[jsxs("div",{style:g.handle,onPointerDown:ae,onPointerMove:le,onPointerUp:de,onClick:()=>{ye.current||R("expanded");},children:[jsx(b,{d:p.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:g.title,children:a?.title}),jsx("div",{style:g.sub,children:a?.branch_name&&jsxs("span",{children:["\u2387 ",a.branch_name]})})]}),jsx(b,{d:p.chevronDown,className:""}),jsx(Ke,{icon:p.minus,onClick:()=>{D(false),J(true),R("mini");}})]}),jsxs("div",{style:g.stats,children:[jsxs("span",{style:{color:n.green},children:[z.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[z.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[z.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[z.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:z.total})]}),(a?.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(b,{d:p.search,size:11,className:""}),jsx("input",{value:X,onChange:e=>$e(e.target.value),placeholder:"Filter test cases...",style:{flex:1,fontSize:"10px",background:"transparent",border:"none",outline:"none",color:n.text,fontFamily:"monospace"}}),X&&jsx("button",{onClick:()=>$e(""),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(b,{d:p.alert,className:""}),jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsx("button",{onClick:ut,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),Z&&jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsx(b,{d:p.checkAll,className:""}),jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsx("button",{onClick:ft,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),a?.intro_notes&&jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:a.intro_notes}),q!=="error"&&jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(a?.test_cases||[]).length===0?jsx("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:"No test cases"}):xe.length===0?jsxs("div",{style:{padding:"16px 12px",textAlign:"center",fontSize:"10px",color:n.gripColor},children:['No matches for "',X,'"']}):De?De.map(e=>{let l=rt.has(e.key);return jsxs("div",{children:[jsxs("button",{onClick:()=>it(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(b,{d:l?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})]}),!l&&e.cases.map(y=>He(y))]},e.key)}):xe.map(e=>He(e))}),mt&&!Z&&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:gt,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(),Ye(),jsx("div",{style:g.progress,children:jsx("div",{style:g.progressBar(Ue)})}),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:dt,onPointerMove:ct,onPointerUp:pt,onPointerEnter:e=>e.currentTarget.style.opacity="0.7",onPointerLeave:e=>{pe.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{Et as TestRunWidget,_e as useDraggable,Me as useRealtimeRefresh,Ce as useTestRun,ze 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 oe=8;function Re(e,r,s,f,p,a){let k=Math.max(oe,p-s-oe),y=Math.max(oe,a-f-oe);return {x:Math.min(Math.max(e,oe),k),y:Math.min(Math.max(r,oe),y)}}function Pe(e,r){let[s,f]=useState({x:e,y:r}),p=useRef(false),a=useRef({x:0,y:0}),k=useRef(false),y=useCallback(u=>{p.current=true,k.current=false,a.current={x:u.clientX-s.x,y:u.clientY-s.y},u.target.setPointerCapture(u.pointerId);},[s]),_=useCallback(u=>{p.current&&(k.current=true,f({x:u.clientX-a.current.x,y:u.clientY-a.current.y}));},[]),l=useCallback(()=>{p.current=false;},[]);return {pos:s,setPos:f,onPointerDown:y,onPointerMove:_,onPointerUp:l,didDrag:k}}function ze(e,r,s){let f=useRef(s);f.current=s,useEffect(()=>{if(!r)return;if(e.supabaseUrl){let a=false,k=null,y=()=>{a||k||(k=setInterval(()=>f.current(),15e3));},_=null;try{let T=new URL(e.supabaseUrl),n=["localhost","127.0.0.1","::1"].includes(T.hostname);if(T.protocol==="http:"&&!n)throw new Error("Realtime WebSocket requires HTTPS outside loopback hosts");T.protocol=T.protocol==="https:"?"wss:":"ws:",_=T.toString().replace(/\/$/,"");}catch{y();}let l=null,u=null,C=null,W=0,R=()=>{if(!(a||!_)){try{l=new WebSocket(`${_}/realtime/v1/websocket?apikey=${e.anonKey}&vsn=1.0.0`);}catch{y();return}l.onopen=()=>{if(a||!l)return;let T={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)};l.send(JSON.stringify(T));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)};l.send(JSON.stringify(n)),u=setInterval(()=>{l?.readyState===WebSocket.OPEN&&l.send(JSON.stringify({topic:"phoenix",event:"heartbeat",payload:{},ref:String(++W)}));},3e4);},l.onmessage=T=>{try{JSON.parse(T.data).event==="postgres_changes"&&f.current();}catch{}},l.onclose=()=>{F(),a||(C=setTimeout(R,3e3));},l.onerror=()=>{l?.close();};}},F=()=>{u&&(clearInterval(u),u=null);};return R(),()=>{a=true,F(),C&&clearTimeout(C),k&&clearInterval(k),l&&(l.onclose=null,l.onerror=null,l.close());}}let p=setInterval(()=>f.current(),15e3);return ()=>clearInterval(p)},[e.supabaseUrl,e.anonKey,r]);}function ve(e,r){let s={apikey:e.anonKey};return r?s.Authorization=`Bearer ${r}`:e.apiKey?s.Authorization=`Bearer ${e.apiKey}`:s.Authorization=`Bearer ${e.anonKey}`,s}async function Tt(e){if(e)return e;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 $e(e){let[r,s]=useState(null),[f,p]=useState("loading"),a=useCallback(async()=>{try{let l=await Tt(e.testRunToken);if(!l){p("no-match"),s(null);return}if(!e.ticketId){p("no-match"),s(null);return}let u=new URLSearchParams;u.set("token",l),u.set("ticket_id",e.ticketId),u.set("app_slug",e.appSlug),e.environment&&u.set("environment",e.environment),e.testRunId&&u.set("test_run_id",e.testRunId),e.targetUrl&&u.set("target_url",e.targetUrl),e.version&&u.set("version",e.version),e.commitSha&&u.set("commit_sha",e.commitSha),e.prNumber&&u.set("pr_number",String(e.prNumber)),e.branchName&&u.set("branch_name",e.branchName);let C=await fetch(`${e.config.serverUrl}/widget/test-run?${u.toString()}`,{headers:ve(e.config,e.authToken)});if(C.status===404){p("no-match"),s(null);return}if(C.status===401||C.status===403){e.authToken&&e.onAuthExpired&&e.onAuthExpired(),p("error");return}if(!C.ok){p("error");return}let W=await C.json();s(W),p(W.status==="completed"?"completed":"ready");}catch{p("error");}},[e.config.serverUrl,e.config.anonKey,e.config.apiKey,e.authToken,e.appSlug,e.environment,e.ticketId,e.testRunId,e.testRunToken,e.targetUrl,e.version,e.commitSha,e.branchName,e.prNumber,e.onAuthExpired]);return useEffect(()=>{a();},[a]),ze(e.config,r?.id,a),{run:r,widgetState:f,fetchRun:a,setVerdict:async(l,u,C,W="human")=>(s(F=>{if(!F)return null;let T=F.test_cases.map(m=>m.id===l?{...m,verdict:u,fail_reason:u==="fail"&&C||null,verdict_by_display_name:W,verdict_at:new Date().toISOString()}:m),n={total:T.length,pending:0,pass:0,fail:0,skip:0};return T.forEach(m=>{m.verdict in n&&n[m.verdict]++;}),{...F,test_cases:T,summary:n}}),(await fetch(`${e.config.serverUrl}/widget/test-cases/${l}/verdict`,{method:"POST",headers:{"Content-Type":"application/json",...ve(e.config,e.authToken)},body:JSON.stringify({verdict:u,fail_reason:C,display_name:W})})).ok),markComplete:async()=>r?(s(u=>u?{...u,status:"completed"}:null),p("completed"),(await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/complete`,{method:"POST",headers:{"Content-Type":"application/json",...ve(e.config,e.authToken)}})).ok):false,resetRun:async()=>{if(!r)return false;let l=await fetch(`${e.config.serverUrl}/widget/test-runs/${r.id}/reset`,{method:"POST",headers:{"Content-Type":"application/json",...ve(e.config,e.authToken)}});return l.ok&&a(),l.ok},setRun:s}}var Be="botbuddy-widget-auth-token",Le="botbuddy-widget-auth-name";function Ee(e){let[r,s]=useState(()=>{try{return localStorage.getItem(Be)}catch(y){return console.warn("Unable to read BotBuddy widget auth token",y),null}}),[f,p]=useState(()=>{try{return localStorage.getItem(Le)}catch(y){return console.warn("Unable to read BotBuddy widget display name",y),null}});useEffect(()=>{let y=new URL(e).origin,_=l=>{if(l.origin===y&&l.data?.type==="botbuddy-widget-auth"&&l.data.token){let{token:u,displayName:C}=l.data;s(u),p(C||"human");try{localStorage.setItem(Be,u),C&&localStorage.setItem(Le,C);}catch(W){console.warn("Unable to persist BotBuddy widget auth token",W);}}};return window.addEventListener("message",_),()=>window.removeEventListener("message",_)},[e]);let a=useCallback(()=>{let y=new URL("/widget-auth",e);y.searchParams.set("origin",window.location.origin);let _=420,l=520,u=window.screenX+(window.innerWidth-_)/2,C=window.screenY+(window.innerHeight-l)/2;window.open(y.toString(),"botbuddy-auth",`width=${_},height=${l},left=${u},top=${C},popup=yes`);},[e]),k=useCallback(()=>{s(null),p(null);try{localStorage.removeItem(Be),localStorage.removeItem(Le);}catch(y){console.warn("Unable to clear BotBuddy widget auth token",y);}},[]);return {token:r,displayName:f,isAuthenticated:!!r,openLogin:a,logout:k}}var we=null;function Pt(){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 We(){return we||(we=(async()=>{if(typeof fetch>"u")return null;try{let e=await fetch(Pt(),{cache:"no-store"});if(!e.ok)return null;let r=await e.json();if(!r||typeof r!="object"||Array.isArray(r))return null;let s={};for(let[f,p]of Object.entries(r))typeof p=="string"&&p.length>0&&(s[f]=p);return s}catch{return null}})(),we)}async function nt(e){return (await We())?.[e]??null}function zt(e){let r=e.replace(/=+$/,"").replace(/\s+/g,"").toUpperCase(),s="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",f=[],p=0,a=0;for(let k of r){let y=s.indexOf(k);if(y<0)throw new Error("Invalid Base32 character in TOTP secret");a=a<<5|y,p+=5,p>=8&&(p-=8,f.push(a>>>p&255));}return Uint8Array.from(f)}async function rt(e,r=Date.now()){if(typeof crypto>"u"||!crypto.subtle)throw new Error("Web Crypto unavailable");let s=zt(e),f=Math.floor(r/1e3/30),p=new Uint8Array(8),a=Math.floor(f/4294967296),k=f>>>0;p[0]=a>>>24&255,p[1]=a>>>16&255,p[2]=a>>>8&255,p[3]=a&255,p[4]=k>>>24&255,p[5]=k>>>16&255,p[6]=k>>>8&255,p[7]=k&255;let y=await crypto.subtle.importKey("raw",s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength),{name:"HMAC",hash:"SHA-1"},false,["sign"]),_=await crypto.subtle.sign("HMAC",y,p.buffer),l=new Uint8Array(_),u=l[l.length-1]&15;return (((l[u]&127)<<24|(l[u+1]&255)<<16|(l[u+2]&255)<<8|l[u+3]&255)%1e6).toString().padStart(6,"0")}function Bt(e){let r=new Date(e),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 p=r.getDate(),a=r.toLocaleString("en",{month:"short"}),k=r.toLocaleString("en",{hour:"numeric",minute:"2-digit",hour12:true});return `${a} ${p}, ${k}`}var v=({d:e,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:e})}),g={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 Lt(){let[e,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,p=f();p&&r(p);let a=window.matchMedia("(prefers-color-scheme: dark)"),k=_=>{let l=f();r(l||(_.matches?"dark":"light"));};a.addEventListener("change",k);let y=new MutationObserver(()=>{let _=f();r(_||(a.matches?"dark":"light"));});return y.observe(s,{attributes:true,attributeFilter:["class"]}),()=>{a.removeEventListener("change",k),y.disconnect();}},[]),e}function Et(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 Wt={pending:"#888",pass:"#34d399",fail:"#f87171",skip:"#f59e0b"},At={pending:g.circle,pass:g.check,fail:g.x,skip:g.skip},ot={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)"}},It=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,s)=>({width:`${r}px`,borderRadius:"8px",background:e.bg,border:s?`1px solid ${e.greenBorder}`:`1px solid ${e.border}`,boxShadow:s?`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 s=ot[r]||ot.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: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,s)=>({fontSize:"8px",padding:"2px 6px",borderRadius:"4px",border:"none",cursor:"pointer",background:r?`${s}33`:"transparent",color:r?s: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 Dt(e){return e.split("/")[0].trim()}async function Ft(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 s=document.execCommand("copy");return document.body.removeChild(r),s}catch{return false}}function it({config:e,appSlug:r,environment:s,seededUsers:f,authToken:p,tk:a,compact:k=false,onExpand:y,onAuthExpired:_}){let[l,u]=useState(false),[C,W]=useState(null),[R,F]=useState(null),[T,n]=useState(null),[m,j]=useState(null);useEffect(()=>{s==="local"&&We();},[s]);let K=useCallback(h=>{W(h),n(null),j(null);let M=S=>{n(S),j(h),window.setTimeout(()=>{j(b=>b===h?null:b),n(b=>b===S?null:b);},3e3);},w=new URLSearchParams({app_slug:r,seed_user_slug:h,environment:s}),$={apikey:e.anonKey};$.Authorization=`Bearer ${p||e.anonKey}`;let E=(async()=>{if(s==="local"){let S=await nt(h);if(S)try{return {ok:!0,code:await rt(S)}}catch{}}try{let S=await fetch(`${e.serverUrl}/widget/totp-code?${w}`,{headers:$});if(!S.ok){let U=await S.json().catch(()=>({error:`HTTP ${S.status}`}));return {ok:!1,status:S.status,error:U.error||`HTTP ${S.status}`}}let b=await S.json();return {ok:!0,code:String(b.code)}}catch{return {ok:false,status:0,error:"Network error"}}})(),z=null;try{if(typeof ClipboardItem<"u"&&navigator.clipboard?.write){let S=E.then(b=>{if(!b.ok)throw new Error(b.error);return new Blob([b.code],{type:"text/plain"})});z=navigator.clipboard.write([new ClipboardItem({"text/plain":S})]).then(()=>!0).catch(()=>!1);}}catch{}(async()=>{let S=await E;if(!S.ok){S.status===401||S.status===403?(_?.(),M("Signed out \u2014 please sign in again")):M(S.status===404?"No 2FA seed registered":S.error),W(null);return}let b=z?await z:false,U=b?true:await Ft(S.code),q=b||U;F({slug:h,code:S.code,copied:q}),window.setTimeout(()=>F(te=>te?.slug===h?null:te),q?2500:6e3),u(false),W(null);})();},[e.serverUrl,e.anonKey,p,r,s]);if(f.length===0)return null;if(k){let h=f.length>1,M=b=>{if(b.stopPropagation(),h&&y){y();return}K(f[0]);},w=!!m,$=!!R,E=$&&R.copied,z=$&&!R.copied,S=w?a.red:E?a.green:z?a.amber:a.purple;return jsxs("span",{onPointerDown:b=>b.stopPropagation(),onPointerUp:b=>b.stopPropagation(),onPointerMove:b=>b.stopPropagation(),onClick:M,style:{display:"inline-flex",alignItems:"center",gap:"3px",color:S,fontWeight:600,cursor:"pointer",letterSpacing:z?"0.08em":void 0},title:w?T||"Failed":z?`Clipboard blocked \u2014 code: ${R.code}`:h?`${f.length} 2FA personas`:`Copy 2FA code for ${f[0]}`,children:[jsx(v,{d:w?g.alert:E?g.check:z?g.copy:g.shield,size:10}),E?jsx(Fragment,{children:"Copied"}):z?jsx(Fragment,{children:R.code}):w?jsx(Fragment,{children:"Failed"}):jsxs(Fragment,{children:["2FA",h&&` \xB7${f.length}`]})]})}if(f.length===1){let h=f[0],M=C===h,w=R?.slug===h,$=w&&R.copied,E=w&&!R.copied,z=m===h,S=z?a.red:$?a.green:E?a.amber:a.purple;return jsxs("button",{onClick:b=>{b.stopPropagation(),K(h);},disabled:M,style:{...st(S),cursor:M?"wait":"pointer",opacity:M?.6:1},title:z?T||"Failed":E?`Clipboard blocked \u2014 code: ${R.code}`:`Copy 2FA code for ${h}`,children:[jsx(v,{d:z?g.alert:$?g.check:E?g.copy:g.shield,size:12}),$?"Copied":E?R.code:z?"Failed":M?"\u2026":`2FA \xB7 ${h}`]})}let Y=!!m&&!l,N=!!R&&R.copied,J=!!R&&!R.copied,G=Y?a.red:N?a.green:J?a.amber:a.purple,ee=useRef(null),le=useRef(null);useLayoutEffect(()=>{if(!l)return;let h=ee.current,M=le.current;if(!h||!M||typeof window>"u")return;let w=()=>{let $=h.getBoundingClientRect(),E=M.getBoundingClientRect(),z=window.innerWidth,S=window.innerHeight,b=$.left,U=$.top-E.height-6;U<8&&(U=$.bottom+6);let q=Math.max(8,z-E.width-8),te=Math.max(8,S-E.height-8);b=Math.min(Math.max(b,8),q),U=Math.min(Math.max(U,8),te),M.style.left=`${Math.round(b)}px`,M.style.top=`${Math.round(U)}px`;};return w(),window.addEventListener("scroll",w,true),window.addEventListener("resize",w),()=>{window.removeEventListener("scroll",w,true),window.removeEventListener("resize",w);}},[l,f.length,T]),useEffect(()=>{if(!l)return;let h=M=>{let w=M.target;le.current?.contains(w)||ee.current?.contains(w)||u(false);};return document.addEventListener("mousedown",h),()=>document.removeEventListener("mousedown",h)},[l]);let P=l&&typeof document<"u"?createPortal(jsxs("div",{ref:le,onPointerDown:h=>h.stopPropagation(),onMouseDown:h=>h.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:[f.map(h=>{let M=C===h;return jsxs("button",{onClick:w=>{w.stopPropagation(),K(h);},disabled:M,style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"5px 8px",background:"transparent",border:"none",borderRadius:4,cursor:M?"wait":"pointer",fontSize:"10px",color:a.text,textAlign:"left",fontFamily:"ui-monospace, SFMono-Regular, monospace"},onMouseEnter:w=>w.currentTarget.style.background=a.btnHover,onMouseLeave:w=>w.currentTarget.style.background="transparent",children:[jsx(v,{d:g.shield,size:10}),jsx("span",{style:{flex:1,overflowWrap:"anywhere",lineHeight:1.3},children:h}),M&&jsx("span",{style:{color:a.textMuted,fontSize:9},children:"\u2026"})]},h)}),T&&jsx("div",{style:{padding:"4px 8px",fontSize:9,color:a.red},children:T})]}),document.body):null;return jsxs(Fragment,{children:[jsxs("button",{ref:ee,onClick:h=>{h.stopPropagation(),u(M=>!M),n(null),j(null);},style:{...st(G),cursor:"pointer"},title:Y?T||"Failed":J?`Clipboard blocked \u2014 code: ${R.code}`:"Choose a persona to copy a 2FA code for",children:[jsx(v,{d:Y?g.alert:N?g.check:J?g.copy:g.shield,size:12}),N?"Copied":J?R.code:Y?"Failed":`2FA \xB7 ${f.length}`,jsx(v,{d:l?g.chevronUp:g.chevronDown,size:8})]}),P]})}function st(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 at="botbuddy-widget-state";function Ut({config:e,appSlug:r,environment:s,ticketId:f,testRunId:p,testRunToken:a,targetUrl:k,version:y,commitSha:_,prNumber:l,branchName:u,onNavigate:C,displayName:W="human",defaultMode:R="mini",defaultPosition:F}){let T=Lt(),n=useMemo(()=>Et(T),[T]),m=useMemo(()=>It(n),[n]),[j,K]=useState(false),[Y,N]=useState(false),[J,G]=useState(false),ee=useRef(false),le=e.dashboardUrl||"https://app.bot-buddy.ai",P=Ee(le),M=(()=>{try{let t=typeof window<"u"?localStorage.getItem(at):null;if(t)return JSON.parse(t)}catch{}return null})(),[w,$]=useState(M?.mode||R),[E,z]=useState(""),[S,b]=useState(null),[U,q]=useState(null),[te,dt]=useState(new Set),[ne,Ae]=useState(""),ct=useCallback(t=>{dt(d=>{let x=new Set(d);return x.has(t)?x.delete(t):x.add(t),x});},[]),pt=M?.x??F?.x??16,ut=M?.y??F?.y??(typeof window<"u"?window.innerHeight-56:600),{pos:B,setPos:Se,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,didDrag:ke}=Pe(pt,ut),ue=useRef(null);useEffect(()=>{try{localStorage.setItem(at,JSON.stringify({mode:w,x:B.x,y:B.y}));}catch{}},[w,B.x,B.y]),useLayoutEffect(()=>{if(typeof window>"u")return;let t=ue.current;if(!t)return;let d=t.getBoundingClientRect(),x=Re(B.x,B.y,d.width,d.height,window.innerWidth,window.innerHeight);(x.x!==B.x||x.y!==B.y)&&Se(x);}),useEffect(()=>{if(typeof window>"u")return;let t=()=>{let d=ue.current;if(!d)return;let x=d.getBoundingClientRect(),D=Re(B.x,B.y,x.width,x.height,window.innerWidth,window.innerHeight);(D.x!==B.x||D.y!==B.y)&&Se(D);};return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[B.x,B.y,Se]);let Ie=useRef(P.isAuthenticated);useEffect(()=>{!Ie.current&&P.isAuthenticated&&$("max"),Ie.current=P.isAuthenticated;},[P.isAuthenticated]);let De="botbuddy-widget-max-size",gt=()=>{try{let t=localStorage.getItem(De);if(t)return JSON.parse(t)}catch{}return {w:340,h:500}},[ge,Fe]=useState(gt),fe=useRef(false),me=useRef({x:0,y:0,w:0,h:0}),ft=useCallback(t=>{t.stopPropagation(),fe.current=true,me.current={x:t.clientX,y:t.clientY,w:ge.w,h:ge.h},t.target.setPointerCapture(t.pointerId);},[ge]),mt=useCallback(t=>{if(!fe.current)return;let d=Math.max(280,Math.min(600,me.current.w+(t.clientX-me.current.x))),x=Math.max(300,Math.min(window.innerHeight*.9,me.current.h+(t.clientY-me.current.y)));Fe({w:d,h:x});},[]),ht=useCallback(()=>{fe.current&&(fe.current=false,Fe(t=>(localStorage.setItem(De,JSON.stringify(t)),t)));},[]),be=k??(typeof window<"u"?window.location.href:void 0),Ue=P.displayName||W,[O,Ne]=useState(null);useEffect(()=>{if(P.isAuthenticated)return;let t=new URLSearchParams;a&&t.set("token",a),f&&t.set("ticket_id",f),t.set("app_slug",r),s&&t.set("environment",s),p&&t.set("test_run_id",p),be&&t.set("target_url",be),y&&t.set("version",y),_&&t.set("commit_sha",_),l&&t.set("pr_number",String(l)),u&&t.set("branch_name",u),fetch(`${e.serverUrl}/widget/preview?${t}`,{headers:{apikey:e.anonKey}}).then(d=>d.json()).then(d=>Ne(d)).catch(()=>Ne(null));},[P.isAuthenticated,e.serverUrl,e.anonKey,r,s,f,p,a,be,y,_,l,u]);let{run:c,widgetState:X,fetchRun:bt,setVerdict:He,markComplete:xt,resetRun:yt}=$e({config:e,appSlug:r,environment:s,ticketId:f,testRunId:p,testRunToken:a,targetUrl:be,version:y,commitSha:_,prNumber:l?String(l):void 0,branchName:u,authToken:P.token,onAuthExpired:P.logout}),xe=useCallback(async(t,d,x)=>{q(t);try{await He(t,d,x,Ue);}finally{q(null),b(null),z("");}},[He,Ue]),L=c?.summary||{total:0,pending:0,pass:0,fail:0,skip:0},vt=L.total>0&&L.pending===0,re=X==="completed",ye=useMemo(()=>{let t=c?.test_cases||[];if(!ne.trim())return t;let d=ne.toLowerCase();return t.filter(x=>x.title.toLowerCase().includes(d)||x.description&&x.description.toLowerCase().includes(d)||x.url_path&&x.url_path.toLowerCase().includes(d)||x.seed_user&&x.seed_user.toLowerCase().includes(d))},[c?.test_cases,ne]),Oe=useMemo(()=>{let t=ye,d=c?.test_cases||[];if(new Set(d.map(I=>I.source_pr_number)).size<=1)return null;let D=[],he=new Map;t.forEach(I=>{let H=I.source_pr_number;he.has(H)||he.set(H,[]),he.get(H).push(I);});let wt=[...he.keys()].sort((I,H)=>I===null?1:H===null?-1:H-I);for(let I of wt){let H=he.get(I),Me={total:H.length,pass:0,fail:0,skip:0,pending:0};H.forEach(Ze=>{Ze.verdict in Me&&Me[Ze.verdict]++;}),D.push({key:I!=null?`pr-${I}`:"general",label:I!=null?`PR #${I}`:"General",cases:H,summary:Me});}return D.filter(I=>I.cases.length>0)},[ye,c?.test_cases]),Ke=L.total>0?(L.pass+L.fail)/L.total*100:0,Z=s??c?.environment??null,Ve=useMemo(()=>{if(!Z||Z==="production")return [];let t=c?.test_cases||[],d=new Set;for(let x of t)x.seed_user&&d.add(Dt(x.seed_user));return [...d]},[c?.test_cases,Z]),_e=useMemo(()=>{let t=c?.auto_tooltip_seconds??O?.auto_tooltip_seconds;return t!=null&&t>0?t*1e3:0},[c,O]),je=X==="ready"||X==="completed"||O?.enabled&&O.run;useEffect(()=>{if(!je||ee.current||_e<=0)return;ee.current=true,N(true);let t=window.setTimeout(()=>N(false),_e);return ()=>window.clearTimeout(t)},[je,_e]);let Ye=t=>jsxs("div",{style:m.caseRow,children:[jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"},children:[jsx("div",{style:{marginTop:"2px",flexShrink:0,color:Wt[t.verdict]},children:U===t.id?jsx(v,{d:g.loader,className:""}):jsx(v,{d:At[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(v,{d:g.key,size:10}),jsx("span",{children:t.seed_user})]}),t.url_path&&jsxs("a",{href:t.url_path,target:"_blank",rel:"noopener noreferrer",onClick:d=>{d.stopPropagation(),C&&(d.preventDefault(),C(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(v,{d:g.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(d=>jsx("button",{onClick:()=>{if(t.verdict===d){xe(t.id,"pending"),b(null);return}if(d==="fail"){b(t.id),z("");return}b(null),xe(t.id,d);},disabled:U!==null,style:m.verdictBtn(t.verdict===d,d==="pass"?n.green:d==="fail"?n.red:n.amber),children:d.toUpperCase()},d)),t.created_by_agent_name&&jsxs("span",{style:{fontSize:"8px",color:n.purple,marginLeft:"4px",display:"inline-flex",alignItems:"center",gap:"2px"},children:[jsx(v,{d:g.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:Bt(t.verdict_at)})]})]}),S===t.id&&jsxs("div",{style:{marginLeft:"22px",marginTop:"4px",display:"flex",gap:"4px"},children:[jsx("input",{autoFocus:true,value:E,onChange:d=>z(d.target.value),onKeyDown:d=>{d.key==="Enter"&&xe(t.id,"fail",E.trim()||void 0),d.key==="Escape"&&(b(null),z(""));},placeholder:"Reason (optional)...",style:m.input}),jsx("button",{onClick:()=>{xe(t.id,"fail",E.trim()||void 0);},style:m.verdictBtn(true,n.red),children:"\u2713"})]})]},t.id);if((X==="no-match"||X==="loading")&&!(!P.isAuthenticated&&O?.enabled&&O.run))return null;if(!P.isAuthenticated&&O?.enabled&&O.run){let t=O.run,d=t.summary,x=t.status==="completed";return jsx("div",{ref:ue,style:{...m.root,left:B.x,top:B.y},children:jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),G(false),N(false);},children:[jsxs("div",{style:{...m.pill(x),gap:"8px",padding:"5px 10px",fontSize:"10px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe();},children:[jsx(v,{d:g.grip,size:10,className:""}),t.ticket_id&&t.ticket_url?jsx("a",{href:t.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:t.ticket_id}):null,t.pr_url?jsxs("a",{href:t.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#",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:D=>D.stopPropagation(),style:{color:n.purple,textDecoration:"none",fontWeight:600,display:"inline-flex",alignItems:"center",gap:"3px"},children:[jsx(v,{d:g.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(v,{d:g.bot,size:10}),t.created_by_agent_name]}):null,jsxs("span",{style:x?{color:n.green}:void 0,children:[d.pass,"/",d.total]}),d.fail>0&&jsxs("span",{style:{color:n.red},children:[d.fail,"\u2717"]}),jsx("span",{onClick:D=>{D.stopPropagation(),P.openLogin();},style:{color:n.textMuted,fontWeight:400,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},children:"Sign in"})]}),!J&&(j||Y)&&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(!P.isAuthenticated)return jsxs("div",{ref:ue,style:{...m.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:{...m.handle,borderBottom:"none"},children:jsxs("div",{style:m.sub,children:[jsx(v,{d:g.grip,size:10,className:""}),jsx(v,{d:g.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:t=>{t.stopPropagation(),P.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||(N(false),$(t=>{let d=t==="mini"?"max":"mini";return G(d==="mini"),d}));},Ge=({icon:t,onClick:d})=>jsx("button",{style:m.btn,onClick:x=>{x.stopPropagation(),d(x);},children:jsx(v,{d:t,className:""})}),qe=()=>jsxs("div",{style:{padding:"6px 12px",display:"flex",gap:"8px",flexWrap:"wrap",alignItems:"center",borderTop:`1px solid ${n.borderSubtle}`,flexShrink:0},children:[c?.pr_url&&jsxs("a",{href:c.pr_url,target:"_blank",rel:"noopener noreferrer",style:{...m.link(n.blue),textDecoration:"none"},children:[jsx(v,{d:g.pr,size:12}),c.pr_number?`PR#${c.pr_number}`:c.pr_id||"PR",jsx(v,{d:g.externalLink,size:8})]}),c?.ticket_url&&jsxs("a",{href:c.ticket_url,target:"_blank",rel:"noopener noreferrer",style:{...m.link(n.amber),textDecoration:"none"},children:[jsx(v,{d:g.ticket,size:12}),c.ticket_id||"Ticket",jsx(v,{d:g.externalLink,size:8})]}),c?.created_by_agent_name&&(c.codex_thread_id?jsxs("a",{href:`codex://threads/${c.codex_thread_id}`,target:"_blank",rel:"noopener noreferrer",style:{...m.link(n.purple),textDecoration:"none"},children:[jsx(v,{d:g.bot,size:12}),c.created_by_agent_name,jsx(v,{d:g.externalLink,size:8})]}):jsxs("span",{style:{...m.link(n.purple)},children:[jsx(v,{d:g.bot,size:12}),c.created_by_agent_name]})),Z&&jsx(it,{config:e,appSlug:r,environment:Z,seededUsers:Ve,authToken:P.token,tk:n,onAuthExpired:P.logout}),jsx("span",{style:{...m.badge(c?.environment||"custom"),marginLeft:"auto"},children:c?.environment})]}),Xe=()=>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"})]}),P.isAuthenticated&&jsx("button",{onClick:t=>{t.stopPropagation(),P.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:{...m.root,left:B.x,top:B.y},children:[w==="mini"&&jsxs("div",{style:{position:"relative"},onMouseEnter:()=>K(true),onMouseLeave:()=>{K(false),G(false),N(false);},children:[jsxs("div",{style:{...m.pill(re),gap:"6px",padding:"3px 8px",fontSize:"9px"},onPointerDown:de,onPointerMove:ce,onPointerUp:()=>{pe(),ke.current||Je();},children:[jsx(v,{d:g.grip,size:9,className:""}),c?.ticket_id&&jsx("span",{style:{color:n.amber,fontWeight:600},children:c.ticket_id}),c?.pr_number&&jsxs("span",{style:{color:n.blue,fontWeight:600},children:["PR#",c.pr_number]}),jsxs("span",{style:re?{color:n.green}:void 0,children:[L.pass,"/",L.total]}),L.fail>0&&jsxs("span",{style:{color:n.red},children:[L.fail,"\u2717"]}),Z&&jsx(it,{config:e,appSlug:r,environment:Z,seededUsers:Ve,authToken:P.token,tk:n,compact:true,onExpand:()=>$("expanded"),onAuthExpired:P.logout})]}),!J&&(j||Y)&&c?.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:c.title}),(c.description||c.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:c.description||c.intro_notes})]})]}),w==="expanded"&&jsxs("div",{style:m.card(300,re),children:[jsxs("div",{style:m.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:Je,children:[jsx(v,{d:g.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:m.title,children:c?.title}),jsx("div",{style:m.sub,children:c?.branch_name&&jsxs("span",{children:["\u2387 ",c.branch_name]})})]}),jsx(v,{d:g.chevronUp,className:""}),jsx(Ge,{icon:g.minus,onClick:()=>{N(false),G(true),$("mini");}})]}),jsxs("div",{style:m.stats,children:[jsxs("span",{style:{color:n.green},children:[L.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[L.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[L.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[L.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:L.total})]}),c?.description&&jsx("div",{style:{padding:"6px 12px",fontSize:"10px",color:n.gripColor,borderBottom:`1px solid ${n.borderSubtle}`,flexShrink:0},children:c.description}),qe(),Xe(),jsx("div",{style:m.progress,children:jsx("div",{style:m.progressBar(Ke)})})]}),w==="max"&&jsxs("div",{style:{...m.card(ge.w,re),height:ge.h,position:"relative"},children:[jsxs("div",{style:m.handle,onPointerDown:de,onPointerMove:ce,onPointerUp:pe,onClick:()=>{ke.current||$("expanded");},children:[jsx(v,{d:g.grip,className:""}),jsxs("div",{style:{flex:1,minWidth:0},children:[jsx("div",{style:m.title,children:c?.title}),jsx("div",{style:m.sub,children:c?.branch_name&&jsxs("span",{children:["\u2387 ",c.branch_name]})})]}),jsx(v,{d:g.chevronDown,className:""}),jsx(Ge,{icon:g.minus,onClick:()=>{N(false),G(true),$("mini");}})]}),jsxs("div",{style:m.stats,children:[jsxs("span",{style:{color:n.green},children:[L.pass,"\u2713"]}),jsxs("span",{style:{color:n.red},children:[L.fail,"\u2717"]}),jsxs("span",{style:{color:n.amber},children:[L.skip,"\u23ED"]}),jsxs("span",{style:{color:n.gripColor},children:[L.pending,"\u25CC"]}),jsx("span",{style:{color:n.textFaint,marginLeft:"auto"},children:L.total})]}),c?.intro_notes&&jsx("div",{style:{padding:"6px 12px",borderBottom:`1px solid ${n.borderSubtle}`,fontSize:"10px",color:n.textMuted,fontStyle:"italic",flexShrink:0},children:c.intro_notes}),(c?.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(v,{d:g.search,size:11,className:""}),jsx("input",{value:ne,onChange:t=>Ae(t.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:()=>Ae(""),style:{background:"none",border:"none",cursor:"pointer",color:n.textFaint,fontSize:"10px",padding:0},children:"\u2715"})]}),X==="error"&&jsxs("div",{style:{padding:"12px",textAlign:"center"},children:[jsx(v,{d:g.alert,className:""}),jsx("div",{style:{fontSize:"10px",color:n.red},children:"Failed to load"}),jsx("button",{onClick:bt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer",marginTop:"4px"},children:"Retry"})]}),re&&jsxs("div",{style:{padding:"6px 12px",display:"flex",alignItems:"center",gap:"8px",borderBottom:`1px solid ${n.greenBorderSubtle}`,background:n.greenBg},children:[jsx(v,{d:g.checkAll,className:""}),jsx("span",{style:{fontSize:"10px",color:n.green,flex:1},children:"Run completed"}),jsx("button",{onClick:yt,style:{fontSize:"9px",color:"#3b82f6",background:"none",border:"none",cursor:"pointer"},children:"Reset"})]}),X!=="error"&&jsx("div",{style:{flex:1,overflowY:"auto",minHeight:0},children:(c?.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,'"']}):Oe?Oe.map(t=>{let d=te.has(t.key);return jsxs("div",{children:[jsxs("button",{onClick:()=>ct(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(v,{d:d?g.chevronDown:g.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})]}),!d&&t.cases.map(x=>Ye(x))]},t.key)}):ye.map(t=>Ye(t))}),vt&&!re&&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:xt,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"})]}),qe(),Xe(),jsx("div",{style:m.progress,children:jsx("div",{style:m.progressBar(Ke)})}),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:ft,onPointerMove:mt,onPointerUp:ht,onPointerEnter:t=>t.currentTarget.style.opacity="0.7",onPointerLeave:t=>{fe.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{Ut as TestRunWidget,Pe as useDraggable,ze as useRealtimeRefresh,$e as useTestRun,Ee as useWidgetAuth};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbuddy/react",
3
- "version": "0.9.10",
3
+ "version": "0.9.13",
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": {