@usecrow/client 0.1.27 → 0.1.29

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/dist/index.cjs CHANGED
@@ -1,3 +1,7 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const I=require("./browserUse-BOc9kyBK.cjs");class _{constructor(){this.state={token:null,metadata:{},isVerified:!1},this.listeners=new Set}identify(e){const{token:t,...s}=e;this.state={token:t,metadata:s,isVerified:!1},this.notify(),console.log("[Crow] User identified")}setVerified(e){this.state={...this.state,isVerified:e},this.notify()}reset(){this.state={token:null,metadata:{},isVerified:!1},this.notify(),console.log("[Crow] User reset")}getToken(){return this.state.token}getState(){return{...this.state}}isIdentified(){return this.state.token!==null}isVerified(){return this.state.isVerified}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){const e=this.getState();for(const t of this.listeners)t(e)}}class k{constructor(){this.handlers={}}register(e){for(const[t,s]of Object.entries(e))typeof s=="function"?(this.handlers[t]=s,console.log(`[Crow] Registered client tool: ${t}`)):console.warn(`[Crow] Skipping ${t}: handler is not a function`)}unregister(e){delete this.handlers[e],console.log(`[Crow] Unregistered client tool: ${e}`)}has(e){return e in this.handlers}getRegisteredTools(){return Object.keys(this.handlers)}async execute(e,t){const s=this.handlers[e];if(!s)return console.warn(`[Crow] No handler registered for tool: ${e}`),{status:"error",error:`No handler registered for tool: ${e}`};try{console.log(`[Crow] Executing client tool: ${e}`,t);const r=await s(t);return console.log(`[Crow] Tool ${e} completed:`,r),r}catch(r){const i=r instanceof Error?r.message:String(r);return console.error(`[Crow] Tool ${e} failed:`,r),{status:"error",error:i}}}}const T="crow_conv_";class C{constructor(e,t){this.currentId=null,this.productId=e,this.apiUrl=t,this.currentId=this.loadFromStorage()}getStorageKey(){return`${T}${this.productId}`}loadFromStorage(){try{return localStorage.getItem(this.getStorageKey())}catch{return null}}saveToStorage(e){try{localStorage.setItem(this.getStorageKey(),e)}catch{}}clearStorage(){try{localStorage.removeItem(this.getStorageKey())}catch{}}getCurrentId(){return this.currentId}setCurrentId(e){this.currentId=e,e?this.saveToStorage(e):this.clearStorage()}hasRestoredConversation(){return this.currentId!==null}clear(){this.currentId=null,this.clearStorage()}async getConversations(e){try{const t=await fetch(`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`);if(!t.ok)throw new Error(`HTTP error: ${t.status}`);return(await t.json()).conversations||[]}catch(t){return console.error("[Crow] Failed to load conversations:",t),[]}}async loadHistory(e,t){try{const s=await fetch(`${this.apiUrl}/api/chat/conversations/${e}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`);if(!s.ok)throw new Error(`HTTP error: ${s.status}`);const r=await s.json();return this.parseHistoryMessages(r.messages||[])}catch(s){return console.error("[Crow] Failed to load conversation history:",s),[]}}async loadAnonymousHistory(e){try{const t=await fetch(`${this.apiUrl}/api/chat/conversations/${e}/history/anonymous?product_id=${this.productId}`);if(!t.ok)throw new Error(`HTTP error: ${t.status}`);const s=await t.json();return this.parseHistoryMessages(s.messages||[])}catch(t){return console.error("[Crow] Failed to load anonymous conversation history:",t),[]}}parseHistoryMessages(e){return e.filter(t=>t.role!=="tool"&&!t.content.startsWith("[Client Tool Result:")).map((t,s)=>({id:`history-${s}`,content:this.parseContent(t.content),role:t.role==="assistant"?"assistant":"user",timestamp:new Date}))}parseContent(e){try{const t=JSON.parse(e);if(Array.isArray(t)){const s=t.find(r=>r.type==="text");return(s==null?void 0:s.text)||e}}catch{}if(e.includes("'type': 'text'")){const t=e.match(/\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/);if(t)return t[1].replace(/\\n/g,`
2
- `).replace(/\\'/g,"'")}return e}}function M(n){if(n==="[DONE]")return{type:"done"};try{const e=JSON.parse(n);switch(e.type){case"verification_status":return{type:"verification_status",isVerified:e.is_verified===!0};case"conversation_id":return{type:"conversation_id",conversationId:e.conversation_id};case"thinking":return e.status==="complete"?{type:"thinking_complete"}:null;case"thinking_token":return{type:"thinking",content:e.content||""};case"content":return{type:"content",text:e.content||"",accumulated:""};case"citations":return{type:"citations",citations:e.citations};case"error":return{type:"error",message:e.message||"Unknown error"};case"tool_call_start":return{type:"tool_call_start",toolName:e.tool_name,arguments:e.arguments||{}};case"tool_call_complete":return{type:"tool_call_complete",toolName:e.tool_name,success:e.success};case"client_tool_call":return{type:"client_tool_call",toolName:e.tool_name,arguments:e.arguments||{}};case"workflow_started":return{type:"workflow_started",name:e.name,todos:e.todos};case"todo_updated":return{type:"workflow_todo_updated",todoId:e.id,status:e.status};case"workflow_ended":return{type:"workflow_ended"};case"workflow_complete_prompt":return{type:"workflow_complete_prompt"};default:return null}}catch{return console.error("[Crow] Failed to parse SSE data:",n),null}}function*b(n){const e=n.split(`
3
- `);for(const t of e)t.startsWith("data: ")&&(yield t.slice(6).trim())}async function*S(n,e){var i;const t=(i=n.body)==null?void 0:i.getReader();if(!t)throw new Error("Response body is not readable");const s=new TextDecoder;let r="";try{for(;;){if(e!=null&&e.aborted){t.cancel();return}const{done:l,value:d}=await t.read();if(l)break;const h=s.decode(d);for(const u of b(h)){const c=M(u);if(c&&(c.type==="content"?(r+=c.text,yield{...c,accumulated:r}):yield c,c.type==="done"))return}}}finally{t.releaseLock()}}const g={refreshPage:async()=>{try{return window.location.reload(),{status:"success",data:{message:"Page refresh initiated"}}}catch(n){return{status:"error",error:String(n)}}}},v=Object.keys(g),E="https://api.usecrow.org",L="claude-sonnet-4-20250514";class ${constructor(e){this.context={},this.abortController=null,this.callbacks={},this._messages=[],this.messageListeners=new Set,this._isLoading=!1,this.loadingListeners=new Set,this.config={productId:e.productId,apiUrl:e.apiUrl||E,model:e.model||L},this.identity=new _,this.tools=new k,this.conversations=new C(this.config.productId,this.config.apiUrl),this.tools.register(g),console.log("[Crow] Default tools registered:",v.join(", ")),this.identity.subscribe(t=>{var s,r;(r=(s=this.callbacks).onVerificationStatus)==null||r.call(s,t.isVerified)})}get productId(){return this.config.productId}get apiUrl(){return this.config.apiUrl}get model(){return this.config.model}set model(e){this.config.model=e}on(e){this.callbacks={...this.callbacks,...e}}identify(e){this.identity.identify(e)}resetUser(){this.identity.reset(),this.clearMessages()}isIdentified(){return this.identity.isIdentified()}isVerified(){return this.identity.isVerified()}registerTools(e){this.tools.register(e)}unregisterTool(e){this.tools.unregister(e)}getRegisteredTools(){return this.tools.getRegisteredTools()}setContext(e){this.context={...this.context,...e}}clearContext(){this.context={}}get messages(){return[...this._messages]}get isLoading(){return this._isLoading}onMessages(e){return this.messageListeners.add(e),()=>this.messageListeners.delete(e)}onLoading(e){return this.loadingListeners.add(e),()=>this.loadingListeners.delete(e)}clearMessages(){this._messages=[],this.conversations.clear(),this.notifyMessages()}loadMessages(e){this._messages=e,this.notifyMessages()}notifyMessages(){const e=this.messages;for(const t of this.messageListeners)t(e)}setLoading(e){this._isLoading=e;for(const t of this.loadingListeners)t(e)}addMessage(e){var t,s;this._messages=[...this._messages,e],this.notifyMessages(),(s=(t=this.callbacks).onMessage)==null||s.call(t,e)}updateMessage(e,t){var s,r;this._messages=this._messages.map(i=>i.id===e?{...i,...t}:i),this.notifyMessages(),(r=(s=this.callbacks).onMessageUpdate)==null||r.call(s,e,t)}generateMessageId(e){return`${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get conversationId(){return this.conversations.getCurrentId()}set conversationId(e){this.conversations.setCurrentId(e)}async getConversations(){const e=this.identity.getToken();return e?this.conversations.getConversations(e):(console.warn("[Crow] Cannot get conversations: user not identified"),[])}async loadHistory(e){const t=this.identity.getToken();return t?this.conversations.loadHistory(e,t):this.conversations.loadAnonymousHistory(e)}async switchConversation(e){const t=await this.loadHistory(e);this.conversations.setCurrentId(e),this.loadMessages(t)}async*sendMessage(e){var l,d,h,u,c,f,p,y,m,w;if(!e.trim())return;const t=this.generateMessageId("user");this.addMessage({id:t,content:e,role:"user",timestamp:new Date});const s=this.generateMessageId("assistant");this.addMessage({id:s,content:"",role:"assistant",timestamp:new Date}),this.setLoading(!0),this.abortController=new AbortController;let r="",i="";try{const a=await fetch(`${this.config.apiUrl}/api/chat/message`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({product_id:this.config.productId,message:e,conversation_id:this.conversations.getCurrentId(),identity_token:this.identity.getToken(),model:this.config.model,context:Object.keys(this.context).length>0?this.context:void 0}),signal:this.abortController.signal});if(!a.ok)throw new Error(`HTTP error: ${a.status}`);for await(const o of S(a,this.abortController.signal)){switch(o.type){case"content":r=o.accumulated,this.updateMessage(s,{content:r});break;case"thinking":i+=o.content,this.updateMessage(s,{thinking:i});break;case"thinking_complete":this.updateMessage(s,{thinkingComplete:!0});break;case"citations":this.updateMessage(s,{citations:o.citations});break;case"verification_status":this.identity.setVerified(o.isVerified);break;case"conversation_id":this.conversations.setCurrentId(o.conversationId);break;case"client_tool_call":await this.tools.execute(o.toolName,o.arguments),(d=(l=this.callbacks).onToolCall)==null||d.call(l,o);break;case"tool_call_start":case"tool_call_complete":(u=(h=this.callbacks).onToolCall)==null||u.call(h,o);break;case"workflow_started":case"workflow_todo_updated":case"workflow_ended":case"workflow_complete_prompt":(f=(c=this.callbacks).onWorkflow)==null||f.call(c,o);break;case"error":this.updateMessage(s,{content:o.message}),(y=(p=this.callbacks).onError)==null||y.call(p,new Error(o.message));break}yield o}}catch(a){if(a instanceof Error&&a.name==="AbortError"){r?this.updateMessage(s,{content:r}):(this._messages=this._messages.filter(o=>o.id!==s),this.notifyMessages());return}console.error("[Crow] Error:",a),this.updateMessage(s,{content:"Sorry, I encountered an error. Please try again."}),(w=(m=this.callbacks).onError)==null||w.call(m,a instanceof Error?a:new Error(String(a)))}finally{this.setLoading(!1),this.abortController=null}}async send(e){let t=null;for await(const r of this.sendMessage(e))if(r.type==="done")break;const s=this.messages;return s.length>0&&(t=s[s.length-1],t.role==="assistant")?t:null}stop(){this.abortController&&(this.abortController.abort(),this.setLoading(!1))}destroy(){this.stop(),this.messageListeners.clear(),this.loadingListeners.clear()}}exports.CrowBrowserUse=I.CrowBrowserUse;exports.ConversationManager=C;exports.CrowClient=$;exports.DEFAULT_TOOLS=g;exports.DEFAULT_TOOL_NAMES=v;exports.IdentityManager=_;exports.ToolManager=k;exports.parseSSEChunk=b;exports.parseSSEData=M;exports.streamResponse=S;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("./browserUse-B-b3zqW1.cjs");class k{constructor(){this.state={token:null,metadata:{},isVerified:!1},this.listeners=new Set}identify(e){const{token:t,...s}=e;this.state={token:t,metadata:s,isVerified:!1},this.notify(),console.log("[Crow] User identified")}setVerified(e){this.state={...this.state,isVerified:e},this.notify()}reset(){this.state={token:null,metadata:{},isVerified:!1},this.notify(),console.log("[Crow] User reset")}getToken(){return this.state.token}getState(){return{...this.state}}isIdentified(){return this.state.token!==null}isVerified(){return this.state.isVerified}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){const e=this.getState();for(const t of this.listeners)t(e)}}class C{constructor(){this.handlers={}}register(e){for(const[t,s]of Object.entries(e))typeof s=="function"?(this.handlers[t]=s,console.log(`[Crow] Registered client tool: ${t}`)):console.warn(`[Crow] Skipping ${t}: handler is not a function`)}unregister(e){delete this.handlers[e],console.log(`[Crow] Unregistered client tool: ${e}`)}has(e){return e in this.handlers}getRegisteredTools(){return Object.keys(this.handlers)}async execute(e,t){const s=this.handlers[e];if(!s)return console.warn(`[Crow] No handler registered for tool: ${e}`),{status:"error",error:`No handler registered for tool: ${e}`};try{console.log(`[Crow] Executing client tool: ${e}`,t);const r=await s(t);return console.log(`[Crow] Tool ${e} completed:`,r),r}catch(r){const i=r instanceof Error?r.message:String(r);return console.error(`[Crow] Tool ${e} failed:`,r),{status:"error",error:i}}}}const T="crow_conv_";class S{constructor(e,t){this.currentId=null,this.productId=e,this.apiUrl=t,this.currentId=this.loadFromStorage()}getStorageKey(){return`${T}${this.productId}`}loadFromStorage(){try{return localStorage.getItem(this.getStorageKey())}catch{return null}}saveToStorage(e){try{localStorage.setItem(this.getStorageKey(),e)}catch{}}clearStorage(){try{localStorage.removeItem(this.getStorageKey())}catch{}}getCurrentId(){return this.currentId}setCurrentId(e){this.currentId=e,e?this.saveToStorage(e):this.clearStorage()}hasRestoredConversation(){return this.currentId!==null}clear(){this.currentId=null,this.clearStorage()}async getConversations(e){try{const t=await fetch(`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`);if(!t.ok)throw new Error(`HTTP error: ${t.status}`);return(await t.json()).conversations||[]}catch(t){return console.error("[Crow] Failed to load conversations:",t),[]}}async loadHistory(e,t){try{const s=await fetch(`${this.apiUrl}/api/chat/conversations/${e}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`);if(!s.ok)throw new Error(`HTTP error: ${s.status}`);const r=await s.json();return this.parseHistoryMessages(r.messages||[])}catch(s){return console.error("[Crow] Failed to load conversation history:",s),[]}}async loadAnonymousHistory(e){try{const t=await fetch(`${this.apiUrl}/api/chat/conversations/${e}/history/anonymous?product_id=${this.productId}`);if(!t.ok)throw new Error(`HTTP error: ${t.status}`);const s=await t.json();return this.parseHistoryMessages(s.messages||[])}catch(t){return console.error("[Crow] Failed to load anonymous conversation history:",t),[]}}parseHistoryMessages(e){return e.filter(t=>t.role!=="tool"&&!t.content.startsWith("[Client Tool Result:")).map((t,s)=>({id:`history-${s}`,content:this.parseContent(t.content),role:t.role==="assistant"?"assistant":"user",timestamp:new Date}))}parseContent(e){try{const t=JSON.parse(e);if(Array.isArray(t)){const s=t.find(r=>r.type==="text");return(s==null?void 0:s.text)||e}}catch{}if(e.includes("'type': 'text'")){const t=e.match(/\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/);if(t)return t[1].replace(/\\n/g,`
2
+ `).replace(/\\'/g,"'")}return e}}function M(o){if(o==="[DONE]")return{type:"done"};try{const e=JSON.parse(o);switch(e.type){case"verification_status":return{type:"verification_status",isVerified:e.is_verified===!0};case"conversation_id":return{type:"conversation_id",conversationId:e.conversation_id};case"thinking":return e.status==="complete"?{type:"thinking_complete"}:null;case"thinking_token":return{type:"thinking",content:e.content||""};case"content":return{type:"content",text:e.content||"",accumulated:""};case"citations":return{type:"citations",citations:e.citations};case"error":return{type:"error",message:e.message||"Unknown error"};case"tool_call_start":return{type:"tool_call_start",toolName:e.tool_name,arguments:e.arguments||{}};case"tool_call_complete":return{type:"tool_call_complete",toolName:e.tool_name,success:e.success};case"client_tool_call":return{type:"client_tool_call",toolName:e.tool_name,arguments:e.arguments||{}};case"workflow_started":return{type:"workflow_started",name:e.name,todos:e.todos};case"todo_updated":return{type:"workflow_todo_updated",todoId:e.id,status:e.status};case"workflow_ended":return{type:"workflow_ended"};case"workflow_complete_prompt":return{type:"workflow_complete_prompt"};default:return null}}catch{return console.error("[Crow] Failed to parse SSE data:",o),null}}function*b(o){const e=o.split(`
3
+ `);for(const t of e)t.startsWith("data: ")&&(yield t.slice(6).trim())}async function*v(o,e){var i;const t=(i=o.body)==null?void 0:i.getReader();if(!t)throw new Error("Response body is not readable");const s=new TextDecoder;let r="";try{for(;;){if(e!=null&&e.aborted){t.cancel();return}const{done:l,value:d}=await t.read();if(l)break;const h=s.decode(d);for(const u of b(h)){const c=M(u);if(c&&(c.type==="content"?(r+=c.text,yield{...c,accumulated:r}):yield c,c.type==="done"))return}}}finally{t.releaseLock()}}const g={refreshPage:async()=>{try{return window.location.reload(),{status:"success",data:{message:"Page refresh initiated"}}}catch(o){return{status:"error",error:String(o)}}},whatsOnScreen:async()=>{try{const o=new _.PageController({viewportExpansion:500}),e=await o.getBrowserState();return o.dispose(),{status:"success",data:{url:e.url,title:e.title,content:`${e.header}
4
+
5
+ ${e.content}
6
+
7
+ ${e.footer}`}}}catch(o){return console.error("[Crow] whatsOnScreen error:",o),{status:"error",error:String(o)}}}},I=Object.keys(g),E="https://api.usecrow.org",$="claude-sonnet-4-20250514";class L{constructor(e){this.context={},this.abortController=null,this.callbacks={},this._messages=[],this.messageListeners=new Set,this._isLoading=!1,this.loadingListeners=new Set,this.config={productId:e.productId,apiUrl:e.apiUrl||E,model:e.model||$},this.identity=new k,this.tools=new C,this.conversations=new S(this.config.productId,this.config.apiUrl),this.tools.register(g),console.log("[Crow] Default tools registered:",I.join(", ")),this.identity.subscribe(t=>{var s,r;(r=(s=this.callbacks).onVerificationStatus)==null||r.call(s,t.isVerified)})}get productId(){return this.config.productId}get apiUrl(){return this.config.apiUrl}get model(){return this.config.model}set model(e){this.config.model=e}on(e){this.callbacks={...this.callbacks,...e}}identify(e){this.identity.identify(e)}resetUser(){this.identity.reset(),this.clearMessages()}isIdentified(){return this.identity.isIdentified()}isVerified(){return this.identity.isVerified()}registerTools(e){this.tools.register(e)}unregisterTool(e){this.tools.unregister(e)}getRegisteredTools(){return this.tools.getRegisteredTools()}setContext(e){this.context={...this.context,...e}}clearContext(){this.context={}}get messages(){return[...this._messages]}get isLoading(){return this._isLoading}onMessages(e){return this.messageListeners.add(e),()=>this.messageListeners.delete(e)}onLoading(e){return this.loadingListeners.add(e),()=>this.loadingListeners.delete(e)}clearMessages(){this._messages=[],this.conversations.clear(),this.notifyMessages()}loadMessages(e){this._messages=e,this.notifyMessages()}notifyMessages(){const e=this.messages;for(const t of this.messageListeners)t(e)}setLoading(e){this._isLoading=e;for(const t of this.loadingListeners)t(e)}addMessage(e){var t,s;this._messages=[...this._messages,e],this.notifyMessages(),(s=(t=this.callbacks).onMessage)==null||s.call(t,e)}updateMessage(e,t){var s,r;this._messages=this._messages.map(i=>i.id===e?{...i,...t}:i),this.notifyMessages(),(r=(s=this.callbacks).onMessageUpdate)==null||r.call(s,e,t)}generateMessageId(e){return`${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get conversationId(){return this.conversations.getCurrentId()}set conversationId(e){this.conversations.setCurrentId(e)}async getConversations(){const e=this.identity.getToken();return e?this.conversations.getConversations(e):(console.warn("[Crow] Cannot get conversations: user not identified"),[])}async loadHistory(e){const t=this.identity.getToken();return t?this.conversations.loadHistory(e,t):this.conversations.loadAnonymousHistory(e)}async switchConversation(e){const t=await this.loadHistory(e);this.conversations.setCurrentId(e),this.loadMessages(t)}async*sendMessage(e){var l,d,h,u,c,f,p,y,w,m;if(!e.trim())return;const t=this.generateMessageId("user");this.addMessage({id:t,content:e,role:"user",timestamp:new Date});const s=this.generateMessageId("assistant");this.addMessage({id:s,content:"",role:"assistant",timestamp:new Date}),this.setLoading(!0),this.abortController=new AbortController;let r="",i="";try{const a=await fetch(`${this.config.apiUrl}/api/chat/message`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({product_id:this.config.productId,message:e,conversation_id:this.conversations.getCurrentId(),identity_token:this.identity.getToken(),model:this.config.model,context:Object.keys(this.context).length>0?this.context:void 0}),signal:this.abortController.signal});if(!a.ok)throw new Error(`HTTP error: ${a.status}`);for await(const n of v(a,this.abortController.signal)){switch(n.type){case"content":r=n.accumulated,this.updateMessage(s,{content:r});break;case"thinking":i+=n.content,this.updateMessage(s,{thinking:i});break;case"thinking_complete":this.updateMessage(s,{thinkingComplete:!0});break;case"citations":this.updateMessage(s,{citations:n.citations});break;case"verification_status":this.identity.setVerified(n.isVerified);break;case"conversation_id":this.conversations.setCurrentId(n.conversationId);break;case"client_tool_call":await this.tools.execute(n.toolName,n.arguments),(d=(l=this.callbacks).onToolCall)==null||d.call(l,n);break;case"tool_call_start":case"tool_call_complete":(u=(h=this.callbacks).onToolCall)==null||u.call(h,n);break;case"workflow_started":case"workflow_todo_updated":case"workflow_ended":case"workflow_complete_prompt":(f=(c=this.callbacks).onWorkflow)==null||f.call(c,n);break;case"error":this.updateMessage(s,{content:n.message}),(y=(p=this.callbacks).onError)==null||y.call(p,new Error(n.message));break}yield n}}catch(a){if(a instanceof Error&&a.name==="AbortError"){r?this.updateMessage(s,{content:r}):(this._messages=this._messages.filter(n=>n.id!==s),this.notifyMessages());return}console.error("[Crow] Error:",a),this.updateMessage(s,{content:"Sorry, I encountered an error. Please try again."}),(m=(w=this.callbacks).onError)==null||m.call(w,a instanceof Error?a:new Error(String(a)))}finally{this.setLoading(!1),this.abortController=null}}async send(e){let t=null;for await(const r of this.sendMessage(e))if(r.type==="done")break;const s=this.messages;return s.length>0&&(t=s[s.length-1],t.role==="assistant")?t:null}stop(){this.abortController&&(this.abortController.abort(),this.setLoading(!1))}destroy(){this.stop(),this.messageListeners.clear(),this.loadingListeners.clear()}}exports.CrowBrowserUse=_.CrowBrowserUse;exports.ConversationManager=S;exports.CrowClient=L;exports.DEFAULT_TOOLS=g;exports.DEFAULT_TOOL_NAMES=I;exports.IdentityManager=k;exports.ToolManager=C;exports.parseSSEChunk=b;exports.parseSSEData=M;exports.streamResponse=v;
package/dist/index.d.ts CHANGED
@@ -7,6 +7,9 @@ export declare interface ActiveWorkflow {
7
7
  declare interface BrowserUseConfig {
8
8
  productId: string;
9
9
  apiUrl: string;
10
+ onConfirmation?: (instruction: string) => Promise<boolean>;
11
+ onQuestion?: (question: string) => Promise<string>;
12
+ onProgress?: (step: number, maxSteps: number, action?: string) => void;
10
13
  }
11
14
 
12
15
  export declare interface Citation {
@@ -95,6 +98,7 @@ export declare class CrowBrowserUse {
95
98
  private pageController;
96
99
  private sessionId;
97
100
  private maxSteps;
101
+ private aborted;
98
102
  constructor(config: BrowserUseConfig);
99
103
  /**
100
104
  * Initialize PageController with non-blocking pointer
@@ -283,6 +287,19 @@ export declare interface CrowEventCallbacks {
283
287
  }) => void;
284
288
  onVerificationStatus?: (isVerified: boolean) => void;
285
289
  onError?: (error: Error) => void;
290
+ onBrowserUseConfirmation?: (event: {
291
+ instruction: string;
292
+ toolCallId: string;
293
+ }) => Promise<boolean>;
294
+ onBrowserUseQuestion?: (event: {
295
+ question: string;
296
+ sessionId: string;
297
+ }) => Promise<string>;
298
+ onBrowserUseProgress?: (event: {
299
+ step: number;
300
+ maxSteps: number;
301
+ action?: string;
302
+ }) => void;
286
303
  }
287
304
 
288
305
  export declare const DEFAULT_TOOL_NAMES: DefaultToolName[];
@@ -295,6 +312,10 @@ export declare const DEFAULT_TOOLS: {
295
312
  * Refresh the current page in the user's browser
296
313
  */
297
314
  readonly refreshPage: () => Promise<ToolResult>;
315
+ /**
316
+ * Capture what's on the user's screen (DOM snapshot)
317
+ */
318
+ readonly whatsOnScreen: () => Promise<ToolResult>;
298
319
  };
299
320
 
300
321
  export declare type DefaultToolName = keyof typeof DEFAULT_TOOLS;
@@ -424,6 +445,19 @@ export declare type StreamEvent = {
424
445
  message: string;
425
446
  } | {
426
447
  type: 'done';
448
+ } | {
449
+ type: 'browser_use_confirmation';
450
+ instruction: string;
451
+ toolCallId: string;
452
+ } | {
453
+ type: 'browser_use_question';
454
+ question: string;
455
+ sessionId: string;
456
+ } | {
457
+ type: 'browser_use_progress';
458
+ step: number;
459
+ maxSteps: number;
460
+ action?: string;
427
461
  };
428
462
 
429
463
  /**
@@ -460,7 +494,7 @@ export declare class ToolManager {
460
494
  }
461
495
 
462
496
  export declare interface ToolResult {
463
- status: 'success' | 'error';
497
+ status: 'success' | 'error' | 'needs_input';
464
498
  data?: unknown;
465
499
  error?: string;
466
500
  }
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { C as x } from "./browserUse-BbPG4pH1.js";
2
- class _ {
1
+ import { P as _ } from "./browserUse-D5NUCzN4.js";
2
+ import { C as R } from "./browserUse-D5NUCzN4.js";
3
+ class k {
3
4
  constructor() {
4
5
  this.state = {
5
6
  token: null,
@@ -71,7 +72,7 @@ class _ {
71
72
  e(t);
72
73
  }
73
74
  }
74
- class k {
75
+ class C {
75
76
  constructor() {
76
77
  this.handlers = {};
77
78
  }
@@ -123,7 +124,7 @@ class k {
123
124
  }
124
125
  }
125
126
  }
126
- const C = "crow_conv_";
127
+ const v = "crow_conv_";
127
128
  class b {
128
129
  constructor(t, e) {
129
130
  this.currentId = null, this.productId = t, this.apiUrl = e, this.currentId = this.loadFromStorage();
@@ -132,7 +133,7 @@ class b {
132
133
  * Get localStorage key for this product
133
134
  */
134
135
  getStorageKey() {
135
- return `${C}${this.productId}`;
136
+ return `${v}${this.productId}`;
136
137
  }
137
138
  /**
138
139
  * Load conversation ID from localStorage
@@ -269,11 +270,11 @@ class b {
269
270
  return t;
270
271
  }
271
272
  }
272
- function v(n) {
273
- if (n === "[DONE]")
273
+ function I(o) {
274
+ if (o === "[DONE]")
274
275
  return { type: "done" };
275
276
  try {
276
- const t = JSON.parse(n);
277
+ const t = JSON.parse(o);
277
278
  switch (t.type) {
278
279
  case "verification_status":
279
280
  return {
@@ -347,18 +348,18 @@ function v(n) {
347
348
  return null;
348
349
  }
349
350
  } catch {
350
- return console.error("[Crow] Failed to parse SSE data:", n), null;
351
+ return console.error("[Crow] Failed to parse SSE data:", o), null;
351
352
  }
352
353
  }
353
- function* I(n) {
354
- const t = n.split(`
354
+ function* M(o) {
355
+ const t = o.split(`
355
356
  `);
356
357
  for (const e of t)
357
358
  e.startsWith("data: ") && (yield e.slice(6).trim());
358
359
  }
359
- async function* M(n, t) {
360
+ async function* S(o, t) {
360
361
  var i;
361
- const e = (i = n.body) == null ? void 0 : i.getReader();
362
+ const e = (i = o.body) == null ? void 0 : i.getReader();
362
363
  if (!e)
363
364
  throw new Error("Response body is not readable");
364
365
  const s = new TextDecoder();
@@ -372,8 +373,8 @@ async function* M(n, t) {
372
373
  const { done: l, value: d } = await e.read();
373
374
  if (l) break;
374
375
  const h = s.decode(d);
375
- for (const u of I(h)) {
376
- const c = v(u);
376
+ for (const u of M(h)) {
377
+ const c = I(u);
377
378
  if (c && (c.type === "content" ? (r += c.text, yield { ...c, accumulated: r }) : yield c, c.type === "done"))
378
379
  return;
379
380
  }
@@ -382,28 +383,50 @@ async function* M(n, t) {
382
383
  e.releaseLock();
383
384
  }
384
385
  }
385
- const w = {
386
+ const m = {
386
387
  /**
387
388
  * Refresh the current page in the user's browser
388
389
  */
389
390
  refreshPage: async () => {
390
391
  try {
391
392
  return window.location.reload(), { status: "success", data: { message: "Page refresh initiated" } };
392
- } catch (n) {
393
- return { status: "error", error: String(n) };
393
+ } catch (o) {
394
+ return { status: "error", error: String(o) };
395
+ }
396
+ },
397
+ /**
398
+ * Capture what's on the user's screen (DOM snapshot)
399
+ */
400
+ whatsOnScreen: async () => {
401
+ try {
402
+ const o = new _({ viewportExpansion: 500 }), t = await o.getBrowserState();
403
+ return o.dispose(), {
404
+ status: "success",
405
+ data: {
406
+ url: t.url,
407
+ title: t.title,
408
+ content: `${t.header}
409
+
410
+ ${t.content}
411
+
412
+ ${t.footer}`
413
+ }
414
+ };
415
+ } catch (o) {
416
+ return console.error("[Crow] whatsOnScreen error:", o), { status: "error", error: String(o) };
394
417
  }
395
418
  }
396
- }, S = Object.keys(w), T = "https://api.usecrow.org", $ = "claude-sonnet-4-20250514";
397
- class E {
419
+ }, T = Object.keys(m), $ = "https://api.usecrow.org", E = "claude-sonnet-4-20250514";
420
+ class U {
398
421
  constructor(t) {
399
422
  this.context = {}, this.abortController = null, this.callbacks = {}, this._messages = [], this.messageListeners = /* @__PURE__ */ new Set(), this._isLoading = !1, this.loadingListeners = /* @__PURE__ */ new Set(), this.config = {
400
423
  productId: t.productId,
401
- apiUrl: t.apiUrl || T,
402
- model: t.model || $
403
- }, this.identity = new _(), this.tools = new k(), this.conversations = new b(
424
+ apiUrl: t.apiUrl || $,
425
+ model: t.model || E
426
+ }, this.identity = new k(), this.tools = new C(), this.conversations = new b(
404
427
  this.config.productId,
405
428
  this.config.apiUrl
406
- ), this.tools.register(w), console.log("[Crow] Default tools registered:", S.join(", ")), this.identity.subscribe((e) => {
429
+ ), this.tools.register(m), console.log("[Crow] Default tools registered:", T.join(", ")), this.identity.subscribe((e) => {
407
430
  var s, r;
408
431
  (r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, e.isVerified);
409
432
  });
@@ -610,7 +633,7 @@ class E {
610
633
  * Returns an async generator of stream events
611
634
  */
612
635
  async *sendMessage(t) {
613
- var l, d, h, u, c, g, f, p, y, m;
636
+ var l, d, h, u, c, g, f, p, y, w;
614
637
  if (!t.trim())
615
638
  return;
616
639
  const e = this.generateMessageId("user");
@@ -644,53 +667,53 @@ class E {
644
667
  });
645
668
  if (!a.ok)
646
669
  throw new Error(`HTTP error: ${a.status}`);
647
- for await (const o of M(a, this.abortController.signal)) {
648
- switch (o.type) {
670
+ for await (const n of S(a, this.abortController.signal)) {
671
+ switch (n.type) {
649
672
  case "content":
650
- r = o.accumulated, this.updateMessage(s, { content: r });
673
+ r = n.accumulated, this.updateMessage(s, { content: r });
651
674
  break;
652
675
  case "thinking":
653
- i += o.content, this.updateMessage(s, { thinking: i });
676
+ i += n.content, this.updateMessage(s, { thinking: i });
654
677
  break;
655
678
  case "thinking_complete":
656
679
  this.updateMessage(s, { thinkingComplete: !0 });
657
680
  break;
658
681
  case "citations":
659
- this.updateMessage(s, { citations: o.citations });
682
+ this.updateMessage(s, { citations: n.citations });
660
683
  break;
661
684
  case "verification_status":
662
- this.identity.setVerified(o.isVerified);
685
+ this.identity.setVerified(n.isVerified);
663
686
  break;
664
687
  case "conversation_id":
665
- this.conversations.setCurrentId(o.conversationId);
688
+ this.conversations.setCurrentId(n.conversationId);
666
689
  break;
667
690
  case "client_tool_call":
668
- await this.tools.execute(o.toolName, o.arguments), (d = (l = this.callbacks).onToolCall) == null || d.call(l, o);
691
+ await this.tools.execute(n.toolName, n.arguments), (d = (l = this.callbacks).onToolCall) == null || d.call(l, n);
669
692
  break;
670
693
  case "tool_call_start":
671
694
  case "tool_call_complete":
672
- (u = (h = this.callbacks).onToolCall) == null || u.call(h, o);
695
+ (u = (h = this.callbacks).onToolCall) == null || u.call(h, n);
673
696
  break;
674
697
  case "workflow_started":
675
698
  case "workflow_todo_updated":
676
699
  case "workflow_ended":
677
700
  case "workflow_complete_prompt":
678
- (g = (c = this.callbacks).onWorkflow) == null || g.call(c, o);
701
+ (g = (c = this.callbacks).onWorkflow) == null || g.call(c, n);
679
702
  break;
680
703
  case "error":
681
- this.updateMessage(s, { content: o.message }), (p = (f = this.callbacks).onError) == null || p.call(f, new Error(o.message));
704
+ this.updateMessage(s, { content: n.message }), (p = (f = this.callbacks).onError) == null || p.call(f, new Error(n.message));
682
705
  break;
683
706
  }
684
- yield o;
707
+ yield n;
685
708
  }
686
709
  } catch (a) {
687
710
  if (a instanceof Error && a.name === "AbortError") {
688
- r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((o) => o.id !== s), this.notifyMessages());
711
+ r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((n) => n.id !== s), this.notifyMessages());
689
712
  return;
690
713
  }
691
714
  console.error("[Crow] Error:", a), this.updateMessage(s, {
692
715
  content: "Sorry, I encountered an error. Please try again."
693
- }), (m = (y = this.callbacks).onError) == null || m.call(y, a instanceof Error ? a : new Error(String(a)));
716
+ }), (w = (y = this.callbacks).onError) == null || w.call(y, a instanceof Error ? a : new Error(String(a)));
694
717
  } finally {
695
718
  this.setLoading(!1), this.abortController = null;
696
719
  }
@@ -724,13 +747,13 @@ class E {
724
747
  }
725
748
  export {
726
749
  b as ConversationManager,
727
- x as CrowBrowserUse,
728
- E as CrowClient,
729
- w as DEFAULT_TOOLS,
730
- S as DEFAULT_TOOL_NAMES,
731
- _ as IdentityManager,
732
- k as ToolManager,
733
- I as parseSSEChunk,
734
- v as parseSSEData,
735
- M as streamResponse
750
+ R as CrowBrowserUse,
751
+ U as CrowClient,
752
+ m as DEFAULT_TOOLS,
753
+ T as DEFAULT_TOOL_NAMES,
754
+ k as IdentityManager,
755
+ C as ToolManager,
756
+ M as parseSSEChunk,
757
+ I as parseSSEData,
758
+ S as streamResponse
736
759
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usecrow/client",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "description": "Headless client for Crow AI agents - streaming, auth, tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1,9 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});async function waitFor(e){await new Promise(n=>setTimeout(n,e*1e3))}async function movePointerToElement(e){const n=e.getBoundingClientRect(),s=n.left+n.width/2,i=n.top+n.height/2;window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo",{detail:{x:s,y:i}})),await waitFor(.3)}function getElementByIndex(e,n){const s=e.get(n);if(!s)throw new Error(`No interactive element found at index ${n}`);const i=s.ref;if(!i)throw new Error(`Element at index ${n} does not have a reference`);if(!(i instanceof HTMLElement))throw new Error(`Element at index ${n} is not an HTMLElement`);return i}let lastClickedElement=null;function blurLastClickedElement(){lastClickedElement&&(lastClickedElement.blur(),lastClickedElement.dispatchEvent(new MouseEvent("mouseout",{bubbles:!0,cancelable:!0})),lastClickedElement=null)}async function clickElement(e){blurLastClickedElement(),lastClickedElement=e,await scrollIntoViewIfNeeded(e),await movePointerToElement(e),window.dispatchEvent(new CustomEvent("PageAgent::ClickPointer")),await waitFor(.1),e.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mouseover",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),e.focus(),e.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),e.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0})),await waitFor(.1)}const nativeInputValueSetter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set,nativeTextAreaValueSetter=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value").set;async function inputTextElement(e,n){if(!(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement))throw new Error("Element is not an input or textarea");await clickElement(e),e instanceof HTMLTextAreaElement?nativeTextAreaValueSetter.call(e,n):nativeInputValueSetter.call(e,n);const s=new Event("input",{bubbles:!0});e.dispatchEvent(s),await waitFor(.1),blurLastClickedElement()}async function selectOptionElement(e,n){if(!(e instanceof HTMLSelectElement))throw new Error("Element is not a select element");const i=Array.from(e.options).find(b=>{var d;return((d=b.textContent)==null?void 0:d.trim())===n.trim()});if(!i)throw new Error(`Option with text "${n}" not found in select element`);e.value=i.value,e.dispatchEvent(new Event("change",{bubbles:!0})),await waitFor(.1)}async function scrollIntoViewIfNeeded(e){const n=e;n.scrollIntoViewIfNeeded?n.scrollIntoViewIfNeeded():n.scrollIntoView({behavior:"auto",block:"center",inline:"nearest"})}async function scrollVertically(e,n,s){if(s){const l=s;console.log("[SCROLL DEBUG] Starting direct container scroll for element:",l.tagName);let h=l,v=!1,w=null,u=0,f=0;const T=n;for(;h&&f<10;){const F=window.getComputedStyle(h),P=/(auto|scroll|overlay)/.test(F.overflowY),O=h.scrollHeight>h.clientHeight;if(console.log("[SCROLL DEBUG] Checking element:",h.tagName,"hasScrollableY:",P,"canScrollVertically:",O,"scrollHeight:",h.scrollHeight,"clientHeight:",h.clientHeight),P&&O){const R=h.scrollTop,z=h.scrollHeight-h.clientHeight;let H=T/3;H>0?H=Math.min(H,z-R):H=Math.max(H,-R),h.scrollTop=R+H;const D=h.scrollTop,_=D-R;if(console.log("[SCROLL DEBUG] Scroll attempt:",h.tagName,"before:",R,"after:",D,"delta:",_),Math.abs(_)>.5){v=!0,w=h,u=_,console.log("[SCROLL DEBUG] Successfully scrolled container:",h.tagName,"delta:",_);break}}if(h===document.body||h===document.documentElement)break;h=h.parentElement,f++}return v?`Scrolled container (${w==null?void 0:w.tagName}) by ${u}px`:`No scrollable container found for element (${l.tagName})`}const i=n,b=l=>l.clientHeight>=window.innerHeight*.5,d=l=>l&&/(auto|scroll|overlay)/.test(getComputedStyle(l).overflowY)&&l.scrollHeight>l.clientHeight&&b(l);let r=document.activeElement;for(;r&&!d(r)&&r!==document.body;)r=r.parentElement;if(r=d(r)?r:Array.from(document.querySelectorAll("*")).find(d)||document.scrollingElement||document.documentElement,r===document.scrollingElement||r===document.documentElement||r===document.body){const l=window.scrollY,h=document.documentElement.scrollHeight-window.innerHeight;window.scrollBy(0,i);const v=window.scrollY,w=v-l;if(Math.abs(w)<1)return i>0?"⚠️ Already at the bottom of the page, cannot scroll down further.":"⚠️ Already at the top of the page, cannot scroll up further.";const u=i>0&&v>=h-1,f=i<0&&v<=1;return u?`✅ Scrolled page by ${w}px. Reached the bottom of the page.`:f?`✅ Scrolled page by ${w}px. Reached the top of the page.`:`✅ Scrolled page by ${w}px.`}else{const l=r.scrollTop,h=r.scrollHeight-r.clientHeight;r.scrollBy({top:i,behavior:"smooth"}),await waitFor(.1);const v=r.scrollTop,w=v-l;if(Math.abs(w)<1)return i>0?`⚠️ Already at the bottom of container (${r.tagName}), cannot scroll down further.`:`⚠️ Already at the top of container (${r.tagName}), cannot scroll up further.`;const u=i>0&&v>=h-1,f=i<0&&v<=1;return u?`✅ Scrolled container (${r.tagName}) by ${w}px. Reached the bottom.`:f?`✅ Scrolled container (${r.tagName}) by ${w}px. Reached the top.`:`✅ Scrolled container (${r.tagName}) by ${w}px.`}}async function scrollHorizontally(e,n,s){if(s){const l=s;console.log("[SCROLL DEBUG] Starting direct container scroll for element:",l.tagName);let h=l,v=!1,w=null,u=0,f=0;const T=e?n:-n;for(;h&&f<10;){const F=window.getComputedStyle(h),P=/(auto|scroll|overlay)/.test(F.overflowX),O=h.scrollWidth>h.clientWidth;if(console.log("[SCROLL DEBUG] Checking element:",h.tagName,"hasScrollableX:",P,"canScrollHorizontally:",O,"scrollWidth:",h.scrollWidth,"clientWidth:",h.clientWidth),P&&O){const R=h.scrollLeft,z=h.scrollWidth-h.clientWidth;let H=T/3;H>0?H=Math.min(H,z-R):H=Math.max(H,-R),h.scrollLeft=R+H;const D=h.scrollLeft,_=D-R;if(console.log("[SCROLL DEBUG] Scroll attempt:",h.tagName,"before:",R,"after:",D,"delta:",_),Math.abs(_)>.5){v=!0,w=h,u=_,console.log("[SCROLL DEBUG] Successfully scrolled container:",h.tagName,"delta:",_);break}}if(h===document.body||h===document.documentElement)break;h=h.parentElement,f++}return v?`Scrolled container (${w==null?void 0:w.tagName}) horizontally by ${u}px`:`No horizontally scrollable container found for element (${l.tagName})`}const i=e?n:-n,b=l=>l.clientWidth>=window.innerWidth*.5,d=l=>l&&/(auto|scroll|overlay)/.test(getComputedStyle(l).overflowX)&&l.scrollWidth>l.clientWidth&&b(l);let r=document.activeElement;for(;r&&!d(r)&&r!==document.body;)r=r.parentElement;if(r=d(r)?r:Array.from(document.querySelectorAll("*")).find(d)||document.scrollingElement||document.documentElement,r===document.scrollingElement||r===document.documentElement||r===document.body){const l=window.scrollX,h=document.documentElement.scrollWidth-window.innerWidth;window.scrollBy(i,0);const v=window.scrollX,w=v-l;if(Math.abs(w)<1)return i>0?"⚠️ Already at the right edge of the page, cannot scroll right further.":"⚠️ Already at the left edge of the page, cannot scroll left further.";const u=i>0&&v>=h-1,f=i<0&&v<=1;return u?`✅ Scrolled page by ${w}px. Reached the right edge of the page.`:f?`✅ Scrolled page by ${w}px. Reached the left edge of the page.`:`✅ Scrolled page horizontally by ${w}px.`}else{const l=r.scrollLeft,h=r.scrollWidth-r.clientWidth;r.scrollBy({left:i,behavior:"smooth"}),await waitFor(.1);const v=r.scrollLeft,w=v-l;if(Math.abs(w)<1)return i>0?`⚠️ Already at the right edge of container (${r.tagName}), cannot scroll right further.`:`⚠️ Already at the left edge of container (${r.tagName}), cannot scroll left further.`;const u=i>0&&v>=h-1,f=i<0&&v<=1;return u?`✅ Scrolled container (${r.tagName}) by ${w}px. Reached the right edge.`:f?`✅ Scrolled container (${r.tagName}) by ${w}px. Reached the left edge.`:`✅ Scrolled container (${r.tagName}) horizontally by ${w}px.`}}const VIEWPORT_EXPANSION=-1,domTree=(e={doHighlightElements:!0,focusHighlightIndex:-1,viewportExpansion:0,debugMode:!1,interactiveBlacklist:[],interactiveWhitelist:[],highlightOpacity:.1,highlightLabelOpacity:.5})=>{const{interactiveBlacklist:n,interactiveWhitelist:s,highlightOpacity:i,highlightLabelOpacity:b}=e,{doHighlightElements:d,focusHighlightIndex:r,viewportExpansion:l,debugMode:h}=e;let v=0;const w=new WeakMap;function u(t,o){!t||t.nodeType!==Node.ELEMENT_NODE||w.set(t,{...w.get(t),...o})}const f={boundingRects:new WeakMap,clientRects:new WeakMap,computedStyles:new WeakMap,clearCache:()=>{f.boundingRects=new WeakMap,f.clientRects=new WeakMap,f.computedStyles=new WeakMap}};function T(t){if(!t)return null;if(f.boundingRects.has(t))return f.boundingRects.get(t);const o=t.getBoundingClientRect();return o&&f.boundingRects.set(t,o),o}function F(t){if(!t)return null;if(f.computedStyles.has(t))return f.computedStyles.get(t);const o=window.getComputedStyle(t);return o&&f.computedStyles.set(t,o),o}function P(t){if(!t)return null;if(f.clientRects.has(t))return f.clientRects.get(t);const o=t.getClientRects();return o&&f.clientRects.set(t,o),o}const O={},R={current:0},z="playwright-highlight-container";function H(t,o,p=null){if(!t)return o;const a=[];let c=null,x=20,E=16,M=null;try{let m=document.getElementById(z);m||(m=document.createElement("div"),m.id=z,m.style.position="fixed",m.style.pointerEvents="none",m.style.top="0",m.style.left="0",m.style.width="100%",m.style.height="100%",m.style.zIndex="2147483640",m.style.backgroundColor="transparent",document.body.appendChild(m));const L=t.getClientRects();if(!L||L.length===0)return o;const A=["#FF0000","#00FF00","#0000FF","#FFA500","#800080","#008080","#FF69B4","#4B0082","#FF4500","#2E8B57","#DC143C","#4682B4"],g=o%A.length;let y=A[g];const k=y+Math.floor(i*255).toString(16).padStart(2,"0");y=y+Math.floor(b*255).toString(16).padStart(2,"0");let S={x:0,y:0};if(p){const I=p.getBoundingClientRect();S.x=I.left,S.y=I.top}const B=document.createDocumentFragment();for(const I of L){if(I.width===0||I.height===0)continue;const $=document.createElement("div");$.style.position="fixed",$.style.border=`2px solid ${y}`,$.style.backgroundColor=k,$.style.pointerEvents="none",$.style.boxSizing="border-box";const N=I.top+S.y,q=I.left+S.x;$.style.top=`${N}px`,$.style.left=`${q}px`,$.style.width=`${I.width}px`,$.style.height=`${I.height}px`,B.appendChild($),a.push({element:$,initialRect:I})}const G=L[0];c=document.createElement("div"),c.className="playwright-highlight-label",c.style.position="fixed",c.style.background=y,c.style.color="white",c.style.padding="1px 4px",c.style.borderRadius="4px",c.style.fontSize=`${Math.min(12,Math.max(8,G.height/2))}px`,c.textContent=o.toString(),x=c.offsetWidth>0?c.offsetWidth:x,E=c.offsetHeight>0?c.offsetHeight:E;const Y=G.top+S.y,Z=G.left+S.x;let j=Y+2,J=Z+G.width-x-2;(G.width<x+4||G.height<E+4)&&(j=Y-E-2,J=Z+G.width-x,J<S.x&&(J=Z)),j=Math.max(0,Math.min(j,window.innerHeight-E)),J=Math.max(0,Math.min(J,window.innerWidth-x)),c.style.top=`${j}px`,c.style.left=`${J}px`,B.appendChild(c);const it=((I,$)=>{let N=0;return(...q)=>{const V=performance.now();if(!(V-N<$))return N=V,I(...q)}})(()=>{const I=t.getClientRects();let $={x:0,y:0};if(p){const N=p.getBoundingClientRect();$.x=N.left,$.y=N.top}if(a.forEach((N,q)=>{if(q<I.length){const V=I[q],et=V.top+$.y,K=V.left+$.x;N.element.style.top=`${et}px`,N.element.style.left=`${K}px`,N.element.style.width=`${V.width}px`,N.element.style.height=`${V.height}px`,N.element.style.display=V.width===0||V.height===0?"none":"block"}else N.element.style.display="none"}),I.length<a.length)for(let N=I.length;N<a.length;N++)a[N].element.style.display="none";if(c&&I.length>0){const N=I[0],q=N.top+$.y,V=N.left+$.x;let et=q+2,K=V+N.width-x-2;(N.width<x+4||N.height<E+4)&&(et=q-E-2,K=V+N.width-x,K<$.x&&(K=V)),et=Math.max(0,Math.min(et,window.innerHeight-E)),K=Math.max(0,Math.min(K,window.innerWidth-x)),c.style.top=`${et}px`,c.style.left=`${K}px`,c.style.display="block"}else c&&(c.style.display="none")},16);return window.addEventListener("scroll",it,!0),window.addEventListener("resize",it),M=()=>{window.removeEventListener("scroll",it,!0),window.removeEventListener("resize",it),a.forEach(I=>I.element.remove()),c&&c.remove()},m.appendChild(B),o+1}finally{M&&(window._highlightCleanupFunctions=window._highlightCleanupFunctions||[]).push(M)}}function D(t){if(!t||t.nodeType!==Node.ELEMENT_NODE)return null;const o=F(t);if(!o)return null;const p=o.display;if(p==="inline"||p==="inline-block")return null;const a=o.overflowX,c=o.overflowY,x=a==="auto"||a==="scroll",E=c==="auto"||c==="scroll";if(!x&&!E)return null;const M=t.scrollWidth-t.clientWidth,m=t.scrollHeight-t.clientHeight,L=4;if(M<L&&m<L||!E&&M<L||!x&&m<L)return null;const A=t.scrollTop,g=t.scrollLeft,y=t.scrollWidth-t.clientWidth-t.scrollLeft,k=t.scrollHeight-t.clientHeight-t.scrollTop,S={top:A,right:y,bottom:k,left:g};return u(t,{scrollable:!0,scrollData:S}),S}function _(t){try{if(l===-1){const E=t.parentElement;if(!E)return!1;try{return E.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const m=window.getComputedStyle(E);return m.display!=="none"&&m.visibility!=="hidden"&&m.opacity!=="0"}}const o=document.createRange();o.selectNodeContents(t);const p=o.getClientRects();if(!p||p.length===0)return!1;let a=!1,c=!1;for(const E of p)if(E.width>0&&E.height>0&&(a=!0,!(E.bottom<-l||E.top>window.innerHeight+l||E.right<-l||E.left>window.innerWidth+l))){c=!0;break}if(!a||!c)return!1;const x=t.parentElement;if(!x)return!1;try{return x.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0})}catch{const M=window.getComputedStyle(x);return M.display!=="none"&&M.visibility!=="hidden"&&M.opacity!=="0"}}catch(o){return console.warn("Error checking text node visibility:",o),!1}}function rt(t){if(!t||!t.tagName)return!1;const o=new Set(["body","div","main","article","section","nav","header","footer"]),p=t.tagName.toLowerCase();return o.has(p)?!0:!new Set(["svg","script","style","link","meta","noscript","template"]).has(p)}function U(t){const o=F(t);return t.offsetWidth>0&&t.offsetHeight>0&&(o==null?void 0:o.visibility)!=="hidden"&&(o==null?void 0:o.display)!=="none"}function C(t){var k,S;if(!t||t.nodeType!==Node.ELEMENT_NODE||n.includes(t))return!1;if(s.includes(t))return!0;const o=t.tagName.toLowerCase(),p=F(t),a=new Set(["pointer","move","text","grab","grabbing","cell","copy","alias","all-scroll","col-resize","context-menu","crosshair","e-resize","ew-resize","help","n-resize","ne-resize","nesw-resize","ns-resize","nw-resize","nwse-resize","row-resize","s-resize","se-resize","sw-resize","vertical-text","w-resize","zoom-in","zoom-out"]),c=new Set(["not-allowed","no-drop","wait","progress","initial","inherit"]);function x(B){return B.tagName.toLowerCase()==="html"?!1:!!(p!=null&&p.cursor&&a.has(p.cursor))}if(x(t))return!0;const M=new Set(["a","button","input","select","textarea","details","summary","label","option","optgroup","fieldset","legend"]),m=new Set(["disabled","readonly"]);if(M.has(o)){if(p!=null&&p.cursor&&c.has(p.cursor))return!1;for(const B of m)if(t.hasAttribute(B)||t.getAttribute(B)==="true"||t.getAttribute(B)==="")return!1;return!(t.disabled||t.readOnly||t.inert)}const L=t.getAttribute("role"),A=t.getAttribute("aria-role");if(t.getAttribute("contenteditable")==="true"||t.isContentEditable||t.classList&&(t.classList.contains("button")||t.classList.contains("dropdown-toggle")||t.getAttribute("data-index")||t.getAttribute("data-toggle")==="dropdown"||t.getAttribute("aria-haspopup")==="true"))return!0;const g=new Set(["button","menu","menubar","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);if(M.has(o)||L&&g.has(L)||A&&g.has(A))return!0;try{if(typeof getEventListeners=="function"){const Y=getEventListeners(t),Z=["click","mousedown","mouseup","dblclick"];for(const j of Z)if(Y[j]&&Y[j].length>0)return!0}const B=((S=(k=t==null?void 0:t.ownerDocument)==null?void 0:k.defaultView)==null?void 0:S.getEventListenersForNode)||window.getEventListenersForNode;if(typeof B=="function"){const Y=B(t),Z=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const j of Z)for(const J of Y)if(J.type===j)return!0}const G=["onclick","onmousedown","onmouseup","ondblclick"];for(const Y of G)if(t.hasAttribute(Y)||typeof t[Y]=="function")return!0}catch{}return!!D(t)}function ot(t){if(l===-1)return!0;const o=P(t);if(!o||o.length===0)return!1;let p=!1;for(const m of o)if(m.width>0&&m.height>0&&!(m.bottom<-l||m.top>window.innerHeight+l||m.right<-l||m.left>window.innerWidth+l)){p=!0;break}if(!p)return!1;if(t.ownerDocument!==window.document)return!0;let c=Array.from(o).find(m=>m.width>0&&m.height>0);if(!c)return!1;const x=t.getRootNode();if(x instanceof ShadowRoot){const m=c.left+c.width/2,L=c.top+c.height/2;try{const A=x.elementFromPoint(m,L);if(!A)return!1;let g=A;for(;g&&g!==x;){if(g===t)return!0;g=g.parentElement}return!1}catch{return!0}}const E=5;return[{x:c.left+c.width/2,y:c.top+c.height/2},{x:c.left+E,y:c.top+E},{x:c.right-E,y:c.bottom-E}].some(({x:m,y:L})=>{try{const A=document.elementFromPoint(m,L);if(!A)return!1;let g=A;for(;g&&g!==document.documentElement;){if(g===t)return!0;g=g.parentElement}return!1}catch{return!0}})}function st(t,o){if(o===-1)return!0;const p=t.getClientRects();if(!p||p.length===0){const a=T(t);return!a||a.width===0||a.height===0?!1:!(a.bottom<-o||a.top>window.innerHeight+o||a.right<-o||a.left>window.innerWidth+o)}for(const a of p)if(!(a.width===0||a.height===0)&&!(a.bottom<-o||a.top>window.innerHeight+o||a.right<-o||a.left>window.innerWidth+o))return!0;return!1}function W(t){if(!t||t.nodeType!==Node.ELEMENT_NODE)return!1;const o=t.tagName.toLowerCase();return new Set(["a","button","input","select","textarea","details","summary","label"]).has(o)?!0:t.hasAttribute("onclick")||t.hasAttribute("role")||t.hasAttribute("tabindex")||t.hasAttribute("aria-")||t.hasAttribute("data-action")||t.getAttribute("contenteditable")==="true"}const X=new Set(["a","button","input","select","textarea","summary","details","label","option"]),Q=new Set(["button","link","menuitem","menuitemradio","menuitemcheckbox","radio","checkbox","tab","switch","slider","spinbutton","combobox","searchbox","textbox","listbox","option","scrollbar"]);function nt(t){if(!t||t.nodeType!==Node.ELEMENT_NODE||!U(t))return!1;const o=t.hasAttribute("role")||t.hasAttribute("tabindex")||t.hasAttribute("onclick")||typeof t.onclick=="function",p=/\b(btn|clickable|menu|item|entry|link)\b/i.test(t.className||""),a=!!t.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'),c=[...t.children].some(U),x=t.parentElement&&t.parentElement.isSameNode(document.body);return(C(t)||o||p)&&c&&a&&!x}function lt(t){var a,c;if(!t||t.nodeType!==Node.ELEMENT_NODE)return!1;const o=t.tagName.toLowerCase(),p=t.getAttribute("role");if(o==="iframe"||X.has(o)||p&&Q.has(p)||t.isContentEditable||t.getAttribute("contenteditable")==="true"||t.hasAttribute("data-testid")||t.hasAttribute("data-cy")||t.hasAttribute("data-test")||t.hasAttribute("onclick")||typeof t.onclick=="function")return!0;try{const x=((c=(a=t==null?void 0:t.ownerDocument)==null?void 0:a.defaultView)==null?void 0:c.getEventListenersForNode)||window.getEventListenersForNode;if(typeof x=="function"){const M=x(t),m=["click","mousedown","mouseup","keydown","keyup","submit","change","input","focus","blur"];for(const L of m)for(const A of M)if(A.type===L)return!0}if(["onmousedown","onmouseup","onkeydown","onkeyup","onsubmit","onchange","oninput","onfocus","onblur"].some(M=>t.hasAttribute(M)))return!0}catch{}return!!nt(t)}function ct(t,o,p,a){if(!t.isInteractive)return!1;let c=!1;return a?lt(o)?c=!0:c=!1:c=!0,c&&(t.isInViewport=st(o,l),(t.isInViewport||l===-1)&&(t.highlightIndex=v++,d))?(r>=0?r===t.highlightIndex&&H(o,t.highlightIndex,p):H(o,t.highlightIndex,p),!0):!1}function tt(t,o=null,p=!1){var E,M,m,L,A;if(!t||t.id===z||t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.TEXT_NODE||!t||t.id===z||((E=t.dataset)==null?void 0:E.browserUseIgnore)==="true"||t.getAttribute&&t.getAttribute("aria-hidden")==="true")return null;if(t===document.body){const g={tagName:"body",attributes:{},xpath:"/body",children:[]};for(const k of t.childNodes){const S=tt(k,o,!1);S&&g.children.push(S)}const y=`${R.current++}`;return O[y]=g,y}if(t.nodeType!==Node.ELEMENT_NODE&&t.nodeType!==Node.TEXT_NODE)return null;if(t.nodeType===Node.TEXT_NODE){const g=(M=t.textContent)==null?void 0:M.trim();if(!g)return null;const y=t.parentElement;if(!y||y.tagName.toLowerCase()==="script")return null;const k=`${R.current++}`;return O[k]={type:"TEXT_NODE",text:g,isVisible:_(t)},k}if(t.nodeType===Node.ELEMENT_NODE&&!rt(t))return null;if(l!==-1&&!t.shadowRoot){const g=T(t),y=F(t),k=y&&(y.position==="fixed"||y.position==="sticky"),S=t.offsetWidth>0||t.offsetHeight>0;if(!g||!k&&!S&&(g.bottom<-l||g.top>window.innerHeight+l||g.right<-l||g.left>window.innerWidth+l))return null}const a={tagName:t.tagName.toLowerCase(),attributes:{},children:[]};if(W(t)||t.tagName.toLowerCase()==="iframe"||t.tagName.toLowerCase()==="body"){const g=((m=t.getAttributeNames)==null?void 0:m.call(t))||[];for(const y of g){const k=t.getAttribute(y);a.attributes[y]=k}t.tagName.toLowerCase()==="input"&&(t.type==="checkbox"||t.type==="radio")&&(a.attributes.checked=t.checked?"true":"false")}let c=!1;if(t.nodeType===Node.ELEMENT_NODE&&(a.isVisible=U(t),a.isVisible)){a.isTopElement=ot(t);const g=t.getAttribute("role"),y=g==="menu"||g==="menubar"||g==="listbox";(a.isTopElement||y)&&(a.isInteractive=C(t),c=ct(a,t,o,p),a.ref=t)}if(t.tagName){const g=t.tagName.toLowerCase();if(g==="iframe")try{const y=t.contentDocument||((L=t.contentWindow)==null?void 0:L.document);if(y)for(const k of y.childNodes){const S=tt(k,t,!1);S&&a.children.push(S)}}catch(y){console.warn("Unable to access iframe:",y)}else if(t.isContentEditable||t.getAttribute("contenteditable")==="true"||t.id==="tinymce"||t.classList.contains("mce-content-body")||g==="body"&&((A=t.getAttribute("data-id"))!=null&&A.startsWith("mce_")))for(const y of t.childNodes){const k=tt(y,o,c);k&&a.children.push(k)}else{if(t.shadowRoot){a.shadowRoot=!0;for(const y of t.shadowRoot.childNodes){const k=tt(y,o,c);k&&a.children.push(k)}}for(const y of t.childNodes){const S=tt(y,o,c||p);S&&a.children.push(S)}}}if(a.tagName==="a"&&a.children.length===0&&!a.attributes.href){const g=T(t);if(!(g&&g.width>0&&g.height>0||t.offsetWidth>0||t.offsetHeight>0))return null}a.extra=w.get(t)||null;const x=`${R.current++}`;return O[x]=a,x}const at=tt(document.body);return f.clearCache(),{rootId:at,map:O}},newElementsCache=new WeakMap;function getFlatTree(e){const n=[];for(const d of e.interactiveBlacklist||[])typeof d=="function"?n.push(d()):n.push(d);const s=[];for(const d of e.interactiveWhitelist||[])typeof d=="function"?s.push(d()):s.push(d);const i=domTree({doHighlightElements:!0,debugMode:!0,focusHighlightIndex:-1,viewportExpansion:VIEWPORT_EXPANSION,interactiveBlacklist:n,interactiveWhitelist:s,highlightOpacity:e.highlightOpacity??0,highlightLabelOpacity:e.highlightLabelOpacity??.1}),b=window.location.href;for(const d in i.map){const r=i.map[d];if(r.isInteractive&&r.ref){const l=r.ref;newElementsCache.has(l)||(newElementsCache.set(l,b),r.isNew=!0)}}return i}function flatTreeToString(e,n){const s=["title","type","checked","name","role","value","placeholder","data-date-format","alt","aria-label","aria-expanded","data-state","aria-checked","id","for","target","aria-haspopup","aria-controls","aria-owns"],i=[...n||[],...s],b=(u,f)=>u.length>f?u.substring(0,f)+"...":u,d=u=>{const f=e.map[u];if(!f)return null;if(f.type==="TEXT_NODE"){const T=f;return{type:"text",text:T.text,isVisible:T.isVisible,parent:null,children:[]}}else{const T=f,F=[];if(T.children)for(const P of T.children){const O=d(P);O&&(O.parent=null,F.push(O))}return{type:"element",tagName:T.tagName,attributes:T.attributes??{},isVisible:T.isVisible??!1,isInteractive:T.isInteractive??!1,isTopElement:T.isTopElement??!1,isNew:T.isNew??!1,highlightIndex:T.highlightIndex,parent:null,children:F,extra:T.extra??{}}}},r=(u,f=null)=>{u.parent=f;for(const T of u.children)r(T,u)},l=d(e.rootId);if(!l)return"";r(l);const h=u=>{let f=u.parent;for(;f;){if(f.type==="element"&&f.highlightIndex!==void 0)return!0;f=f.parent}return!1},v=(u,f,T)=>{var O,R,z,H;let F=f;const P=" ".repeat(f);if(u.type==="element"){if(u.highlightIndex!==void 0){F+=1;const D=getAllTextTillNextClickableElement(u);let _="";if(i.length>0&&u.attributes){const C={};for(const W of i){const X=u.attributes[W];X&&X.trim()!==""&&(C[W]=X.trim())}const ot=i.filter(W=>W in C);if(ot.length>1){const W=new Set,X={};for(const Q of ot){const nt=C[Q];nt.length>5&&(nt in X?W.add(Q):X[nt]=Q)}for(const Q of W)delete C[Q]}C.role===u.tagName&&delete C.role;const st=["aria-label","placeholder","title"];for(const W of st)C[W]&&C[W].toLowerCase().trim()===D.toLowerCase().trim()&&delete C[W];Object.keys(C).length>0&&(_=Object.entries(C).map(([W,X])=>`${W}=${b(X,20)}`).join(" "))}const rt=u.isNew?`*[${u.highlightIndex}]`:`[${u.highlightIndex}]`;let U=`${P}${rt}<${u.tagName??""}`;if(_&&(U+=` ${_}`),u.extra&&u.extra.scrollable){let C="";(O=u.extra.scrollData)!=null&&O.left&&(C+=`left=${u.extra.scrollData.left}, `),(R=u.extra.scrollData)!=null&&R.top&&(C+=`top=${u.extra.scrollData.top}, `),(z=u.extra.scrollData)!=null&&z.right&&(C+=`right=${u.extra.scrollData.right}, `),(H=u.extra.scrollData)!=null&&H.bottom&&(C+=`bottom=${u.extra.scrollData.bottom}`),U+=` data-scrollable="${C}"`}if(D){const C=D.trim();_||(U+=" "),U+=`>${C}`}else _||(U+=" ");U+=" />",T.push(U)}for(const D of u.children)v(D,F,T)}else if(u.type==="text"){if(h(u))return;u.parent&&u.parent.type==="element"&&u.parent.isVisible&&u.parent.isTopElement&&T.push(`${P}${u.text??""}`)}},w=[];return v(l,0,w),w.join(`
2
- `)}const getAllTextTillNextClickableElement=(e,n=-1)=>{const s=[],i=(b,d)=>{if(!(n!==-1&&d>n)&&!(b.type==="element"&&b!==e&&b.highlightIndex!==void 0)){if(b.type==="text"&&b.text)s.push(b.text);else if(b.type==="element")for(const r of b.children)i(r,d+1)}};return i(e,0),s.join(`
3
- `).trim()};function getSelectorMap(e){const n=new Map,s=Object.keys(e.map);for(const i of s){const b=e.map[i];b.isInteractive&&typeof b.highlightIndex=="number"&&n.set(b.highlightIndex,b)}return n}function getElementTextMap(e){const n=e.split(`
4
- `).map(i=>i.trim()).filter(i=>i.length>0),s=new Map;for(const i of n){const d=/^\[(\d+)\]<[^>]+>([^<]*)/.exec(i);if(d){const r=parseInt(d[1],10);s.set(r,i)}}return s}function cleanUpHighlights(){const e=window._highlightCleanupFunctions||[];for(const n of e)typeof n=="function"&&n();window._highlightCleanupFunctions=[]}window.addEventListener("popstate",()=>{cleanUpHighlights()});window.addEventListener("hashchange",()=>{cleanUpHighlights()});window.addEventListener("beforeunload",()=>{cleanUpHighlights()});const navigation=window.navigation;if(navigation&&typeof navigation.addEventListener=="function")navigation.addEventListener("navigate",()=>{cleanUpHighlights()});else{let e=window.location.href;setInterval(()=>{window.location.href!==e&&(e=window.location.href,cleanUpHighlights())},500)}function getPageInfo(){const e=window.innerWidth,n=window.innerHeight,s=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth||0),i=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight||0),b=window.scrollX||window.pageXOffset||document.documentElement.scrollLeft||0,d=window.scrollY||window.pageYOffset||document.documentElement.scrollTop||0,r=Math.max(0,i-(window.innerHeight+d)),l=Math.max(0,s-(window.innerWidth+b));return{viewport_width:e,viewport_height:n,page_width:s,page_height:i,scroll_x:b,scroll_y:d,pixels_above:d,pixels_below:r,pages_above:n>0?d/n:0,pages_below:n>0?r/n:0,total_pages:n>0?i/n:0,current_page_position:d/Math.max(1,i-n),pixels_left:b,pixels_right:l}}function patchReact(e){const n=document.querySelectorAll('[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root');for(const s of n)s.setAttribute("data-page-agent-not-interactive","true")}class PageController extends EventTarget{constructor(e={}){super(),this.flatTree=null,this.selectorMap=new Map,this.elementTextMap=new Map,this.simplifiedHTML="<EMPTY>",this.lastTimeUpdate=0,this.isIndexed=!1,this.mask=null,this.maskReady=null,this.config=e,patchReact(),e.enableMask&&this.initMask()}initMask(){this.maskReady===null&&(this.maskReady=(async()=>{const{SimulatorMask:e}=await Promise.resolve().then(()=>require("./SimulatorMask-DoBLczoQ.cjs"));this.mask=new e})())}async getCurrentUrl(){return window.location.href}async getLastUpdateTime(){return this.lastTimeUpdate}async getBrowserState(){const e=window.location.href,n=document.title,s=getPageInfo(),i=this.config.viewportExpansion??VIEWPORT_EXPANSION;await this.updateTree();const b=this.simplifiedHTML,d=`Current Page: [${n}](${e})`,r=`Page info: ${s.viewport_width}x${s.viewport_height}px viewport, ${s.page_width}x${s.page_height}px total page size, ${s.pages_above.toFixed(1)} pages above, ${s.pages_below.toFixed(1)} pages below, ${s.total_pages.toFixed(1)} total pages, at ${(s.current_page_position*100).toFixed(0)}% of page`,l=i===-1?"Interactive elements from top layer of the current page (full page):":"Interactive elements from top layer of the current page inside the viewport:",v=s.pixels_above>4&&i!==-1?`... ${s.pixels_above} pixels above (${s.pages_above.toFixed(1)} pages) - scroll to see more ...`:"[Start of page]",w=`${d}
5
- ${r}
6
-
7
- ${l}
8
-
9
- ${v}`,f=s.pixels_below>4&&i!==-1?`... ${s.pixels_below} pixels below (${s.pages_below.toFixed(1)} pages) - scroll to see more ...`:"[End of page]";return{url:e,title:n,header:w,content:b,footer:f}}async updateTree(){this.dispatchEvent(new Event("beforeUpdate")),this.lastTimeUpdate=Date.now(),this.mask&&(this.mask.wrapper.style.pointerEvents="none"),cleanUpHighlights();const e=[...this.config.interactiveBlacklist||[],...document.querySelectorAll("[data-page-agent-not-interactive]").values()];return this.flatTree=getFlatTree({...this.config,interactiveBlacklist:e}),this.simplifiedHTML=flatTreeToString(this.flatTree,this.config.include_attributes),this.selectorMap.clear(),this.selectorMap=getSelectorMap(this.flatTree),this.elementTextMap.clear(),this.elementTextMap=getElementTextMap(this.simplifiedHTML),this.isIndexed=!0,this.mask&&(this.mask.wrapper.style.pointerEvents="auto"),this.dispatchEvent(new Event("afterUpdate")),this.simplifiedHTML}async cleanUpHighlights(){cleanUpHighlights()}assertIndexed(){if(!this.isIndexed)throw new Error("DOM tree not indexed yet. Can not perform actions on elements.")}async clickElement(e){try{this.assertIndexed();const n=getElementByIndex(this.selectorMap,e),s=this.elementTextMap.get(e);return await clickElement(n),n instanceof HTMLAnchorElement&&n.target==="_blank"?{success:!0,message:`✅ Clicked element (${s??e}). ⚠️ Link opens in a new tab. You are not capable of reading new tabs.`}:{success:!0,message:`✅ Clicked element (${s??e}).`}}catch(n){return{success:!1,message:`❌ Failed to click element: ${n}`}}}async inputText(e,n){try{this.assertIndexed();const s=getElementByIndex(this.selectorMap,e),i=this.elementTextMap.get(e);return await inputTextElement(s,n),{success:!0,message:`✅ Input text (${n}) into element (${i??e}).`}}catch(s){return{success:!1,message:`❌ Failed to input text: ${s}`}}}async selectOption(e,n){try{this.assertIndexed();const s=getElementByIndex(this.selectorMap,e),i=this.elementTextMap.get(e);return await selectOptionElement(s,n),{success:!0,message:`✅ Selected option (${n}) in element (${i??e}).`}}catch(s){return{success:!1,message:`❌ Failed to select option: ${s}`}}}async scroll(e){try{const{down:n,numPages:s,pixels:i,index:b}=e;this.assertIndexed();const d=i??s*(n?1:-1)*window.innerHeight,r=b!==void 0?getElementByIndex(this.selectorMap,b):null;return{success:!0,message:await scrollVertically(n,d,r)}}catch(n){return{success:!1,message:`❌ Failed to scroll: ${n}`}}}async scrollHorizontally(e){try{const{right:n,pixels:s,index:i}=e;this.assertIndexed();const b=s*(n?1:-1),d=i!==void 0?getElementByIndex(this.selectorMap,i):null;return{success:!0,message:await scrollHorizontally(n,b,d)}}catch(n){return{success:!1,message:`❌ Failed to scroll horizontally: ${n}`}}}async executeJavascript(script){try{const asyncFunction=eval(`(async () => { ${script} })`),result=await asyncFunction();return{success:!0,message:`✅ Executed JavaScript. Result: ${result}`}}catch(e){return{success:!1,message:`❌ Error executing JavaScript: ${e}`}}}async showMask(){var e;await this.maskReady,(e=this.mask)==null||e.show()}async hideMask(){var e;await this.maskReady,(e=this.mask)==null||e.hide()}dispose(){var e;cleanUpHighlights(),this.flatTree=null,this.selectorMap.clear(),this.elementTextMap.clear(),this.simplifiedHTML="<EMPTY>",this.isIndexed=!1,(e=this.mask)==null||e.dispose(),this.mask=null}}exports.PageController=PageController;