@ash-technologia/fathom 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/LICENSE +21 -0
- package/README.md +725 -0
- package/dist/analyzers/architecture/graph.d.ts +29 -0
- package/dist/analyzers/architecture/graph.d.ts.map +1 -0
- package/dist/analyzers/architecture/graph.js +347 -0
- package/dist/analyzers/architecture/graph.js.map +1 -0
- package/dist/analyzers/architecture/imports.d.ts +24 -0
- package/dist/analyzers/architecture/imports.d.ts.map +1 -0
- package/dist/analyzers/architecture/imports.js +155 -0
- package/dist/analyzers/architecture/imports.js.map +1 -0
- package/dist/analyzers/architecture/index.d.ts +13 -0
- package/dist/analyzers/architecture/index.d.ts.map +1 -0
- package/dist/analyzers/architecture/index.js +217 -0
- package/dist/analyzers/architecture/index.js.map +1 -0
- package/dist/analyzers/architecture/types.d.ts +65 -0
- package/dist/analyzers/architecture/types.d.ts.map +1 -0
- package/dist/analyzers/architecture/types.js +2 -0
- package/dist/analyzers/architecture/types.js.map +1 -0
- package/dist/analyzers/cicd/index.d.ts +11 -0
- package/dist/analyzers/cicd/index.d.ts.map +1 -0
- package/dist/analyzers/cicd/index.js +157 -0
- package/dist/analyzers/cicd/index.js.map +1 -0
- package/dist/analyzers/dependencies/index.d.ts +11 -0
- package/dist/analyzers/dependencies/index.d.ts.map +1 -0
- package/dist/analyzers/dependencies/index.js +403 -0
- package/dist/analyzers/dependencies/index.js.map +1 -0
- package/dist/analyzers/dependencies/lockfiles.d.ts +19 -0
- package/dist/analyzers/dependencies/lockfiles.d.ts.map +1 -0
- package/dist/analyzers/dependencies/lockfiles.js +172 -0
- package/dist/analyzers/dependencies/lockfiles.js.map +1 -0
- package/dist/analyzers/dependencies/online.d.ts +19 -0
- package/dist/analyzers/dependencies/online.d.ts.map +1 -0
- package/dist/analyzers/dependencies/online.js +116 -0
- package/dist/analyzers/dependencies/online.js.map +1 -0
- package/dist/analyzers/dependencies/types.d.ts +49 -0
- package/dist/analyzers/dependencies/types.d.ts.map +1 -0
- package/dist/analyzers/dependencies/types.js +2 -0
- package/dist/analyzers/dependencies/types.js.map +1 -0
- package/dist/analyzers/documentation/index.d.ts +11 -0
- package/dist/analyzers/documentation/index.d.ts.map +1 -0
- package/dist/analyzers/documentation/index.js +166 -0
- package/dist/analyzers/documentation/index.js.map +1 -0
- package/dist/analyzers/git/index.d.ts +11 -0
- package/dist/analyzers/git/index.d.ts.map +1 -0
- package/dist/analyzers/git/index.js +180 -0
- package/dist/analyzers/git/index.js.map +1 -0
- package/dist/analyzers/project/index.d.ts +11 -0
- package/dist/analyzers/project/index.d.ts.map +1 -0
- package/dist/analyzers/project/index.js +95 -0
- package/dist/analyzers/project/index.js.map +1 -0
- package/dist/analyzers/quality/index.d.ts +11 -0
- package/dist/analyzers/quality/index.d.ts.map +1 -0
- package/dist/analyzers/quality/index.js +198 -0
- package/dist/analyzers/quality/index.js.map +1 -0
- package/dist/analyzers/security/index.d.ts +11 -0
- package/dist/analyzers/security/index.d.ts.map +1 -0
- package/dist/analyzers/security/index.js +236 -0
- package/dist/analyzers/security/index.js.map +1 -0
- package/dist/analyzers/testing/index.d.ts +11 -0
- package/dist/analyzers/testing/index.d.ts.map +1 -0
- package/dist/analyzers/testing/index.js +134 -0
- package/dist/analyzers/testing/index.js.map +1 -0
- package/dist/baseline/baseline.d.ts +20 -0
- package/dist/baseline/baseline.d.ts.map +1 -0
- package/dist/baseline/baseline.js +134 -0
- package/dist/baseline/baseline.js.map +1 -0
- package/dist/baseline/compare.d.ts +14 -0
- package/dist/baseline/compare.d.ts.map +1 -0
- package/dist/baseline/compare.js +113 -0
- package/dist/baseline/compare.js.map +1 -0
- package/dist/baseline/types.d.ts +25 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +2 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/cli/commands.d.ts +39 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +277 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/options.d.ts +55 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +258 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/core/analyzer.d.ts +33 -0
- package/dist/core/analyzer.d.ts.map +1 -0
- package/dist/core/analyzer.js +19 -0
- package/dist/core/analyzer.js.map +1 -0
- package/dist/core/context.d.ts +90 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +159 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/errors.d.ts +74 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +109 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/findings.d.ts +59 -0
- package/dist/core/findings.d.ts.map +1 -0
- package/dist/core/findings.js +34 -0
- package/dist/core/findings.js.map +1 -0
- package/dist/core/orchestrator.d.ts +44 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +160 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/result.d.ts +169 -0
- package/dist/core/result.d.ts.map +1 -0
- package/dist/core/result.js +2 -0
- package/dist/core/result.js.map +1 -0
- package/dist/detectors/framework.d.ts +22 -0
- package/dist/detectors/framework.d.ts.map +1 -0
- package/dist/detectors/framework.js +147 -0
- package/dist/detectors/framework.js.map +1 -0
- package/dist/detectors/language.d.ts +13 -0
- package/dist/detectors/language.d.ts.map +1 -0
- package/dist/detectors/language.js +100 -0
- package/dist/detectors/language.js.map +1 -0
- package/dist/detectors/package-manager.d.ts +17 -0
- package/dist/detectors/package-manager.d.ts.map +1 -0
- package/dist/detectors/package-manager.js +67 -0
- package/dist/detectors/package-manager.js.map +1 -0
- package/dist/detectors/project-type.d.ts +20 -0
- package/dist/detectors/project-type.d.ts.map +1 -0
- package/dist/detectors/project-type.js +48 -0
- package/dist/detectors/project-type.js.map +1 -0
- package/dist/diff/analyzer.d.ts +16 -0
- package/dist/diff/analyzer.d.ts.map +1 -0
- package/dist/diff/analyzer.js +296 -0
- package/dist/diff/analyzer.js.map +1 -0
- package/dist/diff/git-diff.d.ts +44 -0
- package/dist/diff/git-diff.d.ts.map +1 -0
- package/dist/diff/git-diff.js +256 -0
- package/dist/diff/git-diff.js.map +1 -0
- package/dist/diff/types.d.ts +75 -0
- package/dist/diff/types.d.ts.map +1 -0
- package/dist/diff/types.js +2 -0
- package/dist/diff/types.js.map +1 -0
- package/dist/integrations/github/context.d.ts +22 -0
- package/dist/integrations/github/context.d.ts.map +1 -0
- package/dist/integrations/github/context.js +115 -0
- package/dist/integrations/github/context.js.map +1 -0
- package/dist/integrations/github/types.d.ts +30 -0
- package/dist/integrations/github/types.d.ts.map +1 -0
- package/dist/integrations/github/types.js +2 -0
- package/dist/integrations/github/types.js.map +1 -0
- package/dist/plugins/context.d.ts +13 -0
- package/dist/plugins/context.d.ts.map +1 -0
- package/dist/plugins/context.js +102 -0
- package/dist/plugins/context.js.map +1 -0
- package/dist/plugins/examples/react.d.ts +8 -0
- package/dist/plugins/examples/react.d.ts.map +1 -0
- package/dist/plugins/examples/react.js +129 -0
- package/dist/plugins/examples/react.js.map +1 -0
- package/dist/plugins/index.d.ts +5 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/registry.d.ts +45 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +236 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/types.d.ts +148 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/reporters/html.d.ts +11 -0
- package/dist/reporters/html.d.ts.map +1 -0
- package/dist/reporters/html.js +1352 -0
- package/dist/reporters/html.js.map +1 -0
- package/dist/reporters/json.d.ts +10 -0
- package/dist/reporters/json.d.ts.map +1 -0
- package/dist/reporters/json.js +11 -0
- package/dist/reporters/json.js.map +1 -0
- package/dist/reporters/markdown.d.ts +7 -0
- package/dist/reporters/markdown.d.ts.map +1 -0
- package/dist/reporters/markdown.js +74 -0
- package/dist/reporters/markdown.js.map +1 -0
- package/dist/reporters/sarif.d.ts +133 -0
- package/dist/reporters/sarif.d.ts.map +1 -0
- package/dist/reporters/sarif.js +268 -0
- package/dist/reporters/sarif.js.map +1 -0
- package/dist/reporters/terminal.d.ts +17 -0
- package/dist/reporters/terminal.d.ts.map +1 -0
- package/dist/reporters/terminal.js +423 -0
- package/dist/reporters/terminal.js.map +1 -0
- package/dist/rules/categories.d.ts +8 -0
- package/dist/rules/categories.d.ts.map +1 -0
- package/dist/rules/categories.js +23 -0
- package/dist/rules/categories.js.map +1 -0
- package/dist/rules/definitions.d.ts +25 -0
- package/dist/rules/definitions.d.ts.map +1 -0
- package/dist/rules/definitions.js +429 -0
- package/dist/rules/definitions.js.map +1 -0
- package/dist/rules/registry.d.ts +36 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +64 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/rules/severity.d.ts +13 -0
- package/dist/rules/severity.d.ts.map +1 -0
- package/dist/rules/severity.js +15 -0
- package/dist/rules/severity.js.map +1 -0
- package/dist/scoring/confidence.d.ts +12 -0
- package/dist/scoring/confidence.d.ts.map +1 -0
- package/dist/scoring/confidence.js +22 -0
- package/dist/scoring/confidence.js.map +1 -0
- package/dist/scoring/score.d.ts +27 -0
- package/dist/scoring/score.d.ts.map +1 -0
- package/dist/scoring/score.js +81 -0
- package/dist/scoring/score.js.map +1 -0
- package/dist/scoring/weights.d.ts +11 -0
- package/dist/scoring/weights.d.ts.map +1 -0
- package/dist/scoring/weights.js +26 -0
- package/dist/scoring/weights.js.map +1 -0
- package/dist/utils/filesystem.d.ts +65 -0
- package/dist/utils/filesystem.d.ts.map +1 -0
- package/dist/utils/filesystem.js +299 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/git.d.ts +47 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +125 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +25 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +30 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +48 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/timing.d.ts +12 -0
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +19 -0
- package/dist/utils/timing.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queries the public Open Source Vulnerabilities (OSV) API in batch mode.
|
|
3
|
+
* Strictly respects timeouts and offline failures. Never transmits repository source code or tokens.
|
|
4
|
+
*/
|
|
5
|
+
export async function queryVulnerabilitiesOnline(packages) {
|
|
6
|
+
if (packages.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
// Limit query batch to first 50 packages to preserve bounded network usage
|
|
9
|
+
const batch = packages.slice(0, 50);
|
|
10
|
+
const queries = batch.map((p) => ({
|
|
11
|
+
package: {
|
|
12
|
+
name: p.name,
|
|
13
|
+
ecosystem: p.ecosystem ?? 'npm',
|
|
14
|
+
},
|
|
15
|
+
version: p.version,
|
|
16
|
+
}));
|
|
17
|
+
try {
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
const timer = setTimeout(() => controller.abort(), 3500);
|
|
20
|
+
const response = await fetch('https://api.osv.dev/v1/querybatch', {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
'User-Agent': 'Fathom-Repository-Intelligence/0.1.0',
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify({ queries }),
|
|
27
|
+
signal: controller.signal,
|
|
28
|
+
});
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
if (!response.ok)
|
|
31
|
+
return [];
|
|
32
|
+
const data = (await response.json());
|
|
33
|
+
const advisories = [];
|
|
34
|
+
if (Array.isArray(data.results)) {
|
|
35
|
+
data.results.forEach((res, idx) => {
|
|
36
|
+
const pkg = batch[idx];
|
|
37
|
+
if (!pkg || !res.vulns)
|
|
38
|
+
return;
|
|
39
|
+
for (const v of res.vulns) {
|
|
40
|
+
let severity = 'high';
|
|
41
|
+
const rawSev = v.database_specific?.severity?.toLowerCase();
|
|
42
|
+
if (rawSev === 'critical')
|
|
43
|
+
severity = 'critical';
|
|
44
|
+
else if (rawSev === 'high')
|
|
45
|
+
severity = 'high';
|
|
46
|
+
else if (rawSev === 'medium' || rawSev === 'moderate')
|
|
47
|
+
severity = 'medium';
|
|
48
|
+
else if (rawSev === 'low')
|
|
49
|
+
severity = 'low';
|
|
50
|
+
advisories.push({
|
|
51
|
+
id: v.id,
|
|
52
|
+
packageName: pkg.name,
|
|
53
|
+
affectedVersion: pkg.version,
|
|
54
|
+
severity,
|
|
55
|
+
title: v.summary ?? `Vulnerability in ${pkg.name} (${v.id})`,
|
|
56
|
+
url: `https://osv.dev/vulnerability/${v.id}`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return advisories;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Network errors, timeouts, or offline environments degrade gracefully to empty list
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Checks for latest versions of direct dependencies against npm registry.
|
|
70
|
+
* Limited to first 25 packages with 2.5s individual timeout.
|
|
71
|
+
*/
|
|
72
|
+
export async function checkOutdatedOnline(directDeps) {
|
|
73
|
+
const candidates = directDeps.slice(0, 25);
|
|
74
|
+
const results = [];
|
|
75
|
+
const checks = candidates.map(async (dep) => {
|
|
76
|
+
try {
|
|
77
|
+
const cleanVer = dep.currentVersion.replace(/^[\^~>=<v\s]+/, '').split(' ')[0] ?? '';
|
|
78
|
+
if (!cleanVer || cleanVer === '*' || cleanVer === 'latest')
|
|
79
|
+
return;
|
|
80
|
+
const controller = new AbortController();
|
|
81
|
+
const timer = setTimeout(() => controller.abort(), 2500);
|
|
82
|
+
// Encode package name (supports scoped packages @scope/pkg)
|
|
83
|
+
const encodedName = dep.name.startsWith('@')
|
|
84
|
+
? `@${encodeURIComponent(dep.name.slice(1))}`
|
|
85
|
+
: encodeURIComponent(dep.name);
|
|
86
|
+
const res = await fetch(`https://registry.npmjs.org/${encodedName}/latest`, {
|
|
87
|
+
headers: {
|
|
88
|
+
'User-Agent': 'Fathom-Repository-Intelligence/0.1.0',
|
|
89
|
+
},
|
|
90
|
+
signal: controller.signal,
|
|
91
|
+
});
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
if (res.ok) {
|
|
94
|
+
const data = (await res.json());
|
|
95
|
+
if (data.version && data.version !== cleanVer) {
|
|
96
|
+
const latestMajor = parseInt(data.version.split('.')[0] ?? '0', 10);
|
|
97
|
+
const currentMajor = parseInt(cleanVer.split('.')[0] ?? '0', 10);
|
|
98
|
+
// Only flag if latest major is strictly greater or multiple minor versions behind
|
|
99
|
+
if (latestMajor > currentMajor) {
|
|
100
|
+
results.push({
|
|
101
|
+
packageName: dep.name,
|
|
102
|
+
currentVersion: cleanVer,
|
|
103
|
+
latestVersion: data.version,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
await Promise.allSettled(checks);
|
|
114
|
+
return results.sort((a, b) => a.packageName.localeCompare(b.packageName));
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=online.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"online.js","sourceRoot":"","sources":["../../../src/analyzers/dependencies/online.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type DependencyType = 'direct' | 'dev' | 'peer' | 'transitive';
|
|
2
|
+
export interface DeclaredDependency {
|
|
3
|
+
name: string;
|
|
4
|
+
versionSpec: string;
|
|
5
|
+
type: DependencyType;
|
|
6
|
+
manifestPath: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DuplicatePackage {
|
|
9
|
+
name: string;
|
|
10
|
+
versions: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface SuspiciousDependency {
|
|
13
|
+
name: string;
|
|
14
|
+
versionSpec: string;
|
|
15
|
+
reason: string;
|
|
16
|
+
manifestPath: string;
|
|
17
|
+
}
|
|
18
|
+
export interface UnusedDependency {
|
|
19
|
+
name: string;
|
|
20
|
+
manifestPath: string;
|
|
21
|
+
confidence: number;
|
|
22
|
+
}
|
|
23
|
+
export interface VulnerabilityAdvisory {
|
|
24
|
+
id: string;
|
|
25
|
+
packageName: string;
|
|
26
|
+
affectedVersion: string;
|
|
27
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
28
|
+
title: string;
|
|
29
|
+
url?: string | undefined;
|
|
30
|
+
}
|
|
31
|
+
export interface OutdatedDependency {
|
|
32
|
+
packageName: string;
|
|
33
|
+
currentVersion: string;
|
|
34
|
+
latestVersion: string;
|
|
35
|
+
}
|
|
36
|
+
export interface DependencyIntelligenceSummary {
|
|
37
|
+
manifests: string[];
|
|
38
|
+
lockfiles: string[];
|
|
39
|
+
directCount: number;
|
|
40
|
+
devCount: number;
|
|
41
|
+
transitiveCount: number;
|
|
42
|
+
duplicates: DuplicatePackage[];
|
|
43
|
+
suspicious: SuspiciousDependency[];
|
|
44
|
+
unused: UnusedDependency[];
|
|
45
|
+
vulnerabilities: VulnerabilityAdvisory[];
|
|
46
|
+
outdated: OutdatedDependency[];
|
|
47
|
+
isOnline: boolean;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/analyzers/dependencies/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,YAAY,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/analyzers/dependencies/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Analyzer } from '../../core/analyzer.js';
|
|
2
|
+
import type { RepositoryContext } from '../../core/context.js';
|
|
3
|
+
import type { AnalyzerResult } from '../../core/result.js';
|
|
4
|
+
export declare class DocumentationAnalyzer implements Analyzer {
|
|
5
|
+
readonly id = "documentation";
|
|
6
|
+
readonly name = "Documentation";
|
|
7
|
+
readonly category: "documentation";
|
|
8
|
+
readonly description = "Checks for README, LICENSE, CONTRIBUTING, and SECURITY documentation.";
|
|
9
|
+
analyze(context: RepositoryContext): Promise<AnalyzerResult>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/documentation/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,sBAAsB,CAAC;AAepE,qBAAa,qBAAsB,YAAW,QAAQ;IACpD,QAAQ,CAAC,EAAE,mBAAmB;IAC9B,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,QAAQ,EAAG,eAAe,CAAU;IAC7C,QAAQ,CAAC,WAAW,2EAA2E;IAEzF,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;CAgLnE"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { createFindingId } from '../../core/findings.js';
|
|
3
|
+
import { createTimer } from '../../utils/timing.js';
|
|
4
|
+
import { readFileSafe } from '../../utils/filesystem.js';
|
|
5
|
+
const README_NAMES = ['README.md', 'README.txt', 'README.rst', 'README', 'readme.md'];
|
|
6
|
+
const LICENSE_NAMES = ['LICENSE', 'LICENSE.md', 'LICENSE.txt', 'LICENCE', 'LICENCE.md', 'COPYING'];
|
|
7
|
+
const CONTRIBUTING_NAMES = ['CONTRIBUTING.md', 'CONTRIBUTING.txt', 'CONTRIBUTING'];
|
|
8
|
+
const SECURITY_NAMES = ['SECURITY.md', 'SECURITY.txt', 'SECURITY'];
|
|
9
|
+
const INSTALL_KEYWORDS = ['install', 'setup', 'getting started', 'prerequisites', 'requirement'];
|
|
10
|
+
const USAGE_KEYWORDS = ['usage', 'example', 'quickstart', 'quick start', 'how to use'];
|
|
11
|
+
const DESCRIPTION_MIN_LENGTH = 100; // README needs at least this many chars to be considered described
|
|
12
|
+
export class DocumentationAnalyzer {
|
|
13
|
+
id = 'documentation';
|
|
14
|
+
name = 'Documentation';
|
|
15
|
+
category = 'documentation';
|
|
16
|
+
description = 'Checks for README, LICENSE, CONTRIBUTING, and SECURITY documentation.';
|
|
17
|
+
async analyze(context) {
|
|
18
|
+
const elapsed = createTimer();
|
|
19
|
+
const findings = [];
|
|
20
|
+
const warnings = [];
|
|
21
|
+
const rootFileSet = new Set(context.rootFilenames);
|
|
22
|
+
// DOC-001: README exists
|
|
23
|
+
const readmeFile = README_NAMES.find((name) => rootFileSet.has(name) || context.files.some((f) => path.basename(f.relativePath) === name));
|
|
24
|
+
if (!readmeFile) {
|
|
25
|
+
findings.push({
|
|
26
|
+
id: createFindingId('DOC-001'),
|
|
27
|
+
ruleId: 'DOC-001',
|
|
28
|
+
category: 'documentation',
|
|
29
|
+
severity: 'medium',
|
|
30
|
+
title: 'No README found',
|
|
31
|
+
description: 'A README is the first thing developers see when they discover your project.',
|
|
32
|
+
recommendation: 'Create a README.md with project description, installation, and usage information.',
|
|
33
|
+
confidence: 0.99,
|
|
34
|
+
autoFixable: false,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Read README content for deeper checks
|
|
39
|
+
const readmePath = context.files.find((f) => path.basename(f.relativePath) === readmeFile)?.absolutePath;
|
|
40
|
+
if (readmePath) {
|
|
41
|
+
const content = await readFileSafe(readmePath, 256 * 1024);
|
|
42
|
+
if (content) {
|
|
43
|
+
const lower = content.toLowerCase();
|
|
44
|
+
// DOC-007: Has project description
|
|
45
|
+
if (content.length < DESCRIPTION_MIN_LENGTH) {
|
|
46
|
+
findings.push({
|
|
47
|
+
id: createFindingId('DOC-007'),
|
|
48
|
+
ruleId: 'DOC-007',
|
|
49
|
+
category: 'documentation',
|
|
50
|
+
severity: 'low',
|
|
51
|
+
title: 'README appears to be a stub',
|
|
52
|
+
description: 'The README is very short and may not adequately describe the project.',
|
|
53
|
+
recommendation: 'Expand the README with a project description, features, and goals.',
|
|
54
|
+
confidence: 0.8,
|
|
55
|
+
location: { file: readmeFile },
|
|
56
|
+
autoFixable: false,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// DOC-002: Installation instructions
|
|
60
|
+
if (!INSTALL_KEYWORDS.some((kw) => lower.includes(kw))) {
|
|
61
|
+
findings.push({
|
|
62
|
+
id: createFindingId('DOC-002'),
|
|
63
|
+
ruleId: 'DOC-002',
|
|
64
|
+
category: 'documentation',
|
|
65
|
+
severity: 'low',
|
|
66
|
+
title: 'README may be missing installation instructions',
|
|
67
|
+
description: 'Installation instructions help new contributors get started.',
|
|
68
|
+
recommendation: 'Add an "Installation" or "Getting Started" section to the README.',
|
|
69
|
+
confidence: 0.75,
|
|
70
|
+
location: { file: readmeFile },
|
|
71
|
+
autoFixable: false,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// DOC-003: Usage information
|
|
75
|
+
if (!USAGE_KEYWORDS.some((kw) => lower.includes(kw))) {
|
|
76
|
+
findings.push({
|
|
77
|
+
id: createFindingId('DOC-003'),
|
|
78
|
+
ruleId: 'DOC-003',
|
|
79
|
+
category: 'documentation',
|
|
80
|
+
severity: 'low',
|
|
81
|
+
title: 'README may be missing usage information',
|
|
82
|
+
description: 'Usage examples help developers understand how to use your project.',
|
|
83
|
+
recommendation: 'Add a "Usage" or "Examples" section to the README.',
|
|
84
|
+
confidence: 0.75,
|
|
85
|
+
location: { file: readmeFile },
|
|
86
|
+
autoFixable: false,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const hasDocFile = (names) => names.some((name) => rootFileSet.has(name) ||
|
|
93
|
+
context.files.some((f) => f.relativePath === name ||
|
|
94
|
+
f.relativePath === `.github/${name}` ||
|
|
95
|
+
f.relativePath === `docs/${name}`));
|
|
96
|
+
// DOC-004: LICENSE
|
|
97
|
+
const hasLicense = hasDocFile(LICENSE_NAMES);
|
|
98
|
+
if (!hasLicense) {
|
|
99
|
+
findings.push({
|
|
100
|
+
id: createFindingId('DOC-004'),
|
|
101
|
+
ruleId: 'DOC-004',
|
|
102
|
+
category: 'documentation',
|
|
103
|
+
severity: 'medium',
|
|
104
|
+
title: 'No LICENSE file found',
|
|
105
|
+
description: 'Without a license, the project defaults to "all rights reserved" which prevents others from contributing or using it.',
|
|
106
|
+
recommendation: 'Add a LICENSE file. choosealicense.com can help you pick the right one.',
|
|
107
|
+
confidence: 0.99,
|
|
108
|
+
autoFixable: false,
|
|
109
|
+
references: ['https://choosealicense.com'],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
// DOC-005: CONTRIBUTING
|
|
113
|
+
const hasContributing = hasDocFile(CONTRIBUTING_NAMES);
|
|
114
|
+
if (!hasContributing) {
|
|
115
|
+
findings.push({
|
|
116
|
+
id: createFindingId('DOC-005'),
|
|
117
|
+
ruleId: 'DOC-005',
|
|
118
|
+
category: 'documentation',
|
|
119
|
+
severity: 'low',
|
|
120
|
+
title: 'No CONTRIBUTING guide found',
|
|
121
|
+
description: 'A CONTRIBUTING guide helps new contributors understand how to participate.',
|
|
122
|
+
recommendation: 'Create a CONTRIBUTING.md explaining how to submit issues and pull requests.',
|
|
123
|
+
confidence: 0.99,
|
|
124
|
+
autoFixable: false,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// DOC-006: SECURITY
|
|
128
|
+
const hasSecurity = hasDocFile(SECURITY_NAMES);
|
|
129
|
+
if (!hasSecurity) {
|
|
130
|
+
findings.push({
|
|
131
|
+
id: createFindingId('DOC-006'),
|
|
132
|
+
ruleId: 'DOC-006',
|
|
133
|
+
category: 'documentation',
|
|
134
|
+
severity: 'low',
|
|
135
|
+
title: 'No SECURITY policy found',
|
|
136
|
+
description: 'A SECURITY policy tells users how to responsibly report vulnerabilities.',
|
|
137
|
+
recommendation: 'Create a SECURITY.md with your vulnerability disclosure process.',
|
|
138
|
+
confidence: 0.99,
|
|
139
|
+
autoFixable: false,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const metrics = {
|
|
143
|
+
hasReadme: !!readmeFile,
|
|
144
|
+
hasLicense,
|
|
145
|
+
hasContributing,
|
|
146
|
+
hasSecurityPolicy: hasSecurity,
|
|
147
|
+
documentationFiles: [
|
|
148
|
+
readmeFile,
|
|
149
|
+
hasLicense ? 'LICENSE' : null,
|
|
150
|
+
hasContributing ? 'CONTRIBUTING.md' : null,
|
|
151
|
+
hasSecurity ? 'SECURITY.md' : null,
|
|
152
|
+
].filter(Boolean).length,
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
analyzerId: this.id,
|
|
156
|
+
analyzerName: this.name,
|
|
157
|
+
category: this.category,
|
|
158
|
+
status: 'success',
|
|
159
|
+
findings,
|
|
160
|
+
metrics,
|
|
161
|
+
durationMs: elapsed(),
|
|
162
|
+
warnings,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/documentation/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Analyzer } from '../../core/analyzer.js';
|
|
2
|
+
import type { RepositoryContext } from '../../core/context.js';
|
|
3
|
+
import type { AnalyzerResult } from '../../core/result.js';
|
|
4
|
+
export declare class GitAnalyzer implements Analyzer {
|
|
5
|
+
readonly id = "git";
|
|
6
|
+
readonly name = "Git";
|
|
7
|
+
readonly category: "git";
|
|
8
|
+
readonly description = "Checks Git repository hygiene, .gitignore configuration, and file tracking.";
|
|
9
|
+
analyze(context: RepositoryContext): Promise<AnalyzerResult>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/git/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,sBAAsB,CAAC;AAqBpE,qBAAa,WAAY,YAAW,QAAQ;IAC1C,QAAQ,CAAC,EAAE,SAAS;IACpB,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,QAAQ,EAAG,KAAK,CAAU;IACnC,QAAQ,CAAC,WAAW,iFAC4D;IAE1E,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;CAsKnE"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { createFindingId } from '../../core/findings.js';
|
|
2
|
+
import { createTimer } from '../../utils/timing.js';
|
|
3
|
+
import { hasUncommittedChanges, isPathMentionedInGitignore } from '../../utils/git.js';
|
|
4
|
+
const GENERATED_DIRS = [
|
|
5
|
+
'node_modules',
|
|
6
|
+
'dist',
|
|
7
|
+
'build',
|
|
8
|
+
'coverage',
|
|
9
|
+
'.next',
|
|
10
|
+
'.nuxt',
|
|
11
|
+
'target',
|
|
12
|
+
'vendor',
|
|
13
|
+
'__pycache__',
|
|
14
|
+
'.cache',
|
|
15
|
+
];
|
|
16
|
+
const LARGE_FILE_THRESHOLD_BYTES = 10 * 1024 * 1024; // 10 MB
|
|
17
|
+
export class GitAnalyzer {
|
|
18
|
+
id = 'git';
|
|
19
|
+
name = 'Git';
|
|
20
|
+
category = 'git';
|
|
21
|
+
description = 'Checks Git repository hygiene, .gitignore configuration, and file tracking.';
|
|
22
|
+
async analyze(context) {
|
|
23
|
+
const elapsed = createTimer();
|
|
24
|
+
const findings = [];
|
|
25
|
+
const warnings = [];
|
|
26
|
+
// GIT-001: Is this a Git repository?
|
|
27
|
+
if (!context.git.isRepository) {
|
|
28
|
+
findings.push({
|
|
29
|
+
id: createFindingId('GIT-001'),
|
|
30
|
+
ruleId: 'GIT-001',
|
|
31
|
+
category: 'git',
|
|
32
|
+
severity: 'medium',
|
|
33
|
+
title: 'Not a Git repository',
|
|
34
|
+
description: 'This directory does not appear to be tracked by Git.',
|
|
35
|
+
recommendation: 'Run `git init` to initialize a Git repository.',
|
|
36
|
+
confidence: 0.99,
|
|
37
|
+
autoFixable: false,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
analyzerId: this.id,
|
|
41
|
+
analyzerName: this.name,
|
|
42
|
+
category: this.category,
|
|
43
|
+
status: 'success',
|
|
44
|
+
findings,
|
|
45
|
+
metrics: { isGitRepository: false },
|
|
46
|
+
durationMs: elapsed(),
|
|
47
|
+
warnings,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// GIT-002: .gitignore exists
|
|
51
|
+
if (!context.git.hasGitignore) {
|
|
52
|
+
findings.push({
|
|
53
|
+
id: createFindingId('GIT-002'),
|
|
54
|
+
ruleId: 'GIT-002',
|
|
55
|
+
category: 'git',
|
|
56
|
+
severity: 'medium',
|
|
57
|
+
title: 'No .gitignore found',
|
|
58
|
+
description: 'A .gitignore file helps prevent generated files and secrets from being committed.',
|
|
59
|
+
recommendation: 'Create a .gitignore appropriate for your project type.',
|
|
60
|
+
confidence: 0.99,
|
|
61
|
+
autoFixable: false,
|
|
62
|
+
references: ['https://git-scm.com/docs/gitignore', 'https://gitignore.io'],
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else if (context.git.gitignoreContent) {
|
|
66
|
+
// GIT-003: Check that common generated dirs are gitignored
|
|
67
|
+
const gitignore = context.git.gitignoreContent;
|
|
68
|
+
const notIgnored = [];
|
|
69
|
+
for (const dir of GENERATED_DIRS) {
|
|
70
|
+
// Only flag dirs that are actually relevant (present or implied by ecosystem)
|
|
71
|
+
const isNodeProject = context.languages.some((l) => l.name === 'Node.js');
|
|
72
|
+
const isJavaProject = context.languages.some((l) => l.name === 'Java');
|
|
73
|
+
const isPythonProject = context.languages.some((l) => l.name === 'Python');
|
|
74
|
+
if (dir === 'node_modules' && !isNodeProject)
|
|
75
|
+
continue;
|
|
76
|
+
if (dir === 'target' && !isJavaProject)
|
|
77
|
+
continue;
|
|
78
|
+
if (dir === '__pycache__' && !isPythonProject)
|
|
79
|
+
continue;
|
|
80
|
+
// For framework-specific directories, only check if framework is present or dir exists
|
|
81
|
+
if (dir === '.next') {
|
|
82
|
+
const isNext = context.frameworks.some((f) => f.name === 'Next.js');
|
|
83
|
+
const hasNextDir = context.files.some((f) => f.relativePath.startsWith('.next/'));
|
|
84
|
+
if (!isNext && !hasNextDir)
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (dir === '.nuxt') {
|
|
88
|
+
const isNuxt = context.frameworks.some((f) => f.name === 'Nuxt');
|
|
89
|
+
const hasNuxtDir = context.files.some((f) => f.relativePath.startsWith('.nuxt/'));
|
|
90
|
+
if (!isNuxt && !hasNuxtDir)
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (!isPathMentionedInGitignore(gitignore, dir)) {
|
|
94
|
+
notIgnored.push(dir);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (notIgnored.length > 0) {
|
|
98
|
+
findings.push({
|
|
99
|
+
id: createFindingId('GIT-003'),
|
|
100
|
+
ruleId: 'GIT-003',
|
|
101
|
+
category: 'git',
|
|
102
|
+
severity: 'medium',
|
|
103
|
+
title: 'Generated directories may not be gitignored',
|
|
104
|
+
description: `The following directories may not be in .gitignore: ${notIgnored.join(', ')}`,
|
|
105
|
+
recommendation: `Add these to .gitignore: ${notIgnored.map((d) => `\`${d}\``).join(', ')}`,
|
|
106
|
+
confidence: 0.75,
|
|
107
|
+
autoFixable: false,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// GIT-004: Large files
|
|
112
|
+
const largeFiles = context.files.filter((f) => f.sizeBytes >= LARGE_FILE_THRESHOLD_BYTES);
|
|
113
|
+
if (largeFiles.length > 0) {
|
|
114
|
+
for (const lf of largeFiles) {
|
|
115
|
+
const sizeMb = (lf.sizeBytes / (1024 * 1024)).toFixed(1);
|
|
116
|
+
findings.push({
|
|
117
|
+
id: createFindingId('GIT-004', lf.relativePath),
|
|
118
|
+
ruleId: 'GIT-004',
|
|
119
|
+
category: 'git',
|
|
120
|
+
severity: 'medium',
|
|
121
|
+
title: `Large file: ${lf.relativePath}`,
|
|
122
|
+
description: `This file is ${sizeMb} MB. Large files tracked in Git increase repository size and slow clones.`,
|
|
123
|
+
recommendation: 'Consider using Git LFS or excluding this file from the repository.',
|
|
124
|
+
confidence: 0.99,
|
|
125
|
+
location: { file: lf.relativePath },
|
|
126
|
+
evidence: `${sizeMb} MB`,
|
|
127
|
+
autoFixable: false,
|
|
128
|
+
references: ['https://git-lfs.github.com'],
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// GIT-005: Uncommitted changes
|
|
133
|
+
const hasChanges = await hasUncommittedChanges(context.root);
|
|
134
|
+
if (hasChanges) {
|
|
135
|
+
findings.push({
|
|
136
|
+
id: createFindingId('GIT-005'),
|
|
137
|
+
ruleId: 'GIT-005',
|
|
138
|
+
category: 'git',
|
|
139
|
+
severity: 'info',
|
|
140
|
+
title: 'Uncommitted changes detected',
|
|
141
|
+
description: 'The working directory has uncommitted changes. This is informational.',
|
|
142
|
+
recommendation: 'Commit or stash changes before shipping.',
|
|
143
|
+
confidence: 0.99,
|
|
144
|
+
autoFixable: false,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
// GIT-006: Empty repository
|
|
148
|
+
if (!context.git.hasCommits) {
|
|
149
|
+
findings.push({
|
|
150
|
+
id: createFindingId('GIT-006'),
|
|
151
|
+
ruleId: 'GIT-006',
|
|
152
|
+
category: 'git',
|
|
153
|
+
severity: 'info',
|
|
154
|
+
title: 'Repository has no commits',
|
|
155
|
+
description: 'This Git repository does not have any commits yet.',
|
|
156
|
+
recommendation: 'Make an initial commit to begin tracking history.',
|
|
157
|
+
confidence: 0.99,
|
|
158
|
+
autoFixable: false,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const metrics = {
|
|
162
|
+
isGitRepository: true,
|
|
163
|
+
hasGitignore: context.git.hasGitignore,
|
|
164
|
+
hasCommits: context.git.hasCommits,
|
|
165
|
+
hasUncommittedChanges: hasChanges,
|
|
166
|
+
largeFilesCount: largeFiles.length,
|
|
167
|
+
};
|
|
168
|
+
return {
|
|
169
|
+
analyzerId: this.id,
|
|
170
|
+
analyzerName: this.name,
|
|
171
|
+
category: this.category,
|
|
172
|
+
status: 'success',
|
|
173
|
+
findings,
|
|
174
|
+
metrics,
|
|
175
|
+
durationMs: elapsed(),
|
|
176
|
+
warnings,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/git/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Analyzer } from '../../core/analyzer.js';
|
|
2
|
+
import type { RepositoryContext } from '../../core/context.js';
|
|
3
|
+
import type { AnalyzerResult } from '../../core/result.js';
|
|
4
|
+
export declare class ProjectAnalyzer implements Analyzer {
|
|
5
|
+
readonly id = "project";
|
|
6
|
+
readonly name = "Project";
|
|
7
|
+
readonly category: "project";
|
|
8
|
+
readonly description = "Detects ecosystems, frameworks, package managers, and repository size.";
|
|
9
|
+
analyze(context: RepositoryContext): Promise<AnalyzerResult>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,sBAAsB,CAAC;AAKpE,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,EAAE,aAAa;IACxB,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,QAAQ,EAAG,SAAS,CAAU;IACvC,QAAQ,CAAC,WAAW,4EAA4E;IAE1F,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;CA6FnE"}
|