compromised packages list
https://www.mend.io/blog/npm-supply-chain-attack-packages-compromised-by-self-spreading-malware/
the latest list
https://github.com/wiz-sec-public/wiz-research-iocs/blob/main/reports/shai-hulud-2-packages.csv
support yarn v1, npm, and pnpm
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
// ==========================================
// 1. Configuration and Data Definitions
// ==========================================
// Shai-Hulud compromised package list
const shaiHuludCompromisedPackages = [
{ package: "02-echo", versions: ["0.0.7"] },
{ package: "@accordproject/concerto-analysis", versions: ["3.24.1"] },
{ package: "@accordproject/concerto-linter", versions: ["3.24.1"] },
{ package: "@accordproject/concerto-linter-default-ruleset", versions: ["3.24.1"] },
{ package: "@accordproject/concerto-metamodel", versions: ["3.12.5"] },
{ package: "@accordproject/concerto-types", versions: ["3.24.1"] },
{ package: "@accordproject/markdown-it-cicero", versions: ["0.16.26"] },
{ package: "@accordproject/template-engine", versions: ["2.7.2"] },
{ package: "@actbase/css-to-react-native-transform", versions: ["1.0.3"] },
{ package: "@actbase/native", versions: ["0.1.32"] },
{ package: "@actbase/node-server", versions: ["1.1.19"] },
{ package: "@actbase/react-absolute", versions: ["0.8.3"] },
{ package: "@actbase/react-daum-postcode", versions: ["1.0.5"] },
{ package: "@actbase/react-kakaosdk", versions: ["0.9.27"] },
{ package: "@actbase/react-native-actionsheet", versions: ["1.0.3"] },
{ package: "@actbase/react-native-devtools", versions: ["0.1.3"] },
{ package: "@actbase/react-native-fast-image", versions: ["8.5.13"] },
{ package: "@actbase/react-native-kakao-channel", versions: ["1.0.2"] },
{ package: "@actbase/react-native-kakao-navi", versions: ["2.0.4"] },
{ package: "@actbase/react-native-less-transformer", versions: ["1.0.6"] },
{ package: "@actbase/react-native-naver-login", versions: ["1.0.1"] },
{ package: "@actbase/react-native-simple-video", versions: ["1.0.13"] },
{ package: "@actbase/react-native-tiktok", versions: ["1.1.3"] },
{ package: "@afetcan/api", versions: ["0.0.13"] },
{ package: "@afetcan/storage", versions: ["0.0.27"] },
{ package: "@alaan/s2s-auth", versions: ["2.0.3"] },
{ package: "@alexadark/amadeus-api", versions: ["1.0.4"] },
{ package: "@alexadark/gatsby-theme-events", versions: ["1.0.1"] },
{ package: "@alexadark/gatsby-theme-wordpress-blog", versions: ["2.0.1"] },
{ package: "@alexadark/reusable-functions", versions: ["1.5.1"] },
{ package: "@alexcolls/nuxt-socket.io", versions: ["0.0.7", "0.0.8"] },
{ package: "@alexcolls/nuxt-ux", versions: ["0.6.1", "0.6.2"] },
{ package: "@antstackio/eslint-config-antstack", versions: ["0.0.3"] },
{ package: "@antstackio/express-graphql-proxy", versions: ["0.2.8"] },
{ package: "@antstackio/graphql-body-parser", versions: ["0.1.1"] },
{ package: "@antstackio/json-to-graphql", versions: ["1.0.3"] },
{ package: "@antstackio/shelbysam", versions: ["1.1.7"] },
{ package: "@aryanhussain/my-angular-lib", versions: ["0.0.23"] },
{ package: "@asyncapi/avro-schema-parser", versions: ["3.0.25", "3.0.26"] },
{ package: "@asyncapi/bundler", versions: ["0.6.5", "0.6.6"] },
{ package: "@asyncapi/cli", versions: ["4.1.3", "4.1.2"] },
{ package: "@asyncapi/converter", versions: ["1.6.3", "1.6.4"] },
{ package: "@asyncapi/diff", versions: ["0.5.1", "0.5.2"] },
{ package: "@asyncapi/dotnet-rabbitmq-template", versions: ["1.0.2", "1.0.1"] },
{ package: "@asyncapi/edavisualiser", versions: ["1.2.2", "1.2.1"] },
{ package: "@asyncapi/generator", versions: ["2.8.5", "2.8.6"] },
{ package: "@asyncapi/generator-components", versions: ["0.3.2", "0.3.3"] },
{ package: "@asyncapi/generator-helpers", versions: ["0.2.1", "0.2.2"] },
{ package: "@asyncapi/generator-react-sdk", versions: ["1.1.5", "1.1.4"] },
{ package: "@asyncapi/go-watermill-template", versions: ["0.2.77", "0.2.76"] },
{ package: "@asyncapi/html-template", versions: ["3.3.2", "3.3.3"] },
{ package: "@asyncapi/java-spring-cloud-stream-template", versions: ["0.13.5", "0.13.6"] },
{ package: "@asyncapi/java-spring-template", versions: ["1.6.2", "1.6.1"] },
{ package: "@asyncapi/java-template", versions: ["0.3.6", "0.3.5"] },
{ package: "@asyncapi/keeper", versions: ["0.0.2", "0.0.3"] },
{ package: "@asyncapi/markdown-template", versions: ["1.6.8", "1.6.9"] },
{ package: "@asyncapi/modelina", versions: ["5.10.3", "5.10.2"] },
{ package: "@asyncapi/modelina-cli", versions: ["5.10.3", "5.10.2"] },
{ package: "@asyncapi/multi-parser", versions: ["2.2.1", "2.2.2"] },
{ package: "@asyncapi/nodejs-template", versions: ["3.0.6", "3.0.5"] },
{ package: "@asyncapi/nodejs-ws-template", versions: ["0.10.1", "0.10.2"] },
{ package: "@asyncapi/nunjucks-filters", versions: ["2.1.1", "2.1.2"] },
{ package: "@asyncapi/openapi-schema-parser", versions: ["3.0.25", "3.0.26"] },
{ package: "@asyncapi/optimizer", versions: ["1.0.6", "1.0.5"] },
{ package: "@asyncapi/parser", versions: ["3.4.1", "3.4.2"] },
{ package: "@asyncapi/php-template", versions: ["0.1.1", "0.1.2"] },
{ package: "@asyncapi/problem", versions: ["1.0.2", "1.0.1"] },
{ package: "@asyncapi/protobuf-schema-parser", versions: ["3.5.2", "3.6.1", "3.5.3"] },
{ package: "@asyncapi/python-paho-template", versions: ["0.2.15", "0.2.14"] },
{ package: "@asyncapi/react-component", versions: ["2.6.7", "2.6.6"] },
{ package: "@asyncapi/server-api", versions: ["0.16.24", "0.16.25"] },
{ package: "@asyncapi/specs", versions: ["6.9.1", "6.10.1", "6.8.3", "6.8.2"] },
{ package: "@asyncapi/studio", versions: ["1.0.3", "1.0.2"] },
{ package: "@asyncapi/web-component", versions: ["2.6.7", "2.6.6"] },
{ package: "@bdkinc/knex-ibmi", versions: ["0.5.7"] },
{ package: "@browserbasehq/bb9", versions: ["1.2.21"] },
{ package: "@browserbasehq/director-ai", versions: ["1.0.3"] },
{ package: "@browserbasehq/mcp", versions: ["2.1.1"] },
{ package: "@browserbasehq/mcp-server-browserbase", versions: ["2.4.2"] },
{ package: "@browserbasehq/sdk-functions", versions: ["0.0.4"] },
{ package: "@browserbasehq/stagehand", versions: ["3.0.4"] },
{ package: "@browserbasehq/stagehand-docs", versions: ["1.0.1"] },
{ package: "@caretive/caret-cli", versions: ["0.0.2"] },
{ package: "@chtijs/eslint-config", versions: ["1.0.1"] },
{ package: "@clausehq/flows-step-httprequest", versions: ["0.1.14"] },
{ package: "@clausehq/flows-step-jsontoxml", versions: ["0.1.14"] },
{ package: "@clausehq/flows-step-mqtt", versions: ["0.1.14"] },
{ package: "@clausehq/flows-step-sendgridemail", versions: ["0.1.14"] },
{ package: "@clausehq/flows-step-taskscreateurl", versions: ["0.1.14"] },
{ package: "@cllbk/ghl", versions: ["1.3.1"] },
{ package: "@commute/bloom", versions: ["1.0.3"] },
{ package: "@commute/market-data", versions: ["1.0.2"] },
{ package: "@commute/market-data-chartjs", versions: ["2.3.1"] },
{ package: "@dev-blinq/ai-qa-logic", versions: ["1.0.19"] },
{ package: "@dev-blinq/blinqioclient", versions: ["1.0.21"] },
{ package: "@dev-blinq/cucumber-js", versions: ["1.0.131"] },
{ package: "@dev-blinq/cucumber_client", versions: ["1.0.738"] },
{ package: "@dev-blinq/ui-systems", versions: ["1.0.93"] },
{ package: "@ensdomains/address-encoder", versions: ["1.1.5"] },
{ package: "@ensdomains/blacklist", versions: ["1.0.1"] },
{ package: "@ensdomains/buffer", versions: ["0.1.2"] },
{ package: "@ensdomains/ccip-read-cf-worker", versions: ["0.0.4"] },
{ package: "@ensdomains/ccip-read-dns-gateway", versions: ["0.1.1"] },
{ package: "@ensdomains/ccip-read-router", versions: ["0.0.7"] },
{ package: "@ensdomains/ccip-read-worker-viem", versions: ["0.0.4"] },
{ package: "@ensdomains/content-hash", versions: ["3.0.1"] },
{ package: "@ensdomains/curvearithmetics", versions: ["1.0.1"] },
{ package: "@ensdomains/cypress-metamask", versions: ["1.2.1"] },
{ package: "@ensdomains/dnsprovejs", versions: ["0.5.3"] },
{ package: "@ensdomains/dnssec-oracle-anchors", versions: ["0.0.2"] },
{ package: "@ensdomains/dnssecoraclejs", versions: ["0.2.9"] },
{ package: "@ensdomains/durin", versions: ["0.1.2"] },
{ package: "@ensdomains/durin-middleware", versions: ["0.0.2"] },
{ package: "@ensdomains/ens-archived-contracts", versions: ["0.0.3"] },
{ package: "@ensdomains/ens-avatar", versions: ["1.0.4"] },
{ package: "@ensdomains/ens-contracts", versions: ["1.6.1"] },
{ package: "@ensdomains/ens-test-env", versions: ["1.0.2"] },
{ package: "@ensdomains/ens-validation", versions: ["0.1.1"] },
{ package: "@ensdomains/ensjs", versions: ["4.0.3"] },
{ package: "@ensdomains/ensjs-react", versions: ["0.0.5"] },
{ package: "@ensdomains/eth-ens-namehash", versions: ["2.0.16"] },
{ package: "@ensdomains/hackathon-registrar", versions: ["1.0.5"] },
{ package: "@ensdomains/hardhat-chai-matchers-viem", versions: ["0.1.15"] },
{ package: "@ensdomains/hardhat-toolbox-viem-extended", versions: ["0.0.6"] },
{ package: "@ensdomains/mock", versions: ["2.1.52"] },
{ package: "@ensdomains/name-wrapper", versions: ["1.0.1"] },
{ package: "@ensdomains/offchain-resolver-contracts", versions: ["0.2.2"] },
{ package: "@ensdomains/op-resolver-contracts", versions: ["0.0.2"] },
{ package: "@ensdomains/react-ens-address", versions: ["0.0.32"] },
{ package: "@ensdomains/renewal", versions: ["0.0.13"] },
{ package: "@ensdomains/renewal-widget", versions: ["0.1.10"] },
{ package: "@ensdomains/reverse-records", versions: ["1.0.1"] },
{ package: "@ensdomains/server-analytics", versions: ["0.0.2"] },
{ package: "@ensdomains/solsha1", versions: ["0.0.4"] },
{ package: "@ensdomains/subdomain-registrar", versions: ["0.2.4"] },
{ package: "@ensdomains/test-utils", versions: ["1.3.1"] },
{ package: "@ensdomains/thorin", versions: ["0.6.51"] },
{ package: "@ensdomains/ui", versions: ["3.4.6"] },
{ package: "@ensdomains/unicode-confusables", versions: ["0.1.1"] },
{ package: "@ensdomains/unruggable-gateways", versions: ["0.0.3"] },
{ package: "@ensdomains/vite-plugin-i18next-loader", versions: ["4.0.4"] },
{ package: "@ensdomains/web3modal", versions: ["1.10.2"] },
{ package: "@everreal/react-charts", versions: ["2.0.2", "2.0.1"] },
{ package: "@everreal/validate-esmoduleinterop-imports", versions: ["1.4.5", "1.4.4"] },
{ package: "@everreal/web-analytics", versions: ["0.0.1", "0.0.2"] },
{ package: "@faq-component/core", versions: ["0.0.4"] },
{ package: "@faq-component/react", versions: ["1.0.1"] },
{ package: "@fishingbooker/browser-sync-plugin", versions: ["1.0.5"] },
{ package: "@fishingbooker/react-loader", versions: ["1.0.7"] },
{ package: "@fishingbooker/react-pagination", versions: ["2.0.6"] },
{ package: "@fishingbooker/react-raty", versions: ["2.0.1"] },
{ package: "@fishingbooker/react-swiper", versions: ["0.1.5"] },
{ package: "@hapheus/n8n-nodes-pgp", versions: ["1.5.1"] },
{ package: "@hover-design/core", versions: ["0.0.1"] },
{ package: "@hover-design/react", versions: ["0.2.1"] },
{ package: "@huntersofbook/auth-vue", versions: ["0.4.2"] },
{ package: "@huntersofbook/core", versions: ["0.5.1"] },
{ package: "@huntersofbook/core-nuxt", versions: ["0.4.2"] },
{ package: "@huntersofbook/form-naiveui", versions: ["0.5.1"] },
{ package: "@huntersofbook/i18n", versions: ["0.8.2"] },
{ package: "@huntersofbook/ui", versions: ["0.5.1"] },
{ package: "@hyperlook/telemetry-sdk", versions: ["1.0.19"] },
{ package: "@ifelsedeveloper/protocol-contracts-svm-idl", versions: ["0.1.2", "0.1.3"] },
{ package: "@ifings/design-system", versions: ["4.9.2"] },
{ package: "@ifings/metatron3", versions: ["0.1.5"] },
{ package: "@jayeshsadhwani/telemetry-sdk", versions: ["1.0.14"] },
{ package: "@kvytech/cli", versions: ["0.0.7"] },
{ package: "@kvytech/components", versions: ["0.0.2"] },
{ package: "@kvytech/habbit-e2e-test", versions: ["0.0.2"] },
{ package: "@kvytech/medusa-plugin-announcement", versions: ["0.0.8"] },
{ package: "@kvytech/medusa-plugin-management", versions: ["0.0.5"] },
{ package: "@kvytech/medusa-plugin-newsletter", versions: ["0.0.5"] },
{ package: "@kvytech/medusa-plugin-product-reviews", versions: ["0.0.9"] },
{ package: "@kvytech/medusa-plugin-promotion", versions: ["0.0.2"] },
{ package: "@kvytech/web", versions: ["0.0.2"] },
{ package: "@lessondesk/api-client", versions: ["9.12.2", "9.12.3"] },
{ package: "@lessondesk/babel-preset", versions: ["1.0.1"] },
{ package: "@lessondesk/electron-group-api-client", versions: ["1.0.3"] },
{ package: "@lessondesk/eslint-config", versions: ["1.4.2"] },
{ package: "@lessondesk/material-icons", versions: ["1.0.3"] },
{ package: "@lessondesk/react-table-context", versions: ["2.0.4"] },
{ package: "@lessondesk/schoolbus", versions: ["5.2.2", "5.2.3"] },
{ package: "@livecms/live-edit", versions: ["0.0.32"] },
{ package: "@livecms/nuxt-live-edit", versions: ["1.9.2"] },
{ package: "@lokeswari-satyanarayanan/rn-zustand-expo-template", versions: ["1.0.9"] },
{ package: "@louisle2/core", versions: ["1.0.1"] },
{ package: "@louisle2/cortex-js", versions: ["0.1.6"] },
{ package: "@lpdjs/firestore-repo-service", versions: ["1.0.1"] },
{ package: "@lui-ui/lui-nuxt", versions: ["0.1.1"] },
{ package: "@lui-ui/lui-tailwindcss", versions: ["0.1.2"] },
{ package: "@lui-ui/lui-vue", versions: ["1.0.13"] },
{ package: "@markvivanco/app-version-checker", versions: ["1.0.2", "1.0.1"] },
{ package: "@mcp-use/cli", versions: ["2.2.7", "2.2.6"] },
{ package: "@mcp-use/inspector", versions: ["0.6.3", "0.6.2"] },
{ package: "@mcp-use/mcp-use", versions: ["1.0.2", "1.0.1"] },
{ package: "@micado-digital/stadtmarketing-kufstein-external", versions: ["1.9.1"] },
{ package: "@mizzle-dev/orm", versions: ["0.0.2"] },
{ package: "@mparpaillon/connector-parse", versions: ["1.0.1"] },
{ package: "@mparpaillon/imagesloaded", versions: ["4.1.2"] },
{ package: "@mparpaillon/page", versions: ["1.0.1"] },
{ package: "@ntnx/passport-wso2", versions: ["0.0.3"] },
{ package: "@ntnx/t", versions: ["0.0.101"] },
{ package: "@oku-ui/accordion", versions: ["0.6.2"] },
{ package: "@oku-ui/alert-dialog", versions: ["0.6.2"] },
{ package: "@oku-ui/arrow", versions: ["0.6.2"] },
{ package: "@oku-ui/aspect-ratio", versions: ["0.6.2"] },
{ package: "@oku-ui/avatar", versions: ["0.6.2"] },
{ package: "@oku-ui/checkbox", versions: ["0.6.3"] },
{ package: "@oku-ui/collapsible", versions: ["0.6.2"] },
{ package: "@oku-ui/collection", versions: ["0.6.2"] },
{ package: "@oku-ui/dialog", versions: ["0.6.2"] },
{ package: "@oku-ui/direction", versions: ["0.6.2"] },
{ package: "@oku-ui/dismissable-layer", versions: ["0.6.2"] },
{ package: "@oku-ui/focus-guards", versions: ["0.6.2"] },
{ package: "@oku-ui/focus-scope", versions: ["0.6.2"] },
{ package: "@oku-ui/hover-card", versions: ["0.6.2"] },
{ package: "@oku-ui/label", versions: ["0.6.2"] },
{ package: "@oku-ui/menu", versions: ["0.6.2"] },
{ package: "@oku-ui/motion", versions: ["0.4.4"] },
{ package: "@oku-ui/motion-nuxt", versions: ["0.2.2"] },
{ package: "@oku-ui/popover", versions: ["0.6.2"] },
{ package: "@oku-ui/popper", versions: ["0.6.2"] },
{ package: "@oku-ui/portal", versions: ["0.6.2"] },
{ package: "@oku-ui/presence", versions: ["0.6.2"] },
{ package: "@oku-ui/primitive", versions: ["0.6.2"] },
{ package: "@oku-ui/primitives", versions: ["0.7.9"] },
{ package: "@oku-ui/primitives-nuxt", versions: ["0.3.1"] },
{ package: "@oku-ui/progress", versions: ["0.6.2"] },
{ package: "@oku-ui/provide", versions: ["0.6.2"] },
{ package: "@oku-ui/radio-group", versions: ["0.6.2"] },
{ package: "@oku-ui/roving-focus", versions: ["0.6.2"] },
{ package: "@oku-ui/scroll-area", versions: ["0.6.2"] },
{ package: "@oku-ui/separator", versions: ["0.6.2"] },
{ package: "@oku-ui/slider", versions: ["0.6.2"] },
{ package: "@oku-ui/slot", versions: ["0.6.2"] },
{ package: "@oku-ui/switch", versions: ["0.6.2"] },
{ package: "@oku-ui/tabs", versions: ["0.6.2"] },
{ package: "@oku-ui/toast", versions: ["0.6.2"] },
{ package: "@oku-ui/toggle", versions: ["0.6.2"] },
{ package: "@oku-ui/toggle-group", versions: ["0.6.2"] },
{ package: "@oku-ui/toolbar", versions: ["0.6.2"] },
{ package: "@oku-ui/tooltip", versions: ["0.6.2"] },
{ package: "@oku-ui/use-composable", versions: ["0.6.2"] },
{ package: "@oku-ui/utils", versions: ["0.6.2"] },
{ package: "@oku-ui/visually-hidden", versions: ["0.6.2"] },
{ package: "@orbitgtbelgium/mapbox-gl-draw-cut-polygon-mode", versions: ["2.0.5"] },
{ package: "@orbitgtbelgium/mapbox-gl-draw-scale-rotate-mode", versions: ["1.1.1"] },
{ package: "@orbitgtbelgium/orbit-components", versions: ["1.2.9"] },
{ package: "@orbitgtbelgium/time-slider", versions: ["1.0.187"] },
{ package: "@osmanekrem/bmad", versions: ["1.0.6"] },
{ package: "@osmanekrem/error-handler", versions: ["1.2.2"] },
{ package: "@pergel/cli", versions: ["0.11.1"] },
{ package: "@pergel/module-box", versions: ["0.6.1"] },
{ package: "@pergel/module-graphql", versions: ["0.6.1"] },
{ package: "@pergel/module-ui", versions: ["0.0.9"] },
{ package: "@pergel/nuxt", versions: ["0.25.5"] },
{ package: "@posthog/agent", versions: ["1.24.1"] },
{ package: "@posthog/ai", versions: ["7.1.2"] },
{ package: "@posthog/automatic-cohorts-plugin", versions: ["0.0.8"] },
{ package: "@posthog/bitbucket-release-tracker", versions: ["0.0.8"] },
{ package: "@posthog/cli", versions: ["0.5.15"] },
{ package: "@posthog/clickhouse", versions: ["1.7.1"] },
{ package: "@posthog/core", versions: ["1.5.6"] },
{ package: "@posthog/currency-normalization-plugin", versions: ["0.0.8"] },
{ package: "@posthog/customerio-plugin", versions: ["0.0.8"] },
{ package: "@posthog/databricks-plugin", versions: ["0.0.8"] },
{ package: "@posthog/drop-events-on-property-plugin", versions: ["0.0.8"] },
{ package: "@posthog/event-sequence-timer-plugin", versions: ["0.0.8"] },
{ package: "@posthog/filter-out-plugin", versions: ["0.0.8"] },
{ package: "@posthog/first-time-event-tracker", versions: ["0.0.8"] },
{ package: "@posthog/geoip-plugin", versions: ["0.0.8"] },
{ package: "@posthog/github-release-tracking-plugin", versions: ["0.0.8"] },
{ package: "@posthog/gitub-star-sync-plugin", versions: ["0.0.8"] },
{ package: "@posthog/heartbeat-plugin", versions: ["0.0.8"] },
{ package: "@posthog/hedgehog-mode", versions: ["0.0.42"] },
{ package: "@posthog/icons", versions: ["0.36.1"] },
{ package: "@posthog/ingestion-alert-plugin", versions: ["0.0.8"] },
{ package: "@posthog/intercom-plugin", versions: ["0.0.8"] },
{ package: "@posthog/kinesis-plugin", versions: ["0.0.8"] },
{ package: "@posthog/laudspeaker-plugin", versions: ["0.0.8"] },
{ package: "@posthog/lemon-ui", versions: ["0.0.1"] },
{ package: "@posthog/maxmind-plugin", versions: ["0.1.6"] },
{ package: "@posthog/migrator3000-plugin", versions: ["0.0.8"] },
{ package: "@posthog/netdata-event-processing", versions: ["0.0.8"] },
{ package: "@posthog/nextjs", versions: ["0.0.3"] },
{ package: "@posthog/nextjs-config", versions: ["1.5.1"] },
{ package: "@posthog/nuxt", versions: ["1.2.9"] },
{ package: "@posthog/pagerduty-plugin", versions: ["0.0.8"] },
{ package: "@posthog/piscina", versions: ["3.2.1"] },
{ package: "@posthog/plugin-contrib", versions: ["0.0.6"] },
{ package: "@posthog/plugin-server", versions: ["1.10.8"] },
{ package: "@posthog/plugin-unduplicates", versions: ["0.0.8"] },
{ package: "@posthog/postgres-plugin", versions: ["0.0.8"] },
{ package: "@posthog/react-rrweb-player", versions: ["1.1.4"] },
{ package: "@posthog/rrdom", versions: ["0.0.31"] },
{ package: "@posthog/rrweb", versions: ["0.0.31"] },
{ package: "@posthog/rrweb-player", versions: ["0.0.31"] },
{ package: "@posthog/rrweb-record", versions: ["0.0.31"] },
{ package: "@posthog/rrweb-replay", versions: ["0.0.19"] },
{ package: "@posthog/rrweb-snapshot", versions: ["0.0.31"] },
{ package: "@posthog/rrweb-utils", versions: ["0.0.31"] },
{ package: "@posthog/sendgrid-plugin", versions: ["0.0.8"] },
{ package: "@posthog/siphash", versions: ["1.1.2"] },
{ package: "@posthog/snowflake-export-plugin", versions: ["0.0.8"] },
{ package: "@posthog/taxonomy-plugin", versions: ["0.0.8"] },
{ package: "@posthog/twilio-plugin", versions: ["0.0.8"] },
{ package: "@posthog/twitter-followers-plugin", versions: ["0.0.8"] },
{ package: "@posthog/url-normalizer-plugin", versions: ["0.0.8"] },
{ package: "@posthog/variance-plugin", versions: ["0.0.8"] },
{ package: "@posthog/web-dev-server", versions: ["1.0.5"] },
{ package: "@posthog/wizard", versions: ["1.18.1"] },
{ package: "@posthog/zendesk-plugin", versions: ["0.0.8"] },
{ package: "@postman/aether-icons", versions: ["2.23.2", "2.23.3", "2.23.4"] },
{ package: "@postman/csv-parse", versions: ["4.0.3", "4.0.5", "4.0.4"] },
{ package: "@postman/final-node-keytar", versions: ["7.9.3", "7.9.1", "7.9.2"] },
{ package: "@postman/mcp-ui-client", versions: ["5.5.2", "5.5.3", "5.5.1"] },
{ package: "@postman/node-keytar", versions: ["7.9.4", "7.9.5", "7.9.6"] },
{ package: "@postman/pm-bin-linux-x64", versions: ["1.24.3", "1.24.5", "1.24.4"] },
{ package: "@postman/pm-bin-macos-arm64", versions: ["1.24.3", "1.24.5", "1.24.4"] },
{ package: "@postman/pm-bin-macos-x64", versions: ["1.24.3", "1.24.5", "1.24.4"] },
{ package: "@postman/pm-bin-windows-x64", versions: ["1.24.3", "1.24.5", "1.24.4"] },
{ package: "@postman/postman-collection-fork", versions: ["4.3.3", "4.3.5", "4.3.4"] },
{ package: "@postman/postman-mcp-cli", versions: ["1.0.4", "1.0.5", "1.0.3"] },
{ package: "@postman/postman-mcp-server", versions: ["2.4.12", "2.4.10", "2.4.11"] },
{ package: "@postman/pretty-ms", versions: ["6.1.2", "6.1.3", "6.1.1"] },
{ package: "@postman/secret-scanner-wasm", versions: ["2.1.4", "2.1.3", "2.1.2"] },
{ package: "@postman/tunnel-agent", versions: ["0.6.5", "0.6.7", "0.6.6"] },
{ package: "@postman/wdio-allure-reporter", versions: ["0.0.7", "0.0.8", "0.0.9"] },
{ package: "@postman/wdio-junit-reporter", versions: ["0.0.4", "0.0.5", "0.0.6"] },
{ package: "@pradhumngautam/common-app", versions: ["1.0.2"] },
{ package: "@productdevbook/animejs-vue", versions: ["0.2.1"] },
{ package: "@productdevbook/auth", versions: ["0.2.2"] },
{ package: "@productdevbook/chatwoot", versions: ["2.0.1"] },
{ package: "@productdevbook/motion", versions: ["1.0.4"] },
{ package: "@productdevbook/ts-i18n", versions: ["1.4.2"] },
{ package: "@pruthvi21/use-debounce", versions: ["1.0.3"] },
{ package: "@quick-start-soft/quick-document-translator", versions: ["1.4.2511142126"] },
{ package: "@quick-start-soft/quick-git-clean-markdown", versions: ["1.4.2511142126"] },
{ package: "@quick-start-soft/quick-markdown", versions: ["1.4.2511142126"] },
{ package: "@quick-start-soft/quick-markdown-compose", versions: ["1.4.2506300029"] },
{ package: "@quick-start-soft/quick-markdown-image", versions: ["1.4.2511142126"] },
{ package: "@quick-start-soft/quick-markdown-print", versions: ["1.4.2511142126"] },
{ package: "@quick-start-soft/quick-markdown-translator", versions: ["1.4.2509202331"] },
{ package: "@quick-start-soft/quick-remove-image-background", versions: ["1.4.2511142126"] },
{ package: "@quick-start-soft/quick-task-refine", versions: ["1.4.2511142126"] },
{ package: "@relyt/claude-context-core", versions: ["0.1.1"] },
{ package: "@relyt/claude-context-mcp", versions: ["0.1.1"] },
{ package: "@relyt/mcp-server-relytone", versions: ["0.0.3"] },
{ package: "@sameepsi/sor", versions: ["1.0.3"] },
{ package: "@sameepsi/sor2", versions: ["2.0.2"] },
{ package: "@seezo/sdr-mcp-server", versions: ["0.0.5"] },
{ package: "@seung-ju/next", versions: ["0.0.2"] },
{ package: "@seung-ju/openapi-generator", versions: ["0.0.4"] },
{ package: "@seung-ju/react-hooks", versions: ["0.0.2"] },
{ package: "@seung-ju/react-native-action-sheet", versions: ["0.2.1"] },
{ package: "@silgi/better-auth", versions: ["0.8.1"] },
{ package: "@silgi/drizzle", versions: ["0.8.4"] },
{ package: "@silgi/ecosystem", versions: ["0.7.6"] },
{ package: "@silgi/graphql", versions: ["0.7.15"] },
{ package: "@silgi/module-builder", versions: ["0.8.8"] },
{ package: "@silgi/openapi", versions: ["0.7.4"] },
{ package: "@silgi/permission", versions: ["0.6.8"] },
{ package: "@silgi/ratelimit", versions: ["0.2.1"] },
{ package: "@silgi/scalar", versions: ["0.6.2"] },
{ package: "@silgi/yoga", versions: ["0.7.1"] },
{ package: "@sme-ui/aoma-vevasound-metadata-lib", versions: ["0.1.3"] },
{ package: "@strapbuild/react-native-date-time-picker", versions: ["2.0.4"] },
{ package: "@strapbuild/react-native-perspective-image-cropper", versions: ["0.4.15"] },
{ package: "@strapbuild/react-native-perspective-image-cropper-2", versions: ["0.4.7"] },
{ package: "@strapbuild/react-native-perspective-image-cropper-poojan31", versions: ["0.4.6"] },
{ package: "@suraj_h/medium-common", versions: ["1.0.5"] },
{ package: "@thedelta/eslint-config", versions: ["1.0.2"] },
{ package: "@tiaanduplessis/json", versions: ["2.0.2", "2.0.3"] },
{ package: "@tiaanduplessis/react-progressbar", versions: ["1.0.2", "1.0.1"] },
{ package: "@trackstar/angular-trackstar-link", versions: ["1.0.2"] },
{ package: "@trackstar/react-trackstar-link", versions: ["2.0.21"] },
{ package: "@trackstar/react-trackstar-link-upgrade", versions: ["1.1.10"] },
{ package: "@trackstar/test-angular-package", versions: ["0.0.9"] },
{ package: "@trackstar/test-package", versions: ["1.1.5"] },
{ package: "@trefox/sleekshop-js", versions: ["0.1.6"] },
{ package: "@trigo/atrix", versions: ["7.0.1"] },
{ package: "@trigo/atrix-acl", versions: ["4.0.2"] },
{ package: "@trigo/atrix-elasticsearch", versions: ["2.0.1"] },
{ package: "@trigo/atrix-mongoose", versions: ["1.0.2"] },
{ package: "@trigo/atrix-orientdb", versions: ["1.0.2"] },
{ package: "@trigo/atrix-postgres", versions: ["1.0.3"] },
{ package: "@trigo/atrix-pubsub", versions: ["4.0.3"] },
{ package: "@trigo/atrix-redis", versions: ["1.0.2"] },
{ package: "@trigo/atrix-soap", versions: ["1.0.2"] },
{ package: "@trigo/atrix-swagger", versions: ["3.0.1"] },
{ package: "@trigo/bool-expressions", versions: ["4.1.3"] },
{ package: "@trigo/eslint-config-trigo", versions: ["3.3.1"] },
{ package: "@trigo/fsm", versions: ["3.4.2"] },
{ package: "@trigo/hapi-auth-signedlink", versions: ["1.3.1"] },
{ package: "@trigo/jsdt", versions: ["0.2.1"] },
{ package: "@trigo/keycloak-api", versions: ["1.3.1"] },
{ package: "@trigo/node-soap", versions: ["0.5.4"] },
{ package: "@trigo/pathfinder-ui-css", versions: ["0.1.1"] },
{ package: "@trigo/trigo-hapijs", versions: ["5.0.1"] },
{ package: "@trpc-rate-limiter/cloudflare", versions: ["0.1.4"] },
{ package: "@trpc-rate-limiter/hono", versions: ["0.1.4"] },
{ package: "@varsityvibe/api-client", versions: ["1.3.36", "1.3.37"] },
{ package: "@varsityvibe/utils", versions: ["5.0.6"] },
{ package: "@varsityvibe/validation-schemas", versions: ["0.6.7", "0.6.8"] },
{ package: "@viapip/eslint-config", versions: ["0.2.4"] },
{ package: "@vishadtyagi/full-year-calendar", versions: ["0.1.11"] },
{ package: "@voiceflow/alexa-types", versions: ["2.15.60", "2.15.61"] },
{ package: "@voiceflow/anthropic", versions: ["0.4.4", "0.4.5"] },
{ package: "@voiceflow/api-sdk", versions: ["3.28.59", "3.28.58"] },
{ package: "@voiceflow/backend-utils", versions: ["5.0.1", "5.0.2"] },
{ package: "@voiceflow/base-types", versions: ["2.136.3", "2.136.2"] },
{ package: "@voiceflow/body-parser", versions: ["1.21.3", "1.21.2"] },
{ package: "@voiceflow/chat-types", versions: ["2.14.59", "2.14.58"] },
{ package: "@voiceflow/circleci-config-sdk-orb-import", versions: ["0.2.1", "0.2.2"] },
{ package: "@voiceflow/commitlint-config", versions: ["2.6.2", "2.6.1"] },
{ package: "@voiceflow/common", versions: ["8.9.1", "8.9.2"] },
{ package: "@voiceflow/default-prompt-wrappers", versions: ["1.7.4", "1.7.3"] },
{ package: "@voiceflow/dependency-cruiser-config", versions: ["1.8.11", "1.8.12"] },
{ package: "@voiceflow/dtos-interact", versions: ["1.40.2", "1.40.1"] },
{ package: "@voiceflow/encryption", versions: ["0.3.2", "0.3.3"] },
{ package: "@voiceflow/eslint-config", versions: ["7.16.4", "7.16.5"] },
{ package: "@voiceflow/eslint-plugin", versions: ["1.6.2", "1.6.1"] },
{ package: "@voiceflow/exception", versions: ["1.10.1", "1.10.2"] },
{ package: "@voiceflow/fetch", versions: ["1.11.1", "1.11.2"] },
{ package: "@voiceflow/general-types", versions: ["3.2.22", "3.2.23"] },
{ package: "@voiceflow/git-branch-check", versions: ["1.4.3", "1.4.4"] },
{ package: "@voiceflow/google-dfes-types", versions: ["2.17.12", "2.17.13"] },
{ package: "@voiceflow/google-types", versions: ["2.21.12", "2.21.13"] },
{ package: "@voiceflow/husky-config", versions: ["1.3.2", "1.3.1"] },
{ package: "@voiceflow/logger", versions: ["2.4.3", "2.4.2"] },
{ package: "@voiceflow/metrics", versions: ["1.5.2", "1.5.1"] },
{ package: "@voiceflow/natural-language-commander", versions: ["0.5.2", "0.5.3"] },
{ package: "@voiceflow/nestjs-common", versions: ["2.75.3", "2.75.2"] },
{ package: "@voiceflow/nestjs-mongodb", versions: ["1.3.2", "1.3.1"] },
{ package: "@voiceflow/nestjs-rate-limit", versions: ["1.3.2", "1.3.3"] },
{ package: "@voiceflow/nestjs-redis", versions: ["1.3.2", "1.3.1"] },
{ package: "@voiceflow/nestjs-timeout", versions: ["1.3.2", "1.3.1"] },
{ package: "@voiceflow/npm-package-json-lint-config", versions: ["1.1.2", "1.1.1"] },
{ package: "@voiceflow/openai", versions: ["3.2.3", "3.2.2"] },
{ package: "@voiceflow/pino", versions: ["6.11.4", "6.11.3"] },
{ package: "@voiceflow/pino-pretty", versions: ["4.4.1", "4.4.2"] },
{ package: "@voiceflow/prettier-config", versions: ["1.10.1", "1.10.2"] },
{ package: "@voiceflow/react-chat", versions: ["1.65.3", "1.65.4"] },
{ package: "@voiceflow/runtime", versions: ["1.29.2", "1.29.1"] },
{ package: "@voiceflow/runtime-client-js", versions: ["1.17.2", "1.17.3"] },
{ package: "@voiceflow/sdk-runtime", versions: ["1.43.2", "1.43.1"] },
{ package: "@voiceflow/secrets-provider", versions: ["1.9.2", "1.9.3"] },
{ package: "@voiceflow/semantic-release-config", versions: ["1.4.2", "1.4.1"] },
{ package: "@voiceflow/serverless-plugin-typescript", versions: ["2.1.8", "2.1.7"] },
{ package: "@voiceflow/slate-serializer", versions: ["1.7.4", "1.7.3"] },
{ package: "@voiceflow/stitches-react", versions: ["2.3.3", "2.3.2"] },
{ package: "@voiceflow/storybook-config", versions: ["1.2.3", "1.2.2"] },
{ package: "@voiceflow/stylelint-config", versions: ["1.1.2", "1.1.1"] },
{ package: "@voiceflow/test-common", versions: ["2.1.1", "2.1.2"] },
{ package: "@voiceflow/tsconfig", versions: ["1.12.1", "1.12.2"] },
{ package: "@voiceflow/tsconfig-paths", versions: ["1.1.5", "1.1.4"] },
{ package: "@voiceflow/utils-designer", versions: ["1.74.20", "1.74.19"] },
{ package: "@voiceflow/verror", versions: ["1.1.5", "1.1.4"] },
{ package: "@voiceflow/vite-config", versions: ["2.6.2", "2.6.3"] },
{ package: "@voiceflow/vitest-config", versions: ["1.10.3", "1.10.2"] },
{ package: "@voiceflow/voice-types", versions: ["2.10.58", "2.10.59"] },
{ package: "@voiceflow/voiceflow-types", versions: ["3.32.45", "3.32.46"] },
{ package: "@voiceflow/widget", versions: ["1.7.18", "1.7.19"] },
{ package: "@vucod/email", versions: ["0.0.3"] },
{ package: "@zapier/ai-actions", versions: ["0.1.18", "0.1.19", "0.1.20"] },
{ package: "@zapier/ai-actions-react", versions: ["0.1.13", "0.1.12", "0.1.14"] },
{ package: "@zapier/babel-preset-zapier", versions: ["6.4.2", "6.4.1", "6.4.3"] },
{ package: "@zapier/browserslist-config-zapier", versions: ["1.0.4", "1.0.5", "1.0.3"] },
{ package: "@zapier/eslint-plugin-zapier", versions: ["11.0.5", "11.0.3", "11.0.4"] },
{ package: "@zapier/mcp-integration", versions: ["3.0.3", "3.0.1", "3.0.2"] },
{ package: "@zapier/secret-scrubber", versions: ["1.1.5", "1.1.3", "1.1.4"] },
{ package: "@zapier/spectral-api-ruleset", versions: ["1.9.3", "1.9.2", "1.9.1"] },
{ package: "@zapier/stubtree", versions: ["0.1.4", "0.1.3", "0.1.2"] },
{ package: "@zapier/zapier-sdk", versions: ["0.15.7", "0.15.6", "0.15.5"] },
{ package: "ai-crowl-shield", versions: ["1.0.7"] },
{ package: "arc-cli-fc", versions: ["1.0.1"] },
{ package: "asciitranslator", versions: ["1.0.3"] },
{ package: "asyncapi-preview", versions: ["1.0.2", "1.0.1"] },
{ package: "atrix", versions: ["1.0.1"] },
{ package: "atrix-mongoose", versions: ["1.0.1"] },
{ package: "automation_model", versions: ["1.0.491"] },
{ package: "avvvatars-vue", versions: ["1.1.2"] },
{ package: "axios-builder", versions: ["1.2.1"] },
{ package: "axios-cancelable", versions: ["1.0.2", "1.0.1"] },
{ package: "axios-timed", versions: ["1.0.2", "1.0.1"] },
{ package: "babel-preset-kinvey-flex-service", versions: ["0.1.1"] },
{ package: "barebones-css", versions: ["1.1.3", "1.1.4"] },
{ package: "benmostyn-frame-print", versions: ["1.0.1"] },
{ package: "best_gpio_controller", versions: ["1.0.10"] },
{ package: "better-auth-nuxt", versions: ["0.0.10"] },
{ package: "better-queue-nedb", versions: ["0.1.5"] },
{ package: "bidirectional-adapter", versions: ["1.2.3", "1.2.2", "1.2.5", "1.2.4"] },
{ package: "blinqio-executions-cli", versions: ["1.0.41"] },
{ package: "blob-to-base64", versions: ["1.0.3"] },
{ package: "bool-expressions", versions: ["0.1.2"] },
{ package: "buffered-interpolation-babylon6", versions: ["0.2.8"] },
{ package: "bun-plugin-httpfile", versions: ["0.1.1"] },
{ package: "bytecode-checker-cli", versions: ["1.0.10", "1.0.9", "1.0.8", "1.0.11"] },
{ package: "bytes-to-x", versions: ["1.0.1"] },
{ package: "calc-loan-interest", versions: ["1.0.4"] },
{ package: "capacitor-plugin-apptrackingios", versions: ["0.0.21"] },
{ package: "capacitor-plugin-purchase", versions: ["0.1.1"] },
{ package: "capacitor-plugin-scgssigninwithgoogle", versions: ["0.0.5"] },
{ package: "capacitor-purchase-history", versions: ["0.0.10"] },
{ package: "capacitor-voice-recorder-wav", versions: ["6.0.3"] },
{ package: "ceviz", versions: ["0.0.5"] },
{ package: "chrome-extension-downloads", versions: ["0.0.3", "0.0.4"] },
{ package: "claude-token-updater", versions: ["1.0.3"] },
{ package: "coinmarketcap-api", versions: ["3.1.3", "3.1.2"] },
{ package: "colors-regex", versions: ["2.0.1"] },
{ package: "command-irail", versions: ["0.5.4"] },
{ package: "compare-obj", versions: ["1.1.2", "1.1.1"] },
{ package: "composite-reducer", versions: ["1.0.4", "1.0.5", "1.0.2", "1.0.3"] },
{ package: "count-it-down", versions: ["1.0.2", "1.0.1"] },
{ package: "cpu-instructions", versions: ["0.0.14"] },
{ package: "create-director-app", versions: ["0.1.1"] },
{ package: "create-glee-app", versions: ["0.2.3", "0.2.2"] },
{ package: "create-hardhat3-app", versions: ["1.1.2", "1.1.3", "1.1.1", "1.1.4"] },
{ package: "create-kinvey-flex-service", versions: ["0.2.1"] },
{ package: "create-mcp-use-app", versions: ["0.5.4", "0.5.3"] },
{ package: "create-silgi", versions: ["0.3.1"] },
{ package: "crypto-addr-codec", versions: ["0.1.9"] },
{ package: "css-dedoupe", versions: ["0.1.2"] },
{ package: "csv-tool-cli", versions: ["1.2.1"] },
{ package: "dashboard-empty-state", versions: ["1.0.3"] },
{ package: "designstudiouiux", versions: ["1.0.1"] },
{ package: "devstart-cli", versions: ["1.0.6"] },
{ package: "dialogflow-es", versions: ["1.1.2", "1.1.3", "1.1.1", "1.1.4"] },
{ package: "discord-bot-server", versions: ["0.1.2"] },
{ package: "docusaurus-plugin-vanilla-extract", versions: ["1.0.3"] },
{ package: "dont-go", versions: ["1.1.2"] },
{ package: "dotnet-template", versions: ["0.0.3", "0.0.4"] },
{ package: "drop-events-on-property-plugin", versions: ["0.0.2"] },
{ package: "easypanel-sdk", versions: ["0.3.2"] },
{ package: "electron-volt", versions: ["0.0.2"] },
{ package: "email-deliverability-tester", versions: ["1.1.1"] },
{ package: "enforce-branch-name", versions: ["1.1.3"] },
{ package: "esbuild-plugin-brotli", versions: ["0.2.1"] },
{ package: "esbuild-plugin-eta", versions: ["0.1.1"] },
{ package: "esbuild-plugin-httpfile", versions: ["0.4.1"] },
{ package: "eslint-config-kinvey-flex-service", versions: ["0.1.1"] },
{ package: "eslint-config-nitpicky", versions: ["4.0.1"] },
{ package: "eslint-config-trigo", versions: ["22.0.2"] },
{ package: "eslint-config-zeallat-base", versions: ["1.0.4"] },
{ package: "ethereum-ens", versions: ["0.8.1"] },
{ package: "evm-checkcode-cli", versions: ["1.0.14", "1.0.12", "1.0.15", "1.0.13"] },
{ package: "exact-ticker", versions: ["0.3.5"] },
{ package: "expo-audio-session", versions: ["0.2.1"] },
{ package: "expo-router-on-rails", versions: ["0.0.4"] },
{ package: "express-starter-template", versions: ["1.0.10"] },
{ package: "expressos", versions: ["1.1.3"] },
{ package: "fat-fingered", versions: ["1.0.2", "1.0.1"] },
{ package: "feature-flip", versions: ["1.0.2", "1.0.1"] },
{ package: "firestore-search-engine", versions: ["1.2.3"] },
{ package: "fittxt", versions: ["1.0.3", "1.0.2"] },
{ package: "flapstacks", versions: ["1.0.2", "1.0.1"] },
{ package: "flatten-unflatten", versions: ["1.0.2", "1.0.1"] },
{ package: "formik-error-focus", versions: ["2.0.1"] },
{ package: "formik-store", versions: ["1.0.1"] },
{ package: "frontity-starter-theme", versions: ["1.0.1"] },
{ package: "fuzzy-finder", versions: ["1.0.6", "1.0.5"] },
{ package: "gate-evm-check-code2", versions: ["2.0.6", "2.0.5", "2.0.4", "2.0.3"] },
{ package: "gate-evm-tools-test", versions: ["1.0.6", "1.0.5", "1.0.8", "1.0.7"] },
{ package: "gatsby-plugin-antd", versions: ["2.2.1"] },
{ package: "gatsby-plugin-cname", versions: ["1.0.2", "1.0.1"] },
{ package: "generator-meteor-stock", versions: ["0.1.6"] },
{ package: "generator-ng-itobuz", versions: ["0.0.15"] },
{ package: "get-them-args", versions: ["1.3.3"] },
{ package: "github-action-for-generator", versions: ["2.1.27", "2.1.28"] },
{ package: "gitsafe", versions: ["1.0.5"] },
{ package: "go-template", versions: ["0.1.9", "0.1.8"] },
{ package: "gulp-inject-envs", versions: ["1.2.2", "1.2.1"] },
{ package: "haufe-axera-api-client", versions: ["0.0.1", "0.0.2"] },
{ package: "hope-mapboxdraw", versions: ["0.1.1"] },
{ package: "hopedraw", versions: ["1.0.3"] },
{ package: "hover-design-prototype", versions: ["0.0.5"] },
{ package: "httpness", versions: ["1.0.3", "1.0.2"] },
{ package: "hyper-fullfacing", versions: ["1.0.3"] },
{ package: "hyperterm-hipster", versions: ["1.0.7"] },
{ package: "ids-css", versions: ["1.5.1"] },
{ package: "ids-enterprise-mcp-server", versions: ["0.0.2"] },
{ package: "ids-enterprise-ng", versions: ["20.1.6"] },
{ package: "ids-enterprise-typings", versions: ["20.1.6"] },
{ package: "image-to-uri", versions: ["1.0.2", "1.0.1"] },
{ package: "insomnia-plugin-random-pick", versions: ["1.0.4"] },
{ package: "invo", versions: ["0.2.2"] },
{ package: "iron-shield-miniapp", versions: ["0.0.2"] },
{ package: "ito-button", versions: ["8.0.3"] },
{ package: "itobuz-angular", versions: ["0.0.1"] },
{ package: "itobuz-angular-auth", versions: ["8.0.11"] },
{ package: "itobuz-angular-button", versions: ["8.0.11"] },
{ package: "jacob-zuma", versions: ["1.0.2", "1.0.1"] },
{ package: "jaetut-varit-test", versions: ["1.0.2"] },
{ package: "jan-browser", versions: ["0.13.1"] },
{ package: "jquery-bindings", versions: ["1.1.2", "1.1.3"] },
{ package: "jsonsurge", versions: ["1.0.7"] },
{ package: "just-toasty", versions: ["1.7.1"] },
{ package: "kill-port", versions: ["2.0.2", "2.0.3"] },
{ package: "kinetix-default-token-list", versions: ["1.0.5"] },
{ package: "kinvey-cli-wrapper", versions: ["0.3.1"] },
{ package: "kinvey-flex-scripts", versions: ["0.5.1"] },
{ package: "kns-error-code", versions: ["1.0.8"] },
{ package: "korea-administrative-area-geo-json-util", versions: ["1.0.7"] },
{ package: "kwami", versions: ["1.5.9", "1.5.10"] },
{ package: "lang-codes", versions: ["1.0.2", "1.0.1"] },
{ package: "license-o-matic", versions: ["1.2.2", "1.2.1"] },
{ package: "lint-staged-imagemin", versions: ["1.3.2", "1.3.1"] },
{ package: "lite-serper-mcp-server", versions: ["0.2.2"] },
{ package: "lui-vue-test", versions: ["0.70.9"] },
{ package: "luno-api", versions: ["1.2.3"] },
{ package: "m25-transaction-utils", versions: ["1.1.16"] },
{ package: "manual-billing-system-miniapp-api", versions: ["1.3.1"] },
{ package: "mcp-use", versions: ["1.4.2", "1.4.3"] },
{ package: "medusa-plugin-announcement", versions: ["0.0.3"] },
{ package: "medusa-plugin-logs", versions: ["0.0.17"] },
{ package: "medusa-plugin-momo", versions: ["0.0.68"] },
{ package: "medusa-plugin-product-reviews-kvy", versions: ["0.0.4"] },
{ package: "medusa-plugin-zalopay", versions: ["0.0.40"] },
{ package: "mod10-check-digit", versions: ["1.0.1"] },
{ package: "mon-package-react-typescript", versions: ["1.0.1"] },
{ package: "my-saeed-lib", versions: ["0.1.1"] },
{ package: "n8n-nodes-tmdb", versions: ["0.5.1"] },
{ package: "n8n-nodes-vercel-ai-sdk", versions: ["0.1.7"] },
{ package: "n8n-nodes-viral-app", versions: ["0.2.5"] },
{ package: "nanoreset", versions: ["7.0.2", "7.0.1"] },
{ package: "next-circular-dependency", versions: ["1.0.3", "1.0.2"] },
{ package: "next-simple-google-analytics", versions: ["1.1.2", "1.1.1"] },
{ package: "next-styled-nprogress", versions: ["1.0.4", "1.0.5"] },
{ package: "ngx-useful-swiper-prosenjit", versions: ["9.0.2"] },
{ package: "ngx-wooapi", versions: ["12.0.1"] },
{ package: "nitro-graphql", versions: ["1.5.12"] },
{ package: "nitro-kutu", versions: ["0.1.1"] },
{ package: "nitrodeploy", versions: ["1.0.8"] },
{ package: "nitroping", versions: ["0.1.1"] },
{ package: "normal-store", versions: ["1.3.2", "1.3.4", "1.3.1", "1.3.3"] },
{ package: "nuxt-keycloak", versions: ["0.2.2"] },
{ package: "obj-to-css", versions: ["1.0.3", "1.0.2"] },
{ package: "okta-react-router-6", versions: ["5.0.1"] },
{ package: "open2internet", versions: ["0.1.1"] },
{ package: "orbit-boxicons", versions: ["2.1.3"] },
{ package: "orbit-nebula-draw-tools", versions: ["1.0.10"] },
{ package: "orbit-nebula-editor", versions: ["1.0.2"] },
{ package: "orbit-soap", versions: ["0.43.13"] },
{ package: "orchestrix", versions: ["12.1.2"] },
{ package: "package-tester", versions: ["1.0.1"] },
{ package: "parcel-plugin-asset-copier", versions: ["1.1.2", "1.1.3"] },
{ package: "pdf-annotation", versions: ["0.0.2"] },
{ package: "pergel", versions: ["0.13.2"] },
{ package: "pergeltest", versions: ["0.0.25"] },
{ package: "piclite", versions: ["1.0.1"] },
{ package: "pico-uid", versions: ["1.0.4", "1.0.3"] },
{ package: "pkg-readme", versions: ["1.1.1"] },
{ package: "poper-react-sdk", versions: ["0.1.2"] },
{ package: "posthog-docusaurus", versions: ["2.0.6"] },
{ package: "posthog-js", versions: ["1.297.3"] },
{ package: "posthog-node", versions: ["5.13.3", "5.11.3", "4.18.1"] },
{ package: "posthog-plugin-hello-world", versions: ["1.0.1"] },
{ package: "posthog-react-native", versions: ["4.11.1", "4.12.5"] },
{ package: "posthog-react-native-session-replay", versions: ["1.2.2"] },
{ package: "prime-one-table", versions: ["0.0.19"] },
{ package: "prompt-eng", versions: ["1.0.50"] },
{ package: "prompt-eng-server", versions: ["1.0.18"] },
{ package: "puny-req", versions: ["1.0.3"] },
{ package: "quickswap-ads-list", versions: ["1.0.33"] },
{ package: "quickswap-default-staking-list", versions: ["1.0.11"] },
{ package: "quickswap-default-staking-list-address", versions: ["1.0.55"] },
{ package: "quickswap-default-token-list", versions: ["1.5.16"] },
{ package: "quickswap-router-sdk", versions: ["1.0.1"] },
{ package: "quickswap-sdk", versions: ["3.0.44"] },
{ package: "quickswap-smart-order-router", versions: ["1.0.1"] },
{ package: "quickswap-token-lists", versions: ["1.0.3"] },
{ package: "quickswap-v2-sdk", versions: ["2.0.1"] },
{ package: "ra-auth-firebase", versions: ["1.0.3"] },
{ package: "ra-data-firebase", versions: ["1.0.8", "1.0.7"] },
{ package: "react-component-taggers", versions: ["0.1.9"] },
{ package: "react-data-to-export", versions: ["1.0.1"] },
{ package: "react-element-prompt-inspector", versions: ["0.1.18"] },
{ package: "react-favic", versions: ["1.0.2"] },
{ package: "react-hook-form-persist", versions: ["3.0.1", "3.0.2"] },
{ package: "react-jam-icons", versions: ["1.0.2", "1.0.1"] },
{ package: "react-keycloak-context", versions: ["1.0.9", "1.0.8"] },
{ package: "react-library-setup", versions: ["0.0.6"] },
{ package: "react-linear-loader", versions: ["1.0.2"] },
{ package: "react-micromodal.js", versions: ["1.0.2", "1.0.1"] },
{ package: "react-native-datepicker-modal", versions: ["1.3.2", "1.3.1"] },
{ package: "react-native-email", versions: ["2.1.1", "2.1.2"] },
{ package: "react-native-fetch", versions: ["2.0.2", "2.0.1"] },
{ package: "react-native-get-pixel-dimensions", versions: ["1.0.2", "1.0.1"] },
{ package: "react-native-google-maps-directions", versions: ["2.1.2"] },
{ package: "react-native-jam-icons", versions: ["1.0.2", "1.0.1"] },
{ package: "react-native-log-level", versions: ["1.2.2", "1.2.1"] },
{ package: "react-native-modest-checkbox", versions: ["3.3.1"] },
{ package: "react-native-modest-storage", versions: ["2.1.1"] },
{ package: "react-native-phone-call", versions: ["1.2.2", "1.2.1"] },
{ package: "react-native-retriable-fetch", versions: ["2.0.2", "2.0.1"] },
{ package: "react-native-use-modal", versions: ["1.0.3"] },
{ package: "react-native-view-finder", versions: ["1.2.2", "1.2.1"] },
{ package: "react-native-websocket", versions: ["1.0.4", "1.0.3"] },
{ package: "react-native-worklet-functions", versions: ["3.3.3"] },
{ package: "react-packery-component", versions: ["1.0.3"] },
{ package: "react-qr-image", versions: ["1.1.1"] },
{ package: "react-scrambled-text", versions: ["1.0.4"] },
{ package: "rediff", versions: ["1.0.5"] },
{ package: "rediff-viewer", versions: ["0.0.7"] },
{ package: "redux-forge", versions: ["2.5.3"] },
{ package: "redux-router-kit", versions: ["1.2.3", "1.2.2", "1.2.4"] },
{ package: "revenuecat", versions: ["1.0.1"] },
{ package: "rollup-plugin-httpfile", versions: ["0.2.1"] },
{ package: "sa-company-registration-number-regex", versions: ["1.0.2", "1.0.1"] },
{ package: "sa-id-gen", versions: ["1.0.4", "1.0.5"] },
{ package: "samesame", versions: ["1.0.3"] },
{ package: "scgs-capacitor-subscribe", versions: ["1.0.11"] },
{ package: "scgsffcreator", versions: ["1.0.5"] },
{ package: "schob", versions: ["1.0.3"] },
{ package: "selenium-session", versions: ["1.0.5"] },
{ package: "selenium-session-client", versions: ["1.0.4"] },
{ package: "set-nested-prop", versions: ["2.0.2", "2.0.1"] },
{ package: "shelf-jwt-sessions", versions: ["0.1.2"] },
{ package: "shell-exec", versions: ["1.1.3", "1.1.4"] },
{ package: "shinhan-limit-scrap", versions: ["1.0.3"] },
{ package: "silgi", versions: ["0.43.30"] },
{ package: "simplejsonform", versions: ["1.0.1"] },
{ package: "skills-use", versions: ["0.1.1", "0.1.2"] },
{ package: "solomon-api-stories", versions: ["1.0.2"] },
{ package: "solomon-v3-stories", versions: ["1.15.6"] },
{ package: "solomon-v3-ui-wrapper", versions: ["1.6.1"] },
{ package: "soneium-acs", versions: ["1.0.1"] },
{ package: "sort-by-distance", versions: ["2.0.1"] },
{ package: "south-african-id-info", versions: ["1.0.2"] },
{ package: "stat-fns", versions: ["1.0.1"] },
{ package: "stoor", versions: ["2.3.2"] },
{ package: "sufetch", versions: ["0.4.1"] },
{ package: "super-commit", versions: ["1.0.1"] },
{ package: "svelte-autocomplete-select", versions: ["1.1.1"] },
{ package: "svelte-toasty", versions: ["1.1.2", "1.1.3"] },
{ package: "tanstack-shadcn-table", versions: ["1.1.5"] },
{ package: "tavily-module", versions: ["1.0.1"] },
{ package: "tcsp", versions: ["2.0.2"] },
{ package: "tcsp-draw-test", versions: ["1.0.5"] },
{ package: "tcsp-test-vd", versions: ["2.4.4"] },
{ package: "template-lib", versions: ["1.1.3", "1.1.4"] },
{ package: "template-micro-service", versions: ["1.0.3", "1.0.2"] },
{ package: "tenacious-fetch", versions: ["2.3.3", "2.3.2"] },
{ package: "test-foundry-app", versions: ["1.0.4", "1.0.3", "1.0.2", "1.0.1"] },
{ package: "test-hardhat-app", versions: ["1.0.4", "1.0.3", "1.0.2", "1.0.1"] },
{ package: "test23112222-api", versions: ["1.0.1"] },
{ package: "tiaan", versions: ["1.0.2"] },
{ package: "tiptap-shadcn-vue", versions: ["0.2.1"] },
{ package: "token.js-fork", versions: ["0.7.32"] },
{ package: "toonfetch", versions: ["0.3.2"] },
{ package: "trigo-react-app", versions: ["4.1.2"] },
{ package: "ts-relay-cursor-paging", versions: ["2.1.1"] },
{ package: "typeface-antonio-complete", versions: ["1.0.5"] },
{ package: "typefence", versions: ["1.2.3", "1.2.2"] },
{ package: "typeorm-orbit", versions: ["0.2.27"] },
{ package: "unadapter", versions: ["0.1.3"] },
{ package: "undefsafe-typed", versions: ["1.0.4", "1.0.3"] },
{ package: "unemail", versions: ["0.3.1"] },
{ package: "uniswap-router-sdk", versions: ["1.6.2"] },
{ package: "uniswap-smart-order-router", versions: ["3.16.26"] },
{ package: "uniswap-test-sdk-core", versions: ["4.0.8"] },
{ package: "unsearch", versions: ["0.0.3"] },
{ package: "uplandui", versions: ["0.5.4"] },
{ package: "upload-to-play-store", versions: ["1.0.2", "1.0.1"] },
{ package: "url-encode-decode", versions: ["1.0.2", "1.0.1"] },
{ package: "use-unsaved-changes", versions: ["1.0.9"] },
{ package: "v-plausible", versions: ["1.2.1"] },
{ package: "valid-south-african-id", versions: ["1.0.3"] },
{ package: "valuedex-sdk", versions: ["3.0.5"] },
{ package: "vf-oss-template", versions: ["1.0.4", "1.0.3", "1.0.2", "1.0.1"] },
{ package: "victoria-wallet-constants", versions: ["0.1.1", "0.1.2"] },
{ package: "victoria-wallet-core", versions: ["0.1.1", "0.1.2"] },
{ package: "victoria-wallet-type", versions: ["0.1.1", "0.1.2"] },
{ package: "victoria-wallet-utils", versions: ["0.1.1", "0.1.2"] },
{ package: "victoria-wallet-validator", versions: ["0.1.1", "0.1.2"] },
{ package: "victoriaxoaquyet-wallet-core", versions: ["0.2.1", "0.2.2"] },
{ package: "vite-plugin-httpfile", versions: ["0.2.1"] },
{ package: "vue-browserupdate-nuxt", versions: ["1.0.5"] },
{ package: "wallet-evm", versions: ["0.3.2", "0.3.1"] },
{ package: "wallet-type", versions: ["0.1.1", "0.1.2"] },
{ package: "web-scraper-mcp", versions: ["1.1.4"] },
{ package: "web-types-htmx", versions: ["0.1.1"] },
{ package: "web-types-lit", versions: ["0.1.1"] },
{ package: "webpack-loader-httpfile", versions: ["0.2.1"] },
{ package: "wellness-expert-ng-gallery", versions: ["5.1.1"] },
{ package: "wenk", versions: ["1.0.10", "1.0.9"] },
{ package: "zapier-async-storage", versions: ["1.0.3", "1.0.2", "1.0.1"] },
{ package: "zapier-platform-cli", versions: ["18.0.4", "18.0.3", "18.0.2"] },
{ package: "zapier-platform-core", versions: ["18.0.4", "18.0.3", "18.0.2"] },
{ package: "zapier-platform-legacy-scripting-runner", versions: ["4.0.3", "4.0.2", "4.0.4"] },
{ package: "zapier-platform-schema", versions: ["18.0.4", "18.0.3", "18.0.2"] },
{ package: "zapier-scripts", versions: ["7.8.4", "7.8.3"] },
{ package: "zuper-cli", versions: ["1.0.1"] },
{ package: "zuper-sdk", versions: ["1.0.57"] },
{ package: "zuper-stream", versions: ["2.0.9"] }
];
// Colored console output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m', // 修正: 追加しました
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m'
};
const log = {
error: (msg) => console.log(`${colors.red}❌ ${msg}${colors.reset}`),
success: (msg) => console.log(`${colors.green}✅ ${msg}${colors.reset}`),
warning: (msg) => console.log(`${colors.yellow}⚠️ ${msg}${colors.reset}`),
info: (msg) => console.log(`${colors.blue}ℹ️ ${msg}${colors.reset}`),
danger: (msg) => console.log(`${colors.red}🚨 ${msg}${colors.reset}`),
header: (msg) => console.log(`${colors.cyan}${colors.bright}=== ${msg} ===${colors.reset}`)
};
// ==========================================
// 2. Analysis Logic
// ==========================================
// Package compromise check function
function isCompromised(packageName, version) {
const found = shaiHuludCompromisedPackages.find(p => p.package === packageName);
if (!found) return false;
if (!version) {
return {
compromised: true,
isCompromisedVersion: false,
compromisedVersions: found.versions
};
}
const cleanVersion = version.replace(/^[\^~]/, '');
const isCompromisedVersion = found.versions.includes(cleanVersion);
return {
compromised: true,
isCompromisedVersion,
compromisedVersions: found.versions,
currentVersion: cleanVersion
};
}
// ------------------------------------------
// Yarn v1 Parser (Line-by-Line)
// ------------------------------------------
function analyzeYarnLockV1(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split('\n');
const compromised = [];
let scanCount = 0;
let currentPackages = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.startsWith('#') || line.trim() === '') continue;
if (!line.startsWith(' ')) {
const definitionLine = line.trim().replace(/:$/, '');
const definitions = definitionLine.split(',').map(s => s.trim().replace(/^"|"$/g, ''));
currentPackages = definitions.map(def => {
const lastAt = def.lastIndexOf('@');
if (lastAt > 0) return def.substring(0, lastAt);
return def;
});
}
else if (line.trim().startsWith('version')) {
const versionMatch = line.match(/version\s+"([^"]+)"/);
if (versionMatch && currentPackages.length > 0) {
const version = versionMatch[1];
scanCount += currentPackages.length;
const uniqueNames = [...new Set(currentPackages)];
for (const pkgName of uniqueNames) {
const result = isCompromised(pkgName, version);
if (result.compromised) {
compromised.push({ package: pkgName, version, result, source: 'yarn.lock' });
}
}
}
}
}
return { compromised, scanCount };
} catch (error) {
throw new Error(`Failed to parse ${filePath}: ${error.message}`);
}
}
// ------------------------------------------
// pnpm-lock.yaml Parser (Regex Line-by-Line)
// Supports: pnpm v5, v6, v9 formats
// ------------------------------------------
function analyzePnpmLock(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split('\n');
const compromised = [];
let scanCount = 0;
for (const line of lines) {
const cleanLine = line.trim().replace(/^['"]|['"]:?$/g, '');
if (!cleanLine.includes('@') && !cleanLine.includes('/')) continue;
const noSlash = cleanLine.startsWith('/') ? cleanLine.slice(1) : cleanLine;
const match = noSlash.match(/^((?:@[^@\/]+\/)?[^@\/]+)(?:@|\/)(.+)$/);
if (match) {
const packageName = match[1];
const rawVersion = match[2];
const version = rawVersion.split('_')[0].split('(')[0];
if (!version || !packageName) continue;
scanCount++;
const result = isCompromised(packageName, version);
if (result.compromised) {
const alreadyReported = compromised.some(c => c.package === packageName && c.version === version);
if (!alreadyReported) {
compromised.push({ package: packageName, version, result, source: 'pnpm-lock.yaml' });
}
}
}
}
return { compromised, scanCount };
} catch (e) {
throw new Error(`Failed to parse pnpm-lock.yaml: ${e.message}`);
}
}
// ------------------------------------------
// package-lock.json Parser (Standard JSON)
// ------------------------------------------
function analyzePackageLock(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const lockData = JSON.parse(content);
const compromised = [];
let scanCount = 0;
const packages = lockData.packages || {};
const dependencies = lockData.dependencies || {};
for (const [pkgPath, pkgData] of Object.entries(packages)) {
if (pkgPath === "") continue;
scanCount++;
const packageName = pkgPath.replace(/^.*node_modules\//, '');
const result = isCompromised(packageName, pkgData.version);
if (result.compromised) {
compromised.push({ package: packageName, version: pkgData.version, result, source: 'package-lock.json' });
}
}
if (scanCount === 0) {
function checkDeps(deps) {
for (const [name, data] of Object.entries(deps)) {
scanCount++;
const result = isCompromised(name, data.version);
if (result.compromised) {
compromised.push({ package: name, version: data.version, result, source: 'package-lock.json' });
}
if (data.dependencies) checkDeps(data.dependencies);
}
}
checkDeps(dependencies);
}
return { compromised, scanCount };
} catch (e) {
throw new Error(`Failed to parse package-lock.json: ${e.message}`);
}
}
// ==========================================
// 3. Project Checking Logic
// ==========================================
function checkProject(projectPath, projectName) {
const pnpmLockPath = path.join(projectPath, 'pnpm-lock.yaml');
const yarnLockPath = path.join(projectPath, 'yarn.lock');
const packageLockPath = path.join(projectPath, 'package-lock.json');
const packageJsonPath = path.join(projectPath, 'package.json');
if (!fs.existsSync(packageJsonPath)) {
log.info('No package.json found - skipping');
return null;
}
let hasLockFile = false;
let compromised = [];
let scannedCount = 0;
let lockFileType = '';
// Priority 1: pnpm-lock.yaml
if (fs.existsSync(pnpmLockPath)) {
hasLockFile = true;
lockFileType = 'pnpm-lock.yaml';
try {
const result = analyzePnpmLock(pnpmLockPath);
compromised = result.compromised;
scannedCount = result.scanCount;
} catch (e) {
log.error(e.message);
hasLockFile = false;
}
}
// Priority 2: yarn.lock
else if (fs.existsSync(yarnLockPath)) {
hasLockFile = true;
lockFileType = 'yarn.lock';
try {
const result = analyzeYarnLockV1(yarnLockPath);
compromised = result.compromised;
scannedCount = result.scanCount;
} catch (e) {
log.error(e.message);
hasLockFile = false;
}
}
// Priority 3: package-lock.json
else if (fs.existsSync(packageLockPath)) {
hasLockFile = true;
lockFileType = 'package-lock.json';
try {
const result = analyzePackageLock(packageLockPath);
compromised = result.compromised;
scannedCount = result.scanCount;
} catch (e) {
log.error(e.message);
hasLockFile = false;
}
}
if (hasLockFile && scannedCount > 0) {
log.info(`Analyzed ${lockFileType} (Scanned ${scannedCount} packages)`);
} else if (hasLockFile) {
log.warning(`Analyzed ${lockFileType} but found 0 packages.`);
}
// Fallback: package.json (Name match only)
if (!hasLockFile) {
try {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const allDeps = {
...packageJson.dependencies,
...packageJson.devDependencies,
...packageJson.peerDependencies
};
for (const [pkgName, version] of Object.entries(allDeps)) {
const found = shaiHuludCompromisedPackages.find(p => p.package === pkgName);
if (found) {
compromised.push({
package: pkgName,
version: version,
result: { compromised: true, isCompromisedVersion: false, compromisedVersions: found.versions },
source: 'package.json'
});
}
}
log.warning('No lock file found - checked package names in package.json only');
} catch (error) {
log.error(`Error analyzing package.json: ${error.message}`);
}
}
if (compromised.length > 0) {
log.danger(`Found ${compromised.length} compromised packages!`);
for (const pkg of compromised) {
let status;
if (pkg.source === 'package.json') {
status = `${colors.yellow}Potential Risk (Lockfile missing)${colors.reset}`;
} else if (pkg.result.isCompromisedVersion) {
status = `${colors.red}INFECTED VERSION${colors.reset}`;
} else {
status = `${colors.yellow}Clean version (Package name matches)${colors.reset}`;
}
console.log(` ${colors.red}🦠 ${pkg.package}@${pkg.version}${colors.reset} - ${status}`);
}
return { project: projectName, packages: compromised };
} else {
log.success('No compromised packages found');
return { project: projectName, packages: [] };
}
}
// ==========================================
// 4. Directory Scanning
// ==========================================
function scanDirectory(targetPath) {
const absolutePath = path.resolve(targetPath);
if (!fs.existsSync(absolutePath)) {
log.error(`Path does not exist: ${absolutePath}`);
return;
}
if (!fs.statSync(absolutePath).isDirectory()) {
log.error(`Path is not a directory: ${absolutePath}`);
return;
}
log.header(`Scanning directory: ${absolutePath}`);
let totalCompromised = 0;
let totalProjects = 0;
const compromisedProjects = [];
console.log(`\n${colors.bright}🏠 Checking Root Directory (Monorepo Root)${colors.reset}`);
const rootCheckResult = checkProject(absolutePath, 'ROOT');
if (rootCheckResult) {
totalProjects++;
if (rootCheckResult.packages.length > 0) {
compromisedProjects.push(rootCheckResult);
totalCompromised += rootCheckResult.packages.length;
}
}
let subdirectories = [];
try {
subdirectories = fs.readdirSync(absolutePath)
.filter(item => {
const itemPath = path.join(absolutePath, item);
return fs.statSync(itemPath).isDirectory() && !item.startsWith('.') && item !== 'node_modules';
});
} catch (e) {
log.error(`Failed to read subdirectories: ${e.message}`);
}
if (subdirectories.length > 0) {
log.info(`Found ${subdirectories.length} subdirectories/packages`);
for (const subdir of subdirectories) {
const projectPath = path.join(absolutePath, subdir);
console.log(`\n${colors.bright}📁 Checking submodule: ${subdir}${colors.reset}`);
const result = checkProject(projectPath, subdir);
if (result) {
totalProjects++;
if (result.packages.length > 0) {
compromisedProjects.push(result);
totalCompromised += result.packages.length;
}
}
}
} else {
log.warning('No subdirectories found');
}
console.log(`\n${colors.cyan}${colors.bright}=== FINAL SUMMARY ===${colors.reset}`);
console.log(`Total locations scanned: ${totalProjects}`);
console.log(`Projects with compromised packages: ${compromisedProjects.length}`);
console.log(`Total compromised package instances: ${totalCompromised}`);
if (compromisedProjects.length > 0) {
console.log(`\n${colors.red}${colors.bright}🚨 PROJECTS REQUIRING IMMEDIATE ATTENTION:${colors.reset}`);
for (const project of compromisedProjects) {
console.log(`${colors.red}• ${project.project}${colors.reset} (${project.packages.length} packages)`);
}
console.log(`\n${colors.yellow}${colors.bright}RECOMMENDED ACTIONS:${colors.reset}`);
console.log('1. Update all compromised packages to safe versions');
console.log('2. Rotate all authentication credentials (GitHub, npm, cloud)');
console.log('3. Check for unauthorized repositories or workflows');
console.log('4. Scan for malicious files in node_modules');
} else {
log.success('All scanned projects appear to be clean!');
}
}
// ==========================================
// 5. Main Execution
// ==========================================
function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
console.log(`${colors.cyan}Shai-Hulud Vulnerability Scanner (pnpm/Yarn/npm)${colors.reset}`);
console.log('\nUsage:');
console.log(' node shai-hulud-check.js <target_directory>');
console.log('\nExample:');
console.log(' node shai-hulud-check.js ./');
process.exit(1);
}
const targetPath = args[0];
const start = process.hrtime();
scanDirectory(targetPath);
const end = process.hrtime(start);
console.log(`Execution time: ${end[0]}s ${end[1] / 1000000}ms`);
}
main();