agentaudit 3.7.0 → 3.7.1
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/cli.mjs +44 -6
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -638,6 +638,11 @@ function findMcpConfigs() {
|
|
|
638
638
|
{ name: 'Continue', path: path.join(home, '.continue', 'config.json') },
|
|
639
639
|
];
|
|
640
640
|
|
|
641
|
+
// Also check AGENTAUDIT_TEST_CONFIG env for testing
|
|
642
|
+
if (process.env.AGENTAUDIT_TEST_CONFIG) {
|
|
643
|
+
candidates.push({ name: 'Test Config', path: process.env.AGENTAUDIT_TEST_CONFIG });
|
|
644
|
+
}
|
|
645
|
+
|
|
641
646
|
// Also scan workspace .cursor/mcp.json, .vscode/mcp.json in cwd
|
|
642
647
|
const cwd = process.cwd();
|
|
643
648
|
candidates.push(
|
|
@@ -731,6 +736,22 @@ function serverSlug(server) {
|
|
|
731
736
|
return server.name.toLowerCase().replace(/[^a-z0-9-]/gi, '-');
|
|
732
737
|
}
|
|
733
738
|
|
|
739
|
+
async function searchGitHub(query) {
|
|
740
|
+
try {
|
|
741
|
+
const res = await fetch(`https://api.github.com/search/repositories?q=${encodeURIComponent(query)}&per_page=1`, {
|
|
742
|
+
signal: AbortSignal.timeout(5000),
|
|
743
|
+
headers: { 'Accept': 'application/vnd.github+json' },
|
|
744
|
+
});
|
|
745
|
+
if (res.ok) {
|
|
746
|
+
const data = await res.json();
|
|
747
|
+
if (data.items?.length > 0) {
|
|
748
|
+
return data.items[0].html_url;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
} catch {}
|
|
752
|
+
return null;
|
|
753
|
+
}
|
|
754
|
+
|
|
734
755
|
async function resolveSourceUrl(server) {
|
|
735
756
|
// Already have it
|
|
736
757
|
if (server.sourceUrl) return server.sourceUrl;
|
|
@@ -750,7 +771,9 @@ async function resolveSourceUrl(server) {
|
|
|
750
771
|
}
|
|
751
772
|
}
|
|
752
773
|
} catch {}
|
|
753
|
-
// Fallback:
|
|
774
|
+
// Fallback: try GitHub search for the package name
|
|
775
|
+
const ghUrl = await searchGitHub(server.npmPackage);
|
|
776
|
+
if (ghUrl) return ghUrl;
|
|
754
777
|
return `https://www.npmjs.com/package/${server.npmPackage}`;
|
|
755
778
|
}
|
|
756
779
|
|
|
@@ -767,6 +790,9 @@ async function resolveSourceUrl(server) {
|
|
|
767
790
|
if (source && source.startsWith('http')) return source;
|
|
768
791
|
}
|
|
769
792
|
} catch {}
|
|
793
|
+
// Fallback: GitHub search
|
|
794
|
+
const ghUrl = await searchGitHub(server.pyPackage);
|
|
795
|
+
if (ghUrl) return ghUrl;
|
|
770
796
|
return `https://pypi.org/project/${server.pyPackage}/`;
|
|
771
797
|
}
|
|
772
798
|
|
|
@@ -915,16 +941,28 @@ async function discoverCommand(options = {}) {
|
|
|
915
941
|
if (unauditedServers > 0) console.log(` ${icons.caution} ${c.yellow}${unauditedServers} not audited${c.reset}`);
|
|
916
942
|
console.log();
|
|
917
943
|
|
|
918
|
-
// --scan: automatically scan all servers with resolved source URLs
|
|
944
|
+
// --scan: automatically scan all servers with resolved source URLs (git-cloneable only)
|
|
919
945
|
if (autoScan) {
|
|
920
|
-
const
|
|
921
|
-
|
|
946
|
+
const isCloneable = (url) => /^https?:\/\/(github\.com|gitlab\.com|bitbucket\.org)\//i.test(url);
|
|
947
|
+
const scanTargets = allServersWithUrls.filter(s => s.sourceUrl && isCloneable(s.sourceUrl));
|
|
948
|
+
// Deduplicate by sourceUrl
|
|
949
|
+
const seen = new Set();
|
|
950
|
+
const dedupedTargets = scanTargets.filter(s => {
|
|
951
|
+
if (seen.has(s.sourceUrl)) return false;
|
|
952
|
+
seen.add(s.sourceUrl);
|
|
953
|
+
return true;
|
|
954
|
+
});
|
|
955
|
+
const skipped = allServersWithUrls.filter(s => s.sourceUrl && !isCloneable(s.sourceUrl));
|
|
956
|
+
if (dedupedTargets.length > 0) {
|
|
922
957
|
console.log(`${c.dim}${'─'.repeat(60)}${c.reset}`);
|
|
923
|
-
console.log(` ${c.bold}${icons.scan} Auto-scanning ${
|
|
958
|
+
console.log(` ${c.bold}${icons.scan} Auto-scanning ${dedupedTargets.length} server${dedupedTargets.length !== 1 ? 's' : ''}...${c.reset}`);
|
|
959
|
+
if (skipped.length > 0) {
|
|
960
|
+
console.log(` ${c.dim}(${skipped.length} skipped — no cloneable source URL)${c.reset}`);
|
|
961
|
+
}
|
|
924
962
|
console.log();
|
|
925
963
|
|
|
926
964
|
const scanResults = [];
|
|
927
|
-
for (const target of
|
|
965
|
+
for (const target of dedupedTargets) {
|
|
928
966
|
const result = await scanRepo(target.sourceUrl);
|
|
929
967
|
if (result) scanResults.push({ ...result, serverName: target.name });
|
|
930
968
|
}
|