@visulima/vis 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/LICENSE.md +850 -128
  3. package/dist/bin.js +1 -1
  4. package/dist/binx.js +1 -1
  5. package/dist/packem_chunks/CONFIG_FILES.js +3 -3
  6. package/dist/packem_chunks/bloom-status.js +1 -1
  7. package/dist/packem_chunks/bloom-sync.js +1 -1
  8. package/dist/packem_chunks/catalog.js +67 -67
  9. package/dist/packem_chunks/cli-exec.js +1 -1
  10. package/dist/packem_chunks/cli-main.js +150 -148
  11. package/dist/packem_chunks/dispatch.js +1 -1
  12. package/dist/packem_chunks/doctor-probe.js +1 -1
  13. package/dist/packem_chunks/fix.js +3 -3
  14. package/dist/packem_chunks/handler.js +1 -1
  15. package/dist/packem_chunks/handler10.js +3 -3
  16. package/dist/packem_chunks/handler11.js +1 -1
  17. package/dist/packem_chunks/handler12.js +3 -3
  18. package/dist/packem_chunks/handler13.js +1 -1
  19. package/dist/packem_chunks/handler14.js +1 -1
  20. package/dist/packem_chunks/handler15.js +1 -1
  21. package/dist/packem_chunks/handler16.js +1 -1
  22. package/dist/packem_chunks/handler17.js +1 -1
  23. package/dist/packem_chunks/handler18.js +1 -1
  24. package/dist/packem_chunks/handler19.js +1 -1
  25. package/dist/packem_chunks/handler2.js +1 -1
  26. package/dist/packem_chunks/handler20.js +2 -2
  27. package/dist/packem_chunks/handler21.js +1 -1
  28. package/dist/packem_chunks/handler22.js +1 -1
  29. package/dist/packem_chunks/handler23.js +1 -1
  30. package/dist/packem_chunks/handler24.js +1 -1
  31. package/dist/packem_chunks/handler26.js +1 -1
  32. package/dist/packem_chunks/handler27.js +1 -1
  33. package/dist/packem_chunks/handler28.js +1 -1
  34. package/dist/packem_chunks/handler29.js +1 -1
  35. package/dist/packem_chunks/handler3.js +1 -1
  36. package/dist/packem_chunks/handler30.js +1 -1
  37. package/dist/packem_chunks/handler4.js +4 -4
  38. package/dist/packem_chunks/handler5.js +1 -1
  39. package/dist/packem_chunks/handler50.js +5 -5
  40. package/dist/packem_chunks/handler51.js +2 -2
  41. package/dist/packem_chunks/handler53.js +1 -1
  42. package/dist/packem_chunks/handler54.js +2 -2
  43. package/dist/packem_chunks/handler55.js +1 -1
  44. package/dist/packem_chunks/handler58.js +4 -4
  45. package/dist/packem_chunks/handler59.js +1 -1
  46. package/dist/packem_chunks/handler6.js +7 -7
  47. package/dist/packem_chunks/handler60.js +2 -2
  48. package/dist/packem_chunks/handler61.js +13 -13
  49. package/dist/packem_chunks/handler62.js +3 -3
  50. package/dist/packem_chunks/handler63.js +2 -2
  51. package/dist/packem_chunks/handler64.js +4 -4
  52. package/dist/packem_chunks/handler66.js +1 -1
  53. package/dist/packem_chunks/handler67.js +13 -13
  54. package/dist/packem_chunks/handler68.js +1 -1
  55. package/dist/packem_chunks/handler69.js +15 -15
  56. package/dist/packem_chunks/handler7.js +1 -1
  57. package/dist/packem_chunks/handler70.js +5 -5
  58. package/dist/packem_chunks/handler71.js +1 -1
  59. package/dist/packem_chunks/handler72.js +23 -23
  60. package/dist/packem_chunks/handler73.js +5 -5
  61. package/dist/packem_chunks/handler74.js +24 -24
  62. package/dist/packem_chunks/handler75.js +2 -2
  63. package/dist/packem_chunks/handler76.js +5 -5
  64. package/dist/packem_chunks/handler77.js +18 -18
  65. package/dist/packem_chunks/handler78.js +25 -25
  66. package/dist/packem_chunks/handler8.js +1 -1
  67. package/dist/packem_chunks/handler9.js +1 -1
  68. package/dist/packem_chunks/heal-accept.js +2 -2
  69. package/dist/packem_chunks/heal.js +4 -4
  70. package/dist/packem_chunks/help-command.js +46 -46
  71. package/dist/packem_chunks/index2.js +6 -4
  72. package/dist/packem_chunks/index3.js +3 -3
  73. package/dist/packem_chunks/index4.js +49 -49
  74. package/dist/packem_chunks/keys-refresh.js +1 -1
  75. package/dist/packem_chunks/lean.js +2 -2
  76. package/dist/packem_chunks/list.js +1 -1
  77. package/dist/packem_chunks/loader.js +1 -1
  78. package/dist/packem_chunks/orchestrator.js +2 -2
  79. package/dist/packem_chunks/prompts.js +1 -1
  80. package/dist/packem_chunks/prune.js +1 -1
  81. package/dist/packem_chunks/registry.js +10 -10
  82. package/dist/packem_chunks/status.js +1 -1
  83. package/dist/packem_chunks/sync.js +1 -1
  84. package/dist/packem_chunks/sync2.js +1 -1
  85. package/dist/packem_chunks/tripwire.js +1 -1
  86. package/dist/packem_chunks/ts-loader.js +6 -6
  87. package/dist/packem_chunks/verify-lockfile.js +1 -1
  88. package/dist/packem_shared/{advisories-BGeuHJQg.js → advisories-DsXRmIA5.js} +1 -1
  89. package/dist/packem_shared/{affected-selection-B85ND6JV.js → affected-selection-BE6VFCDV.js} +1 -1
  90. package/dist/packem_shared/{affected-shas-BWRRAB47.js → affected-shas-BKEu4RZc.js} +1 -1
  91. package/dist/packem_shared/ai-analysis-DikAj6rX.js +68 -0
  92. package/dist/packem_shared/{ai-fix-BgBU0TOz.js → ai-fix-bfWo0cZX.js} +4 -4
  93. package/dist/packem_shared/{augment-HVeX6LpU.js → augment-BkJxi_GW.js} +1 -1
  94. package/dist/packem_shared/{bin-DKod8Iqo.js → bin-B-TytgzW.js} +1 -1
  95. package/dist/packem_shared/{build-scripts-CM8M1xcG.js → build-scripts-DWypBQ--.js} +1 -1
  96. package/dist/packem_shared/{command-runtime-BVi4lL8k.js → command-runtime-DQ7ZpLYL.js} +1 -1
  97. package/dist/packem_shared/{cyclonedx-y7VLI-1d.js → cyclonedx-DLBi65MV.js} +3 -3
  98. package/dist/packem_shared/dependency-scan-ZLOuLkGN.js +1 -0
  99. package/dist/packem_shared/{docker-D1LStSlH.js → docker-B4zAZCZG.js} +28 -28
  100. package/dist/packem_shared/{en-BxrK-n-J.js → en-BDYMmM2_.js} +13 -13
  101. package/dist/packem_shared/{failure-log-ChuFC-8f.js → failure-log-DyhWPqno.js} +2 -2
  102. package/dist/packem_shared/glob-BUjyjdE8-Dp_QcayW.js +1 -0
  103. package/dist/packem_shared/index-BLtnel38.js +35 -0
  104. package/dist/packem_shared/index-CuKDxOCI.js +1 -0
  105. package/dist/packem_shared/index-tNFGWxc0.js +39 -0
  106. package/dist/packem_shared/index.server-CusjRLCh.js +2 -0
  107. package/dist/packem_shared/{lifecycle-Db0qh6vR.js → lifecycle-KY9umOg6.js} +1 -1
  108. package/dist/packem_shared/{lockfile-CDQ0n4P5.js → lockfile-YAuZf1gh.js} +1 -1
  109. package/dist/packem_shared/{manifests-Da_no4ZH.js → manifests-BwTn_1ad.js} +1 -1
  110. package/dist/packem_shared/{min-release-age-V6L6dpiP.js → min-release-age-6avfn81h.js} +1 -1
  111. package/dist/packem_shared/missing-package-json-Cl0vdz6K.js +1 -0
  112. package/dist/packem_shared/{native-config-sync-C0pUePad.js → native-config-sync-CHMCJx7H.js} +7 -7
  113. package/dist/packem_shared/{osv-bloom-DNFpvSSO.js → osv-bloom-DdqDnLCt.js} +2 -2
  114. package/dist/packem_shared/package-version-BNRJ3o9C.js +4 -0
  115. package/dist/packem_shared/packument-B9-WqReu.js +1 -0
  116. package/dist/packem_shared/pm-runner-DRybtzOV.js +1 -0
  117. package/dist/packem_shared/{project-name-filter-u2Q7YpQH.js → project-name-filter-Dw0fC6IO.js} +1 -1
  118. package/dist/packem_shared/{provenance-9OT8sTqn.js → provenance-CLxuqCfL.js} +1 -1
  119. package/dist/packem_shared/{readJsonSync-BnWiH5-R-BpnwAB0Z.js → readJsonSync-DweZd5ZA-CtrDlqpb.js} +1 -1
  120. package/dist/packem_shared/{registry-keys-CYHd7qU2.js → registry-keys-cTN24144.js} +1 -1
  121. package/dist/packem_shared/{resolve-explicit-DC3XssJa.js → resolve-explicit-Uw6WQl9R.js} +1 -1
  122. package/dist/packem_shared/{resolve-runtime-f5l4ODsH.js → resolve-runtime-DztanwkZ.js} +1 -1
  123. package/dist/packem_shared/{run-file-zB4ACnUy.js → run-file-CaE5_xBY.js} +1 -1
  124. package/dist/packem_shared/{runtime-check-CWvAfu5u.js → runtime-check-C32yE57I.js} +1 -1
  125. package/dist/packem_shared/{s1ngularity-DsmC71xt.js → s1ngularity-BIYhg82u.js} +1 -1
  126. package/dist/packem_shared/scan-progress-DWfY4zkp.js +2 -0
  127. package/dist/packem_shared/{selectors-CtxnIT4X.js → selectors-D2j4M9Ul.js} +1 -1
  128. package/dist/packem_shared/{signatures-Dwx5fD4g.js → signatures-C8iQ5fUq.js} +1 -1
  129. package/dist/packem_shared/target-merge-DLxJTcxn.js +11 -0
  130. package/dist/packem_shared/{target-options-BO4Uxt0k.js → target-options-3t4-2F-F.js} +1 -1
  131. package/dist/packem_shared/{toolchain-BY8lJaSN.js → toolchain-BPzbahcQ.js} +1 -1
  132. package/dist/packem_shared/{typosquats-BUGgotNu.js → typosquats-BWrmhh36.js} +1 -1
  133. package/dist/packem_shared/{use-measured-height-BLZt9dW2.js → use-measured-height-BwAwGHjw.js} +1 -1
  134. package/dist/packem_shared/verify-CzUPT6Uk.js +1 -0
  135. package/dist/packem_shared/vis-update-app-D6Wq8ZHM.js +1 -0
  136. package/dist/packem_shared/vis-user-error-CfM4_ORo.js +30 -0
  137. package/dist/packem_shared/{watch-CGrUW_JD.js → watch-D_oAxW_Z.js} +1 -1
  138. package/dist/packem_shared/{watch-loop-DIwSMjlA.js → watch-loop-BrjblOz5.js} +4 -4
  139. package/dist/runtime/preload.js +1 -1
  140. package/index.d.ts +204 -204
  141. package/index.js +52 -52
  142. package/package.json +16 -16
  143. package/dist/packem_shared/ai-analysis-oNMAj1wd.js +0 -68
  144. package/dist/packem_shared/dependency-scan-BAzKpXdW.js +0 -1
  145. package/dist/packem_shared/glob-BUjyjdE8-BSrdzgma.js +0 -1
  146. package/dist/packem_shared/index-BJw7gKD1.js +0 -1
  147. package/dist/packem_shared/index-DND6ptxQ.js +0 -35
  148. package/dist/packem_shared/index.server-qvZ-cy29.js +0 -2
  149. package/dist/packem_shared/missing-package-json-Jw8IEHct.js +0 -1
  150. package/dist/packem_shared/package-version-DjHDww_5.js +0 -4
  151. package/dist/packem_shared/packument-N3EWbZpL.js +0 -1
  152. package/dist/packem_shared/pm-runner-Bssje5qH.js +0 -1
  153. package/dist/packem_shared/public-api-WqUCiyIe.js +0 -131
  154. package/dist/packem_shared/scan-progress-Ch8s3Uwl.js +0 -2
  155. package/dist/packem_shared/target-merge-b7bE1AEx.js +0 -11
  156. package/dist/packem_shared/verify-B0ztxKMa.js +0 -1
  157. package/dist/packem_shared/vis-update-app-D1gLJB1O.js +0 -1
  158. package/dist/packem_shared/vis-user-error-DjFv8uxy.js +0 -28
@@ -1,4 +1,4 @@
1
- import{createRequire as Et}from"node:module";import{V as we,E as O,s as ye,q as pt,Q as dt}from"../packem_shared/index.server-qvZ-cy29.js";import{I as Pt,m as z,l as J,z as be,q as Ze,u as Ve,B as Tt}from"../packem_shared/index-DND6ptxQ.js";import{I as Oe}from"../packem_shared/index-BWl4DbMp.js";import{whichBin as Vt}from"#native";import{r as Wt,R as _t,b as Ht}from"../packem_shared/ai-analysis-oNMAj1wd.js";import{N as Ut,O as Ft,B as Gt,X as Bt,p as u,i as Xe}from"./cli-main.js";import"../packem_shared/public-api-WqUCiyIe.js";import{x as qt,c as Kt,n as Jt,b as Yt,N as Zt,f as Xt,v as Qt,S as ei}from"./catalog.js";import{A as ti,j as ii}from"../packem_shared/pm-runner-Bssje5qH.js";import{s as L}from"../packem_shared/index-BAe6e0XE.js";import{c as gt,s as he,p as ai,e as ni,g as oi}from"../packem_shared/index-BJw7gKD1.js";import{d as ri}from"../packem_shared/anolilab-text-CAM_E6uK.js";import{t as si,b as li}from"../packem_shared/cyclonedx-y7VLI-1d.js";import{s as di}from"../packem_shared/scan-progress-Ch8s3Uwl.js";import{r as gi,A as Qe,q as et}from"../packem_shared/advisories-BGeuHJQg.js";import{a as ut}from"../packem_shared/readJsonSync-BnWiH5-R-BpnwAB0Z.js";import{l as fi,f as ui,a as mi}from"../packem_shared/dependency-scan-BAzKpXdW.js";import{r as hi}from"../packem_shared/manifests-Da_no4ZH.js";import{l as xi,p as ki,O as $i}from"../packem_shared/osv-bloom-DNFpvSSO.js";import{H as tt,h as Si,D as Ni,y as Ai}from"../packem_shared/en-BxrK-n-J.js";let Dt;const Ot=e=>(Dt??=Et(import.meta.url))(e),ee=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,Y=e=>{if(typeof ee<"u"&&ee.versions&&ee.versions.node){const[t,i]=ee.versions.node.split(".").map(Number);if(t>22||t===22&&i>=3||t===20&&i>=16)return ee.getBuiltinModule(e)}return Ot(e)},{spawnSync:Mt}=Y("node:child_process"),{createInterface:Lt}=Y("node:readline"),{stripVTControlCharacters:zt}=Y("node:util"),{createHash:ci}=Y("node:crypto"),{relative:ft,join:pi}=Y("node:path"),{readFileSync:mt,existsSync:vi,writeFileSync:wi,renameSync:yi,unlinkSync:bi}=Y("node:fs"),it=(e,t={})=>{Array.isArray(t.extensions)||(t.extensions=["js","mjs","cjs","ts"]);const i=[];for(const a of Pt(e,t))i.push(a.path);return i},xe=e=>`${e.packageName}@${e.packageVersion}:${e.vulnerability.id}`,Ci=e=>e==null||e===!0||e===""||e==="true"||e.toString().toLowerCase()==="all",Ri=(e,t)=>{if(Ci(t))return e;const i=String(t).trim();if(/^\d+$/.test(i)){const n=Number.parseInt(i,10)-1,r=e[n];return r?[r]:[]}const a=i.toLowerCase();return e.filter(n=>{const{aliases:r,id:o}=n.vulnerability;return o.toLowerCase()===a||(r??[]).some(l=>l.toLowerCase()===a)})},Ii=e=>{const{packageName:t,packageVersion:i,vulnerability:a}=e,n=(a.aliases??[]).join(", ")||"none",r=(a.fixedVersions??[]).join(", ")||"no fixed version published";return`You are a security engineer. Explain this dependency vulnerability for a developer triaging it.
1
+ import{createRequire as Et}from"node:module";import{V as we,E as O,s as ye,q as pt,Q as dt}from"../packem_shared/index.server-CusjRLCh.js";import{e as Pt,w as z,l as J,z as be,j as Ze,a as Ve,P as Tt}from"../packem_shared/index-BLtnel38.js";import{I as Oe}from"../packem_shared/index-BWl4DbMp.js";import{whichBin as Vt}from"#native";import{r as Wt,R as _t,c as Ht}from"../packem_shared/ai-analysis-DikAj6rX.js";import{N as Ut,O as Ft,B as Gt,X as Bt,p as u,i as Xe}from"./cli-main.js";import"../packem_shared/index-tNFGWxc0.js";import{x as qt,e as Kt,t as Jt,d as Yt,c as Zt,f as Xt,v as Qt,S as ei}from"./catalog.js";import{A as ti,j as ii}from"../packem_shared/pm-runner-DRybtzOV.js";import{s as L}from"../packem_shared/index-BAe6e0XE.js";import{c as gt,s as he,p as ai,e as ni,g as oi}from"../packem_shared/index-CuKDxOCI.js";import{d as ri}from"../packem_shared/anolilab-text-CAM_E6uK.js";import{t as si,b as li}from"../packem_shared/cyclonedx-DLBi65MV.js";import{s as di}from"../packem_shared/scan-progress-DWfY4zkp.js";import{r as gi,A as Qe,q as et}from"../packem_shared/advisories-DsXRmIA5.js";import{a as ut}from"../packem_shared/readJsonSync-DweZd5ZA-CtrDlqpb.js";import{l as fi,f as ui,a as mi}from"../packem_shared/dependency-scan-ZLOuLkGN.js";import{r as hi}from"../packem_shared/manifests-BwTn_1ad.js";import{l as xi,p as ki,O as $i}from"../packem_shared/osv-bloom-DdqDnLCt.js";import{H as tt,h as Si,D as Ai,y as Ni}from"../packem_shared/en-BDYMmM2_.js";let Dt;const Ot=e=>(Dt??=Et(import.meta.url))(e),ee=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,Y=e=>{if(typeof ee<"u"&&ee.versions&&ee.versions.node){const[t,i]=ee.versions.node.split(".").map(Number);if(t>22||t===22&&i>=3||t===20&&i>=16)return ee.getBuiltinModule(e)}return Ot(e)},{spawnSync:Mt}=Y("node:child_process"),{createInterface:Lt}=Y("node:readline"),{stripVTControlCharacters:zt}=Y("node:util"),{createHash:ci}=Y("node:crypto"),{relative:ft,join:pi}=Y("node:path"),{readFileSync:mt,existsSync:vi,writeFileSync:wi,renameSync:yi,unlinkSync:bi}=Y("node:fs"),it=(e,t={})=>{Array.isArray(t.extensions)||(t.extensions=["js","mjs","cjs","ts"]);const i=[];for(const a of Pt(e,t))i.push(a.path);return i},xe=e=>`${e.packageName}@${e.packageVersion}:${e.vulnerability.id}`,Ci=e=>e==null||e===!0||e===""||e==="true"||e.toString().toLowerCase()==="all",Ri=(e,t)=>{if(Ci(t))return e;const i=String(t).trim();if(/^\d+$/.test(i)){const n=Number.parseInt(i,10)-1,r=e[n];return r?[r]:[]}const a=i.toLowerCase();return e.filter(n=>{const{aliases:r,id:o}=n.vulnerability;return o.toLowerCase()===a||(r??[]).some(l=>l.toLowerCase()===a)})},ji=e=>{const{packageName:t,packageVersion:i,vulnerability:a}=e,n=(a.aliases??[]).join(", ")||"none",r=(a.fixedVersions??[]).join(", ")||"no fixed version published";return`You are a security engineer. Explain this dependency vulnerability for a developer triaging it.
2
2
 
3
3
  Package: ${t}@${i}
4
4
  Advisory: ${a.id} (aliases: ${n})
@@ -11,9 +11,9 @@ Respond ONLY with valid JSON in this exact structure, each value 1-3 plain sente
11
11
  "whatItIs": "what the vulnerability is and how it is exploited",
12
12
  "areYouAtRisk": "what usage pattern makes an app actually exposed; be honest that lockfile presence alone is not exploitation",
13
13
  "whatToDo": "the concrete remediation step"
14
- }`},me=e=>zt(e).replaceAll(/[\u0000-\u0008\u000B-\u001F\u007F]/gu,"").trim(),ji=e=>`What it is: ${e.whatItIs}
14
+ }`},me=e=>zt(e).replaceAll(/[\u0000-\u0008\u000B-\u001F\u007F]/gu,"").trim(),Ii=e=>`What it is: ${e.whatItIs}
15
15
  Are you at risk: ${e.areYouAtRisk}
16
- What to do: ${e.whatToDo}`,Ei=e=>{const t=Ht(e);if(t&&typeof t=="object"){const i=t,a=typeof i.whatItIs=="string"?me(i.whatItIs):"",n=typeof i.areYouAtRisk=="string"?me(i.areYouAtRisk):"",r=typeof i.whatToDo=="string"?me(i.whatToDo):"";if(a||n||r)return ji({areYouAtRisk:n,whatItIs:a,whatToDo:r})}return me(e)},Di=async(e,t,i)=>{let a=0;const n=Array.from({length:Math.min(t,e.length)},async()=>{for(;a<e.length;){const r=a;a+=1;const o=e[r];o!==void 0&&await i(o)}});await Promise.all(n)},Oi=3,Mi={resolveProvider:_t,runWithRetry:Wt},Li=async(e,t,i,a=Mi)=>{const n=new Map;if(e.length===0)return n;const r=a.resolveProvider(t);if(!r)return i?.info?.("No AI CLI provider found on PATH — skipping --explain."),n;const o=Bt("security",t?.cacheTtl);return await Di(e,Oi,async l=>{const c=xe(l),d=Ut({id:l.vulnerability.id,kind:"audit-explain",name:l.packageName,provider:r.name,version:l.packageVersion}),m=Ft(d);if(typeof m=="string"){n.set(c,m);return}try{const b=await a.runWithRetry(r,Ii(l)),h=Ei(b);h&&(n.set(c,h),Gt(d,h,o))}catch(b){const h=b instanceof Error?b.message:String(b);i?.warn?.(`Explain failed for ${l.vulnerability.id} (${h}).`)}}),n},ke=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):[],Me=(e,t)=>{for(const i of t)if(i===e||i.endsWith("*")&&e.startsWith(i.slice(0,-1)))return!0;return!1},ht=e=>{const t=z(e,"pnpm-workspace.yaml");if(!J(t))return{excludedPackages:[],ignoredAdvisories:[]};try{const i=Ve(t);return{excludedPackages:[],ignoredAdvisories:[...ke(i?.auditConfig?.ignoreCves),...ke(i?.auditConfig?.ignoreGhsas)]}}catch{return{excludedPackages:[],ignoredAdvisories:[]}}},vt=e=>{const t=z(e,".yarnrc.yml");if(!J(t))return{excludedPackages:[],ignoredAdvisories:[]};try{const i=Ve(t);return{excludedPackages:ke(i?.npmAuditExcludePackages),ignoredAdvisories:ke(i?.npmAuditIgnoreAdvisories)}}catch{return{excludedPackages:[],ignoredAdvisories:[]}}},Pi=(e,t)=>{switch(t){case"pnpm":return ht(e);case"yarn":return vt(e);default:return{excludedPackages:[],ignoredAdvisories:[]}}},ae=(e,t,i)=>{if(Me(e,t.ignoredAdvisories))return!0;if(i){for(const a of i)if(Me(a,t.ignoredAdvisories))return!0}return!1},Ti=(e,t)=>Me(e,t.excludedPackages),Vi=(e,t,i)=>{if(i.length===0)return["No advisory IDs to sync."];const a=[];switch(e){case"bun":{a.push(`bun has no audit config file. Use CLI flags: bun audit ${i.map(n=>`--ignore ${n}`).join(" ")}`);break}case"npm":{a.push("npm has no native audit exclusion config. vis accepted risks are the only layer.");break}case"pnpm":{const n=z(t,"pnpm-workspace.yaml");if(!J(n)){a.push("pnpm-workspace.yaml not found. Cannot sync.");break}const r=ht(t),o=new Set(r.ignoredAdvisories.filter(g=>g.startsWith("CVE-"))),l=new Set(r.ignoredAdvisories.filter(g=>g.startsWith("GHSA-"))),c=i.filter(g=>g.startsWith("CVE-")),d=i.filter(g=>g.startsWith("GHSA-")),m=[...new Set([...o,...c])],b=[...new Set([...l,...d])],h=c.filter(g=>!o.has(g)).length,v=d.filter(g=>!l.has(g)).length;if(h===0&&v===0){a.push("All advisory IDs already present in pnpm-workspace.yaml.");break}let y=be(n);if(m.length>0){const g=` ignoreCves:
16
+ What to do: ${e.whatToDo}`,Ei=e=>{const t=Ht(e);if(t&&typeof t=="object"){const i=t,a=typeof i.whatItIs=="string"?me(i.whatItIs):"",n=typeof i.areYouAtRisk=="string"?me(i.areYouAtRisk):"",r=typeof i.whatToDo=="string"?me(i.whatToDo):"";if(a||n||r)return Ii({areYouAtRisk:n,whatItIs:a,whatToDo:r})}return me(e)},Di=async(e,t,i)=>{let a=0;const n=Array.from({length:Math.min(t,e.length)},async()=>{for(;a<e.length;){const r=a;a+=1;const o=e[r];o!==void 0&&await i(o)}});await Promise.all(n)},Oi=3,Mi={resolveProvider:_t,runWithRetry:Wt},Li=async(e,t,i,a=Mi)=>{const n=new Map;if(e.length===0)return n;const r=a.resolveProvider(t);if(!r)return i?.info?.("No AI CLI provider found on PATH — skipping --explain."),n;const o=Bt("security",t?.cacheTtl);return await Di(e,Oi,async l=>{const c=xe(l),d=Ut({id:l.vulnerability.id,kind:"audit-explain",name:l.packageName,provider:r.name,version:l.packageVersion}),m=Ft(d);if(typeof m=="string"){n.set(c,m);return}try{const b=await a.runWithRetry(r,ji(l)),h=Ei(b);h&&(n.set(c,h),Gt(d,h,o))}catch(b){const h=b instanceof Error?b.message:String(b);i?.warn?.(`Explain failed for ${l.vulnerability.id} (${h}).`)}}),n},ke=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):[],Me=(e,t)=>{for(const i of t)if(i===e||i.endsWith("*")&&e.startsWith(i.slice(0,-1)))return!0;return!1},ht=e=>{const t=z(e,"pnpm-workspace.yaml");if(!J(t))return{excludedPackages:[],ignoredAdvisories:[]};try{const i=Ve(t);return{excludedPackages:[],ignoredAdvisories:[...ke(i?.auditConfig?.ignoreCves),...ke(i?.auditConfig?.ignoreGhsas)]}}catch{return{excludedPackages:[],ignoredAdvisories:[]}}},vt=e=>{const t=z(e,".yarnrc.yml");if(!J(t))return{excludedPackages:[],ignoredAdvisories:[]};try{const i=Ve(t);return{excludedPackages:ke(i?.npmAuditExcludePackages),ignoredAdvisories:ke(i?.npmAuditIgnoreAdvisories)}}catch{return{excludedPackages:[],ignoredAdvisories:[]}}},Pi=(e,t)=>{switch(t){case"pnpm":return ht(e);case"yarn":return vt(e);default:return{excludedPackages:[],ignoredAdvisories:[]}}},ae=(e,t,i)=>{if(Me(e,t.ignoredAdvisories))return!0;if(i){for(const a of i)if(Me(a,t.ignoredAdvisories))return!0}return!1},Ti=(e,t)=>Me(e,t.excludedPackages),Vi=(e,t,i)=>{if(i.length===0)return["No advisory IDs to sync."];const a=[];switch(e){case"bun":{a.push(`bun has no audit config file. Use CLI flags: bun audit ${i.map(n=>`--ignore ${n}`).join(" ")}`);break}case"npm":{a.push("npm has no native audit exclusion config. vis accepted risks are the only layer.");break}case"pnpm":{const n=z(t,"pnpm-workspace.yaml");if(!J(n)){a.push("pnpm-workspace.yaml not found. Cannot sync.");break}const r=ht(t),o=new Set(r.ignoredAdvisories.filter(g=>g.startsWith("CVE-"))),l=new Set(r.ignoredAdvisories.filter(g=>g.startsWith("GHSA-"))),c=i.filter(g=>g.startsWith("CVE-")),d=i.filter(g=>g.startsWith("GHSA-")),m=[...new Set([...o,...c])],b=[...new Set([...l,...d])],h=c.filter(g=>!o.has(g)).length,v=d.filter(g=>!l.has(g)).length;if(h===0&&v===0){a.push("All advisory IDs already present in pnpm-workspace.yaml.");break}let y=be(n);if(m.length>0){const g=` ignoreCves:
17
17
  ${m.map($=>` - ${$}`).join(`
18
18
  `)}
19
19
  `;/auditConfig:/.test(y)?y=/ignoreCves:/.test(y)?y.replace(/ignoreCves:\s*\n(?:\s+-\s+(?:\S.*|[\t\v\f \u00A0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF])\n)*/,g):y.replace(/auditConfig:\s*\n/,`auditConfig:
@@ -45,17 +45,17 @@ ${m}`,Ze(n,d),a.push(`Synced ${String(c)} advisor${c===1?"y":"ies"} to .yarnrc.y
45
45
  <tr class="explain-row" ${h}>
46
46
  <td colspan="8" class="p-0"><details><summary class="flex cursor-pointer items-center gap-3 px-3 py-2 select-none"><span class="intel-tag text-[9px] font-bold uppercase">[ AI INTEL ]</span><span class="intel-hint text-[9px] uppercase">threat analysis · click to expand</span></summary><div class="explain-body grid gap-3 px-3 pt-1 pb-4">${Qi(a)}</div></details></td>
47
47
  </tr>`:`${v}${y}`},na=e=>{const t=e.now??new Date,i=[...e.findings].sort(gt),a={CRITICAL:0,HIGH:0,LOW:0,MODERATE:0,UNKNOWN:0};let n=0,r=0;for(const x of i)a[x.vulnerability.severity??"UNKNOWN"]+=1,x.acknowledged||(r+=1,x.vulnerability.fixedVersions.length>0&&(n+=1));const o=i.map(x=>aa(x)).join(`
48
- `),l=i.length===0,c=_i.filter(x=>a[x]>0).map(x=>`<div class="dseg dseg-sev dseg-${x.toLowerCase()}"><span class="dk text-[10px] font-medium uppercase">${x}</span><span class="dv text-[22px]">${String(a[x])}</span></div>`),d=!l&&r>0?`<div class="dseg dseg-fixable"><span class="dk text-[10px] font-medium uppercase">fixable</span><span class="dv text-[22px]">${String(n)}<span class="dvsep mx-1 font-light">/</span>${String(r)}</span></div>`:"",m=[`<div class="dseg"><span class="dk text-[10px] font-medium uppercase">scanned</span><span class="dv text-[22px]">${String(e.packagesScanned)}</span></div>`,`<div class="dseg"><span class="dk text-[10px] font-medium uppercase">findings</span><span class="dv text-[22px]"><span id="shown">${String(i.length)}</span>${l?"":`<span class="dvsep mx-1 font-light">/</span>${String(i.length)}`}</span></div>`,d,c.length>0?'<span class="flex-auto"></span>':"",...c,l?'<div class="dseg dseg-ok"><span class="dot inline-block size-[7px] self-center"></span><span class="dk text-[10px] font-medium uppercase">status</span><span class="dv text-[22px]">CLEAN</span></div>':""].join(""),b=l?"ok":a.CRITICAL>0?"crit":a.HIGH>0?"high":"warn",h=[...e.report?.duplicates??[]].sort((x,A)=>x.name.localeCompare(A.name)),v=h.map(x=>`<tr>
48
+ `),l=i.length===0,c=_i.filter(x=>a[x]>0).map(x=>`<div class="dseg dseg-sev dseg-${x.toLowerCase()}"><span class="dk text-[10px] font-medium uppercase">${x}</span><span class="dv text-[22px]">${String(a[x])}</span></div>`),d=!l&&r>0?`<div class="dseg dseg-fixable"><span class="dk text-[10px] font-medium uppercase">fixable</span><span class="dv text-[22px]">${String(n)}<span class="dvsep mx-1 font-light">/</span>${String(r)}</span></div>`:"",m=[`<div class="dseg"><span class="dk text-[10px] font-medium uppercase">scanned</span><span class="dv text-[22px]">${String(e.packagesScanned)}</span></div>`,`<div class="dseg"><span class="dk text-[10px] font-medium uppercase">findings</span><span class="dv text-[22px]"><span id="shown">${String(i.length)}</span>${l?"":`<span class="dvsep mx-1 font-light">/</span>${String(i.length)}`}</span></div>`,d,c.length>0?'<span class="flex-auto"></span>':"",...c,l?'<div class="dseg dseg-ok"><span class="dot inline-block size-[7px] self-center"></span><span class="dk text-[10px] font-medium uppercase">status</span><span class="dv text-[22px]">CLEAN</span></div>':""].join(""),b=l?"ok":a.CRITICAL>0?"crit":a.HIGH>0?"high":"warn",h=[...e.report?.duplicates??[]].sort((x,N)=>x.name.localeCompare(N.name)),v=h.map(x=>`<tr>
49
49
  <td class="px-3 py-3 align-top"><code class="font-medium">${S(x.name)}</code></td>
50
50
  <td class="px-3 py-3 align-top text-[12px] font-medium tabular-nums">${String(x.versionCount)}</td>
51
- <td class="px-3 py-3 align-top"><code class="text-[12px]">${x.versions.map(A=>S(A)).join(", ")}</code></td>
51
+ <td class="px-3 py-3 align-top"><code class="text-[12px]">${x.versions.map(N=>S(N)).join(", ")}</code></td>
52
52
  </tr>`).join(`
53
- `),y=(e.policyDecisions??[]).filter(x=>x.policy!=="vulnerability"),g=[...y].sort((x,A)=>{const K=M=>M==="block"?0:M==="warn"?1:2;return K(x.severity)-K(A.severity)||x.policy.localeCompare(A.policy)||x.packageName.localeCompare(A.packageName)}).map(x=>{const A=x.acceptedRisk?' <span class="ack ml-2 inline-block px-[5px] py-px text-[9px] uppercase">[acknowledged]</span>':"";return`<tr>
53
+ `),y=(e.policyDecisions??[]).filter(x=>x.policy!=="vulnerability"),g=[...y].sort((x,N)=>{const K=M=>M==="block"?0:M==="warn"?1:2;return K(x.severity)-K(N.severity)||x.policy.localeCompare(N.policy)||x.packageName.localeCompare(N.packageName)}).map(x=>{const N=x.acceptedRisk?' <span class="ack ml-2 inline-block px-[5px] py-px text-[9px] uppercase">[acknowledged]</span>':"";return`<tr>
54
54
  <td class="px-3 py-3 align-top"><span class="policy-badge policy-${x.severity} inline-flex items-center gap-[7px] rounded-[3px] py-1 pr-2 pl-[7px] text-[10px] font-bold uppercase">${x.severity.toUpperCase()}</span></td>
55
55
  <td class="px-3 py-3 align-top"><code class="uppercase">${S(x.policy)}</code></td>
56
56
  <td class="px-3 py-3 align-top"><code class="uppercase">${S(x.packageName)}</code></td>
57
57
  <td class="px-3 py-3 align-top"><code class="uppercase">${S(x.version)}</code></td>
58
- <td class="px-3 py-3 align-top">${S(x.reason)}${A}</td>
58
+ <td class="px-3 py-3 align-top">${S(x.reason)}${N}</td>
59
59
  </tr>`}).join(`
60
60
  `),$=e.report?`
61
61
  <script type="application/json" id="vis-audit-report">${JSON.stringify(e.report).replaceAll("</",String.raw`<\/`)}<\/script>`:"";return`<!doctype html>
@@ -69,7 +69,7 @@ ${m}`,Ze(n,d),a.push(`Synced ${String(c)} advisor${c===1?"y":"ies"} to .yarnrc.y
69
69
  <body>
70
70
  <main class="mx-auto max-w-[1080px]">
71
71
  <header class="masthead flex flex-wrap items-end gap-4 px-0 pt-8 pb-5">
72
- <div class="brand leading-none tracking-tight">${(()=>{const[x,...A]=e.tool.name.split("-");return A.length>0?`${S(x??e.tool.name)}<span class="slash mx-[0.12em] font-light">/</span>${S(A.join("-"))}`:S(e.tool.name)})()}<span class="sub mt-3 block text-[11px] font-medium uppercase">dependency security report</span></div>
72
+ <div class="brand leading-none tracking-tight">${(()=>{const[x,...N]=e.tool.name.split("-");return N.length>0?`${S(x??e.tool.name)}<span class="slash mx-[0.12em] font-light">/</span>${S(N.join("-"))}`:S(e.tool.name)})()}<span class="sub mt-3 block text-[11px] font-medium uppercase">dependency security report</span></div>
73
73
  <span class="flex-auto"></span>
74
74
  <span class="chip inline-flex h-7 items-center justify-center rounded-[4px] px-3 text-[11px] font-medium uppercase">v${S(e.tool.version)}</span>
75
75
  <button id="theme" class="tbtn tbtn-theme inline-flex h-7 cursor-pointer items-center justify-center rounded-[4px] bg-transparent px-3 text-[11px] font-medium uppercase" type="button" aria-label="Toggle color theme" title="Toggle color theme"><span class="ticon ticon-moon inline-flex items-center justify-center">${ea}</span><span class="ticon ticon-sun inline-flex items-center justify-center">${ta}</span></button>
@@ -293,7 +293,7 @@ ${v.summary||`Advisory ${v.id}`}${y}`,failureType:Le(v.severity).toUpperCase(),n
293
293
  `;return c+=lt("vulnerabilities",a,t),n.length>0&&(c+=lt("policies",n,t)),c+=`</testsuites>
294
294
  `,c},va=e=>{const t=new Map,i=[],a=e.artifactUri??(ft(e.workspaceRoot,pi(e.workspaceRoot,"package.json"))||"package.json");for(const o of e.findings){const{acknowledged:l,packageName:c,packageVersion:d,vulnerability:m}=o,b=Gi(m.severity),h=Le(m.severity);t.has(m.id)||t.set(m.id,{defaultConfiguration:{level:b},fullDescription:{text:m.summary||`Advisory ${m.id}`},helpUri:P(m.id),id:m.id,name:m.id,properties:{precision:"very-high","security-severity":qi(m),"severity-label":h,tags:["security","vulnerability","supply-chain",`severity:${h}`]},shortDescription:{text:(m.summary.split(`
295
295
  `)[0]??m.id).slice(0,200)}}),i.push({level:b,locations:[{logicalLocations:[{kind:"package",name:`${c}@${d}`}],physicalLocation:{artifactLocation:{uri:a}}}],message:{text:`${m.id}: ${c}@${d} — ${m.summary||"no summary"}${m.fixedVersions.length>0?` (fix: ${m.fixedVersions.join(", ")})`:""}`},partialFingerprints:{advisoryId:m.id,package:c,version:d},properties:{...l?{acknowledged:!0}:{},...m.aliases&&m.aliases.length>0?{aliases:m.aliases}:{},...typeof m.cvssScore=="number"?{cvssScore:m.cvssScore}:{},...m.fixedVersions.length>0?{fixedVersions:m.fixedVersions}:{},packageName:c,packageVersion:d,severityLabel:h},ruleId:m.id})}const n={block:"error",info:"note",warn:"warning"},r={block:"high",info:"none",warn:"medium"};for(const o of e.policyDecisions??[]){if(o.policy==="vulnerability")continue;const l=`vis.policy.${o.policy}`,c=n[o.severity],d=r[o.severity];t.has(l)||t.set(l,{defaultConfiguration:{level:c},fullDescription:{text:`vis policy '${o.policy}' (Socket.dev-style supply-chain gate)`},helpUri:`https://visulima.com/packages/vis/commands/audit#policy-${o.policy}`,id:l,name:l,properties:{precision:"high","security-severity":o.severity==="block"?"8.0":o.severity==="warn"?"5.5":"0.0","severity-label":d,tags:["security","supply-chain","policy",`policy:${o.policy}`]},shortDescription:{text:`vis policy: ${o.policy}`}}),i.push({level:c,locations:[{logicalLocations:[{kind:"package",name:`${o.packageName}@${o.version}`}],physicalLocation:{artifactLocation:{uri:a}}}],message:{text:o.reason},partialFingerprints:{package:o.packageName,policy:o.policy,version:o.version},properties:{...o.acceptedRisk?{acknowledged:!0}:{},packageName:o.packageName,packageVersion:o.version,severityLabel:d},ruleId:l})}return{$schema:"https://json.schemastore.org/sarif-2.1.0.json",runs:[{results:i,tool:{driver:{informationUri:e.tool.informationUri,name:e.tool.name,rules:[...t.values()],version:e.tool.version}}}],version:"2.1.0"}},wa=["dependencies","devDependencies","optionalDependencies","peerDependencies"],ct=e=>{try{return{path:e,pkg:ut(e)}}catch{return}},ya=e=>{const t=[],i=ct(z(e,"package.json"));i&&t.push({path:i.path,pkg:i.pkg,workspaceName:i.pkg.name});const a=qt(e);let n;if(a?n=a:i?.pkg.workspaces&&(Array.isArray(i.pkg.workspaces)?n=i.pkg.workspaces:i.pkg.workspaces.packages&&(n=i.pkg.workspaces.packages)),!n)return t;for(const r of Kt(e,n)){const o=ct(z(e,r,"package.json"));o&&t.push({path:o.path,pkg:o.pkg,workspaceName:o.pkg.name})}return t},ba=(e,t)=>{const i=[];for(const a of e)for(const n of wa){const r=a.pkg[n]?.[t];typeof r=="string"&&i.push({field:n,manifest:a,range:r})}return i},yt=e=>{const t=ya(e.workspaceRoot),i=[],a=[],n=[],r=new Set;for(const o of e.findings){const l=o.vulnerability.fixedVersions[0];if(!l){n.push({packageName:o.packageName,reason:"no-fixed-version"});continue}const c=ba(t,o.packageName);if(c.length===0){n.push({packageName:o.packageName,reason:"transitive-only"});continue}const d=L.coerce(l),m=d?`^${d.version}`:l,b=d?d.version:l;for(const h of c){const v=`${h.manifest.path}::${h.field}::${o.packageName}::${b}`;if(r.has(v))continue;r.add(v);const y=ka(b,h.range),g={currentRange:h.range,field:h.field,inRange:y,manifestPath:h.manifest.path,packageName:o.packageName,targetSpec:m,targetVersion:b,workspaceName:h.manifest.workspaceName};y||e.allowMajor===!0?i.push(g):a.push(g)}}return{apply:i,skippedMajor:a,unmatched:n}},xa=/^(?:workspace|file|link|portal|patch|git\+|git:|github:|npm:|catalog|jsr|http|https):/i,ka=(e,t)=>{if(xa.test(t))return!0;const i=L.coerce(e)?.version??e;try{return L.satisfies(i,t)}catch{return!0}},$a=e=>{const t=[];if(e.apply.length>0){t.push(`Apply (${String(e.apply.length)}):`);for(const i of e.apply){const a=i.workspaceName?` [${i.workspaceName}]`:"";t.push(` + ${i.packageName}: ${i.currentRange} → ${i.targetSpec}${a}`)}}if(e.skippedMajor.length>0){t.push(`Skipped — major bump (${String(e.skippedMajor.length)}, requires --allow-major):`);for(const i of e.skippedMajor){const a=i.workspaceName?` [${i.workspaceName}]`:"";t.push(` ! ${i.packageName}: ${i.currentRange} → ${i.targetSpec}${a}`)}}if(e.unmatched.length>0){const i=e.unmatched.filter(n=>n.reason==="transitive-only"),a=e.unmatched.filter(n=>n.reason==="no-fixed-version");if(i.length>0){t.push(`Transitive only (${String(i.length)}, requires --fix-transitive):`);for(const n of i)t.push(` · ${n.packageName}`)}if(a.length>0){t.push(`No fixed version available (${String(a.length)}):`);for(const n of a)t.push(` · ${n.packageName}`)}}return t.length===0?"No direct-dep fixes to apply.":t.join(`
296
- `)},Sa=5,Na=64,Aa=(e,t)=>{if(t.length===0)return[];const i=new Set;for(const a of e){if(t.includes(a)){i.add(a);continue}let n=!1;for(const r of t)try{L.satisfies(r,a)&&(i.add(r),n=!0)}catch{}!n&&t.length===1&&i.add(t[0])}return[...i]},Ca=e=>{const t=new Map;for(const n of e.entries){let r=t.get(n.name);r||(r=[],t.set(n.name,r)),r.includes(n.version)||r.push(n.version)}const i=new Map;for(const n of e.entries){const r=`${n.name}@${n.version}`;let o=i.get(r);o||(o=new Map,i.set(r,o));for(const l of[n.dependencies,n.peerDependencies,n.optionalDependencies])if(l)for(const[c,d]of Object.entries(l)){const m=t.get(c)??[],b=Aa(d,m);for(const h of b){const v=`${c}@${h}`;o.has(v)||o.set(v,{name:c,version:h})}}}const a=new Map;for(const[n,r]of i)a.set(n,{children:[...r.values()]});return{adjacency:a,versionsByName:t}},Ra=(e,t)=>{const i=t.get(e.name);if(!(!i||i.length===0)){if(i.includes(e.version))return{name:e.name,version:e.version};for(const a of i)try{if(L.satisfies(a,e.version))return{name:e.name,version:a}}catch{}if(i.length===1)return{name:e.name,version:i[0]}}},Ia=(e,t,i={})=>{const a=i.maxPathsPerTarget??Sa,n=i.maxDepth??Na;if(a<=0)return[];const{adjacency:r,versionsByName:o}=Ca(e),l=`${t.name}@${t.version}`,c=[],d=[],m=new Set;for(const v of e.roots){const y=Ra(v,o);if(!y)continue;const g=`${y.name}@${y.version}`;m.has(g)||(m.add(g),d.push(y))}const b=[];for(const v of d){const y=`${v.name}@${v.version}`;if(y===l){if(c.push([v]),c.length>=a)return c;continue}b.push({node:v,path:[v],visited:new Set([y])})}let h=0;for(;h<b.length&&c.length<a;){const v=b[h];if(h+=1,v.path.length>=n)continue;const y=r.get(`${v.node.name}@${v.node.version}`)?.children??[];for(const g of y){const $=`${g.name}@${g.version}`;if(v.visited.has($))continue;const x=[...v.path,g];if($===l){if(c.push(x),c.length>=a)return c;continue}const A=new Set(v.visited);A.add($),b.push({node:g,path:x,visited:A})}}return c},ja={"crates.io":["Cargo.lock"],Go:["go.sum"],Maven:["gradle.lockfile","pom.xml"],PyPI:["uv.lock","poetry.lock","Pipfile.lock"],RubyGems:["Gemfile.lock"]},Ea={cargo:"crates.io","crates.io":"crates.io",go:"Go",maven:"Maven",npm:"npm",pypi:"PyPI",rubygems:"RubyGems"},bt=e=>Ea[e.toLowerCase()]??e,Da=(e,t)=>{const i=bt(t),a=ja[i]??[];for(const n of a){const r=z(e,n);if(vi(r))return r}},Oa=e=>{const t=new Set,i=[];for(const a of e){const n=`${a.name}@${a.version}`;t.has(n)||(t.add(n),i.push(a))}return i},Ma=/\[\[package\]\]([\s\S]*?)(?=\[\[|$)/g,La=/^\s*name\s*=\s*"([^"]+)"\s*$/m,Pa=/^\s*version\s*=\s*"([^"]+)"\s*$/m,Ta=e=>{const t=[];for(const i of e.matchAll(Ma)){const a=i[1]??"",n=La.exec(a)?.[1],r=Pa.exec(a)?.[1];n&&r&&t.push({isDev:!1,name:n,version:r})}return t},Va=e=>{let t;try{t=JSON.parse(e)}catch{return[]}if(typeof t!="object"||t===null)return[];const i=[];for(const a of["default","develop"]){const n=t[a];if(!(typeof n!="object"||n===null))for(const[r,o]of Object.entries(n)){if(typeof o!="object"||o===null)continue;const l=o.version;if(typeof l!="string")continue;const c=l.replace(/^==/,"").trim();c.length>0&&i.push({isDev:!1,name:r,version:c})}}return i},za=/<dependency>([\s\S]*?)<\/dependency>/g,Wa=/<groupId>\s*([^<\s]+)\s*<\/groupId>/,_a=/<artifactId>\s*([^<\s]+)\s*<\/artifactId>/,Ha=/<version>\s*([^<\s]+)\s*<\/version>/,Ua=e=>{const t=[];for(const i of e.matchAll(za)){const a=i[1]??"",n=Wa.exec(a)?.[1],r=_a.exec(a)?.[1],o=Ha.exec(a)?.[1];!n||!r||!o||o.startsWith("${")||t.push({isDev:!1,name:`${n}:${r}`,version:o})}return t},Fa=e=>{const t=[];for(const i of e.split(/\r?\n/)){const a=i.trim();if(a.length===0||a.startsWith("#"))continue;const n=a.indexOf("="),r=(n===-1?a:a.slice(0,n)).split(":");if(r.length<3)continue;const[o,l,c]=r;!o||!l||!c||t.push({isDev:!1,name:`${o}:${l}`,version:c})}return t},Ga=e=>{const t=[];for(const i of e.split(/\r?\n/)){const a=i.trim();if(a.length===0)continue;const n=a.split(/\s+/);if(n.length<3)continue;const[r,o]=n;if(!r||!o?.endsWith("/go.mod"))continue;const l=o.slice(0,-7);l.length!==0&&t.push({isDev:!1,name:r,version:l})}return t},Ba=/^ {4}([^ ()]+) \(([^()]+)\)\s*$/,qa=e=>{const t=[];let i=!1,a=!1;for(const n of e.split(/\r?\n/)){if(n.startsWith("GEM")){i=!0,a=!1;continue}if(i&&/^[A-Z]/.test(n)){i=!1,a=!1;continue}if(i&&n.trim()==="specs:"){a=!0;continue}if(a){const r=Ba.exec(n);if(r){const[,o,l]=r;o&&l&&t.push({isDev:!1,name:o,version:l})}}}return t},Ka=(e,t)=>{const i=Da(e,t);if(!i)return[];let a;try{a=mt(i,"utf8")}catch{return[]}const n=i.split(/[/\\]/).pop()??"";let r;switch(n){case"Cargo.lock":case"poetry.lock":case"uv.lock":{r=Ta(a);break}case"Gemfile.lock":{r=qa(a);break}case"go.sum":{r=Ga(a);break}case"gradle.lockfile":{r=Fa(a);break}case"Pipfile.lock":{r=Va(a);break}case"pom.xml":{r=Ua(a);break}default:return[]}return Oa(r)},Ja=["ts","tsx","js","jsx","mjs","cjs","mts","cts"],Ya=[/node_modules/,/\.git/,/\.next/,/\.cache/,/dist/,/build/,/coverage/,/\.turbo/,/\.nx/,/\.parcel-cache/],Za=["dependencies","devDependencies","peerDependencies","optionalDependencies"],Xa=/(?:import|export)\s+(?:[\s\S]*?from\s+)?["']([^"'\n]+)["']/g,Qa=/(?:^|[^.\w$])require\s*\(\s*["']([^"'\n]+)["']\s*\)/g,en=/\bimport\s*\(\s*["']([^"'\n]+)["']\s*\)/g,tn=e=>{if(e.startsWith(".")||e.startsWith("/")||/^[a-z][a-z0-9+.-]*:/i.test(e))return;const t=e.trim();if(t.length!==0){if(t.startsWith("@")){const i=t.split("/");return i.length<2?void 0:`${i[0]}/${i[1]}`}return t.split("/")[0]}},an=e=>{const t=new Set,i=e.replaceAll(/\/\*[\s\S]*?\*\//g,"").replaceAll(/(^|[^:])\/\/.*$/gm,"$1"),a=n=>{n.lastIndex=0;let r;for(;(r=n.exec(i))!==null;){const o=tn(r[1]);o&&t.add(o)}};return a(Xa),a(Qa),a(en),t},nn=e=>{const t=new Set;try{const i=ut(e);for(const a of Za){const n=i[a];if(n&&typeof n=="object"&&!Array.isArray(n))for(const r of Object.keys(n))t.add(r)}}catch{}return t},on=e=>{const t=e.skip??Ya,i=e.extensions??Ja,a=new Set;let n=0;const r=it(e.workspaceRoot,{extensions:i,includeDirs:!1,skip:t});for(const c of r){n+=1;try{const d=mt(c,"utf8");for(const m of an(d))a.add(m)}catch{}}const o=it(e.workspaceRoot,{extensions:["json"],includeDirs:!1,skip:t}).filter(c=>c.endsWith("/package.json")||c.endsWith(String.raw`\package.json`)||c.endsWith("package.json"));for(const c of o)for(const d of nn(c))a.add(d);if(e.alwaysAssumeUsed)for(const c of e.alwaysAssumeUsed)a.add(c);const l=new Set;for(const c of e.vulnerablePackages)a.has(c)&&l.add(c);return{filesScanned:n,importedTotal:a,reachable:l}},rn=e=>{const t=L.coerce(e)?.major;return t!==void 0&&t>=10},sn=e=>Object.fromEntries(Object.entries(e).sort(([t],[i])=>t.localeCompare(i))),ln=(e,t)=>`${JSON.stringify(e,void 0,t)}
296
+ `)},Sa=5,Aa=64,Na=(e,t)=>{if(t.length===0)return[];const i=new Set;for(const a of e){if(t.includes(a)){i.add(a);continue}let n=!1;for(const r of t)try{L.satisfies(r,a)&&(i.add(r),n=!0)}catch{}!n&&t.length===1&&i.add(t[0])}return[...i]},Ca=e=>{const t=new Map;for(const n of e.entries){let r=t.get(n.name);r||(r=[],t.set(n.name,r)),r.includes(n.version)||r.push(n.version)}const i=new Map;for(const n of e.entries){const r=`${n.name}@${n.version}`;let o=i.get(r);o||(o=new Map,i.set(r,o));for(const l of[n.dependencies,n.peerDependencies,n.optionalDependencies])if(l)for(const[c,d]of Object.entries(l)){const m=t.get(c)??[],b=Na(d,m);for(const h of b){const v=`${c}@${h}`;o.has(v)||o.set(v,{name:c,version:h})}}}const a=new Map;for(const[n,r]of i)a.set(n,{children:[...r.values()]});return{adjacency:a,versionsByName:t}},Ra=(e,t)=>{const i=t.get(e.name);if(!(!i||i.length===0)){if(i.includes(e.version))return{name:e.name,version:e.version};for(const a of i)try{if(L.satisfies(a,e.version))return{name:e.name,version:a}}catch{}if(i.length===1)return{name:e.name,version:i[0]}}},ja=(e,t,i={})=>{const a=i.maxPathsPerTarget??Sa,n=i.maxDepth??Aa;if(a<=0)return[];const{adjacency:r,versionsByName:o}=Ca(e),l=`${t.name}@${t.version}`,c=[],d=[],m=new Set;for(const v of e.roots){const y=Ra(v,o);if(!y)continue;const g=`${y.name}@${y.version}`;m.has(g)||(m.add(g),d.push(y))}const b=[];for(const v of d){const y=`${v.name}@${v.version}`;if(y===l){if(c.push([v]),c.length>=a)return c;continue}b.push({node:v,path:[v],visited:new Set([y])})}let h=0;for(;h<b.length&&c.length<a;){const v=b[h];if(h+=1,v.path.length>=n)continue;const y=r.get(`${v.node.name}@${v.node.version}`)?.children??[];for(const g of y){const $=`${g.name}@${g.version}`;if(v.visited.has($))continue;const x=[...v.path,g];if($===l){if(c.push(x),c.length>=a)return c;continue}const N=new Set(v.visited);N.add($),b.push({node:g,path:x,visited:N})}}return c},Ia={"crates.io":["Cargo.lock"],Go:["go.sum"],Maven:["gradle.lockfile","pom.xml"],PyPI:["uv.lock","poetry.lock","Pipfile.lock"],RubyGems:["Gemfile.lock"]},Ea={cargo:"crates.io","crates.io":"crates.io",go:"Go",maven:"Maven",npm:"npm",pypi:"PyPI",rubygems:"RubyGems"},bt=e=>Ea[e.toLowerCase()]??e,Da=(e,t)=>{const i=bt(t),a=Ia[i]??[];for(const n of a){const r=z(e,n);if(vi(r))return r}},Oa=e=>{const t=new Set,i=[];for(const a of e){const n=`${a.name}@${a.version}`;t.has(n)||(t.add(n),i.push(a))}return i},Ma=/\[\[package\]\]([\s\S]*?)(?=\[\[|$)/g,La=/^\s*name\s*=\s*"([^"]+)"\s*$/m,Pa=/^\s*version\s*=\s*"([^"]+)"\s*$/m,Ta=e=>{const t=[];for(const i of e.matchAll(Ma)){const a=i[1]??"",n=La.exec(a)?.[1],r=Pa.exec(a)?.[1];n&&r&&t.push({isDev:!1,name:n,version:r})}return t},Va=e=>{let t;try{t=JSON.parse(e)}catch{return[]}if(typeof t!="object"||t===null)return[];const i=[];for(const a of["default","develop"]){const n=t[a];if(!(typeof n!="object"||n===null))for(const[r,o]of Object.entries(n)){if(typeof o!="object"||o===null)continue;const l=o.version;if(typeof l!="string")continue;const c=l.replace(/^==/,"").trim();c.length>0&&i.push({isDev:!1,name:r,version:c})}}return i},za=/<dependency>([\s\S]*?)<\/dependency>/g,Wa=/<groupId>\s*([^<\s]+)\s*<\/groupId>/,_a=/<artifactId>\s*([^<\s]+)\s*<\/artifactId>/,Ha=/<version>\s*([^<\s]+)\s*<\/version>/,Ua=e=>{const t=[];for(const i of e.matchAll(za)){const a=i[1]??"",n=Wa.exec(a)?.[1],r=_a.exec(a)?.[1],o=Ha.exec(a)?.[1];!n||!r||!o||o.startsWith("${")||t.push({isDev:!1,name:`${n}:${r}`,version:o})}return t},Fa=e=>{const t=[];for(const i of e.split(/\r?\n/)){const a=i.trim();if(a.length===0||a.startsWith("#"))continue;const n=a.indexOf("="),r=(n===-1?a:a.slice(0,n)).split(":");if(r.length<3)continue;const[o,l,c]=r;!o||!l||!c||t.push({isDev:!1,name:`${o}:${l}`,version:c})}return t},Ga=e=>{const t=[];for(const i of e.split(/\r?\n/)){const a=i.trim();if(a.length===0)continue;const n=a.split(/\s+/);if(n.length<3)continue;const[r,o]=n;if(!r||!o?.endsWith("/go.mod"))continue;const l=o.slice(0,-7);l.length!==0&&t.push({isDev:!1,name:r,version:l})}return t},Ba=/^ {4}([^ ()]+) \(([^()]+)\)\s*$/,qa=e=>{const t=[];let i=!1,a=!1;for(const n of e.split(/\r?\n/)){if(n.startsWith("GEM")){i=!0,a=!1;continue}if(i&&/^[A-Z]/.test(n)){i=!1,a=!1;continue}if(i&&n.trim()==="specs:"){a=!0;continue}if(a){const r=Ba.exec(n);if(r){const[,o,l]=r;o&&l&&t.push({isDev:!1,name:o,version:l})}}}return t},Ka=(e,t)=>{const i=Da(e,t);if(!i)return[];let a;try{a=mt(i,"utf8")}catch{return[]}const n=i.split(/[/\\]/).pop()??"";let r;switch(n){case"Cargo.lock":case"poetry.lock":case"uv.lock":{r=Ta(a);break}case"Gemfile.lock":{r=qa(a);break}case"go.sum":{r=Ga(a);break}case"gradle.lockfile":{r=Fa(a);break}case"Pipfile.lock":{r=Va(a);break}case"pom.xml":{r=Ua(a);break}default:return[]}return Oa(r)},Ja=["ts","tsx","js","jsx","mjs","cjs","mts","cts"],Ya=[/node_modules/,/\.git/,/\.next/,/\.cache/,/dist/,/build/,/coverage/,/\.turbo/,/\.nx/,/\.parcel-cache/],Za=["dependencies","devDependencies","peerDependencies","optionalDependencies"],Xa=/(?:import|export)\s+(?:[\s\S]*?from\s+)?["']([^"'\n]+)["']/g,Qa=/(?:^|[^.\w$])require\s*\(\s*["']([^"'\n]+)["']\s*\)/g,en=/\bimport\s*\(\s*["']([^"'\n]+)["']\s*\)/g,tn=e=>{if(e.startsWith(".")||e.startsWith("/")||/^[a-z][a-z0-9+.-]*:/i.test(e))return;const t=e.trim();if(t.length!==0){if(t.startsWith("@")){const i=t.split("/");return i.length<2?void 0:`${i[0]}/${i[1]}`}return t.split("/")[0]}},an=e=>{const t=new Set,i=e.replaceAll(/\/\*[\s\S]*?\*\//g,"").replaceAll(/(^|[^:])\/\/.*$/gm,"$1"),a=n=>{n.lastIndex=0;let r;for(;(r=n.exec(i))!==null;){const o=tn(r[1]);o&&t.add(o)}};return a(Xa),a(Qa),a(en),t},nn=e=>{const t=new Set;try{const i=ut(e);for(const a of Za){const n=i[a];if(n&&typeof n=="object"&&!Array.isArray(n))for(const r of Object.keys(n))t.add(r)}}catch{}return t},on=e=>{const t=e.skip??Ya,i=e.extensions??Ja,a=new Set;let n=0;const r=it(e.workspaceRoot,{extensions:i,includeDirs:!1,skip:t});for(const c of r){n+=1;try{const d=mt(c,"utf8");for(const m of an(d))a.add(m)}catch{}}const o=it(e.workspaceRoot,{extensions:["json"],includeDirs:!1,skip:t}).filter(c=>c.endsWith("/package.json")||c.endsWith(String.raw`\package.json`)||c.endsWith("package.json"));for(const c of o)for(const d of nn(c))a.add(d);if(e.alwaysAssumeUsed)for(const c of e.alwaysAssumeUsed)a.add(c);const l=new Set;for(const c of e.vulnerablePackages)a.has(c)&&l.add(c);return{filesScanned:n,importedTotal:a,reachable:l}},rn=e=>{const t=L.coerce(e)?.major;return t!==void 0&&t>=10},sn=e=>Object.fromEntries(Object.entries(e).sort(([t],[i])=>t.localeCompare(i))),ln=(e,t)=>`${JSON.stringify(e,void 0,t)}
297
297
  `,xt=(e,t)=>{if(t.name==="pnpm"&&rn(t.version))return{filePath:z(e,"pnpm-workspace.yaml"),surface:"pnpm-workspace.yaml"};const i=z(e,"package.json");return t.name==="pnpm"?{filePath:i,surface:"package.json#pnpm.overrides"}:t.name==="yarn"?{filePath:i,surface:"package.json#resolutions"}:{filePath:i,surface:"package.json#overrides"}},cn=(e,t)=>{const{filePath:i,surface:a}=xt(e,t);if(!J(i))return{};if(a==="pnpm-workspace.yaml")try{return Ve(i)?.overrides??{}}catch{return{}}try{const n=JSON.parse(be(i));return a==="package.json#pnpm.overrides"?(n.pnpm??{}).overrides??{}:a==="package.json#resolutions"?n.resolutions??{}:n.overrides??{}}catch{return{}}},pn=(e,t)=>{const i=Object.keys(t).sort();if(i.length===0&&!/^overrides\s*:/m.test(e))return e;const a=`overrides:
298
298
  ${i.map(n=>` '${n}': '${t[n]}'`).join(`
299
299
  `)}
@@ -303,20 +303,20 @@ ${i.map(n=>` '${n}': '${t[n]}'`).join(`
303
303
  `)?e:`${e}
304
304
  `}
305
305
  ${a}`},dn=(e,t,i,a)=>{const n=Jt(e,t.length>0?t:void 0),r=t.length>0?JSON.parse(t):{};if(i==="package.json#pnpm.overrides"){const o=r.pnpm??{};o.overrides=a,r.pnpm=o}else i==="package.json#resolutions"?r.resolutions=a:r.overrides=a;return ln(r,n)},gn=(e,t,i)=>{const{filePath:a,surface:n}=xt(e,i),r=cn(e,i),o=J(a)?be(a):"",l=[],c={...r};for(const h of t.entries){const v=r[h.packageName];if(v===h.spec){l.push({...h,previousSpec:v,status:"unchanged"});continue}v===void 0?l.push({...h,status:"added"}):l.push({...h,previousSpec:v,status:"updated"}),c[h.packageName]=h.spec}const d=sn(c),m=l.some(h=>h.status!=="unchanged"),b=n==="pnpm-workspace.yaml"?pn(o,d):dn(a,o,n,d);return{changed:m,entries:l,filePath:a,nextContent:b,previousContent:o,surface:n}},fn=e=>{if(!e.changed)return e;if(e.surface==="pnpm-workspace.yaml"&&e.previousContent.length===0)throw new Error(`${e.filePath} not found. Run \`pnpm init\` or create pnpm-workspace.yaml before applying overrides for pnpm v10+.`);const t=`${e.filePath}.tmp`;try{wi(t,e.nextContent),yi(t,e.filePath)}catch(i){try{bi(t)}catch{}throw i}return e},un=e=>{const t=new Map;for(const i of e){const a=i.vulnerability.fixedVersions[0];if(!a)continue;const n=L.coerce(a),r=n?`^${n.version}`:a;t.set(i.packageName,r)}return{entries:[...t.entries()].sort(([i],[a])=>i.localeCompare(a)).map(([i,a])=>({packageName:i,spec:a}))}},mn={critical:we,high:dt,low:pt,medium:ye},Pe=new Set(["cargo","crates.io","go","maven","npm","pypi","rubygems"]),hn=e=>{const t=(e??"npm").split(",").map(n=>n.trim()).filter(n=>n.length>0),i=t.length>0?t:["npm"],a=i.filter(n=>!Pe.has(n.toLowerCase()));return{all:i,unsupported:a}},vn={CRITICAL:we,HIGH:dt,LOW:pt,MODERATE:ye,UNKNOWN:O},wn=(e,t,i,a)=>{const n=vn[i.severity]??O,r=a?` ${O("[acknowledged]")}`:"",o=i.fixedVersions??[],l=o.length>0?` (fix: ${o.join(", ")})`:"";return` ${n(i.severity)} ${i.id} — ${e}@${t}${r}
306
- ${i.summary}${l}`},yn=(e,t)=>{const i=Ai(e),a=`${String(Math.round(e.score.overall*100))}%`,n=t?` ${O("[acknowledged]")}`:"",r=e.alerts.length>0?`, ${String(e.alerts.length)} alert${e.alerts.length===1?"":"s"}`:"";return` ${a} ${i}@${e.version} (${Ni(e.score.overall)}${r})${n}`},bn=new Set(["aube","auto","vis"]),te=e=>e!==void 0&&bn.has(e),xn=(e,t,i)=>{if(e!==void 0&&!te(e))throw new Error(`Invalid --backend value '${e}'. Expected one of: aube, auto, vis.`);const a=process.env.VIS_AUDIT_BACKEND;if(a!==void 0&&a!==""&&!te(a))throw new Error(`Invalid VIS_AUDIT_BACKEND value '${a}'. Expected one of: aube, auto, vis.`);const n=te(a)?a:void 0,r=te(t)?t:void 0,o=(te(e)?e:void 0)??n??r??"auto";return o==="aube"?"aube":o==="vis"?"vis":(i?.install?.backend??process.env.VIS_INSTALLER)==="aube"&&Vt("aube")!==null?"aube":"vis"},kn=e=>{if(e!==void 0)switch(e){case"critical":return"critical";case"high":return"high";case"low":return"low";case"medium":return"moderate";default:return e}},$n=(e,t,i)=>{const a=["audit"],n=kn(t.severity);n!==void 0&&a.push("--audit-level",n),(t.prodOnly===!0||t.prod===!0)&&a.push("--prod"),(t.json===!0||t.format==="json")&&a.push("--json");const r=t.fix===!0;t["fix-transitive"]===!0||t.fixTransitive===!0?a.push("--fix=override"):r&&a.push("--fix=update");const o=[];t.offline===!0&&o.push("--offline (aube has its own offline cache)"),(t.format==="sarif"||t.format==="csaf"||t.format==="cyclonedx"||t.format==="cyclonedx-vex"||t.format==="gitlab"||t.format==="junit")&&o.push(`--format=${String(t.format)} (only json/text is forwarded to aube)`),o.length>0&&u.warn(`Delegating to 'aube audit'. Skipping vis-only flags: ${o.join(", ")}`);const l=Mt("aube",a,{cwd:e,stdio:"inherit"});if(l.error){const{code:c}=l.error;return c==="ENOENT"?u.error("Backend 'aube' selected but the 'aube' binary was not found on PATH. Install aube or run with --backend vis."):u.error(`Failed to spawn aube: ${l.error.message}`),1}return l.status??1},Sn=async(e,t,i,a,n)=>{if(xn(i.backend,a?.security?.audit?.backend,a)==="aube"){process.exitCode=$n(t,i);return}const r=i.severity??"low",o=i.format??"table",l=o==="sarif",c=o==="csaf",d=o==="cyclonedx-vex"||o==="cyclonedx",m=o==="gitlab",b=o==="junit",h=o==="json"||!!i.json,v=i.report,y=a?.security?.audit,g=a?.security?.policies,$=i.offline===void 0?!!y?.offlineByDefault:!!i.offline,x=i.db,A=hn(i.ecosystem),K=!!i.prodOnly,M=i.failOn??g?.vulnerability?.failOn,St=!!i.showFixes,ne=!!i.showAccepted,$e=a?.security?.acceptedRisks,We=g?.vulnerability?.usage,Nt=i.noUsage?!1:i.usage===void 0?!!We?.enabled:!!i.usage,I=h||l||c||d||m||b,_e=i.explain,Se=_e!==void 0,He=Se&&!l&&!c&&!d&&!m&&!b;if(Se&&$){u.error("`--explain` needs network access and cannot run in offline mode (--offline or security.audit.offlineByDefault)."),process.exitCode=1;return}Se&&!He&&u.warn(`\`--explain\` has no effect with --format=${o}; explanations are only rendered in table, json, and HTML output.`);const D=ti(t),C=Pi(t,D.name);if($){const s=x??gi(t);if(!await e.access(s).then(()=>!0).catch(()=>!1)){const p=new Qe(s);I?process.stderr.write(`${p.message}
307
- `):u.error(p.message),process.exitCode=1;return}}!I&&(C.ignoredAdvisories.length>0||C.excludedPackages.length>0)&&u.info(`Loaded ${String(C.ignoredAdvisories.length)} ignored advisor${C.ignoredAdvisories.length===1?"y":"ies"} and ${String(C.excludedPackages.length)} excluded package${C.excludedPackages.length===1?"":"s"} from ${D.name} config.`),!I&&A.unsupported.length>0&&u.warn(`Ecosystems ${A.unsupported.map(s=>`'${s}'`).join(", ")} are not yet supported by the audit matcher. Supported: npm, pypi, crates.io, cargo, maven, go, rubygems.`);const T=fi(t,D.name,{includeDev:!K});if(T.length===0){u.info(`No ${D.name} lockfile entries found. Run ${D.name} install first.`);return}if(!I){const s=K?"production-only packages":"installed packages";u.info(`Scanning ${String(T.length)} ${s}${$?" (offline)":""}…`)}const oe=T.map(s=>({name:s.name,version:s.version})),re=a?.security?.audit?.advisories?.bloom?.mode??"off";let W=[];if(re!=="off")try{const s=await xi(t,{softFail:re==="on"});if(s){if(W=ki(s,oe).map(p=>({name:p.name,version:p.version})),!I&&W.length>0){u.warn(`osv-bloom prefilter flagged ${String(W.length)} package${W.length===1?"":"s"} as possibly malicious (MAL-*). Confirming via the advisory query path…`);const p=10;for(const f of W.slice(0,p))u.warn(` ${we("[bloom]")} ${f.name}@${f.version}`);W.length>p&&u.warn(` …and ${String(W.length-p)} more (full list in --format json output)`)}}else I||u.info(O("osv-bloom cache absent — skipping prefilter (run `vis advisories bloom sync` to enable)."))}catch(s){if(s instanceof $i&&re==="required"){const f=`${s.message} (security.audit.advisories.bloom.mode = "required")`;I?process.stderr.write(`${f}
308
- `):u.error(f),process.exitCode=1;return}const p=s instanceof Error?s.message:String(s);if(re==="required"){I?process.stderr.write(`osv-bloom prefilter failed: ${p}
309
- `):u.error(`osv-bloom prefilter failed: ${p}`),process.exitCode=1;return}I||u.warn(`osv-bloom prefilter failed (continuing): ${p}`)}const se=new Set;$?se.add("socket").add("deps-dev"):(Xe("socket")&&se.add("socket"),Xe("depsDev")&&se.add("deps-dev"));const Ne=Yt(a?.security,{disabled:se,minimumScore:g?.score?.minimum}),Ae=Ne.length>0,At=Ne.map(s=>s.displayName).join(" + "),le=g?.score?.minimum??Si,G=ui(t,D.name),Ct=[{id:"vulnerabilities",label:$?"Known vulnerabilities (offline OSV cache)":"Known vulnerabilities (OSV)"},...Ae?[{id:"security",label:`Supply-chain reports (${At})`}]:[]],V=di(Ct,{live:!I}),Rt=Date.now(),B=s=>{const p=Date.now()-s;return p>=1e3?`${(p/1e3).toFixed(1)}s`:`${String(Math.round(p))}ms`};let Ce,Re;try{const s=Date.now(),p=Date.now();V.start("vulnerabilities"),Ae&&V.start("security");const f=$?Promise.resolve().then(()=>et(oe,{dbPath:x,ecosystem:A.all.find(w=>Pe.has(w.toLowerCase()))??"npm",workspaceRoot:t})).then(w=>{let k=0;for(const N of w.values())k+=N.length;return V.finish("vulnerabilities",k>0?"warn":"ok",k>0?`${String(k)} found · ${B(s)}`:`none found · ${B(s)}`),w}).catch(w=>{const k=w instanceof Error?w.message:String(w);if(V.finish("vulnerabilities","error",k),w instanceof Qe)throw w;return new Map}):Zt(oe).then(w=>{let k=0;for(const N of w.values())k+=N.length;return V.finish("vulnerabilities",k>0?"warn":"ok",k>0?`${String(k)} found · ${B(s)}`:`none found · ${B(s)}`),w}).catch(w=>{const k=w instanceof Error?w.message:String(w);return V.finish("vulnerabilities","error",k),new Map});[Ce,Re]=await Promise.all([f,Ae?Xt(Ne,oe).then(w=>{let k=0,N=0;for(const Q of w.values())k+=Q.alerts.length,Q.score.overall<le&&(N+=1);const E=k+N;return V.finish("security",E>0?"warn":"ok",E>0?`${String(k)} alert${k===1?"":"s"}, ${String(N)} low-score · ${B(p)}`:`clean · ${B(p)}`),w}).catch(w=>{const k=w instanceof Error?w.message:String(w);return V.finish("security","error",k),new Map}):Promise.resolve(new Map)])}finally{V.stop()}h||u.info(O(`Scan completed in ${B(Rt)}`));const ce=[];for(const s of T){if(Ti(s.name,C))continue;const p=Ce.get(s.name)??[],f=Re.get(`${s.name}@${s.version}`),w=tt(s.name,s.version,$e),k=p.length>0,N=f?f.score.overall<le:!1,E=f?f.alerts.length>0:!1;(k||N||E)&&ce.push({acceptedRisk:w,name:s.name,socketReport:f,version:s.version,vulnerabilities:p})}if($){const s=A.all.filter(p=>Pe.has(p.toLowerCase())&&p.toLowerCase()!=="npm");for(const p of s){const f=bt(p),w=Ka(t,f);if(w.length!==0){I||u.info(O(`Scanning ${String(w.length)} ${f} packages…`));try{const k=et(w.map(N=>({name:N.name,version:N.version})),{dbPath:x,ecosystem:f,workspaceRoot:t});for(const N of w){const E=k.get(N.name)??[];E.length!==0&&ce.push({acceptedRisk:tt(N.name,N.version,$e),name:N.name,version:N.version,vulnerabilities:E})}}catch(k){const N=k instanceof Error?k.message:String(k);u.warn(`Failed to scan ${f}: ${N}`)}}}}let R=ce.filter(s=>{const p=s.vulnerabilities.some(k=>he(k.severity,r)),f=s.socketReport?.alerts.some(k=>he(k.severity==="medium"?"MODERATE":k.severity.toUpperCase(),r)),w=s.socketReport&&s.socketReport.score.overall<le;return p||f||w});const It=i.policies,Ue=[],j=await(async()=>{const s=oi().map(E=>`'${E}'`).join(", "),p=ai(It,E=>{Ue.push(E);const Q=`Unknown policy '${E}' — ignoring. Available: ${s}.`;I?process.stderr.write(`vis audit: ${Q}
310
- `):u.warn(Q)});if(p?.size===0)return[];const f=a?.security?.policies?.license,w=!!(f&&((f.allow?.length??0)>0||(f.deny?.length??0)>0)),k=p===void 0||p.has("license"),N=w&&k?hi(t):void 0;return ni({manifestData:N,offline:$,osvFindings:Ce,packageManager:D.name,packages:T,socketReports:Re,workspaceRoot:t},"audit",{enabledPolicies:p,visConfig:a??{}})})();if(Nt){const s=new Set(R.filter(f=>f.vulnerabilities.length>0).map(f=>f.name)),p=on({alwaysAssumeUsed:We?.alwaysAssumeUsed,vulnerablePackages:s,workspaceRoot:t});R=R.filter(f=>f.vulnerabilities.length===0?!0:p.reachable.has(f.name)),I||u.info(O(`Reachability filter: ${String(p.reachable.size)}/${String(s.size)} vulnerable packages reachable (${String(p.filesScanned)} files scanned).`))}const Fe=mi(t,D.name),Ge=Fe?R.map(s=>{const p=Ia(Fe,{name:s.name,version:s.version});return{...s,dependencyPaths:p}}):R.map(s=>({...s,dependencyPaths:[]})),_=()=>Ge.flatMap(s=>s.vulnerabilities.map(p=>({acknowledged:!!s.acceptedRisk||ae(p.id,C,p.aliases),dependencyPaths:s.dependencyPaths,packageName:s.name,packageVersion:s.version,vulnerability:p}))),Be=!!i.fix,qe=!!i.fixTransitive,Ke=!!i.yes,jt=!!i.allowMajor;if(Be||qe){const s=_().filter(p=>!p.acknowledged);if(Be){const p=await An({actionableFindings:s,allowMajor:jt,pm:D,workspaceRoot:t,yes:Ke});if(p!==void 0){process.exitCode=p;return}}if(qe){const p=await Cn({actionableFindings:s,pm:D,visConfig:a,workspaceRoot:t,yes:Ke});if(p!==void 0){process.exitCode=p;return}}}const pe=new Map;if(He){const s=Ri(_().filter(f=>!f.acknowledged).map(f=>({packageName:f.packageName,packageVersion:f.packageVersion,vulnerability:f.vulnerability})).sort(gt),_e),p=await Li(s,a?.ai,{info:f=>{u.info(f)},warn:f=>{u.warn(f)}});for(const[f,w]of p)pe.set(f,w)}if(l){const s=va({findings:_(),policyDecisions:j,tool:{informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"},workspaceRoot:t});process.stdout.write(`${JSON.stringify(s,void 0,2)}
311
- `),ie(R,C,i.exitCode,M,j);return}if(c){const s=ra({findings:_(),tool:{informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"}});process.stdout.write(`${JSON.stringify(s,void 0,2)}
312
- `),ie(R,C,i.exitCode,M,j);return}if(d){const{packageJsons:s,workspace:p}=Qt(t,a),f=ei(t,p,s),w=li({includeDev:!K,projectGraph:f,workspace:p,workspaceRoot:t}),k=ca({bom:w,findings:_()});process.stdout.write(`${JSON.stringify(k,void 0,2)}
313
- `),ie(R,C,i.exitCode,M,j);return}if(m){const s=ua({findings:_(),policyDecisions:j,tool:{informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"},workspaceRoot:t});process.stdout.write(`${JSON.stringify(s,void 0,2)}
314
- `),ie(R,C,i.exitCode,M,j);return}if(b){const s=ha({findings:_(),policyDecisions:j});process.stdout.write(s),ie(R,C,i.exitCode,M,j);return}const Ie={informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"},de=Wi({bloomHits:W,duplicates:G,explanations:pe,filtered:Ge,packagesScanned:T.length,policyDecisions:j,tool:Ie,unknownPolicyTokens:Ue,workspaceRoot:t});if(v){const s=na({findings:_().map(f=>{const w=pe.get(xe({packageName:f.packageName,packageVersion:f.packageVersion,vulnerability:f.vulnerability}));return w?{...f,explanation:w}:f}),packagesScanned:T.length,policyDecisions:j,report:de,tool:{name:Ie.name,version:Ie.version}}),p=Tt(t,v);await e.writeFile(p,s,"utf8"),I||u.success(`HTML report written to ${p}`)}if(h){process.stdout.write(`${JSON.stringify(de,void 0,2)}
315
- `),i.exitCode&&(de.summary.issues>0||de.summary.policyBlocks>0)&&(process.exitCode=1),Te(R,C,M,j);return}if(R.length===0){u.success(`No security issues found across ${String(T.length)} packages.`);return}const Z={CRITICAL:[],HIGH:[],LOW:[],MODERATE:[]};for(const s of R)for(const p of s.vulnerabilities)if(he(p.severity,r)){const f=p.severity==="UNKNOWN"?"LOW":p.severity;Z[f]?.push({entry:s,vuln:p})}let ge=0,je=0;for(const s of["CRITICAL","HIGH","MODERATE","LOW"]){const p=Z[s];if(!(!p||p.length===0)){u.info(`
316
- ── ${s} (${String(p.length)}) ──`);for(const{entry:f,vuln:w}of p){const k=!!f.acceptedRisk||ae(w.id,C,w.aliases);if(k&&(je++,!ne))continue;ge++,u.info(wn(f.name,f.version,w,k)),St&&(w.fixedVersions??[]).length>0&&u.notice(` Fix: update to ${w.fixedVersions.at(-1)}`);const N=pe.get(xe({packageName:f.name,packageVersion:f.version,vulnerability:w}));if(N)for(const E of N.split(`
306
+ ${i.summary}${l}`},yn=(e,t)=>{const i=Ni(e),a=`${String(Math.round(e.score.overall*100))}%`,n=t?` ${O("[acknowledged]")}`:"",r=e.alerts.length>0?`, ${String(e.alerts.length)} alert${e.alerts.length===1?"":"s"}`:"";return` ${a} ${i}@${e.version} (${Ai(e.score.overall)}${r})${n}`},bn=new Set(["aube","auto","vis"]),te=e=>e!==void 0&&bn.has(e),xn=(e,t,i)=>{if(e!==void 0&&!te(e))throw new Error(`Invalid --backend value '${e}'. Expected one of: aube, auto, vis.`);const a=process.env.VIS_AUDIT_BACKEND;if(a!==void 0&&a!==""&&!te(a))throw new Error(`Invalid VIS_AUDIT_BACKEND value '${a}'. Expected one of: aube, auto, vis.`);const n=te(a)?a:void 0,r=te(t)?t:void 0,o=(te(e)?e:void 0)??n??r??"auto";return o==="aube"?"aube":o==="vis"?"vis":(i?.install?.backend??process.env.VIS_INSTALLER)==="aube"&&Vt("aube")!==null?"aube":"vis"},kn=e=>{if(e!==void 0)switch(e){case"critical":return"critical";case"high":return"high";case"low":return"low";case"medium":return"moderate";default:return e}},$n=(e,t,i)=>{const a=["audit"],n=kn(t.severity);n!==void 0&&a.push("--audit-level",n),(t.prodOnly===!0||t.prod===!0)&&a.push("--prod"),(t.json===!0||t.format==="json")&&a.push("--json");const r=t.fix===!0;t["fix-transitive"]===!0||t.fixTransitive===!0?a.push("--fix=override"):r&&a.push("--fix=update");const o=[];t.offline===!0&&o.push("--offline (aube has its own offline cache)"),(t.format==="sarif"||t.format==="csaf"||t.format==="cyclonedx"||t.format==="cyclonedx-vex"||t.format==="gitlab"||t.format==="junit")&&o.push(`--format=${String(t.format)} (only json/text is forwarded to aube)`),o.length>0&&u.warn(`Delegating to 'aube audit'. Skipping vis-only flags: ${o.join(", ")}`);const l=Mt("aube",a,{cwd:e,stdio:"inherit"});if(l.error){const{code:c}=l.error;return c==="ENOENT"?u.error("Backend 'aube' selected but the 'aube' binary was not found on PATH. Install aube or run with --backend vis."):u.error(`Failed to spawn aube: ${l.error.message}`),1}return l.status??1},Sn=async(e,t,i,a,n)=>{if(xn(i.backend,a?.security?.audit?.backend,a)==="aube"){process.exitCode=$n(t,i);return}const r=i.severity??"low",o=i.format??"table",l=o==="sarif",c=o==="csaf",d=o==="cyclonedx-vex"||o==="cyclonedx",m=o==="gitlab",b=o==="junit",h=o==="json"||!!i.json,v=i.report,y=a?.security?.audit,g=a?.security?.policies,$=i.offline===void 0?!!y?.offlineByDefault:!!i.offline,x=i.db,N=hn(i.ecosystem),K=!!i.prodOnly,M=i.failOn??g?.vulnerability?.failOn,St=!!i.showFixes,ne=!!i.showAccepted,$e=a?.security?.acceptedRisks,We=g?.vulnerability?.usage,At=i.noUsage?!1:i.usage===void 0?!!We?.enabled:!!i.usage,j=h||l||c||d||m||b,_e=i.explain,Se=_e!==void 0,He=Se&&!l&&!c&&!d&&!m&&!b;if(Se&&$){u.error("`--explain` needs network access and cannot run in offline mode (--offline or security.audit.offlineByDefault)."),process.exitCode=1;return}Se&&!He&&u.warn(`\`--explain\` has no effect with --format=${o}; explanations are only rendered in table, json, and HTML output.`);const D=ti(t),C=Pi(t,D.name);if($){const s=x??gi(t);if(!await e.access(s).then(()=>!0).catch(()=>!1)){const p=new Qe(s);j?process.stderr.write(`${p.message}
307
+ `):u.error(p.message),process.exitCode=1;return}}!j&&(C.ignoredAdvisories.length>0||C.excludedPackages.length>0)&&u.info(`Loaded ${String(C.ignoredAdvisories.length)} ignored advisor${C.ignoredAdvisories.length===1?"y":"ies"} and ${String(C.excludedPackages.length)} excluded package${C.excludedPackages.length===1?"":"s"} from ${D.name} config.`),!j&&N.unsupported.length>0&&u.warn(`Ecosystems ${N.unsupported.map(s=>`'${s}'`).join(", ")} are not yet supported by the audit matcher. Supported: npm, pypi, crates.io, cargo, maven, go, rubygems.`);const T=fi(t,D.name,{includeDev:!K});if(T.length===0){u.info(`No ${D.name} lockfile entries found. Run ${D.name} install first.`);return}if(!j){const s=K?"production-only packages":"installed packages";u.info(`Scanning ${String(T.length)} ${s}${$?" (offline)":""}…`)}const oe=T.map(s=>({name:s.name,version:s.version})),re=a?.security?.audit?.advisories?.bloom?.mode??"off";let W=[];if(re!=="off")try{const s=await xi(t,{softFail:re==="on"});if(s){if(W=ki(s,oe).map(p=>({name:p.name,version:p.version})),!j&&W.length>0){u.warn(`osv-bloom prefilter flagged ${String(W.length)} package${W.length===1?"":"s"} as possibly malicious (MAL-*). Confirming via the advisory query path…`);const p=10;for(const f of W.slice(0,p))u.warn(` ${we("[bloom]")} ${f.name}@${f.version}`);W.length>p&&u.warn(` …and ${String(W.length-p)} more (full list in --format json output)`)}}else j||u.info(O("osv-bloom cache absent — skipping prefilter (run `vis advisories bloom sync` to enable)."))}catch(s){if(s instanceof $i&&re==="required"){const f=`${s.message} (security.audit.advisories.bloom.mode = "required")`;j?process.stderr.write(`${f}
308
+ `):u.error(f),process.exitCode=1;return}const p=s instanceof Error?s.message:String(s);if(re==="required"){j?process.stderr.write(`osv-bloom prefilter failed: ${p}
309
+ `):u.error(`osv-bloom prefilter failed: ${p}`),process.exitCode=1;return}j||u.warn(`osv-bloom prefilter failed (continuing): ${p}`)}const se=new Set;$?se.add("socket").add("deps-dev"):(Xe("socket")&&se.add("socket"),Xe("depsDev")&&se.add("deps-dev"));const Ae=Yt(a?.security,{disabled:se,minimumScore:g?.score?.minimum}),Ne=Ae.length>0,Nt=Ae.map(s=>s.displayName).join(" + "),le=g?.score?.minimum??Si,G=ui(t,D.name),Ct=[{id:"vulnerabilities",label:$?"Known vulnerabilities (offline OSV cache)":"Known vulnerabilities (OSV)"},...Ne?[{id:"security",label:`Supply-chain reports (${Nt})`}]:[]],V=di(Ct,{live:!j}),Rt=Date.now(),B=s=>{const p=Date.now()-s;return p>=1e3?`${(p/1e3).toFixed(1)}s`:`${String(Math.round(p))}ms`};let Ce,Re;try{const s=Date.now(),p=Date.now();V.start("vulnerabilities"),Ne&&V.start("security");const f=$?Promise.resolve().then(()=>et(oe,{dbPath:x,ecosystem:N.all.find(w=>Pe.has(w.toLowerCase()))??"npm",workspaceRoot:t})).then(w=>{let k=0;for(const A of w.values())k+=A.length;return V.finish("vulnerabilities",k>0?"warn":"ok",k>0?`${String(k)} found · ${B(s)}`:`none found · ${B(s)}`),w}).catch(w=>{const k=w instanceof Error?w.message:String(w);if(V.finish("vulnerabilities","error",k),w instanceof Qe)throw w;return new Map}):Zt(oe).then(w=>{let k=0;for(const A of w.values())k+=A.length;return V.finish("vulnerabilities",k>0?"warn":"ok",k>0?`${String(k)} found · ${B(s)}`:`none found · ${B(s)}`),w}).catch(w=>{const k=w instanceof Error?w.message:String(w);return V.finish("vulnerabilities","error",k),new Map});[Ce,Re]=await Promise.all([f,Ne?Xt(Ae,oe).then(w=>{let k=0,A=0;for(const Q of w.values())k+=Q.alerts.length,Q.score.overall<le&&(A+=1);const E=k+A;return V.finish("security",E>0?"warn":"ok",E>0?`${String(k)} alert${k===1?"":"s"}, ${String(A)} low-score · ${B(p)}`:`clean · ${B(p)}`),w}).catch(w=>{const k=w instanceof Error?w.message:String(w);return V.finish("security","error",k),new Map}):Promise.resolve(new Map)])}finally{V.stop()}h||u.info(O(`Scan completed in ${B(Rt)}`));const ce=[];for(const s of T){if(Ti(s.name,C))continue;const p=Ce.get(s.name)??[],f=Re.get(`${s.name}@${s.version}`),w=tt(s.name,s.version,$e),k=p.length>0,A=f?f.score.overall<le:!1,E=f?f.alerts.length>0:!1;(k||A||E)&&ce.push({acceptedRisk:w,name:s.name,socketReport:f,version:s.version,vulnerabilities:p})}if($){const s=N.all.filter(p=>Pe.has(p.toLowerCase())&&p.toLowerCase()!=="npm");for(const p of s){const f=bt(p),w=Ka(t,f);if(w.length!==0){j||u.info(O(`Scanning ${String(w.length)} ${f} packages…`));try{const k=et(w.map(A=>({name:A.name,version:A.version})),{dbPath:x,ecosystem:f,workspaceRoot:t});for(const A of w){const E=k.get(A.name)??[];E.length!==0&&ce.push({acceptedRisk:tt(A.name,A.version,$e),name:A.name,version:A.version,vulnerabilities:E})}}catch(k){const A=k instanceof Error?k.message:String(k);u.warn(`Failed to scan ${f}: ${A}`)}}}}let R=ce.filter(s=>{const p=s.vulnerabilities.some(k=>he(k.severity,r)),f=s.socketReport?.alerts.some(k=>he(k.severity==="medium"?"MODERATE":k.severity.toUpperCase(),r)),w=s.socketReport&&s.socketReport.score.overall<le;return p||f||w});const jt=i.policies,Ue=[],I=await(async()=>{const s=oi().map(E=>`'${E}'`).join(", "),p=ai(jt,E=>{Ue.push(E);const Q=`Unknown policy '${E}' — ignoring. Available: ${s}.`;j?process.stderr.write(`vis audit: ${Q}
310
+ `):u.warn(Q)});if(p?.size===0)return[];const f=a?.security?.policies?.license,w=!!(f&&((f.allow?.length??0)>0||(f.deny?.length??0)>0)),k=p===void 0||p.has("license"),A=w&&k?hi(t):void 0;return ni({manifestData:A,offline:$,osvFindings:Ce,packageManager:D.name,packages:T,socketReports:Re,workspaceRoot:t},"audit",{enabledPolicies:p,visConfig:a??{}})})();if(At){const s=new Set(R.filter(f=>f.vulnerabilities.length>0).map(f=>f.name)),p=on({alwaysAssumeUsed:We?.alwaysAssumeUsed,vulnerablePackages:s,workspaceRoot:t});R=R.filter(f=>f.vulnerabilities.length===0?!0:p.reachable.has(f.name)),j||u.info(O(`Reachability filter: ${String(p.reachable.size)}/${String(s.size)} vulnerable packages reachable (${String(p.filesScanned)} files scanned).`))}const Fe=mi(t,D.name),Ge=Fe?R.map(s=>{const p=ja(Fe,{name:s.name,version:s.version});return{...s,dependencyPaths:p}}):R.map(s=>({...s,dependencyPaths:[]})),_=()=>Ge.flatMap(s=>s.vulnerabilities.map(p=>({acknowledged:!!s.acceptedRisk||ae(p.id,C,p.aliases),dependencyPaths:s.dependencyPaths,packageName:s.name,packageVersion:s.version,vulnerability:p}))),Be=!!i.fix,qe=!!i.fixTransitive,Ke=!!i.yes,It=!!i.allowMajor;if(Be||qe){const s=_().filter(p=>!p.acknowledged);if(Be){const p=await Nn({actionableFindings:s,allowMajor:It,pm:D,workspaceRoot:t,yes:Ke});if(p!==void 0){process.exitCode=p;return}}if(qe){const p=await Cn({actionableFindings:s,pm:D,visConfig:a,workspaceRoot:t,yes:Ke});if(p!==void 0){process.exitCode=p;return}}}const pe=new Map;if(He){const s=Ri(_().filter(f=>!f.acknowledged).map(f=>({packageName:f.packageName,packageVersion:f.packageVersion,vulnerability:f.vulnerability})).sort(gt),_e),p=await Li(s,a?.ai,{info:f=>{u.info(f)},warn:f=>{u.warn(f)}});for(const[f,w]of p)pe.set(f,w)}if(l){const s=va({findings:_(),policyDecisions:I,tool:{informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"},workspaceRoot:t});process.stdout.write(`${JSON.stringify(s,void 0,2)}
311
+ `),ie(R,C,i.exitCode,M,I);return}if(c){const s=ra({findings:_(),tool:{informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"}});process.stdout.write(`${JSON.stringify(s,void 0,2)}
312
+ `),ie(R,C,i.exitCode,M,I);return}if(d){const{packageJsons:s,workspace:p}=Qt(t,a),f=ei(t,p,s),w=li({includeDev:!K,projectGraph:f,workspace:p,workspaceRoot:t}),k=ca({bom:w,findings:_()});process.stdout.write(`${JSON.stringify(k,void 0,2)}
313
+ `),ie(R,C,i.exitCode,M,I);return}if(m){const s=ua({findings:_(),policyDecisions:I,tool:{informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"},workspaceRoot:t});process.stdout.write(`${JSON.stringify(s,void 0,2)}
314
+ `),ie(R,C,i.exitCode,M,I);return}if(b){const s=ha({findings:_(),policyDecisions:I});process.stdout.write(s),ie(R,C,i.exitCode,M,I);return}const je={informationUri:"https://github.com/visulima/visulima",name:"vis-audit",version:"alpha"},de=Wi({bloomHits:W,duplicates:G,explanations:pe,filtered:Ge,packagesScanned:T.length,policyDecisions:I,tool:je,unknownPolicyTokens:Ue,workspaceRoot:t});if(v){const s=na({findings:_().map(f=>{const w=pe.get(xe({packageName:f.packageName,packageVersion:f.packageVersion,vulnerability:f.vulnerability}));return w?{...f,explanation:w}:f}),packagesScanned:T.length,policyDecisions:I,report:de,tool:{name:je.name,version:je.version}}),p=Tt(t,v);await e.writeFile(p,s,"utf8"),j||u.success(`HTML report written to ${p}`)}if(h){process.stdout.write(`${JSON.stringify(de,void 0,2)}
315
+ `),i.exitCode&&(de.summary.issues>0||de.summary.policyBlocks>0)&&(process.exitCode=1),Te(R,C,M,I);return}if(R.length===0){u.success(`No security issues found across ${String(T.length)} packages.`);return}const Z={CRITICAL:[],HIGH:[],LOW:[],MODERATE:[]};for(const s of R)for(const p of s.vulnerabilities)if(he(p.severity,r)){const f=p.severity==="UNKNOWN"?"LOW":p.severity;Z[f]?.push({entry:s,vuln:p})}let ge=0,Ie=0;for(const s of["CRITICAL","HIGH","MODERATE","LOW"]){const p=Z[s];if(!(!p||p.length===0)){u.info(`
316
+ ── ${s} (${String(p.length)}) ──`);for(const{entry:f,vuln:w}of p){const k=!!f.acceptedRisk||ae(w.id,C,w.aliases);if(k&&(Ie++,!ne))continue;ge++,u.info(wn(f.name,f.version,w,k)),St&&(w.fixedVersions??[]).length>0&&u.notice(` Fix: update to ${w.fixedVersions.at(-1)}`);const A=pe.get(xe({packageName:f.name,packageVersion:f.version,vulnerability:w}));if(A)for(const E of A.split(`
317
317
  `))u.info(` ${E}`)}}}const X=R.filter(s=>s.socketReport&&(s.socketReport.score.overall<le||s.socketReport.alerts.length>0));if(X.length>0){u.info(`
318
318
  ── Socket.dev Supply Chain (${String(X.length)}) ──`);for(const s of X){if(!s.socketReport)continue;const p=!!s.acceptedRisk;if(!(p&&!ne)){u.info(yn(s.socketReport,p));for(const f of s.socketReport.alerts){const w=mn[f.severity]??O;u.info(` ${w(`[${f.severity.toUpperCase()}]`)} ${f.type} — ${f.category}`)}}}}if(G.length>0){u.info(`
319
- ── Duplicate Dependencies (${String(G.length)}) ──`);for(const s of G){const p=s.versions.join(", ");u.info(` ${s.name} — ${String(s.versions.length)} versions: ${ye(p)}`)}}const Je=new Set;for(const s of["CRITICAL","HIGH","MODERATE","LOW"]){const p=Z[s];if(p)for(const{vuln:f}of p)Je.add(f.id)}const Ee=j.filter(s=>{if(s.policy!=="vulnerability")return!0;const p=typeof s.data?.advisoryId=="string"?s.data.advisoryId:void 0;return s.severity==="block"&&p!==void 0&&!Je.has(p)});if(Ee.length>0){u.info(`
320
- ── Policy Decisions (${String(Ee.length)}) ──`);for(const s of Ee){const p=!!s.acceptedRisk;if(p&&!ne)continue;const f=s.severity==="block"?we:s.severity==="warn"?ye:O,w=p?` ${O("[acknowledged]")}`:"";u.info(` ${f(`[${s.severity}]`)} ${s.policy} — ${s.reason}${w}`)}}const fe=s=>!!s.acceptedRisk||s.vulnerabilities.length>0&&s.vulnerabilities.every(p=>ae(p.id,C,p.aliases)),Ye=R.filter(s=>!fe(s)).length;if(u.info(""),u.info("─ Audit Summary"),u.info(` ${String(T.length)} packages scanned`),C.ignoredAdvisories.length>0&&u.info(` ${String(C.ignoredAdvisories.length)} ${D.name} audit exclusion${C.ignoredAdvisories.length===1?"":"s"} applied`),ge>0){const s=Z.CRITICAL?.filter(f=>!fe(f.entry)).length??0,p=Z.HIGH?.filter(f=>!fe(f.entry)).length??0;u.error(` ${String(ge)} vulnerabilit${ge===1?"y":"ies"} found`),s>0&&u.error(` ${String(s)} critical`),p>0&&u.warn(` ${String(p)} high`)}else u.success(" No vulnerabilities found");if(X.length>0){const s=X.filter(p=>!fe(p)).length;u.warn(` ${String(s)} package${s===1?"":"s"} with Socket.dev supply chain issues`)}G.length>0&&(u.warn(` ${String(G.length)} package${G.length===1?"":"s"} with duplicate versions`),u.notice(" Run 'vis dedupe' or your package manager's dedupe command to reduce duplicates."));const ue=j.filter(s=>s.severity==="block"&&!s.acceptedRisk);if(ue.length>0&&u.error(` ${String(ue.length)} policy block${ue.length===1?"":"s"}`),je>0&&(u.info(` ${String(je)} acknowledged (accepted risks)`),ne||u.notice(" Use --show-accepted to see acknowledged issues.")),Ye===0&&u.success(`
319
+ ── Duplicate Dependencies (${String(G.length)}) ──`);for(const s of G){const p=s.versions.join(", ");u.info(` ${s.name} — ${String(s.versions.length)} versions: ${ye(p)}`)}}const Je=new Set;for(const s of["CRITICAL","HIGH","MODERATE","LOW"]){const p=Z[s];if(p)for(const{vuln:f}of p)Je.add(f.id)}const Ee=I.filter(s=>{if(s.policy!=="vulnerability")return!0;const p=typeof s.data?.advisoryId=="string"?s.data.advisoryId:void 0;return s.severity==="block"&&p!==void 0&&!Je.has(p)});if(Ee.length>0){u.info(`
320
+ ── Policy Decisions (${String(Ee.length)}) ──`);for(const s of Ee){const p=!!s.acceptedRisk;if(p&&!ne)continue;const f=s.severity==="block"?we:s.severity==="warn"?ye:O,w=p?` ${O("[acknowledged]")}`:"";u.info(` ${f(`[${s.severity}]`)} ${s.policy} — ${s.reason}${w}`)}}const fe=s=>!!s.acceptedRisk||s.vulnerabilities.length>0&&s.vulnerabilities.every(p=>ae(p.id,C,p.aliases)),Ye=R.filter(s=>!fe(s)).length;if(u.info(""),u.info("─ Audit Summary"),u.info(` ${String(T.length)} packages scanned`),C.ignoredAdvisories.length>0&&u.info(` ${String(C.ignoredAdvisories.length)} ${D.name} audit exclusion${C.ignoredAdvisories.length===1?"":"s"} applied`),ge>0){const s=Z.CRITICAL?.filter(f=>!fe(f.entry)).length??0,p=Z.HIGH?.filter(f=>!fe(f.entry)).length??0;u.error(` ${String(ge)} vulnerabilit${ge===1?"y":"ies"} found`),s>0&&u.error(` ${String(s)} critical`),p>0&&u.warn(` ${String(p)} high`)}else u.success(" No vulnerabilities found");if(X.length>0){const s=X.filter(p=>!fe(p)).length;u.warn(` ${String(s)} package${s===1?"":"s"} with Socket.dev supply chain issues`)}G.length>0&&(u.warn(` ${String(G.length)} package${G.length===1?"":"s"} with duplicate versions`),u.notice(" Run 'vis dedupe' or your package manager's dedupe command to reduce duplicates."));const ue=I.filter(s=>s.severity==="block"&&!s.acceptedRisk);if(ue.length>0&&u.error(` ${String(ue.length)} policy block${ue.length===1?"":"s"}`),Ie>0&&(u.info(` ${String(Ie)} acknowledged (accepted risks)`),ne||u.notice(" Use --show-accepted to see acknowledged issues.")),Ye===0&&u.success(`
321
321
  All issues are acknowledged. No action required.`),i.sync&&$e){const s=new Set;for(const f of ce)if(f.acceptedRisk){for(const w of f.vulnerabilities)if((w.id.startsWith("CVE-")||w.id.startsWith("GHSA-"))&&s.add(w.id),w.aliases)for(const k of w.aliases)(k.startsWith("CVE-")||k.startsWith("GHSA-"))&&s.add(k)}const p=[...s];if(p.length>0){u.info("");const f=Vi(D.name,t,p);for(const w of f)u.success(` ${w}`)}else u.info(`
322
- No advisory IDs to sync to native PM config.`)}i.exitCode&&(Ye>0||ue.length>0)&&(process.exitCode=1),Te(R,C,M,j)},kt=e=>!e||e.length===0?!1:e.some(t=>t.severity==="block"&&!t.acceptedRisk),Te=(e,t,i,a)=>{kt(a)&&(process.exitCode=1),i&&e.some(n=>n.vulnerabilities.some(r=>n.acceptedRisk||ae(r.id,t,r.aliases)?!1:he(r.severity,i)))&&(process.exitCode=1)},ie=(e,t,i,a,n)=>{i&&(e.filter(r=>!r.acceptedRisk&&r.vulnerabilities.some(o=>!ae(o.id,t,o.aliases))).length>0||kt(n))&&(process.exitCode=1),Te(e,t,a,n)},$t=async(e,t)=>{if(!process.stdin.isTTY)return t;const i=Lt({input:process.stdin,output:process.stderr});try{const a="[y/N]",n=await new Promise(r=>{i.question(`${e} ${O(a)} `,o=>{r(o.trim())})});return n.length===0?t:n.toLowerCase().startsWith("y")}finally{i.close()}},Nn=e=>e==="pnpm"||e==="npm"||e==="yarn"||e==="bun",An=async e=>{const t=yt({allowMajor:e.allowMajor,findings:e.actionableFindings,workspaceRoot:e.workspaceRoot});if(u.info(""),u.info("─ Apply (direct deps)"),u.info($a(t)),t.apply.length===0){u.info("Nothing to apply for direct deps.");return}if(Oe&&!e.yes)return u.error("Refusing to run --fix in CI without --yes. Re-run with --yes once the plan above looks right."),1;if(!e.yes&&!await $t("Apply these direct-dep upgrades?",!1))return u.info("Aborted — no changes made."),0;const i=new Map;for(const a of t.apply){const n=a.workspaceName??"",r=i.get(n);r?r.push(a):i.set(n,[a])}for(const[a,n]of i){const r=n.map(c=>`${c.packageName}@${c.targetSpec}`),o=a.length>0?[a]:[];u.info(`Running ${e.pm.name} add ${r.join(" ")}${a.length>0?` --filter ${a}`:""}`);const l=ii(e.pm,{exact:!1,filter:o,global:!1,optional:!1,packages:r,peer:!1,saveDev:!1,workspace:!1,workspaceRoot:!1},e.workspaceRoot,console);if(l!==0)return u.error(`${e.pm.name} add exited ${String(l)} — aborting before rescan.`),l}return u.success("Direct-dep upgrades applied. Re-run `vis audit` to confirm the fixes landed."),0},Cn=async e=>{if(!Nn(e.pm.name))return u.error(`--fix-transitive is not supported for package manager "${e.pm.name}". Use pnpm, npm, yarn, or bun.`),1;const t=!!e.visConfig?.security?.audit?.apply?.transitive?.enabled;if(Oe&&(!e.yes||!t))return u.error("Refusing to run --fix-transitive in CI without both --yes and security.audit.apply.transitive.enabled = true. Overrides have a higher blast radius than direct bumps — gate on config."),1;const i=new Set(yt({findings:e.actionableFindings,workspaceRoot:e.workspaceRoot}).apply.map(o=>o.packageName)),a=e.actionableFindings.filter(o=>!i.has(o.packageName)),n=un(a);if(n.entries.length===0){u.info(""),u.info("─ Apply transitive (overrides)"),u.info("Nothing to override — all vulnerable packages are direct deps or have no fixed version.");return}const r=gn(e.workspaceRoot,n,{name:e.pm.name,version:e.pm.version});u.info(""),u.info("─ Apply transitive (overrides)"),u.info(`Target: ${r.filePath} (${r.surface})`);for(const o of r.entries){const l=o.status==="added"?"+":o.status==="updated"?"~":"·",c=o.previousSpec?` (was ${o.previousSpec})`:"";u.info(` ${l} ${o.packageName}: ${o.spec}${c}`)}if(!r.changed){u.info("No changes — overrides already match the plan.");return}if(!e.yes){if(Oe)return 1;if(!await $t("Write these overrides?",!1))return u.info("Aborted — no changes made."),0}try{fn(r)}catch(o){const l=o instanceof Error?o.message:String(o);return u.error(`Failed to write overrides: ${l}`),1}return u.success(`Wrote ${String(r.entries.filter(o=>o.status!=="unchanged").length)} override${r.entries.length===1?"":"s"}. Run \`${e.pm.name} install\` then re-run \`vis audit\` to confirm the fixes landed.`),0},Jn=async({fs:e,logger:t,options:i,visConfig:a,workspaceRoot:n})=>{if(!n)throw new Error("Could not determine workspace root. Run this command inside a monorepo.");await Sn(e,n,i,a)};export{Jn as default,kn as mapSeverityToAube,xn as resolveAuditBackend};
322
+ No advisory IDs to sync to native PM config.`)}i.exitCode&&(Ye>0||ue.length>0)&&(process.exitCode=1),Te(R,C,M,I)},kt=e=>!e||e.length===0?!1:e.some(t=>t.severity==="block"&&!t.acceptedRisk),Te=(e,t,i,a)=>{kt(a)&&(process.exitCode=1),i&&e.some(n=>n.vulnerabilities.some(r=>n.acceptedRisk||ae(r.id,t,r.aliases)?!1:he(r.severity,i)))&&(process.exitCode=1)},ie=(e,t,i,a,n)=>{i&&(e.filter(r=>!r.acceptedRisk&&r.vulnerabilities.some(o=>!ae(o.id,t,o.aliases))).length>0||kt(n))&&(process.exitCode=1),Te(e,t,a,n)},$t=async(e,t)=>{if(!process.stdin.isTTY)return t;const i=Lt({input:process.stdin,output:process.stderr});try{const a="[y/N]",n=await new Promise(r=>{i.question(`${e} ${O(a)} `,o=>{r(o.trim())})});return n.length===0?t:n.toLowerCase().startsWith("y")}finally{i.close()}},An=e=>e==="pnpm"||e==="npm"||e==="yarn"||e==="bun",Nn=async e=>{const t=yt({allowMajor:e.allowMajor,findings:e.actionableFindings,workspaceRoot:e.workspaceRoot});if(u.info(""),u.info("─ Apply (direct deps)"),u.info($a(t)),t.apply.length===0){u.info("Nothing to apply for direct deps.");return}if(Oe&&!e.yes)return u.error("Refusing to run --fix in CI without --yes. Re-run with --yes once the plan above looks right."),1;if(!e.yes&&!await $t("Apply these direct-dep upgrades?",!1))return u.info("Aborted — no changes made."),0;const i=new Map;for(const a of t.apply){const n=a.workspaceName??"",r=i.get(n);r?r.push(a):i.set(n,[a])}for(const[a,n]of i){const r=n.map(c=>`${c.packageName}@${c.targetSpec}`),o=a.length>0?[a]:[];u.info(`Running ${e.pm.name} add ${r.join(" ")}${a.length>0?` --filter ${a}`:""}`);const l=ii(e.pm,{exact:!1,filter:o,global:!1,optional:!1,packages:r,peer:!1,saveDev:!1,workspace:!1,workspaceRoot:!1},e.workspaceRoot,console);if(l!==0)return u.error(`${e.pm.name} add exited ${String(l)} — aborting before rescan.`),l}return u.success("Direct-dep upgrades applied. Re-run `vis audit` to confirm the fixes landed."),0},Cn=async e=>{if(!An(e.pm.name))return u.error(`--fix-transitive is not supported for package manager "${e.pm.name}". Use pnpm, npm, yarn, or bun.`),1;const t=!!e.visConfig?.security?.audit?.apply?.transitive?.enabled;if(Oe&&(!e.yes||!t))return u.error("Refusing to run --fix-transitive in CI without both --yes and security.audit.apply.transitive.enabled = true. Overrides have a higher blast radius than direct bumps — gate on config."),1;const i=new Set(yt({findings:e.actionableFindings,workspaceRoot:e.workspaceRoot}).apply.map(o=>o.packageName)),a=e.actionableFindings.filter(o=>!i.has(o.packageName)),n=un(a);if(n.entries.length===0){u.info(""),u.info("─ Apply transitive (overrides)"),u.info("Nothing to override — all vulnerable packages are direct deps or have no fixed version.");return}const r=gn(e.workspaceRoot,n,{name:e.pm.name,version:e.pm.version});u.info(""),u.info("─ Apply transitive (overrides)"),u.info(`Target: ${r.filePath} (${r.surface})`);for(const o of r.entries){const l=o.status==="added"?"+":o.status==="updated"?"~":"·",c=o.previousSpec?` (was ${o.previousSpec})`:"";u.info(` ${l} ${o.packageName}: ${o.spec}${c}`)}if(!r.changed){u.info("No changes — overrides already match the plan.");return}if(!e.yes){if(Oe)return 1;if(!await $t("Write these overrides?",!1))return u.info("Aborted — no changes made."),0}try{fn(r)}catch(o){const l=o instanceof Error?o.message:String(o);return u.error(`Failed to write overrides: ${l}`),1}return u.success(`Wrote ${String(r.entries.filter(o=>o.status!=="unchanged").length)} override${r.entries.length===1?"":"s"}. Run \`${e.pm.name} install\` then re-run \`vis audit\` to confirm the fixes landed.`),0},Jn=async({fs:e,logger:t,options:i,visConfig:a,workspaceRoot:n})=>{if(!n)throw new Error("Could not determine workspace root. Run this command inside a monorepo.");await Sn(e,n,i,a)};export{Jn as default,kn as mapSeverityToAube,xn as resolveAuditBackend};