import { initPageController } from '@/agent/RemotePageController.content' // import { DEMO_CONFIG } from '@/agent/constants' const DEBUG_PREFIX = '[Content]' export default defineContentScript({ matches: [''], runAt: 'document_end', main() { console.debug(`${DEBUG_PREFIX} Loaded on ${window.location.href}`) initPageController() // if auth token matches, expose agent to page chrome.storage.local.get('PageAgentExtUserAuthToken').then((result) => { // extension side token. // @note this is isolated world. it is safe to assume user script cannot access it const extToken = result.PageAgentExtUserAuthToken if (!extToken) return // page side token const pageToken = localStorage.getItem('PageAgentExtUserAuthToken') if (!pageToken) return if (pageToken !== extToken) return console.log('[PageAgentExt]: Auth tokens match. Exposing agent to page.') // add isolated world script exposeAgentToPage().then( // add main-world script () => injectScript('/main-world.js') ) }) }, }) async function exposeAgentToPage() { const { MultiPageAgent } = await import('@/agent/MultiPageAgent') console.log('[PageAgentExt]: MultiPageAgent loaded') /** * singleton MultiPageAgent to handle requests from the page */ let multiPageAgent: InstanceType | null = null window.addEventListener('message', async (e) => { const data = e.data if (typeof data !== 'object' || data === null) return if (data.channel !== 'PAGE_AGENT_EXT_REQUEST') return const { action, payload, id } = data switch (action) { case 'execute': { // singleton check if (multiPageAgent && multiPageAgent.status === 'running') { window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'execute_result', error: 'Agent is already running a task. Please wait until it finishes.', }, '*' ) return } try { const { task, config } = payload // create when used multiPageAgent = new MultiPageAgent(config) // events multiPageAgent.addEventListener('statuschange', (event) => { if (!multiPageAgent) return window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'status_change_event', payload: multiPageAgent.status, }, '*' ) }) multiPageAgent.addEventListener('activity', (event) => { if (!multiPageAgent) return window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'activity_event', payload: (event as CustomEvent).detail, }, '*' ) }) multiPageAgent.addEventListener('historychange', (event) => { if (!multiPageAgent) return window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'history_change_event', payload: multiPageAgent.history, }, '*' ) }) multiPageAgent.addEventListener('dispose', () => { window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'dispose_event', }, '*' ) }) // result const result = await multiPageAgent.execute(task) window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'execute_result', payload: result, }, '*' ) } catch (error) { window.postMessage( { channel: 'PAGE_AGENT_EXT_RESPONSE', id, action: 'execute_result', error: (error as Error).message, }, '*' ) } break } case 'dispose': { // @note stop ongoing processes but can still be re-used later multiPageAgent?.dispose() break } default: console.warn(`${DEBUG_PREFIX} Unknown action from page:`, action) break } }) }