UNPKG

pastoralist

Version:

A tool to watch over node module resolutions and overrides

84 lines 111 kB
import{createRequire as es}from"node:module";var ts=es(import.meta.url);var rr=[0,128,0],rs=[210,180,140],ns=(e,t,r)=>[Math.round(e[0]+(t[0]-e[0])*r),Math.round(e[1]+(t[1]-e[1])*r),Math.round(e[2]+(t[2]-e[2])*r)],st=(e)=>{let t=e.split(""),r=t.length;if(r===0)return"";if(r===1)return`${fe(...rr)}${e}${v.RESET}`;return t.map((s,i)=>{if(s===" ")return s;let o=i/(r-1),[c,a,u]=ns(rr,rs,o);return`${fe(c,a,u)}${s}`}).join("")+v.RESET};var _=process.env.DEBUG==="true"||!1,it="\uD83E\uDDD1‍\uD83C\uDF3E",ss="\uD83D\uDC11";var is="•",os="   ",tl=`${os}${is} `;var ot="Pastoralist:",v={RESET:"\x1B[0m",BOLD:"\x1B[1m",CLEAR_LINE:"\r\x1B[K",HIDE_CURSOR:"\x1B[?25l",SHOW_CURSOR:"\x1B[?25h",FG_GREEN:"\x1B[32m",FG_RED:"\x1B[31m",FG_YELLOW:"\x1B[33m",FG_GOLD:"\x1B[93m",FG_ORANGE:"\x1B[38;5;208m",FG_CYAN:"\x1B[36m",FG_GRAY:"\x1B[90m",FG_WHITE:"\x1B[97m"},fe=(e,t,r)=>`\x1B[38;2;${e};${t};${r}m`,cs=v.BOLD,as=v.FG_GOLD,us=v.RESET,rl=`${it} ${st("Pastoralist")} is scanning overrides...`,nl=`${cs}${as}The herd is safe!${us} ${ss}`,nr="rc-file-suggestion",sr="Your pastoralist config is getting large (>10 lines). Consider moving it to a .pastoralistrc file using: pastoralist init --useRcConfigFile",$e={MOCK_MODE:"PASTORALIST_MOCK_SECURITY",FORCE_VULNERABLE:"MOCK_FORCE_VULNERABLE",MOCK_FILE:"MOCK_ALERTS_FILE",GITHUB_TOKEN:"GITHUB_TOKEN"};var w=(e)=>`${v.FG_GREEN}${e}${v.RESET}`,V=(e)=>`${v.FG_RED}${e}${v.RESET}`,k=(e)=>`${v.FG_YELLOW}${e}${v.RESET}`,Ne=(e)=>`${v.FG_GOLD}${e}${v.RESET}`;var b=(e)=>`${v.FG_CYAN}${e}${v.RESET}`,O=(e)=>`${v.FG_GRAY}${e}${v.RESET}`;var q=(e,t)=>{return`\x1B]8;;${e}\x07${t||e}\x1B]8;;\x07`};var ir=20,or=10;var cr=3;var ct=new RegExp(String.fromCharCode(27)+"\\[[0-9;]*m","g"),ar=/\p{Emoji_Presentation}/u,me=()=>{return process.stdout.columns||80},B=(e)=>{let t=e.replace(ct,"");if(typeof Intl<"u"&&Intl.Segmenter){let s=new Intl.Segmenter("en",{granularity:"grapheme"}),i=Array.from(s.segment(t)),o=i.filter((c)=>ar.test(c.segment)).length;return i.length+o}let r=Array.from(t),n=r.filter((s)=>ar.test(s)).length;return r.length+n},at=(e,t,r="left")=>{let n=B(e),s=Math.max(0,t-n),i=" ".repeat(s);return r==="left"?e+i:i+e},ls=(e,t)=>{if(B(e)<=t)return e;if(t<=3)return".".repeat(t);ct.lastIndex=0;let n=ct,s="",i=0,o=0,c,a=!1;while((c=n.exec(e))!==null){let p=e.substring(o,c.index),d=t-3-i;if(p.length<=d)if(s+=p+c[0],i+=p.length,!c[0].includes("[0m")&&!c[0].includes("[m"))a=!0;else a=!1;else{if(s+=p.substring(0,d),a)return s+"\x1B[0m...";return s+"..."}o=n.lastIndex}let u=e.substring(o),l=t-3-i;if(u.length<=l)return s+u;if(s+=u.substring(0,l),a)return s+"\x1B[0m...";return s+"..."};var ur=(e,t=3)=>{return" ".repeat(t)+e};var F={topLeft:"┌",topRight:"┐",bottomLeft:"└",bottomRight:"┘",horizontal:"─",vertical:"│"},_e=(e,t={})=>{let r=t.width??me()-2,n=t.padding??1,s=r-2-n*2,i=" ".repeat(n),o=F.horizontal.repeat(r-2),c=t.title?`${F.topLeft}${F.horizontal} ${t.title} ${F.horizontal.repeat(Math.max(0,r-5-B(t.title)))}${F.topRight}`:`${F.topLeft}${o}${F.topRight}`,a=`${F.bottomLeft}${o}${F.bottomRight}`,u=e.map((l)=>{let p=ls(l,s),d=at(p,s);return`${F.vertical}${i}${d}${i}${F.vertical}`});return[c,...u,a]};var ps={green:w,yellow:k,red:V,cyan:b,gray:O},lr=(e,t)=>{let r=Math.max(0,t-B(e));return e+" ".repeat(r)},ds=(e,t)=>{let r=Math.max(0,t-B(e));return" ".repeat(r)+e},hs=(e,t)=>`+-${"-".repeat(e)}-+-${"-".repeat(t)}-+`,gs=(e,t,r,n,s)=>{let i=ds(t,n),o=s?ps[s](i):i;return`| ${lr(e,r)} | ${o} |`},fs=(e,t,r)=>{let n=e.reduce((i,o)=>Math.max(i,B(o.label)),0),s=e.reduce((i,o)=>Math.max(i,B(String(o.value))),0);return{labelWidth:Math.max(t,n),valueWidth:Math.max(r,s)}},ms=(e,t,r)=>{let n=t+r+cr;return`| ${lr(e,n)} |`},ys=(e,t={})=>{let{title:r,minLabelWidth:n=ir,minValueWidth:s=or}=t,{labelWidth:i,valueWidth:o}=fs(e,n,s),c=hs(i,o),a=r?[c,ms(r,i,o),c]:[c],u=e.map((l)=>gs(l.label,String(l.value),i,o,l.color));return a.concat(u,[c]).join(`
`)};var pr=(e=process.stdout)=>({write:(t)=>e.write(t),writeLine:(t)=>e.write(`${t}
`),clearLine:()=>e.write(v.CLEAR_LINE),hideCursor:()=>e.write(v.HIDE_CURSOR),showCursor:()=>e.write(v.SHOW_CURSOR)}),P=pr();var bs="▪▫▪ Pastoralist",y={success:w("●"),error:V("■"),warning:k("▲"),info:b("◆"),arrow:b("▸"),bullet:O("▫"),check:w("●"),CHECK:w("✓"),SHIELD:b("⬢"),step:b("▶"),section:b("►"),search:b("◇"),edit:k("◆"),folder:b("▸"),skip:O("○"),help:b("◇"),hint:k("\uD83D\uDCA1")},Ss={success:y.success,error:y.error,warning:y.warning,info:y.info,step:y.step,save:y.arrow,next:y.bullet},vs={config:`${y.step} Step 1: Configuration Location`,workspace:`${y.step} Step 2: Workspace Configuration`,security:`${y.step} Step 3: Security Configuration`};var dr=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];var ut=(e,t,r,n=P)=>{let s=e[t];n.clearLine(),n.write(`${s} ${r}`)},te=(e)=>{let t=e.interval;if(t!==null)clearInterval(t);return Object.assign({},e,{interval:null,isSpinning:!1})},lt=(e,t)=>{return Object.assign({},e,{text:t})},pt=(e)=>{let t=(e.frameIndex+1)%dr.length;return Object.assign({},e,{frameIndex:t})},dt=(e,t=P)=>{let r=setInterval(()=>{ut(dr,e.frameIndex,e.text,t),Object.assign(e,pt(e))},80);return Object.assign({},e,{interval:r,isSpinning:!0})},oe=(e,t,r=P)=>{r.clearLine(),r.writeLine(`${e} ${t}`)},ht=(e,t=P)=>{if(e.isSpinning)return D(e,t);t.hideCursor();let n=dt(e,t);return Object.assign(e,n),D(e,t)},gt=(e,t=P)=>{if(!e.isSpinning)return D(e,t);let n=te(e);return Object.assign(e,n),t.clearLine(),t.showCursor(),D(e,t)},ft=(e,t,r=P)=>{let n=te(e);Object.assign(e,n);let s=t||e.text;return oe(y.success,s,r),r.showCursor(),D(e,r)},mt=(e,t,r=P)=>{let n=te(e);Object.assign(e,n);let s=t||e.text;return oe(y.error,s,r),r.showCursor(),D(e,r)},yt=(e,t,r=P)=>{let n=te(e);Object.assign(e,n);let s=t||e.text;return oe(y.info,s,r),r.showCursor(),D(e,r)},bt=(e,t,r=P)=>{let n=te(e);Object.assign(e,n);let s=t||e.text;return oe(y.warning,s,r),r.showCursor(),D(e,r)},As=(e,t,r=P)=>{let n=lt(e,t);return Object.assign(e,n),D(e,r)},D=(e,t=P)=>{return{start:()=>ht(e,t),stop:()=>gt(e,t),succeed:(r)=>ft(e,r,t),fail:(r)=>mt(e,r,t),info:(r)=>yt(e,r,t),warn:(r)=>bt(e,r,t),update:(r)=>As(e,r,t)}},ks=(e,t=P)=>{return D({text:e,isSpinning:!1,frameIndex:0,interval:null},t)},hr=ks;var Os=[255,215,0],Ps=[255,255,255],ws=0.25,Ts=(e,t,r)=>[Math.round(e[0]+(t[0]-e[0])*r),Math.round(e[1]+(t[1]-e[1])*r),Math.round(e[2]+(t[2]-e[2])*r)],Ve=(e,t)=>{let r=e.split(""),n=r.length;if(n===0)return"";let i=r.map((o,c)=>{if(o===" ")return o;let u=c/n,l=Math.abs(u-t),p=Math.min(l,1-l),d=Math.max(0,1-p/ws),[h,g,f]=Ts(Os,Ps,d);return`${fe(h,g,f)}${o}`});return v.BOLD+i.join("")+v.RESET},Rs=(e)=>{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)},De=(e,t=50,r=P,n="",s="",i=process.stdout.isTTY??!1)=>{let o=i,c=20,a=2,u=Array.from({length:20},(l,p)=>p/20);if(o)Array.from({length:2}).forEach(()=>u.forEach((l)=>{r.clearLine(),r.write(`${n}${Ve(e,l)}${s}`),Rs(t)})),r.clearLine();r.writeLine(`${n}${Ve(e,0)}${s}`)};var{BOLD:Cs,RESET:Ue,FG_RED:vt,FG_WHITE:fr}=v,gr=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],Ge={pipe:"│",branch:"├──",last:"└──",indent:"   "},Es=(e)=>{let t=e;return{get:()=>t,set:(r)=>{t=r}}},xs=()=>({phase:"idle",ancestors:[],spinner:{active:!1,frame:0,text:"",interval:null},progress:{current:0,total:0}}),At=(e)=>e.map((t)=>t?`${Ge.pipe}${Ge.indent}`:"    ").join(""),mr=(e)=>e?Ge.last:Ge.branch,Is=(...e)=>e.filter(Boolean).join(" "),Ls=(e,t,...r)=>Is(At(e)+mr(t),...r),$s=(e,t)=>({line:(r,...n)=>{let{ancestors:s}=t.get();e.writeLine(Ls(s,r,...n))},open:()=>{let r=t.get();t.set({...r,ancestors:[...r.ancestors,!0]})},close:()=>{let r=t.get();t.set({...r,ancestors:r.ancestors.slice(0,-1)})},nested:(r,n)=>{let s=t.get();t.set({...s,ancestors:[...s.ancestors,!r]}),n();let i=t.get();t.set({...i,ancestors:i.ancestors.slice(0,-1)})}}),Ns=(e,t)=>{let r=()=>{let s=t.get(),i=gr[s.spinner.frame],o=At(s.ancestors);e.clearLine(),e.write(`${o}${i} ${s.spinner.text}`)},n=()=>{let s=t.get(),i=(s.spinner.frame+1)%gr.length;t.set({...s,spinner:{...s.spinner,frame:i}})};return{start:(s)=>{e.hideCursor();let i=t.get(),o=setInterval(()=>{r(),n()},80);t.set({...i,spinner:{...i.spinner,active:!0,text:s,interval:o}})},stop:()=>{let s=t.get(),i=s.spinner.interval;if(i!==null)clearInterval(i);t.set({...s,spinner:{...s.spinner,active:!1,interval:null}}),e.clearLine(),e.showCursor()},isActive:()=>t.get().spinner.active,render:r}},_s=(e)=>(t)=>{return e.stop(),t()},Vs=(e)=>(t,r,n)=>{De(t,50,e,r,n)},yr=(e)=>{if(!e||e.length===0)return;return`CVE: ${e.join(", ")}`},Ds=(e,t)=>{if(!(e&&t))return"No fix available";return`Fix: upgrade to ${t}`},Us=(e)=>{let t=yr(e.cves),r=Ds(e.fixAvailable,e.patchedVersion);return[e.title,t,r,e.url].filter((n)=>n!==void 0)},Gs=(e)=>{if(e)return y.warning;return y.error},Fs=(e)=>{if(!(e&&e.length>0))return;return`Patches: ${e.join(", ")}`},Ms=(e)=>{let r=Object.keys(e??{}).length;if(r===0)return;return`Used by: ${r} package${r===1?"":"s"}`},js=(e)=>{if(!e)return;if(typeof e==="object"&&e.reason)return`Kept: ${e.reason}`;return"Kept by user"},Ks=(e)=>{if(!e)return;return`Potentially fixed in ${e}, maybe removable`},Bs=(e)=>{let t=yr(e.cves),r=Fs(e.patches),n=Ms(e.dependents),s=js(e.keep),i=Ks(e.potentiallyFixedIn);return[e.reason,t,r,n,s,i].filter((o)=>o!==void 0)},Hs=(e,t)=>{if(t)return y.info;if(e)return y.warning;return y.success},Ws=(e)=>{let t=`${e.fromVersion} → ${e.toVersion}`,r=e.cves&&e.cves.length>0?`Blocks ${e.cves.join(", ")}`:void 0;return[t,r,e.reason].filter((n)=>n!==void 0)},St=(e,t)=>{let r=t.length-1;t.forEach((n,s)=>e.line(s===r,n))},Ys=(e)=>{return e%2===0?vt:fr},zs=(e)=>{return Array.from({length:e},(n,s)=>s).map((n)=>{return`${Ys(n)}-${Ue}`}).join("")},qs=(e)=>{let r=B(e)+4,n=zs(r+2),s=" ".repeat(2)+e+" ".repeat(2),i=`${vt}|${Ue}${Cs}${fr}${s}${Ue}${vt}|${Ue}`;return[n,i,n]},Js={write:()=>{},writeLine:()=>{},clearLine:()=>{},hideCursor:()=>{},showCursor:()=>{}},Qs=(e={})=>{let t=e.quiet?Js:e.out||P,r=Es(xs()),n=$s(t,r),s=Ns(t,r),i=_s(s),o=Vs(t),c={banner:()=>{return i(()=>{let a=["",`${it} ${w("Pastoralist")}`,""].join(`
`);t.writeLine(a)}),c},startPhase:(a,u,l=!1)=>{return i(()=>{let p=r.get();r.set({...p,phase:a}),n.line(l,u);let d=r.get();r.set({...d,ancestors:[...d.ancestors,!l]})}),c},progress:(a,u,l)=>{let p=r.get(),d=`${l} (${a}/${u})`;if(r.set({...p,spinner:{...p.spinner,text:d},progress:{current:a,total:u}}),a===1&&!s.isActive())s.start(d);return c},item:(a,u=!1)=>{return i(()=>n.line(u,y.success,a)),c},vulnerability:(a,u=!1)=>{return i(()=>{let l=Gs(a.fixAvailable),d=`[${a.severity.toUpperCase()}] ${a.packageName}@${a.currentVersion}`,h=Us(a);n.line(u,l,d),n.nested(u,()=>St(n,h))}),c},override:(a,u=!1)=>{return i(()=>{let l=Hs(a.isSecurityFix,a.keep),p=`${a.packageName}@${a.version}`,d=Bs(a);if(n.line(u,l,p),!(d.length>0))return;n.nested(u,()=>St(n,d))}),c},securityFix:(a,u=!1)=>{return i(()=>{let l=`${a.packageName}@${a.toVersion}`,p=Ws(a);if(n.line(u,y.success,l),!(p.length>0))return;n.nested(u,()=>St(n,p))}),c},removedOverride:(a,u=!1)=>{return i(()=>{let l=`${a.packageName}@${a.version}`;n.line(u,y.info,l),n.nested(u,()=>n.line(!0,a.reason))}),c},endPhase:(a)=>{return i(()=>{if(a)n.line(!0,y.success,a);n.close()}),c},summary:(a,u)=>{return i(()=>{let l=Object.keys(a),p=l.length>0,d=u&&u.length>0;if(p)n.line(!d,"Overrides"),n.nested(!d,()=>{l.forEach((h,g)=>{let f=g===l.length-1;n.line(f,`${h}: ${a[h]}`)})});if(d)n.line(!0,"Changes"),n.nested(!0,()=>{u.forEach((h,g)=>{let f=g===u.length-1;n.line(f,h)})})}),c},executiveSummary:(a)=>{return i(()=>{let u=a.vulnerabilitiesFixed&&a.vulnerabilitiesFixed>0,l=a.staleOverridesRemoved&&a.staleOverridesRemoved>0,p=a.packagesProtected&&a.packagesProtected>0;if(!(u||l||p))return;if(u){let h=a.vulnerabilitiesFixed===1?"y":"ies";t.writeLine(`${y.CHECK} ${a.vulnerabilitiesFixed} vulnerabilit${h} fixed`)}if(l){let h=a.staleOverridesRemoved===1?"":"s";t.writeLine(`${y.CHECK} ${a.staleOverridesRemoved} stale override${h} removed`)}if(p){let h=a.packagesProtected===1?"":"s";t.writeLine(`${y.SHIELD} ${a.packagesProtected} package${h} protected`)}}),c},compactSummary:(a)=>{return i(()=>{let u=O(" . "),l=[`${y.error} ${a.severityCritical} crit`,`${y.warning} ${a.severityHigh} high`,`${y.info} ${a.severityMedium} med`,`${y.check} ${a.severityLow} low`,`${y.arrow} ${a.overridesTracked} tracked`,`${y.skip} ${a.overridesRemoved} removed`,`${a.packagesScanned} scanned`];t.writeLine(l.join(u))}),c},complete:(a,u="")=>{return i(()=>{let l=r.get();r.set({...l,phase:"complete",ancestors:[]});let p=At([])+mr(!0);o(a,p,u)}),c},notice:(a)=>{return i(()=>{let u=qs(a);t.writeLine(""),u.forEach((l)=>t.writeLine(l)),t.writeLine("")}),c},stop:()=>{return s.stop(),c}};return c};import{existsSync as br,mkdirSync as kt,readFileSync as Sr,writeFileSync as Zs,renameSync as Xs,readdirSync as ei,statSync as ti,unlinkSync as ri}from"fs";import{join as J,dirname as ni,basename as si}from"path";import{homedir as ii,tmpdir as oi}from"os";import{createHash as ci}from"crypto";var Ot=1,M={REGISTRY:"registry",OSV:"osv",TREE:"tree",ALERTS:"alerts",DECISIONS:"decisions"},U={REGISTRY:86400000,OSV:2592000000,TREE:2592000000,ALERTS:21600000,DECISIONS:21600000},j={REGISTRY:1,OSV:1,TREE:1,ALERTS:1,DECISIONS:1},ai=["bun.lock","bun.lockb","yarn.lock","pnpm-lock.yaml","package-lock.json"];var ce=(e=process.cwd())=>{let t=ai.find((r)=>br(J(e,r)));if(!t)return"no-lockfile";try{let r=Sr(J(e,t),"utf8");return ci("sha256").update(r).digest("hex").slice(0,16)}catch{return"no-lockfile"}},R=(e={})=>{let t=e.cacheDir;if(t)return t;let r=process.env.PASTORALIST_CACHE_DIR;if(r)return r;let n=e.root??process.cwd(),s=J(n,"node_modules",".cache","pastoralist");try{return kt(s,{recursive:!0}),s}catch{let i=[J(ii(),".pastoralist","cache"),J(oi(),"pastoralist","cache")];for(let o of i)try{return kt(o,{recursive:!0}),o}catch{}throw Error("Unable to create a writable cache directory")}},vr=(e,t={})=>{try{let r=t.keep??5,n=t.maxAgeMs??604800000,s=Date.now();ei(e).filter((o)=>o.includes(".backup-")).map((o)=>{let c=J(e,o),a=ti(c).mtimeMs;return{path:c,mtime:a}}).sort((o,c)=>c.mtime-o.mtime).forEach((o,c)=>{let a=s-o.mtime>n,u=c>=r;if(a||u)ri(o.path)})}catch{}};class E{filePath;ttl;version;maxEntries;enabled;data=null;constructor(e,t){if(this.filePath=J(t.dir,`${e}.json`),this.ttl=t.ttl,this.version=t.version,this.maxEntries=t.maxEntries??1000,this.enabled=t.enabled??!0,this.enabled)kt(t.dir,{recursive:!0})}empty(){return{schema:Ot,version:this.version,entries:{}}}load(){if(this.data)return this.data;if(!br(this.filePath))return this.data=this.empty(),this.data;try{let e=Sr(this.filePath,"utf8"),t=JSON.parse(e),r=t?.schema===Ot,n=t?.version===this.version;if(!r||!n)return this.data=this.empty(),this.data;return this.data=t,this.data}catch{return this.data=this.empty(),this.data}}flush(e){let t=ni(this.filePath),r=Math.random().toString(36).slice(2),n=`${si(this.filePath)}.tmp-${process.pid}-${r}`,s=J(t,n);try{Zs(s,JSON.stringify(e)),Xs(s,this.filePath),this.data=e}catch{}}isExpired(e){return this.ttl>0&&Date.now()-e.t>this.ttl}get(e){if(!this.enabled)return;let t=this.load(),r=t.entries[e];if(!r)return;if(this.isExpired(r)){let{[e]:n,...s}=t.entries;this.flush({...t,entries:s});return}return r.v}set(e,t){if(!this.enabled)return;let r=this.load(),n={...r.entries,[e]:{v:t,t:Date.now()}},s=Object.entries(n),o=s.length>this.maxEntries?Object.fromEntries(s.sort((c,a)=>a[1].t-c[1].t).slice(0,this.maxEntries)):n;this.flush({...r,entries:o})}has(e){return this.get(e)!==void 0}delete(e){if(!this.enabled)return;let t=this.load(),{[e]:r,...n}=t.entries;this.flush({...t,entries:n})}clear(){if(!this.enabled)return;this.flush(this.empty())}prune(){if(!this.enabled)return 0;let e=this.load(),t=Object.keys(e.entries).length,r=Object.fromEntries(Object.entries(e.entries).filter(([,s])=>!this.isExpired(s))),n=Object.keys(r).length;if(t!==n)this.flush({...e,entries:r});return t-n}}class re{max;ttl;cache;head;tail;constructor(e){this.max=e.max,this.ttl=e.ttl,this.cache=new Map,this.head=null,this.tail=null}get(e){let t=this.cache.get(e);if(!t)return;if(this.isExpired(t)){this.delete(e);return}return this.moveToFront(t),t.value}set(e,t){let r=this.cache.get(e);if(r){r.value=t,r.timestamp=Date.now(),this.moveToFront(r);return}let n={key:e,value:t,prev:null,next:null,timestamp:Date.now()};if(this.cache.set(e,n),this.addToFront(n),this.cache.size>this.max)this.evictLRU()}has(e){let t=this.cache.get(e);if(!t)return!1;if(this.isExpired(t))return this.delete(e),!1;return!0}delete(e){let t=this.cache.get(e);if(!t)return!1;return this.removeNode(t),this.cache.delete(e),!0}clear(){this.cache.clear(),this.head=null,this.tail=null}get size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}values(){let e=[],t=this.head;while(t){if(!this.isExpired(t))e.push(t.value);t=t.next}return e}isExpired(e){let t=this.ttl;if(t===void 0)return!1;return Date.now()-e.timestamp>t}moveToFront(e){if(e===this.head)return;this.removeNode(e),this.addToFront(e)}addToFront(e){if(e.next=this.head,e.prev=null,this.head)this.head.prev=e;if(this.head=e,!this.tail)this.tail=e}removeNode(e){if(e.prev)e.prev.next=e.next;else this.head=e.next;if(e.next)e.next.prev=e.prev;else this.tail=e.prev}evictLRU(){if(!this.tail)return;this.cache.delete(this.tail.key),this.removeNode(this.tail)}}import{existsSync as Ar,mkdirSync as li,readFileSync as pi,writeFileSync as di}from"fs";import{join as hi}from"path";var kr=604800000,gi=50,Or=()=>R(),Pr=()=>hi(Or(),"hints.json");function wr(){let e=Pr();if(!Ar(e))return{};try{return JSON.parse(pi(e,"utf8"))}catch{return{}}}function fi(e){let t=Or(),r=Pr();try{if(!Ar(t))li(t,{recursive:!0});di(r,JSON.stringify(e))}catch{}}function mi(e,t=kr){let n=wr()[e];if(!n)return!0;return Date.now()-n>t}function yi(e){let t=wr();t[e]=Date.now(),fi(t)}function bi(e,t){let r=[],n="";if(e.split(" ").forEach((s)=>{let i=n?n+" "+s:s;if(i.length<=t)n=i;else{if(n)r.push(n);n=s}}),n)r.push(n);return r}function Si(e,t=gi){let r=t-4,n=r-3,s=bi(e,n),i=Ne("+"+"-".repeat(t-2)+"+"),o=s.map((c,a)=>{let u=a===0?y.hint+" ":"   ",l=at(u+c,r);return Ne("| "+l+" |")});return[i,...o,i].join(`
`)}function Pt(e,t,r=kr,n=P){if(!mi(e,r))return;n.writeLine(""),n.writeLine(Si(t)),n.writeLine(""),yi(e)}function vi(e,t=!0){let r=t?w("●"):O("○"),n=t?w("Y"):"y",s=!t?w("N"):"n",i=t?w("[enter for yes]"):w("[enter for no]");return`${r} ${e} (${n}/${s}) ${O(i)}: `}function Ai(e,t){let r=[`${b("?")} ${e}`,"",...t.map((i,o)=>{return`  ${b(`${o+1}.`)} ${i.name}`})],n=_e(r,{title:k("Configuration"),padding:1,width:Math.min(me()-4,80)});return n.map((i,o)=>{if(o===0||o===n.length-1)return k(i);else return i.replace(/^│/,k("│")).replace(/│$/,k("│"))}).join(`
`)}function ki(){return`
${b("▶")} Enter your choice ${O("(number)")}: `}function Oi(e,t){let r=b("◆");if(t){let n=O(`[enter for "${t}"]`);return`${r} ${e} ${n}: `}return`${r} ${e}: `}function Pi(e,t){let n=[`${b(`▶ Step ${e}:`)} ${t}`],s=_e(n,{padding:1,width:Math.min(me()-4,60)});return`
${s.map((o,c)=>{if(c===0||c===s.length-1)return k(o);else return o.replace(/^│/,k("│")).replace(/│$/,k("│"))}).join(`
`)}
`}function wi(e){return ur(O(`${y.info} ${e}`),3)}function Ti(e,t,r){let n=[r||w(`✓ ${e}`),"",...t.map((o,c)=>`  ${b(`${c+1}.`)} ${o}`)],s=_e(n,{title:k("Next Steps"),padding:2,width:Math.min(me()-4,80)});return s.map((o,c)=>{if(c===0||c===s.length-1)return k(o);else return o.replace(/^│/,k("│")).replace(/│$/,k("│"))}).join(`
`)}var Tr=(e,t,r)=>{return(n,s,...i)=>{if(!t)return;let o=`${ot}[${r}][${s}] ${n}`;console[e](o,...i)}},xi=(e)=>{return(t,r,...n)=>{let s=`${ot}[${e}][${r}] ${t}`;console.warn(s,...n)}},Rr="   ",A=({file:e,isLogging:t=!1})=>({debug:Tr("debug",t,e),error:Tr("error",t,e),warn:xi(e),print:(r)=>console.log(r),line:(r)=>console.log(`
`+r),indent:(r)=>console.log(Rr+r),item:(r,n)=>console.log(`${Rr}${r}. ${n}`)});import{execFile as Ii}from"node:child_process";import{promisify as Li}from"util";var $i=Li(Ii),Ni=()=>new Date().toISOString(),_i=async(e)=>{let{stdout:t}=await $i("git",["log","--diff-filter=A","--follow","--format=%aI","-1","--",e]);return t.trim()},Vi=async(e="package.json",t=Ni)=>{try{let r=await _i(e);return r.length>0?r:t()}catch{return t()}};var Cr=(e)=>e.split("-")[0],Er=(e)=>{let t=parseInt(e,10);return isNaN(t)?0:t};function T(e,t){let r=Cr(e),n=Cr(t),s=r.split(".").map(Er),i=n.split(".").map(Er),o=Math.max(s.length,i.length);return Array.from({length:o}).reduce((c,a,u)=>{if(c!==0)return c;let l=s[u]||0,p=i[u]||0;return l-p},0)}class wt{concurrency;running;queue;constructor(e){if(e<1)throw Error("Concurrency must be at least 1");this.concurrency=e,this.running=0,this.queue=[]}run(e){return new Promise((t,r)=>{this.queue.push({task:e,resolve:t,reject:r}),this.process()})}async process(){if(this.running>=this.concurrency||this.queue.length===0)return;this.running++;let e=this.queue.shift();if(!e){this.running--;return}try{let t=await e.task();e.resolve(t)}catch(t){e.reject(t)}finally{this.running--,this.process()}}get queueSize(){return this.queue.length}get activeCount(){return this.running}clear(){this.queue=[]}}var Tt=(e)=>{let t=new wt(e);return(r)=>t.run(r)};var Fe={retries:3,factor:2,minTimeout:1000,maxTimeout:30000},Di=(e,t,r)=>{let n=e;return n.attemptNumber=t,n.retriesLeft=r,n},Ui=(e,t,r,n)=>{let s=r*Math.pow(t,e-1);return Math.min(s,n)},Gi=(e)=>{return new Promise((t)=>setTimeout(t,e))},Q=async(e,t={})=>{let{retries:r=Fe.retries,factor:n=Fe.factor,minTimeout:s=Fe.minTimeout,maxTimeout:i=Fe.maxTimeout,onFailedAttempt:o,onRetry:c}=t,a=0,u=async()=>{a++;try{return await e()}catch(l){let p=r-a,d=p>=0,h=Math.max(0,p),g=Di(l instanceof Error?l:Error(String(l)),a,h);if(!d)throw g;if(o)await o(g);if(c)c(a,h);let f=Ui(a,n,s,i);return await Gi(f),u()}};return u()};var Fi=Tt(5),Mi="https://registry.npmjs.org",Rt=null,ji=(e)=>{if(e?.cacheDir||e?.noCache)return new E(M.REGISTRY,{dir:e.cacheDir??R(),ttl:U.REGISTRY,version:j.REGISTRY,maxEntries:1000,enabled:!e.noCache});if(!Rt)Rt=new E(M.REGISTRY,{dir:R(),ttl:U.REGISTRY,version:j.REGISTRY,maxEntries:1000});return Rt};var xr=(e)=>{let t=e.split(".")[0];return parseInt(t,10)||0},Ki=(e)=>{return e.includes("-")},Bi=async(e,t)=>{let r=ji(t),n=`pkg:${e}`,s=r.get(n);if(s!==void 0)return s;try{let i=await Q(async()=>{let o=await fetch(`${Mi}/${encodeURIComponent(e)}`,{headers:{Accept:"application/json"}});if(!o.ok)throw Error(`Failed to fetch ${e}: ${o.status}`);return o.json()},{retries:2,minTimeout:500,maxTimeout:3000});return r.set(n,i),i}catch{return null}};var Ir=async(e,t,r)=>{let n=await Bi(e,r);if(!n)return null;if(!n.versions||typeof n.versions!=="object")return null;let s=xr(t),o=Object.keys(n.versions).filter((c)=>{let u=xr(c)===s,l=!Ki(c),p=T(c,t)>=0;return u&&l&&p});if(o.length===0)return null;return o.sort((c,a)=>T(a,c)),o[0]},Ct=async(e,t)=>{let r=new Map,n=e.reduce((o,c)=>{if(!o.has(c.name))o.set(c.name,c.minVersion);return o},new Map),s=Array.from(n.entries()),i=await Promise.all(s.map(([o,c])=>Fi(async()=>{let a=await Ir(o,c,t);return{name:o,version:a}})));for(let{name:o,version:c}of i)if(c)r.set(o,c);return r};import*as G from"fs";import{dirname as no,resolve as W}from"path";import{execFile as so}from"node:child_process";import{promisify as io}from"util";import{readdirSync as Fr,existsSync as ae,statSync as Et}from"node:fs";import{resolve as Se,relative as be,join as xt,isAbsolute as Hi}from"node:path";var Lr=/[.+^${}()|[\]\\]/g,$r=/\*\*/g,Nr=/\*/g,_r=/\?/g,Vr="{{GLOBSTAR}}",Dr=/{{GLOBSTAR}}/g,Ur=["node_modules",".git"];var ye=new Map,Wi=200,ue=(e)=>e.replaceAll("\\","/"),Yi=(e)=>{let i=e.replace(Lr,"\\$&").replace($r,Vr).replace(Nr,"[^/]*").replace(_r,"[^/]").replace(Dr,".*");return new RegExp(`^${i}$`)},It=(e)=>{let t=ye.get(e);if(!t){if(ye.size>=Wi){let r=ye.keys().next().value;if(r!==void 0)ye.delete(r)}t=Yi(e),ye.set(e,t)}return t},Mr=(e)=>!e.includes("*")&&!e.includes("?"),Gr=(e,t)=>{let r=Hi(e)?e:Se(t,e);return ue(be(t,r))},zi=(e,t)=>{if(Mr(t))return e===t;return It(t).test(e)},qi=(e)=>e.split("/").filter((t)=>!t.includes("*")&&t!=="").join("/"),Ji=(e,t)=>t.some((r)=>{if(It(r).test(e))return!0;let s=qi(r);return s!==""&&e.includes(s)}),jr=(e)=>Ur.includes(e),ne=(e,t)=>Ji(e,t),Kr=(e,t,r,n=[])=>{if(!ae(e))return n;let s=Fr(e,{withFileTypes:!0});for(let i of s){let o=xt(e,i.name),c=be(t,o),a=ue(c);if(!i.isDirectory()){if(!ne(a,r))n.push(a)}else if(!jr(i.name)&&!ne(a,r))Kr(o,t,r,n)}return n},Qi=(e)=>Array.isArray(e)?e:[e],Zi=(e,t,r)=>r?Se(t,e):e,Br=(e)=>ue(e).split("/").filter((t)=>t!==""&&t!=="."),Hr=(e)=>{let t=0;while(t<e.length){let r=e[t];if(r.includes("*")||r.includes("?"))break;t++}return t},Xi=(e)=>e.includes("*")||e.includes("?"),eo=(e,t)=>It(t).test(e),Wr=(e,t)=>t.length>0?Se(e,...t):e,to=(e,t,r)=>{let n=Br(e),s=Hr(n),i=n.slice(0,s),o=n.slice(s),c=Wr(t,i);if(!ae(c))return[];if(o.length===0)return[];let a=[c],u=[];for(let l=0;l<o.length;l++){let p=o[l],d=l===o.length-1,h=[];for(let g of a){if(!ae(g))continue;if(!Xi(p)){let m=xt(g,p),S=ue(be(t,m));if(d){if(ae(m)&&!Et(m).isDirectory()&&!ne(S,r))u.push(S)}else if(ae(m)&&Et(m).isDirectory()&&!ne(S,r))h.push(m);continue}let f=Fr(g,{withFileTypes:!0});for(let m of f){if(!eo(m.name,p))continue;let S=xt(g,m.name),C=ue(be(t,S));if(m.isDirectory()){if(!d&&!jr(m.name)&&!ne(C,r))h.push(S);continue}if(d&&!ne(C,r))u.push(C)}}if(a=h,!d&&a.length===0)break}return u},ro=(e,t,r)=>{if(Mr(e.pattern)){let a=Se(t,e.pattern);if(!ae(a))return[];if(Et(a).isDirectory())return[];let u=ue(be(t,a));if(ne(u,r))return[];return[u]}if(!e.hasGlobStar)return to(e.pattern,t,r);let n=Br(e.pattern),s=Hr(n),i=n.slice(0,s),o=Wr(t,i);return Kr(o,t,r).filter((a)=>zi(a,e.pattern))},ve=(e,t={})=>{let{cwd:r=process.cwd(),ignore:n=[],absolute:s=!1}=t,i=Se(r),o=Qi(e).map((l)=>Gr(l,i)),c=n.map((l)=>Gr(l,i)),a=o.map((l)=>({pattern:l,hasGlobStar:l.includes("**")})),u=new Set;for(let l of a){let p=ro(l,i,c);for(let d of p)u.add(d)}return Array.from(u).map((l)=>Zi(l,i,s)).sort()},Yr=(e,t={})=>ve(e,t);var oo=io(so),H=A({file:"packageJSON.ts",isLogging:_}),Ae=null,se=null,co=(e,t)=>{if(e||t)return new E(M.TREE,{dir:e??R(),ttl:U.TREE,version:j.TREE,maxEntries:50,enabled:!t});if(!Ae)Ae=new E(M.TREE,{dir:R(),ttl:U.TREE,version:j.TREE,maxEntries:50});return Ae},K=new re({max:500}),Xp=()=>{return{size:K.size,keys:Array.from(K.keys())}},ed=()=>{let e=K.size;return K.clear(),H.debug(`Cache cleared. Had ${e} entries`,"forceClearCache"),e},Me=(e,t=process.cwd())=>{let r=W(t,e);return G.existsSync(r)},le=(e=process.cwd())=>{if(Me("bun.lockb",e)||Me("bun.lock",e))return"bun";if(Me("yarn.lock",e))return"yarn";if(Me("pnpm-lock.yaml",e))return"pnpm";return"npm"},ao=(e)=>{return e?.resolutions!==void 0},uo=(e)=>{return e?.overrides!==void 0},lo=(e)=>{return e?.pnpm?.overrides!==void 0},po=(e)=>{if(ao(e))return"resolutions";if(uo(e))return"overrides";if(lo(e))return"pnpm";return null},ho=(e)=>{return{yarn:"resolutions",pnpm:"pnpm",npm:"overrides",bun:"overrides"}[e]},go=(e,t)=>{return{...e,resolutions:t}},fo=(e,t)=>{let r=e.pnpm||{};return{...e,pnpm:{...r,overrides:t}}},mo=(e,t)=>{return{...e,overrides:t}},yo=(e,t,r)=>{if(r==="resolutions")return go(e,t);if(r==="pnpm")return fo(e,t);if(r==="overrides")return mo(e,t);return e},bo=(e)=>{try{let t=G.readFileSync(e,"utf8");return JSON.parse(t)}catch(t){H.error(`Invalid JSON at: ${e}`,"parseJsonFile",t);return}},ke=(e)=>{let t=W(e),r=K.get(t);if(r)return r;let n=bo(t);if(n)K.set(t,n);return n},So=(e)=>{let t=Boolean(e.pastoralist?.overridePaths),r=Boolean(e.pastoralist?.resolutionPaths),n=Boolean(e.pastoralist?.security),s=Boolean(e.pastoralist?.depPaths);return t||r||n||s},Lt=(e)=>{let t=e.pastoralist?.depPaths,r=e.pastoralist?.overridePaths,n=e.pastoralist?.resolutionPaths,s=e.pastoralist?.security;return{...t&&{depPaths:t},...r&&{overridePaths:r},...n&&{resolutionPaths:n},...s&&{security:s}}},vo=(e)=>{let{resolutions:t,overrides:r,pnpm:n,...s}=e;if(!n)return s;let{overrides:i,...o}=n,c=Object.keys(o).length>0;return{...s,...c&&{pnpm:o}}},Ao=(e)=>{if(!So(e)){let{pastoralist:n,...s}=e;return s}let r=Lt(e);return{...e,pastoralist:r}},ko=(e,t)=>{let r=Lt(e);return{...e,pastoralist:{appendix:t,...r}}},Oo=(e)=>{let t=vo(e);return Ao(t)},Po=(e,t,r,n,s)=>{let i=t&&Object.keys(t).length>0,o;if(i)o=ko(e,t);else{let p=Lt(e),d=Object.keys(p).length>0,{pastoralist:h,...g}=e;o=d?{...g,pastoralist:p}:g}if(!(r&&Object.keys(r).length>0))return o;let a=po(o),u=no(W(s)),l=a||(n?null:ho(le(u)));return yo(o,r,l)},qr=(e)=>{return JSON.stringify(e,null,2)+`
`},wo=(e)=>{if(!e.pastoralist)return 0;return JSON.stringify(e.pastoralist,null,2).split(`
`).length},To=(e)=>{return wo(e)>10},Ro=(e)=>{try{let t=JSON.parse(e);return Boolean(t.name)}catch{return!1}},Co=(e,t)=>{let r=W(e);if(!r.endsWith(".json")){H.error(`Invalid target file: ${r}`,"writeJsonFile");return}let s=W(process.cwd(),"package.json");if(r===s&&!Ro(t))return;G.writeFileSync(r,t)},Jr=({appendix:e,path:t,config:r,overrides:n,isTesting:s=!1,dryRun:i=!1,silent:o=!1})=>{let c=n&&Object.keys(n).length>0,a=e&&Object.keys(e).length>0,l=c||a?Po(r,e,n||{},s,t):Oo(r);if(s)return l;let p=qr(l),d=qr(r),h=p===d;if(i&&!o)if(h)H.print(`
[DRY RUN] No changes detected, skipping write.`);else H.print(`
[DRY RUN] Would write to package.json:`),H.print(p);if(h)return;if(i)return l;if(_)H.debug(`Writing updated package.json:
${p}`,"updatePackageJSON");Co(t,p);let f=W(t);if(K.delete(f),To(l))Pt(nr,sr)},Eo=(e)=>{let t;try{t=JSON.parse(e)}catch(s){return H.debug("Failed to parse npm ls output","parseNpmLsOutput",s),{}}let r={},n=(s)=>{if(!(s&&typeof s==="object"))return;Object.entries(s).forEach(([o,c])=>{if(r[o]=!0,c&&typeof c==="object"&&"dependencies"in c)n(c.dependencies)})};if(t.dependencies)n(t.dependencies);return r},xo=async(e=process.cwd())=>{try{let{stdout:t}=await oo("npm",["ls","--json","--all"],{cwd:e,encoding:"utf8",maxBuffer:10485760,timeout:60000});return t}catch(t){let r=t;if(r.code===1&&r.stdout)return r.stdout;throw t}},Qr=async(e,t,r,n=process.cwd())=>{let s=ce(n),i=le(n),o=process.versions.node,c=`tree:${s}:${i}:${o}`,a=co(t,r),u=a.get(c);if(u)return u;if(!se)se=new Map;let l=se.get(c);if(l)return l;let p=(async()=>{try{let h=await(e||xo)(n),g=Eo(h);return a.set(c,g),g}catch(d){return H.debug("Failed to get dependency tree","getDependencyTree",d),{}}finally{se?.delete(c)}})();return se.set(c,p),p},Zr=()=>{Ae?.clear(),Ae=null,se?.clear(),se=null},Io=/^[\w@][\w\-./]*@/gm,Lo=/^\s{2}\/[\w@]/gm,Xr=(e="./")=>{let t=W(e,"package-lock.json"),r=W(e,"yarn.lock"),n=W(e,"pnpm-lock.yaml"),s=G.existsSync(t),i=G.existsSync(r),o=G.existsSync(n);if(s)try{let c=G.readFileSync(t,"utf8"),u=JSON.parse(c).packages||{};return Math.max(0,Object.keys(u).length-1)}catch{return 0}if(i)try{let a=G.readFileSync(r,"utf8").match(Io);return a?a.length:0}catch{return 0}if(o)try{let a=G.readFileSync(n,"utf8").match(Lo);return a?a.length:0}catch{return 0}return 0},en=(e,t=[],r="./",n=H)=>{if(e.length===0)throw n.error("No depPaths provided","findPackageJsonFiles"),Error("No depPaths provided to findPackageJsonFiles");try{n.debug(`Searching with patterns: ${e.join(", ")}, ignoring: ${t.join(", ")}, cwd: ${r}`,"findPackageJsonFiles");let i=ve(e,{cwd:r,ignore:t,absolute:!0});if(i.length===0){let c=`No package.json files found matching patterns: ${e.join(", ")} in directory: ${r}`;throw n.error(c,"findPackageJsonFiles"),Error(c)}return n.debug(`Found ${i.length} files`,"findPackageJsonFiles"),i}catch(i){throw n.error("Error finding package.json files","findPackageJsonFiles",i),i}};var $o=(e="@")=>(t)=>(r)=>t+e+r,Oe=$o("@"),tn=(e)=>(...t)=>t.join(e),rd=tn("@"),nd=tn(":");var nn="(unused override)",No=(e,t)=>{return t?.find((r)=>r.packageName===e)?.reason},_o=(e,t)=>{return t?.[e]},$t=(e,t,r,n)=>{if(t)return t;let s=No(e,r);if(s)return s;return _o(e,n)},Vo=(e,t)=>{if(!Boolean(t))return!1;return t.some((n)=>n.packageName===e)},Do=(e,t)=>{return t?.filter((r)=>r.packageName===e)||[]},Uo=()=>({source:"security",securityChecked:!0,securityCheckDate:new Date().toISOString()}),Go=(e,t)=>{if(!Boolean(t))return e;return{...e,securityProvider:t}},Fo=(e,t)=>{let r=t.flatMap((s)=>s.cves||[]),n=[...new Set(r)];if(n.length===0)return e;return{...e,cves:n}},rn=(e)=>{return{low:1,medium:2,high:3,critical:4}[e.toLowerCase()]||0},Mo=(e,t)=>{let r=t.map((s)=>s.severity).filter(Boolean);if(r.length===0)return e;let n=r.reduce((s,i)=>{return rn(i)>rn(s)?i:s});return{...e,severity:n}},jo=(e,t)=>{let r=t.find((n)=>n.url)?.url;if(!r)return e;return{...e,url:r}},Ko=(e,t)=>{let r=t.find((n)=>n.vulnerableRange)?.vulnerableRange;if(!r)return e;return{...e,vulnerableRange:r}},Bo=(e,t)=>{let r=t.find((n)=>n.patchedVersion)?.patchedVersion;if(!r)return e;return{...e,patchedVersion:r}},Ho=(e,t)=>{let r=t.flatMap((s)=>s.sources||[]),n=[...new Set(r)];if(n.length===0)return e;return{...e,sources:n}},Wo=(e,t)=>{let r=t.flatMap((o)=>o.sources||[]),n=[...new Set(r)];if(n.length===0)return e;let i=n.length>=2?"confirmed":"possible";return{...e,confidence:i}},Yo=(e)=>{let r=e.flatMap((n)=>(n.cves||[]).map((s)=>{let i={cve:s};if(n.severity)i.severity=n.severity;if(n.patchedVersion)i.patchedVersion=n.patchedVersion;return[s,i]})).reduce((n,[s,i])=>{if(!n.has(s))n.set(s,i);return n},new Map);return Array.from(r.values())},zo=(e,t)=>{let r=Yo(t);if(r.length===0)return e;return{...e,cveDetails:r}},Nt=(e,t,r)=>{if(!Vo(e,t))return{};let s=Do(e,t);return[(o)=>Go(o,r),(o)=>Fo(o,s),(o)=>zo(o,s),(o)=>Mo(o,s),(o)=>jo(o,s),(o)=>Ko(o,s),(o)=>Bo(o,s),(o)=>Ho(o,s),(o)=>Wo(o,s)].reduce((o,c)=>c(o),Uo())},qo=(e)=>{let t=e;if(!t.cve)return e;let{cve:r,...n}=t,s=n.cves||[],i=[...new Set([...s,r])];return{...n,cves:i}},Jo=(e,t,r)=>{let s={addedDate:r||new Date().toISOString()};return{...e?{...s,reason:e}:s,...t}},_t=(e,t,r,n,s)=>{let o=Boolean(t)?t:Jo(r,n,s),c=o?qo(o):o;return{dependents:e,ledger:c}},Vt=(e,t,r)=>{return{...e,[t]:r}},sn=(e,t,r,n)=>{if(e)return Oe(t)(r??"");if(n?.[t]||!1)return`${t} (transitive dependency)`;return`${t} ${nn}`},on=(e)=>{return typeof e==="object"},Qo=(e)=>{if(!Boolean(e?.dependents))return!0;return Object.keys(e.dependents).length===0},cn=(e)=>{return Object.keys(e).filter((n)=>{let s=e[n];return s&&!Qo(s)}).reduce((n,s)=>{return n[s]=e[s],n},{})},an=(e)=>{let t=e?.dependencies||{},r=e?.devDependencies||{},n=e?.peerDependencies||{};return{...t,...r,...n}},un=(e,t)=>{let r=new Set(t);return e.some((n)=>r.has(n))},ln=(e,t)=>{if(!Boolean(e))return!1;return Object.keys(e).length>0&&t},Pe=(e)=>{if(!e)return!1;return Object.keys(e).length>0},pe=(e,t,r)=>{let n=e[t],s={...n?.dependents,...r.dependents},i=n?{...n,dependents:s}:{dependents:s};return{...e,[t]:i}},Zo=(e)=>{let t=e.ledger;if(!t)return!1;return Boolean(t.securityChecked||t.securityProvider||t.cves?.length||t.severity)},Xo=(e)=>{return Boolean(e.patches&&e.patches.length>0)},je=(e)=>{let t=e.ledger?.keep;return t===!0||typeof t==="object"&&t!==null},ec=(e,t,r)=>{let n=e.ledger?.keep;if(!n||n===!0)return!1;let s=new Date,i=n.until?new Date(n.until):null;if(i?s>=i:!1)return!0;if(n.untilVersion){let a=r[t]?.replace(/^[\^~]/,"");if((a?T(a,n.untilVersion):-1)>=0)return!0}return!1},tc=(e)=>{if(je(e))return!1;return!Zo(e)&&!Xo(e)},rc=(e,t)=>{if(e.ledger?.addedDate)return e.ledger.addedDate;if(t)return t;return new Date().toISOString().split("T")[0]},pn=(e,t)=>Object.entries(e).reduce((r,[n,s])=>{return r[n]=tc(s)?{addedDate:rc(s,t)}:s,r},{}),nc=(e,t,r)=>{let n=je(e),s=n&&ec(e,t,r);if(n&&!s)return!1;let o=e?.dependents;if(!o)return!1;let c=Object.values(o);if(!c.length)return!1;return c.every((a)=>a.includes(nn))},dn=(e,t={})=>{if(!e)return[];return Object.keys(e).filter((r)=>{let n=r.lastIndexOf("@")>0?r.slice(0,r.lastIndexOf("@")):r;return nc(e[r],n,t)})},hn=(e,t)=>{let r=new Set(t),n={};for(let s of Object.keys(e))if(!r.has(s))n[s]=e[s];return n},gn=(e)=>e.map((t)=>{let r=t.lastIndexOf("@");return r>0?t.slice(0,r):t}),fn=(e,t)=>{let r=new Set(t),n={};for(let s of Object.keys(e))if(!r.has(s))n[s]=e[s];return n};var Ke=A({file:"workspace.ts",isLogging:_}),sc=(e,t)=>{return Boolean(t[e])},ic=(e,t)=>{return e.filter((r)=>!sc(r,t))},oc=(e,t)=>{return e>0&&!t},mn=(e,t,r,n)=>{let s=Object.keys(e),i=ic(s,t),o=Boolean(n?.depPaths);if(oc(i.length,o))r.debug(`Found overrides for packages not in root dependencies: ${i.join(", ")}`,"checkMonorepoOverrides"),r.debug("For monorepo support, use --depPaths flag or add depPaths configuration in package.json","checkMonorepoOverrides");return i},cc=(e)=>{let t=e?.dependencies||{},r=e?.devDependencies||{},n=e?.peerDependencies||{};return{...t,...r,...n}},ac=(e)=>{return e.map((r)=>ke(r)).filter(Boolean).reduce((r,n)=>{let s=cc(n);return Object.assign(r,s),r},{})},yn=(e,t,r,n)=>{let s=n(e,t,r),i=ac(e);return{appendix:s,allWorkspaceDeps:i}},uc=(e,t)=>{let r=Boolean(e),n=t.length>0;return r&&n},bn=(e,t,r,n)=>{if(!uc(t,r))return e;return n.debug("Using overridePaths configuration for monorepo support","mergeOverridePaths"),Object.values(t).reduce((i,o)=>Object.entries(o).reduce((c,[a,u])=>pe(c,a,u),i),e)},Sn=(e,t)=>{return typeof t[e]==="object"},vn=(e,t)=>{return Boolean(t[e])},lc=(e,t,r)=>{if(!Sn(e,t))return!1;if(vn(e,r))return!1;return Ke.debug(`Found unused nested override for ${e}: parent package not in dependencies`,"isUnusedNestedOverride"),!0},pc=async(e,t,r,n,s)=>{if(Sn(e,t))return!1;if(vn(e,r))return!1;if(!s)return Ke.debug(`Found unused override for ${e}: no dependencies at all`,"isUnusedSimpleOverride"),!0;if(Boolean(n[e]))return Ke.debug(`Keeping override for ${e}: found in dependency tree`,"isUnusedSimpleOverride"),!1;return Ke.debug(`Found unused override for ${e}: not in dependency tree`,"isUnusedSimpleOverride"),!0},dc=async(e,t,r,n,s)=>{if(lc(e,t,r))return!0;return pc(e,t,r,n,s)},hc=async(e,t)=>{let r=Object.keys(e),n=Object.keys(t).length>0,s=n?await Qr():{},i=await Promise.all(r.map((o)=>dc(o,e,t,s,n)));return r.filter((o,c)=>i[c])},gc=(e,t)=>{if(!t)return!1;return Object.values(t).some((r)=>Object.keys(r).some((n)=>n.startsWith(`${e}@`)))},fc=(e,t)=>{return e.filter((r)=>gc(r,t))},mc=(e,t)=>{let r=new Set(t);return e.filter((n)=>!r.has(n))},yc=(e,t,r)=>{return t.reduce((n,s)=>{return Object.keys(n).filter((o)=>o.startsWith(`${s}@`)).reduce((o,c)=>{r.debug(`Removed appendix entry for ${c}`,"removeAppendixEntries");let{[c]:a,...u}=o;return u},n)},e)},dd=async(e,t,r,n,s,i,o,c)=>{let a=await hc(e,n);if(a.length===0)return{finalOverrides:e,finalAppendix:r};let l=fc(s,i),p=mc(a,l);if(p.length>0){o.debug(`Found ${p.length} packages to remove from overrides: ${p.join(", ")}`,"cleanupUnusedOverrides");let g=c(t,p)||e,f=yc(r,p,o);return{finalOverrides:g,finalAppendix:f}}if(l.length>0)o.debug(`Keeping overrides for packages tracked in overridePaths: ${l.join(", ")}`,"cleanupUnusedOverrides");return{finalOverrides:e,finalAppendix:r}};var Dt=A({file:"patches.ts",isLogging:_}),bc=["patches/*.patch",".patches/*.patch","*.patch","patches/**/*.patch"],Sc=(e)=>{return e.split("/").pop()||""},vc=(e)=>{return e.replace(".patch","")},Ac=(e)=>{return e.length>=2?`${e[0]}/${e[1]}`:e[0]},kc=(e)=>{return e[0]},Oc=(e)=>{if(!e.includes("+"))return e;let r=e.split("+");return e.startsWith("@")?Ac(r):kc(r)},Pc=(e,t,r)=>{let n=e[t]||[];return{...e,[t]:[...n,r]}},wc=(e,t)=>{let r=Sc(e);if(!r.endsWith(".patch"))return t;let s=vc(r),i=Oc(s);if(!Boolean(i))return t;return Dt.debug(`Found patch for ${i}: ${e}`,"processPatchFile"),Pc(t,i,e)},Tc=(e)=>{return e.reduce((t,r)=>wc(r,t),{})},An=(e="./")=>{try{let t=ve(bc,{cwd:e});return Tc(t)}catch(t){return Dt.error("Error detecting patches","detectPatches",t),{}}},Rc=(e,t)=>{return t[e]||[]},Cc=(e,t)=>{return Boolean(t[e])},Ec=(e,t)=>{return e.flatMap(([r,n])=>{if(Cc(r,t))return[];return Dt.debug(`Found unused patches for ${r}: ${n.join(", ")}`,"collectUnusedPatches"),n})},kn=(e,t)=>{let r=Object.entries(e);return Ec(r,t)},xc=(e)=>{let t=e.lastIndexOf("@");return t>0?e.slice(0,t):e},Ic=(e,t,r)=>{let n=xc(t),s=Rc(n,r);if(!(s.length>0))return e;return{...e,[t]:{...e[t],patches:s}}},On=(e,t)=>{return Object.keys(e).reduce((n,s)=>Ic(n,s,t),e)};var we=A({file:"overrides.ts",isLogging:_}),Ut=(e)=>Object.keys(e??{}).length>0,Lc=(e,t,r)=>{let n=t?.overrides||{};return[{type:"overrides",overrides:e},{type:"pnpmOverrides",overrides:n},{type:"resolutions",overrides:r}]},$c=(e)=>{return e.filter(({overrides:t})=>Object.keys(t).length>0)},Nc=(e)=>{return e.length>1},_c=({overrides:e={},pnpm:t={},resolutions:r={}}={})=>{let n=Ut(e),s=Ut(t?.overrides),i=Ut(r);if(!(n||s||i))return;let c=Lc(e,t,r),a=$c(c);if(Nc(a)){we.error("Only 1 override object allowed","defineOverride");return}return a[0]},Vc=(e)=>{return Object.keys(e).reduce((r,n)=>{let s=e[n];return r[n]=s,r},{})},Dc=(e)=>{return{type:"pnpm",pnpm:{overrides:e}}},Uc=(e)=>{return{type:"resolutions",resolutions:e}},Gc=(e)=>{return{type:"npm",overrides:e}},Fc=(e,t)=>{if(e==="pnpmOverrides")return Dc(t);if(e==="resolutions")return Uc(t);return Gc(t)},Be=({config:e={}})=>{let t=_c(e);if(!t){we.debug("No overrides configuration found","resolveOverrides");return}let{type:n,overrides:s}=t,i=Object.keys(s).length>0,o=Boolean(n);if(!(i&&o)){we.debug("No active overrides found","resolveOverrides");return}let a=Vc(s);return Fc(n,a)},Mc=(e)=>{return e?.resolutions},jc=(e)=>{return e?.pnpm?.overrides},Kc=(e)=>{return e?.overrides},de=(e)=>{let t=e?.type;if(!t){we.error("no type found","getOverridesByType");return}if(t==="resolutions")return Mc(e);if(t==="pnpm")return jc(e);return Kc(e)},Bc=(e,t)=>{return!t.includes(e)},Hc=(e,t)=>{return Object.entries(e).reduce((r,[n,s])=>{if(Bc(n,t))r[n]=s;return r},{})},Sd=(e,t)=>{if(!e)return;let n=de(e);if(!n||Object.keys(n).length===0){we.debug("No overrides found to update","updateOverrides");return}return Hc(n,t)};import{writeFileSync as Wc}from"fs";import{resolve as Yc}from"path";var Pn=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),zc=({override:e,overrideVersion:t="",packageName:r,deps:n,appendix:s,packageReason:i,securityLedger:o={},cache:c,onlyUsedOverrides:a=!1,dependencyTree:u,addedDate:l})=>{let p=Pn(n,e),d=u?.[e]||!1;if(a&&(!p&&!d))return s;let f=Oe(e)(t),m=c.get(f);if(m)return s[f]=m,s;let S=s[f]?.dependents||{},C=n[e],z=sn(p,e,C,u),$=Vt(S,r,z),N=s[f]?.ledger,Le=_t($,N,i,o,l);return c.set(f,Le),s[f]=Le,s},qc=({override:e,overrideVersion:t="",packageName:r,parentOverride:n="",deps:s,appendix:i,packageReason:o,securityOverrideDetails:c,securityProvider:a,manualOverrideReasons:u,cache:l,addedDate:p})=>{let d=Oe(e)(t),h=l.get(d);if(h)return i[d]=h,i;let g=i[d]?.dependents||{},f=`${n}@${s[n]} (nested override)`,m=Vt(g,r,f),S=i[d]?.ledger,C=$t(e,void 0,c,u)||o,z=Nt(e,c,a),$=_t(m,S,C,z,p);return l.set(d,$),i[d]=$,i},Jc=({override:e,overrides:t={},packageName:r,deps:n,appendix:s,packageReason:i,securityOverrideDetails:o,securityProvider:c,manualOverrideReasons:a,cache:u,addedDate:l})=>{if(!Pn(n,e))return s;let d=t[e];return Object.entries(d).reduce((h,[g,f])=>qc({override:g,overrideVersion:f,packageName:r,parentOverride:e,deps:n,appendix:h,packageReason:i,securityOverrideDetails:o,securityProvider:c,manualOverrideReasons:a,cache:u,addedDate:l}),s)},Qc=({override:e,overrides:t={},packageName:r,deps:n,appendix:s,reason:i,securityOverrideDetails:o,securityProvider:c,manualOverrideReasons:a,cache:u,onlyUsedOverrides:l=!1,dependencyTree:p,addedDate:d})=>{let h=t[e],g=$t(e,i,o,a),f=Nt(e,o,c);if(on(h))return Jc({override:e,overrides:t,packageName:r,deps:n,appendix:s,packageReason:g,securityOverrideDetails:o,securityProvider:c,manualOverrideReasons:a,cache:u,addedDate:d});return zc({override:e,overrideVersion:h,packageName:r,deps:n,appendix:s,packageReason:g,securityLedger:f,cache:u,onlyUsedOverrides:l,dependencyTree:p,addedDate:d})},Te=({overrides:e={},appendix:t={},dependencies:r={},devDependencies:n={},peerDependencies:s={},packageName:i="",reason:o,securityOverrideDetails:c,securityProvider:a,manualOverrideReasons:u,cache:l=new Map,onlyUsedOverrides:p=!1,dependencyTree:d,addedDate:h})=>{let g=Object.keys(e),f={...r,...n,...s},m={...t},S=g.reduce((C,z)=>Qc({override:z,overrides:e,packageName:i,deps:f,appendix:C,reason:o,securityOverrideDetails:c,securityProvider:a,manualOverrideReasons:u,cache:l,onlyUsedOverrides:p,dependencyTree:d,addedDate:h}),m);return cn(S)},Zc=(e,t,r,n=!0)=>{let s=ke(e);if(!Boolean(s))return;let{name:o,dependencies:c={},devDependencies:a={},peerDependencies:u={}}=s,l=an(s),p=Object.keys(l);if(!un(p,r))return;let h=Te({overrides:t,dependencies:c,devDependencies:a,peerDependencies:u,packageName:o,securityOverrideDetails:void 0,manualOverrideReasons:void 0,onlyUsedOverrides:!0});if(ln(h,n))try{let f=Yc(e),m={...s,pastoralist:{appendix:h}};Wc(e,JSON.stringify(m,null,2)),K.delete(f)}catch(f){let m=f instanceof Error?f.message:String(f);throw Error(`Failed to write ${e}: ${m}`)}return{name:o,dependencies:c,devDependencies:a,appendix:h}},Xc=(e)=>{if(!e)return null;return de(e)||null},ea=(e,t)=>{let r=ke(e);if(!Boolean(r))return null;let s=Be({config:r}),i=de(s)||null,o=Pe(i);if(o)t.debug(`Found ${Object.keys(i).length} overrides in ${e}`,"constructAppendix");return o?i:null},ta=(e,t)=>{return e.map((r)=>ea(r,t))},ra=(e,t,r)=>{if(!Pe(t))return;e.filter((s)=>s!==null).forEach((s)=>{Object.entries(s).forEach(([i,o])=>{let c=t[i];if(c&&c!==o)r.debug(`Override conflict for "${i}": root has "${c}", workspace has "${o}" — workspace wins`,"constructAppendix")})})},na=(e,t)=>{let r=e.filter((s)=>s!==null),n=Pe(t)?{...t}:{};return r.reduce((s,i)=>({...s,...i}),n)},sa=(e,t,r)=>{return e.map((n)=>Zc(n,t,r,!1))},ia=(e,t)=>{return Object.entries(t).reduce((r,[n,s])=>pe(r,n,s),e)},oa=(e)=>{return e.filter((r)=>r!==null&&r!==void 0&&Boolean(r.appendix)).reduce((r,n)=>ia(r,n.appendix),{})},wn=(e,t,r)=>{let n=Xc(t);if(Pe(n))r.debug(`Found ${Object.keys(n).length} overrides in root package.json`,"constructAppendix");let i=ta(e,r);ra(i,n,r);let o=na(i,n);if(!(Object.keys(o).length>0))return r.debug("No overrides found in root or workspace packages","constructAppendix"),{};let a=Object.keys(o);r.debug(`Processing ${a.length} total unique overrides across all packages`,"constructAppendix");let u=sa(e,o,a);return oa(u)},Rd=(e)=>{if(!e)return[];let t=Object.keys(e);if(t.length===0)return[];return t.filter((r)=>{let n=e[r]?.dependents;return!n||Object.keys(n).length===0}).map((r)=>r.replace(/@[^@]+$/,""))};var Tn={SINGLE:"workspace",MULTIPLE:"workspaces"},Rn=(e,t,r,n)=>{return en(e,r,t,n)},ca=(e,t)=>{if(!t)return e;return pn(e)},Cn=(e)=>{let t=e.options?.outputFormat==="json",r=e.config?.pastoralist?.compactAppendix===!0,n=ca(e.finalAppendix,r);Jr({appendix:n,path:e.path,config:e.config,overrides:e.finalOverrides,dryRun:e.options?.dryRun||!1,silent:t,isTesting:e.isTesting})},En=(e,t,r,n)=>{let s=t.pastoralist?.depPaths,i=e?.depPaths&&e.depPaths.length>0,o=!i&&s,c=aa(e,t);return{mode:i||o?"workspace":"root",depPaths:c,hasRootOverrides:r,missingInRoot:n}},aa=(e,t)=>{if(e?.depPaths)return e.depPaths;let r=t.pastoralist?.depPaths;if(r===Tn.SINGLE||r===Tn.MULTIPLE)return t.workspaces?.map((n)=>`${n}/package.json`)||null;if(Array.isArray(r))return r;if(t.workspaces&&!r)return t.workspaces.map((n)=>`${n}/package.json`);return null};var ua=(e)=>{let t=An(e.root),r=Object.keys(t);if(r.length>0)e.log.debug(`Found patches for packages: ${r.join(", ")}`,"stepDetectPatches");return{...e,patchMap:t}},la=(e)=>{if(!e.config)return e;let t=Be({options:e.options,config:e.config}),r=de(t)||{};if(e.options?.securityOverrides)e.log.debug("Merging security overrides","stepPrepareOverrides"),r={...r,...e.options.securityOverrides};return{...e,overridesData:t,overrides:r}},pa=(e)=>{if(!e.config)return e;let t=e.overrides||{},r=Object.keys(t).length>0,n={...e.config.dependencies,...e.config.devDependencies,...e.config.peerDependencies},s=mn(t,n,e.log,e.options),i=En(e.options,e.config,r,s);return{...e,hasRootOverrides:r,rootDeps:n,missingInRoot:s,mode:i}},da=(e)=>{if(!e.config||!e.mode||!e.overridesData)return e;let t=e.mode.depPaths;if(!(t&&t.length>0))return e;let n=e.options?.ignore||[],s=Rn(t,e.root,n,e.log);if(s.length===0)return e;e.log.debug(`Processing ${s.length} workspace packages`,"stepProcessWorkspaces");let{appendix:i,allWorkspaceDeps:o}=yn(s,e.overridesData,e.log,wn);return{...e,workspaceAppendix:i,allWorkspaceDeps:o}},ha=(e)=>{if(!e.config||!e.overrides)return e;let t=e.config.pastoralist?.appendix||{};return{...e,existingAppendix:t}},ga=(e)=>{if(!e.config||!e.overrides)return e;let{dependencies:t={},devDependencies:r={},peerDependencies:n={}}=e.config,s=Te({overrides:e.overrides,appendix:e.existingAppendix||{},dependencies:t,devDependencies:r,peerDependencies:n,packageName:e.config.name||"root",securityOverrideDetails:e.options?.securityOverrideDetails,securityProvider:e.options?.securityProvider,manualOverrideReasons:e.options?.manualOverrideReasons,addedDate:e.options?.addedDate});if(!e.workspaceAppendix)return{...e,appendix:s};e.log.debug("Merging workspace appendix with root appendix","stepBuildAppendix");let i=Object.entries(e.workspaceAppendix).reduce((o,[c,a])=>pe(o,c,a),s);return{...e,appendix:i}},fa=(e)=>{if(!e.appendix||!e.patchMap)return e;let t=On(e.appendix,e.patchMap);return{...e,appendix:t}},ma=(e)=>{if(!e.config||!e.appendix||!e.missingInRoot)return e;let t=e.config.pastoralist?.overridePaths||e.config.pastoralist?.resolutionPaths,r=bn(e.appendix,t,e.missingInRoot,e.log);return{...e,appendix:r,overridePaths:t}},ya=(e)=>{if(!e.patchMap||!e.rootDeps)return e;let t=Object.assign({},e.rootDeps,e.allWorkspaceDeps||{}),r=kn(e.patchMap,t);if(r.length>0)e.log.line(`Found ${r.length} potentially unused patch files:`),r.forEach((n)=>e.log.indent(`- ${n}`)),e.log.print("Consider removing these patches if the packages are no longer used.");return{...e,allDeps:t,unusedPatchCount:r.length}},ba=(e,t)=>e.find((r)=>{return(r.cves||[]).some((i)=>t.includes(i))&&Boolean(r.patchedVersion)}),Sa=(e,t)=>({...e,potentiallyFixedIn:t}),va=(e)=>{let{potentiallyFixedIn:t,...r}=e;return r},Aa=(e)=>{let t=e.appendix;if(!t)return e;let r=e.securityAlerts||e.options?.securityAlerts||[],n=!1,s={...t};if(Object.keys(s).forEach((i)=>{let o=s[i];if(!je(o))return;if(!o.ledger)return;let c=o.ledger.cves||[];if(c.length===0)return;let a=ba(r,c),u=o.ledger.potentiallyFixedIn,l=a?.patchedVersion;if(u===l)return;let p=l?Sa(o.ledger,l):va(o.ledger);s[i]={...o,ledger:p},n=!0}),!n)return e;return{...e,appendix:s}},ka=(e)=>{let t=e.finalAppendix||e.appendix||{},r=e.finalOverrides||e.overrides||{},n={...e,finalOverrides:r,finalAppendix:t};if(e.options?.removeUnused!==!0)return n;let i=dn(t,e.rootDeps),o=new Set(e.options?.skipRemovalKeys||[]),c=i.filter((g)=>!o.has(g));if(!(c.length>0))return n;let u=gn(c),l=(g)=>{let f=t[g]?.ledger?.cves;return Boolean(f?.length)},p=c.filter(l);if(p.length>0)e.log.warn(`Removing ${p.length} override(s) that had tracked CVEs: ${p.join(", ")}. Verify the base versions are not vulnerable.`,"stepRemoveUnused");e.log.debug(`Removing ${c.length} unused overrides: ${u.join(", ")}`,"stepRemoveUnused");let d=hn(t,c),h=fn(r,u);return{...n,finalOverrides:h,finalAppendix:d}},Oa=(e)=>{if(e.isTesting)return Object.assign({},e,{writeSkipped:!1,writeSuccess:!0});if(!e.config||e.finalAppendix===void 0||e.finalOverrides===void 0)return e.log.debug("No changes to write - missing required data","stepWriteResult"),Object.assign({},e,{writeSkipped:!0,writeSuccess:!1});return e.log.debug(`Writing results: appendix keys=${Object.keys(e.finalAppendix||{}).length}, override keys=${Object.keys(e.finalOverrides||{}).length}`,"stepWriteResult"),Cn({path:e.path,config:e.config,finalAppendix:e.finalAppendix,finalOverrides:e.finalOverrides,options:e.options,isTesting:e.isTesting}),Object.assign({},e,{writeSkipped:!1,writeSuccess:!0})},Pa=(e)=>{if(!e)return 0;return Object.keys(e).length},wa=(e,t)=>{if(!t)return 0;if(!e)return Object.keys(t).length;let r=new Set(Object.keys(e));return Object.keys(t).filter((i)=>!r.has(i)).length},Ta=(e,t)=>{let r=new Set(Object.keys(e||{})),n=new Set(Object.keys(t||{})),s=Array.from(n).filter((a)=>!r.has(a)).length,i=Array.from(r).filter((a)=>!n.has(a)),o=i.length,c=i.map((a)=>({packageName:a,version:String(e?.[a]||"")}));return{added:s,removed:o,removedPackages:c}},Ra=(e)=>{if(!e)return{critical:0,high:0,medium:0,low:0};return e.reduce((t,r)=>{let n=(r.severity||"medium").toLowerCase();return{critical:t.critical+(n==="critical"?1:0),high:t.high+(n==="high"?1:0),medium:t.medium+(n==="medium"?1:0),low:t.low+(n==="low"?1:0)}},{critical:0,high:0,medium:0,low:0})},Ca=(e)=>{let t=e.options,r=t?.outputFormat==="json";if(!Boolean(t&&(t.summary||r)))return 0;return Xr(e.root)},Ea=(e)=>{let t=Ca(e),r=Pa(e.allWorkspaceDeps),n=wa(e.existingAppendix,e.finalAppendix),s=e.options?.securityOverrideDetails||[],i=s.length,o=Ra(s),c=e.config?.overrides||e.config?.resolutions,a=Ta(c,e.finalOverrides),u=e.writeSuccess||!1,l=e.writeSkipped||!1,p={packagesScanned:t,workspacePackagesScanned:r,appendixEntriesUpdated:n,vulnerabilitiesBlocked:i,overridesAdded:a.added,overridesRemoved:a.removed,removedOverridePackages:a.removedPackages,severityCritical:o.critical,severityHigh:o.high,severityMedium:o.medium,severityLow:o.low,writeSuccess:u,writeSkipped:l};return Object.assign({},e,{metrics:p})},xa=(e,...t)=>{return t.reduce((r,n)=>n(r),e)},Ia=(e)=>{let t=!e.mode?.hasRootOverrides,r=e.mode?.mode==="root",n=Boolean(e.config);if(!(t&&r&&n))return e;return e.log.debug("No overrides found","update"),{...e,finalOverrides:{},finalAppendix:{}}},jd=(e)=>{let t=e?.path||"package.json",r=e?.root||"./",n=e?.isTesting||!1,s=_||e?.debug||!1,i=A({file:"update",isLogging:s});if(e?.clearCache===!0)Zr(),K.clear();if(!e.config)return i.debug("No config provided","update"),{options:e,path:t,root:r,isTesting:n,log:i};let c={options:e,path:t,root:r,isTesting:n,log:i,config:e.config,securityAlerts:e.securityAlerts},a=xa(c,ua,la,pa,da,Ia,ha,ga,Aa,fa,ma,ya,ka,Oa,Ea);if(_)a.log.debug("Update complete","update");return a};class Z extends Error{provider;originalMessage;constructor(e,t){let r=Z.getGuidance(t);super(`${e} security check skipped: ${t}. ${r}`);this.provider=e;this.originalMessage=t;this.name="SecurityProviderPermissionError"}static getGuidance(e){let t=e.toLowerCase(),r=t.includes("resource not accessible")||t.includes("must have admin"),n=t.includes("not enabled")||t.includes("disabled"),s=t.includes("not found");if(r)return"Add 'vulnerability-alerts: read' permission to your workflow or enable Dependabot alerts in repo settings.";if(n)return"Enable Dependabot alerts in Settings > Code security and analysis.";if(s)return"Verify the repository exists and you have access, or enable Dependabot alerts.";return"Check repository permissions and Dependabot settings."}}var x=30000,xn=120000,He=60000,Gt="https://github.com/settings/tokens",Ft="https://app.snyk.io/account",Mt="https://socket.dev/dashboard/api-keys",jt="https://spektion.com",La=`GitHub CLI not found and no GITHUB_TOKEN provided. Please install gh CLI or set GITHUB_TOKEN environment variable. Create a token at: ${Gt}`,$a=`Snyk requires authentication. Set SNYK_TOKEN or provide --securityProviderToken. Create a token at: ${Ft}`,Na=`Socket requires authentication. Set SOCKET_SECURITY_API_KEY or provide --securityProviderToken. Create an API key at: ${Mt}`,_a=`Spektion requires authentication. Set SPEKTION_API_KEY or provide --securityProviderToken. Get an API key at: ${jt}`,he={GITHUB_CLI_NOT_FOUND:La,SNYK_AUTH_REQUIRED:$a,SOCKET_AUTH_REQUIRED:Na,SPEKTION_AUTH_REQUIRED:_a},Va=q(Gt,"GitHub Tokens"),Da=q(Ft,"Snyk Account"),Ua=q(Mt,"Socket API Keys"),Ga=q(jt,"Spektion"),In=["github","snyk","socket","osv","npm","spektion"],Re={github:{name:"GitHub Dependabot",envVar:"GITHUB_TOKEN",tokenUrl:Gt,cliAlternative:"gh",requiredScopes:["repo","security_events"],setupSteps:[`1. Open ${Va}`,"2. Click 'Generate new token (classic)'","3. Name it 'pastoralist-security'","4. Select scopes: 'repo' and 'security_events'","5. Click 'Generate token' and copy it"]},snyk:{name:"Snyk",envVar:"SNYK_TOKEN",tokenUrl:Ft,setupSteps:[`1. Open ${Da}`,"2. Find 'Auth Token' section","3. Click to reveal and copy the token"]},socket:{name:"Socket.dev",envVar:"SOCKET_SECURITY_API_KEY",tokenUrl:Mt,setupSteps:[`1. Open ${Ua}`,"2. Create a new API key","3. Copy the key"]},osv:{name:"OSV (Open Source Vulnerabilities)",envVar:null,tokenUrl:null,setupSteps:["OSV is free and requires no authentication!"]},spektion:{name:"Spektion",envVar:"SPEKTION_API_KEY",tokenUrl:jt,setupSteps:[`1. Open ${Ga}`,"2. Create an account and generate an API key","3. Set SPEKTION_API_KEY in your environment"]}};var Fa="https://cli.github.com/",Ma="https://github.com/cli/cli/blob/trunk/docs/install_linux.md",ja=q(Fa,"cli.github.com"),Ka=q(Ma,"GitHub CLI Linux install guide"),X={READY:"GitHub CLI is installed and authenticated!",USING_CLI:"Using GitHub CLI for authentication",NOT_AUTHED:"GitHub CLI is installed but not authenticated.",AUTH_PROMPT:"Would you like to authenticate with GitHub CLI? (recommended)",NOT_INSTALLED:"GitHub CLI (gh) is not installed.",HOW_TO_AUTH:"How would you like to authenticate with GitHub?",OPT_INSTALL:"Install GitHub CLI (recommended)",OPT_TOKEN:"Use a Personal Access Token",OPT_SKIP:"Skip setup",SKIPPED:"Setup skipped",STARTING:"Starting GitHub CLI authentication...",BROWSER_INFO:"This will open a browser for you to authenticate.",SUCCESS:"GitHub CLI authenticated successfully!",VIA_CLI:"Authenticated via GitHub CLI",INCOMPLETE:"GitHub CLI authentication did not complete.",FAILED:"GitHub CLI auth failed",INSTALLING:"Installing GitHub CLI...",BREW_CMD:"Running: brew install gh",INSTALLED:"GitHub CLI installed!",INSTALL_FAILED:"Failed to install GitHub CLI automatically.",MANUAL_INSTALL:`Install manually: ${ja}`,LINUX_INSTALL:`Install manually: ${Ka}`},We={github:"https://api.github.com/user",snyk:"https://api.snyk.io/rest/self",socket:"https://api.socket.dev/v0/organizations"},Ye={BASE:"https://api.osv.dev/v1",QUERY:"https://api.osv.dev/v1/query",QUERY_BATCH:"https://api.osv.dev/v1/querybatch",VULN:(e)=>`https://api.osv.dev/v1/vulns/${e}`},Ln={SCAN:"https://api.spektion.com/v1/scan"},ze={critical:"critical",high:"high",medium:"medium",moderate:"medium",low:"low",info:"low"};class Ce{providerType="osv";debug;isIRLFix;isIRLCatch;strict;log;retryOptions;osvCache;constructor(e={}){this.debug=e.debug||!1,this.isIRLFix=e.isIRLFix||!1,this.isIRLCatch=e.isIRLCatch||!1,this.strict=e.strict||!1,this.log=A({file:"security/osv.ts",isLogging:this.debug}),this.retryOptions=e.retryOptions||{retries:3,factor:2,minTimeout:1000};let t=e.cacheTtl,n=t!==void 0?t*1000:U.OSV;this.osvCache=new E(M.OSV,{dir:e.cacheDir??R(),ttl:n,version:j.OSV,maxEntries:500,enabled:!(e.noCache??!1)})}async isAvailable(){try{return(await fetch(Ye.QUERY,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({package:{name:"test",ecosystem:"npm"}})})).ok}catch{return!1}}async fetchFromOSVBatchAPI(e){let t=e.map((o)=>({package:{name:o.name,ecosystem:"npm"},version:o.version})),r=await fetch(Ye.QUERY_BATCH,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({queries:t})});if(!r.ok)throw Error(`HTTP ${r.status}`);let s=(await r.json()).results||[];return await Promise.all(s.map(async(o)=>{let c=o?.vulns;if(!(c&&c.length>0))return o;return{vulns:await this.fetchFullVulnerabilityDetails(c)}}))}async fetchSingleVulnerability(e){let t=`osv:${e.id}`,r=this.osvCache.get(t);if(r)return r;let n=await fetch(Ye.VULN(e.id));if(!n.ok)throw Error(`HTTP ${n.status}`);let s=await n.json();return this.osvCache.set(t,s),s}async fetchFullVulnerabilityDetails(e){let r=e.reduce((i,o,c)=>{let a=Math.floor(c/5);return i[a]=i[a]||[],i[a].push(o),i},[]),n=async(i)=>{return(await Promise.allSettled(i.map((c)=>this.fetchSingleVulnerability(c)))).map((c,a)=>{if(c.status==="fulfilled")return c.value;let l=`Failed to fetch ${i[a].id}: ${c.reason}`;if(this.strict)throw Error(l);return this.log.debug(l,"fetchFullVulnerabilityDetails"),i[a]})};return await r.reduce(async(i,o)=>{let c=await i,a=await n(o);return c.concat(a)},Promise.resolve([]))}async fetchAlerts(e){if(this.log.debug(`OSV checking ${e.length} packages`,"fetchAlerts"),e.length===0)return[];let t=await Q(async()=>{return this.fetchFromOSVBatchAPI(e)},{...this.retryOptions,onFailedAttempt:(i)=>{this.log.debug(`Batch API attempt ${i.attemptNumber} failed`,"fetchAlerts")}}).catch((i)=>{this.log.debug("Failed to fetch batch results after retries","fetchAlerts",{error:i});let o=i instanceof Error?i.message:"Unknown error";if(this.strict)throw Error(`OSV security check failed after ${this.retryOptions.retries} retries. Reason: ${o}. Failing due to --strict mode.`);return this.log.warn(`OSV security check failed after ${this.retryOptions.retries} retries. Your dependencies were NOT checked for vulnerabilities. Reason: ${o}. Run with --debug for details or --strict to fail on errors.`,"fetchAlerts"),[]}),r=e.map((i,o)=>{let c=t[o];if(!(c?.vulns&&c.vulns.length>0))return[];return this.convertOSVAlerts(i,c.vulns)}).flat(),n=this.isIRLFix?[{packageName:"fake-pastoralist-check-2",currentVersion:"1.0.0",vulnerableVersions:"< 2.1.0",patchedVersion:"2.1.0",severity:"critical",title:"Critical vulnerability in fake-pastoralist-check-2 (transitive from fake-pastoralist-check-1)",cves:["CVE-FAKE-PASTORALIST-2024-0001"],fixAvailable:!0,description:"Fake critical security vulnerability in fake-pastoralist-check-2. Used by fake-pastoralist-check-1@1.0.0.",url:"https://example.com/fake-pastoralist-advisory-0001"}]:[],s=this.isIRLCatch?[{packageName:"fake-pastoralist-check-4",currentVersion:"0.5.0",vulnerableVersions:"< 1.0.0",patchedVersion:void 0,severity:"high",title:"High severity issue in fake-pastoralist-check-4 with no patch available",cves:["CVE-FAKE-PASTORALIST-2024-0002"],fixAvailable:!1,description:"Fake high severity vulnerability with no available patch for testing alert capture functionality.",url:"https://example.com/fake-pastoralist-advisory-0002"}]:[];return r.concat(n).concat(s)}convertOSVAlerts(e,t){return t.map((r)=>{let n=this.extractCVEs(r),s={packageName:e.name,currentVersion:e.version,vulnerableVersions:this.extractVersionRange(r),patchedVersion:this.extractPatchedVersion(r),severity:this.extractSeverity(r),title:r.summary||r.details||`Vulnerability in ${e.name}`,description:r.details,url:r.references?.[0]?.url||`https://osv.dev/vulnerability/${r.id}`,fixAvailable:!!this.extractPatchedVersion(r)};return n.length>0?{...s,cves:n}:s})}extractVersionRange(e){let r=e.affected?.[0]?.ranges?.[0]?.events;if(!r)return"";let n=r.find((o)=>o.introduced)?.introduced||"0",s=r.find((o)=>o.fixed)?.fixed;return s?`>= ${n} < ${s}`:`>= ${n}`}extractPatchedVersion(e){return(e.affected?.[0]?.ranges?.[0]?.events||[]).find((s)=>s.fixed)?.fixed}extractSeverity(e){let t=e.database_specific?.severity||e.severity?.[0]?.score||"medium";if(typeof t==="string"){let n=t.toLowerCase();if(["low","medium","high","critical"].includes(n))return n;let i=parseFloat(n);if(!isNaN(i))return this.cvssScoreToSeverity(i)}if(typeof t==="number")return this.cvssScoreToSeverity(t);return"medium"}cvssScoreToSeverity(e){let t=e>=9,r=e>=7,n=e>=4;if(t)return"critical";if(r)return"high";if(n)return"medium";return"low"}extractCVEs(e){return e.aliases?.filter((t)=>t.startsWith("CVE-"))||[]}}import{execFile as Ba}from"child_process";import{promisify as Ha}from"util";var Wa=Ha(Ba),Ya=30000,za=60000;class qe{providerType="github";owner;repo;token;log;execFileAsync=Wa;constructor(e){this.token=e.token||process.env.GITHUB_TOKEN,this.log=A({file:"github.ts",isLogging:e.debug}),this.log.debug(`Token provided: ${this.token?"yes (length: "+this.token.length+")":"no"}`,"constructor"),this.owner=e.owner||"",this.repo=e.repo||""}async initialize(){if(!this.owner)this.owner=await this.getRepoOwner();if(!this.repo)this.repo=await this.getRepoName()}async getRepoOwner(){let e={timeout:x};try{let t=["config","--get","remote.origin.url"],{stdout:r}=await this.execFileAsync("git",t,e),n=r.trim();if(this.isGitHubUrl(n)){let s=n.match(/github\.com[:/]([^/]+)\//);if(s)return s[1]}}catch{this.log.debug("Failed to get repo owner from git","getRepoOwner")}throw Error("Unable to determine GitHub repository owner")}async getRepoName(){let e={timeout:x};try{let t=["config","--get","remote.origin.url"],{stdout:r}=await this.execFileAsync("git",t,e),n=r.trim();if(this.isGitHubUrl(n)){let s=n.match(/github\.com[:/][^/]+\/([^/.]+)/);if(s)return s[1]}}catch{this.log.debug("Failed to get repo name from git","getRepoName")}throw Error("Unable to determine GitHub repository name")}isGitHubUrl(e){if(e.startsWith("git@github.com:"))return!0;try{return new URL(e).hostname==="github.com"}catch{return!1}}async fetchAlerts(){this.log.debug("Fetching GitHub Dependabot alerts","fetchAlerts");let e=await this.fetchDependabotAlerts();this.log.debug(`Found ${e.length} Dependabot alerts`,"fetchAlerts");let t=this.convertToSecurityAlerts(e);return this.log.debug(`Converted to ${t.length} security alerts`,"fetchAlerts"),t}async fetchDependabotAlerts(){if(await this.initialize(),this.isMockMode())return this.fetchMockAlerts();return this.fetchRealAlerts()}isMockMode(){return process.env[$e.MOCK_MODE]==="true"}async fetchRealAlerts(){if(this.token)return this.log.debug("Using GitHub API with provided token","fetchRealAlerts"),this.fetchAlertsWithApi();if(await this.isGhCliAvailable())return this.log.debug("Using gh CLI (no token provided)","fetchRealAlerts"),this.fetchAlertsWithGhCli();throw Error(he.GITHUB_CLI_NOT_FOUND)}async fetchMockAlerts(){if(this.log.debug("Using mock Dependabot alerts","fetchMockAlerts"),this.shouldForceVulnerable())return this.getMockVulnerableAlerts();return[]}shouldForceVulnerable(){return process.env[$e.FORCE_VULNERABLE]==="true"}async getMockVulnerableAlerts(){let e=process.env[$e.MOCK_FILE];if(e){let t=await this.loadMockFile(e);if(t)return t}return this.getDefaultMockAlerts()}async loadMockFile(e){try{let{readFileSync:t}=await import("fs"),r=t(e,"utf-8");return JSON.parse(r)}catch(t){return this.log.debug("Failed to read mock file","loadMockFile",{error:t}),null}}getDefaultMockAlerts(){return[{number:1,state:"open",url:"https://mock.url",html_url:"https://mock.url",created_at:"2021-01-01T00:00:00Z",updated_at:"2021-01-01T00:00:00Z",dependency:{package:{ecosystem:"npm",name:"lodash"},manifest_path:"package.json",scope:"runtime"},security_advisory:{severity:"high",summary:"Mock vulnerability in lodash",description:"Mock description",vulnerabilities:[{package:{ecosystem:"npm",name:"lodash"},vulnerable_version_range:"< 4.17.21",first_patched_version:{identifier:"4.17.21"}}]},security_vulnerability:{package:{ecosystem:"npm",name:"lodash"},severity:"high",vulnerable_version_range:"< 4.17.21",first_patched_version:{identifier:"4.17.21"}}},{number:2,state:"open",url:"https://mock.url",html_url:"https://mock.url",created_at:"2021-01-01T00:00:00Z",updated_at:"2021-01-01T00:00:00Z",dependency:{package:{ecosystem:"npm",name:"minimist"},manifest_path:"package.json",scope:"runtime"},security_advisory:{severity:"medium",summary:"Mock vulnerability in minimist",description:"Mock description",vulnerabilities:[{package:{ecosystem:"npm",name:"minimist"},vulnerable_version_range:"< 1.2.6",first_patched_version:{identifier:"1.2.6"}}]},security_vulnerability:{package:{ecosystem:"npm",name:"minimist"},severity:"medium",vulnerable_version_range:"< 1.2.6",first_patched_version:{identifier:"1.2.6"}}}]}async isGhCliAvailable(){let e={timeout:x};try{return await this.execFileAsync("gh",["--version"],e),!0}catch{return!1}}async executeGhCli(){let e=["api",`repos/${this.owner}/${this.repo}/dependabot/alerts`,"--paginate"];this.log.debug(`Fetching alerts with gh CLI: gh ${e.join(" ")}`,"executeGhCli");let t={timeout:za},{stdout:r}=await this.execFileAsync("gh",e,t);return this.log.debug(`gh CLI stdout length: ${r.length}`,"executeGhCli"),r}async fetchAlertsWithGhCli(){try{let e=await Q(()=>this.executeGhCli(),{retries:3,factor:2,minTimeout:1000,onFailedAttempt:(n)=>{let s=String(n);if(this.isPermissionError(s))throw new Z("GitHub CLI",s);this.log.debug(`gh CLI attempt ${n.attemptNumber} failed`,"fetchAlertsWithGhCli")}}),t=JSON.parse(e),r=Array.isArray(t)?t.length:"non-array";return this.log.debug(`Parsed ${r} alerts`,"fetchAlertsWithGhCli"),Array.isArray(t)?t:[]}catch(e){if(e instanceof Z)throw e;let r=String(e);if(this.isPermissionError(r))throw new Z("GitHub CLI",r);throw this.log.error("Failed to fetch alerts with gh CLI","fetchAlertsWithGhCli",{error:e}),Error(`Failed to fetch Dependabot alerts: ${e}`)}}isPermissionError(e){return["Resource not accessible by integration","Must have admin rights","Not Found","Dependabot alerts are not enabled","vulnerability alerts are disabled"].some((r)=>e.toLowerCase().includes(r.toLowerCase()))}async fetchFromGitHubAPI(){let e=`https://api.github.com/repos/${this.owner}/${this.repo}/dependabot/alerts`,t=new AbortController,r=setTimeout(()=>t.abort(),Ya);try{let n=await fetch(e,{headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github.v3+json"},signal:t.signal});if(!n.ok){let o=(await n.json()).message||n.statusText;if(this.isPermissionError(o))throw new Z("GitHub",o);throw Error(`GitHub API error: ${o}`)}let s=await n.json();return Array.isArray(s)?s:[]}finally{clearTimeout(r)}}async fetchAlertsWithApi(){try{return await Q(()=>this.fetchFromGitHubAPI(),{retries:3,factor:2,minTimeout:1000,onFailedAttempt:(e)=>{if(e.name==="SecurityProviderPermissionError")throw e;this.log.debug(`GitHub API attempt ${e.attemptNumber} failed`,"fetchAlertsWithApi")}})}catch(e){if(e instanceof Z)throw e;throw this.log.error("Failed to fetch alerts with API","fetchAlertsWithApi",{error:e}),Error(`Failed to fetch Dependabot alerts: ${e}`)}}convertToSecurityAlerts(e){return e.filter((t)=>t.state==="open").map((t)=>{let{security_vulnerability:r,security_advisory:n}=t,s=this.extractCurrentVersion(t),i=n.cve_id?[n.cve_id]:[],o={packageName:r.package.name,currentVersion:s,vulnerableVersions:r.vulnerable_version_range,patchedVersion:r.first_patched_version?.identifier,severity:this.normalizeSeverity(r.severity),title:n.summary,description:n.description,url:t.html_url,fixAvailable:!!r.first_patched_version};return i.length>0?{...o,cves:i}:o})}extractCurrentVersion(e){let t=e.security_vulnerability.vulnerable_version_range;if(t.includes(">=")&&t.includes("<=")){let r=t.match(/>= ?([^\s,]+)/);return r?r[1]:"unknown"}if(t.includes(">=")){let r=t.match(/>= ?([^\s,]+)/);return r?r[1]:"unknown"}return"unknown"}normalizeSeverity(e){let t=e.toLowerCase();switch(t){case"low":case"medium":case"high":case"critical":return t;default:return"medium"}}}import{execFile as nu}from"child_process";import{promisify as su}from"util";import{execFile as qa}from"child_process";import{promisify as Ja}from"util";import*as Vn from"readline/promises";var Je=Ja(qa),ie=(e)=>{return{low:1,medium:2,high:3,critical:4}[e.toLowerCase()]||0},$n=(e,t)=>{let r=[...e.sources||[],...t.sources||[]];return[...new Set(r)]},Dn=(e)=>{let t=e.reduce((r,n)=>{let s=`${n.packageName}@${n.currentVersion}:${n.cves?.[0]||n.title}`,i=r.get(s);if(!i||ie(n.severity)>ie(i.severity)){let c=i?[...new Set([...i.cves||[],...n.cves||[]])]:n.cves,a=i?$n(i,n):n.sources,u=c&&c.length>0?{cves:c}:{},l=a&&a.length>0?{sources:a}:{};r.set(s,{...n,...u,...l})}else if(i){let c=[...i.cves||[],...n.cves||[]],a=[...new Set(c)],u=$n(i,n),l=a.length>0?{cves:a}:{},p=u.length>0?{sources:u}:{};r.set(s,{...i,...l,...p})}return r},new Map);return Array.from(t.values())},Nn=(e)=>e.length>=2?"confirmed":"possible",_n={confirmed:2,possible:1},Un=(e)=>[...e].sort((t,r)=>{let n=t.sources??[],s=r.sources??[],i=_n[Nn(n)],o=_n[Nn(s)],c=ie(t.severity)*i;return ie(r.severity)*o-c}),Gn=(e,t=[])=>{let r=Object.assign({},e.dependencies,e.devDependencies,e.peerDependencies);return Object.entries(r).filter(([n])=>!t.includes(n)).map(([n,s])=>({name:n,version:s.replace(/^[\^~]/,"")}))},Qa=(e,t)=>{if(!(t.includes(">=")&&t.includes("<")))return null;let[,n]=t.match(/>= ?([^\s,]+)/)||[],[,s]=t.match(/< ?([^\s,]+)/)||[];if(!Boolean(n&&s))return null;return T(e,n)>=0&&T(e,s)<0},Za=(e,t)=>{if(!t.startsWith("<="))return null;let n=t.replace(/<= ?/,"");return T(e,n)<=0},Xa=(e,t)=>{if(!(t.startsWith("<")&&!t.startsWith("<=")))return null;let n=t.replace(/< ?/,"");return T(e,n)<0},eu=(e,t)=>{if(!(t.startsWith(">=")&&!t.includes("<")))return null;let n=t.replace(/>= ?/,"");return T(e,n)>=0},Kt=(e,t)=>{try{let r=e.replace(/^[\^~]/,"");return Qa(r,t)??eu(r,t)??Za(r,t)??Xa(r,t)??!1}catch{return!1}},Fn=(e,t,r,n)=>{let s=n.filter((a)=>a.packageName===e&&a.vulnerableVersions);if(!(s.length>0))return{skip:!1,targetStillVulnerable:!1};let o=s.filter((a)=>Kt(t,a.vulnerableVersions)).length,c=s.filter((a)=>Kt(r,a.vulnerableVersions)).length;return{skip:c>=o,targetStillVulnerable:c>0}},Mn=(e,t)=>{let r={...e.dependencies,...e.devDependencies,...e.peerDependencies};return t.filter((n)=>{let s=r[n.packageName];return Boolean(s)&&Kt(s,n.vulnerableVersions)}).map((n)=>({...n,currentVersion:r[n.packageName]}))};class Ee{log;constructor(e={}){this.log=A({file:"security/cli-installer.ts",isLogging:e.debug})}async isInstalled(e){let t={timeout:x};try{return await Je("which",[e],t),!0}catch{return!1}}async isInstalledGlobally(e){let t={timeout:x},r=["list","-g",e,"--depth=0"];try{let{stdout:n}=await Je("npm",r,t);return n.includes(e)}catch{return!1}}async installGlobally(e){this.log.print(`Installing ${e} globally...`);let t={timeout:xn};try{await Je("npm",["install","-g",e],t),this.log.print(`Successfully installed ${e}`)}catch(r){throw this.log.error(`Failed to install ${e}`,"installGlobally",{error:r}),Error(`Failed to install ${e}: ${r}`)}}async ensureInstalled(e){let{packageName:t,cliCommand:r}=e;if(await this.isInstalled(r))return this.log.debug(`${r} is already installed`,"ensureInstalled"),!0;if(await this.isInstalledGlobally(t))return this.log.debug(`${t} is installed globally but command not in PATH`,"ensureInstalled"),!0;this.log.print(`${r} not found, installing ${t}...`);try{if(await this.installGlobally(t),!await this.isInstalled(r))return this.log.print(`${t} was installed but ${r} is still not available. Please ensure it's in your PATH.`),!1;return!0}catch(i){return this.log.error(`Could not install ${t}`,"ensureInstalled",{error:i}),!1}}async getVersion(e){let t={timeout:x};try{let{stdout:r}=await Je(e,["--version"],t);return r.trim()}catch{return}}}var Bt=()=>{return Vn.createInterface({input:process.stdin,output:process.stdout})},Ht=async(e,t,r)=>{return new Promise((n,s)=>{let i=setTimeout(()=>{e.close(),s(Error("Prompt timed out"))},r);e.question(t).then((o)=>{clearTimeout(i),n(o)}).catch((o)=>{clearTimeout(i),s(o)})})},tu=(e)=>{if(e)return`${b("Y")}/n`;return`y/${b("N")}`},Qe=async(e,t=!0)=>{let r=Bt(),n=tu(t),s=`${b("?")} ${e} (${n}): `;try{let i=await Ht(r,s,He);r.close();let o=i.trim();if(o==="")return t;return o.toLowerCase().startsWith("y")}catch{return r.close(),t}},Wt=async(e,t)=>{let r=Bt(),n=t[0]?.value||"";console.log(`${b("?")} ${e}`),t.forEach((a,u)=>{let l=b(`${u+1})`);console.log(`  ${l} ${a.name}`)});let s=`${O("Select")} (1-${t.length}): `,i=null,o=0,c=5;while(i===null&&o<c){o++;try{let a=await Ht(r,s,He),u=parseInt(a.trim(),10);if(u>=1&&u<=t.length)i=t[u-1].value;else console.log("Invalid selection. Please try again.")}catch{return r.close(),n}}return r.close(),i||n},ru=(e,t)=>{if(t!=="")return`${b("?")} ${e} (${O(t)}): `;return`${b("?")} ${e}: `},Yt=async(e,t="")=>{let r=Bt(),n=ru(e,t);try{let s=await Ht(r,n,He);return r.close(),s.trim()||t}catch{return r.close(),t}};class zt{prompts;constructor(e={confirm:Qe,select:Wt,input:Yt}){this.prompts=e}async promptForSecurityActions(e,t){if(e.length===0)return[];console.log(`
Security Vulnerabilities Found
`),console.log("═".repeat(50));let r=this.generateSummary(e);if(console.log(r),!await this.prompts.confirm("Would you like to review and apply security fixes?",!0))return[];let s=[];for(let o of t){let c=e.find((u)=>u.packageName===o.packageName);if(!c)continue;if(console.log(`
${o.packageName}`),console.log(`   Current: ${o.fromVersion}`),console.log(`   ${this.getSeverityEmoji(c.severity)} ${c.title}`),c.cves&&c.cves.length>0)console.log(`   CVE: ${c.cves.join(", ")}`);let a=await this.prompts.select("How would you like to handle this vulnerability?",[{name:`Apply fix: Update to ${o.toVersion}`,value:"apply"},{name:"Skip this vulnerability",value:"skip"},{name:"Enter custom version",value:"custom"}]);if(a==="apply")s.push(o);else if(a==="custom"){let u=await this.prompts.input("Enter the version to use:",o.toVersion);s.push(Object.assign({},o,{toVersion:u}))}}if(s.length>0){if(console.log(`
Selected Overrides:
`),s.forEach((c)=>{console.log(`  ${c.packageName}: ${c.fromVersion} → ${c.toVersion}`)}),!await this.prompts.confirm("Apply these overrides to your package.json?",!0))return[]}return s}generateSummary(e){let t=e.reduce((n,s)=>{return n[s.severity]++,n},{critical:0,high:0,medium:0,low:0}),r=`Found ${e.length} vulnerable package(s):
`;if(t.critical>0)r+=`  ${V("[CRITICAL]")} ${t.critical}
`;if(t.high>0)r+=`  ${V("[HIGH]    ")} ${t.high}
`;if(t.medium>0)r+=`  ${k("[MEDIUM]  ")} ${t.medium}
`;if(t.low>0)r+=`  ${b("[LOW]     ")} ${t.low}
`;return r}getSeverityEmoji(e){switch(e.toLowerCase()){case"critical":return V("[!]");case"high":return V("[!]");case"medium":return k("[*]");case"low":return b("[i]");default:return O("[*]")}}}var jn=su(nu),iu=60000;class Ze{providerType="snyk";log;installer;token;strict;constructor(e={}){this.log=A({file:"security/snyk.ts",isLogging:e.debug||!1}),this.installer=new Ee({debug:e.debug}),this.token=e.token||process.env.SNYK_TOKEN,this.strict=e.strict||!1,this.log.warn("Snyk provider is EXPERIMENTAL. Report issues at https://github.com/yowainwright/pastoralist/issues","constructor")}async ensureInstalled(){return this.installer.ensureInstalled({packageName:"snyk",cliCommand:"snyk"})}async isAuthenticated(){if(!this.token){let e={timeout:x};try{return await jn("snyk",["config","get","api"],e),!0}catch{return!1}}return!0}async authenticate(){if(!Boolean(this.token))throw Error(he.SNYK_AUTH_REQUIRED);this.log.debug("Authenticated with Snyk using environment variable","authenticate")}async validatePrerequisites(){if(!await this.ensureInstalled())return this.log.print("Snyk CLI not available, skipping Snyk scan"),!1;if(!await this.isAuthenticated())try{return await this.authenticate(),!0}catch{return this.log.print("Snyk authentication failed, skipping Snyk scan"),!1}return!0}async runSnykScan(){let e=this.token?{...process.env,SNYK_TOKEN:this.token}:process.env,t={timeout:iu,env:e},{stdout:r}=await jn("snyk",["test","--json"],t);return JSON.parse(r)}async fetchAlerts(){if(!await this.validatePrerequisites())return[];try{let t=await this.runSnykScan();return this.convertSnykVulnerabilities(t)}catch(t){let r=t;if(r.stdout)try{let i=JSON.parse(r.stdout);return this.convertSnykVulnerabilities(i)}catch{this.log.debug("Failed to parse Snyk error output","fetchAlerts",{error:t})}this.log.debug("Snyk scan failed","fetchAlerts",{error:t});let s=t instanceof Error?t.message:"Unknown error";if(this.strict)throw Error(`Snyk security check failed. Reason: ${s}. Failing due to --strict mode.`);return this.log.warn(`Snyk security check failed. Your dependencies were NOT checked. Reason: ${s}. Run with --debug for details or --strict to fail on errors.`,"fetchAlerts"),[]}}convertSnykVulnerabilities(e){if(!e.vulnerabilities||!Array.isArray(e.vulnerabilities))return[];return e.vulnerabilities.map((t)=>this.convertVulnToAlert(t))}convertVulnToAlert(e){let t=e.packageName||e.name||"",r=e.version,n=e.semver?.vulnerable||"",s=this.extractPatchedVersion(e),i=this.normalizeSeverity(e.severity),o=e.title,c=e.description,a=e.identifiers?.CVE||[],u=e.url||`https://snyk.io/vuln/${e.id}`,p={packageName:t,currentVersion:r,vulnerableVersions:n,patchedVersion:s,severity:i,title:o,description:c,url:u,fixAvailable:!!s};return a.length>0?{...p,cves:a}:p}extractPatchedVersion(e){if(e.fixedIn&&e.fixedIn.length>0)return e.fixedIn[0];if(e.upgradePath&&e.upgradePath.length>1){let t=e.upgradePath[e.upgradePath.length-1];if(typeof t==="string")return t.split("@")[1]}return}normalizeSeverity(e){let t=e.toLowerCase();switch(t){case"low":case"medium":case"high":case"critical":return t;default:return"medium"}}}import{execFile as ou}from"child_process";import{promisify as cu}from"util";var au=cu(ou);class Xe{providerType="socket";log;installer;token;strict;constructor(e={}){this.log=A({file:"security/socket.ts",isLogging:e.debug||!1}),this.installer=new Ee({debug:e.debug}),this.token=e.token||process.env.SOCKET_SECURITY_API_KEY,this.strict=e.strict||!1,this.log.warn("Socket provider is EXPERIMENTAL. Report issues at https://github.com/yowainwright/pastoralist/issues","constructor")}async ensureInstalled(){return this.installer.ensureInstalled({packageName:"@socketsecurity/cli",cliCommand:"socket"})}async isAuthenticated(){return!!this.token}async validatePrerequisites(){if(!await this.ensureInstalled())return this.log.print("Socket CLI not available, skipping Socket scan"),!1;if(!await this.isAuthenticated())return this.log.print(he.SOCKET_AUTH_REQUIRED),!1;return!0}async runSocketScan(){let e={...process.env,SOCKET_SECURITY_API_KEY:this.token},{stdout:t}=await au("socket",["report","create","--format","json"],{timeout:60000,env:e});return JSON.parse(t)}async fetchAlerts(){if(!await this.validatePrerequisites())return[];try{let t=await this.runSocketScan();return this.convertSocketAlerts(t)}catch(t){this.log.debug("Socket scan failed","fetchAlerts",{error:t});let r=t instanceof Error?t.message:"Unknown error";if(this.strict)throw Error(`Socket security check failed. Reason: ${r}. Failing due to --strict mode.`);return this.log.warn(`Socket security check failed. Your dependencies were NOT checked. Reason: ${r}. Run with --debug for details or --strict to fail on errors.`,"fetchAlerts"),[]}}convertSocketAlerts(e){if(!e?.packages)return[];return e.packages.filter((t)=>t.issues&&t.issues.length>0).flatMap((t)=>t.issues.map((r)=>this.convertIssueToAlert(t,r)))}convertIssueToAlert(e,t){let r=t.type==="vulnerability",n=e.name,s=e.version,i=r?`<= ${s}`:"",o=void 0,c=this.mapSocketSeverity(t.severity),a=t.title||t.type,u=t.description,l=r&&t.cve?[t.cve]:[],p=t.url||`https://socket.dev/npm/package/${n}/overview/${s}`,d=!1,h={packageName:n,currentVersion:s,vulnerableVersions:i,patchedVersion:void 0,severity:c,title:a,description:u,url:p,fixAvailable:!1};return l.length>0?{...h,cves:l}:h}mapSocketSeverity(e){switch(e.toLowerCase()){case"critical":return"critical";case"high":return"high";case"medium":case"moderate":return"medium";case"low":case"info":return"low";default:return"medium"}}}var uu=(e)=>ze[e.toLowerCase()]??"medium",lu=(e)=>{if(!e||typeof e!=="object")return null;let t=e,r=t.patchedVersion?String(t.patchedVersion):void 0;return{packageName:String(t.package??""),currentVersion:String(t.version??""),vulnerableVersions:t.vulnerableRange?String(t.vulnerableRange):"",patchedVersion:r,severity:uu(String(t.severity??"")),title:String(t.title??t.description??"Vulnerability"),description:t.description?String(t.description):void 0,cves:t.cve?[String(t.cve)]:void 0,url:t.url?String(t.url):void 0,fixAvailable:Boolean(r)}},pu=(e)=>{if(!e||typeof e!=="object")return[];let t=e;if(!Array.isArray(t.vulnerabilities))return[];return t.vulnerabilities.map(lu).filter((r)=>r!==null)},du=async(e,t)=>{let r=await fetch(Ln.SCAN,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({packages:t})});if(!r.ok)throw Error(`HTTP ${r.status}`);let n=await r.json();return pu(n)};class et{providerType="spektion";log;token;strict;constructor(e={}){this.log=A({file:"security/spektion.ts",isLogging:e.debug||!1}),this.token=e.token||process.env.SPEKTION_API_KEY,this.strict=e.strict||!1,this.log.debug("SpektionProvider initialized (experimental)","constructor")}async isAuthenticated(){return Boolean(this.token)}async fetchAlerts(e){if(!this.token)return this.log.print("Spektion requires authentication. Set SPEKTION_API_KEY or provide --securityProviderToken."),[];try{return await du(this.token,e)}catch(t){let r=t instanceof Error?t.message:"Unknown error";if(this.strict)throw Error(`Spektion security check failed. Reason: ${r}. Failing due to --strict mode.`);return this.log.warn(`Spektion security check failed. Your dependencies were NOT checked. Reason: ${r}. Run with --debug for details or --strict to fail on errors.`,"fetchAlerts"),[]}}}import{execFile as hu}from"child_process";import{promisify as gu}from"util";var fu=120000;class tt{providerType="npm";log;strict;exec=gu(hu);constructor(e={}){this.log=A({file:"security/package-manager-audit.ts",isLogging:e.debug||!1}),this.strict=e.strict||!1}async fetchAlerts(e){if(e.length===0)return[];let t=le();try{let r=await this.runAudit(t);return this.enrichWithVersions(r,e)}catch(r){let n=r instanceof Error?r.message:"Unknown error";if(this.strict)throw Error(`Package manager audit failed (${t}). Reason: ${n}. Failing due to --strict mode.`);return this.log.warn(`Package manager audit failed (${t}). Dependencies NOT checked via ${t} audit. Reason: ${n}. Run with --debug for details or --strict to fail on errors.`,"fetchAlerts"),[]}}enrichWithVersions(e,t){let r=new Map(t.map((n)=>[n.name,n.version]));return e.map((n)=>{let s=r.get(n.packageName);return s?{...n,currentVersion:s}:null}).filter((n)=>n!==null)}async runAudit(e){let t={timeout:fu};if(e==="yarn"){let{stdout:i}=await this.exec("yarn",["audit","--json"],t).catch((o)=>{if(Boolean(o.stdout))return{stdout:o.stdout};throw o});return this.parseYarnAuditOutput(i)}let r=e==="bun"?"bun":e,{stdout:n}=await this.exec(r,["audit","--json"],t).catch((i)=>{if(Boolean(i.stdout))return{stdout:i.stdout};throw i}),s=JSON.parse(n);return this.parseNpmCompatibleOutput(s)}parseNpmCompatibleOutput(e){if(!Boolean(e?.vulnerabilities))return[];return Object.values(e.vulnerabilities).flatMap((r)=>{return r.via.filter((s)=>typeof s==="object"&&s!==null).map((s)=>{let i=this.extractNpmPatchedVersion(r.fixAvailable);return{packageName:r.name,currentVersion:"",vulnerableVersions:s.range||r.range,patchedVersion:i,severity:this.normalizeSeverity(s.severity),title:s.title,url:s.url,fixAvailable:Boolean(i)}})})}parseYarnAuditOutput(e){return e.split(`
`).filter(Boolean).map((r)=>{try{return JSON.parse(r)}catch{return null}}).filter((r)=>r?.type==="auditAdvisory").flatMap(({data:r})=>{let{advisory:n}=r;if(!n)return[];let s=this.extractYarnPatchedVersion(n.patched_versions),i={packageName:n.module_name,currentVersion:"",vulnerableVersions:n.vulnerable_versions,patchedVersion:s,severity:this.normalizeSeverity(n.severity),title:n.title,url:n.url,fixAvailable:Boolean(s)},o=n.cves&&n.cves.length>0?{cves:n.cves}:{};return[{...i,...o}]})}extractNpmPatchedVersion(e){if(!(typeof e==="object"&&e!==null))return;return e.version}extractYarnPatchedVersion(e){if(!e||e==="<0.0.0"||e==="No fix available")return;return e.match(/>=\s*([\d.]+)/)?.[1]}normalizeSeverity(e){return ze[e.toLowerCase()]||"medium"}}import{execFile as mu,spawn as yu}from"child_process";import{promisify as bu}from"util";import{existsSync as Su,readFileSync as vu,appendFileSync as Au}from"fs";import{homedir as ku}from"os";import{join as qt}from"path";var ge=bu(mu),Jt=()=>({log:(e)=>process.stdout.write(`${e}
`),success:(e)=>process.stdout.write(`${w("[OK]")} ${e}
`),warn:(e)=>process.stdout.write(`${k("[WARN]")} ${e}
`),error:(e)=>process.stdout.write(`${V("[FAIL]")} ${e}
`),info:(e)=>process.stdout.write(`${O(e)}
`)});class xe{log;prompts;skipBrowserOpen;out;constructor(e={}){this.log=A({file:"security/setup.ts",isLogging:e.debug}),this.prompts={confirm:Qe,select:Wt,input:Yt},this.skipBrowserOpen=e.skipBrowserOpen||!1,this.out=Jt()}async checkTokenAvailable(e){let t=Re[e];if(!t.envVar)return!0;let n=t.envVar;if(!!process.env[n])return!0;if(!(e==="github"&&t.cliAlternative))return!1;return this.isGhCliAuthenticated()}async isGhCliAuthenticated(){try{return await ge("gh",["auth","status"],{timeout:x}),!0}catch{return!1}}printSetupHeader(e){let t=b("=".repeat(50)),r=b("Security Provider Setup:");this.out.log(`
${t}`),this.out.log(`${r} ${e}`),this.out.log(`${t}
`)}async runSetup(e){let t=Re[e];if(this.printSetupHeader(t.name),!t.envVar)return{success:!0,message:"OSV requires no setup - you're good to go!"};let n=await this.checkExistingToken(e,t);if(n)return n;let s=await this.tryGitHubCliIfApplicable(e);if(s)return s;return this.runTokenSetup(e,t)}async checkExistingToken(e,t){let r=process.env[t.envVar];if(!r)return null;if(!await this.validateToken(e,r))return this.out.warn(`Existing ${t.envVar} appears invalid or expired.
`),null;return{success:!0,token:r,message:`${t.envVar} is already configured and working!`}}async tryGitHubCliIfApplicable(e){if(e!=="github")return null;let r=await this.tryGitHubCliSetup();if(!r.success)return null;return r}async tryGitHubCliSetup(){if(!await this.isCommandAvailable("gh"))return this.handleMissingGhCli();if(await this.isGhCliAuthenticated())return this.out.success(`GitHub CLI is installed and authenticated!
`),{success:!0,usedCli:!0,message:"Using GitHub CLI for authentication"};if(this.out.log(`GitHub CLI is installed but not authenticated.
`),!await this.prompts.confirm("Would you like to authenticate with GitHub CLI? (recommended)",!0))return{success:!1,message:"Proceeding with token setup"};return this.runGhAuth()}async handleMissingGhCli(){this.out.log(`GitHub CLI (gh) is not installed.
`);let e=await this.prompts.select("How would you like to authenticate with GitHub?",[{name:"Install GitHub CLI (recommended)",value:"install-gh"},{name:"Use a Personal Access Token",value:"token"},{name:"Skip setup",value:"skip"}]);if(e==="install-gh")return this.installAndAuthGh();if(e==="skip")return{success:!1,message:"Setup skipped"};return{success:!1,message:"Proceeding with token setup"}}async runGhAuth(){this.out.log(`
Starting GitHub CLI authentication...
`),this.out.info(`This will open a browser for you to authenticate.
`);try{if(await this.spawnGhAuth(),await this.isGhCliAuthenticated())return this.out.success(`GitHub CLI authenticated successfully!
`),{success:!0,usedCli:!0,message:"Authenticated via GitHub CLI"}}catch(e){this.log.debug("gh auth failed","runGhAuth",{error:e})}return this.out.warn(`GitHub CLI authentication did not complete.
`),{success:!1,message:"GitHub CLI auth failed"}}spawnGhAuth(){return new Promise((e,t)=>{let r=yu("gh",["auth","login","--web","-h","github.com"],{stdio:"inherit"});r.on("close",(n)=>{if(n===0)e();else t(Error(`gh auth exited with code ${n}`))}),r.on("error",t)})}async installAndAuthGh(){let e=process.platform,t=e==="linux",r=e==="darwin",n="Manual gh install required";if(this.out.log(`
`+X.INSTALLING+`
`),t)return this.out.warn(X.LINUX_INSTALL),{success:!1,message:"Manual gh install required"};if(!r)return this.out.warn(X.MANUAL_INSTALL),{success:!1,message:"Manual gh install required"};try{return this.out.info(X.BREW_CMD+`
`),await ge("brew",["install","gh"],{timeout:120000}),this.out.success(X.INSTALLED+`
`),this.runGhAuth()}catch(s){return this.log.debug("gh install failed","installAndAuthGh",{error:s}),this.out.warn(X.INSTALL_FAILED+`
`),this.out.log(X.MANUAL_INSTALL),{success:!1,message:"gh install failed"}}}async runTokenSetup(e,t){if(this.out.log(`
To use ${t.name}, you'll need an API token.
`),t.setupSteps.forEach((h)=>this.out.log(`  ${h}`)),!!t.requiredScopes)this.out.log(`
  Required scopes: ${t.requiredScopes.join(", ")}`);if(this.out.log(""),t.tokenUrl&&!this.skipBrowserOpen){if(await this.prompts.confirm(`Open ${t.tokenUrl} in your browser?`,!0))await this.openUrl(t.tokenUrl),this.out.info(`
Browser opened. Create your token there.
`)}this.out.info(`Tip: The token will be hidden as you type for security.
`);let s=await this.prompts.input(`Paste your ${t.name} token here`);if(!s)return{success:!1,message:"No token provided"};if(this.out.log(`
Validating token...`),!await this.validateToken(e,s))return this.handleInvalidToken(t);this.out.success(`Token is valid!
`),this.out.warn("Note: This saves the token as plaintext in your shell profile.");let a=await this.prompts.confirm("Save token to your shell profile for future use?",!1)?await this.saveToShellProfile(t.envVar,s):!1;process.env[t.envVar]=s;let u=`${s.slice(0,8)}...`,l=`Token set for this session. Set ${t.envVar}=${u} in your environment to persist.`;return{success:!0,token:s,savedToProfile:a,message:a?"Token saved to shell profile. Restart your terminal or run 'source ~/.zshrc' to use it globally.":l}}handleInvalidToken(e){if(this.out.error(`Token validation failed.
`),this.out.log("Please check that:"),this.out.log("  - The token was copied correctly"),this.out.log("  - The token has the required permissions"),!!e.requiredScopes)this.out.log(`  - Scopes include: ${e.requiredScopes.join(", ")}`);return{success:!1,message:"Token validation failed"}}async validateToken(e,t){try{if(e==="github")return this.validateGitHubToken(t);if(e==="snyk")return this.validateSnykToken(t);if(e==="socket")return this.validateSocketToken(t);return!0}catch(r){return this.log.debug("Token validation error","validateToken",{error:r}),!1}}async validateGitHubToken(e){try{return(await fetch(We.github,{headers:{Authorization:`Bearer ${e}`,Accept:"application/vnd.github.v3+json"}})).ok}catch{return!1}}async validateSnykToken(e){try{let t=await fetch(We.snyk,{headers:{Authorization:`token ${e}`}}),r=t.ok,n=t.status===404;return r||n}catch{return!1}}async validateSocketToken(e){try{let t=Buffer.from(`${e}:`).toString("base64");return(await fetch(We.socket,{headers:{Authorization:`Basic ${t}`}})).ok}catch{return!1}}async isCommandAvailable(e){try{return await ge("which",[e],{timeout:x}),!0}catch{return!1}}async openUrl(e){let t=process.platform,r=t==="darwin",n=t==="linux",s=t==="win32";try{if(r){await ge("open",[e]);return}if(n){await ge("xdg-open",[e]);return}if(s){await ge("cmd",["/c","start",e]);return}}catch(i){this.log.debug("Failed to open URL","openUrl",{error:i})}this.out.log(`Please open manually: ${e}`)}async saveToShellProfile(e,t){let r=ku(),n=[".zshrc",".bashrc",".bash_profile"],s=this.findShellProfile(r,n);try{let i=vu(s,"utf-8"),o=`export ${e}=`;if(i.includes(o))return this.out.warn(`${e} already exists in ${s}. Skipping.`),this.out.log(`To update it, edit ${s} manually.`),!1;let a=`
# Added by pastoralist
export ${e}="${t}"
`;return Au(s,a),this.out.success(`Added ${e} to ${s}
`),!0}catch(i){return this.log.debug("Failed to save to profile","saveToShellProfile",{error:i}),this.out.warn(`Couldn't write to ${s}.`),this.out.log("Add this to your shell profile manually:"),this.out.log(`  export ${e}="${t}"`),!1}}findShellProfile(e,t){let r=t.find((s)=>Su(qt(e,s))),n=qt(e,".zshrc");return r?qt(e,r):n}}async function Qt(e,t={}){let r=new xe(t),n=Jt();if(await r.checkTokenAvailable(e))return{success:!0,message:`${Re[e].name} is already configured.`};let i=Re[e];if(n.warn(`No ${i.name} authentication found.
`),!await Qe(`Would you like help setting up ${i.name}?`,!0))return{success:!1,message:`Skipped ${i.name} setup. Security scan may be limited.`};return r.runSetup(e)}import{readFileSync as Kn,copyFileSync as Bn,writeFileSync as Ou,existsSync as Hn,mkdirSync as Pu}from"fs";import{createHash as wu}from"crypto";import{resolve as rt,dirname as Wn,basename as Tu}from"path";class Yn{static DEFAULT_MEMORY_CACHE_TTL=3600000;providers;log;cache;cacheConfigHash;diskAlertsCache;strict;noCache;refreshCache;cacheDir;constructor(e){this.log=A({file:"security/index.ts",isLogging:e.debug}),this.providers=this.createProviders(e);let t=this.resolveCacheTtlMs(e.cacheTtl,Yn.DEFAULT_MEMORY_CACHE_TTL),r=this.resolveCacheTtlMs(e.cacheTtl,U.ALERTS);this.cache=new re({max:500,ttl:t}),this.cacheConfigHash=this.buildCacheConfigHash(e),this.strict=e.strict??!1,this.noCache=e.noCache??!1,this.refreshCache=e.refreshCache??!1,this.cacheDir=e.cacheDir,this.diskAlertsCache=new E(M.ALERTS,{dir:e.cacheDir??R(),ttl:r,version:j.ALERTS,maxEntries:50,enabled:!this.noCache})}resolveCacheTtlMs(e,t){return e===void 0?t:e*1000}buildCacheConfigHash(e){let t=[];if(e.isIRLFix)t.push("irlfix");if(e.isIRLCatch)t.push("irlcatch");if(e.strict)t.push("strict");return t.length>0?t.sort().join(":"):"default"}createProviders(e){return(Array.isArray(e.provider)?e.provider:[e.provider||"osv"]).map((r)=>this.createProvider(r,e))}isKnownSecurityProvider(e){return In.includes(e)}async ensureProviderAuth(e,t={}){if(!this.isKnownSecurityProvider(e))return!0;let n=e;if(await new xe({debug:t.debug}).checkTokenAvailable(n))return!0;if(t.interactive===!1)return!1;return(await Qt(n,{debug:t.debug})).success}createProvider(e,t){switch(e){case"osv":return new Ce({debug:t.debug,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch,strict:t.strict,cacheDir:t.cacheDir,cacheTtl:t.cacheTtl,noCache:t.noCache});case"github":return new qe({debug:t.debug,token:t.token});case"snyk":return new Ze({debug:t.debug,token:t.token,strict:t.strict});case"socket":return new Xe({debug:t.debug,token:t.token,strict:t.strict});case"spektion":return new et({debug:t.debug,token:t.token,strict:t.strict});case"npm":return new tt({debug:t.debug,strict:t.strict});default:return this.log.debug(`Provider ${e} not yet implemented, using OSV`,"createProvider"),new Ce({debug:t.debug,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch,strict:t.strict})}}generateCacheKey(e){let t=e.map((n)=>`${n.name}@${n.version}`).sort().join("|");return`${this.providers.map((n)=>n.providerType).sort().join("|")}:${this.cacheConfigHash}:${t}`}generateDiskCacheKey(e,t){let r=ce(t),n=wu("sha256").update(this.generateCacheKey(e)).digest("hex").slice(0,16);return`alerts:${r}:${n}`}async checkSecurity(e,t={}){this.log.debug("Starting security check","checkSecurity");let r=t.onProgress;try{r?.({phase:"extracting",message:"Extracting packages from dependencies..."});let n=Gn(e,t.excludePackages||[]);if(n.length===0)return this.log.debug("No packages to check","checkSecurity"),{alerts:[],overrides:[],updates:[],packagesScanned:0};let s=this.generateCacheKey(n),i=this.generateDiskCacheKey(n,t.root),o=this.cache.get(s),a=!this.noCache&&!this.refreshCache?this.diskAlertsCache.get(i):void 0,u;if(o)this.log.debug("Using cached security results","checkSecurity"),u=o;else if(a)this.log.debug("Using disk-cached security alerts","checkSecurity"),u=a,this.cache.set(s,u);else if(r?.({phase:"fetching",message:`Checking ${n.length} packages...`,current:0,total:n.length}),u=(await Promise.allSettled(this.providers.map((N)=>N.fetchAlerts(n)))).flatMap((N,Le)=>{let Zn=N.status==="fulfilled",tr=this.providers[Le].providerType;if(Zn)return N.value.map((nt)=>({...nt,sources:[...new Set([...nt.sources||[],tr])]}));if(this.log.warn(`Provider failed: ${N.reason}`,"checkSecurity"),this.strict){let Xn=N.reason instanceof Error?N.reason.message:String(N.reason);throw Error(`Provider ${tr} failed: ${Xn}`)}return[]}),this.cache.set(s,u),!this.noCache)this.diskAlertsCache.set(i,u);this.log.debug(`Found ${u.length} security alerts from ${this.providers.length} provider(s)`,"checkSecurity");let p=`Analyzing ${u.length} security alerts...`;r?.({phase:"analyzing",message:p});let d=Un(Dn(u));if(t.severityThreshold){let $=ie(t.severityThreshold);d=d.filter((N)=>ie(N.severity)>=$)}if(t.depPaths&&t.depPaths.length>0){this.log.debug("Scanning workspace packages for vulnerabilities","checkSecurity");let $=await this.findWorkspaceVulnerabilities(t.depPaths,t.root||"./",u);d=[...d,...$]}this.log.debug(`Found ${d.length} vulnerable packages in dependencies`,"checkSecurity");let f=`Resolving fixes for ${d.length} vulnerabilities...`;r?.({phase:"resolving",message:f});let m=await this.fetchLatestForVulnerablePackages(d),S=this.generateOverrides(d,m),C=await this.checkOverrideUpdates(e,u);if(t.interactive&&d.length>0)S=await new zt().promptForSecurityActions(d,S);return{alerts:d,overrides:S,updates:C,packagesScanned:n.length}}catch(n){throw this.log.error("Security check failed","checkSecurity",{error:n}),n}}readPackageFile(e){try{let t=Kn(e,"utf-8"),r=JSON.parse(t);if(!(r&&typeof r==="object"))return this.log.debug(`Invalid package.json format in ${e}`,"readPackageFile"),null;return r}catch(t){return this.log.debug(`Failed to check ${e}`,"readPackageFile",{error:t}),null}}isNewVulnerability(e,t){let r=`${e.packageName}@${e.currentVersion}`;return!t.has(r)}extractNewVulnerabilities(e,t,r){return Mn(e,t).filter((s)=>this.isNewVulnerability(s,r))}async findWorkspaceVulnerabilities(e,t,r){try{let n=e.map((c)=>rt(t,c)),s=Yr(n,{ignore:["**/node_modules/**"],absolute:!0}),i=[],o=new Set;for(let c of s){let a=this.readPackageFile(c);if(!a)continue;let u=this.extractNewVulnerabilities(a,r,o);for(let l of u)o.add(`${l.packageName}@${l.currentVersion}`),i.push(l)}return i}catch(n){return this.log.error("Failed to find workspace vulnerabilities","findWorkspaceVulnerabilities",{error:n}),[]}}async checkOverrideUpdates(e,t){let r=e.overrides||e.pnpm?.overrides||e.resolutions||{},n=e.pastoralist?.appendix||{},s=Object.entries(r),i=s.filter(([p,d])=>typeof d!=="string").length;if(i>0)this.log.debug(`Skipping ${i} nested override(s) for security update check`,"checkOverrideUpdates");let c=s.filter(([p,d])=>typeof d==="string"),a=t.reduce((p,d)=>{if(!d.patchedVersion)return p;let h=p.get(d.packageName);if(h)h.push(d);else p.set(d.packageName,[d]);return p},new Map),u=c.map(([p,d])=>{let h=`${p}@${d}`,g=n[h];if(!g?.ledger?.securityChecked)return null;let S=(a.get(p)||[]).find(($)=>T($.patchedVersion,d)>0);if(!S)return null;return{packageName:p,currentOverride:d,newerVersion:S.patchedVersion,reason:`Newer security patch available: ${S.title}`,addedDate:g.ledger?.addedDate}}).filter((p)=>p!==null);if(u.length>0)this.log.debug(`Found ${u.length} override updates available`,"checkOverrideUpdates");return u}async fetchLatestForVulnerablePackages(e){let t=e.filter((r)=>r.fixAvailable&&r.patchedVersion).map((r)=>({name:r.packageName,minVersion:r.patchedVersion}));return Ct(t,{cacheDir:this.cacheDir,noCache:this.noCache})}generateOverrides(e,t){return e.filter((r)=>r.fixAvailable&&r.patchedVersion).flatMap((r)=>{let n=t.get(r.packageName),s=r.patchedVersion,o=n&&T(n,s)>=0?n:s,{skip:c,targetStillVulnerable:a}=Fn(r.packageName,r.currentVersion,o,e);if(c)return[];let u={packageName:r.packageName,fromVersion:r.currentVersion,toVersion:o,reason:`Security fix: ${r.title} (${r.severity})`,severity:r.severity,vulnerableRange:r.vulnerableVersions,patchedVersion:s},l=r.cves&&r.cves.length>0?{cves:r.cves}:{},p=r.description?{description:r.description}:{},d=r.url?{url:r.url}:{},h=a?{targetStillVulnerable:!0}:{},g=r.sources&&r.sources.length>0?{sources:r.sources}:{};return[Object.assign({},u,l,p,d,h,g)]})}generatePackageOverrides(e){return e.reduce((t,r)=>{let n=t[r.packageName],s=typeof n==="string";if(n&&typeof n==="object")return t;if(!(s&&T(r.toVersion,n)<=0))t[r.packageName]=r.toVersion;return t},{})}formatVulnerabilityEntry(e){let t=[];if(t.push(`[${e.severity.toUpperCase()}] ${e.packageName}@${e.currentVersion}
`),t.push(`   ${e.title}
`),e.cves&&e.cves.length>0)t.push(`   CVE: ${e.cves.join(", ")}
`);if(e.fixAvailable&&e.patchedVersion)t.push(`   Fix available: ${e.patchedVersion}
`);else t.push(`   No fix available yet
`);if(Boolean(e.url))t.push(`   ${e.url}
`);return t.join("")+`
`}formatOverridesSection(e){if(!(e.length>0))return"";let r=`
Generated ${e.length} override(s):

`,n=e.map((s)=>`  "${s.packageName}": "${s.toVersion}"
`).join("");return r+n}formatSecurityReport(e,t){let r=`
Security Check Report
`+"=".repeat(50)+`

`;if(e.length===0)return r+`No vulnerable packages found
`;let s=`Found ${e.length} vulnerable package(s):

`,i=e.map((c)=>this.formatVulnerabilityEntry(c)).join(""),o=this.formatOverridesSection(t);return[r,s,i,o].filter(Boolean).join("")}createBackup(e){let t=rt(Wn(e),"node_modules",".cache","pastoralist");Pu(t,{recursive:!0});let r=rt(t,`${Tu(e)}.backup-${Date.now()}`);return Bn(e,r),this.log.debug(`Created backup at ${r}`,"createBackup"),r}applyOverridesToPackageJson(e,t,r){if(t==="pnpm")return{...e,pnpm:{...e.pnpm,overrides:{...e.pnpm?.overrides,...r}}};let n=this.getOverrideField(t);return{...e,[n]:{...e[n],...r}}}applyAutoFix(e,t){try{let r=t||rt(process.cwd(),"package.json");if(!Hn(r))throw Error(`package.json not found at ${r}`);let n=this.createBackup(r),s=JSON.parse(Kn(r,"utf-8")),i=le(Wn(r)),o=this.generatePackageOverrides(e),c=e.map((m)=>{let S={packageName:m.packageName,reason:m.reason};if(m.cves&&m.cves.length>0)S.cves=m.cves;if(m.severity)S.severity=m.severity;if(m.description)S.description=m.description;if(m.url)S.url=m.url;if(m.sources&&m.sources.length>0)S.sources=m.sources;return S}),a=this.providers[0]?.providerType??"osv",u=s.pastoralist?.appendix||{},l=s.dependencies||{},p=s.devDependencies||{},d=s.peerDependencies||{},h=s.name||"",g=Te({overrides:o,appendix:u,dependencies:l,devDependencies:p,peerDependencies:d,packageName:h,securityOverrideDetails:c,securityProvider:a}),f=this.applyOverridesToPackageJson(s,i,o);return f.pastoralist=f.pastoralist||{},f.pastoralist.appendix=g,Ou(r,JSON.stringify(f,null,2)+`
`),n}catch(r){this.log.error("Failed to apply auto-fix","applyAutoFix",{error:r});let n=r instanceof Error?r:Error(String(r));throw Error(`Auto-fix failed: ${n.message}`,{cause:n})}}getOverrideField(e){switch(e){case"yarn":return"resolutions";case"pnpm":case"npm":case"bun":default:return"overrides"}}rollbackAutoFix(e,t){try{if(!Hn(e))throw Error(`Backup file not found at ${e}`);Bn(e,t),this.log.print(`Rolled back to ${e}`)}catch(r){throw this.log.error("Failed to rollback","rollbackAutoFix",{error:r}),Error(`Rollback failed: ${r}`)}}}import{existsSync as Gu,readFileSync as Fu}from"fs";import{resolve as Qn}from"path";var zn=[".pastoralistrc",".pastoralistrc.json","pastoralist.json","pastoralist.config.js","pastoralist.config.ts"],Y=(e)=>{return typeof e==="object"&&e!==null&&!Array.isArray(e)},L=(e)=>{return typeof e==="string"},ee=(e)=>{return typeof e==="boolean"},qn=(e)=>{return Array.isArray(e)},Ie=(e)=>{return qn(e)&&e.every(L)},Xt=(e)=>{return L(e)&&["osv","github","snyk","npm","socket","spektion"].includes(e)},Ru=(e)=>{if(Xt(e))return!0;return qn(e)&&e.every(Xt)},Cu=(e)=>{return L(e)&&["low","medium","high","critical"].includes(e)},Eu=(e)=>{return Y(e)},I=(e,t,r)=>{return!((t in e)&&e[t]!==void 0)||r(e[t])},xu=(e)=>{let t=Y(e),r=t?e.reason:void 0;return t&&L(r)},Iu=(e)=>ee(e)||xu(e),Lu=(e)=>["clean","error","skipped"].includes(e),$u=(e)=>["upgrade","not-applicable","disputed"].includes(e),Nu=(e)=>{if(!Y(e))return!1;if(!(("addedDate"in e)&&L(e.addedDate)))return!1;if(!I(e,"reason",L))return!1;let n=I(e,"securityChecked",ee),s=I(e,"securityCheckDate",L);if(!(n&&s))return!1;let o=I(e,"securityProvider",Xt),c=I(e,"securityCheckResult",Lu);if(!(o&&c))return!1;if(!I(e,"cves",Ie))return!1;let l=I(e,"vulnerableRange",L),p=I(e,"patchedVersion",L);if(!(l&&p))return!1;let h=I(e,"keep",Iu),g=I(e,"potentiallyFixedIn",L);if(!(h&&g))return!1;let m=I(e,"resolvedAt",L),S=I(e,"resolvedBy",$u);if(!(m&&S))return!1;return I(e,"resolvedVersion",L)},_u=(e)=>{if(!Y(e))return!1;if("rootDeps"in e&&e.rootDeps!==void 0&&!Ie(e.rootDeps))return!1;if("dependents"in e&&e.dependents!==void 0&&!Eu(e.dependents))return!1;if("patches"in e&&e.patches!==void 0&&!Ie(e.patches))return!1;if("ledger"in e&&e.ledger!==void 0&&!Nu(e.ledger))return!1;return!0},Zt=(e)=>{if(!Y(e))return!1;return Object.values(e).every(_u)},Vu=(e)=>{if(!Y(e))return!1;if("enabled"in e&&e.enabled!==void 0&&!ee(e.enabled))return!1;if("provider"in e&&e.provider!==void 0&&!Ru(e.provider))return!1;if("autoFix"in e&&e.autoFix!==void 0&&!ee(e.autoFix))return!1;if("interactive"in e&&e.interactive!==void 0&&!ee(e.interactive))return!1;if("securityProviderToken"in e&&e.securityProviderToken!==void 0&&!L(e.securityProviderToken))return!1;if("severityThreshold"in e&&e.severityThreshold!==void 0&&!Cu(e.severityThreshold))return!1;if("excludePackages"in e&&e.excludePackages!==void 0&&!Ie(e.excludePackages))return!1;if("hasWorkspaceSecurityChecks"in e&&e.hasWorkspaceSecurityChecks!==void 0&&!ee(e.hasWorkspaceSecurityChecks))return!1;if("strict"in e&&e.strict!==void 0&&!ee(e.strict))return!1;return!0},Du=(e)=>{if(e==="workspace"||e==="workspaces")return!0;return Ie(e)},Uu=(e)=>{if(!Y(e))return!1;if("appendix"in e&&e.appendix!==void 0&&!Zt(e.appendix))return!1;if("depPaths"in e&&e.depPaths!==void 0&&!Du(e.depPaths))return!1;if("checkSecurity"in e&&e.checkSecurity!==void 0&&!ee(e.checkSecurity))return!1;if("overridePaths"in e&&e.overridePaths!==void 0){if(!Y(e.overridePaths))return!1;if(!Object.values(e.overridePaths).every(Zt))return!1}if("resolutionPaths"in e&&e.resolutionPaths!==void 0){if(!Y(e.resolutionPaths))return!1;if(!Object.values(e.resolutionPaths).every(Zt))return!1}if("security"in e&&e.security!==void 0&&!Vu(e.security))return!1;return!0};function Jn(e){if(!Uu(e))return;return e}var er=new Map,Rg=()=>{er.clear()},Mu=(e)=>e.endsWith(".json")||e===".pastoralistrc",ju=(e)=>{let t=Fu(e,"utf8");return JSON.parse(t)},Ku=async(e)=>{let r=await import(Qn(e));return r.default||r},Bu=async(e,t)=>{if(Mu(e))return ju(t);return Ku(t)},Hu=(e,t)=>{if(!t)return e;return Jn(e)||null},Wu=async(e,t,r)=>{let n=Qn(t,e);if(!Gu(n))return null;try{let s=await Bu(e,n);if(!s)return null;return Hu(s,r)}catch(s){let i=s instanceof Error?s.message:String(s);return console.error(`Failed to load config from ${e}: ${i}`),null}},Yu=async(e=process.cwd(),t=!0)=>{for(let r of zn){let n=await Wu(r,e,t);if(n!==null)return n}return},zu=(e,t)=>{if(!e&&!t)return;if(!e)return t;if(!t)return e;let r=(n,s)=>{if(!e[n])return s;let i=e[n],o=Object.assign({},i.dependents,s.dependents),c=s.patches?(i.patches||[]).concat(s.patches):i.patches;return{dependents:o,patches:c,ledger:s.ledger||i.ledger}};return Object.entries(t).reduce((n,[s,i])=>({...n,[s]:r(s,i)}),{...e})},qu=(e,t)=>{if(!e)return t;if(!t)return e;let r=zu(e.appendix,t.appendix),n=Object.assign({},e.overridePaths,t.overridePaths),s=Object.assign({},e.resolutionPaths,t.resolutionPaths),i=Object.assign({},e.security,t.security);return Object.assign({},e,t,{appendix:r,overridePaths:n,resolutionPaths:s,security:i})},Cg=async(e=process.cwd(),t,r=!0)=>{let n=`${e}:${r}:${JSON.stringify(t)}`,s=er.get(n);if(s)return s;let i=await Yu(e,r),o=qu(i,t);if(o)er.set(n,o);return o};
export{ts as a,_ as b,it as c,ss as d,rl as e,w as f,k as g,ys as h,bs as i,hr as j,Ve as k,Qs as l,R as m,vr as n,vi as o,Ai as p,ki as q,Oi as r,Pi as s,wi as t,Ti as u,A as v,Vi as w,K as x,Xp as y,ed as z,le as A,po as B,ho as C,yo as D,ke as E,Jr as F,Zr as G,en as H,dn as I,gn as J,mn as K,bn as L,hc as M,dd as N,An as O,kn as P,On as Q,_c as R,Be as S,de as T,Sd as U,Te as V,Zc as W,wn as X,Rd as Y,jd as Z,Z as _,Yn as $,Rg as aa,Yu as ba,qu as ca,Cg as da};