@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.
Files changed (236) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/LICENSE +21 -0
  3. package/README.md +725 -0
  4. package/dist/analyzers/architecture/graph.d.ts +29 -0
  5. package/dist/analyzers/architecture/graph.d.ts.map +1 -0
  6. package/dist/analyzers/architecture/graph.js +347 -0
  7. package/dist/analyzers/architecture/graph.js.map +1 -0
  8. package/dist/analyzers/architecture/imports.d.ts +24 -0
  9. package/dist/analyzers/architecture/imports.d.ts.map +1 -0
  10. package/dist/analyzers/architecture/imports.js +155 -0
  11. package/dist/analyzers/architecture/imports.js.map +1 -0
  12. package/dist/analyzers/architecture/index.d.ts +13 -0
  13. package/dist/analyzers/architecture/index.d.ts.map +1 -0
  14. package/dist/analyzers/architecture/index.js +217 -0
  15. package/dist/analyzers/architecture/index.js.map +1 -0
  16. package/dist/analyzers/architecture/types.d.ts +65 -0
  17. package/dist/analyzers/architecture/types.d.ts.map +1 -0
  18. package/dist/analyzers/architecture/types.js +2 -0
  19. package/dist/analyzers/architecture/types.js.map +1 -0
  20. package/dist/analyzers/cicd/index.d.ts +11 -0
  21. package/dist/analyzers/cicd/index.d.ts.map +1 -0
  22. package/dist/analyzers/cicd/index.js +157 -0
  23. package/dist/analyzers/cicd/index.js.map +1 -0
  24. package/dist/analyzers/dependencies/index.d.ts +11 -0
  25. package/dist/analyzers/dependencies/index.d.ts.map +1 -0
  26. package/dist/analyzers/dependencies/index.js +403 -0
  27. package/dist/analyzers/dependencies/index.js.map +1 -0
  28. package/dist/analyzers/dependencies/lockfiles.d.ts +19 -0
  29. package/dist/analyzers/dependencies/lockfiles.d.ts.map +1 -0
  30. package/dist/analyzers/dependencies/lockfiles.js +172 -0
  31. package/dist/analyzers/dependencies/lockfiles.js.map +1 -0
  32. package/dist/analyzers/dependencies/online.d.ts +19 -0
  33. package/dist/analyzers/dependencies/online.d.ts.map +1 -0
  34. package/dist/analyzers/dependencies/online.js +116 -0
  35. package/dist/analyzers/dependencies/online.js.map +1 -0
  36. package/dist/analyzers/dependencies/types.d.ts +49 -0
  37. package/dist/analyzers/dependencies/types.d.ts.map +1 -0
  38. package/dist/analyzers/dependencies/types.js +2 -0
  39. package/dist/analyzers/dependencies/types.js.map +1 -0
  40. package/dist/analyzers/documentation/index.d.ts +11 -0
  41. package/dist/analyzers/documentation/index.d.ts.map +1 -0
  42. package/dist/analyzers/documentation/index.js +166 -0
  43. package/dist/analyzers/documentation/index.js.map +1 -0
  44. package/dist/analyzers/git/index.d.ts +11 -0
  45. package/dist/analyzers/git/index.d.ts.map +1 -0
  46. package/dist/analyzers/git/index.js +180 -0
  47. package/dist/analyzers/git/index.js.map +1 -0
  48. package/dist/analyzers/project/index.d.ts +11 -0
  49. package/dist/analyzers/project/index.d.ts.map +1 -0
  50. package/dist/analyzers/project/index.js +95 -0
  51. package/dist/analyzers/project/index.js.map +1 -0
  52. package/dist/analyzers/quality/index.d.ts +11 -0
  53. package/dist/analyzers/quality/index.d.ts.map +1 -0
  54. package/dist/analyzers/quality/index.js +198 -0
  55. package/dist/analyzers/quality/index.js.map +1 -0
  56. package/dist/analyzers/security/index.d.ts +11 -0
  57. package/dist/analyzers/security/index.d.ts.map +1 -0
  58. package/dist/analyzers/security/index.js +236 -0
  59. package/dist/analyzers/security/index.js.map +1 -0
  60. package/dist/analyzers/testing/index.d.ts +11 -0
  61. package/dist/analyzers/testing/index.d.ts.map +1 -0
  62. package/dist/analyzers/testing/index.js +134 -0
  63. package/dist/analyzers/testing/index.js.map +1 -0
  64. package/dist/baseline/baseline.d.ts +20 -0
  65. package/dist/baseline/baseline.d.ts.map +1 -0
  66. package/dist/baseline/baseline.js +134 -0
  67. package/dist/baseline/baseline.js.map +1 -0
  68. package/dist/baseline/compare.d.ts +14 -0
  69. package/dist/baseline/compare.d.ts.map +1 -0
  70. package/dist/baseline/compare.js +113 -0
  71. package/dist/baseline/compare.js.map +1 -0
  72. package/dist/baseline/types.d.ts +25 -0
  73. package/dist/baseline/types.d.ts.map +1 -0
  74. package/dist/baseline/types.js +2 -0
  75. package/dist/baseline/types.js.map +1 -0
  76. package/dist/cli/commands.d.ts +39 -0
  77. package/dist/cli/commands.d.ts.map +1 -0
  78. package/dist/cli/commands.js +277 -0
  79. package/dist/cli/commands.js.map +1 -0
  80. package/dist/cli/index.d.ts +3 -0
  81. package/dist/cli/index.d.ts.map +1 -0
  82. package/dist/cli/index.js +29 -0
  83. package/dist/cli/index.js.map +1 -0
  84. package/dist/cli/options.d.ts +55 -0
  85. package/dist/cli/options.d.ts.map +1 -0
  86. package/dist/cli/options.js +258 -0
  87. package/dist/cli/options.js.map +1 -0
  88. package/dist/core/analyzer.d.ts +33 -0
  89. package/dist/core/analyzer.d.ts.map +1 -0
  90. package/dist/core/analyzer.js +19 -0
  91. package/dist/core/analyzer.js.map +1 -0
  92. package/dist/core/context.d.ts +90 -0
  93. package/dist/core/context.d.ts.map +1 -0
  94. package/dist/core/context.js +159 -0
  95. package/dist/core/context.js.map +1 -0
  96. package/dist/core/errors.d.ts +74 -0
  97. package/dist/core/errors.d.ts.map +1 -0
  98. package/dist/core/errors.js +109 -0
  99. package/dist/core/errors.js.map +1 -0
  100. package/dist/core/findings.d.ts +59 -0
  101. package/dist/core/findings.d.ts.map +1 -0
  102. package/dist/core/findings.js +34 -0
  103. package/dist/core/findings.js.map +1 -0
  104. package/dist/core/orchestrator.d.ts +44 -0
  105. package/dist/core/orchestrator.d.ts.map +1 -0
  106. package/dist/core/orchestrator.js +160 -0
  107. package/dist/core/orchestrator.js.map +1 -0
  108. package/dist/core/result.d.ts +169 -0
  109. package/dist/core/result.d.ts.map +1 -0
  110. package/dist/core/result.js +2 -0
  111. package/dist/core/result.js.map +1 -0
  112. package/dist/detectors/framework.d.ts +22 -0
  113. package/dist/detectors/framework.d.ts.map +1 -0
  114. package/dist/detectors/framework.js +147 -0
  115. package/dist/detectors/framework.js.map +1 -0
  116. package/dist/detectors/language.d.ts +13 -0
  117. package/dist/detectors/language.d.ts.map +1 -0
  118. package/dist/detectors/language.js +100 -0
  119. package/dist/detectors/language.js.map +1 -0
  120. package/dist/detectors/package-manager.d.ts +17 -0
  121. package/dist/detectors/package-manager.d.ts.map +1 -0
  122. package/dist/detectors/package-manager.js +67 -0
  123. package/dist/detectors/package-manager.js.map +1 -0
  124. package/dist/detectors/project-type.d.ts +20 -0
  125. package/dist/detectors/project-type.d.ts.map +1 -0
  126. package/dist/detectors/project-type.js +48 -0
  127. package/dist/detectors/project-type.js.map +1 -0
  128. package/dist/diff/analyzer.d.ts +16 -0
  129. package/dist/diff/analyzer.d.ts.map +1 -0
  130. package/dist/diff/analyzer.js +296 -0
  131. package/dist/diff/analyzer.js.map +1 -0
  132. package/dist/diff/git-diff.d.ts +44 -0
  133. package/dist/diff/git-diff.d.ts.map +1 -0
  134. package/dist/diff/git-diff.js +256 -0
  135. package/dist/diff/git-diff.js.map +1 -0
  136. package/dist/diff/types.d.ts +75 -0
  137. package/dist/diff/types.d.ts.map +1 -0
  138. package/dist/diff/types.js +2 -0
  139. package/dist/diff/types.js.map +1 -0
  140. package/dist/integrations/github/context.d.ts +22 -0
  141. package/dist/integrations/github/context.d.ts.map +1 -0
  142. package/dist/integrations/github/context.js +115 -0
  143. package/dist/integrations/github/context.js.map +1 -0
  144. package/dist/integrations/github/types.d.ts +30 -0
  145. package/dist/integrations/github/types.d.ts.map +1 -0
  146. package/dist/integrations/github/types.js +2 -0
  147. package/dist/integrations/github/types.js.map +1 -0
  148. package/dist/plugins/context.d.ts +13 -0
  149. package/dist/plugins/context.d.ts.map +1 -0
  150. package/dist/plugins/context.js +102 -0
  151. package/dist/plugins/context.js.map +1 -0
  152. package/dist/plugins/examples/react.d.ts +8 -0
  153. package/dist/plugins/examples/react.d.ts.map +1 -0
  154. package/dist/plugins/examples/react.js +129 -0
  155. package/dist/plugins/examples/react.js.map +1 -0
  156. package/dist/plugins/index.d.ts +5 -0
  157. package/dist/plugins/index.d.ts.map +1 -0
  158. package/dist/plugins/index.js +4 -0
  159. package/dist/plugins/index.js.map +1 -0
  160. package/dist/plugins/registry.d.ts +45 -0
  161. package/dist/plugins/registry.d.ts.map +1 -0
  162. package/dist/plugins/registry.js +236 -0
  163. package/dist/plugins/registry.js.map +1 -0
  164. package/dist/plugins/types.d.ts +148 -0
  165. package/dist/plugins/types.d.ts.map +1 -0
  166. package/dist/plugins/types.js +2 -0
  167. package/dist/plugins/types.js.map +1 -0
  168. package/dist/reporters/html.d.ts +11 -0
  169. package/dist/reporters/html.d.ts.map +1 -0
  170. package/dist/reporters/html.js +1352 -0
  171. package/dist/reporters/html.js.map +1 -0
  172. package/dist/reporters/json.d.ts +10 -0
  173. package/dist/reporters/json.d.ts.map +1 -0
  174. package/dist/reporters/json.js +11 -0
  175. package/dist/reporters/json.js.map +1 -0
  176. package/dist/reporters/markdown.d.ts +7 -0
  177. package/dist/reporters/markdown.d.ts.map +1 -0
  178. package/dist/reporters/markdown.js +74 -0
  179. package/dist/reporters/markdown.js.map +1 -0
  180. package/dist/reporters/sarif.d.ts +133 -0
  181. package/dist/reporters/sarif.d.ts.map +1 -0
  182. package/dist/reporters/sarif.js +268 -0
  183. package/dist/reporters/sarif.js.map +1 -0
  184. package/dist/reporters/terminal.d.ts +17 -0
  185. package/dist/reporters/terminal.d.ts.map +1 -0
  186. package/dist/reporters/terminal.js +423 -0
  187. package/dist/reporters/terminal.js.map +1 -0
  188. package/dist/rules/categories.d.ts +8 -0
  189. package/dist/rules/categories.d.ts.map +1 -0
  190. package/dist/rules/categories.js +23 -0
  191. package/dist/rules/categories.js.map +1 -0
  192. package/dist/rules/definitions.d.ts +25 -0
  193. package/dist/rules/definitions.d.ts.map +1 -0
  194. package/dist/rules/definitions.js +429 -0
  195. package/dist/rules/definitions.js.map +1 -0
  196. package/dist/rules/registry.d.ts +36 -0
  197. package/dist/rules/registry.d.ts.map +1 -0
  198. package/dist/rules/registry.js +64 -0
  199. package/dist/rules/registry.js.map +1 -0
  200. package/dist/rules/severity.d.ts +13 -0
  201. package/dist/rules/severity.d.ts.map +1 -0
  202. package/dist/rules/severity.js +15 -0
  203. package/dist/rules/severity.js.map +1 -0
  204. package/dist/scoring/confidence.d.ts +12 -0
  205. package/dist/scoring/confidence.d.ts.map +1 -0
  206. package/dist/scoring/confidence.js +22 -0
  207. package/dist/scoring/confidence.js.map +1 -0
  208. package/dist/scoring/score.d.ts +27 -0
  209. package/dist/scoring/score.d.ts.map +1 -0
  210. package/dist/scoring/score.js +81 -0
  211. package/dist/scoring/score.js.map +1 -0
  212. package/dist/scoring/weights.d.ts +11 -0
  213. package/dist/scoring/weights.d.ts.map +1 -0
  214. package/dist/scoring/weights.js +26 -0
  215. package/dist/scoring/weights.js.map +1 -0
  216. package/dist/utils/filesystem.d.ts +65 -0
  217. package/dist/utils/filesystem.d.ts.map +1 -0
  218. package/dist/utils/filesystem.js +299 -0
  219. package/dist/utils/filesystem.js.map +1 -0
  220. package/dist/utils/git.d.ts +47 -0
  221. package/dist/utils/git.d.ts.map +1 -0
  222. package/dist/utils/git.js +125 -0
  223. package/dist/utils/git.js.map +1 -0
  224. package/dist/utils/logger.d.ts +14 -0
  225. package/dist/utils/logger.d.ts.map +1 -0
  226. package/dist/utils/logger.js +25 -0
  227. package/dist/utils/logger.js.map +1 -0
  228. package/dist/utils/paths.d.ts +30 -0
  229. package/dist/utils/paths.d.ts.map +1 -0
  230. package/dist/utils/paths.js +48 -0
  231. package/dist/utils/paths.js.map +1 -0
  232. package/dist/utils/timing.d.ts +12 -0
  233. package/dist/utils/timing.d.ts.map +1 -0
  234. package/dist/utils/timing.js +19 -0
  235. package/dist/utils/timing.js.map +1 -0
  236. package/package.json +73 -0
@@ -0,0 +1,44 @@
1
+ import type { RepositoryContext } from './context.js';
2
+ import type { AnalysisResult } from './result.js';
3
+ import { AnalyzerRegistry } from './analyzer.js';
4
+ import type { RuleConfigValue } from '../rules/registry.js';
5
+ import type { FathomPlugin } from '../plugins/types.js';
6
+ import { PluginRegistry } from '../plugins/registry.js';
7
+ /**
8
+ * Options passed to the orchestrator.
9
+ */
10
+ export interface OrchestratorOptions {
11
+ /** Path to repository root */
12
+ repositoryPath?: string;
13
+ /** Alias for repositoryPath */
14
+ targetPath?: string;
15
+ /** Additional ignore patterns */
16
+ ignorePatterns?: string[];
17
+ /** Optional pre-built repository context */
18
+ context?: RepositoryContext;
19
+ /** Optional per-rule configuration overrides */
20
+ ruleOverrides?: Record<string, RuleConfigValue>;
21
+ /** Optional online mode flag for analyzers requiring network opt-in */
22
+ online?: boolean;
23
+ /** Optional plugins to execute during analysis */
24
+ plugins?: FathomPlugin[] | undefined;
25
+ /** Optional custom plugin registry */
26
+ pluginRegistry?: PluginRegistry | undefined;
27
+ }
28
+ /**
29
+ * Creates an AnalyzerRegistry populated with all 9 core analyzers.
30
+ */
31
+ export declare function createDefaultRegistry(): AnalyzerRegistry;
32
+ /**
33
+ * The orchestrator is the central coordinator.
34
+ *
35
+ * It:
36
+ * 1. Builds the repository context once
37
+ * 2. Runs all registered analyzers (with error isolation)
38
+ * 3. Aggregates findings and metrics
39
+ * 4. Calculates the health score
40
+ * 5. Returns a complete AnalysisResult
41
+ */
42
+ export declare function runAnalysis(options: OrchestratorOptions): Promise<AnalysisResult>;
43
+ export declare function runAnalysis(registry: AnalyzerRegistry, options: OrchestratorOptions): Promise<AnalysisResult>;
44
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAkB,cAAc,EAAW,MAAM,aAAa,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAiBjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAChD,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,OAAO,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACrC,sCAAsC;IACtC,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,gBAAgB,CAWxD;AA+BD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AACzF,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,160 @@
1
+ import path from 'node:path';
2
+ import { AnalyzerRegistry } from './analyzer.js';
3
+ import { buildRepositoryContext } from './context.js';
4
+ import { calculateHealthScore } from '../scoring/score.js';
5
+ import { sortFindings, deduplicateFindings } from './findings.js';
6
+ import { createTimer } from '../utils/timing.js';
7
+ import { logger } from '../utils/logger.js';
8
+ import { ProjectAnalyzer } from '../analyzers/project/index.js';
9
+ import { GitAnalyzer } from '../analyzers/git/index.js';
10
+ import { SecurityAnalyzer } from '../analyzers/security/index.js';
11
+ import { DependencyAnalyzer } from '../analyzers/dependencies/index.js';
12
+ import { QualityAnalyzer } from '../analyzers/quality/index.js';
13
+ import { TestingAnalyzer } from '../analyzers/testing/index.js';
14
+ import { DocumentationAnalyzer } from '../analyzers/documentation/index.js';
15
+ import { CICDAnalyzer } from '../analyzers/cicd/index.js';
16
+ import { ArchitectureAnalyzer } from '../analyzers/architecture/index.js';
17
+ import { ruleRegistry } from '../rules/registry.js';
18
+ const FATHOM_VERSION = '0.1.0';
19
+ const SCHEMA_VERSION = '1.0';
20
+ import { PluginRegistry } from '../plugins/registry.js';
21
+ /**
22
+ * Creates an AnalyzerRegistry populated with all 9 core analyzers.
23
+ */
24
+ export function createDefaultRegistry() {
25
+ return new AnalyzerRegistry()
26
+ .register(new ProjectAnalyzer())
27
+ .register(new GitAnalyzer())
28
+ .register(new SecurityAnalyzer())
29
+ .register(new DependencyAnalyzer())
30
+ .register(new QualityAnalyzer())
31
+ .register(new TestingAnalyzer())
32
+ .register(new DocumentationAnalyzer())
33
+ .register(new CICDAnalyzer())
34
+ .register(new ArchitectureAnalyzer());
35
+ }
36
+ /**
37
+ * Run a single analyzer safely, catching and isolating failures.
38
+ */
39
+ async function runAnalyzerSafely(analyzer, context) {
40
+ const elapsed = createTimer();
41
+ try {
42
+ logger.debug(`Running analyzer: ${analyzer.name}`);
43
+ const result = await analyzer.analyze(context);
44
+ return result;
45
+ }
46
+ catch (err) {
47
+ const message = err instanceof Error ? err.message : String(err);
48
+ logger.warn(`Analyzer "${analyzer.name}" failed: ${message}`);
49
+ return {
50
+ analyzerId: analyzer.id,
51
+ analyzerName: analyzer.name,
52
+ category: analyzer.category,
53
+ status: 'failed',
54
+ findings: [],
55
+ metrics: {},
56
+ durationMs: elapsed(),
57
+ warnings: [],
58
+ error: message,
59
+ };
60
+ }
61
+ }
62
+ export async function runAnalysis(first, second) {
63
+ let registry;
64
+ let options;
65
+ if ('getAll' in first) {
66
+ registry = first;
67
+ options = second ?? { repositoryPath: '.' };
68
+ }
69
+ else {
70
+ registry = createDefaultRegistry();
71
+ options = first;
72
+ }
73
+ const targetPath = options.repositoryPath ?? options.targetPath ?? '.';
74
+ const totalTimer = createTimer();
75
+ // Build shared context
76
+ logger.debug('Building repository context...');
77
+ const context = options.context ??
78
+ (await buildRepositoryContext(targetPath, options.ignorePatterns ?? [], options.online ?? false));
79
+ if (options.online !== undefined) {
80
+ context.online = options.online;
81
+ }
82
+ // Register plugins if provided
83
+ if (options.plugins && options.plugins.length > 0) {
84
+ const pluginRegistry = options.pluginRegistry ?? new PluginRegistry();
85
+ for (const plugin of options.plugins) {
86
+ if (!pluginRegistry.has(plugin.manifest.name)) {
87
+ await pluginRegistry.register(plugin);
88
+ }
89
+ }
90
+ for (const pluginAnalyzer of pluginRegistry.getAnalyzers()) {
91
+ registry.register(pluginAnalyzer);
92
+ }
93
+ }
94
+ else if (options.pluginRegistry) {
95
+ for (const pluginAnalyzer of options.pluginRegistry.getAnalyzers()) {
96
+ registry.register(pluginAnalyzer);
97
+ }
98
+ }
99
+ // Run analyzers — parallel but capped to avoid thrashing
100
+ const analyzers = registry.getAll();
101
+ const results = await Promise.all(analyzers.map((analyzer) => runAnalyzerSafely(analyzer, context)));
102
+ // Apply per-rule overrides (e.g. "off", "warning", "error", or custom severity)
103
+ const ruleOverrides = options.ruleOverrides ?? {};
104
+ if (Object.keys(ruleOverrides).length > 0) {
105
+ for (const r of results) {
106
+ r.findings = r.findings
107
+ .filter((f) => ruleRegistry.isEnabled(f.ruleId, ruleOverrides))
108
+ .map((f) => {
109
+ const effectiveSeverity = ruleRegistry.getEffectiveSeverity(f.ruleId, ruleOverrides);
110
+ if (effectiveSeverity && effectiveSeverity !== f.severity) {
111
+ return { ...f, severity: effectiveSeverity };
112
+ }
113
+ return f;
114
+ });
115
+ }
116
+ }
117
+ // Aggregate findings
118
+ const allFindings = results.flatMap((r) => r.findings);
119
+ const deduped = deduplicateFindings(allFindings);
120
+ const sorted = sortFindings(deduped);
121
+ // Aggregate metrics
122
+ const mergedMetrics = {};
123
+ for (const result of results) {
124
+ for (const [key, value] of Object.entries(result.metrics)) {
125
+ // Prefix with analyzer ID to avoid collisions
126
+ mergedMetrics[`${result.analyzerId}.${key}`] = value;
127
+ }
128
+ }
129
+ // Calculate score
130
+ const score = calculateHealthScore(sorted, results);
131
+ const elapsed = totalTimer();
132
+ return {
133
+ schemaVersion: SCHEMA_VERSION,
134
+ fathomVersion: FATHOM_VERSION,
135
+ status: results.some((r) => r.status === 'failed') ? 'partial' : 'success',
136
+ repositoryPath: path.resolve(targetPath),
137
+ repository: {
138
+ name: path.basename(path.resolve(targetPath)),
139
+ root: path.resolve(targetPath),
140
+ filesCount: context.files.length,
141
+ languages: context.languages,
142
+ frameworks: context.frameworks,
143
+ packageManagers: context.packageManagers,
144
+ projectType: context.projectType,
145
+ git: {
146
+ isRepo: context.git.isRepository,
147
+ hasCommits: context.git.hasCommits,
148
+ hasGitignore: context.git.hasGitignore,
149
+ },
150
+ },
151
+ timestamp: new Date().toISOString(),
152
+ score,
153
+ metrics: mergedMetrics,
154
+ findings: sorted,
155
+ analyzers: results,
156
+ duration: elapsed,
157
+ durationMs: elapsed,
158
+ };
159
+ }
160
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ import type { Category } from '../rules/categories.js';
2
+ import type { Finding } from './findings.js';
3
+ import type { PRAnalysisResult } from '../diff/types.js';
4
+ /**
5
+ * Score delta for an individual category in baseline comparison.
6
+ */
7
+ export interface CategoryScoreDiff {
8
+ category: Category;
9
+ baselineScore: number;
10
+ currentScore: number;
11
+ delta: number;
12
+ }
13
+ /**
14
+ * A finding that existed in both baseline and current, but whose severity or confidence changed.
15
+ */
16
+ export interface FindingChange {
17
+ current: Finding;
18
+ baseline: Finding;
19
+ severityChanged: boolean;
20
+ confidenceChanged: boolean;
21
+ }
22
+ /**
23
+ * Full comparison between current analysis and the baseline.
24
+ */
25
+ export interface ComparisonResult {
26
+ /** Timestamp when baseline was established */
27
+ baselineTimestamp: string;
28
+ /** Fathom version that created the baseline */
29
+ baselineVersion: string;
30
+ /** Baseline overall score (0–100) */
31
+ baselineScore: number;
32
+ /** Current overall score (0–100) */
33
+ currentScore: number;
34
+ /** Overall score delta (currentScore - baselineScore) */
35
+ scoreDelta: number;
36
+ /**
37
+ * True if a regression is detected:
38
+ * - Overall score dropped
39
+ * - Any category score dropped
40
+ * - New critical or high findings were introduced
41
+ */
42
+ isRegression: boolean;
43
+ /** Category-by-category score differences */
44
+ categoryDiffs: CategoryScoreDiff[];
45
+ /** Findings newly introduced since the baseline */
46
+ newFindings: Finding[];
47
+ /** Findings present in baseline that are now resolved */
48
+ resolvedFindings: Finding[];
49
+ /** Findings present in both baseline and current without severity/confidence change */
50
+ unchangedFindings: Finding[];
51
+ /** Findings present in both with changed severity or confidence */
52
+ changedFindings: FindingChange[];
53
+ }
54
+ /**
55
+ * Metrics produced by an analyzer.
56
+ * Metrics describe the repository — they do not recommend actions.
57
+ */
58
+ export type Metrics = Record<string, number | string | boolean | string[]>;
59
+ /**
60
+ * Status of an individual analyzer run.
61
+ */
62
+ export type AnalyzerStatus = 'success' | 'failed' | 'skipped';
63
+ /**
64
+ * Result produced by a single analyzer.
65
+ */
66
+ export interface AnalyzerResult {
67
+ /** Analyzer ID */
68
+ analyzerId: string;
69
+ /** Display name */
70
+ analyzerName: string;
71
+ /** Category */
72
+ category: Category;
73
+ /** Run status */
74
+ status: AnalyzerStatus;
75
+ /** Findings from this analyzer */
76
+ findings: Finding[];
77
+ /** Numeric/string metrics */
78
+ metrics: Metrics;
79
+ /** Execution time in milliseconds */
80
+ durationMs: number;
81
+ /** Non-fatal warnings */
82
+ warnings: string[];
83
+ /** Error message if status === 'failed' */
84
+ error?: string;
85
+ }
86
+ /**
87
+ * Category score after applying findings.
88
+ */
89
+ export interface CategoryScore {
90
+ category: Category;
91
+ score: number;
92
+ maxScore: number;
93
+ weight: number;
94
+ findingCount: number;
95
+ }
96
+ /**
97
+ * Overall health score with category breakdown.
98
+ */
99
+ export interface HealthScore {
100
+ /** Overall weighted score 0–100 */
101
+ overall: number;
102
+ /** Human-readable band */
103
+ band: 'critical' | 'needs-attention' | 'fair' | 'healthy' | 'excellent';
104
+ /** Per-category scores */
105
+ categories: CategoryScore[];
106
+ }
107
+ export interface RepositoryInfo {
108
+ name: string;
109
+ root: string;
110
+ filesCount: number;
111
+ languages: Array<{
112
+ name: string;
113
+ confidence: number;
114
+ evidence: string[];
115
+ }>;
116
+ frameworks: Array<{
117
+ name: string;
118
+ confidence: number;
119
+ evidence: string[];
120
+ }>;
121
+ packageManagers: Array<{
122
+ name: string;
123
+ confidence: number;
124
+ lockfile?: string;
125
+ }>;
126
+ projectType: {
127
+ type: string;
128
+ confidence: number;
129
+ evidence: string[];
130
+ };
131
+ git: {
132
+ isRepo: boolean;
133
+ hasCommits: boolean;
134
+ hasGitignore: boolean;
135
+ };
136
+ }
137
+ /**
138
+ * The complete result of a repository analysis.
139
+ */
140
+ export interface AnalysisResult {
141
+ /** Schema version for future compatibility */
142
+ schemaVersion: string;
143
+ /** Fathom version */
144
+ fathomVersion: string;
145
+ /** Status of the analysis */
146
+ status: 'success' | 'partial' | 'failed';
147
+ /** Repository root path */
148
+ repositoryPath: string;
149
+ /** High-level repository metadata */
150
+ repository: RepositoryInfo;
151
+ /** ISO timestamp */
152
+ timestamp: string;
153
+ /** Overall health score */
154
+ score: HealthScore;
155
+ /** Global metrics (merged from all analyzers) */
156
+ metrics: Metrics;
157
+ /** All findings sorted by severity/confidence */
158
+ findings: Finding[];
159
+ /** Per-analyzer results */
160
+ analyzers: AnalyzerResult[];
161
+ /** Total duration in milliseconds */
162
+ duration: number;
163
+ durationMs: number;
164
+ /** Optional comparison against baseline when --compare is used */
165
+ comparison?: ComparisonResult;
166
+ /** Optional PR analysis when --diff is used */
167
+ prAnalysis?: PRAnalysisResult;
168
+ }
169
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/core/result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,eAAe,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,6CAA6C;IAC7C,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,mDAAmD;IACnD,WAAW,EAAE,OAAO,EAAE,CAAC;IACvB,yDAAyD;IACzD,gBAAgB,EAAE,OAAO,EAAE,CAAC;IAC5B,uFAAuF;IACvF,iBAAiB,EAAE,OAAO,EAAE,CAAC;IAC7B,mEAAmE;IACnE,eAAe,EAAE,aAAa,EAAE,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,kCAAkC;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,6BAA6B;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,IAAI,EAAE,UAAU,GAAG,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;IACxE,0BAA0B;IAC1B,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC3E,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5E,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACtE,GAAG,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACzC,2BAA2B;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,UAAU,EAAE,cAAc,CAAC;IAC3B,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,2BAA2B;IAC3B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,+CAA+C;IAC/C,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/core/result.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Framework detection.
3
+ *
4
+ * Frameworks are detected from package.json dependencies,
5
+ * config files, and directory structure.
6
+ * Never claims a framework without evidence.
7
+ */
8
+ export interface FrameworkDetection {
9
+ name: string;
10
+ confidence: number;
11
+ evidence: string[];
12
+ }
13
+ /**
14
+ * Detect frameworks from package dependencies and file indicators.
15
+ */
16
+ export declare function detectFrameworks(params: {
17
+ dependencies: string[];
18
+ devDependencies: string[];
19
+ rootFiles: string[];
20
+ allFiles: string[];
21
+ }): FrameworkDetection[];
22
+ //# sourceMappingURL=framework.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework.d.ts","sourceRoot":"","sources":["../../src/detectors/framework.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA2GD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,kBAAkB,EAAE,CAoDvB"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Framework detection.
3
+ *
4
+ * Frameworks are detected from package.json dependencies,
5
+ * config files, and directory structure.
6
+ * Never claims a framework without evidence.
7
+ */
8
+ const FRAMEWORK_SIGNATURES = [
9
+ // Frontend JS
10
+ {
11
+ name: 'Next.js',
12
+ packages: ['next'],
13
+ configFiles: ['next.config.js', 'next.config.ts', 'next.config.mjs'],
14
+ directories: ['.next'],
15
+ },
16
+ {
17
+ name: 'React',
18
+ packages: ['react', 'react-dom'],
19
+ filePatterns: [/\.(jsx|tsx)$/],
20
+ },
21
+ {
22
+ name: 'Vue',
23
+ packages: ['vue'],
24
+ configFiles: ['vue.config.js', 'vue.config.ts', 'vite.config.ts'],
25
+ filePatterns: [/\.vue$/],
26
+ },
27
+ {
28
+ name: 'Nuxt',
29
+ packages: ['nuxt', 'nuxt3'],
30
+ configFiles: ['nuxt.config.js', 'nuxt.config.ts'],
31
+ directories: ['.nuxt'],
32
+ },
33
+ {
34
+ name: 'Angular',
35
+ packages: ['@angular/core'],
36
+ configFiles: ['angular.json', '.angular-cli.json'],
37
+ },
38
+ {
39
+ name: 'Svelte',
40
+ packages: ['svelte'],
41
+ configFiles: ['svelte.config.js'],
42
+ filePatterns: [/\.svelte$/],
43
+ },
44
+ {
45
+ name: 'Remix',
46
+ packages: ['@remix-run/node', '@remix-run/react'],
47
+ configFiles: ['remix.config.js'],
48
+ },
49
+ {
50
+ name: 'Astro',
51
+ packages: ['astro'],
52
+ configFiles: ['astro.config.mjs', 'astro.config.js'],
53
+ },
54
+ // Backend JS/TS
55
+ {
56
+ name: 'Express',
57
+ packages: ['express'],
58
+ },
59
+ {
60
+ name: 'NestJS',
61
+ packages: ['@nestjs/core', '@nestjs/common'],
62
+ },
63
+ {
64
+ name: 'Fastify',
65
+ packages: ['fastify'],
66
+ },
67
+ {
68
+ name: 'Hono',
69
+ packages: ['hono'],
70
+ },
71
+ // Python
72
+ {
73
+ name: 'FastAPI',
74
+ packages: ['fastapi'],
75
+ filePatterns: [/main\.py$/, /app\.py$/],
76
+ },
77
+ {
78
+ name: 'Django',
79
+ packages: ['django', 'Django'],
80
+ configFiles: ['manage.py'],
81
+ filePatterns: [/settings\.py$/],
82
+ },
83
+ {
84
+ name: 'Flask',
85
+ packages: ['flask', 'Flask'],
86
+ },
87
+ // Java
88
+ {
89
+ name: 'Spring Boot',
90
+ configFiles: ['pom.xml'],
91
+ filePatterns: [/Application\.java$/, /SpringApplication\.java$/],
92
+ },
93
+ // Build tools (informational)
94
+ {
95
+ name: 'Vite',
96
+ packages: ['vite'],
97
+ configFiles: ['vite.config.ts', 'vite.config.js', 'vite.config.mts'],
98
+ },
99
+ ];
100
+ /**
101
+ * Detect frameworks from package dependencies and file indicators.
102
+ */
103
+ export function detectFrameworks(params) {
104
+ const { dependencies, devDependencies, rootFiles, allFiles } = params;
105
+ const allPackages = new Set([...dependencies, ...devDependencies]);
106
+ const rootFileNames = new Set(rootFiles.map((f) => f.split('/').pop() ?? f));
107
+ const allFileNames = allFiles.map((f) => f.replace(/\\/g, '/'));
108
+ const detections = [];
109
+ for (const sig of FRAMEWORK_SIGNATURES) {
110
+ const evidence = [];
111
+ let confidence = 0;
112
+ // Check packages
113
+ for (const pkg of sig.packages ?? []) {
114
+ if (allPackages.has(pkg)) {
115
+ evidence.push(`dependency: ${pkg}`);
116
+ confidence = Math.max(confidence, 0.95);
117
+ }
118
+ }
119
+ // Check config files
120
+ for (const cfgFile of sig.configFiles ?? []) {
121
+ if (rootFileNames.has(cfgFile) || allFileNames.some((f) => f.endsWith(cfgFile))) {
122
+ evidence.push(`config: ${cfgFile}`);
123
+ confidence = Math.max(confidence, confidence > 0 ? confidence : 0.8);
124
+ }
125
+ }
126
+ // Check directories
127
+ for (const dir of sig.directories ?? []) {
128
+ if (allFileNames.some((f) => f.startsWith(dir + '/'))) {
129
+ evidence.push(`directory: ${dir}/`);
130
+ confidence = Math.max(confidence, confidence > 0 ? confidence : 0.7);
131
+ }
132
+ }
133
+ // Check file patterns
134
+ for (const pattern of sig.filePatterns ?? []) {
135
+ const match = allFileNames.find((f) => pattern.test(f));
136
+ if (match) {
137
+ evidence.push(`files matching ${pattern.source}`);
138
+ confidence = Math.max(confidence, confidence > 0 ? confidence : 0.65);
139
+ }
140
+ }
141
+ if (confidence > 0) {
142
+ detections.push({ name: sig.name, confidence, evidence });
143
+ }
144
+ }
145
+ return detections.sort((a, b) => b.confidence - a.confidence);
146
+ }
147
+ //# sourceMappingURL=framework.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework.js","sourceRoot":"","sources":["../../src/detectors/framework.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Detected programming ecosystem.
3
+ */
4
+ export interface EcosystemDetection {
5
+ name: string;
6
+ confidence: number;
7
+ evidence: string[];
8
+ }
9
+ /**
10
+ * Detect ecosystems from the file list and root files.
11
+ */
12
+ export declare function detectLanguages(rootFiles: string[], allFiles: string[]): EcosystemDetection[];
13
+ //# sourceMappingURL=language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/detectors/language.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAqED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAsC7F"}