const Qe="modulepreload",et=function(e){return"/"+e},pe={},Q=function(t,n,r){let o=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const s=document.querySelector("meta[property=csp-nonce]"),a=(s==null?void 0:s.nonce)||(s==null?void 0:s.getAttribute("nonce"));o=Promise.allSettled(n.map(u=>{if(u=et(u),u in pe)return;pe[u]=!0;const l=u.endsWith(".css"),d=l?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${d}`))return;const c=document.createElement("link");if(c.rel=l?"stylesheet":Qe,l||(c.as="script"),c.crossOrigin="",c.href=u,a&&c.setAttribute("nonce",a),document.head.appendChild(c),l)return new Promise((w,M)=>{c.addEventListener("load",w),c.addEventListener("error",()=>M(new Error(`Unable to preload CSS for ${u}`)))})}))}function i(s){const a=new Event("vite:preloadError",{cancelable:!0});if(a.payload=s,window.dispatchEvent(a),!a.defaultPrevented)throw s}return o.then(s=>{for(const a of s||[])a.status==="rejected"&&i(a.reason);return t().catch(i)})};const Ne="127.0.0.1";function tt(e){return`ws://${Ne}:${e}/ext`}function nt(e){return`http://${Ne}:${e}`}const rt=2e3,ot=6e4,ae="chrisgaoRuntimeConfig",N="chrisgaoAutomationSessions",Oe=12e4,se="chrisgao-session-",J="data:text/html,<html></html>",Pe='Chrisgao needs Chrome "Allow in Incognito" enabled before it can create its dedicated incognito automation window. Open chrome://extensions, open Chrisgao details, and enable "Allow in Incognito".';function S(e){return e?!e.startsWith("chrome://")&&!e.startsWith("chrome-extension://"):!0}const p=new Set;async function T(e){try{const t=await chrome.tabs.get(e);if(!S(t.url))throw p.delete(e),new Error(`Cannot debug tab ${e}: URL is ${t.url??"unknown"}`)}catch(t){throw t instanceof Error&&t.message.startsWith("Cannot debug tab")?t:(p.delete(e),new Error(`Tab ${e} no longer exists`))}if(p.has(e))try{await chrome.debugger.sendCommand({tabId:e},"Runtime.evaluate",{expression:"1",returnByValue:!0});return}catch{p.delete(e)}try{await chrome.debugger.attach({tabId:e},"1.3")}catch(t){const n=t instanceof Error?t.message:String(t),r=n.includes("chrome-extension://")?". Tip: another Chrome extension may be interfering — try disabling other extensions":"";if(n.includes("Another debugger is already attached")){console.warn(`[chrisgao-bridge] Another debugger (e.g. DevTools) is attached to tab ${e}. Detaching it to take over. Close DevTools to avoid interference.`);try{await chrome.debugger.detach({tabId:e})}catch{}try{await chrome.debugger.attach({tabId:e},"1.3")}catch{throw new Error(`attach failed: ${n}${r}`)}}else throw new Error(`attach failed: ${n}${r}`)}p.add(e);try{await chrome.debugger.sendCommand({tabId:e},"Runtime.enable")}catch{}}async function X(e,t){var r,o;await T(e);const n=await chrome.debugger.sendCommand({tabId:e},"Runtime.evaluate",{expression:t,returnByValue:!0,awaitPromise:!0});if(n.exceptionDetails){const i=((r=n.exceptionDetails.exception)==null?void 0:r.description)||n.exceptionDetails.text||"Eval error";throw new Error(i)}return(o=n.result)==null?void 0:o.value}async function it(e,t={}){await T(e);const n=t.format??"png",r={format:n};if(n==="jpeg"&&t.quality!==void 0&&(r.quality=Math.max(0,Math.min(100,t.quality))),t.fullPage){r.captureBeyondViewport=!0;try{const i=await chrome.debugger.sendCommand({tabId:e},"Page.getLayoutMetrics"),s=i.cssContentSize||i.contentSize;s&&s.width>0&&s.height>0&&(s.height<=16e3&&s.width<=16e3?r.clip={x:0,y:0,width:Math.ceil(s.width),height:Math.ceil(s.height),scale:1}:r.clip={x:0,y:0,width:Math.ceil(Math.min(s.width,16e3)),height:16e3,scale:1})}catch{}}return(await chrome.debugger.sendCommand({tabId:e},"Page.captureScreenshot",r)).data}function Ee(e){if(p.has(e)){p.delete(e);try{chrome.debugger.detach({tabId:e})}catch{}}}async function at(e,t){try{const n=await X(e,`(()=>{
        const candidates=[];
        document.querySelectorAll('[id],[class],[name],[data-testid],[aria-label]').forEach(el=>{
          const id=el.id; if(id)candidates.push('#'+id);
          const nm=el.getAttribute('name'); if(nm)candidates.push('[name="'+nm+'"]');
          const testid=el.getAttribute('data-testid'); if(testid)candidates.push('[data-testid="'+testid+'"]');
          const aria=el.getAttribute('aria-label'); if(aria)candidates.push('[aria-label="'+aria+'"]');
          const tag=el.tagName.toLowerCase();
          el.classList.forEach(c=>candidates.push(tag+'.'+c));
        });
        const unique=[...new Set(candidates)].slice(0,200);
        const target=${JSON.stringify(t)};
        // 相似度打分
        function sim(a,b){let s=0;const al=a.length,bl=b.length;for(let i=0;i<Math.min(al,bl);i++)if(a[i]===b[i])s++;return s/Math.max(al,bl)}
        const scored=unique.map(s=>({s,score:sim(s.toLowerCase(),target.toLowerCase())})).sort((a,b)=>b.score-a.score);
        return JSON.stringify(scored.slice(0,5).map(s=>s.s));
      })()`),r=JSON.parse(n);return Array.isArray(r)?r:[]}catch{return[]}}function st(){chrome.tabs.onRemoved.addListener(e=>{p.delete(e),Q(()=>Promise.resolve().then(()=>oe),void 0).then(t=>t.cleanupTab(e))}),chrome.debugger.onDetach.addListener(e=>{e.tabId&&(p.delete(e.tabId),Q(()=>Promise.resolve().then(()=>oe),void 0).then(t=>t.cleanupTab(e.tabId)))}),chrome.tabs.onUpdated.addListener((e,t)=>{if(t.url&&!S(t.url)&&p.has(e)){p.delete(e);try{chrome.debugger.detach({tabId:e})}catch{}}}),chrome.debugger.onEvent.addListener((e,t,n)=>{if(!e.tabId)return;const r=n||{};Q(()=>Promise.resolve().then(()=>oe),void 0).then(o=>{t.startsWith("Network.")?o.handleNetworkEvent(e.tabId,t,r):(t==="Runtime.consoleAPICalled"||t==="Runtime.exceptionThrown"||t.startsWith("Log."))&&o.handleConsoleEvent(e.tabId,t,r)})})}function E(e){return e==="human"}function A(e){return se+e}let ve=Promise.resolve();function x(e){const t=ve.then(async()=>{const r=(await chrome.storage.session.get(N))[N]||{},o=await e(r);try{await chrome.storage.session.set({[N]:r})}catch(i){console.error("[chrisgao-bridge] Failed to persist sessions:",i instanceof Error?i.message:String(i))}return o});return ve=t.catch(n=>{console.error("[chrisgao-bridge] Session mutation error — subsequent operations may be affected:",n instanceof Error?n.message:String(n))}),t}const ee=new Map;function ct(e,t){const n=ee.get(e);if(n)return n;const r=t().finally(()=>{ee.delete(e)});return ee.set(e,r),r}async function lt(){var t;if(!((t=chrome.extension)!=null&&t.isAllowedIncognitoAccess))throw new Error("Chrome incognito access check is unavailable in this extension context.");if(!await chrome.extension.isAllowedIncognitoAccess())throw new Error(Pe)}async function xe(e){return ct(e,async()=>{let t=await x(async o=>{const i=o[e];if(i){try{return await chrome.windows.get(i.windowId),i.windowId}catch{}delete o[e]}return null});if(t!==null)return t;await lt();const n=await chrome.windows.create({url:J,focused:!1,width:1280,height:900,type:"normal",incognito:!0});if(!n.id)throw new Error("Failed to create incognito automation window");if(!n.incognito){try{await chrome.windows.remove(n.id)}catch{}throw new Error(Pe)}const r=Date.now();return await x(async o=>{o[e]={windowId:n.id,deadlineAt:r+Oe,createdAt:r},await chrome.alarms.create(A(e),{when:o[e].deadlineAt})}),console.log(`[chrisgao-bridge] Created incognito automation window ${n.id} (${e})`),await new Promise(o=>setTimeout(o,200)),n.id})}async function ut(e){await x(async t=>{const n=t[e];n&&(n.deadlineAt=Date.now()+Oe,await chrome.alarms.create(A(e),{when:n.deadlineAt}))})}async function Me(e,t){await x(async n=>{n[e]&&(delete n[e],await chrome.alarms.clear(A(e)).catch(()=>{}))})}async function G(){const e=await chrome.windows.getLastFocused({windowTypes:["normal"]});if(e!=null&&e.id&&!e.incognito)return e.id;throw new Error("No focused normal Chrome window found.")}async function dt(e){if(e!==void 0){const o=await chrome.tabs.get(e);if(!o.incognito&&S(o.url))return e;throw new Error(`Tab ${e} is not a debuggable tab in a normal Chrome window.`)}const t=await G(),r=(await chrome.tabs.query({windowId:t,active:!0})).find(o=>o.id&&!o.incognito&&S(o.url));if(!(r!=null&&r.id))throw new Error("No debuggable active tab found in the user's visible Chrome window.");return r.id}async function f(e,t){if(E(t))return await dt(e);if(e!==void 0){const a=await chrome.tabs.get(e);if(!S(a.url))throw new Error(`Tab ${e} URL is not debuggable: ${a.url}`);const d=((await chrome.storage.session.get(N))[N]||{})[t];if(!d||a.windowId!==d.windowId)throw new Error(`Tab ${e} does not belong to workspace "${t}"`);return e}const n=await xe(t),r=await chrome.tabs.query({windowId:n}),o=r.find(a=>a.id&&S(a.url));if(o!=null&&o.id)return o.id;const i=r.find(a=>a.id);if(i!=null&&i.id){await chrome.tabs.update(i.id,{url:J}),await new Promise(a=>setTimeout(a,300));try{const a=await chrome.tabs.get(i.id);if(S(a.url))return i.id}catch{}}const s=await chrome.tabs.create({windowId:n,url:J,active:!0});if(!s.id)throw new Error("Failed to create tab in automation window");return s.id}async function wt(e){const r=((await chrome.storage.session.get(N))[N]||{})[e];if(!r)return[];try{return await chrome.tabs.query({windowId:r.windowId})}catch{return await Me(e),[]}}async function te(e){return(await wt(e)).filter(n=>S(n.url))}async function ne(){const e=await G();return(await chrome.tabs.query({windowId:e})).filter(n=>!n.incognito&&S(n.url))}async function ft(){const e=await chrome.windows.getAll({}),t=new Map;for(const n of e)n.id&&t.set(n.id,n);await x(async n=>{const r=Date.now();for(const[o,i]of Object.entries(n)){const s=t.get(i.windowId);if(!s||!s.incognito||s.type!=="normal")delete n[o],await chrome.alarms.clear(A(o)).catch(()=>{});else if(i.deadlineAt<=r){try{await chrome.windows.remove(i.windowId)}catch(a){console.warn(`[chrisgao-bridge] Could not close expired session window ${i.windowId} (${o}):`,a instanceof Error?a.message:String(a))}delete n[o],await chrome.alarms.clear(A(o)).catch(()=>{})}else await chrome.alarms.create(A(o),{when:i.deadlineAt})}})}function ht(){chrome.windows.onRemoved.addListener(e=>{x(async t=>{for(const[n,r]of Object.entries(t))r.windowId===e&&(console.log(`[chrisgao-bridge] Automation window closed (${n})`),delete t[n],await chrome.alarms.clear(A(n)).catch(()=>{}))})}),chrome.alarms.onAlarm.addListener(e=>{if(!e.name.startsWith(se))return;const t=e.name.slice(se.length);x(async n=>{const r=n[t];if(r){if(r.deadlineAt>Date.now()){await chrome.alarms.create(A(t),{when:r.deadlineAt});return}try{await chrome.windows.remove(r.windowId),console.log(`[chrisgao-bridge] Automation window ${r.windowId} (${t}) closed (idle timeout)`)}catch{}delete n[t],await chrome.alarms.clear(A(t)).catch(()=>{})}})})}function gt(e){return!!(e&&typeof e=="object"&&e.ok===!0&&e.running===!0&&typeof e.host=="string"&&typeof e.port=="number")}async function mt(e,t){const n=new AbortController,r=setTimeout(()=>n.abort(),t);try{const o=await fetch(e,{signal:n.signal,headers:{Accept:"application/json"}}),i=await o.text(),s=i?JSON.parse(i):null;return o.ok?s:{responseOk:!1,payload:s}}finally{clearTimeout(r)}}async function bt(e,t=500){try{const n=await mt(`${nt(e)}/ping`,t);return gt(n)?{kind:"bridge-daemon",status:n}:{kind:"occupied"}}catch{return{kind:"available"}}}async function yt(e=12190,t=12200,n=500){var s;const r=[];for(let a=e;a<=t;a+=1)r.push(a);const o=await Promise.all(r.map(a=>bt(a,n))),i=((s=o[0])==null?void 0:s.kind)==="occupied";for(let a=0;a<o.length;a++){const u=o[a];if(u.kind==="bridge-daemon")return{daemonPort:r[a],candidatePort:r[a],defaultPortBusy:i,status:u.status}}for(let a=0;a<o.length;a++)if(o[a].kind==="available")return{daemonPort:null,candidatePort:r[a],defaultPortBusy:i,status:null};return{daemonPort:null,candidatePort:t,defaultPortBusy:!0,status:null}}function Le(e){return typeof e!="number"||Number.isNaN(e)?12190:Math.min(12200,Math.max(12190,Math.trunc(e)))}async function Re(){const t=(await chrome.storage.local.get(ae))[ae];return{servingEnabled:t===void 0?!0:!!t.servingEnabled,port:Le(t==null?void 0:t.port)}}async function pt(e){const t=await Re(),n={servingEnabled:e.servingEnabled??t.servingEnabled,port:Le(e.port??t.port)};return await chrome.storage.local.set({[ae]:n}),n}const I=new Map,_=new Map,K=new Set,Et=500,Se=10240,C=new Map,H=new Set,vt=200;async function De(e){try{await chrome.debugger.sendCommand({tabId:e},"Network.enable",{maxTotalBufferSize:1e7,maxResourceBufferSize:5e6})}catch{}K.add(e),I.has(e)||I.set(e,[])}async function We(e){K.delete(e);try{await chrome.debugger.sendCommand({tabId:e},"Network.disable")}catch{}}function $e(e){return I.get(e)||[]}function qe(e){I.set(e,[])}function St(e,t){I.has(e)||I.set(e,[]);const n=I.get(e);n.push(t),n.length>Et&&n.shift()}function kt(e,t,n){if(K.has(e))switch(t){case"Network.requestWillBeSent":{const r=n.request,o=n.requestId,i={id:o,url:r.url||"",method:r.method||"GET",type:n.type||r.type||"",timestamp:Date.now(),headers:r.headers||{}};_.set(o,{tabId:e,startTime:performance.now(),entry:i}),St(e,i);break}case"Network.responseReceived":{const r=n.requestId,o=n.response,i=_.get(r);i&&i.entry&&(i.entry.status=o.status,i.entry.statusText=o.statusText,i.entry.responseHeaders=o.headers);break}case"Network.loadingFinished":{const r=n.requestId,o=_.get(r);o&&o.entry&&(o.entry.duration=performance.now()-o.startTime,o.entry.bodyLength=n.encodedDataLength||0,_.delete(r));break}case"Network.loadingFailed":{const r=n.requestId,o=_.get(r);o&&o.entry&&(o.entry.error=n.errorText||"Unknown error",o.entry.duration=performance.now()-o.startTime,_.delete(r));break}}}async function Ue(e){try{await chrome.debugger.sendCommand({tabId:e},"Runtime.enable"),await chrome.debugger.sendCommand({tabId:e},"Log.enable")}catch{}H.add(e),C.has(e)||C.set(e,[])}async function Be(e){H.delete(e);try{await chrome.debugger.sendCommand({tabId:e},"Log.disable")}catch{}}function Fe(e){return C.get(e)||[]}function Je(e){C.set(e,[])}function re(e,t){C.has(e)||C.set(e,[]);const n=C.get(e);n.push(t),n.length>vt&&n.shift()}function At(e,t,n){var r,o,i,s,a,u;if(H.has(e)){if(t==="Runtime.consoleAPICalled"){const d=(n.args||[]).map(c=>c.value??c.description??JSON.stringify(c)).join(" ");re(e,{level:n.type||"log",text:d,timestamp:Date.now(),url:(i=(o=(r=n.stackTrace)==null?void 0:r.callFrames)==null?void 0:o[0])==null?void 0:i.url,lineNumber:(u=(a=(s=n.stackTrace)==null?void 0:s.callFrames)==null?void 0:a[0])==null?void 0:u.lineNumber});return}if(t==="Log.entryAdded"){const l=n.entry;re(e,{level:l.level||"info",text:l.text||JSON.stringify(l),timestamp:Date.now(),url:l.url,lineNumber:l.lineNumber,stackTrace:l.stackTrace});return}if(t==="Runtime.exceptionThrown"){const l=n.exceptionDetails,d=l==null?void 0:l.exception;re(e,{level:"error",text:`[Uncaught] ${(d==null?void 0:d.description)||(l==null?void 0:l.text)||"Unknown error"}`,timestamp:Date.now(),url:l==null?void 0:l.url,lineNumber:l==null?void 0:l.lineNumber})}}}async function je(e,t){try{const n=await chrome.debugger.sendCommand({tabId:e},"Network.getResponseBody",{requestId:t});return n.body?n.base64Encoded?`[base64: ${n.body.length} chars]`:n.body.length>Se?n.body.slice(0,Se)+"…[truncated]":n.body:null}catch{return null}}async function we(e){try{await chrome.debugger.sendCommand({tabId:e},"Accessibility.enable")}catch{}const n=(await chrome.debugger.sendCommand({tabId:e},"Accessibility.getFullAXTree",{max_depth:8})).nodes||[],r=[];let o=0;const i=new Map,s=new Map,a=[];for(const d of n){const c=d.nodeId;i.set(c,d);const w=d.parentId;w?(s.has(w)||s.set(w,[]),s.get(w).push(c)):a.push(c)}const u=new Set;function l(d){var W,me,be,ye;if(u.has(d))return null;u.add(d);const c=i.get(d);if(!c)return null;const w=((W=c.role)==null?void 0:W.value)||"unknown",M=((me=c.name)==null?void 0:me.value)||"",b={};if(c.properties)for(const $ of c.properties)((be=$.value)==null?void 0:be.value)!==void 0&&(b[$.name]=String($.value.value));(w==="link"||w==="button"||w==="textbox"||w==="searchbox"||w==="combobox"||w==="listbox"||w==="checkbox"||w==="radio"||w==="switch"||w==="menuitem"||w==="option"||w==="tab"||w==="slider"||b.focusable==="1")&&o++;const y={role:w,name:M.slice(0,120),nodeId:(ye=c.backendDOMNodeId)==null?void 0:ye.toString(),properties:Object.keys(b).length>0?b:void 0},g=s.get(d);return g&&g.length>0&&(y.children=g.map(l).filter($=>$!==null).slice(0,50)),y}for(const d of a.slice(0,5)){const c=l(d);c&&r.push(c)}return{nodes:r,interactiveCount:o}}function Tt(e){I.delete(e),C.delete(e),K.delete(e),H.delete(e);for(const[t,n]of _.entries())n.tabId===e&&_.delete(t)}const oe=Object.freeze(Object.defineProperty({__proto__:null,cleanupTab:Tt,clearConsoleMessages:Je,clearNetworkEntries:qe,disableConsoleMonitoring:Be,disableNetworkMonitoring:We,enableConsoleMonitoring:Ue,enableNetworkMonitoring:De,getAccessibilityTree:we,getConsoleMessages:Fe,getNetworkEntries:$e,getNetworkResponseBody:je,handleConsoleEvent:At,handleNetworkEvent:kt},Symbol.toStringTag,{value:"Module"}));let j=0;function _t(){return j}function It(){j+=1}function Ct(){j>0&&(j-=1)}async function Nt(e,t,n){if(n.includes("Selector not found"))try{const r=await f(e.tabId,t),o=await at(r,e.selector||e.code||"");if(o.length>0)return`${n}

💡 页面上的相似元素:
  ${o.join(`
  `)}`}catch{}return n}const Ot=new Set(["snapshot","observe","cookies","network_list","network_body","console_list","bounds","pdf","wait_for_selector"]),Pt=new Set(["exec","navigate","close-window","network_start","network_stop","console_start","console_stop"]);function xt(e){if(e.action==="close-window")return"workspace-write";if(e.action==="tabs"){const t=e.op;return t==="new"?"workspace-create":t==="list"||!t?"none":"write"}return e.action==="screenshot"?e.fullPage?"write":"read":Ot.has(e.action)?"read":Pt.has(e.action)?"write":"none"}const O=new Map,Mt="_ws:";function ze(e){const t=O.get(e);if(t)return t;const n={readers:0,writerActive:!1,writerWaiting:!1,waiters:[]};return O.set(e,n),n}function ke(e){return new Promise((t,n)=>{const r=ze(e);!r.writerActive&&!r.writerWaiting&&r.waiters.length===0?(r.readers+=1,t()):r.waiters.push({isWriter:!1,fn:()=>{r.readers+=1,t()}})})}function ce(e){const t=O.get(e);t&&(t.readers-=1,Ke(e))}function Xe(e){return new Promise((t,n)=>{const r=ze(e);r.readers===0&&!r.writerActive&&r.waiters.length===0?(r.writerActive=!0,t()):(r.writerWaiting=!0,r.waiters.push({isWriter:!0,fn:()=>{r.writerActive=!0,t()}}))})}function Ge(e){const t=O.get(e);t&&(t.writerActive=!1,t.writerWaiting=!1,Ke(e))}function Ke(e){const t=O.get(e);if(t){if(t.waiters.length===0){O.delete(e);return}if(t.waiters[0].isWriter){if(t.readers===0&&!t.writerActive){const n=t.waiters.shift();t.writerWaiting=t.waiters.some(r=>r.isWriter),n.fn()}return}if(t.readers===0&&!t.writerActive){for(;t.waiters.length>0&&!t.waiters[0].isWriter;)t.waiters.shift().fn();t.readers===0&&t.waiters.length===0&&O.delete(e)}}}function V(e){return Mt+e}async function Ae(e){const t=V(e);await Xe(t)}function Te(e){Ge(V(e))}async function Lt(e,t,n){const r=V(e);await ke(r);try{const o=`${e}:${t}`;n?await Xe(o):await ke(o)}catch(o){throw ce(r),o}}function Rt(e,t,n){const r=`${e}:${t}`;n?Ge(r):ce(r),ce(V(e))}const le=new Map;function B(e){return le.get(e)??0}function Dt(e){const t=(le.get(e)??0)+1;return le.set(e,t),t}async function Wt(e){It();try{return await $t(e)}finally{Ct()}}async function $t(e){const t=E(e.workspace??"human")?"human":e.workspace??"human";if(E(t)||await ut(t),E(t))return await q(e,t);const n=xt(e);if(n==="none")return await q(e,t);const r=B(t);if(n==="workspace-write"){await Ae(t);try{const s=await q(e,t);return s.ok&&(Dt(t),void 0),s}finally{Te(t)}}if(n==="workspace-create"){await Ae(t);try{return await q(e,t)}finally{Te(t)}}if(B(t)!==r)return{id:e.id,ok:!1,error:"ERR_WORKSPACE_GONE: Workspace was closed"};let o;try{o=e.tabId??await f(e.tabId,t)}catch{return{id:e.id,ok:!1,error:"ERR_WORKSPACE_GONE: Workspace no longer exists"}}if(B(t)!==r)return{id:e.id,ok:!1,error:"ERR_WORKSPACE_GONE: Workspace was closed"};const i=n==="write";await Lt(t,o,i);try{return B(t)!==r?{id:e.id,ok:!1,error:"ERR_WORKSPACE_GONE: Workspace was closed during lock wait"}:await q(e,t)}finally{Rt(t,o,i)}}async function q(e,t){try{switch(e.action){case"exec":return await qt(e,t);case"navigate":return await Ut(e,t);case"tabs":return await Bt(e,t);case"cookies":return await Ft(e);case"screenshot":return await Jt(e,t);case"close-window":return await jt(e,t);case"sessions":return await zt(e);case"network_start":return await Xt(e,t);case"network_stop":return await Gt(e,t);case"network_list":return await Kt(e,t);case"network_body":return await Ht(e,t);case"console_start":return await Vt(e,t);case"console_stop":return await Yt(e,t);case"console_list":return await Zt(e,t);case"snapshot":return await Qt(e,t);case"observe":return await en(e,t);case"pdf":return await tn(e,t);case"bounds":return await nn(e,t);case"wait_for_selector":return await rn(e,t);default:return{id:e.id,ok:!1,error:`Unknown action: ${e.action}`}}}catch(n){return{id:e.id,ok:!1,error:n instanceof Error?n.message:String(n)}}}async function qt(e,t){if(!e.code)return{id:e.id,ok:!1,error:"Missing code"};const n=await f(e.tabId,t);try{const r=await X(n,e.code);return{id:e.id,ok:!0,data:r}}catch(r){return{id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)}}}async function Ut(e,t){if(!e.url)return{id:e.id,ok:!1,error:"Missing url"};const n=e.url,r=E(t)&&e.tabId===void 0;let o=!1,i=null,s=null;if(await new Promise(l=>{let d=!1,c=null,w="";const M=()=>{chrome.tabs.onUpdated.removeListener(b),clearTimeout(D),c!==null&&clearTimeout(c),l()},b=(y,g)=>{i===null||y!==i||(g.url&&g.url!==w&&(d=!0,c!==null&&clearTimeout(c),c=setTimeout(M,2e3)),d&&g.status==="complete"&&M())};chrome.tabs.onUpdated.addListener(b);const D=setTimeout(()=>{chrome.tabs.onUpdated.removeListener(b),c!==null&&clearTimeout(c),o=!0,console.warn(`[chrisgao-bridge] Navigate to ${n} timed out after 15s`),l()},15e3);(async()=>{try{if(r){const y=await G(),g=await chrome.tabs.create({windowId:y,url:n,active:!0});if(!g.id)throw new Error("Failed to create tab");i=g.id,setTimeout(async()=>{try{const W=await chrome.tabs.get(i);W.url!=="about:blank"&&W.status==="complete"&&(chrome.tabs.onUpdated.removeListener(b),clearTimeout(D),l())}catch{}},150)}else i=await f(e.tabId,t),w=(await chrome.tabs.get(i)).url??"",await chrome.tabs.update(i,{url:n}),setTimeout(async()=>{try{const g=await chrome.tabs.get(i);g.url!==w&&g.status==="complete"&&(chrome.tabs.onUpdated.removeListener(b),clearTimeout(D),l())}catch{}},150)}catch(y){s=y instanceof Error?y.message:String(y),chrome.tabs.onUpdated.removeListener(b),clearTimeout(D),l()}})()}),i===null||s)return{id:e.id,ok:!1,error:s||"Navigation failed — no tab"};const u=await chrome.tabs.get(i);return{id:e.id,ok:!0,data:{title:u.title,url:u.url,tabId:i,timedOut:o}}}async function Bt(e,t){switch(e.op){case"list":{const r=(E(t)?await ne():await te(t)).map((o,i)=>({index:i,tabId:o.id,url:o.url,title:o.title,active:o.active}));return{id:e.id,ok:!0,data:r}}case"new":{const r={windowId:E(t)?await G():await xe(t),active:!0},o=e.url??(E(t)?void 0:J);o!==void 0&&(r.url=o);const i=await chrome.tabs.create(r);return{id:e.id,ok:!0,data:{tabId:i.id,url:i.url}}}case"close":{if(e.index!==void 0){const o=(E(t)?await ne():await te(t))[e.index];return o!=null&&o.id?(await chrome.tabs.remove(o.id),Ee(o.id),{id:e.id,ok:!0,data:{closed:o.id}}):{id:e.id,ok:!1,error:`Tab index ${e.index} not found`}}const n=await f(e.tabId,t);return await chrome.tabs.remove(n),Ee(n),{id:e.id,ok:!0,data:{closed:n}}}case"select":{if(e.index===void 0&&e.tabId===void 0)return{id:e.id,ok:!1,error:"Missing index or tabId"};if(e.tabId!==void 0){const o=await f(e.tabId,t);await chrome.tabs.update(o,{active:!0});const i=await chrome.tabs.get(o);return i.windowId&&await chrome.windows.update(i.windowId,{focused:!0}),{id:e.id,ok:!0,data:{selected:o}}}const r=(E(t)?await ne():await te(t))[e.index];return r!=null&&r.id?(await chrome.tabs.update(r.id,{active:!0}),r.windowId&&await chrome.windows.update(r.windowId,{focused:!0}),{id:e.id,ok:!0,data:{selected:r.id}}):{id:e.id,ok:!1,error:`Tab index ${e.index} not found`}}default:return{id:e.id,ok:!1,error:`Unknown tabs op: ${e.op}`}}}async function Ft(e){const t={};e.domain&&(t.domain=e.domain),e.url&&(t.url=e.url);const r=(await chrome.cookies.getAll(t)).map(o=>({name:o.name,value:o.value,domain:o.domain,path:o.path,secure:o.secure,httpOnly:o.httpOnly,expirationDate:o.expirationDate}));return{id:e.id,ok:!0,data:r}}async function Jt(e,t){const n=await f(e.tabId,t);try{const r=await it(n,{format:e.format,quality:e.quality,fullPage:e.fullPage});return{id:e.id,ok:!0,data:r}}catch(r){return{id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)}}}async function jt(e,t){if(E(t))return{id:e.id,ok:!0,data:{closed:!1,reason:"human workspace does not close the user's normal Chrome window"}};const o=((await chrome.storage.session.get("chrisgaoAutomationSessions")).chrisgaoAutomationSessions||{})[t];if(o){try{await chrome.windows.remove(o.windowId)}catch{}await Me(t)}return{id:e.id,ok:!0,data:{closed:!0}}}async function zt(e){const t=Date.now(),r=(await chrome.storage.session.get("chrisgaoAutomationSessions")).chrisgaoAutomationSessions||{},o=Object.entries(r),i=await Promise.all(o.map(async([s,a])=>{try{const u=await chrome.windows.get(a.windowId),l=await chrome.tabs.query({windowId:a.windowId});return{workspace:s,windowId:a.windowId,incognito:u.incognito,tabCount:l.filter(d=>S(d.url)).length,idleMsRemaining:Math.max(0,a.deadlineAt-t)}}catch{return{workspace:s,windowId:a.windowId,error:"window gone"}}}));return{id:e.id,ok:!0,data:i}}async function Xt(e,t){const n=await f(e.tabId,t);return await T(n),qe(n),await De(n),{id:e.id,ok:!0,data:{enabled:!0,tabId:n}}}async function Gt(e,t){const n=await f(e.tabId,t);return await We(n),{id:e.id,ok:!0,data:{enabled:!1,tabId:n}}}async function Kt(e,t){const n=await f(e.tabId,t),r=$e(n);return{id:e.id,ok:!0,data:{tabId:n,count:r.length,entries:r}}}async function Ht(e,t){if(!e.requestId)return{id:e.id,ok:!1,error:"Missing requestId"};const n=await f(e.tabId,t),r=await je(n,e.requestId);return{id:e.id,ok:!0,data:{requestId:e.requestId,body:r}}}async function Vt(e,t){const n=await f(e.tabId,t);return await T(n),Je(n),await Ue(n),{id:e.id,ok:!0,data:{enabled:!0,tabId:n}}}async function Yt(e,t){const n=await f(e.tabId,t);return await Be(n),{id:e.id,ok:!0,data:{enabled:!1,tabId:n}}}async function Zt(e,t){const n=await f(e.tabId,t),r=Fe(n);return{id:e.id,ok:!0,data:{tabId:n,count:r.length,messages:r}}}async function Qt(e,t){const n=await f(e.tabId,t);await T(n);try{const r=await we(n);return{id:e.id,ok:!0,data:{tabId:n,interactiveCount:r.interactiveCount,nodes:r.nodes}}}catch(r){return{id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)}}}async function en(e,t){const n=await f(e.tabId,t);await T(n);try{let r=function(l){var d;for(const c of l)c.role==="link"?i.push({name:c.name,url:((d=c.properties)==null?void 0:d.url)||""}):c.role==="button"?s.push(c.name):c.role==="textbox"||c.role==="searchbox"||c.role==="combobox"||c.role==="checkbox"||c.role==="radio"||c.role==="switch"?a.push({name:c.name,role:c.role}):(c.role==="menuitem"||c.role==="option"||c.role==="tab"||c.role==="slider")&&u.push({role:c.role,name:c.name}),c.children&&r(c.children)};const o=await we(n),i=[],s=[],a=[],u=[];return r(o.nodes),{id:e.id,ok:!0,data:{tabId:n,summary:{links:i.length,buttons:s.length,inputs:a.length,other:u.length},actions:{links:i.slice(0,50),buttons:s.slice(0,30),inputs:a.slice(0,30),other:u.slice(0,20)}}}}catch(r){return{id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)}}}async function tn(e,t){const n=await f(e.tabId,t);await T(n);try{await chrome.debugger.sendCommand({tabId:n},"Page.enable")}catch{}try{const r=await chrome.debugger.sendCommand({tabId:n},"Page.printToPDF",{landscape:!1,printBackground:!0,preferCSSPageSize:!0,marginTop:.4,marginBottom:.4,marginLeft:.4,marginRight:.4});return{id:e.id,ok:!0,data:{tabId:n,pdf:r.data,format:"base64"}}}catch(r){return{id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)}}}async function nn(e,t){if(!e.selector)return{id:e.id,ok:!1,error:"Missing selector"};const n=await f(e.tabId,t);await T(n);const r=await X(n,`(()=>{const el=document.querySelector(${JSON.stringify(e.selector)});if(!el)throw new Error('Selector not found');const r=el.getBoundingClientRect();return JSON.stringify({x:r.x,y:r.y,width:r.width,height:r.height,top:r.top,left:r.left,bottom:r.bottom,right:r.right,tag:el.tagName,visible:r.width>0&&r.height>0})})()`);try{return{id:e.id,ok:!0,data:JSON.parse(r)}}catch(o){const i=o instanceof Error?o.message:String(o);return{id:e.id,ok:!1,error:await Nt(e,t,i)}}}async function rn(e,t){const n=e.selector,r=typeof e.timeout=="number"&&e.timeout>0?e.timeout:1e4;if(!n)return{id:e.id,ok:!1,error:"Missing selector"};const o=await f(e.tabId,t);await T(o);const i=Date.now()+r;for(;Date.now()<i;){try{const s=await X(o,`(()=>{const el=document.querySelector(${JSON.stringify(n)});return el?JSON.stringify({found:true,tag:el.tagName,text:el.textContent?.trim()?.slice(0,80)}):null})()`),a=typeof s=="string"?JSON.parse(s):s;if(a!=null&&a.found)return{id:e.id,ok:!0,data:a}}catch(s){const a=s instanceof Error?s.message:String(s),u=a.toLowerCase();if(!u.includes("context")&&!u.includes("frame"))return{id:e.id,ok:!1,error:a}}await new Promise(s=>setTimeout(s,500))}return{id:e.id,ok:!1,error:`Timed out waiting for selector after ${r}ms: ${n}`}}let h=null,R=null,z=0,L=null,He="idle",Ve="Ready to start serving.",m=!1,v=12190,P=null;const on=console.log.bind(console),an=console.warn.bind(console),sn=console.error.bind(console);function fe(e,t){if(!(!h||h.readyState!==WebSocket.OPEN))try{const n=t.map(r=>typeof r=="string"?r:JSON.stringify(r)).join(" ");h.send(JSON.stringify({type:"log",level:e,msg:n,ts:Date.now()}))}catch{}}console.log=(...e)=>{on(...e),fe("info",e)};console.warn=(...e)=>{an(...e),fe("warn",e)};console.error=(...e)=>{sn(...e),fe("error",e)};async function cn(){const e=await chrome.storage.local.get("chrisgaoInstanceId");if(e.chrisgaoInstanceId)return e.chrisgaoInstanceId;const t=crypto.randomUUID();return await chrome.storage.local.set({chrisgaoInstanceId:t}),t}function Ye(){return!!(h&&h.readyState===WebSocket.OPEN)}function ln(){return m}function un(){return v}function he(e,t){return(e==null?void 0:e.daemonPort)!==null?`Local daemon detected on ${t}. Click Start Serving.`:e!=null&&e.defaultPortBusy&&t!==12190?`Default port 12190 is busy. Start Serving will use ${t}.`:`Ready to start serving on ${t}.`}function ie(e,t){return e!=null&&e.defaultPortBusy&&t!==12190?`Default port 12190 is busy. Waiting for local daemon on ${t}.`:`Waiting for local daemon on ${t}.`}function dn(e){return`Connecting to local daemon on ${e}.`}function _e(e){return`Serving on ${e}.`}function k(e,t){He=e,Ve=t}function wn(){return{servingEnabled:m,port:v,activeCommands:_t(),statusText:Ve,connectionState:He,defaultPortBusy:!!(P!=null&&P.defaultPortBusy)}}async function Ie(){return await Y(),m&&!Ye()&&U(),wn()}async function ge(){await pt({servingEnabled:m,port:v})}async function Y(){const e=await yt();P=e;const t=e.daemonPort??e.candidatePort;return v!==t&&(v=t,await ge()),m||k("idle",he(e,v)),e}function Ze(){if(!h){L=null;return}const e=h;h=null,L=null,e.onopen=null,e.onmessage=null,e.onclose=null,e.onerror=null;try{e.close()}catch{}}function ue(){R&&(clearTimeout(R),R=null)}function Ce(){if(!m||R)return;z+=1;const e=Math.min(rt*Math.pow(2,z-1),ot);R=setTimeout(()=>{R=null,U()},e)}async function U(){if(!m)return;const e=await Y(),t=v;if(Ye()&&L===t){k("connected",_e(t));return}if((h==null?void 0:h.readyState)===WebSocket.CONNECTING&&L===t)return;ue(),Ze(),e.daemonPort===t?k("connecting",dn(t)):k("waiting",ie(e,t));let n;try{const r=tt(t);n=new WebSocket(r)}catch{k("waiting",ie(e,t)),Ce();return}h=n,L=t,n.onopen=()=>{h===n&&(console.log("[chrisgao-bridge] Connected to daemon"),cn().then(r=>{n.send(JSON.stringify({type:"hello",role:"extension",version:chrome.runtime.getManifest().version,extensionId:chrome.runtime.id,instanceId:r,ts:Date.now()}))}),z=0,ue(),k("connected",_e(t)))},n.onmessage=async r=>{try{const o=JSON.parse(r.data);if(o.type==="ping"){try{n.send(JSON.stringify({type:"pong",ts:Date.now()}))}catch{}return}const s=await Wt(o);h==null||h.send(JSON.stringify(s))}catch(o){console.error("[chrisgao-bridge] Message handling error:",o)}},n.onclose=()=>{if(h===n){if(console.log("[chrisgao-bridge] Disconnected from daemon"),h=null,L=null,!m){k("idle",he(P,v));return}k("waiting",ie(P,v)),Ce()}},n.onerror=()=>{n.close()}}async function fn(){m=!0,await ge(),await U()}async function hn(){m=!1,await ge(),z=0,ue(),Ze(),await Y(),k("idle",he(P,v))}async function gn(){const e=await Re();m=e.servingEnabled,v=e.port,await Y(),m&&await U()}let de=!1,F=null;async function mn(){de||(de=!0,chrome.alarms.create("keepalive",{periodInMinutes:.5}),st(),ht(),await ft(),await gn(),console.log("[chrisgao-bridge] Extension initialized"))}async function Z(){F||(F=mn().catch(e=>{throw F=null,de=!1,e})),await F}chrome.runtime.onInstalled.addListener(()=>{Z()});chrome.runtime.onStartup.addListener(()=>{Z()});chrome.alarms.onAlarm.addListener(e=>{e.name==="keepalive"&&Z().then(()=>{ln()&&U()})});chrome.runtime.onMessage.addListener((e,t,n)=>(Z().then(async()=>{if((e==null?void 0:e.type)==="chrisgao:get-popup-state"){n(await Ie());return}if((e==null?void 0:e.type)==="chrisgao:set-serving"){e.enabled?await fn():await hn(),n(await Ie());return}n(null)}).catch(r=>{const o={servingEnabled:!1,port:un(),activeCommands:0,statusText:r instanceof Error?r.message:"Failed to initialize Chrisgao.",connectionState:"error",defaultPortBusy:!1};n(o)}),!0));
