agentic-qe 3.15.6 → 3.15.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +141 -0
- package/README.md +2 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/cli/bundle.js +8 -6
- package/dist/cli/chunks/adapter-PEOUNYXJ.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-SY7UCLBL.js → agent-booster-wasm-OS5G7KMQ.js} +2 -2
- package/dist/cli/chunks/{agent-handler-KAMYBU3S.js → agent-handler-PI4I7PME.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-2CAW3KUM.js → agent-memory-branch-J7TXHX4U.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-DHKZI5RX.js +2 -0
- package/dist/cli/chunks/{arena-QCCVIOAH.js → arena-FXESDCFR.js} +4 -4
- package/dist/cli/chunks/{arena-4OFLJ3R2.js → arena-OWUGXKNT.js} +2 -2
- package/dist/cli/chunks/{audit-RBDQJQJB.js → audit-EPAWLYIZ.js} +3 -3
- package/dist/cli/chunks/base-QZWK3D5P.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-5JRACCDQ.js → better-sqlite3-IYVR5EQY.js} +2 -2
- package/dist/cli/chunks/{brain-handler-W4QIIRT4.js → brain-handler-3W2E6TC6.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-IBNGI572.js → branch-enumerator-HU7VACJ4.js} +2 -2
- package/dist/cli/chunks/{browser-GMSCVAOI.js → browser-72XOR6E2.js} +2 -2
- package/dist/cli/chunks/browser-workflow-ITPX72RX.js +2 -0
- package/dist/cli/chunks/{chunk-CR66HNAE.js → chunk-2423JAA5.js} +1 -1
- package/dist/cli/chunks/{chunk-LAY7NCQK.js → chunk-24CENUT4.js} +3 -3
- package/dist/cli/chunks/{chunk-PEMSXSP2.js → chunk-2AYBYXOA.js} +2 -2
- package/dist/cli/chunks/{chunk-TUDENMAE.js → chunk-2E3XWKEU.js} +2 -2
- package/dist/cli/chunks/{chunk-KIDOBLUO.js → chunk-2RJYA6WK.js} +2 -2
- package/dist/cli/chunks/{chunk-2IWPJUVV.js → chunk-2YVJ5OUL.js} +5 -5
- package/dist/cli/chunks/{chunk-34MDMFET.js → chunk-34JLY3U6.js} +2 -2
- package/dist/cli/chunks/{chunk-SV5BUYHH.js → chunk-3JD2USUH.js} +2 -2
- package/dist/cli/chunks/{chunk-EF5UHDCG.js → chunk-3RM46XFP.js} +1 -1
- package/dist/cli/chunks/{chunk-7XTANLTN.js → chunk-44DPYNPE.js} +1 -1
- package/dist/cli/chunks/{chunk-ONPPBLRB.js → chunk-4DIZ5BT6.js} +2 -2
- package/dist/cli/chunks/{chunk-22OZIJAD.js → chunk-4G2VNW4C.js} +2 -2
- package/dist/cli/chunks/{chunk-LJCEDTUM.js → chunk-56ZKQYZY.js} +3 -3
- package/dist/cli/chunks/{chunk-HOEWMEF2.js → chunk-5KCBX225.js} +2 -2
- package/dist/cli/chunks/{chunk-V3OLS2NG.js → chunk-5KS7HA37.js} +2 -2
- package/dist/cli/chunks/{chunk-MQCTLTGE.js → chunk-5PBRBS7D.js} +2 -2
- package/dist/cli/chunks/{chunk-TVLOED6O.js → chunk-5Q22XPTH.js} +2 -2
- package/dist/cli/chunks/{chunk-B7RHBKHL.js → chunk-634D2ENF.js} +2 -2
- package/dist/cli/chunks/{chunk-7TVIX4WL.js → chunk-6AYRAOCA.js} +2 -2
- package/dist/cli/chunks/{chunk-4KOVHQXK.js → chunk-6BO3WCK7.js} +2 -2
- package/dist/cli/chunks/{chunk-5HAPS6VD.js → chunk-6FEQ73BF.js} +2 -2
- package/dist/cli/chunks/{chunk-FQ5N666N.js → chunk-6JT73S5B.js} +1 -1
- package/dist/cli/chunks/{chunk-6MXAJBEA.js → chunk-6OS7HREG.js} +1 -1
- package/dist/cli/chunks/{chunk-6R3FBFCJ.js → chunk-6PKCQXEW.js} +2 -2
- package/dist/cli/chunks/{chunk-DQNUPEY5.js → chunk-7EX4DEQR.js} +2 -2
- package/dist/cli/chunks/{chunk-KCB6P463.js → chunk-7UCVYYWL.js} +2 -2
- package/dist/cli/chunks/{chunk-RLB7K7QP.js → chunk-AAA4SHEG.js} +1 -1
- package/dist/cli/chunks/{chunk-ITIJ23K2.js → chunk-AXO7OOOA.js} +2 -2
- package/dist/cli/chunks/{chunk-6RDVY26I.js → chunk-B7M323VL.js} +2 -2
- package/dist/cli/chunks/{chunk-EJ4KZFZN.js → chunk-BB7OLQKO.js} +1 -1
- package/dist/cli/chunks/{chunk-5NC7QEJ6.js → chunk-BTIBXGVQ.js} +4 -4
- package/dist/cli/chunks/{chunk-RD5BYLN7.js → chunk-BTYKGVJ5.js} +1 -1
- package/dist/cli/chunks/{chunk-YXU35GGD.js → chunk-C2CUPJGR.js} +1 -1
- package/dist/cli/chunks/{chunk-XFPQIWEH.js → chunk-C2MDBBFF.js} +3 -3
- package/dist/cli/chunks/{chunk-QLKUCMZC.js → chunk-CG5DZCOZ.js} +1 -1
- package/dist/cli/chunks/{chunk-YLNYPQDR.js → chunk-CIFWOMNX.js} +1 -1
- package/dist/cli/chunks/{chunk-ORBODZSO.js → chunk-CWPRU7ZI.js} +2 -2
- package/dist/cli/chunks/{chunk-WKDWRRDT.js → chunk-CXTJ47QS.js} +2 -2
- package/dist/cli/chunks/{chunk-SOSJWM3E.js → chunk-DCJW2DPL.js} +4 -4
- package/dist/cli/chunks/{chunk-GVRFSXY6.js → chunk-DGK6GQMO.js} +2 -2
- package/dist/cli/chunks/{chunk-X33F7NXH.js → chunk-DVPGBDBP.js} +3 -3
- package/dist/cli/chunks/chunk-EB2PP6X2.js +2 -0
- package/dist/cli/chunks/{chunk-HZFK2Z2Z.js → chunk-ECSLJJOQ.js} +1 -1
- package/dist/cli/chunks/{chunk-JCE76MPP.js → chunk-ED32XJ5R.js} +2 -2
- package/dist/cli/chunks/{chunk-ULCHPPW2.js → chunk-EDU72RTW.js} +1 -1
- package/dist/cli/chunks/{chunk-ZOUEQ6DL.js → chunk-EL75G2A3.js} +1 -1
- package/dist/cli/chunks/{chunk-GNYOHZVV.js → chunk-EV2BYY6T.js} +1 -1
- package/dist/cli/chunks/{chunk-RUTO67PT.js → chunk-F62EKVVC.js} +2 -2
- package/dist/cli/chunks/{chunk-IVJIHZSM.js → chunk-FTTFJ7SJ.js} +1 -1
- package/dist/cli/chunks/{chunk-NYS2GUNO.js → chunk-FVBFASOD.js} +2 -2
- package/dist/cli/chunks/{chunk-5DH5QI7G.js → chunk-G762PEFO.js} +3 -3
- package/dist/cli/chunks/{chunk-JPJEAK4G.js → chunk-G7YTZTGU.js} +1 -1
- package/dist/cli/chunks/{chunk-5VUIXDY2.js → chunk-GY2SAIXP.js} +2 -2
- package/dist/cli/chunks/{chunk-7XUB7U6Z.js → chunk-H4WHDFB5.js} +2 -2
- package/dist/cli/chunks/{chunk-72MQCZSM.js → chunk-HLZATDD2.js} +2 -2
- package/dist/cli/chunks/{chunk-AX26QJ6T.js → chunk-HPG7354V.js} +2 -2
- package/dist/cli/chunks/{chunk-7SAMMQVS.js → chunk-HSDOOFV7.js} +1 -1
- package/dist/cli/chunks/{chunk-K55EAWZ5.js → chunk-HTWIGQL4.js} +2 -2
- package/dist/cli/chunks/{chunk-BXATKI5S.js → chunk-HXBAQKMH.js} +2 -2
- package/dist/cli/chunks/{chunk-46HBVDMU.js → chunk-HZFT3P5B.js} +1 -1
- package/dist/cli/chunks/{chunk-RFDFET3O.js → chunk-I7H4IP7T.js} +2 -2
- package/dist/cli/chunks/{chunk-AJT3XDRD.js → chunk-IARSGAG7.js} +2 -2
- package/dist/cli/chunks/{chunk-TL5GV3PR.js → chunk-IC2WSSD5.js} +3 -3
- package/dist/cli/chunks/{chunk-TLUIO37P.js → chunk-ICPALF4Q.js} +2 -2
- package/dist/cli/chunks/{chunk-ZSBD4FUX.js → chunk-IWQQIXHO.js} +2 -2
- package/dist/cli/chunks/{chunk-AUOSHM63.js → chunk-IYQ7XNE5.js} +2 -2
- package/dist/cli/chunks/{chunk-RHIQ6QO5.js → chunk-J26GADQE.js} +281 -281
- package/dist/cli/chunks/{chunk-AUN4FG7V.js → chunk-J43DV3ME.js} +1 -1
- package/dist/cli/chunks/{chunk-ALCIUWFC.js → chunk-JFPXCQNP.js} +1 -1
- package/dist/cli/chunks/{chunk-R363XXGH.js → chunk-JK6B3ULP.js} +2 -2
- package/dist/cli/chunks/{chunk-7VTKR44N.js → chunk-JPHDMHFG.js} +2 -2
- package/dist/cli/chunks/{chunk-FOJRPEIP.js → chunk-JVYPXW6Y.js} +2 -2
- package/dist/cli/chunks/{chunk-ZUTFHGEO.js → chunk-JY4AIEZ7.js} +1 -1
- package/dist/cli/chunks/{chunk-47Q7JL3V.js → chunk-JY4WLN3K.js} +2 -2
- package/dist/cli/chunks/{chunk-IEPWO4XP.js → chunk-JYXOFN3E.js} +2 -2
- package/dist/cli/chunks/{chunk-2CIDFR2H.js → chunk-K7W55B7Q.js} +2 -2
- package/dist/cli/chunks/{chunk-D5N2O5EH.js → chunk-KPOPBUUJ.js} +2 -2
- package/dist/cli/chunks/{chunk-OQ4S6B7P.js → chunk-LDXQRNTT.js} +1 -1
- package/dist/cli/chunks/{chunk-6T6AHVLF.js → chunk-LDZWIV2O.js} +1 -1
- package/dist/cli/chunks/{chunk-A7ANPS4E.js → chunk-LGBN7TKC.js} +2 -2
- package/dist/cli/chunks/{chunk-X2DR27AY.js → chunk-LMEU64TR.js} +2 -2
- package/dist/cli/chunks/{chunk-GI5HWS4H.js → chunk-LP4AS2E4.js} +1 -1
- package/dist/cli/chunks/{chunk-VVF337SV.js → chunk-LQOVA4YX.js} +2 -2
- package/dist/cli/chunks/{chunk-KYVIOC3C.js → chunk-LVEX4GID.js} +2 -2
- package/dist/cli/chunks/{chunk-BO7UFNYV.js → chunk-M63QB466.js} +2 -2
- package/dist/cli/chunks/{chunk-UHHMAKPE.js → chunk-MDC4G323.js} +1 -1
- package/dist/cli/chunks/{chunk-4CLDYT36.js → chunk-MHZPC4HJ.js} +2 -2
- package/dist/cli/chunks/{chunk-24ZSGYC6.js → chunk-MJJC6HUK.js} +1 -1
- package/dist/cli/chunks/{chunk-ZL5LJT7D.js → chunk-MKFQNCXI.js} +2 -2
- package/dist/cli/chunks/{chunk-XZ46CI35.js → chunk-MMXG3LL6.js} +2 -2
- package/dist/cli/chunks/{chunk-OPDZBRIL.js → chunk-MNCF643K.js} +2 -2
- package/dist/cli/chunks/{chunk-CEXNW5TR.js → chunk-MNZFEIE5.js} +1 -1
- package/dist/cli/chunks/{chunk-L4D3TPFP.js → chunk-MQ6OF6DU.js} +1 -1
- package/dist/cli/chunks/{chunk-UB6DQGWM.js → chunk-MRHM4COP.js} +2 -2
- package/dist/cli/chunks/{chunk-CLAMMGY3.js → chunk-N4PMPSJJ.js} +2 -2
- package/dist/cli/chunks/{chunk-XQ53PZEF.js → chunk-NZQPP533.js} +3 -3
- package/dist/cli/chunks/{chunk-FU7LNUD7.js → chunk-OA4GR3EZ.js} +2 -2
- package/dist/cli/chunks/{chunk-ORFL3YXB.js → chunk-OJEZNLB6.js} +2 -2
- package/dist/cli/chunks/{chunk-5LST62QR.js → chunk-ONVALAZN.js} +2 -2
- package/dist/cli/chunks/{chunk-DA7DGDTI.js → chunk-PEKDSJBC.js} +2 -2
- package/dist/cli/chunks/{chunk-3DJNKNBR.js → chunk-PG64YV6C.js} +57 -57
- package/dist/cli/chunks/{chunk-2ZTWPMTK.js → chunk-PQV7E7XH.js} +2 -2
- package/dist/cli/chunks/chunk-PTK66HEY.js +2 -0
- package/dist/cli/chunks/{chunk-CZBIREL5.js → chunk-PUECC4WI.js} +2 -2
- package/dist/cli/chunks/{chunk-JYKQVYX2.js → chunk-PXZKPUW6.js} +2 -2
- package/dist/cli/chunks/{chunk-I7WAW7TM.js → chunk-PYHYOKYT.js} +2 -2
- package/dist/cli/chunks/{chunk-LCCTJ2PC.js → chunk-PZG3542B.js} +2 -2
- package/dist/cli/chunks/{chunk-F7A2UBZO.js → chunk-Q2T5FXEA.js} +2 -2
- package/dist/cli/chunks/{chunk-PS6WFCA4.js → chunk-QJE6ZW2X.js} +2 -2
- package/dist/cli/chunks/{chunk-LZWJ5BMP.js → chunk-QNQSM2OG.js} +2 -2
- package/dist/cli/chunks/{chunk-QLYO3H7E.js → chunk-QQT6QENQ.js} +2 -2
- package/dist/cli/chunks/{chunk-VCONCVSY.js → chunk-QVG4ZDXX.js} +2 -2
- package/dist/cli/chunks/{chunk-NMY4KTWA.js → chunk-QWLTHFZW.js} +2 -2
- package/dist/cli/chunks/{chunk-NBUXM5X6.js → chunk-RCYLCA7E.js} +2 -2
- package/dist/cli/chunks/{chunk-P7DXVL2S.js → chunk-REEIFA6A.js} +2 -2
- package/dist/cli/chunks/{chunk-5MT7DMD7.js → chunk-RNYX4CPI.js} +2 -2
- package/dist/cli/chunks/{chunk-HAN4MS5T.js → chunk-RORZ5O5Z.js} +2 -2
- package/dist/cli/chunks/{chunk-ZCP4P6O2.js → chunk-RRPYWBFX.js} +2 -2
- package/dist/cli/chunks/{chunk-3NJ7O3OH.js → chunk-RXAFLK34.js} +2 -2
- package/dist/cli/chunks/{chunk-VAYZ5QIE.js → chunk-SQHLC6I5.js} +1 -1
- package/dist/cli/chunks/{chunk-Q2RBOC7V.js → chunk-SSP2B2WR.js} +2 -2
- package/dist/cli/chunks/{chunk-CCL436IU.js → chunk-SX2YSHE7.js} +14 -6
- package/dist/cli/chunks/{chunk-ZTB32K5N.js → chunk-T3ZDVU6F.js} +3 -3
- package/dist/cli/chunks/{chunk-624QRKQX.js → chunk-T6W5APYP.js} +1 -1
- package/dist/cli/chunks/{chunk-BAYGQRNP.js → chunk-TU4LIIOP.js} +2 -2
- package/dist/cli/chunks/{chunk-L2TDHJR3.js → chunk-UBYCR3O4.js} +2 -2
- package/dist/cli/chunks/{chunk-JAPBSSFY.js → chunk-UCLN6AME.js} +1 -1
- package/dist/cli/chunks/{chunk-66NW3ZB4.js → chunk-UIYKR2SA.js} +2 -2
- package/dist/cli/chunks/{chunk-BIXRTOH3.js → chunk-UUHIEM2M.js} +3 -3
- package/dist/cli/chunks/{chunk-ELI4GDQO.js → chunk-UY3REQOK.js} +2 -2
- package/dist/cli/chunks/{chunk-BUTGIVKW.js → chunk-V2SAEMZY.js} +1 -1
- package/dist/cli/chunks/{chunk-6WOZUSSN.js → chunk-V5NGBQAQ.js} +2 -2
- package/dist/cli/chunks/{chunk-7TJZDRDU.js → chunk-VCA6YYII.js} +1 -1
- package/dist/cli/chunks/chunk-VJRZFWR5.js +2 -0
- package/dist/cli/chunks/{chunk-5GIJU2ZY.js → chunk-VKPKYMCT.js} +2 -2
- package/dist/cli/chunks/{chunk-XPB5BVU6.js → chunk-VNW5Q2CX.js} +2 -2
- package/dist/cli/chunks/{chunk-7QVPMH25.js → chunk-VUFRTGML.js} +2 -2
- package/dist/cli/chunks/{chunk-MP3FSUNB.js → chunk-W4X2VTIY.js} +2 -2
- package/dist/cli/chunks/{chunk-GWM4M5NF.js → chunk-WTLIEBDH.js} +1 -1
- package/dist/cli/chunks/{chunk-QS5KZYUZ.js → chunk-WUV5RZUI.js} +2 -2
- package/dist/cli/chunks/{chunk-HEGGV2PT.js → chunk-WXI2STKQ.js} +2 -2
- package/dist/cli/chunks/{chunk-GFB6BZWU.js → chunk-XEWXYGJI.js} +2 -2
- package/dist/cli/chunks/{chunk-NHRF3V4B.js → chunk-XNSQZ3O7.js} +2 -2
- package/dist/cli/chunks/{chunk-4POOJYXA.js → chunk-XTJMY3KS.js} +1 -1
- package/dist/cli/chunks/{chunk-LMAEMVPA.js → chunk-XXAVQACL.js} +1 -1
- package/dist/cli/chunks/{chunk-RV6HSMKJ.js → chunk-Y4SAWE45.js} +1 -1
- package/dist/cli/chunks/{chunk-DLSFT6PO.js → chunk-Y6A46M3B.js} +2 -2
- package/dist/cli/chunks/{chunk-5UPIL62W.js → chunk-YDZJWDR6.js} +3 -3
- package/dist/cli/chunks/{chunk-F3KS3TAB.js → chunk-YFOBQSOW.js} +2 -2
- package/dist/cli/chunks/{chunk-XBEI2JBA.js → chunk-YK3NOC2R.js} +2 -2
- package/dist/cli/chunks/{chunk-MQTA6KIO.js → chunk-YUC7RJGR.js} +1 -1
- package/dist/cli/chunks/{chunk-A74J23QB.js → chunk-Z3VJLWRR.js} +2 -2
- package/dist/cli/chunks/{chunk-YNG7E26C.js → chunk-ZLVQSEZK.js} +2 -2
- package/dist/cli/chunks/{chunk-6HWARQWV.js → chunk-ZRLNACPY.js} +2 -2
- package/dist/cli/chunks/{chunk-XBFQJZWX.js → chunk-ZTMZFF25.js} +2 -2
- package/dist/cli/chunks/chunk-ZUMDDMDE.js +3 -0
- package/dist/cli/chunks/{ci-GEJCXMBK.js → ci-5HEXJZ2C.js} +2 -2
- package/dist/cli/chunks/{ci-config-2ZVV4OXL.js → ci-config-WU4NPDAM.js} +2 -2
- package/dist/cli/chunks/{ci-output-E45OGVPR.js → ci-output-BJQVXX5E.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-X73ITYZC.js → circuit-breaker-3BMGTQCB.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-W4PPH46C.js → claude-flow-setup-GVDGJWMU.js} +2 -2
- package/dist/cli/chunks/client-S7GNYTZ5.js +2 -0
- package/dist/cli/chunks/{cline-installer-NUEPMWDE.js → cline-installer-V4MRGWVA.js} +2 -2
- package/dist/cli/chunks/{code-6WQHBS7G.js → code-A3TGQPEO.js} +3 -3
- package/dist/cli/chunks/{code-index-extractor-BXQIFIFT.js → code-index-extractor-YJQSYWD3.js} +2 -2
- package/dist/cli/chunks/{codex-installer-Z337R2KH.js → codex-installer-7N7UQPAH.js} +2 -2
- package/dist/cli/chunks/{completions-F5DMYFHV.js → completions-PPGVYLZS.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-W2SYPZDI.js → complexity-analyzer-XZTFLYV5.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-ZCHUIFTN.js → continuedev-installer-Z5I57RAH.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-M5JNODXF.js → copilot-installer-F5YZ6BHB.js} +2 -2
- package/dist/cli/chunks/core-handlers-CUEPOQIO.js +2 -0
- package/dist/cli/chunks/{cost-tracker-LSYTHBHV.js → cost-tracker-GO33ZQAP.js} +2 -2
- package/dist/cli/chunks/{coverage-PGMRS5SS.js → coverage-GSHKLY74.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-CXN5QFEV.js +2 -0
- package/dist/cli/chunks/{cursor-installer-XPUA73UW.js → cursor-installer-JJ7IVJZB.js} +2 -2
- package/dist/cli/chunks/daemon-3DQCKRYO.js +10 -0
- package/dist/cli/chunks/{daemon-ITKDIYMW.js → daemon-IRL7QRNE.js} +3 -3
- package/dist/cli/chunks/{dag-attention-scheduler-T55AXLD6.js → dag-attention-scheduler-ORXSUHPA.js} +2 -2
- package/dist/cli/chunks/{detect-DR7J6K4O.js → detect-RHU62KRI.js} +2 -2
- package/dist/cli/chunks/{dist-node-LAJJBOUT.js → dist-node-3VKV4Z6C.js} +2 -2
- package/dist/cli/chunks/{domain-handler-OMSHCRMK.js → domain-handler-SFIML4FK.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-EQXSKC5K.js → domain-plugins-CJ4FA3OC.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-FKRAGVSW.js → domain-transfer-BCRKPCAA.js} +2 -2
- package/dist/cli/chunks/dream-5AUNJW24.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-JZFPCNL3.js → embed-and-insert-pattern-VL3HFLPV.js} +2 -2
- package/dist/cli/chunks/{eval-JSNNASBW.js → eval-GGKRI4P5.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-UPD3IZBK.js → experience-capture-middleware-F72TIRQY.js} +3 -3
- package/dist/cli/chunks/{fast-paths-YNMIBS2E.js → fast-paths-7KOOF3MA.js} +2 -2
- package/dist/cli/chunks/{feature-flags-SRLXDKBI.js → feature-flags-FNHBTHBH.js} +2 -2
- package/dist/cli/chunks/{feature-flags-VIR7O4L7.js → feature-flags-IOZEWWFU.js} +2 -2
- package/dist/cli/chunks/file-discovery-AYWF357I.js +2 -0
- package/dist/cli/chunks/{fleet-K2ED46EL.js → fleet-QX5KXTRC.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-QCU4ZRYW.js → gnn-wrapper-OH2DOQP7.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-YYQI4WZM.js → heartbeat-handler-W67NXTNE.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-7ZIDVXIP.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-P77OC7FM.js +2 -0
- package/dist/cli/chunks/hnsw-index-3LBOTQAW.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-C5TJSWTZ.js → hnsw-legacy-bridge-6MLLOGOE.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-SE3MJJYS.js → hnswlib-node-4UDISJ3G.js} +2 -2
- package/dist/cli/chunks/{hooks-C572SRDH.js → hooks-NOQJWQ4P.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-LOM54PDD.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-35A6G3M5.js → hypergraph-engine-2OD3APVP.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-U2756CWI.js → hypergraph-handler-5AZGMBUM.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-QSDJVBPS.js +2 -0
- package/dist/cli/chunks/init-guard-SMGJ45PW.js +2 -0
- package/dist/cli/chunks/init-handler-5T4MP2NM.js +88 -0
- package/dist/cli/chunks/init-wizard-MK2325JJ.js +2 -0
- package/dist/cli/chunks/kernel-2NJQQ2KT.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-32PX5YH7.js → kilocode-installer-RLZYLVQJ.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-C4ROMMUS.js → kiro-installer-LFZOC7VD.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-SDISHO62.js +2 -0
- package/dist/cli/chunks/{learning-GEPVZGJQ.js → learning-XRPGLUWR.js} +20 -20
- package/dist/cli/chunks/{llm-router-XRKTTJTX.js → llm-router-OMK5HYPH.js} +4 -4
- package/dist/cli/chunks/llm-router-service-YTCMRBAN.js +2 -0
- package/dist/cli/chunks/{load-XVH6HW7E.js → load-XADC7KCU.js} +2 -2
- package/dist/cli/chunks/load-test-RPKHLBCC.js +2 -0
- package/dist/cli/chunks/{mcp-IULSTM4Z.js → mcp-PIBKSSVU.js} +2 -2
- package/dist/cli/chunks/{memory-6K7IAU4T.js → memory-AP7EZERS.js} +5 -5
- package/dist/cli/chunks/memory-backend-BZXFO4JZ.js +2 -0
- package/dist/cli/chunks/{memory-handlers-CG6DRLAW.js → memory-handlers-MOFDNB6E.js} +2 -2
- package/dist/cli/chunks/{multi-model-executor-VZDUYPLX.js → multi-model-executor-7JJ2FZ33.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-QUTXKNH4.js → opencode-installer-ZZZ6EBYJ.js} +2 -2
- package/dist/cli/chunks/{orchestrator-PCKKUWOP.js → orchestrator-2H2YKSGJ.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-4PRPIOR6.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-PX5HQVRL.js → pattern-usage-recorder-7MJJWC2Z.js} +2 -2
- package/dist/cli/chunks/{pipeline-O562GTOG.js → pipeline-LIE5BWQY.js} +2 -2
- package/dist/cli/chunks/{platform-PM7Q2AZS.js → platform-SMYUNLGX.js} +2 -2
- package/dist/cli/chunks/{plugin-OTYTFGPY.js → plugin-LJDIXQNT.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-6CFXTHC2.js → prime-radiant-advanced-wasm-RIDNE5D2.js} +2 -2
- package/dist/cli/chunks/project-root-NBIQF63D.js +2 -0
- package/dist/cli/chunks/protocol-executor-BRPGIYWQ.js +2 -0
- package/dist/cli/chunks/{protocol-handler-PPGNSAOS.js → protocol-handler-YVM66DLI.js} +2 -2
- package/dist/cli/chunks/{prove-WQ3BKRZG.js → prove-ZBDT52GD.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-GDZACWKW.js +2 -0
- package/dist/cli/chunks/{quality-C5WUU3AA.js → quality-DUKXGDDO.js} +2 -2
- package/dist/cli/chunks/{quality-gate-WSSRKD5U.js → quality-gate-SM3RXF4V.js} +3 -3
- package/dist/cli/chunks/queen-coordinator-LDKLBPD5.js +2 -0
- package/dist/cli/chunks/{real-embeddings-CFQE7IRQ.js → real-embeddings-4QLQZDB5.js} +2 -2
- package/dist/cli/chunks/{ref-validation-DHKHXVZT.js → ref-validation-M3EO32YQ.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-3PPODABV.js → roocode-installer-S6Q5OLV5.js} +2 -2
- package/dist/cli/chunks/router-H5YSIRH2.js +2 -0
- package/dist/cli/chunks/routing-feedback-5R36TJDH.js +2 -0
- package/dist/cli/chunks/{routing-handler-JNXTGT6T.js → routing-handler-55FMUACP.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-6YLROPVP.js → ruvector-commands-QATKAAPK.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-TT2DBQQQ.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-BCLFJKSK.js +2 -0
- package/dist/cli/chunks/{rvf-migration-coordinator-4DWB4WRK.js → rvf-migration-coordinator-RFXFU6JD.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-UXI66OQJ.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-YKR2ZNBF.js → rvf-store-integrity-PKDVXQAW.js} +2 -2
- package/dist/cli/chunks/safe-db-MSTD2GDH.js +2 -0
- package/dist/cli/chunks/schedule-KST6KIFD.js +2 -0
- package/dist/cli/chunks/scheduler-FTQS6YK3.js +2 -0
- package/dist/cli/chunks/security-CMRB6WA3.js +18 -0
- package/dist/cli/chunks/{shared-rvf-adapter-LNRLFP5I.js → shared-rvf-adapter-YHLLNFHF.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-GWU6YQNS.js → shared-rvf-dual-writer-4BGDVPQ7.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-ZX5QFDMR.js +2 -0
- package/dist/cli/chunks/{standalone-memory-46KKBSSV.js → standalone-memory-LUHKQAGM.js} +2 -2
- package/dist/cli/chunks/{status-handler-35T5FTDQ.js → status-handler-S6S5PNR7.js} +2 -2
- package/dist/cli/chunks/{structural-health-P7QPQWLO.js → structural-health-PQ7NZAJ4.js} +2 -2
- package/dist/cli/chunks/{sync-W6Z4R4PL.js → sync-Q6KRQXU6.js} +2 -2
- package/dist/cli/chunks/{sync-Y43EWBSY.js → sync-S744AEJC.js} +2 -2
- package/dist/cli/chunks/{task-handler-5CX3ZYT7.js → task-handler-GAMGEHUW.js} +2 -2
- package/dist/cli/chunks/{task-handlers-DQZGOJNE.js → task-handlers-6CRDEELN.js} +3 -3
- package/dist/cli/chunks/{test-TPP53VVV.js → test-FNH67DBK.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-WBV4UMQH.js → test-scheduling-NZA5SHK6.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-GIIDXHLC.js → token-bootstrap-CXKG55JD.js} +2 -2
- package/dist/cli/chunks/{token-usage-AKK37RB7.js → token-usage-M7WWEDJX.js} +2 -2
- package/dist/cli/chunks/{transformers-7MASPELS.js → transformers-2IFMCK6A.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-YZKD6UGB.js → tree-sitter-wasm-parser-NMNA6RJC.js} +2 -2
- package/dist/cli/chunks/{types-AZ3BTXDP.js → types-N7FWTOLD.js} +2 -2
- package/dist/cli/chunks/unified-memory-2Z2F446J.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-A4EWYPJQ.js +2 -0
- package/dist/cli/chunks/unified-persistence-Z6N6JZFA.js +2 -0
- package/dist/cli/chunks/{upgrade-L7OTDKEK.js → upgrade-KDB5RGL7.js} +2 -2
- package/dist/cli/chunks/{validate-O3QVFIGP.js → validate-KMUV5FUA.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-2UGBGLTX.js → validate-swarm-ANZWRCJU.js} +2 -2
- package/dist/cli/chunks/visual-security-GXYZV7KR.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-J75IYPRO.js → web-tree-sitter-SXXC4NMS.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-FQ5DBFCG.js → windsurf-installer-2LWSKMBU.js} +2 -2
- package/dist/cli/chunks/witness-chain-52PEIEGK.js +2 -0
- package/dist/cli/chunks/{witness-chain-I7TN4MXZ.js → witness-chain-JJMSJFZP.js} +2 -2
- package/dist/cli/chunks/{witness-chain-repair-D3NE3NQK.js → witness-chain-repair-OX7VFW6T.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-RU2WOP5M.js → witness-chain-verifier-QLSMXHAZ.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-IHQB2FR5.js → witness-key-manager-3DS4L7LE.js} +2 -2
- package/dist/cli/chunks/{workflow-6BWTNVV6.js → workflow-ARWAMHD3.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-DORMQMG7.js +2 -0
- package/dist/cli/chunks/{wrappers-URVP25VU.js → wrappers-J6KGTUSJ.js} +2 -2
- package/dist/cli/commands/learning.js +3 -2
- package/dist/cli/commands/security.d.ts +16 -0
- package/dist/cli/commands/security.js +76 -9
- package/dist/cli/handlers/init-guard.d.ts +21 -1
- package/dist/cli/handlers/init-guard.js +51 -8
- package/dist/cli/handlers/init-handler.js +57 -56
- package/dist/cli/index.js +11 -0
- package/dist/cli/utils/ci-output.d.ts +5 -0
- package/dist/cli/utils/ci-output.js +8 -0
- package/dist/coordination/handlers/security-handlers.js +22 -6
- package/dist/coordination/protocols/defect-investigation.js +7 -1
- package/dist/coordination/protocols/security-audit.js +11 -0
- package/dist/coordination/result-saver.d.ts +9 -0
- package/dist/coordination/result-saver.js +34 -4
- package/dist/domains/coverage-analysis/collected-metrics.d.ts +2 -0
- package/dist/domains/coverage-analysis/collected-metrics.js +6 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.js +9 -6
- package/dist/domains/quality-assessment/interfaces.d.ts +4 -0
- package/dist/domains/quality-assessment/quality-evidence.d.ts +1 -1
- package/dist/domains/quality-assessment/services/quality-analyzer.js +7 -5
- package/dist/domains/quality-assessment/services/quality-gate.js +12 -3
- package/dist/domains/security-compliance/dependency-advisory-engine.d.ts +52 -0
- package/dist/domains/security-compliance/dependency-advisory-engine.js +113 -0
- package/dist/domains/security-compliance/interfaces.d.ts +30 -0
- package/dist/domains/security-compliance/plugin.d.ts +7 -1
- package/dist/domains/security-compliance/plugin.js +19 -0
- package/dist/domains/security-compliance/services/scanners/dependency-resolver.d.ts +71 -0
- package/dist/domains/security-compliance/services/scanners/dependency-resolver.js +232 -0
- package/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts +21 -6
- package/dist/domains/security-compliance/services/scanners/dependency-scanner.js +142 -64
- package/dist/domains/security-compliance/services/scanners/lockfile-versions.d.ts +43 -0
- package/dist/domains/security-compliance/services/scanners/lockfile-versions.js +248 -0
- package/dist/domains/security-compliance/services/scanners/scanner-types.d.ts +30 -2
- package/dist/domains/security-compliance/services/security-auditor.d.ts +19 -6
- package/dist/domains/security-compliance/services/security-auditor.js +133 -92
- package/dist/domains/test-execution/services/retry-handler.js +17 -6
- package/dist/domains/test-execution/services/test-executor.d.ts +1 -0
- package/dist/domains/test-execution/services/test-executor.js +87 -7
- package/dist/kernel/shared-dirs.js +17 -5
- package/dist/mcp/bundle.js +874 -874
- package/dist/mcp/handlers/domain-handler-configs.d.ts +4 -0
- package/dist/mcp/handlers/domain-handler-configs.js +5 -1
- package/dist/mcp/protocol-server.js +2 -1
- package/dist/mcp/types.d.ts +6 -0
- package/dist/shared/security/index.d.ts +2 -2
- package/dist/shared/security/index.js +1 -1
- package/dist/shared/security/osv-client.d.ts +79 -132
- package/dist/shared/security/osv-client.js +344 -167
- package/dist/shared/security/osv-lookup.d.ts +124 -0
- package/dist/shared/security/osv-lookup.js +246 -0
- package/dist/shared/security/osv-types.d.ts +119 -0
- package/dist/shared/security/osv-types.js +6 -0
- package/dist/workers/interfaces.d.ts +6 -1
- package/dist/workers/namespaced-keys.d.ts +16 -0
- package/dist/workers/namespaced-keys.js +24 -0
- package/dist/workers/quality-daemon/persistent-memory.d.ts +1 -1
- package/dist/workers/quality-daemon/persistent-memory.js +2 -2
- package/dist/workers/worker-manager.js +5 -2
- package/dist/workers/workers/defect-predictor.d.ts +25 -8
- package/dist/workers/workers/defect-predictor.js +223 -216
- package/dist/workers/workers/performance-baseline.d.ts +24 -9
- package/dist/workers/workers/performance-baseline.js +187 -230
- package/dist/workers/workers/quality-gate.d.ts +11 -9
- package/dist/workers/workers/quality-gate.js +125 -267
- package/dist/workers/workers/security-scan-records.d.ts +111 -0
- package/dist/workers/workers/security-scan-records.js +128 -0
- package/dist/workers/workers/security-scan.d.ts +25 -7
- package/dist/workers/workers/security-scan.js +187 -164
- package/package.json +2 -2
- package/dist/cli/chunks/adapter-PP3XIXDV.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-VDUQJKKY.js +0 -2
- package/dist/cli/chunks/base-QSYWWPCE.js +0 -2
- package/dist/cli/chunks/browser-workflow-WXXPBSCM.js +0 -2
- package/dist/cli/chunks/chunk-45MVRQG4.js +0 -2
- package/dist/cli/chunks/chunk-5VZVMO7B.js +0 -3
- package/dist/cli/chunks/chunk-EECF4CMA.js +0 -2
- package/dist/cli/chunks/client-6XKSQ4JT.js +0 -2
- package/dist/cli/chunks/core-handlers-OJYW4Y6M.js +0 -2
- package/dist/cli/chunks/cross-domain-router-QVUPQ2SC.js +0 -2
- package/dist/cli/chunks/daemon-QBYTCIMH.js +0 -10
- package/dist/cli/chunks/dream-3UABDRZJ.js +0 -2
- package/dist/cli/chunks/file-discovery-ZFGZTKZ4.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-MJ6MTPDF.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-FQWJCFVW.js +0 -2
- package/dist/cli/chunks/hnsw-index-NJYKJUHC.js +0 -2
- package/dist/cli/chunks/hybrid-backend-SL7RFID7.js +0 -2
- package/dist/cli/chunks/impact-analyzer-5ZJTXPVC.js +0 -2
- package/dist/cli/chunks/init-handler-PCLYQUSB.js +0 -88
- package/dist/cli/chunks/init-wizard-MQMDSIOF.js +0 -2
- package/dist/cli/chunks/kernel-MEJ5GMRH.js +0 -2
- package/dist/cli/chunks/knowledge-graph-XUBZSEZE.js +0 -2
- package/dist/cli/chunks/llm-router-service-QZAPAEPX.js +0 -2
- package/dist/cli/chunks/load-test-OVXIQ3AF.js +0 -2
- package/dist/cli/chunks/memory-backend-TRPOMPK4.js +0 -2
- package/dist/cli/chunks/pattern-null-store-JWYBRBZG.js +0 -2
- package/dist/cli/chunks/project-root-VVSTHIP4.js +0 -2
- package/dist/cli/chunks/protocol-executor-PXZCLZD3.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-42FRS5V3.js +0 -2
- package/dist/cli/chunks/queen-coordinator-UI3B7DI6.js +0 -2
- package/dist/cli/chunks/router-HYRPWLAY.js +0 -2
- package/dist/cli/chunks/routing-feedback-BPZ5R6F3.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-DEKDQ6KO.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-L53VBS7I.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-I6RUGD2D.js +0 -2
- package/dist/cli/chunks/safe-db-KS65XDCP.js +0 -2
- package/dist/cli/chunks/schedule-KD2VN6GB.js +0 -2
- package/dist/cli/chunks/scheduler-ZH3RMUHY.js +0 -2
- package/dist/cli/chunks/security-PWQTGDRU.js +0 -13
- package/dist/cli/chunks/sqlite-persistence-6DTVME5D.js +0 -2
- package/dist/cli/chunks/unified-memory-FCX7NLFZ.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-VU5QJK37.js +0 -2
- package/dist/cli/chunks/unified-persistence-FM376LGE.js +0 -2
- package/dist/cli/chunks/visual-security-EU7Y3X46.js +0 -2
- package/dist/cli/chunks/witness-chain-CSEBT52D.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-ALNKOM3N.js +0 -2
|
@@ -5,168 +5,359 @@
|
|
|
5
5
|
* OSV provides vulnerability information for npm, PyPI, Go, Maven, and more.
|
|
6
6
|
* API Documentation: https://google.github.io/osv.dev/api/
|
|
7
7
|
*/
|
|
8
|
+
import { isIP } from 'node:net';
|
|
8
9
|
import { HttpClient } from '../http/index.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import { OSVLookupError, advisoryAffectsVersion, boundedList, classifyNpmSpec, exactNpmVersion, isAdvisoryRecord, isConcreteVersion, lookupKey, lookupStatus, parseBatchBody, } from './osv-lookup.js';
|
|
11
|
+
export { OSVLookupError } from './osv-lookup.js';
|
|
12
|
+
const DEFAULT_BASE_URL = 'https://api.osv.dev';
|
|
13
|
+
/**
|
|
14
|
+
* A loopback host: exactly `localhost`, an IPv4 literal in 127.0.0.0/8, or the
|
|
15
|
+
* IPv6 literal ::1. A DNS name that merely starts with "127." (e.g.
|
|
16
|
+
* 127.evil.com, 127.0.0.1.nip.io) is not loopback.
|
|
17
|
+
*/
|
|
18
|
+
function isLoopbackHost(hostname) {
|
|
19
|
+
const host = hostname.toLowerCase().replace(/^\[|\]$/g, '');
|
|
20
|
+
if (host === 'localhost')
|
|
21
|
+
return true;
|
|
22
|
+
if (isIP(host) === 4)
|
|
23
|
+
return host.startsWith('127.');
|
|
24
|
+
return isIP(host) === 6 && (host === '::1' || host === '0:0:0:0:0:0:0:1');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The OSV endpoint: `AQE_OSV_API_URL` or the public API. https is required,
|
|
28
|
+
* except plain http on a loopback host (local mirrors and test stubs).
|
|
29
|
+
* @throws Error naming AQE_OSV_API_URL when the value is not acceptable.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveOSVBaseUrl(env = process.env) {
|
|
32
|
+
const configured = env.AQE_OSV_API_URL?.trim();
|
|
33
|
+
if (!configured)
|
|
34
|
+
return DEFAULT_BASE_URL;
|
|
35
|
+
if (configured.length > MAX_OSV_URL_LENGTH) {
|
|
36
|
+
throw new Error(`AQE_OSV_API_URL is longer than ${MAX_OSV_URL_LENGTH} characters (expected https://host)`);
|
|
37
|
+
}
|
|
38
|
+
let url;
|
|
39
|
+
try {
|
|
40
|
+
url = new URL(configured);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw new Error(`AQE_OSV_API_URL is not a URL: "${configured.slice(0, 200)}" (expected https://host)`);
|
|
44
|
+
}
|
|
45
|
+
const loopback = isLoopbackHost(url.hostname);
|
|
46
|
+
if (url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) {
|
|
47
|
+
throw new Error(`AQE_OSV_API_URL must use https (http only for localhost/loopback): "${configured.slice(0, 200)}"`);
|
|
48
|
+
}
|
|
49
|
+
// A plain loop, not /\/+$/ (CodeQL js/polynomial-redos).
|
|
50
|
+
let base = configured;
|
|
51
|
+
while (base.endsWith('/'))
|
|
52
|
+
base = base.slice(0, -1);
|
|
53
|
+
return base;
|
|
54
|
+
}
|
|
55
|
+
/** Longest accepted AQE_OSV_API_URL; a longer value is invalid. */
|
|
56
|
+
export const MAX_OSV_URL_LENGTH = 2048;
|
|
15
57
|
/**
|
|
16
58
|
* OSV API Client
|
|
17
|
-
* Queries the Open Source Vulnerabilities database for dependency vulnerabilities
|
|
59
|
+
* Queries the Open Source Vulnerabilities database for dependency vulnerabilities.
|
|
60
|
+
*
|
|
61
|
+
* #1049: a failed or partial lookup is never reported as "no vulnerabilities".
|
|
62
|
+
* `lookupBatch` returns the packages it could not check; the list-returning
|
|
63
|
+
* methods throw `OSVLookupError` instead of returning `[]`.
|
|
18
64
|
*/
|
|
19
65
|
export class OSVClient {
|
|
20
66
|
config;
|
|
67
|
+
configuredBaseUrl;
|
|
68
|
+
endpoint = null;
|
|
21
69
|
http;
|
|
22
|
-
|
|
70
|
+
detailCache = new Map();
|
|
23
71
|
constructor(config = {}) {
|
|
24
|
-
this.
|
|
72
|
+
this.configuredBaseUrl = config.baseUrl;
|
|
73
|
+
this.config = {
|
|
74
|
+
timeout: config.timeout ?? 30000,
|
|
75
|
+
retries: config.retries ?? 2,
|
|
76
|
+
batchSize: Math.max(1, Math.min(1000, config.batchSize ?? 500)),
|
|
77
|
+
detailConcurrency: Math.max(1, config.detailConcurrency ?? 8),
|
|
78
|
+
enableCache: config.enableCache ?? true,
|
|
79
|
+
cacheTtl: config.cacheTtl ?? 60 * 60 * 1000,
|
|
80
|
+
};
|
|
25
81
|
this.http = new HttpClient();
|
|
26
82
|
}
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
const result = await this.http.post(`${this.config.baseUrl}/v1/query`, {
|
|
41
|
-
package: {
|
|
42
|
-
name: packageName,
|
|
43
|
-
ecosystem,
|
|
44
|
-
...(version && { version }),
|
|
45
|
-
},
|
|
46
|
-
}, { timeout: this.config.timeout });
|
|
47
|
-
if (!result.success) {
|
|
48
|
-
console.error(`OSV query failed for ${ecosystem}:${packageName}:`, result.error);
|
|
49
|
-
return [];
|
|
83
|
+
/** The endpoint this client queries, or null when the configured URL is invalid. */
|
|
84
|
+
get baseUrl() {
|
|
85
|
+
const endpoint = this.resolveEndpoint();
|
|
86
|
+
return 'url' in endpoint ? endpoint.url : null;
|
|
87
|
+
}
|
|
88
|
+
/** Resolve (once) the endpoint; an invalid value is a reason, never a throw. */
|
|
89
|
+
resolveEndpoint() {
|
|
90
|
+
if (!this.endpoint) {
|
|
91
|
+
try {
|
|
92
|
+
this.endpoint = { url: this.configuredBaseUrl !== undefined
|
|
93
|
+
? resolveOSVBaseUrl({ AQE_OSV_API_URL: this.configuredBaseUrl })
|
|
94
|
+
: resolveOSVBaseUrl() };
|
|
50
95
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (this.config.enableCache && response.vulns) {
|
|
54
|
-
this.cache.set(cacheKey, {
|
|
55
|
-
data: response,
|
|
56
|
-
timestamp: Date.now(),
|
|
57
|
-
});
|
|
96
|
+
catch (error) {
|
|
97
|
+
this.endpoint = { reason: error instanceof Error ? error.message : String(error) };
|
|
58
98
|
}
|
|
59
|
-
return this.parseVulnerabilities(response.vulns || []);
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
// Return empty on error (non-blocking)
|
|
63
|
-
console.error(`OSV query failed for ${ecosystem}:${packageName}:`, error);
|
|
64
|
-
return [];
|
|
65
99
|
}
|
|
100
|
+
return this.endpoint;
|
|
101
|
+
}
|
|
102
|
+
get base() {
|
|
103
|
+
const endpoint = this.resolveEndpoint();
|
|
104
|
+
if ('reason' in endpoint)
|
|
105
|
+
throw new OSVLookupError(endpoint.reason);
|
|
106
|
+
return endpoint.url;
|
|
66
107
|
}
|
|
67
108
|
/**
|
|
68
|
-
*
|
|
109
|
+
* Look up advisories for packages, reporting every package that could not be
|
|
110
|
+
* checked. Only `status: 'complete'` may be read as a clean/measured result.
|
|
69
111
|
*/
|
|
70
|
-
async
|
|
112
|
+
async lookupBatch(packages) {
|
|
71
113
|
const results = new Map();
|
|
72
|
-
|
|
73
|
-
|
|
114
|
+
const unchecked = [];
|
|
115
|
+
const errors = [];
|
|
116
|
+
const queryable = [];
|
|
117
|
+
let checked = 0;
|
|
118
|
+
const endpoint = this.resolveEndpoint();
|
|
119
|
+
if ('reason' in endpoint) {
|
|
120
|
+
return {
|
|
121
|
+
status: lookupStatus(packages.length, 0), results, packagesRequested: packages.length, packagesChecked: 0,
|
|
122
|
+
unchecked: packages.map((pkg) => ({ ...pkg, reason: endpoint.reason })), errors: [endpoint.reason],
|
|
123
|
+
};
|
|
74
124
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
name: pkg.name,
|
|
79
|
-
ecosystem: pkg.ecosystem,
|
|
80
|
-
...(pkg.version && { version: pkg.version }),
|
|
81
|
-
},
|
|
82
|
-
}));
|
|
83
|
-
const result = await this.http.post(`${this.config.baseUrl}/v1/querybatch`, { queries }, { timeout: this.config.timeout });
|
|
84
|
-
if (!result.success) {
|
|
85
|
-
console.error('OSV batch query failed:', result.error);
|
|
86
|
-
for (const pkg of packages) {
|
|
87
|
-
results.set(`${pkg.ecosystem}:${pkg.name}`, []);
|
|
88
|
-
}
|
|
89
|
-
return results;
|
|
125
|
+
for (const pkg of packages) {
|
|
126
|
+
if (pkg.version && isConcreteVersion(pkg.version)) {
|
|
127
|
+
queryable.push(pkg);
|
|
90
128
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const key = `${pkg.ecosystem}:${pkg.name}`;
|
|
96
|
-
const vulns = response.results[i]?.vulns || [];
|
|
97
|
-
results.set(key, this.parseVulnerabilities(vulns));
|
|
129
|
+
else {
|
|
130
|
+
unchecked.push({ ...pkg, reason: pkg.version
|
|
131
|
+
? `version "${pkg.version}" is a range or tag, not a concrete version (no lockfile resolution)`
|
|
132
|
+
: 'no version declared; advisories cannot be matched' });
|
|
98
133
|
}
|
|
99
134
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
135
|
+
const pending = [];
|
|
136
|
+
for (let start = 0; start < queryable.length; start += this.config.batchSize) {
|
|
137
|
+
const chunk = queryable.slice(start, start + this.config.batchSize);
|
|
138
|
+
const outcome = await this.postBatch(chunk);
|
|
139
|
+
if ('reason' in outcome) {
|
|
140
|
+
errors.push(`querybatch for ${chunk.length} package(s) failed: ${outcome.reason}`);
|
|
141
|
+
for (const pkg of chunk)
|
|
142
|
+
unchecked.push({ ...pkg, reason: outcome.reason });
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
outcome.entries.forEach((entry, i) => {
|
|
146
|
+
if ('reason' in entry)
|
|
147
|
+
unchecked.push({ ...chunk[i], reason: entry.reason });
|
|
148
|
+
else
|
|
149
|
+
pending.push({ pkg: chunk[i], ids: entry.ids });
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const details = await this.fetchDetails([...new Set(pending.flatMap((p) => p.ids))]);
|
|
153
|
+
for (const { pkg, ids } of pending) {
|
|
154
|
+
const missing = ids.filter((id) => 'reason' in details.get(id));
|
|
155
|
+
if (missing.length > 0) {
|
|
156
|
+
const why = details.get(missing[0]).reason;
|
|
157
|
+
unchecked.push({ ...pkg, reason: `advisory details unavailable for ${boundedList(missing)}: ${why}` });
|
|
158
|
+
continue;
|
|
105
159
|
}
|
|
160
|
+
// querybatch can over-match; keep only advisories whose own ranges do not exclude the version.
|
|
161
|
+
const vulns = ids.map((id) => details.get(id).vuln)
|
|
162
|
+
.filter((vuln) => advisoryAffectsVersion(vuln, { name: pkg.name, ecosystem: pkg.ecosystem, version: pkg.version }));
|
|
163
|
+
results.set(lookupKey(pkg), this.parseVulnerabilities(vulns).map((v) => ({ ...v, affectedPackage: pkg.name })));
|
|
164
|
+
checked++;
|
|
106
165
|
}
|
|
107
|
-
|
|
166
|
+
const detailFailures = [...details.values()].filter((d) => 'reason' in d);
|
|
167
|
+
if (detailFailures.length > 0) {
|
|
168
|
+
errors.push(`${detailFailures.length} advisory detail request(s) failed: ${detailFailures[0].reason}`);
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
status: lookupStatus(packages.length, checked),
|
|
172
|
+
results,
|
|
173
|
+
packagesRequested: packages.length,
|
|
174
|
+
packagesChecked: checked,
|
|
175
|
+
unchecked,
|
|
176
|
+
errors,
|
|
177
|
+
};
|
|
108
178
|
}
|
|
109
179
|
/**
|
|
110
|
-
*
|
|
180
|
+
* Look up npm `package.json` dependencies (`name -> version spec`).
|
|
181
|
+
*
|
|
182
|
+
* A dependency is checked at its lockfile-resolved version when one is given,
|
|
183
|
+
* else only when the spec is an exact version ("1.2.3", "=1.2.3", "v1.2.3").
|
|
184
|
+
* Ranges, tags and non-registry specs are reported unchecked, never guessed:
|
|
185
|
+
* checking a range's bound (e.g. "<4.17.12" as 4.17.12) can miss advisories
|
|
186
|
+
* that affect the versions the range allows (#1049).
|
|
111
187
|
*/
|
|
112
|
-
async
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
188
|
+
async lookupNpmDependencies(dependencies, lockedVersions = {}) {
|
|
189
|
+
const queries = [];
|
|
190
|
+
const unresolved = [];
|
|
191
|
+
for (const [name, spec] of Object.entries(dependencies)) {
|
|
192
|
+
const kind = classifyNpmSpec(spec);
|
|
193
|
+
if (kind.kind === 'local' || kind.kind === 'remote') {
|
|
194
|
+
unresolved.push({ name, ecosystem: 'npm', version: spec, reason: kind.kind === 'local'
|
|
195
|
+
? `local package ("${spec}"); not an OSV subject`
|
|
196
|
+
: `not a registry dependency ("${spec}": git/URL/tarball source); OSV advisories cannot be matched` });
|
|
197
|
+
continue;
|
|
118
198
|
}
|
|
119
|
-
|
|
120
|
-
|
|
199
|
+
// An `npm:<real>@<range>` alias is the registry package <real>.
|
|
200
|
+
const packageName = kind.kind === 'alias' ? kind.name : name;
|
|
201
|
+
const locked = lockedVersions[name] !== undefined ? exactNpmVersion(lockedVersions[name]) : null;
|
|
202
|
+
const version = locked ?? exactNpmVersion(kind.spec);
|
|
203
|
+
if (version)
|
|
204
|
+
queries.push({ name: packageName, ecosystem: 'npm', version });
|
|
205
|
+
else
|
|
206
|
+
unresolved.push({ name, ecosystem: 'npm', version: spec, reason: `version range "${spec}", no lockfile resolution` });
|
|
121
207
|
}
|
|
122
|
-
|
|
123
|
-
|
|
208
|
+
const lookup = await this.lookupBatch(queries);
|
|
209
|
+
const requested = queries.length + unresolved.length;
|
|
210
|
+
return {
|
|
211
|
+
...lookup,
|
|
212
|
+
status: lookupStatus(requested, lookup.packagesChecked),
|
|
213
|
+
packagesRequested: requested,
|
|
214
|
+
unchecked: [...unresolved, ...lookup.unchecked],
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Query OSV for vulnerabilities affecting a package.
|
|
219
|
+
* @throws OSVLookupError when the advisory lookup did not complete.
|
|
220
|
+
*/
|
|
221
|
+
async queryPackage(packageName, ecosystem, version) {
|
|
222
|
+
const result = await this.http.post(`${this.base}/v1/query`,
|
|
223
|
+
// OSV reads `version` at the top level of a query; inside `package` it is ignored (#1049).
|
|
224
|
+
{ package: { name: packageName, ecosystem }, ...(version && { version }) }, this.requestOptions());
|
|
225
|
+
const body = await this.readJson(result);
|
|
226
|
+
if ('reason' in body)
|
|
227
|
+
throw new OSVLookupError(`OSV query for ${ecosystem}:${packageName} failed: ${body.reason}`);
|
|
228
|
+
const vulns = body.value?.vulns;
|
|
229
|
+
if (vulns === undefined && body.value && typeof body.value === 'object')
|
|
124
230
|
return [];
|
|
231
|
+
if (!Array.isArray(vulns) || !vulns.every(isAdvisoryRecord)) {
|
|
232
|
+
throw new OSVLookupError(`OSV query for ${ecosystem}:${packageName} failed: malformed response`);
|
|
125
233
|
}
|
|
234
|
+
return this.parseVulnerabilities(vulns);
|
|
126
235
|
}
|
|
127
236
|
/**
|
|
128
|
-
*
|
|
237
|
+
* Batch query multiple packages.
|
|
238
|
+
* @throws OSVLookupError when any package could not be checked.
|
|
239
|
+
*/
|
|
240
|
+
async queryBatch(packages) {
|
|
241
|
+
const lookup = await this.lookupBatch(packages);
|
|
242
|
+
if (lookup.status !== 'complete')
|
|
243
|
+
throw OSVLookupError.fromLookup(lookup);
|
|
244
|
+
return lookup.results;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Query vulnerabilities by advisory/CVE id. An id OSV does not know (404) is [].
|
|
248
|
+
* @throws OSVLookupError on any other failure.
|
|
249
|
+
*/
|
|
250
|
+
async queryByCVE(cveId) {
|
|
251
|
+
void this.base; // an invalid endpoint throws OSVLookupError
|
|
252
|
+
const outcome = await this.fetchDetail(cveId);
|
|
253
|
+
if ('vuln' in outcome)
|
|
254
|
+
return this.parseVulnerabilities([outcome.vuln]);
|
|
255
|
+
if (outcome.reason === 'HTTP 404')
|
|
256
|
+
return [];
|
|
257
|
+
throw new OSVLookupError(`OSV lookup for ${cveId} failed: ${outcome.reason}`);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Scan npm dependencies for vulnerabilities.
|
|
261
|
+
* @throws OSVLookupError when any dependency could not be checked; use
|
|
262
|
+
* `lookupNpmDependencies` to get partial results with the unchecked list.
|
|
129
263
|
*/
|
|
130
264
|
async scanNpmDependencies(dependencies) {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}));
|
|
136
|
-
const results = await this.queryBatch(packages);
|
|
137
|
-
const allVulns = [];
|
|
138
|
-
for (const vulns of results.values()) {
|
|
139
|
-
allVulns.push(...vulns);
|
|
140
|
-
}
|
|
141
|
-
return allVulns;
|
|
265
|
+
const lookup = await this.lookupNpmDependencies(dependencies);
|
|
266
|
+
if (lookup.status !== 'complete')
|
|
267
|
+
throw OSVLookupError.fromLookup(lookup);
|
|
268
|
+
return [...lookup.results.values()].flat();
|
|
142
269
|
}
|
|
143
270
|
/**
|
|
144
|
-
* Scan a Python requirements.txt file content
|
|
271
|
+
* Scan a Python requirements.txt file content. Only `==` pins are concrete
|
|
272
|
+
* versions; other requirements are reported as unchecked.
|
|
273
|
+
* @throws OSVLookupError when any requirement could not be checked.
|
|
145
274
|
*/
|
|
146
275
|
async scanPythonRequirements(requirements) {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
.map((
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
276
|
+
const packages = requirements.split('\n')
|
|
277
|
+
.map((line) => line.trim())
|
|
278
|
+
.filter((line) => line && !line.startsWith('#') && !line.startsWith('-'))
|
|
279
|
+
.map((line) => line.match(/^([a-zA-Z0-9_.-]+)(?:\s*==\s*([^\s;#,]+))?/))
|
|
280
|
+
.filter((m) => m !== null)
|
|
281
|
+
.map((m) => ({ name: m[1], ecosystem: 'PyPI', version: m[2] }));
|
|
282
|
+
const lookup = await this.lookupBatch(packages);
|
|
283
|
+
if (lookup.status !== 'complete')
|
|
284
|
+
throw OSVLookupError.fromLookup(lookup);
|
|
285
|
+
return [...lookup.results.values()].flat();
|
|
286
|
+
}
|
|
287
|
+
/** Clear the advisory-detail cache. */
|
|
288
|
+
clearCache() {
|
|
289
|
+
this.detailCache.clear();
|
|
290
|
+
}
|
|
291
|
+
// ==========================================================================
|
|
292
|
+
// Private
|
|
293
|
+
// ==========================================================================
|
|
294
|
+
requestOptions() {
|
|
295
|
+
return { timeout: this.config.timeout, retries: this.config.retries };
|
|
296
|
+
}
|
|
297
|
+
/** Read a JSON body; any transport failure, non-2xx status or parse failure is a reason. */
|
|
298
|
+
async readJson(result) {
|
|
299
|
+
if (!result.success)
|
|
300
|
+
return { reason: `${result.error.code}: ${result.error.message}` };
|
|
301
|
+
const response = result.value;
|
|
302
|
+
if (!response.ok) {
|
|
303
|
+
await response.body?.cancel().catch(() => undefined);
|
|
304
|
+
return { reason: `HTTP ${response.status}${response.status === 429 ? ' (rate limited)' : ''}` };
|
|
305
|
+
}
|
|
306
|
+
let text;
|
|
307
|
+
try {
|
|
308
|
+
text = await response.text();
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
const timedOut = error instanceof Error && (error.name === 'TimeoutError' || error.name === 'AbortError');
|
|
312
|
+
return { reason: `${timedOut ? 'TIMEOUT' : 'BODY_READ_FAILED'}: response body could not be read` };
|
|
168
313
|
}
|
|
169
|
-
|
|
314
|
+
try {
|
|
315
|
+
return { value: JSON.parse(text) };
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return { reason: 'malformed JSON response' };
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
async postBatch(chunk) {
|
|
322
|
+
const queries = chunk.map((pkg) => ({
|
|
323
|
+
// OSV reads `version` at the top level of a query; inside `package` it is ignored (#1049).
|
|
324
|
+
package: { name: pkg.name, ecosystem: pkg.ecosystem },
|
|
325
|
+
...(pkg.version ? { version: pkg.version } : {}),
|
|
326
|
+
}));
|
|
327
|
+
const result = await this.http.post(`${this.base}/v1/querybatch`, { queries }, this.requestOptions());
|
|
328
|
+
const body = await this.readJson(result);
|
|
329
|
+
if ('reason' in body)
|
|
330
|
+
return body;
|
|
331
|
+
const entries = parseBatchBody(body.value, chunk.length);
|
|
332
|
+
return entries ? { entries } : { reason: 'malformed OSV querybatch response (results do not match the queries)' };
|
|
333
|
+
}
|
|
334
|
+
/** Fetch full advisory records (querybatch returns only ids) with bounded concurrency. */
|
|
335
|
+
async fetchDetails(ids) {
|
|
336
|
+
const out = new Map();
|
|
337
|
+
let next = 0;
|
|
338
|
+
const worker = async () => {
|
|
339
|
+
while (next < ids.length) {
|
|
340
|
+
const id = ids[next++];
|
|
341
|
+
out.set(id, await this.fetchDetail(id));
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
await Promise.all(Array.from({ length: Math.min(this.config.detailConcurrency, ids.length) }, worker));
|
|
345
|
+
return out;
|
|
346
|
+
}
|
|
347
|
+
async fetchDetail(id) {
|
|
348
|
+
const cached = this.config.enableCache ? this.detailCache.get(id) : undefined;
|
|
349
|
+
if (cached && Date.now() - cached.timestamp < this.config.cacheTtl)
|
|
350
|
+
return { vuln: cached.data };
|
|
351
|
+
const result = await this.http.get(`${this.base}/v1/vulns/${encodeURIComponent(id)}`, this.requestOptions());
|
|
352
|
+
const body = await this.readJson(result);
|
|
353
|
+
if ('reason' in body)
|
|
354
|
+
return body;
|
|
355
|
+
if (!isAdvisoryRecord(body.value))
|
|
356
|
+
return { reason: 'malformed OSV advisory record' };
|
|
357
|
+
const vuln = body.value;
|
|
358
|
+
if (this.config.enableCache)
|
|
359
|
+
this.detailCache.set(id, { data: vuln, timestamp: Date.now() });
|
|
360
|
+
return { vuln };
|
|
170
361
|
}
|
|
171
362
|
/**
|
|
172
363
|
* Parse vulnerabilities into a more usable format
|
|
@@ -174,55 +365,54 @@ export class OSVClient {
|
|
|
174
365
|
parseVulnerabilities(vulns) {
|
|
175
366
|
return vulns.map((vuln) => {
|
|
176
367
|
const cvssScore = this.extractCVSSScore(vuln.severity);
|
|
177
|
-
const severity = this.scoreSeverity(cvssScore);
|
|
178
|
-
const fixedVersions = this.extractFixedVersions(vuln.affected);
|
|
179
368
|
return {
|
|
180
369
|
id: vuln.id,
|
|
181
370
|
cveIds: vuln.aliases?.filter((a) => a.startsWith('CVE-')) || [],
|
|
182
371
|
summary: vuln.summary || 'No summary available',
|
|
183
372
|
details: vuln.details || '',
|
|
184
|
-
severity,
|
|
373
|
+
severity: this.scoreSeverity(cvssScore, vuln.database_specific),
|
|
185
374
|
cvssScore,
|
|
186
|
-
affectedPackage: vuln.affected[0]?.package?.name || 'unknown',
|
|
187
|
-
affectedVersions: vuln.affected[0]?.versions || [],
|
|
188
|
-
fixedVersions,
|
|
375
|
+
affectedPackage: vuln.affected?.[0]?.package?.name || 'unknown',
|
|
376
|
+
affectedVersions: vuln.affected?.[0]?.versions || [],
|
|
377
|
+
fixedVersions: this.extractFixedVersions(vuln.affected ?? []),
|
|
189
378
|
publishedDate: vuln.published ? new Date(vuln.published) : null,
|
|
190
379
|
references: vuln.references?.map((r) => r.url) || [],
|
|
191
380
|
};
|
|
192
381
|
});
|
|
193
382
|
}
|
|
194
383
|
/**
|
|
195
|
-
* Extract CVSS score
|
|
384
|
+
* Extract a numeric CVSS score. OSV usually carries a CVSS vector string
|
|
385
|
+
* ("CVSS:3.1/AV:N/..."), which holds no base score: that yields null.
|
|
196
386
|
*/
|
|
197
387
|
extractCVSSScore(severity) {
|
|
198
388
|
if (!severity || severity.length === 0)
|
|
199
389
|
return null;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
const v2 = severity.find((s) => s.type === 'CVSS_V2');
|
|
207
|
-
if (v2) {
|
|
208
|
-
const score = parseFloat(v2.score.split('/')[0]);
|
|
209
|
-
return isNaN(score) ? null : score;
|
|
210
|
-
}
|
|
211
|
-
return null;
|
|
390
|
+
const entry = severity.find((s) => s.type === 'CVSS_V3') ?? severity.find((s) => s.type === 'CVSS_V2');
|
|
391
|
+
if (!entry || typeof entry.score !== 'string' || entry.score.startsWith('CVSS:'))
|
|
392
|
+
return null;
|
|
393
|
+
const score = parseFloat(entry.score.split('/')[0]);
|
|
394
|
+
return isNaN(score) ? null : score;
|
|
212
395
|
}
|
|
213
396
|
/**
|
|
214
|
-
*
|
|
397
|
+
* Severity from a numeric CVSS score, else the advisory's own severity label
|
|
398
|
+
* (GitHub advisories carry `database_specific.severity`), else unknown.
|
|
215
399
|
*/
|
|
216
|
-
scoreSeverity(cvss) {
|
|
217
|
-
if (cvss
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
400
|
+
scoreSeverity(cvss, databaseSpecific) {
|
|
401
|
+
if (cvss !== null) {
|
|
402
|
+
if (cvss >= 9.0)
|
|
403
|
+
return 'critical';
|
|
404
|
+
if (cvss >= 7.0)
|
|
405
|
+
return 'high';
|
|
406
|
+
if (cvss >= 4.0)
|
|
407
|
+
return 'medium';
|
|
408
|
+
return 'low';
|
|
409
|
+
}
|
|
410
|
+
const label = typeof databaseSpecific?.severity === 'string' ? databaseSpecific.severity.toLowerCase() : '';
|
|
411
|
+
if (label === 'critical' || label === 'high' || label === 'low')
|
|
412
|
+
return label;
|
|
413
|
+
if (label === 'medium' || label === 'moderate')
|
|
224
414
|
return 'medium';
|
|
225
|
-
return '
|
|
415
|
+
return 'unknown';
|
|
226
416
|
}
|
|
227
417
|
/**
|
|
228
418
|
* Extract fixed versions from affected ranges
|
|
@@ -231,26 +421,13 @@ export class OSVClient {
|
|
|
231
421
|
const fixed = [];
|
|
232
422
|
for (const aff of affected) {
|
|
233
423
|
for (const range of aff.ranges || []) {
|
|
234
|
-
for (const event of range.events) {
|
|
235
|
-
if (event.fixed)
|
|
424
|
+
for (const event of range.events || []) {
|
|
425
|
+
if (event.fixed)
|
|
236
426
|
fixed.push(event.fixed);
|
|
237
|
-
}
|
|
238
427
|
}
|
|
239
428
|
}
|
|
240
429
|
}
|
|
241
430
|
return [...new Set(fixed)];
|
|
242
431
|
}
|
|
243
|
-
/**
|
|
244
|
-
* Clean version string (remove ^ ~ etc.)
|
|
245
|
-
*/
|
|
246
|
-
cleanVersion(version) {
|
|
247
|
-
return version.replace(/^[\^~>=<]/, '').split(' ')[0];
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Clear the cache
|
|
251
|
-
*/
|
|
252
|
-
clearCache() {
|
|
253
|
-
this.cache.clear();
|
|
254
|
-
}
|
|
255
432
|
}
|
|
256
433
|
//# sourceMappingURL=osv-client.js.map
|