Skip to content

Instantly share code, notes, and snippets.

@b0tting
Last active September 16, 2025 19:57
Show Gist options
  • Select an option

  • Save b0tting/8f808aa7d140b102924579540450d242 to your computer and use it in GitHub Desktop.

Select an option

Save b0tting/8f808aa7d140b102924579540450d242 to your computer and use it in GitHub Desktop.
Given a list of compromised NPM packages, check to see which have an updated or retracted version, or which are still compromised when pulling the most recent. Run with "node .\checkPackages.js .\packages.txt".
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const https = require('https');
// Cache latest version lookups per package to ensure only one fetch per unique package
/** @type {Map<string, Promise<string>>} */
const latestVersionCache = new Map();
/** Add a version entry for a package into the map */
function addVersion(packageToVersions, name, version) {
if (!packageToVersions.has(name)) packageToVersions.set(name, new Set());
packageToVersions.get(name).add(version);
}
/** Process a single comma-separated segment and update the map; returns updated currentPackage */
function processSegment(segment, currentPackage, packageToVersions, isSemver) {
// Case: "name@1.2.3" or "@scope/name@1.2.3"
const atPos = segment.lastIndexOf('@');
const hasExplicitVersionWithAt = atPos > 0 && atPos < segment.length - 1 && isSemver(segment.slice(atPos + 1).trim());
if (hasExplicitVersionWithAt) {
const name = segment.slice(0, atPos).trim();
const version = segment.slice(atPos + 1).trim();
addVersion(packageToVersions, name, version);
return name;
}
// Case: shorthand "@1.2.3" meaning version only (must have currentPackage)
if (segment.startsWith('@')) {
const maybeVersion = segment.slice(1).trim();
if (currentPackage && isSemver(maybeVersion)) {
addVersion(packageToVersions, currentPackage, maybeVersion);
return currentPackage;
}
}
// Case: "name 1.2.3" or "@scope/name 1.2.3"
const spaceIdx = segment.lastIndexOf(' ');
if (spaceIdx > 0) {
const left = segment.slice(0, spaceIdx).trim();
const right = segment.slice(spaceIdx + 1).trim();
if (isSemver(right)) {
addVersion(packageToVersions, left, right);
return left;
}
}
// Case: segment is just a semver (e.g. "1.2.3") using the last seen package
if (isSemver(segment) && currentPackage) {
addVersion(packageToVersions, currentPackage, segment);
return currentPackage;
}
// Case: segment is a bare package name
if (segment) {
if (!packageToVersions.has(segment)) packageToVersions.set(segment, new Set());
return segment;
}
return currentPackage;
}
/**
* Parse the packages.txt file into a map of packageName -> Set of compromised versions
* Supported input patterns per line (commas separate entries):
* - name@1.2.3
* - @scope/name@1.2.3
* - name@1.2.3, 1.2.4
* - @scope/name@1.2.3, @1.2.4 (shorthand for same package)
* - @scope/name 1.2.3 (space separator)
*/
function parsePackagesFile(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split(/\r?\n/);
/** @type {Map<string, Set<string>>} */
const packageToVersions = new Map();
const isSemver = (s) => /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(s);
for (const rawLine of lines) {
const line = rawLine.trim();
if (!line || line.startsWith('#')) continue;
let currentPackage = null;
// Split on commas to support multiple versions or entries per line
const segments = line.split(',').map(s => s.trim()).filter(Boolean);
for (const segment of segments) {
if (!segment) continue;
currentPackage = processSegment(segment, currentPackage, packageToVersions, isSemver);
}
}
return packageToVersions;
}
function fetchJson(url) {
return new Promise((resolve, reject) => {
https
.get(url, { headers: { 'Accept': 'application/vnd.npm.install-v1+json, application/json', 'User-Agent': 'npmPackageScanner/1.0 (+node https)'} }, (res) => {
let data = '';
res.setEncoding('utf8');
res.on('data', (chunk) => (data += chunk));
res.on('end', () => {
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
try {
resolve(JSON.parse(data));
} catch (err) {
reject(new Error(`Failed to parse JSON from ${url}: ${err.message}`));
}
} else {
reject(new Error(`HTTP ${res.statusCode} for ${url}: ${data.slice(0, 200)}`));
}
});
})
.on('error', (err) => reject(err));
});
}
function compareSemver(a, b) {
const parse = (s) => {
const [core, pre] = s.split('-');
const [ma, mi, pa] = core.split('.').map((n) => parseInt(n, 10));
return { ma, mi, pa, pre: pre || '' };
};
const A = parse(a);
const B = parse(b);
if (A.ma !== B.ma) return A.ma - B.ma;
if (A.mi !== B.mi) return A.mi - B.mi;
if (A.pa !== B.pa) return A.pa - B.pa;
// Pre-release: absence > presence (e.g., 1.0.0 > 1.0.0-beta)
if (A.pre === B.pre) return 0;
if (!A.pre) return 1;
if (!B.pre) return -1;
return A.pre.localeCompare(B.pre);
}
async function getLatestVersionFromRegistry(pkgName) {
if (latestVersionCache.has(pkgName)) {
return latestVersionCache.get(pkgName);
}
const promise = (async () => {
const encoded = encodeURIComponent(pkgName);
const url = `https://registry.npmjs.org/${encoded}`;
const json = await fetchJson(url);
if (json && json['dist-tags'] && json['dist-tags'].latest) {
return json['dist-tags'].latest;
}
// Fallback: pick max of versions keys
if (json && json.versions && typeof json.versions === 'object') {
const versions = Object.keys(json.versions);
if (versions.length > 0) {
versions.sort(compareSemver);
return versions[versions.length - 1];
}
}
throw new Error(`No versions found for ${pkgName}`);
})();
latestVersionCache.set(pkgName, promise);
return promise;
}
async function main() {
const argPath = process.argv[2];
if (!argPath) {
console.error('Usage: node checkPackages.js <path-to-packages.txt>');
process.exit(1);
}
const filePath = path.resolve(process.cwd(), argPath);
if (!fs.existsSync(filePath)) {
console.error(`File not found: ${filePath}`);
process.exit(1);
}
const packageToVersions = parsePackagesFile(filePath);
const entries = Array.from(packageToVersions.entries());
if (entries.length === 0) {
const raw = fs.readFileSync(filePath, 'utf8');
console.error('No packages parsed from packages.txt. Please check formatting.');
console.error(`packages.txt path: ${filePath}`);
console.error(`packages.txt size: ${raw.length} chars`);
const preview = raw.split(/\r?\n/).slice(0, 5).join('\n');
console.error('First lines preview:\n' + preview);
return;
}
// Limit concurrency to avoid overwhelming the registry
const concurrency = 8;
let index = 0;
const results = [];
async function worker() {
while (true) {
let i;
if (index >= entries.length) return;
i = index++;
const [pkg, compromisedSet] = entries[i];
try {
const latest = await getLatestVersionFromRegistry(pkg);
const stillCompromised = compromisedSet.has(latest);
results[i] = { pkg, compromisedSet, latest, stillCompromised, error: null };
} catch (err) {
results[i] = { pkg, compromisedSet, latest: null, stillCompromised: false, error: String(err.message || err) };
}
}
}
const workers = Array.from({ length: Math.min(concurrency, entries.length) }, () => worker());
await Promise.all(workers);
let compromisedCount = 0;
let notCompromisedCount = 0;
let errorCount = 0;
for (const r of results) {
if (!r) continue;
const versions = Array.from(r.compromisedSet || []).sort(compareSemver).join(', ');
if (r.error) {
console.log(`${r.pkg}@${versions} -> ERROR: ${r.error}`);
errorCount++;
} else if (r.stillCompromised) {
console.log(`${r.pkg}@${versions} -> still compromised`);
compromisedCount++;
} else {
console.log(`${r.pkg}@${versions} -> latest ${r.latest}`);
notCompromisedCount++;
}
}
console.log(`\nScanned ${results.filter(Boolean).length} packages: ${compromisedCount} still compromised, ${notCompromisedCount} not compromised, ${errorCount} errors.`);
}
// Given a file with a list of packages and versions, this script will check if requesting the packages from the npm registry
// gives you either a higher version (meaning there was an update) or a lower version (meaning the compromised version is detracted)
// If neither, the package is still compromised. Version information is retrieved by from the npm registry - see for example
// https://registry.npmjs.org/angulartics2
//
// App was mostly vibecoded with Cursor :)
//
// This works great with the list from https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages
// but I started with other examples from aikido.dev which had a comma separated list of versions per package. Also works.
main().catch((err) => {
console.error(err);
process.exit(1);
});
# List from https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages, 21:39 16-09-2025
@ahmedhfarag/ngx-perfect-scrollbar@20.0.20
@ahmedhfarag/ngx-virtual-scroller@4.0.4
@art-ws/common@2.0.28
@art-ws/config-eslint@2.0.4
@art-ws/config-eslint@2.0.5
@art-ws/config-ts@2.0.7
@art-ws/config-ts@2.0.8
@art-ws/db-context@2.0.24
@art-ws/di-node@2.0.13
@art-ws/di@2.0.28
@art-ws/di@2.0.32
@art-ws/eslint@1.0.5
@art-ws/eslint@1.0.6
@art-ws/fastify-http-server@2.0.24
@art-ws/fastify-http-server@2.0.27
@art-ws/http-server@2.0.21
@art-ws/http-server@2.0.25
@art-ws/openapi@0.1.12
@art-ws/openapi@0.1.9
@art-ws/package-base@1.0.5
@art-ws/package-base@1.0.6
@art-ws/prettier@1.0.5
@art-ws/prettier@1.0.6
@art-ws/slf@2.0.15
@art-ws/slf@2.0.22
@art-ws/ssl-info@1.0.10
@art-ws/ssl-info@1.0.9
@art-ws/web-app@1.0.3
@art-ws/web-app@1.0.4
@crowdstrike/commitlint@8.1.1
@crowdstrike/commitlint@8.1.2
@crowdstrike/falcon-shoelace@0.4.1
@crowdstrike/falcon-shoelace@0.4.2
@crowdstrike/foundry-js@0.19.1
@crowdstrike/foundry-js@0.19.2
@crowdstrike/glide-core@0.34.2
@crowdstrike/glide-core@0.34.3
@crowdstrike/logscale-dashboard@1.205.1
@crowdstrike/logscale-dashboard@1.205.2
@crowdstrike/logscale-file-editor@1.205.1
@crowdstrike/logscale-file-editor@1.205.2
@crowdstrike/logscale-parser-edit@1.205.1
@crowdstrike/logscale-parser-edit@1.205.2
@crowdstrike/logscale-search@1.205.1
@crowdstrike/logscale-search@1.205.2
@crowdstrike/tailwind-toucan-base@5.0.1
@crowdstrike/tailwind-toucan-base@5.0.2
@ctrl/deluge@7.2.1
@ctrl/deluge@7.2.2
@ctrl/golang-template@1.4.2
@ctrl/golang-template@1.4.3
@ctrl/magnet-link@4.0.3
@ctrl/magnet-link@4.0.4
@ctrl/ngx-codemirror@7.0.1
@ctrl/ngx-codemirror@7.0.2
@ctrl/ngx-csv@6.0.1
@ctrl/ngx-csv@6.0.2
@ctrl/ngx-emoji-mart@9.2.1
@ctrl/ngx-emoji-mart@9.2.2
@ctrl/ngx-rightclick@4.0.1
@ctrl/ngx-rightclick@4.0.2
@ctrl/qbittorrent@9.7.1
@ctrl/qbittorrent@9.7.2
@ctrl/react-adsense@2.0.1
@ctrl/react-adsense@2.0.2
@ctrl/shared-torrent@6.3.1
@ctrl/shared-torrent@6.3.2
@ctrl/tinycolor@4.1.1
@ctrl/tinycolor@4.1.2
@ctrl/torrent-file@4.1.1
@ctrl/torrent-file@4.1.2
@ctrl/transmission@7.3.1
@ctrl/ts-base32@4.0.1
@ctrl/ts-base32@4.0.2
@hestjs/core@0.2.1
@hestjs/cqrs@0.1.6
@hestjs/demo@0.1.2
@hestjs/eslint-config@0.1.2
@hestjs/logger@0.1.6
@hestjs/scalar@0.1.7
@hestjs/validation@0.1.6
@nativescript-community/arraybuffers@1.1.6
@nativescript-community/arraybuffers@1.1.7
@nativescript-community/arraybuffers@1.1.8
@nativescript-community/gesturehandler@2.0.35
@nativescript-community/perms@3.0.5
@nativescript-community/perms@3.0.6
@nativescript-community/perms@3.0.7
@nativescript-community/perms@3.0.8
@nativescript-community/sentry@4.6.43
@nativescript-community/sqlite@3.5.2
@nativescript-community/sqlite@3.5.3
@nativescript-community/sqlite@3.5.4
@nativescript-community/sqlite@3.5.5
@nativescript-community/text@1.6.10
@nativescript-community/text@1.6.11
@nativescript-community/text@1.6.12
@nativescript-community/text@1.6.13
@nativescript-community/text@1.6.9
@nativescript-community/typeorm@0.2.30
@nativescript-community/typeorm@0.2.31
@nativescript-community/typeorm@0.2.32
@nativescript-community/typeorm@0.2.33
@nativescript-community/ui-collectionview@6.0.6
@nativescript-community/ui-document-picker@1.1.27
@nativescript-community/ui-document-picker@1.1.28
@nativescript-community/ui-drawer@0.1.30
@nativescript-community/ui-image@4.5.6
@nativescript-community/ui-label@1.3.35
@nativescript-community/ui-label@1.3.36
@nativescript-community/ui-label@1.3.37
@nativescript-community/ui-material-bottom-navigation@7.2.72
@nativescript-community/ui-material-bottom-navigation@7.2.73
@nativescript-community/ui-material-bottom-navigation@7.2.74
@nativescript-community/ui-material-bottom-navigation@7.2.75
@nativescript-community/ui-material-bottomsheet@7.2.72
@nativescript-community/ui-material-core-tabs@7.2.72
@nativescript-community/ui-material-core-tabs@7.2.73
@nativescript-community/ui-material-core-tabs@7.2.74
@nativescript-community/ui-material-core-tabs@7.2.75
@nativescript-community/ui-material-core-tabs@7.2.76
@nativescript-community/ui-material-core@7.2.72
@nativescript-community/ui-material-core@7.2.73
@nativescript-community/ui-material-core@7.2.74
@nativescript-community/ui-material-core@7.2.75
@nativescript-community/ui-material-core@7.2.76
@nativescript-community/ui-material-ripple@7.2.72
@nativescript-community/ui-material-ripple@7.2.73
@nativescript-community/ui-material-ripple@7.2.74
@nativescript-community/ui-material-ripple@7.2.75
@nativescript-community/ui-material-tabs@7.2.72
@nativescript-community/ui-material-tabs@7.2.73
@nativescript-community/ui-material-tabs@7.2.74
@nativescript-community/ui-material-tabs@7.2.75
@nativescript-community/ui-pager@14.1.36
@nativescript-community/ui-pager@14.1.37
@nativescript-community/ui-pager@14.1.38
@nativescript-community/ui-pulltorefresh@2.5.4
@nativescript-community/ui-pulltorefresh@2.5.5
@nativescript-community/ui-pulltorefresh@2.5.6
@nativescript-community/ui-pulltorefresh@2.5.7
@nexe/config-manager@0.1.1
@nexe/eslint-config@0.1.1
@nexe/logger@0.1.3
@nstudio/angular@20.0.4
@nstudio/angular@20.0.5
@nstudio/angular@20.0.6
@nstudio/focus@20.0.4
@nstudio/focus@20.0.5
@nstudio/focus@20.0.6
@nstudio/nativescript-checkbox@2.0.6
@nstudio/nativescript-checkbox@2.0.7
@nstudio/nativescript-checkbox@2.0.8
@nstudio/nativescript-checkbox@2.0.9
@nstudio/nativescript-loading-indicator@5.0.1
@nstudio/nativescript-loading-indicator@5.0.2
@nstudio/nativescript-loading-indicator@5.0.3
@nstudio/nativescript-loading-indicator@5.0.4
@nstudio/ui-collectionview@5.1.11
@nstudio/ui-collectionview@5.1.12
@nstudio/ui-collectionview@5.1.13
@nstudio/ui-collectionview@5.1.14
@nstudio/web-angular@20.0.4
@nstudio/web@20.0.4
@nstudio/xplat-utils@20.0.5
@nstudio/xplat-utils@20.0.6
@nstudio/xplat-utils@20.0.7
@nstudio/xplat@20.0.5
@nstudio/xplat@20.0.6
@nstudio/xplat@20.0.7
@operato/board@9.0.36
@operato/board@9.0.37
@operato/board@9.0.38
@operato/board@9.0.39
@operato/board@9.0.40
@operato/board@9.0.41
@operato/board@9.0.42
@operato/board@9.0.43
@operato/board@9.0.44
@operato/board@9.0.45
@operato/board@9.0.46
@operato/data-grist@9.0.29
@operato/data-grist@9.0.35
@operato/data-grist@9.0.36
@operato/data-grist@9.0.37
@operato/graphql@9.0.22
@operato/graphql@9.0.35
@operato/graphql@9.0.36
@operato/graphql@9.0.37
@operato/graphql@9.0.38
@operato/graphql@9.0.39
@operato/graphql@9.0.40
@operato/graphql@9.0.41
@operato/graphql@9.0.42
@operato/graphql@9.0.43
@operato/graphql@9.0.44
@operato/graphql@9.0.45
@operato/graphql@9.0.46
@operato/headroom@9.0.2
@operato/headroom@9.0.35
@operato/headroom@9.0.36
@operato/headroom@9.0.37
@operato/help@9.0.35
@operato/help@9.0.36
@operato/help@9.0.37
@operato/help@9.0.38
@operato/help@9.0.39
@operato/help@9.0.40
@operato/help@9.0.41
@operato/help@9.0.42
@operato/help@9.0.43
@operato/help@9.0.44
@operato/help@9.0.45
@operato/help@9.0.46
@operato/i18n@9.0.35
@operato/i18n@9.0.36
@operato/i18n@9.0.37
@operato/input@9.0.27
@operato/input@9.0.35
@operato/input@9.0.36
@operato/input@9.0.37
@operato/input@9.0.38
@operato/input@9.0.39
@operato/input@9.0.40
@operato/input@9.0.41
@operato/input@9.0.42
@operato/input@9.0.43
@operato/input@9.0.44
@operato/input@9.0.45
@operato/input@9.0.46
@operato/input@9.0.47
@operato/input@9.0.48
@operato/layout@9.0.35
@operato/layout@9.0.36
@operato/layout@9.0.37
@operato/popup@9.0.22
@operato/popup@9.0.35
@operato/popup@9.0.36
@operato/popup@9.0.37
@operato/popup@9.0.38
@operato/popup@9.0.39
@operato/popup@9.0.40
@operato/popup@9.0.41
@operato/popup@9.0.42
@operato/popup@9.0.43
@operato/popup@9.0.44
@operato/popup@9.0.45
@operato/popup@9.0.46
@operato/popup@9.0.49
@operato/pull-to-refresh@9.0.36
@operato/pull-to-refresh@9.0.37
@operato/pull-to-refresh@9.0.38
@operato/pull-to-refresh@9.0.39
@operato/pull-to-refresh@9.0.40
@operato/pull-to-refresh@9.0.41
@operato/pull-to-refresh@9.0.42
@operato/shell@9.0.22
@operato/shell@9.0.35
@operato/shell@9.0.36
@operato/shell@9.0.37
@operato/shell@9.0.38
@operato/shell@9.0.39
@operato/styles@9.0.2
@operato/styles@9.0.35
@operato/styles@9.0.36
@operato/styles@9.0.37
@operato/utils@9.0.22
@operato/utils@9.0.35
@operato/utils@9.0.36
@operato/utils@9.0.37
@operato/utils@9.0.38
@operato/utils@9.0.39
@operato/utils@9.0.40
@operato/utils@9.0.41
@operato/utils@9.0.42
@operato/utils@9.0.43
@operato/utils@9.0.44
@operato/utils@9.0.45
@operato/utils@9.0.46
@operato/utils@9.0.49
@teselagen/bio-parsers@0.4.30
@teselagen/bounce-loader@0.3.16
@teselagen/bounce-loader@0.3.17
@teselagen/file-utils@0.3.22
@teselagen/liquibase-tools@0.4.1
@teselagen/ove@0.7.40
@teselagen/range-utils@0.3.14
@teselagen/range-utils@0.3.15
@teselagen/react-list@0.8.19
@teselagen/react-list@0.8.20
@teselagen/react-table@6.10.19
@teselagen/react-table@6.10.20
@teselagen/react-table@6.10.22
@teselagen/sequence-utils@0.3.34
@teselagen/ui@0.9.10
@thangved/callback-window@1.1.4
@things-factory/attachment-base@9.0.43
@things-factory/attachment-base@9.0.44
@things-factory/attachment-base@9.0.45
@things-factory/attachment-base@9.0.46
@things-factory/attachment-base@9.0.47
@things-factory/attachment-base@9.0.48
@things-factory/attachment-base@9.0.49
@things-factory/attachment-base@9.0.50
@things-factory/auth-base@9.0.43
@things-factory/auth-base@9.0.44
@things-factory/auth-base@9.0.45
@things-factory/email-base@9.0.42
@things-factory/email-base@9.0.43
@things-factory/email-base@9.0.44
@things-factory/email-base@9.0.45
@things-factory/email-base@9.0.46
@things-factory/email-base@9.0.47
@things-factory/email-base@9.0.48
@things-factory/email-base@9.0.49
@things-factory/email-base@9.0.50
@things-factory/email-base@9.0.51
@things-factory/email-base@9.0.52
@things-factory/email-base@9.0.53
@things-factory/email-base@9.0.54
@things-factory/env@9.0.42
@things-factory/env@9.0.43
@things-factory/env@9.0.44
@things-factory/env@9.0.45
@things-factory/integration-base@9.0.43
@things-factory/integration-base@9.0.44
@things-factory/integration-base@9.0.45
@things-factory/integration-marketplace@9.0.43
@things-factory/integration-marketplace@9.0.44
@things-factory/integration-marketplace@9.0.45
@things-factory/shell@9.0.43
@things-factory/shell@9.0.44
@things-factory/shell@9.0.45
@tnf-dev/api@1.0.8
@tnf-dev/core@1.0.8
@tnf-dev/js@1.0.8
@tnf-dev/mui@1.0.8
@tnf-dev/react@1.0.8
@ui-ux-gang/devextreme-angular-rpk@24.1.7
@yoobic/design-system@6.5.17
@yoobic/jpeg-camera-es6@1.0.13
@yoobic/yobi@8.7.53
airchief@0.3.1
airpilot@0.8.8
angulartics2@14.1.1
angulartics2@14.1.2
browser-webdriver-downloader@3.0.8
capacitor-notificationhandler@0.0.2
capacitor-notificationhandler@0.0.3
capacitor-plugin-healthapp@0.0.2
capacitor-plugin-healthapp@0.0.3
capacitor-plugin-ihealth@1.1.8
capacitor-plugin-ihealth@1.1.9
capacitor-plugin-vonage@1.0.2
capacitor-plugin-vonage@1.0.3
capacitorandroidpermissions@0.0.4
capacitorandroidpermissions@0.0.5
config-cordova@0.8.5
cordova-plugin-voxeet2@1.0.24
cordova-voxeet@1.0.32
create-hest-app@0.1.9
db-evo@1.1.4
db-evo@1.1.5
devextreme-angular-rpk@21.2.8
ember-browser-services@5.0.2
ember-browser-services@5.0.3
ember-headless-form-yup@1.0.1
ember-headless-form@1.1.2
ember-headless-form@1.1.3
ember-headless-table@2.1.5
ember-headless-table@2.1.6
ember-url-hash-polyfill@1.0.12
ember-url-hash-polyfill@1.0.13
ember-velcro@2.2.1
ember-velcro@2.2.2
encounter-playground@0.0.2
encounter-playground@0.0.3
encounter-playground@0.0.4
encounter-playground@0.0.5
eslint-config-crowdstrike-node@4.0.3
eslint-config-crowdstrike-node@4.0.4
eslint-config-crowdstrike@11.0.2
eslint-config-crowdstrike@11.0.3
eslint-config-teselagen@6.1.7
eslint-config-teselagen@6.1.8
globalize-rpk@1.7.4
graphql-sequelize-teselagen@5.3.8
graphql-sequelize-teselagen@5.3.9
html-to-base64-image@1.0.2
json-rules-engine-simplified@0.2.1
json-rules-engine-simplified@0.2.4
jumpgate@0.0.2
koa2-swagger-ui@5.11.1
koa2-swagger-ui@5.11.2
mcfly-semantic-release@1.3.1
mcp-knowledge-base@0.0.2
mcp-knowledge-graph@1.2.1
mobioffice-cli@1.0.3
monorepo-next@13.0.1
monorepo-next@13.0.2
mstate-angular@0.4.4
mstate-cli@0.4.7
mstate-dev-react@1.1.1
mstate-react@1.6.5
ng2-file-upload@7.0.2
ng2-file-upload@7.0.3
ng2-file-upload@8.0.1
ng2-file-upload@8.0.2
ng2-file-upload@8.0.3
ng2-file-upload@9.0.1
ngx-bootstrap@18.1.4
ngx-bootstrap@19.0.3
ngx-bootstrap@19.0.4
ngx-bootstrap@20.0.3
ngx-bootstrap@20.0.4
ngx-bootstrap@20.0.5
ngx-color@10.0.1
ngx-color@10.0.2
ngx-toastr@19.0.1
ngx-toastr@19.0.2
ngx-trend@8.0.1
ngx-ws@1.1.5
ngx-ws@1.1.6
oradm-to-gql@35.0.14
oradm-to-gql@35.0.15
oradm-to-sqlz@1.1.2
ove-auto-annotate@0.0.10
ove-auto-annotate@0.0.9
pm2-gelf-json@1.0.4
pm2-gelf-json@1.0.5
printjs-rpk@1.6.1
react-complaint-image@0.0.32
react-complaint-image@0.0.35
react-jsonschema-form-conditionals@0.3.18
react-jsonschema-form-conditionals@0.3.21
react-jsonschema-form-extras@1.0.4
react-jsonschema-rxnt-extras@0.4.9
remark-preset-lint-crowdstrike@4.0.1
remark-preset-lint-crowdstrike@4.0.2
rxnt-authentication@0.0.3
rxnt-authentication@0.0.4
rxnt-authentication@0.0.5
rxnt-authentication@0.0.6
rxnt-healthchecks-nestjs@1.0.2
rxnt-healthchecks-nestjs@1.0.3
rxnt-healthchecks-nestjs@1.0.4
rxnt-healthchecks-nestjs@1.0.5
rxnt-kue@1.0.4
rxnt-kue@1.0.5
rxnt-kue@1.0.6
rxnt-kue@1.0.7
swc-plugin-component-annotate@1.9.1
swc-plugin-component-annotate@1.9.2
tbssnch@1.0.2
teselagen-interval-tree@1.1.2
tg-client-query-builder@2.14.4
tg-client-query-builder@2.14.5
tg-redbird@1.3.1
tg-redbird@1.3.2
tg-seq-gen@1.0.10
tg-seq-gen@1.0.9
thangved-react-grid@1.0.3
ts-gaussian@3.0.5
ts-gaussian@3.0.6
ts-imports@1.0.1
ts-imports@1.0.2
tvi-cli@0.1.5
ve-bamreader@0.2.6
ve-bamreader@0.2.7
ve-editor@1.0.1
ve-editor@1.0.2
verror-extra@6.0.1
voip-callkit@1.0.2
voip-callkit@1.0.3
wdio-web-reporter@0.1.3
yargs-help-output@5.0.3
yoo-styles@6.0.326
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment