/* ========================================================= JOBALIGN AI CLIENT A product by John_D Resume generation now runs through the Cloudflare Worker backend. No local LLM download. No WebGPU. No WASM model. ========================================================= */ const JOBALIGN_BACKEND = "https://jobalign-adzuna-proxy.darbymjohn.workers.dev"; /* ========================================================= STATUS ========================================================= */ function setAIStatus( message, type = "normal" ) { const status = document.getElementById( "generationStatus" ); if (!status) { return; } let className = ""; if (type === "success") { className = "success-text"; } else if (type === "error") { className = "danger-text"; } else if (type === "warning") { className = "warning-text"; } status.innerHTML = `
${escapeHTML(message)} `; } /* ========================================================= GENERATE RESUME ========================================================= */ async function generateResume({ resume, jobDescription, jobTitle, company, location }) { if ( !resume || resume.trim().length < 100 ) { throw new Error( "Master resume is missing." ); } if ( !jobDescription || jobDescription.trim().length < 100 ) { throw new Error( "Job description is missing." ); } setAIStatus( "Analyzing job and rebuilding resume..." ); const response = await fetch( JOBALIGN_BACKEND + "/resume", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ resume: resume, jobDescription: jobDescription, jobTitle: jobTitle, company: company, location: location }) } ); let data; try { data = await response.json(); } catch (error) { throw new Error( "Resume service returned an unreadable response." ); } if (!response.ok) { const details = data.details ? " " + data.details : ""; throw new Error( ( data.error || "Resume generation failed." ) + details ); } if ( !data.ok || !data.resume ) { throw new Error( "Resume service did not return a completed resume." ); } const generatedResume = String( data.resume ).trim(); if ( generatedResume.length < 300 ) { throw new Error( "The generated resume was incomplete." ); } setAIStatus( "Targeted resume generated", "success" ); return generatedResume; } /* ========================================================= OPTIONAL HEALTH CHECK ========================================================= */ async function checkBackend() { try { const response = await fetch( JOBALIGN_BACKEND + "/health" ); const data = await response.json(); return Boolean( response.ok && data.ok && data.aiConfigured ); } catch (error) { console.error( "JobAlign backend health check failed:", error ); return false; } } /* ========================================================= HTML SAFETY ========================================================= */ function escapeHTML( value ) { const element = document.createElement( "div" ); element.textContent = String( value || "" ); return element.innerHTML; } /* ========================================================= EXPOSE TO APP.JS ========================================================= */ window.JobAlignAI = { generateResume: generateResume, checkBackend: checkBackend, mode: "cloudflare-workers-ai" }; window.dispatchEvent( new CustomEvent( "jobalign-ai-ready" ) );