@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,134 @@
|
|
|
1
|
+
import { createFindingId } from '../../core/findings.js';
|
|
2
|
+
import { createTimer } from '../../utils/timing.js';
|
|
3
|
+
const TEST_DIR_NAMES = new Set([
|
|
4
|
+
'test',
|
|
5
|
+
'tests',
|
|
6
|
+
'__tests__',
|
|
7
|
+
'spec',
|
|
8
|
+
'specs',
|
|
9
|
+
'e2e',
|
|
10
|
+
'integration',
|
|
11
|
+
'unit',
|
|
12
|
+
'test-utils',
|
|
13
|
+
'testing',
|
|
14
|
+
]);
|
|
15
|
+
/**
|
|
16
|
+
* Common test script names in package.json scripts.
|
|
17
|
+
*/
|
|
18
|
+
const TEST_SCRIPT_NAMES = [
|
|
19
|
+
'test',
|
|
20
|
+
'test:unit',
|
|
21
|
+
'test:integration',
|
|
22
|
+
'test:e2e',
|
|
23
|
+
'vitest',
|
|
24
|
+
'jest',
|
|
25
|
+
'mocha',
|
|
26
|
+
'jasmine',
|
|
27
|
+
];
|
|
28
|
+
export class TestingAnalyzer {
|
|
29
|
+
id = 'testing';
|
|
30
|
+
name = 'Testing';
|
|
31
|
+
category = 'testing';
|
|
32
|
+
description = 'Checks for test infrastructure: directories, test files, and test scripts.';
|
|
33
|
+
async analyze(context) {
|
|
34
|
+
const elapsed = createTimer();
|
|
35
|
+
const findings = [];
|
|
36
|
+
const warnings = [];
|
|
37
|
+
const testFiles = context.files.filter((f) => f.isTest);
|
|
38
|
+
const sourceFiles = context.files.filter((f) => f.isSource && !f.isTest);
|
|
39
|
+
// TEST-001: Test directories
|
|
40
|
+
const allDirs = new Set();
|
|
41
|
+
for (const file of context.files) {
|
|
42
|
+
const parts = file.relativePath.split('/');
|
|
43
|
+
for (let i = 1; i < parts.length; i++) {
|
|
44
|
+
allDirs.add(parts[i - 1] ?? '');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const testDirs = [...allDirs].filter((d) => TEST_DIR_NAMES.has(d.toLowerCase()));
|
|
48
|
+
if (testDirs.length === 0 && context.files.filter((f) => f.isSource).length > 0) {
|
|
49
|
+
findings.push({
|
|
50
|
+
id: createFindingId('TEST-001'),
|
|
51
|
+
ruleId: 'TEST-001',
|
|
52
|
+
category: 'testing',
|
|
53
|
+
severity: 'low',
|
|
54
|
+
title: 'No standard test directory found',
|
|
55
|
+
description: 'No directories matching common test naming conventions (test, tests, __tests__, spec, etc.) were detected.',
|
|
56
|
+
recommendation: 'Create a test directory and add tests for your source code.',
|
|
57
|
+
confidence: 0.8,
|
|
58
|
+
autoFixable: false,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// TEST-002: Test files
|
|
62
|
+
if (testFiles.length === 0) {
|
|
63
|
+
findings.push({
|
|
64
|
+
id: createFindingId('TEST-002'),
|
|
65
|
+
ruleId: 'TEST-002',
|
|
66
|
+
category: 'testing',
|
|
67
|
+
severity: 'medium',
|
|
68
|
+
title: 'No test files detected',
|
|
69
|
+
description: 'No files matching common test naming conventions were found.',
|
|
70
|
+
recommendation: 'Add tests for your source code to improve reliability.',
|
|
71
|
+
confidence: 0.85,
|
|
72
|
+
autoFixable: false,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// TEST-003: Test scripts in package.json
|
|
76
|
+
let hasTestScript = false;
|
|
77
|
+
if (context.manifests.packageJson?.scripts) {
|
|
78
|
+
const scripts = context.manifests.packageJson.scripts;
|
|
79
|
+
hasTestScript = TEST_SCRIPT_NAMES.some((name) => name in scripts);
|
|
80
|
+
if (!hasTestScript) {
|
|
81
|
+
findings.push({
|
|
82
|
+
id: createFindingId('TEST-003'),
|
|
83
|
+
ruleId: 'TEST-003',
|
|
84
|
+
category: 'testing',
|
|
85
|
+
severity: 'medium',
|
|
86
|
+
title: 'No test script in package.json',
|
|
87
|
+
description: 'A "test" script makes it easy to run tests consistently.',
|
|
88
|
+
recommendation: 'Add a "test" script to package.json.',
|
|
89
|
+
confidence: 0.9,
|
|
90
|
+
location: { file: 'package.json' },
|
|
91
|
+
autoFixable: false,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// TEST-004: Test-to-source ratio heuristic
|
|
96
|
+
const ratio = sourceFiles.length > 0 ? testFiles.length / sourceFiles.length : 0;
|
|
97
|
+
let ratioSeverity = 'info';
|
|
98
|
+
if (ratio === 0 && sourceFiles.length > 5)
|
|
99
|
+
ratioSeverity = 'medium';
|
|
100
|
+
else if (ratio < 0.1 && sourceFiles.length > 10)
|
|
101
|
+
ratioSeverity = 'low';
|
|
102
|
+
if (ratio < 0.1 && sourceFiles.length > 5) {
|
|
103
|
+
findings.push({
|
|
104
|
+
id: createFindingId('TEST-004', 'ratio'),
|
|
105
|
+
ruleId: 'TEST-004',
|
|
106
|
+
category: 'testing',
|
|
107
|
+
severity: ratioSeverity,
|
|
108
|
+
title: 'Low test-to-source file ratio',
|
|
109
|
+
description: `Test files represent only ${(ratio * 100).toFixed(0)}% of source files (${testFiles.length} tests vs ${sourceFiles.length} source files).`,
|
|
110
|
+
recommendation: 'Increase test coverage for critical application logic.',
|
|
111
|
+
confidence: 0.7,
|
|
112
|
+
autoFixable: false,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const metrics = {
|
|
116
|
+
testFiles: testFiles.length,
|
|
117
|
+
sourceFiles: sourceFiles.length,
|
|
118
|
+
testDirs: testDirs,
|
|
119
|
+
hasTestScript,
|
|
120
|
+
testToSourceRatio: +ratio.toFixed(2),
|
|
121
|
+
};
|
|
122
|
+
return {
|
|
123
|
+
analyzerId: this.id,
|
|
124
|
+
analyzerName: this.name,
|
|
125
|
+
category: this.category,
|
|
126
|
+
status: 'success',
|
|
127
|
+
findings,
|
|
128
|
+
metrics,
|
|
129
|
+
durationMs: elapsed(),
|
|
130
|
+
warnings,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/testing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AnalysisResult } from '../core/result.js';
|
|
2
|
+
import type { BaselineData } from './types.js';
|
|
3
|
+
export declare const CURRENT_BASELINE_SCHEMA_VERSION = "1.0";
|
|
4
|
+
export declare const BASELINE_DIR_NAME = ".fathom";
|
|
5
|
+
export declare const BASELINE_FILE_NAME = "baseline.json";
|
|
6
|
+
/**
|
|
7
|
+
* Get the absolute path to the baseline file for a given repository root.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getBaselinePath(repositoryRoot: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Save an AnalysisResult as a deterministic baseline file in .fathom/baseline.json.
|
|
12
|
+
*/
|
|
13
|
+
export declare function saveBaseline(repositoryRoot: string, result: AnalysisResult): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Load and validate .fathom/baseline.json from a repository root.
|
|
16
|
+
* Throws FathomBaselineMissingError if missing.
|
|
17
|
+
* Throws FathomBaselineCorruptError if malformed or invalid schema.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadBaseline(repositoryRoot: string): Promise<BaselineData>;
|
|
20
|
+
//# sourceMappingURL=baseline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/baseline/baseline.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,eAAO,MAAM,+BAA+B,QAAQ,CAAC;AACrD,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD;;GAEG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE9D;AAqCD;;GAEG;AACH,wBAAsB,YAAY,CAChC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAmDhF"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { FathomBaselineMissingError, FathomBaselineCorruptError } from '../core/errors.js';
|
|
4
|
+
export const CURRENT_BASELINE_SCHEMA_VERSION = '1.0';
|
|
5
|
+
export const BASELINE_DIR_NAME = '.fathom';
|
|
6
|
+
export const BASELINE_FILE_NAME = 'baseline.json';
|
|
7
|
+
/**
|
|
8
|
+
* Get the absolute path to the baseline file for a given repository root.
|
|
9
|
+
*/
|
|
10
|
+
export function getBaselinePath(repositoryRoot) {
|
|
11
|
+
return path.resolve(repositoryRoot, BASELINE_DIR_NAME, BASELINE_FILE_NAME);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Sanitize a finding for baseline storage.
|
|
15
|
+
* Ensures evidence never contains secrets and repository code is never stored.
|
|
16
|
+
*/
|
|
17
|
+
function sanitizeFindingForBaseline(f) {
|
|
18
|
+
const finding = {
|
|
19
|
+
id: f.id,
|
|
20
|
+
ruleId: f.ruleId,
|
|
21
|
+
category: f.category,
|
|
22
|
+
severity: f.severity,
|
|
23
|
+
title: f.title,
|
|
24
|
+
description: f.description,
|
|
25
|
+
recommendation: f.recommendation,
|
|
26
|
+
confidence: f.confidence,
|
|
27
|
+
autoFixable: f.autoFixable,
|
|
28
|
+
};
|
|
29
|
+
if (f.location) {
|
|
30
|
+
finding.location = {};
|
|
31
|
+
if (f.location.file !== undefined)
|
|
32
|
+
finding.location.file = f.location.file;
|
|
33
|
+
if (f.location.line !== undefined)
|
|
34
|
+
finding.location.line = f.location.line;
|
|
35
|
+
if (f.location.column !== undefined)
|
|
36
|
+
finding.location.column = f.location.column;
|
|
37
|
+
}
|
|
38
|
+
if (f.evidence) {
|
|
39
|
+
finding.evidence = f.evidence.slice(0, 200);
|
|
40
|
+
}
|
|
41
|
+
if (f.references) {
|
|
42
|
+
finding.references = [...f.references];
|
|
43
|
+
}
|
|
44
|
+
return finding;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Save an AnalysisResult as a deterministic baseline file in .fathom/baseline.json.
|
|
48
|
+
*/
|
|
49
|
+
export async function saveBaseline(repositoryRoot, result) {
|
|
50
|
+
const baselinePath = getBaselinePath(repositoryRoot);
|
|
51
|
+
const baselineDir = path.dirname(baselinePath);
|
|
52
|
+
// Ensure .fathom directory exists
|
|
53
|
+
await fs.mkdir(baselineDir, { recursive: true });
|
|
54
|
+
// Map analyzer metrics
|
|
55
|
+
const metrics = {};
|
|
56
|
+
for (const analyzer of result.analyzers) {
|
|
57
|
+
metrics[analyzer.analyzerId] = analyzer.metrics;
|
|
58
|
+
}
|
|
59
|
+
const baselineData = {
|
|
60
|
+
schemaVersion: CURRENT_BASELINE_SCHEMA_VERSION,
|
|
61
|
+
fathomVersion: result.fathomVersion,
|
|
62
|
+
createdAt: result.timestamp,
|
|
63
|
+
repositoryPath: path.basename(result.repositoryPath),
|
|
64
|
+
score: {
|
|
65
|
+
overall: result.score.overall,
|
|
66
|
+
band: result.score.band,
|
|
67
|
+
categories: result.score.categories.map((c) => ({
|
|
68
|
+
category: c.category,
|
|
69
|
+
score: c.score,
|
|
70
|
+
maxScore: c.maxScore,
|
|
71
|
+
weight: c.weight,
|
|
72
|
+
findingCount: c.findingCount,
|
|
73
|
+
})),
|
|
74
|
+
},
|
|
75
|
+
// Sort findings stably by ruleId and file for deterministic output
|
|
76
|
+
findings: result.findings.map(sanitizeFindingForBaseline).sort((a, b) => {
|
|
77
|
+
const cmpRule = a.ruleId.localeCompare(b.ruleId);
|
|
78
|
+
if (cmpRule !== 0)
|
|
79
|
+
return cmpRule;
|
|
80
|
+
const fileA = a.location?.file ?? '';
|
|
81
|
+
const fileB = b.location?.file ?? '';
|
|
82
|
+
return fileA.localeCompare(fileB);
|
|
83
|
+
}),
|
|
84
|
+
metrics,
|
|
85
|
+
};
|
|
86
|
+
const json = JSON.stringify(baselineData, null, 2);
|
|
87
|
+
await fs.writeFile(baselinePath, json + '\n', 'utf8');
|
|
88
|
+
return baselinePath;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Load and validate .fathom/baseline.json from a repository root.
|
|
92
|
+
* Throws FathomBaselineMissingError if missing.
|
|
93
|
+
* Throws FathomBaselineCorruptError if malformed or invalid schema.
|
|
94
|
+
*/
|
|
95
|
+
export async function loadBaseline(repositoryRoot) {
|
|
96
|
+
const baselinePath = getBaselinePath(repositoryRoot);
|
|
97
|
+
let rawContent;
|
|
98
|
+
try {
|
|
99
|
+
rawContent = await fs.readFile(baselinePath, 'utf8');
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const error = err;
|
|
103
|
+
if (error?.code === 'ENOENT') {
|
|
104
|
+
throw new FathomBaselineMissingError(baselinePath);
|
|
105
|
+
}
|
|
106
|
+
throw new FathomBaselineCorruptError(baselinePath, `Cannot read baseline file (${error?.message ?? String(err)})`);
|
|
107
|
+
}
|
|
108
|
+
let parsed;
|
|
109
|
+
try {
|
|
110
|
+
parsed = JSON.parse(rawContent);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
throw new FathomBaselineCorruptError(baselinePath, 'File contains invalid JSON syntax');
|
|
114
|
+
}
|
|
115
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
116
|
+
throw new FathomBaselineCorruptError(baselinePath, 'Expected a root JSON object');
|
|
117
|
+
}
|
|
118
|
+
const data = parsed;
|
|
119
|
+
// Validate required schema fields
|
|
120
|
+
if (!data.schemaVersion || typeof data.schemaVersion !== 'string') {
|
|
121
|
+
throw new FathomBaselineCorruptError(baselinePath, 'Missing or invalid "schemaVersion" field');
|
|
122
|
+
}
|
|
123
|
+
if (!data.score || typeof data.score !== 'object' || typeof data.score.overall !== 'number') {
|
|
124
|
+
throw new FathomBaselineCorruptError(baselinePath, 'Missing or invalid "score" object');
|
|
125
|
+
}
|
|
126
|
+
if (!Array.isArray(data.score.categories)) {
|
|
127
|
+
throw new FathomBaselineCorruptError(baselinePath, 'Missing or invalid "score.categories" array');
|
|
128
|
+
}
|
|
129
|
+
if (!Array.isArray(data.findings)) {
|
|
130
|
+
throw new FathomBaselineCorruptError(baselinePath, 'Missing or invalid "findings" array');
|
|
131
|
+
}
|
|
132
|
+
return data;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/baseline/baseline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AnalysisResult } from '../core/result.js';
|
|
2
|
+
import type { Finding } from '../core/findings.js';
|
|
3
|
+
import type { BaselineData, ComparisonResult } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generate a stable identity key for a finding.
|
|
6
|
+
* Uses ruleId, normalized file path, and title.
|
|
7
|
+
* Excludes line numbers so that line shifts in source files do not produce false diffs.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getStableFindingKey(finding: Finding): string;
|
|
10
|
+
/**
|
|
11
|
+
* Compare a current AnalysisResult against a loaded BaselineData.
|
|
12
|
+
*/
|
|
13
|
+
export declare function compareWithBaseline(currentResult: AnalysisResult, baseline: BaselineData): ComparisonResult;
|
|
14
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/baseline/compare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAqB,gBAAgB,EAAiB,MAAM,YAAY,CAAC;AAEnG;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAK5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,cAAc,EAC7B,QAAQ,EAAE,YAAY,GACrB,gBAAgB,CAqHlB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a stable identity key for a finding.
|
|
3
|
+
* Uses ruleId, normalized file path, and title.
|
|
4
|
+
* Excludes line numbers so that line shifts in source files do not produce false diffs.
|
|
5
|
+
*/
|
|
6
|
+
export function getStableFindingKey(finding) {
|
|
7
|
+
const fileKey = finding.location?.file
|
|
8
|
+
? finding.location.file.replace(/\\/g, '/').toLowerCase()
|
|
9
|
+
: '__nofile__';
|
|
10
|
+
return `${finding.ruleId}:${fileKey}:${finding.title}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compare a current AnalysisResult against a loaded BaselineData.
|
|
14
|
+
*/
|
|
15
|
+
export function compareWithBaseline(currentResult, baseline) {
|
|
16
|
+
const currentScore = currentResult.score.overall;
|
|
17
|
+
const baselineScore = baseline.score.overall;
|
|
18
|
+
const scoreDelta = currentScore - baselineScore;
|
|
19
|
+
// 1. Compare category scores
|
|
20
|
+
const categoryDiffs = [];
|
|
21
|
+
const baselineCategoryMap = new Map(baseline.score.categories.map((c) => [c.category, c.score]));
|
|
22
|
+
for (const currentCat of currentResult.score.categories) {
|
|
23
|
+
const baseCatScore = baselineCategoryMap.get(currentCat.category) ?? 100;
|
|
24
|
+
categoryDiffs.push({
|
|
25
|
+
category: currentCat.category,
|
|
26
|
+
baselineScore: baseCatScore,
|
|
27
|
+
currentScore: currentCat.score,
|
|
28
|
+
delta: currentCat.score - baseCatScore,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// 2. Stable 1-to-1 Finding Diffing
|
|
32
|
+
// Group by stable key
|
|
33
|
+
const baselineBuckets = new Map();
|
|
34
|
+
for (const finding of baseline.findings) {
|
|
35
|
+
const key = getStableFindingKey(finding);
|
|
36
|
+
const bucket = baselineBuckets.get(key) ?? [];
|
|
37
|
+
bucket.push(finding);
|
|
38
|
+
baselineBuckets.set(key, bucket);
|
|
39
|
+
}
|
|
40
|
+
const currentBuckets = new Map();
|
|
41
|
+
for (const finding of currentResult.findings) {
|
|
42
|
+
const key = getStableFindingKey(finding);
|
|
43
|
+
const bucket = currentBuckets.get(key) ?? [];
|
|
44
|
+
bucket.push(finding);
|
|
45
|
+
currentBuckets.set(key, bucket);
|
|
46
|
+
}
|
|
47
|
+
const newFindings = [];
|
|
48
|
+
const resolvedFindings = [];
|
|
49
|
+
const unchangedFindings = [];
|
|
50
|
+
const changedFindings = [];
|
|
51
|
+
// Union of all unique keys
|
|
52
|
+
const allKeys = new Set([...baselineBuckets.keys(), ...currentBuckets.keys()]);
|
|
53
|
+
for (const key of allKeys) {
|
|
54
|
+
const baseList = baselineBuckets.get(key) ?? [];
|
|
55
|
+
const currList = currentBuckets.get(key) ?? [];
|
|
56
|
+
const commonCount = Math.min(baseList.length, currList.length);
|
|
57
|
+
// Compare paired findings
|
|
58
|
+
for (let i = 0; i < commonCount; i++) {
|
|
59
|
+
const baseFinding = baseList[i];
|
|
60
|
+
const currFinding = currList[i];
|
|
61
|
+
if (!baseFinding || !currFinding)
|
|
62
|
+
continue;
|
|
63
|
+
const severityChanged = currFinding.severity !== baseFinding.severity;
|
|
64
|
+
const confidenceChanged = Math.abs(currFinding.confidence - baseFinding.confidence) > 0.05;
|
|
65
|
+
if (severityChanged || confidenceChanged) {
|
|
66
|
+
changedFindings.push({
|
|
67
|
+
current: currFinding,
|
|
68
|
+
baseline: baseFinding,
|
|
69
|
+
severityChanged,
|
|
70
|
+
confidenceChanged,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
unchangedFindings.push(currFinding);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Surplus in current -> newly introduced
|
|
78
|
+
if (currList.length > commonCount) {
|
|
79
|
+
newFindings.push(...currList.slice(commonCount));
|
|
80
|
+
}
|
|
81
|
+
// Surplus in baseline -> resolved
|
|
82
|
+
if (baseList.length > commonCount) {
|
|
83
|
+
resolvedFindings.push(...baseList.slice(commonCount));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// 3. Determine if regression occurred
|
|
87
|
+
// Regression is flagged if:
|
|
88
|
+
// - Overall score decreased
|
|
89
|
+
// - Any individual category score decreased
|
|
90
|
+
// - Newly introduced critical or high severity finding
|
|
91
|
+
// - Existing finding escalated to critical or high severity
|
|
92
|
+
const scoreDecreased = scoreDelta < 0;
|
|
93
|
+
const anyCategoryDecreased = categoryDiffs.some((d) => d.delta < 0);
|
|
94
|
+
const newCriticalOrHigh = newFindings.some((f) => f.severity === 'critical' || f.severity === 'high');
|
|
95
|
+
const escalatedToCriticalOrHigh = changedFindings.some((cf) => (cf.current.severity === 'critical' || cf.current.severity === 'high') &&
|
|
96
|
+
cf.baseline.severity !== 'critical' &&
|
|
97
|
+
cf.baseline.severity !== 'high');
|
|
98
|
+
const isRegression = scoreDecreased || anyCategoryDecreased || newCriticalOrHigh || escalatedToCriticalOrHigh;
|
|
99
|
+
return {
|
|
100
|
+
baselineTimestamp: baseline.createdAt,
|
|
101
|
+
baselineVersion: baseline.fathomVersion,
|
|
102
|
+
baselineScore,
|
|
103
|
+
currentScore,
|
|
104
|
+
scoreDelta,
|
|
105
|
+
isRegression,
|
|
106
|
+
categoryDiffs,
|
|
107
|
+
newFindings,
|
|
108
|
+
resolvedFindings,
|
|
109
|
+
unchangedFindings,
|
|
110
|
+
changedFindings,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/baseline/compare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Finding } from '../core/findings.js';
|
|
2
|
+
import type { HealthScore, Metrics, CategoryScoreDiff, FindingChange, ComparisonResult } from '../core/result.js';
|
|
3
|
+
export type { CategoryScoreDiff, FindingChange, ComparisonResult };
|
|
4
|
+
/**
|
|
5
|
+
* Persisted format for .fathom/baseline.json.
|
|
6
|
+
* Versioned for future compatibility.
|
|
7
|
+
* Contains only metadata, findings, scores, and metrics — NEVER raw source code or secrets.
|
|
8
|
+
*/
|
|
9
|
+
export interface BaselineData {
|
|
10
|
+
/** Baseline schema version (currently "1.0") */
|
|
11
|
+
schemaVersion: string;
|
|
12
|
+
/** Fathom CLI version that generated the baseline */
|
|
13
|
+
fathomVersion: string;
|
|
14
|
+
/** ISO timestamp of when the baseline was created */
|
|
15
|
+
createdAt: string;
|
|
16
|
+
/** Relative or resolved repository path */
|
|
17
|
+
repositoryPath: string;
|
|
18
|
+
/** Overall health score and category breakdown */
|
|
19
|
+
score: HealthScore;
|
|
20
|
+
/** Sanitized findings from the baseline analysis */
|
|
21
|
+
findings: Finding[];
|
|
22
|
+
/** Metrics map from all analyzers */
|
|
23
|
+
metrics: Record<string, Metrics>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/baseline/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EACV,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,KAAK,EAAE,WAAW,CAAC;IACnB,oDAAoD;IACpD,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/baseline/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface AnalyzeOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
sarif?: boolean;
|
|
4
|
+
html?: string | boolean;
|
|
5
|
+
ci?: boolean;
|
|
6
|
+
failUnder?: number;
|
|
7
|
+
/** Show all findings in terminal output (no 10-finding cap) */
|
|
8
|
+
verbose?: boolean;
|
|
9
|
+
/** Write JSON or SARIF output to this file instead of stdout */
|
|
10
|
+
output?: string;
|
|
11
|
+
/** Save the current analysis as baseline in .fathom/baseline.json */
|
|
12
|
+
baseline?: boolean;
|
|
13
|
+
/** Compare current analysis against .fathom/baseline.json */
|
|
14
|
+
compare?: boolean;
|
|
15
|
+
/** Analyze changes introduced by Git diff against base ref */
|
|
16
|
+
diff?: string | boolean;
|
|
17
|
+
/** Write Markdown PR summary (to file or GITHUB_STEP_SUMMARY) */
|
|
18
|
+
summary?: string | boolean;
|
|
19
|
+
/** Post PR summary comment to GitHub pull request (requires GITHUB_TOKEN) */
|
|
20
|
+
prComment?: boolean;
|
|
21
|
+
/** Display architecture model, layers, and boundary checks */
|
|
22
|
+
architecture?: boolean;
|
|
23
|
+
/** Display dependency intelligence breakdown */
|
|
24
|
+
deps?: boolean;
|
|
25
|
+
/** Enable online dependency vulnerability and freshness checks */
|
|
26
|
+
online?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Exit codes:
|
|
30
|
+
* 0 = success
|
|
31
|
+
* 1 = analysis completed but threshold / high-severity findings triggered
|
|
32
|
+
* 2 = invalid usage / config error
|
|
33
|
+
* 3 = unexpected failure
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* The main analyze command.
|
|
37
|
+
*/
|
|
38
|
+
export declare function analyzeCommand(targetPath: string, options: AnalyzeOptions): Promise<void>;
|
|
39
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AAEH;;GAEG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiR/F"}
|