ilml-plugin-linkedin 1.4.0 → 1.5.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.0
4
+ - **Easy Apply now fills optional fields too, not just required ones.** Until now we only answered fields that LinkedIn flagged with a validation error — i.e. required ones. Optional fields (cover letter, salary expectation, LinkedIn URL, portfolio, notice period, etc.) silently went unanswered, which is exactly the kind of small signal that makes a candidate look less interested. Each step of the form is now scanned proactively: any field that's not required, not pre-filled by LinkedIn from your profile, and still empty gets routed through Lifebot for an answer. If Lifebot returns nothing or an answer that doesn't match the available options, the field stays empty — no breakage, just no answer logged.
5
+ - **Pre-filled values stay untouched.** When LinkedIn pulls phone / email / name from your profile we leave it alone, even if the field is technically optional. The pre-filled answer goes into the stats as-is (`wasPreFilled: true`), counted as your answer because it came from your profile.
6
+ - **Form Q&A log now records `wasOptional` and `isRequired` per field**, so the upcoming FAQ/canonicalization step (cluster recurring questions, let the user pick canonical answers, feed them back to Lifebot) can tell required from optional and surface optional answers the user may want to override. `isRequired` is always written explicitly on new entries (`true` OR `false`); legacy entries from previous versions simply omit the flag and are read as "unknown" — no migration needed, old `application-questions.json` files keep working as-is.
7
+ - Internal: new `fillOptionalFields(page, fields)` runs in `processNavigation` between the City/CV special-case block and `fillErrorsWithAnswers`. Three new setters in `run.mjs` (`setRadioForLabel`, `setSelectForLabel`, `setCheckboxesForLabel`) mirror the existing `setAnswerForLabel`, with the same shadow-DOM fallback (`#interop-outlet`). `getAnsweredLabels` now records `wasPreFilled` for checkbox and file types too, not just input/radio/select. Failures inside `fillOptionalFields` are caught and logged — they never abort the application.
8
+ - Heads-up: each application now makes more Lifebot calls (roughly +1 per empty optional field). Form completion is slightly slower; nothing else changes about the queue, daily limits, or output formats.
9
+
3
10
  ## 1.4.0
4
11
  - **Apply phase no longer crashes on Puppeteer hangs.** When Chrome's CDP (DevTools Protocol) channel goes dead — the most common failure mode on long sessions, where `Runtime.callFunctionOn timed out` previously aborted the run with `Apply phase crashed: ... Increase the 'protocolTimeout' setting` — the runner now detects it via a fast liveness probe and transparently recovers. Recovery escalates: close the dead page and open a fresh one (cookies preserved, navigates back to the search URL, continues applying) → if that keeps failing, full browser restart → if even that fails, exit with a clear actionable error. Jobs in the queue aren't lost; the run keeps going.
5
12
  - **Clearer error messages when authentication expires.** Two distinct, easy-to-confuse expiries are now detected separately and printed with the *correct* command:
@@ -1,7 +1,7 @@
1
- var mt=Object.defineProperty;var Ie=(t,e)=>()=>(t&&(e=t(t=0)),e);var $e=(t,e)=>{for(var o in e)mt(t,o,{get:e[o],enumerable:!0})};var ze={};$e(ze,{addEncounter:()=>xe,canSendConnection:()=>Je,commitDataSnapshot:()=>Ge,default:()=>wt,getAllApplications:()=>Ve,getPersonStatus:()=>Le,getQuestionStats:()=>Qe,getQuotaStatus:()=>Ne,getRecentConnections:()=>ee,linkPersonToJob:()=>_e,loadApplicationQuestions:()=>de,loadConversations:()=>Ae,loadJobs:()=>H,loadPeople:()=>O,loadQuota:()=>Z,loadSyncState:()=>Ue,logApplicationQuestions:()=>Be,migrateFromDailyFiles:()=>Me,recordConnectionSent:()=>ke,resetCaches:()=>yt,saveConversations:()=>Re,saveJobs:()=>X,savePeople:()=>R,saveQuota:()=>fe,saveSyncState:()=>Pe,updateConnectionStatus:()=>Fe,upsertJob:()=>Ee,upsertPerson:()=>pe});import"dotenv/config";import*as d from"fs";import*as h from"path";import{fileURLToPath as ht}from"url";import{execSync as ie}from"child_process";function yt(){L=null,F=null,D=null,C=null,k=null,T=null}function y(){d.existsSync(S)||d.mkdirSync(S,{recursive:!0})}function A(t,e){let o=JSON.stringify(e,null,2),r=t+".tmp";d.writeFileSync(r,o);for(let n=0;n<3;n++)try{d.renameSync(r,t);return}catch(s){if(n<2&&(s.code==="EPERM"||s.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw s}}function U(t,e){if(!d.existsSync(t))return null;try{let o=JSON.parse(d.readFileSync(t,"utf-8"));try{d.copyFileSync(t,t+".backup")}catch{}return o}catch(o){console.error(`[!] ${e} is corrupted: ${o.message}`),console.error(` File: ${h.resolve(t)}`);let r=t+".backup";if(d.existsSync(r))try{let n=JSON.parse(d.readFileSync(r,"utf-8"));console.error(` Restored from ${r}`);try{d.copyFileSync(r,t)}catch{}return n}catch{console.error(" Backup also corrupted!")}console.error(` Starting with empty data. Old file preserved as ${t}.corrupted`);try{d.copyFileSync(t,t+".corrupted")}catch{}return null}}function J(){return new Date().toISOString().split("T")[0]}function O(){return L||(y(),L=U(ce,"people.json")||{},L)}function R(t){y(),L=t;try{A(ce,t)}catch(e){console.error(`[!] Failed to save people.json: ${e.message}`),console.error(` Path: ${h.resolve(ce)}`)}}function H(){return F||(y(),F=U(le,"jobs.json")||{},F)}function X(t){y(),F=t;try{A(le,t)}catch(e){console.error(`[!] Failed to save jobs.json: ${e.message}`),console.error(` Path: ${h.resolve(le)}`)}}function Ae(){return C||(y(),C=U(K,"conversations.json")||{},jt(C),C)}function jt(t){let e=0;for(let o of Object.values(t)){if(!(o.draftStatus!==void 0||o.draftPreparedAt!==void 0))continue;let n=(o.messages||[]).find(s=>s.status==="draft");n&&o.draftStatus&&o.draftStatus!=="pending"&&(n.status=o.draftStatus),delete o.draftStatus,delete o.draftPreparedAt,e++}if(e>0){console.log(` [migration] Moved draft state from conv to msg.status for ${e} conversations`);try{A(K,t)}catch{}}}function Re(t){y(),C=t;try{A(K,t)}catch(e){console.error(`[!] Failed to save conversations.json: ${e.message}`),console.error(` Path: ${h.resolve(K)}`)}}function pe(t,e={}){if(!t)return null;let o=O(),r=J(),n=new Date().toISOString(),s=o[t];if(s){s.seenCount=(s.seenCount||1)+1,s.lastSeen=r,s.lastUpdated=n,e.source&&!s.sources?.includes(e.source)&&(s.sources=s.sources||[],s.sources.push(e.source));for(let i of ue)e[i]!=null&&(s[i]=e[i])}else o[t]={name:e.name||null,title:e.title||null,location:e.location||null,company:e.company||null,connectionDegree:e.connectionDegree||null,connectionsCount:e.connectionsCount||null,mutualConnections:e.mutualConnections||null,photoUrl:e.photoUrl||null,hasVerifiedBadge:e.hasVerifiedBadge||!1,firstSeen:r,lastSeen:r,seenCount:1,sources:e.source?[e.source]:[],connectionStatus:null,connectionDate:null,connectionMethod:null,messageSent:null,jobIds:[],lastUpdated:n};return R(o),o[t]}function Ee(t,e={}){if(!t)return null;let o=H(),r=J(),n=o[t];if(n){let s=["title","company","companyUrl","location","salary","url","applied","appliedDate","recruiterUrl","description","techStack","jobTags","seniority","employmentType","industries","jobFunction","postedTime","applicantCount","companySize","workplaceType","contractType","isEasyApply","applyType","scoutedAt","lastSeen"];for(let i of s)e[i]!=null&&(n[i]=e[i])}else o[t]={title:e.title||null,company:e.company||null,location:e.location||null,salary:e.salary||null,url:e.url||null,applied:e.applied||!1,appliedDate:e.appliedDate||r,recruiterUrl:e.recruiterUrl||null,firstSeen:r};return X(o),o[t]}function _e(t,e){if(!t||!e)return;let o=O(),r=o[t];r&&(r.jobIds||(r.jobIds=[]),r.jobIds.includes(e)||(r.jobIds.push(e),r.lastUpdated=new Date().toISOString(),R(o)))}function xe(t,e){if(!t||!e)return;let o=O(),r=o[t];if(!r)return;r.encounters||(r.encounters=[]);let s={date:J(),source:e.source||"unknown",action:e.action||"unknown"};e.jobId&&(s.jobId=String(e.jobId)),e.jobTitle&&(s.jobTitle=e.jobTitle),e.jobCompany&&(s.jobCompany=e.jobCompany),!r.encounters.some(a=>a.date===s.date&&a.source===s.source&&a.action===s.action&&(a.jobId||"")===(s.jobId||""))&&(r.encounters.push(s),r.lastUpdated=new Date().toISOString(),R(o))}function Le(t){return t&&O()[t]?.connectionStatus||null}function Fe(t,e,o={}){if(!t)return;let r=O(),n=r[t];if(n||(pe(t,o.profileInfo||{}),n=r[t]),!!n){if(n.connectionStatus=e,n.connectionDate=J(),n.connectionMethod=o.method||n.connectionMethod,n.messageSent=o.messageSent||n.messageSent,n.lastUpdated=new Date().toISOString(),o.profileInfo)for(let s of ue)o.profileInfo[s]!=null&&(n[s]=o.profileInfo[s]);R(r)}}function Z(){return D||(y(),D=U(Te,"quota.json"),(!D||!D.connections)&&(D={connections:[]}),D)}function fe(t){y(),D=t;try{A(Te,t)}catch(e){console.error(`[!] Failed to save quota.json: ${e.message}`)}}function ke(t,e="unknown"){let o=Z(),r=new Date;o.connections.push({date:r.toISOString().split("T")[0],time:r.toTimeString().split(" ")[0],profileUrl:t,source:e}),fe(o)}function ee(){let t=Z(),e=new Date;e.setDate(e.getDate()-7);let o=e.toISOString().split("T")[0];return t.connections.filter(r=>r.date>=o)}function Je(){let t=ee(),e=J(),o=t.filter(u=>u.date===e).length,r=t.length,n=o>=N,s=r>=M,i=!n&&!s,a={allowed:i,daily:{sent:o,max:N},weekly:{sent:r,max:M}};return i||(a.reason=n?`Daily limit reached (${o}/${N})`:`Weekly limit reached (${r}/${M})`),a}function Ne(){let t=ee(),e=J(),o=t.filter(n=>n.date===e).length,r=t.length;return{daily:{sent:o,max:N,remaining:N-o},weekly:{sent:r,max:M,remaining:M-r}}}function bt(t){if(!t)return null;let e=t.match(/jobs\/view\/(\d+)/);return e?e[1]:null}function Me(){y();let t=d.readdirSync(S).filter(s=>s.endsWith(".json")&&s!=="people.json"&&s!=="jobs.json"&&s!=="quota.json");if(t.length===0)return console.log("No daily files found to migrate."),{people:0,jobs:0};console.log(`
1
+ var mt=Object.defineProperty;var Ie=(t,e)=>()=>(t&&(e=t(t=0)),e);var $e=(t,e)=>{for(var o in e)mt(t,o,{get:e[o],enumerable:!0})};var ze={};$e(ze,{addEncounter:()=>xe,canSendConnection:()=>Je,commitDataSnapshot:()=>Ge,default:()=>wt,getAllApplications:()=>Ve,getPersonStatus:()=>Le,getQuestionStats:()=>Qe,getQuotaStatus:()=>Ne,getRecentConnections:()=>ee,linkPersonToJob:()=>_e,loadApplicationQuestions:()=>de,loadConversations:()=>Re,loadJobs:()=>H,loadPeople:()=>O,loadQuota:()=>Z,loadSyncState:()=>Ue,logApplicationQuestions:()=>Be,migrateFromDailyFiles:()=>Me,recordConnectionSent:()=>ke,resetCaches:()=>yt,saveConversations:()=>Ae,saveJobs:()=>X,savePeople:()=>A,saveQuota:()=>fe,saveSyncState:()=>Pe,updateConnectionStatus:()=>Fe,upsertJob:()=>Ee,upsertPerson:()=>pe});import"dotenv/config";import*as d from"fs";import*as h from"path";import{fileURLToPath as ht}from"url";import{execSync as ie}from"child_process";function yt(){L=null,F=null,D=null,C=null,k=null,T=null}function y(){d.existsSync(S)||d.mkdirSync(S,{recursive:!0})}function R(t,e){let o=JSON.stringify(e,null,2),r=t+".tmp";d.writeFileSync(r,o);for(let n=0;n<3;n++)try{d.renameSync(r,t);return}catch(s){if(n<2&&(s.code==="EPERM"||s.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw s}}function U(t,e){if(!d.existsSync(t))return null;try{let o=JSON.parse(d.readFileSync(t,"utf-8"));try{d.copyFileSync(t,t+".backup")}catch{}return o}catch(o){console.error(`[!] ${e} is corrupted: ${o.message}`),console.error(` File: ${h.resolve(t)}`);let r=t+".backup";if(d.existsSync(r))try{let n=JSON.parse(d.readFileSync(r,"utf-8"));console.error(` Restored from ${r}`);try{d.copyFileSync(r,t)}catch{}return n}catch{console.error(" Backup also corrupted!")}console.error(` Starting with empty data. Old file preserved as ${t}.corrupted`);try{d.copyFileSync(t,t+".corrupted")}catch{}return null}}function J(){return new Date().toISOString().split("T")[0]}function O(){return L||(y(),L=U(ce,"people.json")||{},L)}function A(t){y(),L=t;try{R(ce,t)}catch(e){console.error(`[!] Failed to save people.json: ${e.message}`),console.error(` Path: ${h.resolve(ce)}`)}}function H(){return F||(y(),F=U(le,"jobs.json")||{},F)}function X(t){y(),F=t;try{R(le,t)}catch(e){console.error(`[!] Failed to save jobs.json: ${e.message}`),console.error(` Path: ${h.resolve(le)}`)}}function Re(){return C||(y(),C=U(K,"conversations.json")||{},jt(C),C)}function jt(t){let e=0;for(let o of Object.values(t)){if(!(o.draftStatus!==void 0||o.draftPreparedAt!==void 0))continue;let n=(o.messages||[]).find(s=>s.status==="draft");n&&o.draftStatus&&o.draftStatus!=="pending"&&(n.status=o.draftStatus),delete o.draftStatus,delete o.draftPreparedAt,e++}if(e>0){console.log(` [migration] Moved draft state from conv to msg.status for ${e} conversations`);try{R(K,t)}catch{}}}function Ae(t){y(),C=t;try{R(K,t)}catch(e){console.error(`[!] Failed to save conversations.json: ${e.message}`),console.error(` Path: ${h.resolve(K)}`)}}function pe(t,e={}){if(!t)return null;let o=O(),r=J(),n=new Date().toISOString(),s=o[t];if(s){s.seenCount=(s.seenCount||1)+1,s.lastSeen=r,s.lastUpdated=n,e.source&&!s.sources?.includes(e.source)&&(s.sources=s.sources||[],s.sources.push(e.source));for(let i of ue)e[i]!=null&&(s[i]=e[i])}else o[t]={name:e.name||null,title:e.title||null,location:e.location||null,company:e.company||null,connectionDegree:e.connectionDegree||null,connectionsCount:e.connectionsCount||null,mutualConnections:e.mutualConnections||null,photoUrl:e.photoUrl||null,hasVerifiedBadge:e.hasVerifiedBadge||!1,firstSeen:r,lastSeen:r,seenCount:1,sources:e.source?[e.source]:[],connectionStatus:null,connectionDate:null,connectionMethod:null,messageSent:null,jobIds:[],lastUpdated:n};return A(o),o[t]}function Ee(t,e={}){if(!t)return null;let o=H(),r=J(),n=o[t];if(n){let s=["title","company","companyUrl","location","salary","url","applied","appliedDate","recruiterUrl","description","techStack","jobTags","seniority","employmentType","industries","jobFunction","postedTime","applicantCount","companySize","workplaceType","contractType","isEasyApply","applyType","scoutedAt","lastSeen"];for(let i of s)e[i]!=null&&(n[i]=e[i])}else o[t]={title:e.title||null,company:e.company||null,location:e.location||null,salary:e.salary||null,url:e.url||null,applied:e.applied||!1,appliedDate:e.appliedDate||r,recruiterUrl:e.recruiterUrl||null,firstSeen:r};return X(o),o[t]}function _e(t,e){if(!t||!e)return;let o=O(),r=o[t];r&&(r.jobIds||(r.jobIds=[]),r.jobIds.includes(e)||(r.jobIds.push(e),r.lastUpdated=new Date().toISOString(),A(o)))}function xe(t,e){if(!t||!e)return;let o=O(),r=o[t];if(!r)return;r.encounters||(r.encounters=[]);let s={date:J(),source:e.source||"unknown",action:e.action||"unknown"};e.jobId&&(s.jobId=String(e.jobId)),e.jobTitle&&(s.jobTitle=e.jobTitle),e.jobCompany&&(s.jobCompany=e.jobCompany),!r.encounters.some(a=>a.date===s.date&&a.source===s.source&&a.action===s.action&&(a.jobId||"")===(s.jobId||""))&&(r.encounters.push(s),r.lastUpdated=new Date().toISOString(),A(o))}function Le(t){return t&&O()[t]?.connectionStatus||null}function Fe(t,e,o={}){if(!t)return;let r=O(),n=r[t];if(n||(pe(t,o.profileInfo||{}),n=r[t]),!!n){if(n.connectionStatus=e,n.connectionDate=J(),n.connectionMethod=o.method||n.connectionMethod,n.messageSent=o.messageSent||n.messageSent,n.lastUpdated=new Date().toISOString(),o.profileInfo)for(let s of ue)o.profileInfo[s]!=null&&(n[s]=o.profileInfo[s]);A(r)}}function Z(){return D||(y(),D=U(Te,"quota.json"),(!D||!D.connections)&&(D={connections:[]}),D)}function fe(t){y(),D=t;try{R(Te,t)}catch(e){console.error(`[!] Failed to save quota.json: ${e.message}`)}}function ke(t,e="unknown"){let o=Z(),r=new Date;o.connections.push({date:r.toISOString().split("T")[0],time:r.toTimeString().split(" ")[0],profileUrl:t,source:e}),fe(o)}function ee(){let t=Z(),e=new Date;e.setDate(e.getDate()-7);let o=e.toISOString().split("T")[0];return t.connections.filter(r=>r.date>=o)}function Je(){let t=ee(),e=J(),o=t.filter(u=>u.date===e).length,r=t.length,n=o>=N,s=r>=M,i=!n&&!s,a={allowed:i,daily:{sent:o,max:N},weekly:{sent:r,max:M}};return i||(a.reason=n?`Daily limit reached (${o}/${N})`:`Weekly limit reached (${r}/${M})`),a}function Ne(){let t=ee(),e=J(),o=t.filter(n=>n.date===e).length,r=t.length;return{daily:{sent:o,max:N,remaining:N-o},weekly:{sent:r,max:M,remaining:M-r}}}function bt(t){if(!t)return null;let e=t.match(/jobs\/view\/(\d+)/);return e?e[1]:null}function Me(){y();let t=d.readdirSync(S).filter(s=>s.endsWith(".json")&&s!=="people.json"&&s!=="jobs.json"&&s!=="quota.json");if(t.length===0)return console.log("No daily files found to migrate."),{people:0,jobs:0};console.log(`
2
2
  Migrating from ${t.length} daily files...
3
- `);let e=O(),o=H(),r=0,n=0;t.sort();for(let s of t){let i=h.join(S,s),a;try{a=JSON.parse(d.readFileSync(i,"utf-8"))}catch(c){console.log(` Skipping ${s}: ${c.message}`);continue}let u=a.date||s.match(/\d{4}-\d{2}-\d{2}/)?.[0]||null,p=a.source||s.split("-").slice(0,-1).join("-").replace(/-\d{4}$/,"")||"unknown";if(!a.profiles||!Array.isArray(a.profiles)){console.log(` Skipping ${s}: no profiles array`);continue}console.log(` ${s}: ${a.profiles.length} profiles`);for(let c of a.profiles){let m=c.profileUrl;if(!m)continue;let l=e[m];if(l){l.seenCount=(l.seenCount||1)+1,u&&(!l.lastSeen||u>l.lastSeen)&&(l.lastSeen=u),u&&(!l.firstSeen||u<l.firstSeen)&&(l.firstSeen=u),p&&!l.sources?.includes(p)&&(l.sources=l.sources||[],l.sources.push(p));for(let f of ue)c[f]!=null&&(l[f]=c[f]);c.status&&c.processed&&(l.connectionStatus=c.status,l.connectionDate=u,c.funnelResult&&(l.connectionMethod=c.funnelResult.method||l.connectionMethod,l.messageSent=c.funnelResult.message||l.messageSent)),l.lastUpdated=new Date().toISOString()}else e[m]={name:c.name||null,title:c.title||null,location:c.location||null,company:c.company||null,connectionDegree:c.connectionDegree||null,connectionsCount:c.connectionsCount||null,mutualConnections:c.mutualConnections||null,photoUrl:c.photoUrl||null,hasVerifiedBadge:c.hasVerifiedBadge||!1,firstSeen:u,lastSeen:u,seenCount:1,sources:p?[p]:[],connectionStatus:c.processed&&c.status||null,connectionDate:c.processed?u:null,connectionMethod:c.funnelResult?.method||null,messageSent:c.funnelResult?.message||null,jobIds:[],lastUpdated:new Date().toISOString()},r++;if(c.fromJob?.url){let f=bt(c.fromJob.url);f&&(e[m].jobIds||(e[m].jobIds=[]),e[m].jobIds.includes(f)||e[m].jobIds.push(f),o[f]?o[f].recruiterUrl||(o[f].recruiterUrl=m):(o[f]={title:c.fromJob.title||null,company:c.fromJob.company||null,location:null,salary:null,url:c.fromJob.url,applied:!0,appliedDate:u,recruiterUrl:m,firstSeen:u},n++))}}}return R(e),X(o),console.log(`
4
- Migration complete!`),console.log(` People: ${Object.keys(e).length} total (${r} new)`),console.log(` Jobs: ${Object.keys(o).length} total (${n} new)`),{people:Object.keys(e).length,jobs:Object.keys(o).length}}function Ue(){return k||(y(),k=U(Ce,"sync-state.json")||{},k)}function Pe(t){y(),k=t;try{A(Ce,t)}catch(e){console.error(`[!] Failed to save sync-state.json: ${e.message}`)}}function de(){if(T)return T;y();try{d.existsSync(ae)&&(T=JSON.parse(d.readFileSync(ae,"utf-8")))}catch{}return T||(T={}),T}function qe(t){return Array.isArray(t.applications)}function Ve(){let t=de();if(qe(t))return t.applications;let e=[];for(let o of Object.values(t))o.applications&&e.push(...o.applications);return e}function Be(t){if(!t||!t.questions||t.questions.length===0)return;let e=de(),o=t.jobId||"unknown",n={applicationId:`${o}_${Date.now()}`,date:new Date().toISOString(),result:t.result||"submitted",formPages:t.formPages||null,duration:t.duration||null,retries:t.retries||0,failedField:t.failedField||null,questionCount:t.questions.length,questions:t.questions.map(s=>{let i={type:s.type||"input",question:s.labelText||s.question||"",answer:s.answer||""};return s.options&&(s.options.length<=vt?i.options=s.options:i.optionsOmitted=!0),s.page&&(i.page=s.page),s.wasPreFilled&&(i.wasPreFilled=!0),s.wasRetry&&(i.wasRetry=!0),i})};qe(e)?(n.jobId=o,n.jobTitle=t.jobTitle||null,n.jobCompany=t.jobCompany||null,n.jobUrl=t.jobUrl||null,e.applications.push(n)):(e[o]||(e[o]={applications:[]}),e[o].applications.push(n));try{A(ae,e)}catch(s){console.error(`[!] Failed to save application-questions.json: ${s.message}`)}}function Qe(){let t=Ve(),e=new Map;for(let s of t)for(let i of s.questions||[]){let a=i.question.toLowerCase().trim();if(!a)continue;e.has(a)||e.set(a,{question:i.question,count:0,answers:new Map});let u=e.get(a);u.count++;let p=(i.answer||"").trim();u.answers.set(p,(u.answers.get(p)||0)+1)}let o=[...e.values()].sort((s,i)=>i.count-s.count),r=o.slice(0,15).map(s=>({question:s.question,count:s.count,topAnswer:[...s.answers.entries()].sort((i,a)=>a[1]-i[1])[0]?.[0]||""})),n=o.filter(s=>s.answers.size>1&&s.count>=3).map(s=>({question:s.question,count:s.count,answers:[...s.answers.entries()].sort((i,a)=>a[1]-i[1]).map(([i,a])=>`${i} (${a}x)`)}));return{totalApplications:t.length,uniqueQuestions:e.size,topQuestions:r,inconsistent:n}}function Ge(t){if(d.existsSync(h.join(S,".git")))try{let e={cwd:S,stdio:"pipe",timeout:1e4};ie("git add conversations.json people.json jobs.json quota.json sync-state.json run-log.json application-questions.json",e);try{ie("git diff --cached --quiet",e);return}catch{}let o=(t||`sync ${new Date().toISOString().slice(0,16)}`).replace(/"/g,'\\"');ie(`git commit -m "${o}"`,e)}catch(e){process.env.VERBOSE&&console.log(` [git] snapshot skipped: ${e.message?.slice(0,80)}`)}}var gt,St,S,ce,le,Te,K,Ce,ae,N,M,L,F,D,C,k,T,ue,vt,wt,me=Ie(()=>{gt=ht(import.meta.url),St=h.dirname(h.dirname(gt)),S=process.env.DATA_DIR?h.resolve(process.env.DATA_DIR,"collected-profiles"):h.join(St,"collected-profiles"),ce=h.join(S,"people.json"),le=h.join(S,"jobs.json"),Te=h.join(S,"quota.json"),K=h.join(S,"conversations.json"),Ce=h.join(S,"sync-state.json"),ae=h.join(S,"application-questions.json"),N=20,M=100,L=null,F=null,D=null,C=null,k=null,T=null;ue=["name","title","location","company","connectionDegree","connectionsCount","mutualConnections","photoUrl","hasVerifiedBadge"];vt=50;wt={loadPeople:O,savePeople:R,loadJobs:H,saveJobs:X,loadConversations:Ae,saveConversations:Re,upsertPerson:pe,upsertJob:Ee,linkPersonToJob:_e,addEncounter:xe,getPersonStatus:Le,updateConnectionStatus:Fe,migrateFromDailyFiles:Me,loadQuota:Z,saveQuota:fe,recordConnectionSent:ke,canSendConnection:Je,getRecentConnections:ee,getQuotaStatus:Ne,loadSyncState:Ue,saveSyncState:Pe,commitDataSnapshot:Ge,logApplicationQuestions:Be,getQuestionStats:Qe}});var et={};$e(et,{getJobDecision:()=>Ct,getLastVisit:()=>_t,getScoutStats:()=>xt,loadCompanies:()=>Ze,loadDiscoveredPeople:()=>ge,loadJobDecisions:()=>Y,loadScoutedJobs:()=>W,loadVisitLog:()=>te,recordVisit:()=>Et,resetCaches:()=>$t,saveCompany:()=>Rt,saveDiscoveredPerson:()=>At,saveScoutedJob:()=>he,setJobDecision:()=>Tt});import"dotenv/config";import*as v from"fs";import*as j from"path";import{fileURLToPath as Ot}from"url";function Q(){v.existsSync(_)||v.mkdirSync(_,{recursive:!0})}function G(t,e){let o=JSON.stringify(e,null,2),r=t+".tmp";v.writeFileSync(r,o);for(let n=0;n<3;n++)try{v.renameSync(r,t);return}catch(s){if(n<2&&(s.code==="EPERM"||s.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw s}}function z(t){try{if(v.existsSync(t))return JSON.parse(v.readFileSync(t,"utf-8"))}catch{}return null}function $t(){P=null,q=null,V=null,B=null,E=null}function W(){return P||(P=z(We)||{},P)}function he(t,e){if(!t)return;Q();let o=W(),r=new Date().toISOString().slice(0,10);if(o[t]){for(let[n,s]of Object.entries(e))s!=null&&(o[t][n]=s);o[t].lastSeen=r}else o[t]={...e,scoutedAt:r,lastSeen:r};try{G(We,o)}catch(n){console.error(`[!] Failed to save scouted-jobs.json: ${n.message}`)}}function Y(){return q||(q=z(Xe)||{},q)}function Tt(t,e,o={}){if(!t||!e)return;Q();let r=Y(),n=new Date().toISOString().slice(0,10);r[t]?(r[t].status=e,r[t].updatedAt=n,o.reason&&(r[t].reason=o.reason),o.score!=null&&(r[t].score=o.score),o.source&&(r[t].source=o.source)):r[t]={status:e,decidedAt:n,updatedAt:n,reason:o.reason||null,score:o.score??null,source:o.source||null};try{G(Xe,r)}catch(s){console.error(`[!] Failed to save job-decisions.json: ${s.message}`)}}function Ct(t){return Y()[t]||null}function ge(){return V||(V=z(Ye)||{},V)}function At(t,e){if(!t)return;Q();let o=ge(),r=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.title&&(n.title=e.title),e.company&&(n.company=e.company),e.location&&(n.location=e.location),e.role&&(n.role=e.role),e.isConnected!=null&&(n.isConnected=e.isConnected),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),n.lastSeen=r,n.seenCount=(n.seenCount||1)+1}else o[t]={name:e.name||null,title:e.title||null,company:e.company||null,location:e.location||null,role:e.role||null,source:e.source||"scout",isConnected:e.isConnected||!1,discoveredAt:r,lastSeen:r,seenCount:1,jobIds:e.jobId?[e.jobId]:[]};try{G(Ye,o)}catch(n){console.error(`[!] Failed to save discovered-people.json: ${n.message}`)}}function Ze(){return B||(B=z(He)||{},B)}function Rt(t,e){if(!t)return;Q();let o=Ze(),r=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.about&&(n.about=e.about),e.size&&(n.size=e.size),e.industries&&(n.industries=e.industries),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),e.recruiterUrl&&(n.recruiterUrls||(n.recruiterUrls=[]),n.recruiterUrls.includes(e.recruiterUrl)||n.recruiterUrls.push(e.recruiterUrl)),n.lastSeen=r,n.jobCount=n.jobIds?.length||0}else o[t]={name:e.name||null,about:e.about||null,size:e.size||null,industries:e.industries||null,discoveredAt:r,lastSeen:r,jobIds:e.jobId?[e.jobId]:[],recruiterUrls:e.recruiterUrl?[e.recruiterUrl]:[],jobCount:e.jobId?1:0};try{G(He,o)}catch(n){console.error(`[!] Failed to save companies.json: ${n.message}`)}}function te(){return E||(E=z(Ke)||{visits:[]},Array.isArray(E.visits)||(E.visits=[]),E)}function Et(t,e={}){if(!t)return;Q();let o=te();o.visits.push({date:new Date().toISOString(),profileUrl:t,name:e.name||null,source:e.source||"manual"});let r=Date.now()-90*24*60*60*1e3;o.visits=o.visits.filter(n=>new Date(n.date).getTime()>r);try{G(Ke,o)}catch(n){console.error(`[!] Failed to save visit-log.json: ${n.message}`)}}function _t(t){let e=te();for(let o=e.visits.length-1;o>=0;o--)if(e.visits[o].profileUrl===t)return e.visits[o].date;return null}function xt(){let t=W(),e=ge(),o=Object.values(t),r=Object.values(e),n={};for(let l of o)l.company&&(n[l.company]=(n[l.company]||0)+1);let s=Object.entries(n).sort((l,f)=>f[1]-l[1]).slice(0,5).map(([l,f])=>`${l} (${f})`),i={};for(let l of o)for(let f of l.techStack||[])i[f]=(i[f]||0)+1;let a=Object.entries(i).sort((l,f)=>f[1]-l[1]).slice(0,8).map(([l,f])=>`${l} (${f})`),u=te(),p=new Date().toISOString().slice(0,10),c=u.visits.filter(l=>l.date.startsWith(p)).length,m=new Set(u.visits.map(l=>l.profileUrl)).size;return{totalJobs:o.length,totalRecruiters:r.length,topCompanies:s,topTech:a,totalVisited:m,todayVisited:c,lastScoutDate:o.length>0?o.sort((l,f)=>(f.scoutedAt||"").localeCompare(l.scoutedAt||""))[0]?.scoutedAt:null}}var Dt,It,_,We,Ye,Ke,He,Xe,P,q,V,B,E,oe=Ie(()=>{Dt=Ot(import.meta.url),It=j.dirname(j.dirname(Dt)),_=process.env.DATA_DIR?j.resolve(process.env.DATA_DIR,"market-research"):j.join(It,"market-research"),We=j.join(_,"scouted-jobs.json"),Ye=j.join(_,"discovered-people.json"),Ke=j.join(_,"visit-log.json"),He=j.join(_,"companies.json"),Xe=j.join(_,"job-decisions.json");P=null;q=null;V=null;B=null;E=null});import"dotenv/config";import*as $ from"fs";import*as x from"path";import{fileURLToPath as to}from"url";import{execFileSync as oo}from"child_process";me();oe();var Lt=new Set(["java","c#",".net","scala","python","typescript","javascript","react","node.js","aws","azure","docker","kubernetes","microservices","graphql","rest","sql","postgresql","mongodb","kafka","redis","ci/cd","terraform","spring"]),Ft=new Set(["iot","machine learning","ai","data engineering","spark","go","rust","kotlin","next.js","devops","sre"]),tt=["vancouver","british columbia"],kt=["canada","montreal","quebec","alberta","calgary","ottawa"],Jt=["toronto","ontario"],Nt=["india","pakistan","nigeria","philippines"];function Mt(t,e={}){let o=0,r=(t.techStack||[]).map(c=>c.toLowerCase()),n=0,s=0;for(let c of r)Lt.has(c)&&n++,Ft.has(c)&&s++;if(o+=Math.min(n*6,24),o+=Math.min(s*3,6),t.salary){let c=Ut(t.salary);c&&(c>=15e4?o+=20:c>=12e4?o+=15:c>=1e5?o+=10:c>=8e4?o+=5:c>=100&&c<1e3?o+=15:c>=70&&c<1e3&&(o+=10))}let i=(t.location||"").toLowerCase(),a=/remote/i.test(i)||t.workplaceType==="remote";Nt.some(c=>i.includes(c))?o-=30:a&&/united states|usa|\bus\b/i.test(i)?o+=25:a&&tt.some(c=>i.includes(c))?o+=22:a?o+=20:tt.some(c=>i.includes(c))?o+=18:kt.some(c=>i.includes(c))?o+=10:Jt.some(c=>i.includes(c))&&(o+=5),t.isEasyApply&&(o+=5);let u=(t.seniority||"").toLowerCase();u.includes("senior")||u.includes("lead")||u.includes("staff")?o+=10:u.includes("mid")?o+=5:(u.includes("entry")||u.includes("intern"))&&(o-=10),t.recruiterUrl&&(e.conversationRecruiters?.has(t.recruiterUrl)?o+=20:e.connectedRecruiters?.has(t.recruiterUrl)?o+=15:o+=3);let p=new Set(t.jobTags||[]);return p.has("managerial")?o+=8:p.has("senior-ic")&&(o+=5),p.has("junior")&&(o-=15),p.has("consultant")&&(o-=3),Math.max(0,Math.min(100,o))}function Se(t=10,e={}){let{easyApplyOnly:o=!0}=e,r=W(),n=O(),s=new Set,i=new Set;for(let[m,l]of Object.entries(n))l.connectionStatus==="connected"&&s.add(m);let a={connectedRecruiters:s,conversationRecruiters:i},u=Y(),p=new Set(["applied","skipped","expired","archived"]);return Object.entries(r).filter(([m,l])=>{if(typeof l!="object"||o&&!l.isEasyApply||l.applied)return!1;let f=u[m];return!(f&&p.has(f.status))}).map(([m,l])=>({jobId:m,score:Mt(l,a),job:l})).sort((m,l)=>{if(l.score!==m.score)return l.score-m.score;let f=m.job.scoutedAt||m.job.postedTime||"";return(l.job.scoutedAt||l.job.postedTime||"").localeCompare(f)}).slice(0,t)}function Ut(t){if(!t)return null;let e=t.match(/[\$£€CAD\s]*([\d,]+(?:\.\d+)?)\s*[kK]?/g);if(!e||e.length===0)return null;let o=e.map(r=>{let n=parseFloat(r.replace(/[^\d.]/g,""));return r.toLowerCase().includes("k")&&(n*=1e3),n}).filter(r=>r>0);return o.length>=2?(o[0]+o[1])/2:o.length===1?o[0]:null}oe();import"dotenv/config";import*as w from"fs";import*as I from"path";import{fileURLToPath as Gt}from"url";import"dotenv/config";import{createGraphClient as Pt,resolveToken as qt}from"@ilivemylife/graph-sdk";import{config as Vt}from"dotenv";Vt();var ot=qt()||process.env.TOKEN;ot||(console.error(`
3
+ `);let e=O(),o=H(),r=0,n=0;t.sort();for(let s of t){let i=h.join(S,s),a;try{a=JSON.parse(d.readFileSync(i,"utf-8"))}catch(c){console.log(` Skipping ${s}: ${c.message}`);continue}let u=a.date||s.match(/\d{4}-\d{2}-\d{2}/)?.[0]||null,p=a.source||s.split("-").slice(0,-1).join("-").replace(/-\d{4}$/,"")||"unknown";if(!a.profiles||!Array.isArray(a.profiles)){console.log(` Skipping ${s}: no profiles array`);continue}console.log(` ${s}: ${a.profiles.length} profiles`);for(let c of a.profiles){let m=c.profileUrl;if(!m)continue;let l=e[m];if(l){l.seenCount=(l.seenCount||1)+1,u&&(!l.lastSeen||u>l.lastSeen)&&(l.lastSeen=u),u&&(!l.firstSeen||u<l.firstSeen)&&(l.firstSeen=u),p&&!l.sources?.includes(p)&&(l.sources=l.sources||[],l.sources.push(p));for(let f of ue)c[f]!=null&&(l[f]=c[f]);c.status&&c.processed&&(l.connectionStatus=c.status,l.connectionDate=u,c.funnelResult&&(l.connectionMethod=c.funnelResult.method||l.connectionMethod,l.messageSent=c.funnelResult.message||l.messageSent)),l.lastUpdated=new Date().toISOString()}else e[m]={name:c.name||null,title:c.title||null,location:c.location||null,company:c.company||null,connectionDegree:c.connectionDegree||null,connectionsCount:c.connectionsCount||null,mutualConnections:c.mutualConnections||null,photoUrl:c.photoUrl||null,hasVerifiedBadge:c.hasVerifiedBadge||!1,firstSeen:u,lastSeen:u,seenCount:1,sources:p?[p]:[],connectionStatus:c.processed&&c.status||null,connectionDate:c.processed?u:null,connectionMethod:c.funnelResult?.method||null,messageSent:c.funnelResult?.message||null,jobIds:[],lastUpdated:new Date().toISOString()},r++;if(c.fromJob?.url){let f=bt(c.fromJob.url);f&&(e[m].jobIds||(e[m].jobIds=[]),e[m].jobIds.includes(f)||e[m].jobIds.push(f),o[f]?o[f].recruiterUrl||(o[f].recruiterUrl=m):(o[f]={title:c.fromJob.title||null,company:c.fromJob.company||null,location:null,salary:null,url:c.fromJob.url,applied:!0,appliedDate:u,recruiterUrl:m,firstSeen:u},n++))}}}return A(e),X(o),console.log(`
4
+ Migration complete!`),console.log(` People: ${Object.keys(e).length} total (${r} new)`),console.log(` Jobs: ${Object.keys(o).length} total (${n} new)`),{people:Object.keys(e).length,jobs:Object.keys(o).length}}function Ue(){return k||(y(),k=U(Ce,"sync-state.json")||{},k)}function Pe(t){y(),k=t;try{R(Ce,t)}catch(e){console.error(`[!] Failed to save sync-state.json: ${e.message}`)}}function de(){if(T)return T;y();try{d.existsSync(ae)&&(T=JSON.parse(d.readFileSync(ae,"utf-8")))}catch{}return T||(T={}),T}function qe(t){return Array.isArray(t.applications)}function Ve(){let t=de();if(qe(t))return t.applications;let e=[];for(let o of Object.values(t))o.applications&&e.push(...o.applications);return e}function Be(t){if(!t||!t.questions||t.questions.length===0)return;let e=de(),o=t.jobId||"unknown",n={applicationId:`${o}_${Date.now()}`,date:new Date().toISOString(),result:t.result||"submitted",formPages:t.formPages||null,duration:t.duration||null,retries:t.retries||0,failedField:t.failedField||null,questionCount:t.questions.length,questions:t.questions.map(s=>{let i={type:s.type||"input",question:s.labelText||s.question||"",answer:s.answer||""};return s.options&&(s.options.length<=vt?i.options=s.options:i.optionsOmitted=!0),s.page&&(i.page=s.page),s.wasPreFilled&&(i.wasPreFilled=!0),s.wasRetry&&(i.wasRetry=!0),typeof s.isRequired=="boolean"&&(i.isRequired=s.isRequired),s.wasOptional&&(i.wasOptional=!0),i})};qe(e)?(n.jobId=o,n.jobTitle=t.jobTitle||null,n.jobCompany=t.jobCompany||null,n.jobUrl=t.jobUrl||null,e.applications.push(n)):(e[o]||(e[o]={applications:[]}),e[o].applications.push(n));try{R(ae,e)}catch(s){console.error(`[!] Failed to save application-questions.json: ${s.message}`)}}function Qe(){let t=Ve(),e=new Map;for(let s of t)for(let i of s.questions||[]){let a=i.question.toLowerCase().trim();if(!a)continue;e.has(a)||e.set(a,{question:i.question,count:0,answers:new Map});let u=e.get(a);u.count++;let p=(i.answer||"").trim();u.answers.set(p,(u.answers.get(p)||0)+1)}let o=[...e.values()].sort((s,i)=>i.count-s.count),r=o.slice(0,15).map(s=>({question:s.question,count:s.count,topAnswer:[...s.answers.entries()].sort((i,a)=>a[1]-i[1])[0]?.[0]||""})),n=o.filter(s=>s.answers.size>1&&s.count>=3).map(s=>({question:s.question,count:s.count,answers:[...s.answers.entries()].sort((i,a)=>a[1]-i[1]).map(([i,a])=>`${i} (${a}x)`)}));return{totalApplications:t.length,uniqueQuestions:e.size,topQuestions:r,inconsistent:n}}function Ge(t){if(d.existsSync(h.join(S,".git")))try{let e={cwd:S,stdio:"pipe",timeout:1e4};ie("git add conversations.json people.json jobs.json quota.json sync-state.json run-log.json application-questions.json",e);try{ie("git diff --cached --quiet",e);return}catch{}let o=(t||`sync ${new Date().toISOString().slice(0,16)}`).replace(/"/g,'\\"');ie(`git commit -m "${o}"`,e)}catch(e){process.env.VERBOSE&&console.log(` [git] snapshot skipped: ${e.message?.slice(0,80)}`)}}var gt,St,S,ce,le,Te,K,Ce,ae,N,M,L,F,D,C,k,T,ue,vt,wt,me=Ie(()=>{gt=ht(import.meta.url),St=h.dirname(h.dirname(gt)),S=process.env.DATA_DIR?h.resolve(process.env.DATA_DIR,"collected-profiles"):h.join(St,"collected-profiles"),ce=h.join(S,"people.json"),le=h.join(S,"jobs.json"),Te=h.join(S,"quota.json"),K=h.join(S,"conversations.json"),Ce=h.join(S,"sync-state.json"),ae=h.join(S,"application-questions.json"),N=20,M=100,L=null,F=null,D=null,C=null,k=null,T=null;ue=["name","title","location","company","connectionDegree","connectionsCount","mutualConnections","photoUrl","hasVerifiedBadge"];vt=50;wt={loadPeople:O,savePeople:A,loadJobs:H,saveJobs:X,loadConversations:Re,saveConversations:Ae,upsertPerson:pe,upsertJob:Ee,linkPersonToJob:_e,addEncounter:xe,getPersonStatus:Le,updateConnectionStatus:Fe,migrateFromDailyFiles:Me,loadQuota:Z,saveQuota:fe,recordConnectionSent:ke,canSendConnection:Je,getRecentConnections:ee,getQuotaStatus:Ne,loadSyncState:Ue,saveSyncState:Pe,commitDataSnapshot:Ge,logApplicationQuestions:Be,getQuestionStats:Qe}});var et={};$e(et,{getJobDecision:()=>Ct,getLastVisit:()=>_t,getScoutStats:()=>xt,loadCompanies:()=>Ze,loadDiscoveredPeople:()=>ge,loadJobDecisions:()=>Y,loadScoutedJobs:()=>W,loadVisitLog:()=>te,recordVisit:()=>Et,resetCaches:()=>$t,saveCompany:()=>At,saveDiscoveredPerson:()=>Rt,saveScoutedJob:()=>he,setJobDecision:()=>Tt});import"dotenv/config";import*as v from"fs";import*as j from"path";import{fileURLToPath as Ot}from"url";function Q(){v.existsSync(_)||v.mkdirSync(_,{recursive:!0})}function G(t,e){let o=JSON.stringify(e,null,2),r=t+".tmp";v.writeFileSync(r,o);for(let n=0;n<3;n++)try{v.renameSync(r,t);return}catch(s){if(n<2&&(s.code==="EPERM"||s.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw s}}function z(t){try{if(v.existsSync(t))return JSON.parse(v.readFileSync(t,"utf-8"))}catch{}return null}function $t(){P=null,q=null,V=null,B=null,E=null}function W(){return P||(P=z(We)||{},P)}function he(t,e){if(!t)return;Q();let o=W(),r=new Date().toISOString().slice(0,10);if(o[t]){for(let[n,s]of Object.entries(e))s!=null&&(o[t][n]=s);o[t].lastSeen=r}else o[t]={...e,scoutedAt:r,lastSeen:r};try{G(We,o)}catch(n){console.error(`[!] Failed to save scouted-jobs.json: ${n.message}`)}}function Y(){return q||(q=z(Xe)||{},q)}function Tt(t,e,o={}){if(!t||!e)return;Q();let r=Y(),n=new Date().toISOString().slice(0,10);r[t]?(r[t].status=e,r[t].updatedAt=n,o.reason&&(r[t].reason=o.reason),o.score!=null&&(r[t].score=o.score),o.source&&(r[t].source=o.source)):r[t]={status:e,decidedAt:n,updatedAt:n,reason:o.reason||null,score:o.score??null,source:o.source||null};try{G(Xe,r)}catch(s){console.error(`[!] Failed to save job-decisions.json: ${s.message}`)}}function Ct(t){return Y()[t]||null}function ge(){return V||(V=z(Ye)||{},V)}function Rt(t,e){if(!t)return;Q();let o=ge(),r=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.title&&(n.title=e.title),e.company&&(n.company=e.company),e.location&&(n.location=e.location),e.role&&(n.role=e.role),e.isConnected!=null&&(n.isConnected=e.isConnected),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),n.lastSeen=r,n.seenCount=(n.seenCount||1)+1}else o[t]={name:e.name||null,title:e.title||null,company:e.company||null,location:e.location||null,role:e.role||null,source:e.source||"scout",isConnected:e.isConnected||!1,discoveredAt:r,lastSeen:r,seenCount:1,jobIds:e.jobId?[e.jobId]:[]};try{G(Ye,o)}catch(n){console.error(`[!] Failed to save discovered-people.json: ${n.message}`)}}function Ze(){return B||(B=z(He)||{},B)}function At(t,e){if(!t)return;Q();let o=Ze(),r=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.about&&(n.about=e.about),e.size&&(n.size=e.size),e.industries&&(n.industries=e.industries),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),e.recruiterUrl&&(n.recruiterUrls||(n.recruiterUrls=[]),n.recruiterUrls.includes(e.recruiterUrl)||n.recruiterUrls.push(e.recruiterUrl)),n.lastSeen=r,n.jobCount=n.jobIds?.length||0}else o[t]={name:e.name||null,about:e.about||null,size:e.size||null,industries:e.industries||null,discoveredAt:r,lastSeen:r,jobIds:e.jobId?[e.jobId]:[],recruiterUrls:e.recruiterUrl?[e.recruiterUrl]:[],jobCount:e.jobId?1:0};try{G(He,o)}catch(n){console.error(`[!] Failed to save companies.json: ${n.message}`)}}function te(){return E||(E=z(Ke)||{visits:[]},Array.isArray(E.visits)||(E.visits=[]),E)}function Et(t,e={}){if(!t)return;Q();let o=te();o.visits.push({date:new Date().toISOString(),profileUrl:t,name:e.name||null,source:e.source||"manual"});let r=Date.now()-90*24*60*60*1e3;o.visits=o.visits.filter(n=>new Date(n.date).getTime()>r);try{G(Ke,o)}catch(n){console.error(`[!] Failed to save visit-log.json: ${n.message}`)}}function _t(t){let e=te();for(let o=e.visits.length-1;o>=0;o--)if(e.visits[o].profileUrl===t)return e.visits[o].date;return null}function xt(){let t=W(),e=ge(),o=Object.values(t),r=Object.values(e),n={};for(let l of o)l.company&&(n[l.company]=(n[l.company]||0)+1);let s=Object.entries(n).sort((l,f)=>f[1]-l[1]).slice(0,5).map(([l,f])=>`${l} (${f})`),i={};for(let l of o)for(let f of l.techStack||[])i[f]=(i[f]||0)+1;let a=Object.entries(i).sort((l,f)=>f[1]-l[1]).slice(0,8).map(([l,f])=>`${l} (${f})`),u=te(),p=new Date().toISOString().slice(0,10),c=u.visits.filter(l=>l.date.startsWith(p)).length,m=new Set(u.visits.map(l=>l.profileUrl)).size;return{totalJobs:o.length,totalRecruiters:r.length,topCompanies:s,topTech:a,totalVisited:m,todayVisited:c,lastScoutDate:o.length>0?o.sort((l,f)=>(f.scoutedAt||"").localeCompare(l.scoutedAt||""))[0]?.scoutedAt:null}}var Dt,It,_,We,Ye,Ke,He,Xe,P,q,V,B,E,oe=Ie(()=>{Dt=Ot(import.meta.url),It=j.dirname(j.dirname(Dt)),_=process.env.DATA_DIR?j.resolve(process.env.DATA_DIR,"market-research"):j.join(It,"market-research"),We=j.join(_,"scouted-jobs.json"),Ye=j.join(_,"discovered-people.json"),Ke=j.join(_,"visit-log.json"),He=j.join(_,"companies.json"),Xe=j.join(_,"job-decisions.json");P=null;q=null;V=null;B=null;E=null});import"dotenv/config";import*as $ from"fs";import*as x from"path";import{fileURLToPath as to}from"url";import{execFileSync as oo}from"child_process";me();oe();var Lt=new Set(["java","c#",".net","scala","python","typescript","javascript","react","node.js","aws","azure","docker","kubernetes","microservices","graphql","rest","sql","postgresql","mongodb","kafka","redis","ci/cd","terraform","spring"]),Ft=new Set(["iot","machine learning","ai","data engineering","spark","go","rust","kotlin","next.js","devops","sre"]),tt=["vancouver","british columbia"],kt=["canada","montreal","quebec","alberta","calgary","ottawa"],Jt=["toronto","ontario"],Nt=["india","pakistan","nigeria","philippines"];function Mt(t,e={}){let o=0,r=(t.techStack||[]).map(c=>c.toLowerCase()),n=0,s=0;for(let c of r)Lt.has(c)&&n++,Ft.has(c)&&s++;if(o+=Math.min(n*6,24),o+=Math.min(s*3,6),t.salary){let c=Ut(t.salary);c&&(c>=15e4?o+=20:c>=12e4?o+=15:c>=1e5?o+=10:c>=8e4?o+=5:c>=100&&c<1e3?o+=15:c>=70&&c<1e3&&(o+=10))}let i=(t.location||"").toLowerCase(),a=/remote/i.test(i)||t.workplaceType==="remote";Nt.some(c=>i.includes(c))?o-=30:a&&/united states|usa|\bus\b/i.test(i)?o+=25:a&&tt.some(c=>i.includes(c))?o+=22:a?o+=20:tt.some(c=>i.includes(c))?o+=18:kt.some(c=>i.includes(c))?o+=10:Jt.some(c=>i.includes(c))&&(o+=5),t.isEasyApply&&(o+=5);let u=(t.seniority||"").toLowerCase();u.includes("senior")||u.includes("lead")||u.includes("staff")?o+=10:u.includes("mid")?o+=5:(u.includes("entry")||u.includes("intern"))&&(o-=10),t.recruiterUrl&&(e.conversationRecruiters?.has(t.recruiterUrl)?o+=20:e.connectedRecruiters?.has(t.recruiterUrl)?o+=15:o+=3);let p=new Set(t.jobTags||[]);return p.has("managerial")?o+=8:p.has("senior-ic")&&(o+=5),p.has("junior")&&(o-=15),p.has("consultant")&&(o-=3),Math.max(0,Math.min(100,o))}function Se(t=10,e={}){let{easyApplyOnly:o=!0}=e,r=W(),n=O(),s=new Set,i=new Set;for(let[m,l]of Object.entries(n))l.connectionStatus==="connected"&&s.add(m);let a={connectedRecruiters:s,conversationRecruiters:i},u=Y(),p=new Set(["applied","skipped","expired","archived"]);return Object.entries(r).filter(([m,l])=>{if(typeof l!="object"||o&&!l.isEasyApply||l.applied)return!1;let f=u[m];return!(f&&p.has(f.status))}).map(([m,l])=>({jobId:m,score:Mt(l,a),job:l})).sort((m,l)=>{if(l.score!==m.score)return l.score-m.score;let f=m.job.scoutedAt||m.job.postedTime||"";return(l.job.scoutedAt||l.job.postedTime||"").localeCompare(f)}).slice(0,t)}function Ut(t){if(!t)return null;let e=t.match(/[\$£€CAD\s]*([\d,]+(?:\.\d+)?)\s*[kK]?/g);if(!e||e.length===0)return null;let o=e.map(r=>{let n=parseFloat(r.replace(/[^\d.]/g,""));return r.toLowerCase().includes("k")&&(n*=1e3),n}).filter(r=>r>0);return o.length>=2?(o[0]+o[1])/2:o.length===1?o[0]:null}oe();import"dotenv/config";import*as w from"fs";import*as I from"path";import{fileURLToPath as Gt}from"url";import"dotenv/config";import{createGraphClient as Pt,resolveToken as qt}from"@ilivemylife/graph-sdk";import{config as Vt}from"dotenv";Vt();var ot=qt()||process.env.TOKEN;ot||(console.error(`
5
5
  [FATAL] No iLiveMyLife token found.`),console.error(" The bot uses Lifebot AI to decide which jobs to apply for"),console.error(` and how to fill application forms. It cannot work without it.
6
6
  `),console.error(" Easiest way:"),console.error(" 1. npm install -g @ilivemylife/graph-sdk"),console.error(` 2. ilml login your@email.com yourpassword
7
7
  `),console.error(` Or add ILML_TOKEN=... to .env
package/dist/daily.mjs CHANGED
@@ -1,22 +1,22 @@
1
- var ht=Object.defineProperty;var De=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ie=(t,e)=>{for(var o in e)ht(t,o,{get:e[o],enumerable:!0})};var Ge={};Ie(Ge,{addEncounter:()=>Ne,canSendConnection:()=>ee,commitDataSnapshot:()=>We,default:()=>xt,getAllApplications:()=>Qe,getPersonStatus:()=>Me,getQuestionStats:()=>ze,getQuotaStatus:()=>te,getRecentConnections:()=>Z,linkPersonToJob:()=>ke,loadApplicationQuestions:()=>me,loadConversations:()=>xe,loadJobs:()=>K,loadPeople:()=>w,loadQuota:()=>X,loadSyncState:()=>qe,logApplicationQuestions:()=>Ye,migrateFromDailyFiles:()=>Ue,recordConnectionSent:()=>Pe,resetCaches:()=>Ct,saveConversations:()=>Fe,saveJobs:()=>H,savePeople:()=>A,saveQuota:()=>de,saveSyncState:()=>Ve,updateConnectionStatus:()=>Je,upsertJob:()=>Le,upsertPerson:()=>fe});import"dotenv/config";import*as d from"fs";import*as m from"path";import{fileURLToPath as Ot}from"url";import{execSync as ce}from"child_process";function Ct(){x=null,F=null,I=null,T=null,L=null,R=null}function S(){d.existsSync(h)||d.mkdirSync(h,{recursive:!0})}function C(t,e){let o=JSON.stringify(e,null,2),s=t+".tmp";d.writeFileSync(s,o);for(let n=0;n<3;n++)try{d.renameSync(s,t);return}catch(r){if(n<2&&(r.code==="EPERM"||r.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw r}}function P(t,e){if(!d.existsSync(t))return null;try{let o=JSON.parse(d.readFileSync(t,"utf-8"));try{d.copyFileSync(t,t+".backup")}catch{}return o}catch(o){console.error(`[!] ${e} is corrupted: ${o.message}`),console.error(` File: ${m.resolve(t)}`);let s=t+".backup";if(d.existsSync(s))try{let n=JSON.parse(d.readFileSync(s,"utf-8"));console.error(` Restored from ${s}`);try{d.copyFileSync(s,t)}catch{}return n}catch{console.error(" Backup also corrupted!")}console.error(` Starting with empty data. Old file preserved as ${t}.corrupted`);try{d.copyFileSync(t,t+".corrupted")}catch{}return null}}function k(){return new Date().toISOString().split("T")[0]}function w(){return x||(S(),x=P(le,"people.json")||{},x)}function A(t){S(),x=t;try{C(le,t)}catch(e){console.error(`[!] Failed to save people.json: ${e.message}`),console.error(` Path: ${m.resolve(le)}`)}}function K(){return F||(S(),F=P(ae,"jobs.json")||{},F)}function H(t){S(),F=t;try{C(ae,t)}catch(e){console.error(`[!] Failed to save jobs.json: ${e.message}`),console.error(` Path: ${m.resolve(ae)}`)}}function xe(){return T||(S(),T=P(G,"conversations.json")||{},At(T),T)}function At(t){let e=0;for(let o of Object.values(t)){if(!(o.draftStatus!==void 0||o.draftPreparedAt!==void 0))continue;let n=(o.messages||[]).find(r=>r.status==="draft");n&&o.draftStatus&&o.draftStatus!=="pending"&&(n.status=o.draftStatus),delete o.draftStatus,delete o.draftPreparedAt,e++}if(e>0){console.log(` [migration] Moved draft state from conv to msg.status for ${e} conversations`);try{C(G,t)}catch{}}}function Fe(t){S(),T=t;try{C(G,t)}catch(e){console.error(`[!] Failed to save conversations.json: ${e.message}`),console.error(` Path: ${m.resolve(G)}`)}}function fe(t,e={}){if(!t)return null;let o=w(),s=k(),n=new Date().toISOString(),r=o[t];if(r){r.seenCount=(r.seenCount||1)+1,r.lastSeen=s,r.lastUpdated=n,e.source&&!r.sources?.includes(e.source)&&(r.sources=r.sources||[],r.sources.push(e.source));for(let i of pe)e[i]!=null&&(r[i]=e[i])}else o[t]={name:e.name||null,title:e.title||null,location:e.location||null,company:e.company||null,connectionDegree:e.connectionDegree||null,connectionsCount:e.connectionsCount||null,mutualConnections:e.mutualConnections||null,photoUrl:e.photoUrl||null,hasVerifiedBadge:e.hasVerifiedBadge||!1,firstSeen:s,lastSeen:s,seenCount:1,sources:e.source?[e.source]:[],connectionStatus:null,connectionDate:null,connectionMethod:null,messageSent:null,jobIds:[],lastUpdated:n};return A(o),o[t]}function Le(t,e={}){if(!t)return null;let o=K(),s=k(),n=o[t];if(n){let r=["title","company","companyUrl","location","salary","url","applied","appliedDate","recruiterUrl","description","techStack","jobTags","seniority","employmentType","industries","jobFunction","postedTime","applicantCount","companySize","workplaceType","contractType","isEasyApply","applyType","scoutedAt","lastSeen"];for(let i of r)e[i]!=null&&(n[i]=e[i])}else o[t]={title:e.title||null,company:e.company||null,location:e.location||null,salary:e.salary||null,url:e.url||null,applied:e.applied||!1,appliedDate:e.appliedDate||s,recruiterUrl:e.recruiterUrl||null,firstSeen:s};return H(o),o[t]}function ke(t,e){if(!t||!e)return;let o=w(),s=o[t];s&&(s.jobIds||(s.jobIds=[]),s.jobIds.includes(e)||(s.jobIds.push(e),s.lastUpdated=new Date().toISOString(),A(o)))}function Ne(t,e){if(!t||!e)return;let o=w(),s=o[t];if(!s)return;s.encounters||(s.encounters=[]);let r={date:k(),source:e.source||"unknown",action:e.action||"unknown"};e.jobId&&(r.jobId=String(e.jobId)),e.jobTitle&&(r.jobTitle=e.jobTitle),e.jobCompany&&(r.jobCompany=e.jobCompany),!s.encounters.some(c=>c.date===r.date&&c.source===r.source&&c.action===r.action&&(c.jobId||"")===(r.jobId||""))&&(s.encounters.push(r),s.lastUpdated=new Date().toISOString(),A(o))}function Me(t){return t&&w()[t]?.connectionStatus||null}function Je(t,e,o={}){if(!t)return;let s=w(),n=s[t];if(n||(fe(t,o.profileInfo||{}),n=s[t]),!!n){if(n.connectionStatus=e,n.connectionDate=k(),n.connectionMethod=o.method||n.connectionMethod,n.messageSent=o.messageSent||n.messageSent,n.lastUpdated=new Date().toISOString(),o.profileInfo)for(let r of pe)o.profileInfo[r]!=null&&(n[r]=o.profileInfo[r]);A(s)}}function X(){return I||(S(),I=P(Ee,"quota.json"),(!I||!I.connections)&&(I={connections:[]}),I)}function de(t){S(),I=t;try{C(Ee,t)}catch(e){console.error(`[!] Failed to save quota.json: ${e.message}`)}}function Pe(t,e="unknown"){let o=X(),s=new Date;o.connections.push({date:s.toISOString().split("T")[0],time:s.toTimeString().split(" ")[0],profileUrl:t,source:e}),de(o)}function Z(){let t=X(),e=new Date;e.setDate(e.getDate()-7);let o=e.toISOString().split("T")[0];return t.connections.filter(s=>s.date>=o)}function ee(){let t=Z(),e=k(),o=t.filter(a=>a.date===e).length,s=t.length,n=o>=M,r=s>=J,i=!n&&!r,c={allowed:i,daily:{sent:o,max:M},weekly:{sent:s,max:J}};return i||(c.reason=n?`Daily limit reached (${o}/${M})`:`Weekly limit reached (${s}/${J})`),c}function te(){let t=Z(),e=k(),o=t.filter(n=>n.date===e).length,s=t.length;return{daily:{sent:o,max:M,remaining:M-o},weekly:{sent:s,max:J,remaining:J-s}}}function Et(t){if(!t)return null;let e=t.match(/jobs\/view\/(\d+)/);return e?e[1]:null}function Ue(){S();let t=d.readdirSync(h).filter(r=>r.endsWith(".json")&&r!=="people.json"&&r!=="jobs.json"&&r!=="quota.json");if(t.length===0)return console.log("No daily files found to migrate."),{people:0,jobs:0};console.log(`
1
+ var ht=Object.defineProperty;var De=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ie=(t,e)=>{for(var o in e)ht(t,o,{get:e[o],enumerable:!0})};var Ge={};Ie(Ge,{addEncounter:()=>Ne,canSendConnection:()=>ee,commitDataSnapshot:()=>We,default:()=>xt,getAllApplications:()=>Qe,getPersonStatus:()=>Me,getQuestionStats:()=>ze,getQuotaStatus:()=>te,getRecentConnections:()=>Z,linkPersonToJob:()=>ke,loadApplicationQuestions:()=>me,loadConversations:()=>xe,loadJobs:()=>K,loadPeople:()=>O,loadQuota:()=>X,loadSyncState:()=>qe,logApplicationQuestions:()=>Ye,migrateFromDailyFiles:()=>Ue,recordConnectionSent:()=>Pe,resetCaches:()=>Ct,saveConversations:()=>Fe,saveJobs:()=>H,savePeople:()=>A,saveQuota:()=>de,saveSyncState:()=>Ve,updateConnectionStatus:()=>Je,upsertJob:()=>Le,upsertPerson:()=>fe});import"dotenv/config";import*as d from"fs";import*as m from"path";import{fileURLToPath as $t}from"url";import{execSync as ce}from"child_process";function Ct(){x=null,F=null,I=null,T=null,L=null,R=null}function S(){d.existsSync(h)||d.mkdirSync(h,{recursive:!0})}function C(t,e){let o=JSON.stringify(e,null,2),s=t+".tmp";d.writeFileSync(s,o);for(let n=0;n<3;n++)try{d.renameSync(s,t);return}catch(r){if(n<2&&(r.code==="EPERM"||r.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw r}}function P(t,e){if(!d.existsSync(t))return null;try{let o=JSON.parse(d.readFileSync(t,"utf-8"));try{d.copyFileSync(t,t+".backup")}catch{}return o}catch(o){console.error(`[!] ${e} is corrupted: ${o.message}`),console.error(` File: ${m.resolve(t)}`);let s=t+".backup";if(d.existsSync(s))try{let n=JSON.parse(d.readFileSync(s,"utf-8"));console.error(` Restored from ${s}`);try{d.copyFileSync(s,t)}catch{}return n}catch{console.error(" Backup also corrupted!")}console.error(` Starting with empty data. Old file preserved as ${t}.corrupted`);try{d.copyFileSync(t,t+".corrupted")}catch{}return null}}function k(){return new Date().toISOString().split("T")[0]}function O(){return x||(S(),x=P(le,"people.json")||{},x)}function A(t){S(),x=t;try{C(le,t)}catch(e){console.error(`[!] Failed to save people.json: ${e.message}`),console.error(` Path: ${m.resolve(le)}`)}}function K(){return F||(S(),F=P(ae,"jobs.json")||{},F)}function H(t){S(),F=t;try{C(ae,t)}catch(e){console.error(`[!] Failed to save jobs.json: ${e.message}`),console.error(` Path: ${m.resolve(ae)}`)}}function xe(){return T||(S(),T=P(G,"conversations.json")||{},At(T),T)}function At(t){let e=0;for(let o of Object.values(t)){if(!(o.draftStatus!==void 0||o.draftPreparedAt!==void 0))continue;let n=(o.messages||[]).find(r=>r.status==="draft");n&&o.draftStatus&&o.draftStatus!=="pending"&&(n.status=o.draftStatus),delete o.draftStatus,delete o.draftPreparedAt,e++}if(e>0){console.log(` [migration] Moved draft state from conv to msg.status for ${e} conversations`);try{C(G,t)}catch{}}}function Fe(t){S(),T=t;try{C(G,t)}catch(e){console.error(`[!] Failed to save conversations.json: ${e.message}`),console.error(` Path: ${m.resolve(G)}`)}}function fe(t,e={}){if(!t)return null;let o=O(),s=k(),n=new Date().toISOString(),r=o[t];if(r){r.seenCount=(r.seenCount||1)+1,r.lastSeen=s,r.lastUpdated=n,e.source&&!r.sources?.includes(e.source)&&(r.sources=r.sources||[],r.sources.push(e.source));for(let i of pe)e[i]!=null&&(r[i]=e[i])}else o[t]={name:e.name||null,title:e.title||null,location:e.location||null,company:e.company||null,connectionDegree:e.connectionDegree||null,connectionsCount:e.connectionsCount||null,mutualConnections:e.mutualConnections||null,photoUrl:e.photoUrl||null,hasVerifiedBadge:e.hasVerifiedBadge||!1,firstSeen:s,lastSeen:s,seenCount:1,sources:e.source?[e.source]:[],connectionStatus:null,connectionDate:null,connectionMethod:null,messageSent:null,jobIds:[],lastUpdated:n};return A(o),o[t]}function Le(t,e={}){if(!t)return null;let o=K(),s=k(),n=o[t];if(n){let r=["title","company","companyUrl","location","salary","url","applied","appliedDate","recruiterUrl","description","techStack","jobTags","seniority","employmentType","industries","jobFunction","postedTime","applicantCount","companySize","workplaceType","contractType","isEasyApply","applyType","scoutedAt","lastSeen"];for(let i of r)e[i]!=null&&(n[i]=e[i])}else o[t]={title:e.title||null,company:e.company||null,location:e.location||null,salary:e.salary||null,url:e.url||null,applied:e.applied||!1,appliedDate:e.appliedDate||s,recruiterUrl:e.recruiterUrl||null,firstSeen:s};return H(o),o[t]}function ke(t,e){if(!t||!e)return;let o=O(),s=o[t];s&&(s.jobIds||(s.jobIds=[]),s.jobIds.includes(e)||(s.jobIds.push(e),s.lastUpdated=new Date().toISOString(),A(o)))}function Ne(t,e){if(!t||!e)return;let o=O(),s=o[t];if(!s)return;s.encounters||(s.encounters=[]);let r={date:k(),source:e.source||"unknown",action:e.action||"unknown"};e.jobId&&(r.jobId=String(e.jobId)),e.jobTitle&&(r.jobTitle=e.jobTitle),e.jobCompany&&(r.jobCompany=e.jobCompany),!s.encounters.some(c=>c.date===r.date&&c.source===r.source&&c.action===r.action&&(c.jobId||"")===(r.jobId||""))&&(s.encounters.push(r),s.lastUpdated=new Date().toISOString(),A(o))}function Me(t){return t&&O()[t]?.connectionStatus||null}function Je(t,e,o={}){if(!t)return;let s=O(),n=s[t];if(n||(fe(t,o.profileInfo||{}),n=s[t]),!!n){if(n.connectionStatus=e,n.connectionDate=k(),n.connectionMethod=o.method||n.connectionMethod,n.messageSent=o.messageSent||n.messageSent,n.lastUpdated=new Date().toISOString(),o.profileInfo)for(let r of pe)o.profileInfo[r]!=null&&(n[r]=o.profileInfo[r]);A(s)}}function X(){return I||(S(),I=P(Ee,"quota.json"),(!I||!I.connections)&&(I={connections:[]}),I)}function de(t){S(),I=t;try{C(Ee,t)}catch(e){console.error(`[!] Failed to save quota.json: ${e.message}`)}}function Pe(t,e="unknown"){let o=X(),s=new Date;o.connections.push({date:s.toISOString().split("T")[0],time:s.toTimeString().split(" ")[0],profileUrl:t,source:e}),de(o)}function Z(){let t=X(),e=new Date;e.setDate(e.getDate()-7);let o=e.toISOString().split("T")[0];return t.connections.filter(s=>s.date>=o)}function ee(){let t=Z(),e=k(),o=t.filter(a=>a.date===e).length,s=t.length,n=o>=M,r=s>=J,i=!n&&!r,c={allowed:i,daily:{sent:o,max:M},weekly:{sent:s,max:J}};return i||(c.reason=n?`Daily limit reached (${o}/${M})`:`Weekly limit reached (${s}/${J})`),c}function te(){let t=Z(),e=k(),o=t.filter(n=>n.date===e).length,s=t.length;return{daily:{sent:o,max:M,remaining:M-o},weekly:{sent:s,max:J,remaining:J-s}}}function Et(t){if(!t)return null;let e=t.match(/jobs\/view\/(\d+)/);return e?e[1]:null}function Ue(){S();let t=d.readdirSync(h).filter(r=>r.endsWith(".json")&&r!=="people.json"&&r!=="jobs.json"&&r!=="quota.json");if(t.length===0)return console.log("No daily files found to migrate."),{people:0,jobs:0};console.log(`
2
2
  Migrating from ${t.length} daily files...
3
- `);let e=w(),o=K(),s=0,n=0;t.sort();for(let r of t){let i=m.join(h,r),c;try{c=JSON.parse(d.readFileSync(i,"utf-8"))}catch(u){console.log(` Skipping ${r}: ${u.message}`);continue}let a=c.date||r.match(/\d{4}-\d{2}-\d{2}/)?.[0]||null,f=c.source||r.split("-").slice(0,-1).join("-").replace(/-\d{4}$/,"")||"unknown";if(!c.profiles||!Array.isArray(c.profiles)){console.log(` Skipping ${r}: no profiles array`);continue}console.log(` ${r}: ${c.profiles.length} profiles`);for(let u of c.profiles){let v=u.profileUrl;if(!v)continue;let l=e[v];if(l){l.seenCount=(l.seenCount||1)+1,a&&(!l.lastSeen||a>l.lastSeen)&&(l.lastSeen=a),a&&(!l.firstSeen||a<l.firstSeen)&&(l.firstSeen=a),f&&!l.sources?.includes(f)&&(l.sources=l.sources||[],l.sources.push(f));for(let p of pe)u[p]!=null&&(l[p]=u[p]);u.status&&u.processed&&(l.connectionStatus=u.status,l.connectionDate=a,u.funnelResult&&(l.connectionMethod=u.funnelResult.method||l.connectionMethod,l.messageSent=u.funnelResult.message||l.messageSent)),l.lastUpdated=new Date().toISOString()}else e[v]={name:u.name||null,title:u.title||null,location:u.location||null,company:u.company||null,connectionDegree:u.connectionDegree||null,connectionsCount:u.connectionsCount||null,mutualConnections:u.mutualConnections||null,photoUrl:u.photoUrl||null,hasVerifiedBadge:u.hasVerifiedBadge||!1,firstSeen:a,lastSeen:a,seenCount:1,sources:f?[f]:[],connectionStatus:u.processed&&u.status||null,connectionDate:u.processed?a:null,connectionMethod:u.funnelResult?.method||null,messageSent:u.funnelResult?.message||null,jobIds:[],lastUpdated:new Date().toISOString()},s++;if(u.fromJob?.url){let p=Et(u.fromJob.url);p&&(e[v].jobIds||(e[v].jobIds=[]),e[v].jobIds.includes(p)||e[v].jobIds.push(p),o[p]?o[p].recruiterUrl||(o[p].recruiterUrl=v):(o[p]={title:u.fromJob.title||null,company:u.fromJob.company||null,location:null,salary:null,url:u.fromJob.url,applied:!0,appliedDate:a,recruiterUrl:v,firstSeen:a},n++))}}}return A(e),H(o),console.log(`
4
- Migration complete!`),console.log(` People: ${Object.keys(e).length} total (${s} new)`),console.log(` Jobs: ${Object.keys(o).length} total (${n} new)`),{people:Object.keys(e).length,jobs:Object.keys(o).length}}function qe(){return L||(S(),L=P(_e,"sync-state.json")||{},L)}function Ve(t){S(),L=t;try{C(_e,t)}catch(e){console.error(`[!] Failed to save sync-state.json: ${e.message}`)}}function me(){if(R)return R;S();try{d.existsSync(ue)&&(R=JSON.parse(d.readFileSync(ue,"utf-8")))}catch{}return R||(R={}),R}function Be(t){return Array.isArray(t.applications)}function Qe(){let t=me();if(Be(t))return t.applications;let e=[];for(let o of Object.values(t))o.applications&&e.push(...o.applications);return e}function Ye(t){if(!t||!t.questions||t.questions.length===0)return;let e=me(),o=t.jobId||"unknown",n={applicationId:`${o}_${Date.now()}`,date:new Date().toISOString(),result:t.result||"submitted",formPages:t.formPages||null,duration:t.duration||null,retries:t.retries||0,failedField:t.failedField||null,questionCount:t.questions.length,questions:t.questions.map(r=>{let i={type:r.type||"input",question:r.labelText||r.question||"",answer:r.answer||""};return r.options&&(r.options.length<=_t?i.options=r.options:i.optionsOmitted=!0),r.page&&(i.page=r.page),r.wasPreFilled&&(i.wasPreFilled=!0),r.wasRetry&&(i.wasRetry=!0),i})};Be(e)?(n.jobId=o,n.jobTitle=t.jobTitle||null,n.jobCompany=t.jobCompany||null,n.jobUrl=t.jobUrl||null,e.applications.push(n)):(e[o]||(e[o]={applications:[]}),e[o].applications.push(n));try{C(ue,e)}catch(r){console.error(`[!] Failed to save application-questions.json: ${r.message}`)}}function ze(){let t=Qe(),e=new Map;for(let r of t)for(let i of r.questions||[]){let c=i.question.toLowerCase().trim();if(!c)continue;e.has(c)||e.set(c,{question:i.question,count:0,answers:new Map});let a=e.get(c);a.count++;let f=(i.answer||"").trim();a.answers.set(f,(a.answers.get(f)||0)+1)}let o=[...e.values()].sort((r,i)=>i.count-r.count),s=o.slice(0,15).map(r=>({question:r.question,count:r.count,topAnswer:[...r.answers.entries()].sort((i,c)=>c[1]-i[1])[0]?.[0]||""})),n=o.filter(r=>r.answers.size>1&&r.count>=3).map(r=>({question:r.question,count:r.count,answers:[...r.answers.entries()].sort((i,c)=>c[1]-i[1]).map(([i,c])=>`${i} (${c}x)`)}));return{totalApplications:t.length,uniqueQuestions:e.size,topQuestions:s,inconsistent:n}}function We(t){if(d.existsSync(m.join(h,".git")))try{let e={cwd:h,stdio:"pipe",timeout:1e4};ce("git add conversations.json people.json jobs.json quota.json sync-state.json run-log.json application-questions.json",e);try{ce("git diff --cached --quiet",e);return}catch{}let o=(t||`sync ${new Date().toISOString().slice(0,16)}`).replace(/"/g,'\\"');ce(`git commit -m "${o}"`,e)}catch(e){process.env.VERBOSE&&console.log(` [git] snapshot skipped: ${e.message?.slice(0,80)}`)}}var Rt,Tt,h,le,ae,Ee,G,_e,ue,M,J,x,F,I,T,L,R,pe,_t,xt,ge=De(()=>{Rt=Ot(import.meta.url),Tt=m.dirname(m.dirname(Rt)),h=process.env.DATA_DIR?m.resolve(process.env.DATA_DIR,"collected-profiles"):m.join(Tt,"collected-profiles"),le=m.join(h,"people.json"),ae=m.join(h,"jobs.json"),Ee=m.join(h,"quota.json"),G=m.join(h,"conversations.json"),_e=m.join(h,"sync-state.json"),ue=m.join(h,"application-questions.json"),M=20,J=100,x=null,F=null,I=null,T=null,L=null,R=null;pe=["name","title","location","company","connectionDegree","connectionsCount","mutualConnections","photoUrl","hasVerifiedBadge"];_t=50;xt={loadPeople:w,savePeople:A,loadJobs:K,saveJobs:H,loadConversations:xe,saveConversations:Fe,upsertPerson:fe,upsertJob:Le,linkPersonToJob:ke,addEncounter:Ne,getPersonStatus:Me,updateConnectionStatus:Je,migrateFromDailyFiles:Ue,loadQuota:X,saveQuota:de,recordConnectionSent:Pe,canSendConnection:ee,getRecentConnections:Z,getQuotaStatus:te,loadSyncState:qe,saveSyncState:Ve,commitDataSnapshot:We,logApplicationQuestions:Ye,getQuestionStats:ze}});var ot={};Ie(ot,{getJobDecision:()=>Pt,getLastVisit:()=>Bt,getScoutStats:()=>Qt,loadCompanies:()=>tt,loadDiscoveredPeople:()=>ye,loadJobDecisions:()=>Se,loadScoutedJobs:()=>he,loadVisitLog:()=>oe,recordVisit:()=>Vt,resetCaches:()=>Nt,saveCompany:()=>qt,saveDiscoveredPerson:()=>Ut,saveScoutedJob:()=>Mt,setJobDecision:()=>Jt});import"dotenv/config";import*as D from"fs";import*as y from"path";import{fileURLToPath as Ft}from"url";function Q(){D.existsSync(_)||D.mkdirSync(_,{recursive:!0})}function Y(t,e){let o=JSON.stringify(e,null,2),s=t+".tmp";D.writeFileSync(s,o);for(let n=0;n<3;n++)try{D.renameSync(s,t);return}catch(r){if(n<2&&(r.code==="EPERM"||r.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw r}}function z(t){try{if(D.existsSync(t))return JSON.parse(D.readFileSync(t,"utf-8"))}catch{}return null}function Nt(){U=null,q=null,V=null,B=null,E=null}function he(){return U||(U=z(Ke)||{},U)}function Mt(t,e){if(!t)return;Q();let o=he(),s=new Date().toISOString().slice(0,10);if(o[t]){for(let[n,r]of Object.entries(e))r!=null&&(o[t][n]=r);o[t].lastSeen=s}else o[t]={...e,scoutedAt:s,lastSeen:s};try{Y(Ke,o)}catch(n){console.error(`[!] Failed to save scouted-jobs.json: ${n.message}`)}}function Se(){return q||(q=z(et)||{},q)}function Jt(t,e,o={}){if(!t||!e)return;Q();let s=Se(),n=new Date().toISOString().slice(0,10);s[t]?(s[t].status=e,s[t].updatedAt=n,o.reason&&(s[t].reason=o.reason),o.score!=null&&(s[t].score=o.score),o.source&&(s[t].source=o.source)):s[t]={status:e,decidedAt:n,updatedAt:n,reason:o.reason||null,score:o.score??null,source:o.source||null};try{Y(et,s)}catch(r){console.error(`[!] Failed to save job-decisions.json: ${r.message}`)}}function Pt(t){return Se()[t]||null}function ye(){return V||(V=z(He)||{},V)}function Ut(t,e){if(!t)return;Q();let o=ye(),s=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.title&&(n.title=e.title),e.company&&(n.company=e.company),e.location&&(n.location=e.location),e.role&&(n.role=e.role),e.isConnected!=null&&(n.isConnected=e.isConnected),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),n.lastSeen=s,n.seenCount=(n.seenCount||1)+1}else o[t]={name:e.name||null,title:e.title||null,company:e.company||null,location:e.location||null,role:e.role||null,source:e.source||"scout",isConnected:e.isConnected||!1,discoveredAt:s,lastSeen:s,seenCount:1,jobIds:e.jobId?[e.jobId]:[]};try{Y(He,o)}catch(n){console.error(`[!] Failed to save discovered-people.json: ${n.message}`)}}function tt(){return B||(B=z(Ze)||{},B)}function qt(t,e){if(!t)return;Q();let o=tt(),s=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.about&&(n.about=e.about),e.size&&(n.size=e.size),e.industries&&(n.industries=e.industries),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),e.recruiterUrl&&(n.recruiterUrls||(n.recruiterUrls=[]),n.recruiterUrls.includes(e.recruiterUrl)||n.recruiterUrls.push(e.recruiterUrl)),n.lastSeen=s,n.jobCount=n.jobIds?.length||0}else o[t]={name:e.name||null,about:e.about||null,size:e.size||null,industries:e.industries||null,discoveredAt:s,lastSeen:s,jobIds:e.jobId?[e.jobId]:[],recruiterUrls:e.recruiterUrl?[e.recruiterUrl]:[],jobCount:e.jobId?1:0};try{Y(Ze,o)}catch(n){console.error(`[!] Failed to save companies.json: ${n.message}`)}}function oe(){return E||(E=z(Xe)||{visits:[]},Array.isArray(E.visits)||(E.visits=[]),E)}function Vt(t,e={}){if(!t)return;Q();let o=oe();o.visits.push({date:new Date().toISOString(),profileUrl:t,name:e.name||null,source:e.source||"manual"});let s=Date.now()-90*24*60*60*1e3;o.visits=o.visits.filter(n=>new Date(n.date).getTime()>s);try{Y(Xe,o)}catch(n){console.error(`[!] Failed to save visit-log.json: ${n.message}`)}}function Bt(t){let e=oe();for(let o=e.visits.length-1;o>=0;o--)if(e.visits[o].profileUrl===t)return e.visits[o].date;return null}function Qt(){let t=he(),e=ye(),o=Object.values(t),s=Object.values(e),n={};for(let l of o)l.company&&(n[l.company]=(n[l.company]||0)+1);let r=Object.entries(n).sort((l,p)=>p[1]-l[1]).slice(0,5).map(([l,p])=>`${l} (${p})`),i={};for(let l of o)for(let p of l.techStack||[])i[p]=(i[p]||0)+1;let c=Object.entries(i).sort((l,p)=>p[1]-l[1]).slice(0,8).map(([l,p])=>`${l} (${p})`),a=oe(),f=new Date().toISOString().slice(0,10),u=a.visits.filter(l=>l.date.startsWith(f)).length,v=new Set(a.visits.map(l=>l.profileUrl)).size;return{totalJobs:o.length,totalRecruiters:s.length,topCompanies:r,topTech:c,totalVisited:v,todayVisited:u,lastScoutDate:o.length>0?o.sort((l,p)=>(p.scoutedAt||"").localeCompare(l.scoutedAt||""))[0]?.scoutedAt:null}}var Lt,kt,_,Ke,He,Xe,Ze,et,U,q,V,B,E,nt=De(()=>{Lt=Ft(import.meta.url),kt=y.dirname(y.dirname(Lt)),_=process.env.DATA_DIR?y.resolve(process.env.DATA_DIR,"market-research"):y.join(kt,"market-research"),Ke=y.join(_,"scouted-jobs.json"),He=y.join(_,"discovered-people.json"),Xe=y.join(_,"visit-log.json"),Ze=y.join(_,"companies.json"),et=y.join(_,"job-decisions.json");U=null;q=null;V=null;B=null;E=null});import{execFileSync as Ht}from"child_process";import"dotenv/config";import*as b from"fs";import*as $ from"path";import{fileURLToPath as Dt}from"url";import"dotenv/config";import{createGraphClient as St,resolveToken as yt}from"@ilivemylife/graph-sdk";import{config as jt}from"dotenv";jt();var $e=yt()||process.env.TOKEN;$e||(console.error(`
3
+ `);let e=O(),o=K(),s=0,n=0;t.sort();for(let r of t){let i=m.join(h,r),c;try{c=JSON.parse(d.readFileSync(i,"utf-8"))}catch(u){console.log(` Skipping ${r}: ${u.message}`);continue}let a=c.date||r.match(/\d{4}-\d{2}-\d{2}/)?.[0]||null,f=c.source||r.split("-").slice(0,-1).join("-").replace(/-\d{4}$/,"")||"unknown";if(!c.profiles||!Array.isArray(c.profiles)){console.log(` Skipping ${r}: no profiles array`);continue}console.log(` ${r}: ${c.profiles.length} profiles`);for(let u of c.profiles){let v=u.profileUrl;if(!v)continue;let l=e[v];if(l){l.seenCount=(l.seenCount||1)+1,a&&(!l.lastSeen||a>l.lastSeen)&&(l.lastSeen=a),a&&(!l.firstSeen||a<l.firstSeen)&&(l.firstSeen=a),f&&!l.sources?.includes(f)&&(l.sources=l.sources||[],l.sources.push(f));for(let p of pe)u[p]!=null&&(l[p]=u[p]);u.status&&u.processed&&(l.connectionStatus=u.status,l.connectionDate=a,u.funnelResult&&(l.connectionMethod=u.funnelResult.method||l.connectionMethod,l.messageSent=u.funnelResult.message||l.messageSent)),l.lastUpdated=new Date().toISOString()}else e[v]={name:u.name||null,title:u.title||null,location:u.location||null,company:u.company||null,connectionDegree:u.connectionDegree||null,connectionsCount:u.connectionsCount||null,mutualConnections:u.mutualConnections||null,photoUrl:u.photoUrl||null,hasVerifiedBadge:u.hasVerifiedBadge||!1,firstSeen:a,lastSeen:a,seenCount:1,sources:f?[f]:[],connectionStatus:u.processed&&u.status||null,connectionDate:u.processed?a:null,connectionMethod:u.funnelResult?.method||null,messageSent:u.funnelResult?.message||null,jobIds:[],lastUpdated:new Date().toISOString()},s++;if(u.fromJob?.url){let p=Et(u.fromJob.url);p&&(e[v].jobIds||(e[v].jobIds=[]),e[v].jobIds.includes(p)||e[v].jobIds.push(p),o[p]?o[p].recruiterUrl||(o[p].recruiterUrl=v):(o[p]={title:u.fromJob.title||null,company:u.fromJob.company||null,location:null,salary:null,url:u.fromJob.url,applied:!0,appliedDate:a,recruiterUrl:v,firstSeen:a},n++))}}}return A(e),H(o),console.log(`
4
+ Migration complete!`),console.log(` People: ${Object.keys(e).length} total (${s} new)`),console.log(` Jobs: ${Object.keys(o).length} total (${n} new)`),{people:Object.keys(e).length,jobs:Object.keys(o).length}}function qe(){return L||(S(),L=P(_e,"sync-state.json")||{},L)}function Ve(t){S(),L=t;try{C(_e,t)}catch(e){console.error(`[!] Failed to save sync-state.json: ${e.message}`)}}function me(){if(R)return R;S();try{d.existsSync(ue)&&(R=JSON.parse(d.readFileSync(ue,"utf-8")))}catch{}return R||(R={}),R}function Be(t){return Array.isArray(t.applications)}function Qe(){let t=me();if(Be(t))return t.applications;let e=[];for(let o of Object.values(t))o.applications&&e.push(...o.applications);return e}function Ye(t){if(!t||!t.questions||t.questions.length===0)return;let e=me(),o=t.jobId||"unknown",n={applicationId:`${o}_${Date.now()}`,date:new Date().toISOString(),result:t.result||"submitted",formPages:t.formPages||null,duration:t.duration||null,retries:t.retries||0,failedField:t.failedField||null,questionCount:t.questions.length,questions:t.questions.map(r=>{let i={type:r.type||"input",question:r.labelText||r.question||"",answer:r.answer||""};return r.options&&(r.options.length<=_t?i.options=r.options:i.optionsOmitted=!0),r.page&&(i.page=r.page),r.wasPreFilled&&(i.wasPreFilled=!0),r.wasRetry&&(i.wasRetry=!0),typeof r.isRequired=="boolean"&&(i.isRequired=r.isRequired),r.wasOptional&&(i.wasOptional=!0),i})};Be(e)?(n.jobId=o,n.jobTitle=t.jobTitle||null,n.jobCompany=t.jobCompany||null,n.jobUrl=t.jobUrl||null,e.applications.push(n)):(e[o]||(e[o]={applications:[]}),e[o].applications.push(n));try{C(ue,e)}catch(r){console.error(`[!] Failed to save application-questions.json: ${r.message}`)}}function ze(){let t=Qe(),e=new Map;for(let r of t)for(let i of r.questions||[]){let c=i.question.toLowerCase().trim();if(!c)continue;e.has(c)||e.set(c,{question:i.question,count:0,answers:new Map});let a=e.get(c);a.count++;let f=(i.answer||"").trim();a.answers.set(f,(a.answers.get(f)||0)+1)}let o=[...e.values()].sort((r,i)=>i.count-r.count),s=o.slice(0,15).map(r=>({question:r.question,count:r.count,topAnswer:[...r.answers.entries()].sort((i,c)=>c[1]-i[1])[0]?.[0]||""})),n=o.filter(r=>r.answers.size>1&&r.count>=3).map(r=>({question:r.question,count:r.count,answers:[...r.answers.entries()].sort((i,c)=>c[1]-i[1]).map(([i,c])=>`${i} (${c}x)`)}));return{totalApplications:t.length,uniqueQuestions:e.size,topQuestions:s,inconsistent:n}}function We(t){if(d.existsSync(m.join(h,".git")))try{let e={cwd:h,stdio:"pipe",timeout:1e4};ce("git add conversations.json people.json jobs.json quota.json sync-state.json run-log.json application-questions.json",e);try{ce("git diff --cached --quiet",e);return}catch{}let o=(t||`sync ${new Date().toISOString().slice(0,16)}`).replace(/"/g,'\\"');ce(`git commit -m "${o}"`,e)}catch(e){process.env.VERBOSE&&console.log(` [git] snapshot skipped: ${e.message?.slice(0,80)}`)}}var Rt,Tt,h,le,ae,Ee,G,_e,ue,M,J,x,F,I,T,L,R,pe,_t,xt,ge=De(()=>{Rt=$t(import.meta.url),Tt=m.dirname(m.dirname(Rt)),h=process.env.DATA_DIR?m.resolve(process.env.DATA_DIR,"collected-profiles"):m.join(Tt,"collected-profiles"),le=m.join(h,"people.json"),ae=m.join(h,"jobs.json"),Ee=m.join(h,"quota.json"),G=m.join(h,"conversations.json"),_e=m.join(h,"sync-state.json"),ue=m.join(h,"application-questions.json"),M=20,J=100,x=null,F=null,I=null,T=null,L=null,R=null;pe=["name","title","location","company","connectionDegree","connectionsCount","mutualConnections","photoUrl","hasVerifiedBadge"];_t=50;xt={loadPeople:O,savePeople:A,loadJobs:K,saveJobs:H,loadConversations:xe,saveConversations:Fe,upsertPerson:fe,upsertJob:Le,linkPersonToJob:ke,addEncounter:Ne,getPersonStatus:Me,updateConnectionStatus:Je,migrateFromDailyFiles:Ue,loadQuota:X,saveQuota:de,recordConnectionSent:Pe,canSendConnection:ee,getRecentConnections:Z,getQuotaStatus:te,loadSyncState:qe,saveSyncState:Ve,commitDataSnapshot:We,logApplicationQuestions:Ye,getQuestionStats:ze}});var ot={};Ie(ot,{getJobDecision:()=>Pt,getLastVisit:()=>Bt,getScoutStats:()=>Qt,loadCompanies:()=>tt,loadDiscoveredPeople:()=>ye,loadJobDecisions:()=>Se,loadScoutedJobs:()=>he,loadVisitLog:()=>oe,recordVisit:()=>Vt,resetCaches:()=>Nt,saveCompany:()=>qt,saveDiscoveredPerson:()=>Ut,saveScoutedJob:()=>Mt,setJobDecision:()=>Jt});import"dotenv/config";import*as D from"fs";import*as y from"path";import{fileURLToPath as Ft}from"url";function Q(){D.existsSync(_)||D.mkdirSync(_,{recursive:!0})}function Y(t,e){let o=JSON.stringify(e,null,2),s=t+".tmp";D.writeFileSync(s,o);for(let n=0;n<3;n++)try{D.renameSync(s,t);return}catch(r){if(n<2&&(r.code==="EPERM"||r.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw r}}function z(t){try{if(D.existsSync(t))return JSON.parse(D.readFileSync(t,"utf-8"))}catch{}return null}function Nt(){U=null,q=null,V=null,B=null,E=null}function he(){return U||(U=z(Ke)||{},U)}function Mt(t,e){if(!t)return;Q();let o=he(),s=new Date().toISOString().slice(0,10);if(o[t]){for(let[n,r]of Object.entries(e))r!=null&&(o[t][n]=r);o[t].lastSeen=s}else o[t]={...e,scoutedAt:s,lastSeen:s};try{Y(Ke,o)}catch(n){console.error(`[!] Failed to save scouted-jobs.json: ${n.message}`)}}function Se(){return q||(q=z(et)||{},q)}function Jt(t,e,o={}){if(!t||!e)return;Q();let s=Se(),n=new Date().toISOString().slice(0,10);s[t]?(s[t].status=e,s[t].updatedAt=n,o.reason&&(s[t].reason=o.reason),o.score!=null&&(s[t].score=o.score),o.source&&(s[t].source=o.source)):s[t]={status:e,decidedAt:n,updatedAt:n,reason:o.reason||null,score:o.score??null,source:o.source||null};try{Y(et,s)}catch(r){console.error(`[!] Failed to save job-decisions.json: ${r.message}`)}}function Pt(t){return Se()[t]||null}function ye(){return V||(V=z(He)||{},V)}function Ut(t,e){if(!t)return;Q();let o=ye(),s=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.title&&(n.title=e.title),e.company&&(n.company=e.company),e.location&&(n.location=e.location),e.role&&(n.role=e.role),e.isConnected!=null&&(n.isConnected=e.isConnected),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),n.lastSeen=s,n.seenCount=(n.seenCount||1)+1}else o[t]={name:e.name||null,title:e.title||null,company:e.company||null,location:e.location||null,role:e.role||null,source:e.source||"scout",isConnected:e.isConnected||!1,discoveredAt:s,lastSeen:s,seenCount:1,jobIds:e.jobId?[e.jobId]:[]};try{Y(He,o)}catch(n){console.error(`[!] Failed to save discovered-people.json: ${n.message}`)}}function tt(){return B||(B=z(Ze)||{},B)}function qt(t,e){if(!t)return;Q();let o=tt(),s=new Date().toISOString().slice(0,10);if(o[t]){let n=o[t];e.name&&(n.name=e.name),e.about&&(n.about=e.about),e.size&&(n.size=e.size),e.industries&&(n.industries=e.industries),e.jobId&&(n.jobIds||(n.jobIds=[]),n.jobIds.includes(e.jobId)||n.jobIds.push(e.jobId)),e.recruiterUrl&&(n.recruiterUrls||(n.recruiterUrls=[]),n.recruiterUrls.includes(e.recruiterUrl)||n.recruiterUrls.push(e.recruiterUrl)),n.lastSeen=s,n.jobCount=n.jobIds?.length||0}else o[t]={name:e.name||null,about:e.about||null,size:e.size||null,industries:e.industries||null,discoveredAt:s,lastSeen:s,jobIds:e.jobId?[e.jobId]:[],recruiterUrls:e.recruiterUrl?[e.recruiterUrl]:[],jobCount:e.jobId?1:0};try{Y(Ze,o)}catch(n){console.error(`[!] Failed to save companies.json: ${n.message}`)}}function oe(){return E||(E=z(Xe)||{visits:[]},Array.isArray(E.visits)||(E.visits=[]),E)}function Vt(t,e={}){if(!t)return;Q();let o=oe();o.visits.push({date:new Date().toISOString(),profileUrl:t,name:e.name||null,source:e.source||"manual"});let s=Date.now()-90*24*60*60*1e3;o.visits=o.visits.filter(n=>new Date(n.date).getTime()>s);try{Y(Xe,o)}catch(n){console.error(`[!] Failed to save visit-log.json: ${n.message}`)}}function Bt(t){let e=oe();for(let o=e.visits.length-1;o>=0;o--)if(e.visits[o].profileUrl===t)return e.visits[o].date;return null}function Qt(){let t=he(),e=ye(),o=Object.values(t),s=Object.values(e),n={};for(let l of o)l.company&&(n[l.company]=(n[l.company]||0)+1);let r=Object.entries(n).sort((l,p)=>p[1]-l[1]).slice(0,5).map(([l,p])=>`${l} (${p})`),i={};for(let l of o)for(let p of l.techStack||[])i[p]=(i[p]||0)+1;let c=Object.entries(i).sort((l,p)=>p[1]-l[1]).slice(0,8).map(([l,p])=>`${l} (${p})`),a=oe(),f=new Date().toISOString().slice(0,10),u=a.visits.filter(l=>l.date.startsWith(f)).length,v=new Set(a.visits.map(l=>l.profileUrl)).size;return{totalJobs:o.length,totalRecruiters:s.length,topCompanies:r,topTech:c,totalVisited:v,todayVisited:u,lastScoutDate:o.length>0?o.sort((l,p)=>(p.scoutedAt||"").localeCompare(l.scoutedAt||""))[0]?.scoutedAt:null}}var Lt,kt,_,Ke,He,Xe,Ze,et,U,q,V,B,E,nt=De(()=>{Lt=Ft(import.meta.url),kt=y.dirname(y.dirname(Lt)),_=process.env.DATA_DIR?y.resolve(process.env.DATA_DIR,"market-research"):y.join(kt,"market-research"),Ke=y.join(_,"scouted-jobs.json"),He=y.join(_,"discovered-people.json"),Xe=y.join(_,"visit-log.json"),Ze=y.join(_,"companies.json"),et=y.join(_,"job-decisions.json");U=null;q=null;V=null;B=null;E=null});import{execFileSync as Ht}from"child_process";import"dotenv/config";import*as b from"fs";import*as w from"path";import{fileURLToPath as Dt}from"url";import"dotenv/config";import{createGraphClient as St,resolveToken as yt}from"@ilivemylife/graph-sdk";import{config as jt}from"dotenv";jt();var we=yt()||process.env.TOKEN;we||(console.error(`
5
5
  [FATAL] No iLiveMyLife token found.`),console.error(" The bot uses Lifebot AI to decide which jobs to apply for"),console.error(` and how to fill application forms. It cannot work without it.
6
6
  `),console.error(" Easiest way:"),console.error(" 1. npm install -g @ilivemylife/graph-sdk"),console.error(` 2. ilml login your@email.com yourpassword
7
7
  `),console.error(` Or add ILML_TOKEN=... to .env
8
- `),process.exit(1));var we=St({token:$e});function vt(t){if(!t||t<1e3)return`${t||0}ms`;let e=Math.round(t/1e3);if(e<60)return`${e}s`;let o=Math.floor(e/60),s=e%60;return s?`${o}m ${s}s`:`${o}m`}function bt({scriptName:t,mode:e,status:o,error:s,duration:n}){let r=o==="error"?"\u2717":o==="quota-reached"?"\u26A0":"\u2713",i=new Date().toISOString().slice(0,16).replace("T"," "),c=n?` ${vt(n)}`:"",a=o==="error"?`error${s?`: ${String(s).slice(0,80)}`:""}`:o==="quota-reached"?"daily quota reached":"done",f=e&&e!=="default"?` (${e})`:"";return`${r} ${t}${f} \u2014 ${a} \u2014 ${i}${c}`}async function Oe({scriptName:t,mode:e,status:o,summaryLines:s,error:n,duration:r}){let i=process.env.NODE_RUN_REPORTS;if(!i||!Array.isArray(s)||s.length===0)return;let a=`**${bt({scriptName:t,mode:e,status:o,error:n,duration:r})}**
8
+ `),process.exit(1));var Oe=St({token:we});function vt(t){if(!t||t<1e3)return`${t||0}ms`;let e=Math.round(t/1e3);if(e<60)return`${e}s`;let o=Math.floor(e/60),s=e%60;return s?`${o}m ${s}s`:`${o}m`}function bt({scriptName:t,mode:e,status:o,error:s,duration:n}){let r=o==="error"?"\u2717":o==="quota-reached"?"\u26A0":"\u2713",i=new Date().toISOString().slice(0,16).replace("T"," "),c=n?` ${vt(n)}`:"",a=o==="error"?`error${s?`: ${String(s).slice(0,80)}`:""}`:o==="quota-reached"?"daily quota reached":"done",f=e&&e!=="default"?` (${e})`:"";return`${r} ${t}${f} \u2014 ${a} \u2014 ${i}${c}`}async function $e({scriptName:t,mode:e,status:o,summaryLines:s,error:n,duration:r}){let i=process.env.NODE_RUN_REPORTS;if(!i||!Array.isArray(s)||s.length===0)return;let a=`**${bt({scriptName:t,mode:e,status:o,error:n,duration:r})}**
9
9
 
10
10
  ${s.join(`
11
- `)}`;try{await we.addMessage(i,a)}catch(f){console.error(`[runReport] Failed to post end-of-session message: ${f.message}`)}}var It=Dt(import.meta.url),$t=$.dirname($.dirname(It)),re=process.env.DATA_DIR?$.resolve(process.env.DATA_DIR,"collected-profiles"):$.join($t,"collected-profiles"),ie=$.join(re,"run-log.json");function wt(t,e){let o=JSON.stringify(e,null,2),s=t+".tmp";b.writeFileSync(s,o);for(let n=0;n<3;n++)try{b.renameSync(s,t);return}catch(r){if(n<2&&(r.code==="EPERM"||r.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw r}}function Re(){try{if(!b.existsSync(ie))return{runs:[]};let t=JSON.parse(b.readFileSync(ie,"utf-8"));return!t.runs||!Array.isArray(t.runs)?{runs:[]}:t}catch{return{runs:[]}}}function Te(t){b.existsSync(re)||b.mkdirSync(re,{recursive:!0});try{wt(ie,t)}catch(e){console.error(`[!] Failed to save run-log.json: ${e.message}`)}}function Ce(t,e="default"){let o=Re();for(let i of o.runs)i.status==="running"&&(i.status="interrupted",i.result="interrupted",i.timestamp&&(i.duration=Date.now()-new Date(i.timestamp).getTime()));let s=new Date,n={timestamp:s.toISOString(),script:t,mode:e,status:"running",result:null,duration:null,stats:null,error:null};o.runs.push(n);let r=Date.now()-30*24*60*60*1e3;return o.runs=o.runs.filter(i=>new Date(i.timestamp).getTime()>r),Te(o),{script:t,mode:e,startTime:s.getTime(),runIndex:o.runs.length-1}}function Ae(t,e,o=null,s=null){if(!t)return;let n=null;try{let i=Re(),c=i.runs[t.runIndex];if(c&&c.status==="running"&&c.script===t.script)c.status=e,c.result=e,c.duration=Date.now()-t.startTime,c.stats=o,c.error=s,n=c.duration;else{let a=i.runs.find(f=>f.script===t.script&&f.status==="running"&&f.timestamp===new Date(t.startTime).toISOString());a&&(a.status=e,a.result=e,a.duration=Date.now()-t.startTime,a.stats=o,a.error=s,n=a.duration)}Te(i)}catch(i){console.error(`[runLog] Failed to end run: ${i.message}`)}let r=o&&Array.isArray(o.summaryLines)?o.summaryLines:null;if(r&&r.length>0&&process.env.NODE_RUN_REPORTS){let i=e==="error"?"error":o&&o.dailyLimitHit?"quota-reached":"done";Oe({scriptName:t.script,mode:t.mode,status:i,summaryLines:r,error:s,duration:n??Date.now()-t.startTime}).catch(c=>console.error(`[runLog] postRunReport failed: ${c.message}`))}}ge();import"dotenv/config";import*as j from"fs";import*as g from"path";import{fileURLToPath as Yt}from"url";var zt=Yt(import.meta.url),Wt=g.dirname(zt),it=g.dirname(g.dirname(Wt)),ne=process.env.DATA_DIR?g.resolve(process.env.DATA_DIR,"collected-profiles"):g.join(it,"collected-profiles"),se=process.env.DATA_DIR?g.resolve(process.env.DATA_DIR,"market-research"):g.join(it,"market-research"),je=1,Gt=[{version:1,file:"./v001-normalize-jobs-and-questions.mjs"}];function ct(t){return g.join(t,".schema-version")}function ve(t){let e=ct(t);if(!j.existsSync(e))return{version:0,migrations:[]};try{return JSON.parse(j.readFileSync(e,"utf-8"))}catch{return{version:0,migrations:[]}}}function Kt(t,e){j.writeFileSync(ct(t),JSON.stringify(e,null,2))}function st(t,e){if(!j.existsSync(t))return;let o=`.pre-v${String(e).padStart(3,"0")}.backup`,s=j.readdirSync(t).filter(n=>n.endsWith(".json")&&!n.includes(".backup"));for(let n of s){let r=g.join(t,n),i=g.join(t,n+o);try{j.copyFileSync(r,i)}catch(c){console.error(` [!] Failed to backup ${n}: ${c.message}`)}}s.length>0&&console.log(` Backed up ${s.length} files in ${g.basename(t)}/ (${o})`)}var rt=!1;async function lt(){if(rt)return;rt=!0;let t=ve(ne),e=ve(se),o=Math.min(t.version,e.version);if(o>=je)return;console.log(`
11
+ `)}`;try{await Oe.addMessage(i,a)}catch(f){console.error(`[runReport] Failed to post end-of-session message: ${f.message}`)}}var It=Dt(import.meta.url),wt=w.dirname(w.dirname(It)),re=process.env.DATA_DIR?w.resolve(process.env.DATA_DIR,"collected-profiles"):w.join(wt,"collected-profiles"),ie=w.join(re,"run-log.json");function Ot(t,e){let o=JSON.stringify(e,null,2),s=t+".tmp";b.writeFileSync(s,o);for(let n=0;n<3;n++)try{b.renameSync(s,t);return}catch(r){if(n<2&&(r.code==="EPERM"||r.code==="EBUSY")){let i=Date.now();for(;Date.now()-i<200;);continue}throw r}}function Re(){try{if(!b.existsSync(ie))return{runs:[]};let t=JSON.parse(b.readFileSync(ie,"utf-8"));return!t.runs||!Array.isArray(t.runs)?{runs:[]}:t}catch{return{runs:[]}}}function Te(t){b.existsSync(re)||b.mkdirSync(re,{recursive:!0});try{Ot(ie,t)}catch(e){console.error(`[!] Failed to save run-log.json: ${e.message}`)}}function Ce(t,e="default"){let o=Re();for(let i of o.runs)i.status==="running"&&(i.status="interrupted",i.result="interrupted",i.timestamp&&(i.duration=Date.now()-new Date(i.timestamp).getTime()));let s=new Date,n={timestamp:s.toISOString(),script:t,mode:e,status:"running",result:null,duration:null,stats:null,error:null};o.runs.push(n);let r=Date.now()-30*24*60*60*1e3;return o.runs=o.runs.filter(i=>new Date(i.timestamp).getTime()>r),Te(o),{script:t,mode:e,startTime:s.getTime(),runIndex:o.runs.length-1}}function Ae(t,e,o=null,s=null){if(!t)return;let n=null;try{let i=Re(),c=i.runs[t.runIndex];if(c&&c.status==="running"&&c.script===t.script)c.status=e,c.result=e,c.duration=Date.now()-t.startTime,c.stats=o,c.error=s,n=c.duration;else{let a=i.runs.find(f=>f.script===t.script&&f.status==="running"&&f.timestamp===new Date(t.startTime).toISOString());a&&(a.status=e,a.result=e,a.duration=Date.now()-t.startTime,a.stats=o,a.error=s,n=a.duration)}Te(i)}catch(i){console.error(`[runLog] Failed to end run: ${i.message}`)}let r=o&&Array.isArray(o.summaryLines)?o.summaryLines:null;if(r&&r.length>0&&process.env.NODE_RUN_REPORTS){let i=e==="error"?"error":o&&o.dailyLimitHit?"quota-reached":"done";$e({scriptName:t.script,mode:t.mode,status:i,summaryLines:r,error:s,duration:n??Date.now()-t.startTime}).catch(c=>console.error(`[runLog] postRunReport failed: ${c.message}`))}}ge();import"dotenv/config";import*as j from"fs";import*as g from"path";import{fileURLToPath as Yt}from"url";var zt=Yt(import.meta.url),Wt=g.dirname(zt),it=g.dirname(g.dirname(Wt)),ne=process.env.DATA_DIR?g.resolve(process.env.DATA_DIR,"collected-profiles"):g.join(it,"collected-profiles"),se=process.env.DATA_DIR?g.resolve(process.env.DATA_DIR,"market-research"):g.join(it,"market-research"),je=1,Gt=[{version:1,file:"./v001-normalize-jobs-and-questions.mjs"}];function ct(t){return g.join(t,".schema-version")}function ve(t){let e=ct(t);if(!j.existsSync(e))return{version:0,migrations:[]};try{return JSON.parse(j.readFileSync(e,"utf-8"))}catch{return{version:0,migrations:[]}}}function Kt(t,e){j.writeFileSync(ct(t),JSON.stringify(e,null,2))}function st(t,e){if(!j.existsSync(t))return;let o=`.pre-v${String(e).padStart(3,"0")}.backup`,s=j.readdirSync(t).filter(n=>n.endsWith(".json")&&!n.includes(".backup"));for(let n of s){let r=g.join(t,n),i=g.join(t,n+o);try{j.copyFileSync(r,i)}catch(c){console.error(` [!] Failed to backup ${n}: ${c.message}`)}}s.length>0&&console.log(` Backed up ${s.length} files in ${g.basename(t)}/ (${o})`)}var rt=!1;async function lt(){if(rt)return;rt=!0;let t=ve(ne),e=ve(se),o=Math.min(t.version,e.version);if(o>=je)return;console.log(`
12
12
  \u{1F4E6} Schema migration: v${o} \u2192 v${je}`);let s=Gt.filter(n=>n.version>o);for(let n of s){console.log(`
13
13
  Running migration v${String(n.version).padStart(3,"0")}...`),st(ne,n.version),st(se,n.version);let r=await import(n.file);try{await r.up(ne,se)}catch(a){console.error(`
14
14
  [FATAL] Migration v${n.version} failed: ${a.message}`),console.error(` Backups are in collected-profiles/ and market-research/ (.pre-v${String(n.version).padStart(3,"0")}.backup)`),console.error(` Fix the issue and restart.
15
15
  `),process.exit(1)}let i=new Date().toISOString(),c={version:n.version,name:r.NAME||`v${String(n.version).padStart(3,"0")}`,appliedAt:i};for(let a of[ne,se]){if(!j.existsSync(a))continue;let f=ve(a);f.version=n.version,f.migratedAt=i,f.migrations.push(c),Kt(a,f)}console.log(` \u2713 Migration v${String(n.version).padStart(3,"0")} complete`)}try{let{resetCaches:n}=await Promise.resolve().then(()=>(ge(),Ge));n()}catch{}try{let{resetCaches:n}=await Promise.resolve().then(()=>(nt(),ot));n()}catch{}console.log(`
16
16
  \u2713 Schema is now at v${je}
17
- `)}await lt();var W=process.argv.slice(2),be=new Set((W.find(t=>t.startsWith("--skip="))?.split("=")[1]||"").split(",").filter(Boolean)),at=new Set((W.find(t=>t.startsWith("--only="))?.split("=")[1]||"").split(",").filter(Boolean)),ft=W.includes("--dry-run"),dt=W.includes("--jobs"),mt=W.includes("--comms"),ut=["apply-queue","apply","funnel","scout","visit"],pt=["sync","today"],gt=dt?ut:mt?pt:[...ut,...pt];function O(t){return at.size>0?at.has(t):!be.has(t)&&gt.includes(t)}function N(t,e,o=[],{optional:s=!1}={}){if(console.log(`
17
+ `)}await lt();var W=process.argv.slice(2),be=new Set((W.find(t=>t.startsWith("--skip="))?.split("=")[1]||"").split(",").filter(Boolean)),at=new Set((W.find(t=>t.startsWith("--only="))?.split("=")[1]||"").split(",").filter(Boolean)),ft=W.includes("--dry-run"),dt=W.includes("--jobs"),mt=W.includes("--comms"),ut=["apply-queue","apply","funnel","scout","visit"],pt=["sync","today"],gt=dt?ut:mt?pt:[...ut,...pt];function $(t){return at.size>0?at.has(t):!be.has(t)&&gt.includes(t)}function N(t,e,o=[],{optional:s=!1}={}){if(console.log(`
18
18
  ${"\u2550".repeat(50)}`),console.log(` STEP: ${t}`),console.log("\u2550".repeat(50)),ft)return console.log(` [DRY RUN] Would run: node ${e} ${o.join(" ")}`),!0;try{return Ht("node",[e,...o],{stdio:"inherit",timeout:18e6}),console.log(` \u2713 ${t} completed`),!0}catch(n){return s?(console.log(` \u26A0 ${t} failed (optional): ${n.message?.slice(0,80)}`),!1):(console.error(` \u2717 ${t} failed: ${n.message?.slice(0,80)}`),!1)}}async function Xt(){let t=dt?"jobs":mt?"comms":"full";console.log(`
19
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`),console.log(` DAILY PIPELINE (${t})`),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");let e=gt.filter(O);console.log(` Steps: ${e.join(" \u2192 ")}`),be.size>0&&console.log(` Skipping: ${[...be].join(", ")}`),ft&&console.log(" [DRY RUN MODE]");let o=Ce("daily",t),s={};if(O("apply-queue")&&(s["apply-queue"]=N("Apply Queue (scored jobs)","applyQueue.mjs",["--max=50","--min-score=50"],{optional:!0})),O("apply")){let r=te();s.apply=N("Apply from Search","run.mjs",["--no-wait"],{optional:!0})}if(O("funnel")&&!O("apply")){let r=ee();r.allowed?s.funnel=N("Connection Funnel","funnelRunner.mjs",["--max=20"],{optional:!0}):(console.log(`
20
- \u26A0 Funnel skipped: ${r.reason}`),s.funnel="skipped_quota")}O("scout")&&(s.scout=N("Scout Jobs for Tomorrow","scout.mjs",["--max=300","--verbose"],{optional:!0})),O("sync")&&(s.sync=N("Sync Inbox","syncAll.mjs")),O("today")&&(s.today=N("Daily Report","syncAll.mjs",["--today"])),console.log(`
19
+ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`),console.log(` DAILY PIPELINE (${t})`),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");let e=gt.filter($);console.log(` Steps: ${e.join(" \u2192 ")}`),be.size>0&&console.log(` Skipping: ${[...be].join(", ")}`),ft&&console.log(" [DRY RUN MODE]");let o=Ce("daily",t),s={};if($("apply-queue")&&(s["apply-queue"]=N("Apply Queue (scored jobs)","applyQueue.mjs",["--max=50","--min-score=50"],{optional:!0})),$("apply")){let r=te();s.apply=N("Apply from Search","run.mjs",["--no-wait"],{optional:!0})}if($("funnel")&&!$("apply")){let r=ee();r.allowed?s.funnel=N("Connection Funnel","funnelRunner.mjs",["--max=20"],{optional:!0}):(console.log(`
20
+ \u26A0 Funnel skipped: ${r.reason}`),s.funnel="skipped_quota")}$("scout")&&(s.scout=N("Scout Jobs for Tomorrow","scout.mjs",["--max=300","--verbose"],{optional:!0})),$("sync")&&(s.sync=N("Sync Inbox","syncAll.mjs")),$("today")&&(s.today=N("Daily Report","syncAll.mjs",["--today"])),console.log(`
21
21
  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`),console.log(" PIPELINE COMPLETE"),console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");for(let[r,i]of Object.entries(s))console.log(` ${i===!0?"\u2713":i===!1?"\u2717":"\u26A0"} ${r}: ${i===!0?"success":i===!1?"failed":i}`);console.log(`\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
22
22
  `);let n=Object.values(s).some(r=>r===!1);Ae(o,n?"partial":"success",s)}Xt().catch(t=>{console.error("Daily pipeline failed:",t),process.exit(1)});