0\rm4'153import{t as e,a as t,b as n,r as s,g as a,f as o,c as r,d as i,n as c,e as l,h as d,i as h,u,s as m,j as p,k as g,l as f,m as w,o as y,p as _,q as b,v as T,S as I,w as k,x as C,y as S,z as v,A as E,B as A,C as N,D as M,E as R,F as U,G as O,H as D,I as x,J as L,K as P,L as $,M as H,N as F,O as q,P as B,Q as G,R as j}from"./mcpPermissions-CJK8I7C7.js";import{C as K,a as W,b as z}from"./conway-storage-gJvF6Skp.js";import{r as Y}from"./onboarding-prompts-CWLEgoC0.js";import"./index-BBLsn8fp.js";var J=globalThis.AbortController,X=globalThis.TextDecoder;function Q(e){return JSON.parse(e.trim())}var V={toolCallTimeoutMs:12e4,toolCallWarningMs:6e4,idleSessionTimeoutMs:3e5,heartbeatIntervalMs:1e4,heartbeatTimeoutMs:25e3,healthProbeTimeoutMs:5e3,connectTimeoutMs:3e4,wakeReconnectTimeoutMs:2e4},Z={initialDelayMs:1e3,maxDelayMs:3e4,multiplier:2,jitterFactor:.1,maxAttempts:0,resetAfterConnectedMs:6e4};function ee(e){return"object"==typeof e&&null!==e&&"string"==typeof e.layer&&"string"==typeof e.code&&"string"==typeof e.message}function te(e,t={}){return function n(s){const a=(n,a,o,r,i)=>{e({ts:Date.now(),layer:"sdk",level:n,cat:a,event:o,msg:r,...i&&{data:i},...s&&{corr:s},ctx:t})};return{debug:(e,t,n,s)=>a("debug",e,t,n,s),info:(e,t,n,s)=>a("info",e,t,n,s),warn:(e,t,n,s)=>a("warn",e,t,n,s),error:(e,t,n,s)=>a("error",e,t,n,s),withCorr:e=>n(e)}}(void 0)}var ne=class e extends Error{status;conwayError;constructor(e,t,n){super(t),this.name="ConwayHttpError",this.status=e,this.conwayError=n}static async fromResponse(t,n){const s=await t.text().catch(()=>"");try{const a=JSON.parse(s);if(ee(a.error))return new e(t.status,a.error.message,a.error);if("string"==typeof a.error){const s={layer:"server",code:n,message:a.error,data:{status:t.status}};return new e(t.status,a.error,s)}}catch{}const a=(t.headers.get("content-type")??"").toLowerCase(),o=s.replace(/^\uFEFF/,""),r=a.startsWith("text/html")||/^\s*<(?:!doctype|html)\b/i.test(o),i=[t.status,t.statusText].filter(Boolean).join(" ");let c;c=r?`Backend unavailable (HTTP ${i} from proxy/CDN). Please retry.`:s.length>300?`${s.slice(0,300)}… (HTTP ${i})`:s||i;const l={layer:"sdk",code:n,message:c,data:{status:t.status,proxyBody:s?s.slice(0,500):void 0}};return new e(t.status,l.message,l)}},se=class{url;headers;reconnectConfig;timeoutConfig;onMessage;onStateChange;onError;onReconnected;onContainerChanged;slog;fetchFn;credentials;macrotaskYieldEvery;state="init";attempt=0;currentBackoffMs=0;connectedAt=null;abortController=null;backoffAbort=null;resetTimer=null;lastServerSeq=0;lastHeartbeatAt=null;heartbeatChecker=null;intentionalDisconnect=!1;constructor(e){this.url=e.url,this.headers=e.headers||{},this.reconnectConfig={...Z,...e.reconnectConfig},this.timeoutConfig={...V,...e.timeoutConfig},this.onMessage=e.onMessage,this.onStateChange=e.onStateChange,this.onError=e.onError,this.onReconnected=e.onReconnected,this.onContainerChanged=e.onContainerChanged,this.slog=e.log?te(e.log):void 0,this.fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this.credentials=e.credentials,this.macrotaskYieldEvery=e.macrotaskYieldEvery??0}async connect(){for(this.intentionalDisconnect=!1;"failed"!==this.state;){if(this.intentionalDisconnect)return void this.slog?.info("stream","user_disconnect","Connection aborted by user");try{if(this.setState("connecting"),this.abortController=new J,this.attempt>0&&this.onReconnected&&(this.slog?.info("stream","re_registering_pre_stream","Re-registering before stream opens"),await this.onReconnected()),this.intentionalDisconnect)return void this.slog?.info("stream","user_disconnect","Disconnected during re-register");this.slog?.info("stream","connecting",`Connecting (attempt ${this.attempt+1})`,{url:this.url,attempt:this.attempt+1});const e=setTimeout(()=>{this.slog?.warn("stream","connect_timeout",`No response headers after ${this.timeoutConfig.connectTimeoutMs}ms`),this.abortController?.abort()},this.timeoutConfig.connectTimeoutMs);let t;try{t=await this.fetchFn(this.url,{signal:this.abortController.signal,credentials:this.credentials,headers:{Accept:"application/x-ndjson",...this.headers}})}finally{clearTimeout(e)}if(!t.ok){if(410===t.status){let e;try{e=(await t.json()).current_container_id||void 0}catch{}return void(e&&this.onContainerChanged?(this.slog?.info("stream","container_replaced","Container replaced",{newContainerId:e}),this.setState("init"),this.onContainerChanged(e)):(this.slog?.warn("stream","container_gone","Container gone (410), no replacement"),this.setState("failed")))}throw await ne.fromResponse(t,"STREAM_CONNECT_FAILED")}if(!t.body)throw new Error("No response body");if(this.setState("connected"),this.connectedAt=Date.now(),this.lastHeartbeatAt=Date.now(),this.startHeartbeatChecker(),this.resetTimer=setTimeout(()=>{"connected"===this.state&&(this.attempt=0,this.currentBackoffMs=0,this.slog?.debug("stream","backoff_reset","Connection stable, reset backoff"))},this.reconnectConfig.resetAfterConnectedMs),await this.processStream(t),this.slog?.info("stream","stream_ended","Stream ended"),this.stopHeartbeatChecker(),this.resetTimer&&(clearTimeout(this.resetTimer),this.resetTimer=null),this.intentionalDisconnect)return void this.slog?.info("stream","user_disconnect","Connection aborted by user");if(this.attempt++,this.reconnectConfig.maxAttempts>0&&this.attempt>=this.reconnectConfig.maxAttempts)return void this.setState("failed");if(this.setState("backing_off"),await this.backoff(),this.intentionalDisconnect)return void this.slog?.info("stream","user_disconnect","Disconnected during backoff")}catch(e){if(this.stopHeartbeatChecker(),this.resetTimer&&(clearTimeout(this.resetTimer),this.resetTimer=null),this.intentionalDisconnect)return void this.slog?.info("stream","user_disconnect","Connection aborted by user");const t=e;if(this.slog?.warn("stream","connection_error",t?.message??String(t),{status:t?.status}),this.onError?.(t instanceof Error?t:new Error(String(t),{cause:t})),this.attempt++,this.reconnectConfig.maxAttempts>0&&this.attempt>=this.reconnectConfig.maxAttempts)throw this.setState("failed"),t;this.setState("backing_off"),await this.backoff()}}}disconnect(){this.slog?.info("stream","disconnecting","Disconnecting"),this.intentionalDisconnect=!0,this.stopHeartbeatChecker(),this.resetTimer&&(clearTimeout(this.resetTimer),this.resetTimer=null),this.abortController&&(this.abortController.abort(),this.abortController=null),this.backoffAbort?.abort(),this.setState("init"),this.attempt=0,this.currentBackoffMs=0}getState(){return this.state}getAttempt(){return this.attempt}isConnected(){return"connected"===this.state}getLastServerSeq(){return this.lastServerSeq}getUrl(){return this.url}setUrl(e){this.url=e}setHeaders(e){for(const[t,n]of Object.entries(e))void 0===n?delete this.headers[t]:this.headers[t]=n}setState(e){this.state!==e&&(this.slog?.debug("stream","state_change",`${this.state} → ${e}`,{from:this.state,to:e,attempt:this.attempt}),this.state=e,this.onStateChange?.(e,this.attempt))}async processStream(e){const t=e.body.getReader();let n=0;try{for await(const e of async function*(e){const t=new X;let n="",s=0;for(;;){const{done:o,value:r}=await e.read();if(o)break;if(n+=t.decode(r,{stream:!0}),n.length>10485760){n="";continue}const i=n.split("\n");n=i.pop()||"";for(const e of i){const t=e.trim();if(t)try{yield Q(t),s=0}catch(a){if(s++,s>=3)throw new Error("Stream corrupted: 3 consecutive JSONL parse failures")}}}if(n.trim())try{yield Q(n)}catch{}}(t))"number"==typeof e.seq&&(this.lastServerSeq=e.seq),"heartbeat"===e.type&&(this.lastHeartbeatAt=Date.now()),this.onMessage(e),this.macrotaskYieldEvery>0&&++n%this.macrotaskYieldEvery===0&&await new Promise(e=>setTimeout(e,0))}finally{t.releaseLock()}}async backoff(){if(this.intentionalDisconnect)return;const e=Math.min(this.currentBackoffMs,this.reconnectConfig.maxDelayMs),t=e*this.reconnectConfig.jitterFactor*(2*Math.random()-1),n=Math.max(0,Math.round(e+t));this.currentBackoffMs=0===this.currentBackoffMs?Math.max(this.reconnectConfig.initialDelayMs,100):Math.min(this.currentBackoffMs*this.reconnectConfig.multiplier,this.reconnectConfig.maxDelayMs),this.slog?.info("stream","backing_off",`Backing off for ${n}ms`,{delayMs:n,attempt:this.attempt}),this.backoffAbort=new J;const s=this.backoffAbort.signal;try{await new Promise(e=>{const t=setTimeout(e,n);s.addEventListener("abort",()=>{clearTimeout(t),e()},{once:!0})})}finally{this.backoffAbort=null}}startHeartbeatChecker(){this.stopHeartbeatChecker(),this.heartbeatChecker=setInterval(()=>{if("connected"!==this.state)return;const e=Date.now(),t=e-(this.lastHeartbeatAt||e);t>this.timeoutConfig.heartbeatTimeoutMs&&(this.slog?.warn("stream","heartbeat_timeout","Heartbeat timeout",{msSinceLast:t}),this.abortController&&this.abortController.abort())},this.timeoutConfig.heartbeatIntervalMs)}stopHeartbeatChecker(){this.heartbeatChecker&&(clearInterval(this.heartbeatChecker),this.heartbeatChecker=null)}};function ae(){try{if("undefined"!=typeof navigator&&navigator.userAgent)return navigator.userAgent;const e=globalThis.process;if(e?.versions?.bun)return`bun/${e.versions.bun} (${e.platform??"unknown"})`;if(e?.versions?.node)return`node/${e.versions.node} (${e.platform??"unknown"})`}catch{}return"unknown"}function oe(e){return"handler"in e&&"definition"in e}function re(e){const t=[],n={};for(const s of e)oe(s)?(t.push(s.definition),n[s.name]=s.handler):t.push(s);return{definitions:t,handlers:n}}var ie=class e{hostUrl;clientName;clientDescription;displayName;welcomeMessage;tools;toolHandlers;reconnectConfig;timeoutConfig;logSink;slog;customHeaders;credentials;bearerToken;fetchFn;singleton;expectTools;macrotaskYieldEvery;wantsDeltas;healthHandler;clientId;connectedAt=null;destroyed=!1;stream=null;connected=!1;streamState=null;lastSeenSeq=0;listeners=new Map;constructor(e){this.clientId=e.resumeClientId??null,this.fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this.bearerToken="bearer"===e.auth?.kind?e.auth.token:void 0,this.hostUrl=e.hostUrl,this.customHeaders=e.customHeaders??{},this.credentials=e.credentials,this.clientName=e.clientName,this.clientDescription=e.clientDescription??`${this.clientName} client`,this.displayName=e.displayName,this.welcomeMessage=e.welcomeMessage;const{definitions:t,handlers:n}=re(e.tools??[]);this.tools=t,this.toolHandlers=n,this.singleton=e.singleton,this.expectTools=e.expectTools,this.macrotaskYieldEvery=e.macrotaskYieldEvery,this.wantsDeltas=e.wantsDeltas??!1,this.healthHandler=e.healthHandler??(()=>({ok:!0,name:this.clientName,version:"0.2.0",platform:ae()})),this.reconnectConfig=e.reconnectConfig,this.timeoutConfig=e.timeoutConfig,this.logSink=e.log,this.slog=e.log?te(e.log):void 0}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n));const s=t;return n.add(s),()=>{n.delete(s)}}once(e){return new Promise((t,n)=>{const s=this.on(e,(...e)=>{a(),s(),t(e)}),a=this.on("disconnected",()=>{s(),a(),n(new Error(`Disconnected while waiting for '${String(e)}'`))})})}emit(e,...t){const n=this.listeners.get(e);if(n&&0!==n.size)for(const a of[...n])try{a(...t)}catch(s){this.slog?.error("error","listener_threw",`Listener threw on '${String(e)}'`,{event:String(e),error:s?.message??String(s)})}else if("error"===e){const e=t[0];this.slog?.error("error","unhandled_error_event",e?.message??String(e))}}async connect(){if(this.stream)throw new Error("Already connected. Call disconnect() first.");const e=await this.register();if(this.clientId=e.client_id,this.destroyed)return this.slog?.info("conn","connect_aborted_destroyed","destroy() ran during register; not opening stream"),this.destroy(),e;this.slog?.info("conn","registered",`registered as ${this.clientId}`,{clientId:this.clientId,tools:e.registered_tools});const t=this.wantsDeltas?"&deltas=1":"",n=`/stream?client_id=${this.clientId}${t}`,s=`${this.hostUrl}${n}`;return this.stream=new se({url:s,headers:{"X-Client-Id":this.clientId,...this.bearerToken?{Authorization:`Bearer ${this.bearerToken}`}:{},...this.customHeaders},onMessage:e=>this.handleMessage(e),onStateChange:(e,t)=>this.handleStateChange(e,t),onError:e=>{this.slog?.warn("stream","stream_error",e?.message??String(e)),e instanceof ne&&(this.checkAuth(e.status),e.conwayError&&this.emit("conwayError",e.conwayError,"main")),this.emit("error",e instanceof Error?e:new Error(String(e),{cause:e}))},onReconnected:()=>this.handleReconnected(),onContainerChanged:e=>{this.slog?.info("conn","container_changed","container changed",{newContainerId:e}),this.connected=!1,this.streamState=null,this.stream=null,this.emit("containerChanged",e),this.emit("disconnected")},log:this.logSink,fetch:this.fetchFn,credentials:this.credentials,macrotaskYieldEvery:this.macrotaskYieldEvery,reconnectConfig:{maxAttempts:0,...this.reconnectConfig},timeoutConfig:this.timeoutConfig}),this.stream.connect().catch(e=>{this.slog?.error("stream","stream_fatal",e?.message??String(e)),e instanceof ne&&(this.checkAuth(e.status),e.conwayError&&this.emit("conwayError",e.conwayError)),this.emit("error",e instanceof Error?e:new Error(String(e),{cause:e}))}),e}disconnect(){this.slog?.info("conn","disconnecting","disconnecting"),this.stream?.disconnect(),this.stream=null,this.connected=!1,this.streamState=null,this.emit("disconnected")}destroy(){if(this.destroyed=!0,this.clientId){const e="/unregister",t=this.getAuthHeaders();try{this.fetchFn(`${this.hostUrl}${e}`,{method:"POST",headers:{"Content-Type":"application/json","X-Client-Id":this.clientId,...t},body:JSON.stringify({client_id:this.clientId,connected_at:this.connectedAt??0}),credentials:this.credentials,keepalive:!0}).catch(()=>{})}catch{}}this.disconnect(),this.listeners.clear()}isConnected(){return this.connected&&(this.stream?.isConnected()??!1)}getStreamState(){return this.streamState}getClientId(){return this.clientId}setWantsDeltas(e){this.wantsDeltas=e}setAuth(e){this.bearerToken="bearer"===e.kind?e.token:void 0,this.bearerToken&&this.stream?.setHeaders({Authorization:`Bearer ${this.bearerToken}`})}async sendChat(e){if(!e.message&&!e.parts?.length)throw new Error("sendChat requires at least message or parts");if("failed"===this.streamState||null===this.streamState)throw new Error("Cannot send chat: connection failed or not established");const{corr:t,...n}={interrupt:!0,...e},s=await this.post("/sandbox/chat",n,t);if(!s.ok)throw await ne.fromResponse(s,"SEND_CHAT_FAILED")}async uploadFile(e,t){if("failed"===this.streamState||null===this.streamState)throw new Error("Cannot upload file: connection failed or not established");t?.signal?.throwIfAborted();const n=new Uint8Array(await e.arrayBuffer());let s;const a=globalThis.Buffer;if(a)s=a.from(n).toString("base64");else{const e=32768;let t="";for(let s=0;se.name);const s=await this.patch(`/clients/${encodeURIComponent(this.clientId)}/tools`,{tools:t});if(!s.ok)throw await ne.fromResponse(s,"UPDATE_TOOLS_FAILED");return(await s.json()).registered_tools||[]}getTools(){return[...this.tools]}async post(e,t,n,s){const a=e,o=JSON.stringify(t),r=this.getAuthHeaders(),i=await this.fetchFn(`${this.hostUrl}${a}`,{method:"POST",headers:{"Content-Type":"application/json",...this.clientId?{"X-Client-Id":this.clientId}:{},...n?{"X-Conway-Correlation-Id":n}:{},...r},body:o,credentials:this.credentials,signal:s});return this.checkAuth(i.status),i}async patch(e,t){const n=e,s=JSON.stringify(t),a=this.getAuthHeaders(),o=await this.fetchFn(`${this.hostUrl}${n}`,{method:"PATCH",headers:{"Content-Type":"application/json",...this.clientId?{"X-Client-Id":this.clientId}:{},...a},body:s,credentials:this.credentials});return this.checkAuth(o.status),o}async get(e){const t=e,n=this.getAuthHeaders(),s=await this.fetchFn(`${this.hostUrl}${t}`,{method:"GET",headers:{...this.clientId?{"X-Client-Id":this.clientId}:{},...n},credentials:this.credentials});return this.checkAuth(s.status),s}getAuthHeaders(){return{...this.bearerToken?{Authorization:`Bearer ${this.bearerToken}`}:{},...this.customHeaders}}checkAuth(e){401===e&&this.emit("authExpired")}async register(){this.slog?.info("conn","registering","registering with host");const e={client_name:this.clientName,client_id:this.clientId,client_description:this.clientDescription,...void 0!==this.displayName?{display_name:this.displayName}:{},...void 0!==this.singleton?{singleton:this.singleton}:{},tools:this.tools,welcome_message:this.welcomeMessage,expect_tools:this.expectTools};this.expectTools=void 0;const t=JSON.stringify(e),n=this.getAuthHeaders(),s=new J,a=this.timeoutConfig?.connectTimeoutMs??V.connectTimeoutMs,o=setTimeout(()=>s.abort(),a);let r;try{r=await this.fetchFn(`${this.hostUrl}/clients`,{method:"POST",headers:{"Content-Type":"application/json",...n},body:t,credentials:this.credentials,signal:s.signal})}finally{clearTimeout(o)}if(this.checkAuth(r.status),!r.ok)throw await ne.fromResponse(r,"REGISTER_FAILED");return r.json()}async handleReconnected(){if(this.destroyed)return;this.slog?.info("conn","re_registering","re-registering after reconnection");const e=await this.register();if(this.destroyed)return this.clientId=e.client_id,void this.destroy();const t=e.client_id;if(this.slog?.info("conn","re_registered",`re-registered as ${t}`,{clientId:t,tools:e.registered_tools}),t!==this.clientId){this.slog?.warn("conn","client_id_changed","client_id changed",{old:this.clientId,new:t});const e=this.clientId;if(this.clientId=t,this.stream){const n=n=>n.replace(`client_id=${e}`,`client_id=${t}`);this.stream.setUrl(n(this.stream.getUrl())),this.stream.setHeaders({"X-Client-Id":t}),this.slog?.info("conn","reconnect_new_identity","url+headers updated for new client_id; next fetch uses new identity")}}}static HIGH_FREQ_TYPES=new Set(["input_json_delta","content_block_start"]);handleMessage(t){switch(e.HIGH_FREQ_TYPES.has(t.type)||this.slog?.debug("stream","msg_received",t.type,{seq:t.seq}),"connected"!==t.type&&t.seq!==this.lastSeenSeq+1&&(this.slog?.warn("stream","seq_gap",`seq gap: expected ${this.lastSeenSeq+1}, got ${t.seq}`,{expected:this.lastSeenSeq+1,received:t.seq}),this.emit("seqGap",this.lastSeenSeq+1,t.seq)),this.lastSeenSeq=t.seq,t.type){case"connected":this.slog?.info("conn","stream_connected","stream connected",{containerId:t.container_id}),this.connected=!0,this.connectedAt=t.connected_at??null,this.emit("connected",t.client_id,t.container_id);break;case"heartbeat":case"tool_result":break;case"health_probe":this.handleHealthProbe(t.probe_id);break;case"tool":this.emit("toolInfo",t.name,t.input,t.agentId??"main");break;case"tool_result_info":this.emit("toolResultInfo",t.result,t.agentId??"main");break;case"sampling_started":this.emit("samplingStarted",t.agentId??"main");break;case"server_tool_call":this.emit("serverToolCall",{name:t.name,input:t.input,toolUseId:t.tool_use_id},t.agentId??"main");break;case"tool_call":this.handleToolCall({request_id:t.request_id,tool_name:t.tool_name,input:t.input});break;case"context":this.emit("context",{tokenCount:t.tokenCount,rawTokenCount:t.rawTokenCount,snipsApplied:t.snipsApplied,snipsRegistered:t.snipsRegistered,renderedMessageCount:t.renderedMessageCount,rawMessageCount:t.rawMessageCount,tokenBudget:t.tokenBudget});break;case"error":{const e=t,n=ee(e.error)?e.error:function(e,t,n){if(ee(e))return{layer:t,code:n,message:e.message,cause:e};if(function(e){return"object"==typeof e&&null!==e&&"number"==typeof e.status&&"error"in e}(e)){const s=e.error?.error;return{layer:t,code:n,message:s?.message??e.message,data:{status:e.status,requestId:e.requestID??e.error?.request_id,apiErrorType:s?.type}}}return e instanceof Error?{layer:t,code:n,message:e.message}:{layer:t,code:n,message:String(e)}}(new Error(e.message??JSON.stringify(e)),"server","SERVER_ERROR");this.emit("conwayError",n,t.agentId??"main"),this.emit("error",new Error(n.message));break}case"restart":this.emit("restart");break;case"goodbye":this.slog?.info("conn","server_goodbye",`server goodbye: ${t.reason}`,{reason:t.reason}),this.emit("goodbye",t.reason),"replaced_by_same_host"===t.reason&&this.disconnect();break;case"shutdown":this.slog?.info("conn","server_shutdown",`server shutdown: ${t.reason}`,{reason:t.reason,waitMs:t.wait_ms}),this.emit("shutdown",t.reason,t.wait_ms);break;case"status_line":this.emit("statusLine",t.text,t.agentId??"main");break;case"agents_updated":case"agentsUpdated":{const e=t.agents??[];e.length>0?this.emit("agentsUpdated",e):(this.slog?.debug("agent","agents_updated_empty","empty payload, fetching agents"),this.getAgents().then(e=>this.emit("agentsUpdated",e)).catch(e=>{this.slog?.error("error","agents_fetch_failed",e?.message??String(e))}));break}case"clients_changed":this.emit("clientsChanged",t.clients,t.serverTools??[]);break;case"fork_created":this.emit("forkCreated",t.agentId,t.label,t.createdAt);break;case"fork_joined":this.emit("forkJoined",t.agentId,t.summary);break;case"forks_snapshot":this.emit("forksSnapshot",t.forks);break;case"extensions_changed":this.emit("extensionsChanged",t.extension);break;case"input_json_delta":this.emit("inputJsonDelta",t.delta,t.index,t.agentId??"main");break;case"content_block_start":this.emit("contentBlockStart",t.blockType,t.index,t.name,t.agentId??"main");break;case"sampling_ended":this.emit("samplingEnded",t.agentId??"main");break;default:{const e=t;if("log"===e.type&&e.entry){this.emit("serverLog",e.entry);break}this.emit("unhandledMessage",e);break}}}async handleHealthProbe(e){let t;try{t=await this.healthHandler()}catch(n){t={ok:!1,error:n?.message??String(n)}}this.slog?.debug("conn","health_probe_responding","health_probe",{probeId:e,ok:t.ok});try{await this.post("/health_response",{probe_id:e,result:t})}catch(n){this.slog?.warn("conn","health_response_send_failed",n?.message??String(n),{probeId:e})}}async handleToolCall(e){let t;this.slog?.info("tool","tool_executing",`executing: ${e.tool_name}`,{toolName:e.tool_name,requestId:e.request_id});let n,s=!0;const a=this.toolHandlers[e.tool_name];if(a)try{t=await a(e.input)}catch(o){s=!1,n=o?.message??String(o)}else s=!1,n=`Unknown tool: ${e.tool_name}`;try{await this.post("/tool-result",{request_id:e.request_id,success:s,result:s?t:void 0,error:s?void 0:n}),this.slog?.info("tool","tool_result_sent",`result sent: ${e.tool_name}`,{toolName:e.tool_name,success:s})}catch(o){this.slog?.error("error","tool_result_send_failed",o?.message??String(o),{toolName:e.tool_name})}}handleStateChange(e,t){this.streamState=e,this.slog?.debug("stream","state",`state: ${e}`,{state:e,attempt:t}),this.emit("stateChange",e,t),"connected"===e?this.connected=!0:"backing_off"===e?(this.connected=!1,this.emit("reconnecting",t)):"connecting"===e&&t>0?this.emit("reconnecting",t):"failed"===e&&(this.connected=!1,this.emit("disconnected"))}};async function ce(e){const t=await e.text().catch(()=>""),n=t.slice(0,200),{status:s}=e;if(404===s)return{kind:"not_rolled_out"};if(403===s){try{const e=JSON.parse(t);if("no_container_for_headless_client"===e.error)return{kind:"headless_no_container"};if("headless_container_asleep"===e.error)return{kind:"headless_container_asleep"}}catch{}return{kind:"client_error",status:s,message:n}}return 408===s||429===s||s>=500?{kind:"server_error",status:s,message:n}:{kind:"client_error",status:s,message:n}}const le=[e,t,n,s,a,o,r,i,c,l,d,h,u,m,p];function de(e){return async t=>{const n=t??{},s="number"==typeof n.tabId?n.tabId:void 0,a="number"==typeof n.tabGroupId?n.tabGroupId:void 0,o=await g({toolName:e,args:n,tabId:s,tabGroupId:a,source:"bridge"});return void 0===o?o:{content:o.content,..."is_error"in o&&void 0!==o.is_error&&{is_error:o.is_error}}}}function he(e,t){const n=t;return n.input_schema?{name:n.name??e.name,description:n.description??e.description,input_schema:n.input_schema}:{name:e.name,description:e.description,input_schema:{type:"object",properties:e.parameters}}}const ue="https://claude.ai";let me=ue;function pe(e){return{"x-organization-uuid":e}}async function ge(e,t,n,s){const a=new AbortController,o=setTimeout(()=>a.abort(),n),r={Authorization:`Bearer ${s}`,...t.headers};try{return await fetch(e,{...t,headers:r,signal:a.signal,credentials:"omit"})}finally{clearTimeout(o)}}async function fe(e,t){const n=await async function(e){const t=e.fetch??fetch,n={client:{name:e.clientName},...e.forceNew?{force_new:!0}:{}};let s,a;try{s=await t(`${e.baseUrl}/sandbox/containers/create`,{method:"POST",headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(n),signal:e.signal})}catch(o){return e.signal?.aborted?{ok:!1,failure:{kind:"aborted"}}:{ok:!1,failure:{kind:"network",error:o}}}if(!s.ok)return{ok:!1,failure:await ce(s)};try{a=await s.json()}catch(o){return{ok:!1,failure:{kind:"network",error:o}}}return{ok:!0,containerId:a.container_id,webhookUrl:a.webhook_url,healthError:a.health_error}}({baseUrl:me,clientName:"claude-in-chrome",fetch:(e,n)=>ge(e.toString(),n??{},3e4,t),headers:pe(e)});return n.ok?(n.containerId,n.containerId):(n.failure.kind,null)}async function we(){me=await async function(){const e=await w(K.HOST_URL);return e&&/^https:\/\//i.test(e)?e.replace(/\/+$/,""):ue}();const e=await async function(){return await y()||null}();if(!e)return null;const t=await async function(e){const t=await w(K.ORG_UUID);if(t)return t;const{apiBaseUrl:n}=b(),s=`${n}/api/oauth/profile`;try{const t=await ge(s,{method:"GET"},1e4,e);if(t.status,!t.ok)return 401===t.status||t.status,null;const n=await t.json(),a=n.organization?.uuid;return a?(n.organization,await _(K.ORG_UUID,a),a):null}catch(a){return a.message,null}}(e);if(!t)return null;const n=await fe(t,e);return n?function(e,t,n){return{hostUrl:`${me}/sandbox/proxy/my`,orgUuid:t,containerId:e,bearerToken:n}}(n,t,e):null}async function ye(){if("local"===await async function(){const e=await w(K.MODE);return"local"===e||"remote"===e?e:"remote"}())return async function(){return{hostUrl:await w(K.HOST_URL)||"http://localhost:3000",customHeaders:{},mode:"local"}}();const e=await async function(){const e=await we();return e?{hostUrl:e.hostUrl,customHeaders:{"x-organization-uuid":e.orgUuid},bearerToken:e.bearerToken,containerId:e.containerId,mode:"remote"}:null}();return e||null}function _e(e){return"conwayNotificationUrl:"+e}const be={get_tabs_summary:async function(){return{tabs:(await chrome.tabs.query({})).map(e=>({id:e.id??-1,windowId:e.windowId,groupId:e.groupId,url:e.url??"",title:e.title??"",active:e.active,pinned:e.pinned}))}},open_tab:async function(e){const{url:t,background:n}=e;if(!t||"string"!=typeof t)throw new Error("url is required");const s=/^https?:\/\//i.test(t)?t:`https://${t}`,a=await chrome.tabs.create({url:s,active:!n});return{tab_id:a.id??-1,url:a.url??s}},close_tab:async function(e){const{tab_id:t}=e;if("number"!=typeof t)throw new Error("tab_id (number) is required");return await chrome.tabs.remove(t),{closed:!0}},show_notification:async function(e){const{title:t,body:n,url:s}=e;if(!t||!n)throw new Error("title and body are required");const a=`conway-${crypto.randomUUID()}`;return s&&await chrome.storage.session.set({[_e(a)]:s}),await chrome.notifications.create(a,{type:"basic",iconUrl:chrome.runtime.getURL("icon-128.png"),title:t,message:n}),{notification_id:a}}},Te=[{name:"get_tabs_summary",description:"Returns a summary of all open browser tabs (id, url, title, active, pinned, window and group membership). Use this to understand what the user is currently browsing before taking any action.",input_schema:{type:"object",properties:{}}},{name:"open_tab",description:"Open a new browser tab with the specified URL. Set background=true to open without switching focus.",input_schema:{type:"object",properties:{url:{type:"string",description:"URL to open (with or without protocol)"},background:{type:"boolean",description:"If true, open in background without focusing the tab"}},required:["url"]}},{name:"close_tab",description:"Close a browser tab by its numeric ID.",input_schema:{type:"object",properties:{tab_id:{type:"number",description:"The numeric tab ID to close"}},required:["tab_id"]}},{name:"show_notification",description:"Show a Chrome notification to the user. Optionally include a URL to open when the notification is clicked.",input_schema:{type:"object",properties:{title:{type:"string",description:"Notification title"},body:{type:"string",description:"Notification body text"},url:{type:"string",description:"Optional URL to open when the notification is clicked"}},required:["title","body"]}}].map(e=>({name:e.name,definition:e,handler:be[e.name]})),Ie="conway-keepalive",ke="claude-in-chrome";let Ce=null,Se=!1,ve=!1,Ee="disconnected";async function Ae(){return T(z)}function Ne(e){Ee!==e&&(Ee=e,Ue().then(t=>{chrome.runtime.sendMessage({type:W.STATUS_CHANGED,status:e,containerId:t??""}).catch(()=>{})}))}async function Me(){if(!(await Ae()))return Ne("disconnected"),chrome.alarms.clear(Ie),!1;if(ve||(ve=!0,chrome.alarms.onAlarm.addListener(e=>{e.name===Ie&&Ae().then(e=>{e?Me():(chrome.alarms.clear(Ie),Ce&&(Ce.destroy(),Ce=null,Ne("disconnected")))})})),chrome.alarms.create(Ie,{periodInMinutes:.5}),Ce?.isConnected()||Se)return!1;Se=!0,Ne("connecting");let e=null;try{const t=await ye();if(!t)return Se=!1,Ne("disconnected"),chrome.alarms.clear(Ie),!1;const n=await w(K.LAST_CONNECTION),s=t.containerId??"local",a=n?.containerId===s?n.clientId:void 0;t.mode,t.hostUrl;const o=await async function(){const e=[];for(const t of le){const n=await t.toAnthropicSchema({tabId:-1}),s=he(t,n);e.push({name:t.name,definition:s,handler:de(t.name)})}return e}().catch(e=>(e.message,[]));return e=new ie({hostUrl:t.hostUrl,clientName:ke,displayName:"Claude in Chrome",clientDescription:"Claude Chrome extension hand",singleton:!0,customHeaders:t.customHeaders,auth:t.bearerToken?{kind:"bearer",token:t.bearerToken}:void 0,credentials:t.bearerToken?"omit":void 0,tools:[...Te,...o],welcomeMessage:"## Chrome Extension Hand Connected\n\nThe Claude Chrome extension is now connected as a hand. This hand runs inside the user's browser and can observe tabs, open/close pages, and show notifications.\n\n### Tab Management\n- **get_tabs_summary** — see all open tabs\n- **open_tab** / **close_tab** — manage tabs\n- **tabs_context** / **tabs_create** — MCP-style tab orchestration (get/create tabs in the Claude-managed tab group)\n- **show_notification** — surface a Chrome notification\n\n### Browser Automation\nFull browser control on any tab you have a tabId for. Call tabs_context first to get available tabs.\n- **navigate** — go to a URL or back/forward\n- **read_page** / **get_page_text** — screenshot + accessibility tree / extracted text\n- **find** — natural-language element search\n- **form_input** — fill form fields\n- **computer** — mouse/keyboard automation via CDP\n- **javascript_tool** — execute JS in page context\n- **read_console_messages** / **read_network_requests** — observability\n- **upload_image** — file upload\n- **shortcuts_list** / **shortcuts_execute** — keyboard shortcuts\n\n### Active Session\nThe user is actively browsing — they're looking at a screen and have intent. Match their current focus; augment rather than interrupt.\n",resumeClientId:a??void 0,healthHandler:async()=>{const e=await chrome.permissions.getAll();return{ok:!0,name:ke,version:chrome.runtime.getManifest().version,platform:navigator.platform,permissions:e.permissions??[]}},log:e=>(e.event,e.msg,void e.data)}),e.on("connected",(n,s)=>{Ce===e&&(_(K.LAST_CONNECTION,{containerId:s??t.containerId??"local",clientId:n}),Se=!1,Ne("connected"))}),e.on("disconnected",()=>{}),e.on("stateChange",(t,n)=>{Ce===e&&("connected"===t?Ne("connected"):"connecting"===t||"backing_off"===t?Ne("connecting"):"failed"===t&&(Ce=null,Se=!1,Ne("error")))}),e.on("error",e=>{e.message}),e.on("conwayError",e=>{e.message,e.cause}),e.on("goodbye",e=>{}),e.on("shutdown",t=>{Ce===e&&(Ce=null,Se=!1,e?.destroy(),f(K.LAST_CONNECTION),Ne("disconnected"))}),e.on("containerChanged",t=>{w(K.LAST_CONNECTION).then(n=>{Ce===e&&n&&_(K.LAST_CONNECTION,{...n,containerId:t})})}),t.bearerToken&&e.on("authExpired",async()=>{const t=await y();Ce===e&&t&&e?.setAuth({kind:"bearer",token:t})}),Ce&&Ce!==e&&Ce.destroy(),Ce=e,await e.connect(),!0}catch(t){return t.message,e?.destroy(),Ce===e&&(Ce=null),Se=!1,Ne("error"),!1}}function Re(){Ce?.destroy(),Ce=null,Se=!1,chrome.alarms.clear(Ie),Ne("disconnected"),async function(){await f(K.ORG_UUID)}(),f(K.LAST_CONNECTION)}async function Ue(){const e=await w(K.LAST_CONNECTION),t=e?.containerId;return"local"===t?void 0:t}let Oe=null,De=null,xe=!1,Le=!1,Pe=!1,$e=null,He=null;function Fe(e){e?.includes("native messaging host not found")&&(Le=!1)}async function qe(){try{return await async function(){if(Oe)return!0;if(xe)return!1;xe=!0;try{if(!(await chrome.permissions.contains({permissions:["nativeMessaging"]})))return!1;if("function"!=typeof chrome.runtime.connectNative)return!1;const t=[{name:"com.anthropic.claude_browser_extension",label:"Desktop"},{name:"com.anthropic.claude_code_browser_extension",label:"Claude Code"}];for(const n of t)try{const e=chrome.runtime.connectNative(n.name);if(await new Promise(t=>{let n=!1;const s=()=>{n||(n=!0,chrome.runtime.lastError,t(!1))},a=o=>{n||"pong"===o.type&&(n=!0,e.onDisconnect.removeListener(s),e.onMessage.removeListener(a),t(!0))};e.onDisconnect.addListener(s),e.onMessage.addListener(a);try{e.postMessage({type:"ping"})}catch(o){return void(n||(n=!0,t(!1)))}setTimeout(()=>{n||(n=!0,e.onDisconnect.removeListener(s),e.onMessage.removeListener(a),t(!1))},1e4)}))return Oe=e,De=n.name,Le=!0,Oe.onMessage.addListener(async e=>{await Ge(e)}),Oe.onDisconnect.addListener(()=>{const e=chrome.runtime.lastError?.message;Oe=null,De=null,Pe=!1,_(I.MCP_CONNECTED,!1),Fe(e),k()}),Oe.postMessage({type:"get_status"}),!0;e.disconnect()}catch(e){}return!1}catch(e){return e instanceof Error&&Fe(e.message),!1}finally{xe=!1}}()}catch(e){return!1}}async function Be(){try{return await chrome.permissions.remove({permissions:["nativeMessaging"]}),Oe?.disconnect(),Oe=null,De=null,xe=!1,Le=!1,Pe=!1,!0}catch(e){return!1}}async function Ge(e){switch(e.type){case"tool_request":await async function(e){try{const{method:t,params:n}=e;if("execute_tool"===t){if(!n?.tool)return void je(S("No tool specified"));const e=n.client_id,t=n.args?.tabGroupId,s="number"==typeof t?t:"string"==typeof t&&parseInt(t,10)||void 0,a=n.args?.tabId??("browser_batch"===n.tool&&Array.isArray(n.args?.actions)?n.args.actions.find(e=>"number"==typeof e?.input?.tabId)?.input?.tabId:void 0),o="number"==typeof a?a:"string"==typeof a&&parseInt(a,10)||void 0,r=n.session_scope;je(await g({toolName:n.tool,args:n.args||{},tabId:o,tabGroupId:s,clientId:e,source:"native-messaging",sessionScope:r}),e)}else je({content:`Unknown method: ${t}`})}catch(t){je(S(`Tool execution failed: ${t instanceof Error?t.message:"Unknown error"}`))}}(e);break;case"status_response":$e&&(clearTimeout(He),He=null,$e({nativeHostInstalled:Le,mcpConnected:Pe}),$e=null);break;case"mcp_connected":!async function(){Pe=!0,_(I.MCP_CONNECTED,!0),await C.initialize(),C.startTabGroupChangeListener()}();break;case"mcp_disconnected":Pe=!1,_(I.MCP_CONNECTED,!1),C.stopTabGroupChangeListener()}}function je({content:e,is_error:t},n){if(!Oe)return;if(!e||"string"!=typeof e&&!Array.isArray(e))return;let s;s=t?function(e){let t;const n="IMPORTANT: The user has explicitly declined this action. Do not attempt to use other tools or workarounds. Instead, acknowledge the denial and ask the user how they would prefer to proceed.";t="string"==typeof e?e.includes("Permission denied by user")?`${e} - ${n}`:e:e.map(t=>"object"==typeof t&&null!==t&&"text"in t&&"string"==typeof t.text&&t.text.includes("Permission denied by user")?{...t,text:`${e} - ${n}`}:t);return{type:"tool_response",error:{content:t}}}(e):{type:"tool_response",result:{content:e}},Oe.postMessage(s)}const Ke="/chrome/";async function We(e,t){try{const n=new URL(e);if("clau.de"!==n.host)return!1;if("/chrome/permissions"===n.pathname.toLowerCase())return await async function(e){try{const e=chrome.runtime.getURL("options.html#permissions");await chrome.tabs.create({url:e})}catch(t){}finally{await ze(e)}}(t),!0;if(!n.pathname.startsWith(Ke))return!1;const s=n.pathname.substring(8).toLowerCase();if("reconnect"===s)return await async function(e){try{await Be(),E(),await new Promise(e=>setTimeout(e,500));const[e,t]=await Promise.all([qe(),A()]);v("claude_chrome.extension_url.reconnect",{native_host_success:e,bridge_initiated:t})}catch(t){v("claude_chrome.extension_url.reconnect",{success:!1})}finally{await ze(e)}}(t),!0;if(s.startsWith("tab/")){const e=parseInt(s.substring(4),10);return await async function(e,t){if(isNaN(e))return v("claude_chrome.extension_url.tab_switch",{success:!1,error:"invalid_tab_id"}),await ze(t),!0;try{await C.initialize();const n=await C.findGroupByTab(e);if(!n||n.isUnmanaged)return v("claude_chrome.extension_url.tab_switch",{success:!1,error:"tab_not_managed"}),await ze(t),!0;const s=await chrome.tabs.get(e);return void 0!==s.windowId&&await chrome.windows.update(s.windowId,{focused:!0}),await chrome.tabs.update(e,{active:!0}),v("claude_chrome.extension_url.tab_switch",{success:!0}),await ze(t),!0}catch(n){return v("claude_chrome.extension_url.tab_switch",{success:!1}),await ze(t),!0}}(e,t),!0}return!1}catch{return v("claude_chrome.extension_url.unknown_exception",{}),!1}}async function ze(e){try{await chrome.tabs.remove(e)}catch(t){}}async function Ye(){const e=b(),t=`claude-browser-extension/${chrome.runtime.getManifest().version} (external)`,n=chrome.runtime.getManifest().version,s=`${t} ${navigator.userAgent} `,a=[{id:1,priority:1,action:{type:chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,requestHeaders:[{header:"User-Agent",operation:chrome.declarativeNetRequest.HeaderOperation.SET,value:s},{header:"anthropic-client-platform",operation:chrome.declarativeNetRequest.HeaderOperation.SET,value:"claude_browser_extension"},{header:"anthropic-client-version",operation:chrome.declarativeNetRequest.HeaderOperation.SET,value:n}]},condition:{urlFilter:`${e.apiBaseUrl}/*`,resourceTypes:[chrome.declarativeNetRequest.ResourceType.XMLHTTPREQUEST,chrome.declarativeNetRequest.ResourceType.OTHER]}}];await chrome.declarativeNetRequest.updateSessionRules({removeRuleIds:[1],addRules:a})}async function Je(){try{const t=(await F.getAllPrompts()).filter(e=>e.repeatType&&"none"!==e.repeatType);if(0===t.length)return;let n=0,s=0;for(const a of t)try{await F.updateAlarmForPrompt(a),n++}catch(e){s++}try{await F.updateNextRunTimes()}catch(e){}}catch(e){}}N(),M(),R(),A(),U().catch(e=>{}),qe(),Me();const Xe=new Map;chrome.runtime.onInstalled.addListener(async e=>{chrome.storage.local.remove(["updateAvailable"]),chrome.runtime.setUninstallURL("https://docs.google.com/forms/d/e/1FAIpQLSdLa1wTVkB2ml2abPI1FP9KiboOnp2N0c3aDmp5rWmaOybWwQ/viewform"),O(),await C.initialize(),await Ye(),e.reason===chrome.runtime.OnInstalledReason.INSTALL&&D(),qe(),await Je()}),chrome.runtime.onStartup.addListener(async()=>{O(),await Ye(),await C.initialize(),A(),qe(),await Je()}),chrome.permissions.onAdded.addListener(e=>{e.permissions?.includes("nativeMessaging")&&qe()}),chrome.permissions.onRemoved.addListener(e=>{e.permissions?.includes("nativeMessaging")&&Be()}),chrome.action.onClicked.addListener(Ze),chrome.notifications.onClicked.addListener(async e=>{if(e.startsWith("conway-"))return void async function(e){const t=_e(e),n=(await chrome.storage.session.get(t))[t];chrome.storage.session.remove(t),n&&chrome.tabs.create({url:n}),chrome.notifications.clear(e)}(e);chrome.notifications.clear(e);const t=e.split("_");let n=null;if(t.length>=2&&"unknown"!==t[1]&&(n=parseInt(t[1],10)),n&&!isNaN(n))try{const e=await chrome.tabs.get(n);if(e&&e.windowId)return await chrome.windows.update(e.windowId,{focused:!0}),void(await chrome.tabs.update(n,{active:!0}))}catch{}const[s]=await chrome.tabs.query({active:!0,currentWindow:!0});s?.id&&s.windowId&&await chrome.windows.update(s.windowId,{focused:!0})}),chrome.notifications.onClosed.addListener(e=>{e.startsWith("conway-")&&async function(e){await chrome.storage.session.remove(_e(e))}(e)}),chrome.commands.onCommand.addListener(e=>{"toggle-side-panel"===e&&chrome.tabs.query({active:!0,currentWindow:!0},e=>{const t=e[0];t&&Ze(t)})});let Qe=!1;async function Ve(e){if(!chrome.sidePanel)return v("claude_chrome.sidepanel.unsupported_browser",{user_agent:navigator.userAgent}),void(Qe||(Qe=!0,chrome.notifications.create({type:"basic",iconUrl:"/icon-128.png",title:"Browser not supported",message:"Claude requires the Chrome Side Panel API, which isn't available in this browser. Use Google Chrome, Microsoft Edge, or Brave."})));chrome.sidePanel.setOptions({tabId:e,path:`sidepanel.html?tabId=${encodeURIComponent(e)}`,enabled:!0}),chrome.sidePanel.open({tabId:e}),await C.initialize(!0);const t=await C.findGroupByTab(e);if(t){if(t.isUnmanaged){try{await C.adoptOrphanedGroup(e,t.chromeGroupId)}catch(n){}return}}else{try{await C.createGroup(e)}catch(n){}qe()}}async function Ze(e){const t=e.id;t&&await Ve(t)}chrome.runtime.onUpdateAvailable.addListener(e=>{_(I.UPDATE_AVAILABLE,!0),v("claude_chrome.extension.update_available",{current_version:chrome.runtime.getManifest().version,new_version:e.version})});const et=new Set(["SW_KEEPALIVE","check_and_refresh_oauth","PLAY_NOTIFICATION_SOUND","open_side_panel","logout","check_native_host_status","SEND_MCP_NOTIFICATION","OPEN_OPTIONS_WITH_TASK","EXECUTE_SCHEDULED_TASK","STOP_AGENT","SWITCH_TO_MAIN_TAB","SECONDARY_TAB_CHECK_MAIN","MAIN_TAB_ACK_RESPONSE","STATIC_INDICATOR_HEARTBEAT","DISMISS_STATIC_INDICATOR_FOR_GROUP",W.GET_STATUS]);async function tt(e,t){const n=`session_${Date.now()}_${Math.random().toString(36).substring(2,11)}`,s=await chrome.windows.create({url:e.url||"about:blank",type:"normal",focused:!0});if(!s||!s.id||!s.tabs||0===s.tabs.length)throw new Error("Failed to create window for scheduled task");const a=s.tabs[0];if(!a.id)throw new Error("Failed to get tab in new window for scheduled task");await C.initialize(!0);await C.createGroup(a.id);await _(I.TARGET_TAB_ID,a.id),await async function(e){const{sessionId:t,skipPermissions:n,model:s}=e,a=chrome.runtime.getURL(`sidepanel.html?mode=window&sessionId=${t}${n?"&skipPermissions=true":""}${s?`&model=${encodeURIComponent(s)}`:""}`),o=await chrome.windows.create({url:a,type:"popup",width:500,height:768,left:100,top:100,focused:!0});if(!o)throw new Error("Failed to create sidepanel window");return o}({sessionId:n,skipPermissions:e.skipPermissions,model:e.model}),await async function(e){const{tabId:t,prompt:n,taskName:s,runLogId:a,sessionId:o,isScheduledTask:r}=e;return new Promise((e,i)=>{const c=3e4,l=Date.now();let d=!1;const h=async()=>{try{if(Date.now()-l>c)return void i(new Error("Timeout waiting for tab to load for task execution"));"complete"===(await chrome.tabs.get(t)).status?setTimeout(()=>{d||(d=!0,chrome.runtime.sendMessage({type:"EXECUTE_TASK",prompt:n,taskName:s,runLogId:a,windowSessionId:o,isScheduledTask:r},t=>{const n=chrome.runtime.lastError?.message;n||!t?.success?i(new Error(`Failed to send prompt: ${n??"side panel not ready"}`)):e()}))},3e3):setTimeout(h,500)}catch(u){i(u)}};setTimeout(h,1e3)})}({tabId:a.id,prompt:e.prompt,taskName:e.name,runLogId:t,sessionId:n,isScheduledTask:!0})}chrome.runtime.onMessage.addListener((e,t,n)=>!!et.has(e.type)&&((async()=>{if("SW_KEEPALIVE"!==e.type){if("check_and_refresh_oauth"===e.type){const e=await x();return void n(e)}if("PLAY_NOTIFICATION_SOUND"!==e.type){if("open_side_panel"===e.type){const s=e.tabId||t.tab?.id;if(!s)return void n({success:!1});await Ve(s);const a=Y(e.onboardingTaskId);if(a){const e=async(t=0)=>{try{const e=0===t?800:500;await new Promise(t=>setTimeout(t,e)),await new Promise((e,t)=>{chrome.runtime.sendMessage({type:"POPULATE_INPUT_TEXT",prompt:a},n=>{const s=chrome.runtime.lastError?.message;s||!n?.success?t(new Error(s??"side panel not ready")):e()})})}catch(n){t<5&&await e(t+1)}};await e()}return void n({success:!0})}if(e.type!==W.GET_STATUS)if("logout"===e.type)try{L(),await P(),await C.clearAllGroups(),Re(),n({success:!0})}catch(s){n({success:!1,error:String(s)})}else if("check_native_host_status"===e.type){const e=await async function(){return Oe&&Le?(He&&clearTimeout(He),new Promise(e=>{$e=e,Oe.postMessage({type:"get_status"}),He=setTimeout(()=>{$e=null,e({nativeHostInstalled:Le,mcpConnected:Pe})},1e4)})):{nativeHostInstalled:Le,mcpConnected:Pe}}();n({status:{nativeHostInstalled:e.nativeHostInstalled,mcpConnected:e.mcpConnected||$()}})}else if("SEND_MCP_NOTIFICATION"===e.type){const t=function(e,t){if(!Oe)return!1;const n={type:"notification",jsonrpc:"2.0",method:e,params:t||{}};return Oe.postMessage(n),!0}(e.method,e.params),s=H(e.method,e.params);n({success:t||s})}else if("OPEN_OPTIONS_WITH_TASK"===e.type)try{await _(I.PENDING_SCHEDULED_TASK,e.task);const t=chrome.runtime.getURL("options.html"),s=(await chrome.tabs.query({})).find(e=>e.url?.startsWith(t));s&&s.id?(await chrome.tabs.update(s.id,{url:chrome.runtime.getURL("options.html#prompts"),active:!0}),s.windowId&&await chrome.windows.update(s.windowId,{focused:!0})):await chrome.tabs.create({url:chrome.runtime.getURL("options.html#prompts")}),n({success:!0})}catch(s){n({success:!1,error:s.message})}else if("EXECUTE_SCHEDULED_TASK"===e.type){if(t.tab)return void n({success:!1,error:"Forbidden sender"});try{const{task:t,runLogId:s}=e;await tt(t,s),v("claude_chrome.scheduled_task.executed",{task_id:t.id,task_name:t.name,success:!0,execution_type:e.isManual?"manual":"automatic"}),n({success:!0})}catch(s){v("claude_chrome.scheduled_task.executed",{task_id:e.task.id,task_name:e.task.name,success:!1,execution_type:e.isManual?"manual":"automatic",error:s.message}),n({success:!1,error:s.message})}}else if("STOP_AGENT"===e.type){let s;if("CURRENT_TAB"===e.fromTabId&&t.tab?.id){s=await C.getMainTabId(t.tab.id)||t.tab.id}else"number"==typeof e.fromTabId&&(s=e.fromTabId);s&&chrome.runtime.sendMessage({type:"STOP_AGENT",targetTabId:s}),n({success:!0})}else if("SWITCH_TO_MAIN_TAB"===e.type)if(t.tab?.id)try{await C.initialize(!0);const e=await C.getMainTabId(t.tab.id);if(e){await chrome.tabs.update(e,{active:!0});const t=await chrome.tabs.get(e);t.windowId&&await chrome.windows.update(t.windowId,{focused:!0}),n({success:!0})}else n({success:!1,error:"No main tab found"})}catch(s){n({success:!1,error:s.message})}else n({success:!1,error:"No sender tab"});else"SECONDARY_TAB_CHECK_MAIN"===e.type?chrome.runtime.sendMessage({type:"MAIN_TAB_ACK_REQUEST",secondaryTabId:e.secondaryTabId,mainTabId:e.mainTabId,timestamp:e.timestamp},e=>{n(e?.success?{success:!0}:{success:!1})}):"MAIN_TAB_ACK_RESPONSE"===e.type?n({success:e.success}):"STATIC_INDICATOR_HEARTBEAT"===e.type?(async()=>{const e=t.tab?.id;if(e)try{const t=(await chrome.tabs.get(e)).groupId;if(void 0===t||t===chrome.tabGroups.TAB_GROUP_ID_NONE)return void n({success:!1});if(await C.findGroupByTab(e))return void n({success:!0});const s=await chrome.tabs.query({groupId:t}),a=async t=>{if(t>=s.length)return void n({success:!1});const o=s[t];if(o.id===e||!o.id)return void(await a(t+1));const r=o.id,i=Date.now(),c=Xe.get(r);if(c&&i-c.timestamp<3e3)return c.isAlive?void n({success:!0}):void(await a(t+1));chrome.runtime.sendMessage({type:"MAIN_TAB_ACK_REQUEST",secondaryTabId:e,mainTabId:r,timestamp:i},async e=>{const s=e?.success??!1;Xe.set(r,{timestamp:i,isAlive:s}),s?n({success:!0}):await a(t+1)})};await a(0)}catch(s){n({success:!1})}else n({success:!1})})():"DISMISS_STATIC_INDICATOR_FOR_GROUP"===e.type&&(async()=>{const e=t.tab?.id;if(e)try{const t=(await chrome.tabs.get(e)).groupId;if(void 0===t||t===chrome.tabGroups.TAB_GROUP_ID_NONE)return void n({success:!1});await C.initialize(),await C.dismissStaticIndicatorsForGroup(t),n({success:!0})}catch(s){n({success:!1})}else n({success:!1})})();else n({status:Ee,containerId:await Ue()??""})}else try{await U(),await chrome.runtime.sendMessage({type:"OFFSCREEN_PLAY_SOUND",audioUrl:e.audioUrl,volume:e.volume||.5}),n({success:!0})}catch(s){n({success:!1,error:s.message})}}else n()})().catch(e=>{n({success:!1,error:String(e)})}),!0)),chrome.tabs.onRemoved.addListener(async e=>{await C.handleTabClosed(e)}),chrome.webNavigation.onBeforeNavigate.addListener(async e=>{0===e.frameId&&await We(e.url,e.tabId)}),chrome.alarms.onAlarm.addListener(async e=>{if(e.name.startsWith("prompt_"))try{const a=e.name,o=await chrome.storage.local.get(["savedPrompts"]),r=(o.savedPrompts||[]).find(e=>e.id===a);if(r){const e=`${Date.now()}_${Math.random().toString(36).substring(2,11)}`;let o=null;try{const t={id:r.id,name:r.command||"Scheduled Task",prompt:r.prompt,url:r.url,enabled:!0,skipPermissions:!1!==r.skipPermissions,model:r.model};await tt(t,e)}catch(t){o=t instanceof Error?t:new Error(String(t));try{await chrome.notifications.create({type:"basic",iconUrl:"/icon-128.png",title:"Scheduled Task Failed",message:`Task "${r.command||"Scheduled Task"}" failed to execute. ${o.message}`,priority:2})}catch(n){}}if("monthly"===r.repeatType||"annually"===r.repeatType)try{await F.updateAlarmForPrompt(r)}catch(t){const e=`retry_${a}`;try{await chrome.alarms.create(e,{delayInMinutes:1})}catch(s){}try{await chrome.notifications.create({type:"basic",iconUrl:"/icon-128.png",title:"Scheduled Task Setup Failed",message:`Failed to schedule next occurrence of "${r.command||"Scheduled Task"}". Please check the task settings.`,priority:2})}catch(n){}}}}catch(t){}else if(e.name.startsWith("retry_"))try{const s=e.name.replace("retry_",""),a=await chrome.storage.local.get(["savedPrompts"]),o=(a.savedPrompts||[]).find(e=>e.id===s);if(o&&("monthly"===o.repeatType||"annually"===o.repeatType))try{await F.updateAlarmForPrompt(o)}catch(t){try{await chrome.notifications.create({type:"basic",iconUrl:"/icon-128.png",title:"Scheduled Task Needs Attention",message:`Could not automatically reschedule "${o.command||"Scheduled Task"}". Please edit the task to reschedule it.`,priority:2})}catch(n){}}}catch(t){}}),chrome.runtime.onMessageExternal.addListener((e,t,n)=>((async()=>{var s;if((s=t.origin)&&["https://claude.ai"].includes(s))if("oauth_redirect"===e.type){q();const s=await B(e.redirect_uri,t?.tab?.id);n(s),s.success&&(G().then(()=>{A(),Me()}),qe(),L(),j())}else"ping"===e.type?n({success:!0,exists:!0}):n();else n({success:!1,error:"Untrusted origin"})})().catch(e=>{n({success:!1,error:String(e)})}),!0)); A Eob]E}HTTP/1.1 200 OKContent-Security-Policy: script-src 'self'; object-src 'self'; connect-src 'self' https://api.anthropic.com wss://api.anthropic.com https://claude.ai https://platform.claude.com https://api.segment.io https://*.segment.com https://*.ingest.us.sentry.io https://api.honeycomb.io https://browser-intake-us5-datadoghq.com wss://bridge.claudeusercontent.com wss://bridge-staging.claudeusercontent.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;ETag: "/3cx9/+u0EmQUNmtXzHF5SH2MS8="cache-control: no-cacheContent-Type: text/javascriptLast-Modified: Tue, 16 Jun 2026 06:10:17 GMTb 3!Uj"h9rvayR,j$ݷA EoС[