// WidgeTDC Harvester Background Script let API_BASE = 'http://localhost:3001'; // Load config on startup chrome.storage.sync.get({ widgetdc_api_url: 'http://localhost:3001' }, (items) => { API_BASE = items.widgetdc_api_url; }); // Listen for config changes chrome.storage.onChanged.addListener((changes, namespace) => { if (namespace === 'sync' && changes.widgetdc_api_url) { API_BASE = changes.widgetdc_api_url.newValue; } }); // Listen for messages from popup or content script chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'ingest_page') { handleIngestion(request.data).then(sendResponse); return true; // Keep channel open for async response } if (request.action === 'crawl_site') { handleCrawl(request.data).then(sendResponse); return true; } if (request.action === 'check_connection') { checkBackendHealth().then(sendResponse); return true; } }); async function checkBackendHealth() { try { const response = await fetch(`${API_BASE}/health`); return { success: response.ok }; } catch (error) { return { success: false, error: error.message }; } } async function handleIngestion(data) { const { url, title, html } = data; console.log('Ingesting page:', url); try { // Option 1: Send raw HTML (heavy) // Option 2: Send URL and let backend crawl (cleaner) -> We use this via ingestion.crawl const response = await fetch(`${API_BASE}/api/mcp/route`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ tool: 'ingestion.crawl', params: { url: url, depth: 0 // Single page } }) }); const result = await response.json(); return { success: true, data: result }; } catch (error) { console.error('Ingestion failed:', error); return { success: false, error: error.message }; } } async function handleCrawl(data) { const { url, depth } = data; console.log(`Crawling site: ${url} (Depth: ${depth})`); try { const response = await fetch(`${API_BASE}/api/mcp/route`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ tool: 'ingestion.crawl', params: { url: url, depth: depth || 1, mode: data.mode || 'single', keywords: data.keywords || [], user: data.user } }) }); const result = await response.json(); return { success: true, data: result }; } catch (error) { console.error('Crawl failed:', error); return { success: false, error: error.message }; } } // Context menu for quick actions chrome.runtime.onInstalled.addListener(() => { chrome.contextMenus.create({ id: "widgetdc-ingest", title: "Ingest to WidgeTDC", contexts: ["page", "selection", "link"] }); }); chrome.contextMenus.onClicked.addListener((info, tab) => { if (info.menuItemId === "widgetdc-ingest") { const targetUrl = info.linkUrl || info.pageUrl; handleIngestion({ url: targetUrl }); } });