@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
package/README.md ADDED
@@ -0,0 +1,725 @@
1
+ # FATHOM
2
+
3
+ > **Know what's beneath the surface.**
4
+
5
+ [![CI](https://github.com/Ash-Technologia/Fathom/actions/workflows/ci.yml/badge.svg)](https://github.com/Ash-Technologia/Fathom/actions)
6
+ [![npm version](https://img.shields.io/npm/v/@ash-technologia/fathom.svg)](https://www.npmjs.com/package/@ash-technologia/fathom)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
8
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org)
9
+ [![GitHub Action](https://img.shields.io/badge/action-Ash--Technologia%2FFathom-blue?logo=githubactions)](https://github.com/Ash-Technologia/Fathom)
10
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Ash-Technologia/Fathom/blob/main/CONTRIBUTING.md)
11
+
12
+ **Fathom** is a local-first repository intelligence CLI for developers. It analyzes software repositories and produces an actionable understanding of health, architecture, security hygiene, Git hygiene, dependencies, testing maturity, documentation quality, and CI/CD readiness.
13
+
14
+ ---
15
+
16
+ ## ⚡ Quick Start
17
+
18
+ Analyze any repository directly with `npx`:
19
+
20
+ ```bash
21
+ npx @ash-technologia/fathom .
22
+ ```
23
+
24
+ Or install globally:
25
+
26
+ ```bash
27
+ npm install -g @ash-technologia/fathom
28
+ fathom .
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 🧭 Why Fathom?
34
+
35
+ Most linters focus exclusively on syntax or code formatting, and full security scanners are often slow, cloud-dependent, or noisy.
36
+
37
+ Fathom answers a different question:
38
+
39
+ > *"What is really going on inside this codebase, and what should I address before continuing work or shipping it?"*
40
+
41
+ ### Core Principles
42
+
43
+ - 🔒 **Local-First & Privacy-Focused**: Never uploads code or telemetry. Safe, read-only operations only.
44
+ - 🎯 **Deterministic**: Same repository state produces the exact same score and findings every time.
45
+ - 🚫 **Safe Secrets Handling**: Detects exposed credentials without ever printing or logging secret values.
46
+ - 🧩 **Extensible Architecture**: 9 isolated analyzers with typed findings, metrics, and scoring.
47
+ - ⚡ **Blazing Fast**: Single filesystem traversal index; completes typical repository scans in under 200ms.
48
+
49
+ ---
50
+
51
+ ## 📊 Terminal UX
52
+
53
+ Running `fathom .` produces a clean, readable overview:
54
+
55
+ ```text
56
+ FATHOM
57
+ Know what's beneath the surface.
58
+
59
+ Scanning my-app...
60
+
61
+ Detected: Node.js, TypeScript, React, Next.js
62
+
63
+ ────────────────────────────────────────────────────────
64
+
65
+ HEALTH
66
+
67
+ 88 / 100
68
+ Healthy
69
+
70
+ Project 100
71
+ Git 94
72
+ Security 85
73
+ Dependencies 90
74
+ Code Quality 85
75
+ Testing 80
76
+ Documentation 85
77
+ CI/CD 90
78
+
79
+ ────────────────────────────────────────────────────────
80
+
81
+ ATTENTION
82
+
83
+ HIGH
84
+ Environment file may not be gitignored: .env
85
+ .env
86
+
87
+ MEDIUM
88
+ Low test-to-source file ratio
89
+ Test files represent only 8% of source files (2 tests vs 24 source files).
90
+
91
+ LOW
92
+ 12 debug statements found across source files
93
+
94
+ ────────────────────────────────────────────────────────
95
+
96
+ NEXT STEPS
97
+
98
+ 1. Add ".env" to .gitignore to prevent accidental commits.
99
+ 2. Increase test coverage for critical application logic.
100
+ 3. Remove or gate debug statements before shipping to production.
101
+
102
+ ────────────────────────────────────────────────────────
103
+
104
+ ✓ Project
105
+ ✓ Git
106
+ ✓ Security
107
+ ✓ Dependencies
108
+ ✓ Code Quality
109
+ ✓ Testing
110
+ ✓ Documentation
111
+ ✓ CI/CD
112
+ ✓ Architecture
113
+
114
+ Completed in 142ms
115
+ ```
116
+
117
+ ---
118
+
119
+ ## 🛠️ CLI Commands & Options
120
+
121
+ ```bash
122
+ # Analyze current directory
123
+ fathom .
124
+
125
+ # Analyze specific repository path
126
+ fathom /path/to/repo
127
+
128
+ # Output machine-readable JSON to stdout
129
+ fathom --json
130
+
131
+ # Save JSON report directly to a file
132
+ fathom --json -o report.json
133
+
134
+ # Output SARIF 2.1.0 to stdout
135
+ fathom --sarif
136
+
137
+ # Save SARIF 2.1.0 report directly to a file for GitHub Code Scanning
138
+ fathom --sarif -o fathom.sarif
139
+
140
+ # Display all findings without truncation (disables the default 10-finding limit)
141
+ fathom --verbose
142
+
143
+ # Generate self-contained HTML report
144
+ fathom --html report.html
145
+
146
+ # Save a deterministic baseline to .fathom/baseline.json
147
+ fathom --baseline
148
+
149
+ # Compare current analysis against saved baseline and report regressions
150
+ fathom --compare
151
+
152
+ # Compare against baseline and output machine-readable JSON
153
+ fathom --compare --json
154
+
155
+ # Compare against baseline and generate interactive HTML report
156
+ fathom --compare --html report.html
157
+
158
+ # Analyze changes introduced by Git diff (auto-detects base branch)
159
+ fathom --diff
160
+
161
+ # Analyze changes against a specific branch, commit, or remote ref
162
+ fathom --diff main
163
+ fathom --diff HEAD~1
164
+ fathom --diff origin/main
165
+
166
+ # PR analysis with machine-readable JSON output
167
+ fathom --diff main --json
168
+
169
+ # View architecture hierarchy and graph warnings in terminal
170
+ fathom --architecture
171
+
172
+ # Inspect dependency inventory and lockfile metrics (offline)
173
+ fathom --deps
174
+
175
+ # Inspect dependency inventory with opt-in vulnerability & freshness checks
176
+ fathom --deps --online
177
+
178
+ # Run in CI mode (compact logging, fails if critical/high findings exist)
179
+ fathom --ci
180
+
181
+ # Fail CI build if overall health score is below threshold, regression is detected, or PR diff introduces findings
182
+ fathom --ci --fail-under 80
183
+
184
+ # Display version or help
185
+ fathom --version
186
+ fathom --help
187
+ ```
188
+
189
+ ### Exit Codes
190
+
191
+ | Code | Meaning |
192
+ |:----:|:--------|
193
+ | **0** | Analysis successful and meets health thresholds |
194
+ | **1** | Analysis complete, but `--fail-under` threshold failed, critical findings found in CI mode, regression detected in CI mode, or PR diff introduces findings |
195
+ | **2** | Invalid CLI usage, missing/corrupted baseline, Git diff error (e.g. not a git repo, unresolvable base ref), or configuration syntax error |
196
+ | **3** | Repository access error or fatal system failure |
197
+
198
+ ---
199
+
200
+ ## 🔀 Pull Request & Git Diff Intelligence
201
+
202
+ Fathom extends beyond isolated file scanning with **PR-aware Git Diff Intelligence**. Instead of inspecting modified files in a vacuum, Fathom evaluates changes against the complete repository context:
203
+
204
+ ```
205
+ Git Diff
206
+
207
+ RepositoryContext
208
+
209
+ Affected files
210
+
211
+ Existing analyzers/rules
212
+
213
+ Finding comparison
214
+
215
+ PR report
216
+ ```
217
+
218
+ ### How It Works:
219
+ 1. **Safe Git Operations**: Invokes Git strictly through `child_process.execFile` in read-only mode (`git rev-parse`, `git diff`, `git show`, `git merge-base`). Never modifies working tree, never checks out branches, never executes repository scripts.
220
+ 2. **Whole-Repository Shadow Context**: Reconstructs base file versions for changed files using in-memory/temp shadow buffers, keeping untouched files referenced directly on disk. Runs all 26 rules across full architectural relationships.
221
+ 3. **Three-Way Finding Categorization**:
222
+ - **New Findings**: Issues introduced by added or modified lines in the pull request.
223
+ - **Touched Findings**: Pre-existing issues within files touched by the diff.
224
+ - **Resolved Findings**: Issues previously present that were eliminated by the PR.
225
+ 4. **Health & Category Impact**: Computes overall health score delta (`91 → 84 (-7 points)`) and per-category scoring shifts (Security, Quality, Testing, etc.).
226
+ 5. **Git Resilience**: Gracefully handles detached HEAD states, shallow clones (providing actionable fetch guidance), merge commits, and binary files.
227
+
228
+ Example terminal output:
229
+ ```text
230
+ FATHOM PR ANALYSIS
231
+ ────────────────────────────────────────────────────────
232
+
233
+ Changed:
234
+ 8 files
235
+ +312 lines
236
+ -87 lines
237
+
238
+ Health:
239
+ 91 → 84
240
+ -7 points
241
+
242
+ NEW FINDINGS
243
+ 🔴 SEC-002
244
+ Potential secret detected
245
+
246
+ 🟠 QUAL-004
247
+ Empty catch block
248
+
249
+ RESOLVED
250
+ ✓ TEST-004
251
+
252
+ CATEGORY IMPACT
253
+ Security -12
254
+ Quality -4
255
+ Testing +3
256
+
257
+ VERDICT
258
+ ⚠ Changes introduce 2 findings
259
+ ```
260
+
261
+ ---
262
+
263
+ ## 📉 Baseline & Regression Tracking
264
+
265
+ Fathom supports deterministic repository baselines to detect regressions over time or during CI/CD checks:
266
+
267
+ 1. **Create a baseline**:
268
+ ```bash
269
+ fathom --baseline
270
+ ```
271
+ Analyzes the repository and saves `.fathom/baseline.json` containing only scores, metrics, rule IDs, and safe evidence — never secret values or repository source code.
272
+
273
+ 2. **Compare current analysis**:
274
+ ```bash
275
+ fathom --compare
276
+ ```
277
+ Detects:
278
+ - Overall health score change (e.g. `91 → 84 (-7)`)
279
+ - Category score changes
280
+ - Newly introduced findings (`+`)
281
+ - Resolved findings (`-`)
282
+ - Unchanged & modified findings
283
+ - Regression verdict (`REGRESSION: YES / NO`)
284
+
285
+ 3. **Export reports**:
286
+ - `fathom --compare --json`: Attaches regression comparison data to the JSON output.
287
+ - `fathom --compare --html report.html`: Generates an interactive visual report with dedicated regression breakdown.
288
+
289
+ ---
290
+
291
+ ## 🏛️ Architecture Intelligence
292
+
293
+ Fathom includes a lightweight in-memory architecture graph analyzer that inspects import/export topologies without executing project code:
294
+
295
+ - **Static Import Parsing**: Scans ESM, CommonJS, dynamic imports, and Python modules.
296
+ - **Path Alias Resolution**: Honors `tsconfig.json` / `jsconfig.json` `compilerOptions.paths` and `baseUrl`.
297
+ - **Circular Dependency Detection (`ARCH-002`)**: Uses Tarjan's SCC algorithm to detect directed import loops.
298
+ - **Layer Boundary Violations (`ARCH-003`)**: Detects backend code referencing UI components, or client code referencing server-only primitives (`child_process`, `fs`, `net`, etc.).
299
+ - **Deep Coupling & Sizing (`ARCH-004`, `ARCH-005`)**: Flags excessive fan-out imports and large monolithic files requiring decomposition.
300
+ - **Orphaned File Detection (`ARCH-006`)**: Identifies dead, unreferenced source modules.
301
+ - **CLI View**: Run `fathom --architecture` for a visual tree of layers and graph warnings.
302
+
303
+ ---
304
+
305
+ ## 🤖 GitHub Action Integration
306
+
307
+ You can run Fathom directly in your GitHub Actions workflows with zero extra configuration:
308
+
309
+ ```yaml
310
+ name: Repository Intelligence
311
+
312
+ on:
313
+ push:
314
+ branches: [main]
315
+ pull_request:
316
+ branches: [main]
317
+
318
+ jobs:
319
+ fathom:
320
+ name: Repository Health Check
321
+ runs-on: ubuntu-latest
322
+ steps:
323
+ - name: Checkout Code
324
+ uses: actions/checkout@v4
325
+
326
+ - name: Run Fathom
327
+ uses: Ash-Technologia/Fathom@main
328
+ with:
329
+ fail-under: '80'
330
+ html: 'fathom-report.html'
331
+ sarif: 'fathom.sarif'
332
+
333
+ - name: Upload HTML Report
334
+ uses: actions/upload-artifact@v4
335
+ if: always()
336
+ with:
337
+ name: fathom-report
338
+ path: fathom-report.html
339
+
340
+ - name: Upload SARIF to GitHub Code Scanning
341
+ uses: github/codeql-action/upload-sarif@v3
342
+ if: always()
343
+ with:
344
+ sarif_file: fathom.sarif
345
+ category: fathom
346
+
347
+ fathom-pr:
348
+ name: PR Intelligence & Step Summary
349
+ if: github.event_name == 'pull_request'
350
+ runs-on: ubuntu-latest
351
+ permissions:
352
+ contents: read
353
+ pull-requests: write # Required only if pr-comment: 'true'
354
+ steps:
355
+ - name: Checkout Code
356
+ uses: actions/checkout@v4
357
+ with:
358
+ fetch-depth: 0 # Full history needed for base ref diff
359
+
360
+ - name: Run Fathom PR Intelligence
361
+ uses: Ash-Technologia/Fathom@main
362
+ with:
363
+ diff: 'true' # Automatically resolves github.base_ref
364
+ pr-comment: 'true'
365
+ github-token: ${{ secrets.GITHUB_TOKEN }}
366
+ ```
367
+
368
+ ### GitHub Actions Step Summary & PR Comments
369
+
370
+ When running in GitHub Actions:
371
+ - **Automatic Step Summary**: If running under a `pull_request` event or when `--diff` is analyzed, Fathom automatically generates and writes a concise Markdown summary to `$GITHUB_STEP_SUMMARY`.
372
+ - **PR Commenting**: Passing `--pr-comment` posts the concise PR health and findings table directly as a review comment on the pull request.
373
+ - **Offline / Local Execution**: When executed locally, Fathom runs completely offline without needing GitHub credentials or network connectivity. Tokens are never logged or exposed.
374
+ - **Custom Summary File**: Output Markdown directly to any file via `fathom --diff [ref] --summary pr-summary.md`.
375
+
376
+ ---
377
+
378
+ ## 🛡️ GitHub Code Scanning & SARIF 2.1.0 Integration
379
+
380
+ Fathom natively exports findings in standard **SARIF 2.1.0** (Static Analysis Results Interchange Format) format, which integrates seamlessly into GitHub Code Scanning:
381
+
382
+ ```
383
+ Fathom
384
+
385
+ SARIF (fathom --sarif -o fathom.sarif)
386
+
387
+ GitHub Code Scanning (github/codeql-action/upload-sarif)
388
+
389
+ Security & Quality Alerts in GitHub Security tab & PRs
390
+ ```
391
+
392
+ ### Standalone GitHub Actions Workflow
393
+
394
+ To run Fathom via npm/npx and upload results directly to GitHub Code Scanning:
395
+
396
+ ```yaml
397
+ name: Security & Health Scanning
398
+
399
+ on:
400
+ push:
401
+ branches: [main]
402
+ pull_request:
403
+ branches: [main]
404
+
405
+ jobs:
406
+ fathom-scan:
407
+ name: Fathom SARIF Analysis
408
+ runs-on: ubuntu-latest
409
+ permissions:
410
+ security-events: write
411
+ contents: read
412
+ steps:
413
+ - name: Checkout Code
414
+ uses: actions/checkout@v4
415
+
416
+ - name: Set up Node.js
417
+ uses: actions/setup-node@v4
418
+ with:
419
+ node-version: 20
420
+
421
+ - name: Run Fathom SARIF Analysis
422
+ run: npx @ash-technologia/fathom . --sarif -o fathom.sarif
423
+
424
+ - name: Upload SARIF to GitHub Code Scanning
425
+ uses: github/codeql-action/upload-sarif@v3
426
+ if: always()
427
+ with:
428
+ sarif_file: fathom.sarif
429
+ category: fathom
430
+ ```
431
+
432
+ ---
433
+
434
+ ## 🔍 Analyzers & Rules (26 Core Rules)
435
+
436
+ Fathom evaluates repositories across **9 isolated analyzers**:
437
+
438
+ | Rule ID | Category | Title | Severity |
439
+ |:---|:---|:---|:---:|
440
+ | `PROJ-001` | Project | Ecosystem detection (Node.js, Python, Go, Rust, Java, PHP) | `info` |
441
+ | `PROJ-002` | Project | Framework detection (React, Next.js, Vue, Angular, Express, FastAPI, etc.) | `info` |
442
+ | `PROJ-003` | Project | Package manager detection (npm, pnpm, yarn, poetry, cargo, etc.) | `info` |
443
+ | `PROJ-004` | Project | Repository size & file count heuristics | `info` |
444
+ | `GIT-001` | Git | Git repository initialized check | `medium` |
445
+ | `GIT-002` | Git | `.gitignore` existence | `medium` |
446
+ | `GIT-003` | Git | Generated directory ignore checks (`node_modules`, `dist`, `target`, etc.) | `medium` |
447
+ | `GIT-004` | Git | Detection of large files committed (>10 MB) | `high` |
448
+ | `GIT-005` | Git | Uncommitted changes status (informational, does not penalize) | `info` |
449
+ | `GIT-006` | Git | Empty repository (no commits) check | `low` |
450
+ | `SEC-001` | Security | `.env` not ignored by Git | `high` |
451
+ | `SEC-002` | Security | Potential credentials/secrets in source code (AWS keys, tokens, etc.) | `high` |
452
+ | `SEC-003` | Security | Private key files present (`id_rsa`, `.pem`, `.key`) | `critical` |
453
+ | `SEC-004` | Security | Tracked credential/config files (`secrets.json`, etc.) | `high` |
454
+ | `SEC-005` | Security | Credentials embedded in connection URLs | `high` |
455
+ | `DEP-001` | Dependencies | Manifest detection (`package.json`, `Cargo.toml`, etc.) | `info` |
456
+ | `DEP-002` | Dependencies | Lockfile detection (`package-lock.json`, `pnpm-lock.yaml`, etc.) | `info` |
457
+ | `DEP-003` | Dependencies | Missing lockfile when manifest is present | `medium` |
458
+ | `DEP-004` | Dependencies | Package manager / lockfile mismatch | `low` |
459
+ | `DEP-005` | Dependencies | Total dependencies declared | `info` |
460
+ | `DEP-006` | Dependencies | Suspicious dependency configuration (wildcards, git URLs, duplicate declarations) | `medium` |
461
+ | `DEP-007` | Dependencies | Known security vulnerabilities detected in dependencies (online) | `high` |
462
+ | `DEP-008` | Dependencies | Duplicate versions of the same package installed | `low` |
463
+ | `DEP-009` | Dependencies | Outdated major/minor dependencies detected (online) | `low` |
464
+ | `DEP-010` | Dependencies | Unused production dependency declared in manifest | `low` |
465
+ | `QUAL-001` | Quality | TODO comment count | `low` |
466
+ | `QUAL-002` | Quality | FIXME comment count | `medium` |
467
+ | `QUAL-003` | Quality | Debug/console statements left in code (`console.log`, `debugger`, etc.) | `low` |
468
+ | `QUAL-004` | Quality | Empty catch blocks | `medium` |
469
+ | `QUAL-005` | Quality | Extremely large source files (>500 lines) | `low` |
470
+ | `QUAL-006` | Quality | Deep directory nesting (>6 levels) | `low` |
471
+ | `TEST-001` | Testing | Standard test directory detection | `low` |
472
+ | `TEST-002` | Testing | Test files detection | `medium` |
473
+ | `TEST-003` | Testing | Test scripts in package manifest | `medium` |
474
+ | `TEST-004` | Testing | Test-to-source file ratio heuristic | `medium` |
475
+ | `DOC-001` | Documentation | `README.md` exists | `medium` |
476
+ | `DOC-002` | Documentation | Installation instructions present in README | `low` |
477
+ | `DOC-003` | Documentation | Usage instructions present in README | `low` |
478
+ | `DOC-004` | Documentation | `LICENSE` exists | `medium` |
479
+ | `DOC-005` | Documentation | `CONTRIBUTING.md` exists | `low` |
480
+ | `DOC-006` | Documentation | `SECURITY.md` exists | `low` |
481
+ | `DOC-007` | Documentation | Project description present in README | `low` |
482
+ | `CI-001` | CI/CD | GitHub Actions workflows detected | `info` |
483
+ | `CI-002` | CI/CD | CI/CD configuration presence | `medium` |
484
+ | `CI-003` | CI/CD | Test execution detected in CI | `medium` |
485
+ | `CI-004` | CI/CD | Build step detected in CI | `low` |
486
+ | `ARCH-001` | Architecture | Project layout & structure observations | `info` |
487
+ | `ARCH-002` | Architecture | Circular import dependencies detected | `high` |
488
+ | `ARCH-003` | Architecture | Suspicious cross-layer import or boundary violation | `high` |
489
+ | `ARCH-004` | Architecture | Deep fan-out coupling to internal modules | `low` |
490
+ | `ARCH-005` | Architecture | Large monolithic module decomposition indicator | `low` |
491
+ | `ARCH-006` | Architecture | Orphaned source file unreferenced across repository | `info` |
492
+
493
+ ---
494
+
495
+ ## 📈 Scoring System
496
+
497
+ Fathom calculates individual 0–100 scores for each category based on deductions from detected findings:
498
+
499
+ | Category | Weight |
500
+ |:---|:---:|
501
+ | **Security** | 20% |
502
+ | **Git** | 15% |
503
+ | **Project Structure** | 15% |
504
+ | **Testing** | 15% |
505
+ | **Dependencies** | 10% |
506
+ | **Documentation** | 10% |
507
+ | **Code Quality** | 10% |
508
+ | **CI/CD** | 5% |
509
+
510
+ ### Score Bands
511
+
512
+ - **90–100**: Excellent
513
+ - **75–89**: Healthy
514
+ - **60–74**: Fair
515
+ - **40–59**: Needs Attention
516
+ - **0–39**: Critical
517
+
518
+ ---
519
+
520
+ ## ⚙️ Configuration & Repository Targeting
521
+
522
+ ### 1. `.fathomignore`
523
+
524
+ Create a `.fathomignore` file in the root of your repository to specify repository-specific exclusion patterns using familiar gitignore-style syntax:
525
+
526
+ ```text
527
+ # Exclude code generation and vendor directories
528
+ generated/
529
+ vendor/
530
+ legacy/
531
+
532
+ # Exclude generated artifacts
533
+ *.generated.ts
534
+ *.min.js
535
+ ```
536
+
537
+ - Comments starting with `#` and blank lines are ignored.
538
+ - Trailing slashes automatically match directories and all nested contents.
539
+ - Patterns are merged deterministically with `.fathom.json` and built-in ignore lists.
540
+
541
+ ---
542
+
543
+ ### 2. `.fathom.json`
544
+
545
+ Customize rules, thresholds, and quality gates with a `.fathom.json` configuration file:
546
+
547
+ ```json
548
+ {
549
+ "version": 1,
550
+ "ignore": [
551
+ "fixtures/**"
552
+ ],
553
+ "rules": {
554
+ "QUAL-001": "warning",
555
+ "QUAL-005": "off"
556
+ },
557
+ "failUnder": 75
558
+ }
559
+ ```
560
+
561
+ #### Rule States:
562
+ - `"off"`: Disables the rule completely.
563
+ - `"warning"`: Enables the rule at warning severity.
564
+ - `"error"`: Enables the rule at error severity (triggers CI failure if violated).
565
+
566
+ #### Security Safeguards:
567
+ To prevent unintentional security vulnerabilities, Fathom **does not allow configuration to silently disable critical security checks** (e.g. `SEC-001` through `SEC-005`).
568
+ Disabling a security rule requires explicit authorization:
569
+ ```json
570
+ {
571
+ "version": 1,
572
+ "rules": {
573
+ "SEC-002": {
574
+ "enabled": false,
575
+ "reason": "Handled upstream by pre-commit secrets hook"
576
+ }
577
+ }
578
+ }
579
+ ```
580
+ Or with global opt-in:
581
+ ```json
582
+ {
583
+ "version": 1,
584
+ "allowDisableSecurity": true,
585
+ "rules": {
586
+ "SEC-003": "off"
587
+ }
588
+ }
589
+ ```
590
+ If disabled, Fathom explicitly logs a warning to stderr during analysis.
591
+
592
+ #### Configuration Precedence:
593
+ ```text
594
+ CLI Arguments (e.g. --fail-under 80, --ci, explicit flags)
595
+
596
+ .fathom.json Configuration
597
+
598
+ .fathomignore Patterns
599
+
600
+ Built-in Defaults
601
+ ```
602
+
603
+ ---
604
+
605
+ ## 🏗️ Architecture Intelligence (`--architecture`)
606
+
607
+ Fathom builds an in-memory structural graph without running any code:
608
+ - **Zero Runtime Execution**: Parses import/export relationships purely via AST text regex scanners; supports ESM, CommonJS, dynamic imports, and Python modules.
609
+ - **Path Alias Resolution**: Automatically resolves module aliases defined in `tsconfig.json` or `jsconfig.json`.
610
+ - **Cycle Detection**: Uses Tarjan's Strongly Connected Components (SCC) algorithm to detect directed import loops (`ARCH-002`).
611
+ - **Boundary Violations (`ARCH-003`)**: Flags suspicious cross-layer imports (e.g., backend importing React components or client importing `fs`/`child_process`).
612
+ - **Deep Coupling (`ARCH-004`) & Monolithic Modules (`ARCH-005`)**: Flags high fan-out files and oversized monolithic units.
613
+ - **Orphan Detection (`ARCH-006`)**: Identifies unreachable source files with confident heuristic filtering.
614
+
615
+ ---
616
+
617
+ ## 📦 Dependency Intelligence (`--deps`, `--deps --online`)
618
+
619
+ Fathom provides deep dependency insights without acting as a package manager or mutating repositories:
620
+ - **Offline-by-Default Safe Analysis (`fathom --deps`)**:
621
+ - Direct vs transitive dependency counting across multi-package projects.
622
+ - Multi-lockfile support: npm `package-lock.json` (v1, v2, v3), `yarn.lock` (line-by-line), and `pnpm-lock.yaml`.
623
+ - Duplicate dependency version detection (`DEP-008`).
624
+ - Suspicious dependency configurations (`DEP-006`: wildcards, git URLs, duplicate dev/prod declarations).
625
+ - High-confidence unused dependency detection (`DEP-010`) cross-checked against static import graphs.
626
+ - **Opt-in Online Intelligence (`fathom --deps --online`)**:
627
+ - Batch queries to OSV API (Open Source Vulnerabilities) (`DEP-007`) with strict 3s timeouts.
628
+ - Npm registry queries for outdated package detection (`DEP-009`).
629
+ - Completely silent offline fallback when network is unavailable.
630
+ - Zero repository code transmission or token leakage.
631
+
632
+ ## 🔌 Plugin Architecture
633
+
634
+ Fathom features a stable, sandboxed plugin system enabling developers to extend Fathom with custom rules and analyzers without modifying core engine code:
635
+
636
+ ```text
637
+ Fathom Core
638
+
639
+ Plugin Registry
640
+ ├── @fathom/plugin-react (Built-in)
641
+ ├── @fathom/plugin-docker
642
+ └── Community Plugins
643
+ ```
644
+
645
+ ### Stable Plugin API:
646
+ - `PluginManifest`: Defines package name, semver version, description, author, and declared rules.
647
+ - `PluginRule`: Extends Fathom rules with `recommendation`, `confidence`, `autoFixable`, and reference URLs.
648
+ - `PluginAnalyzer`: Custom analyzer contract (`id`, `name`, `category`, `description`, `analyze(context: PluginContext)`).
649
+ - `PluginContext`: Read-only, sandboxed context enforcing path traversal protections, bounded file reads (1MB limit), and structured finding creation.
650
+ - `PluginRegistry`: Lifecycle manager, schema validator, and error boundary wrapper.
651
+
652
+ ### Example Internal Plugin: `@fathom/plugin-react`
653
+ Built into Fathom as a reference implementation:
654
+ - `REACT-001` (Security / medium): `dangerouslySetInnerHTML` usage without sanitization.
655
+ - `REACT-002` (Quality / low): Array index used as key or missing key in list render.
656
+ - `REACT-003` (Quality / medium): Direct React state mutation (`this.state.x = ...`).
657
+
658
+ ### Enabling Plugins via `.fathom.json`:
659
+ ```json
660
+ {
661
+ "version": 1,
662
+ "plugins": [
663
+ "@fathom/plugin-react"
664
+ ],
665
+ "rules": {
666
+ "REACT-001": "warning"
667
+ }
668
+ }
669
+ ```
670
+
671
+ ---
672
+
673
+ ## 💻 Interactive Developer Dashboard (HTML)
674
+
675
+ Generate a polished, standalone, interactive single-file dashboard for any repository:
676
+
677
+ ```bash
678
+ fathom --html report.html
679
+ ```
680
+
681
+ Or compare against a baseline and generate an interactive regression report:
682
+
683
+ ```bash
684
+ fathom --compare --html report.html
685
+ ```
686
+
687
+ ### Dashboard Features:
688
+ - **100% Self-Contained**: Zero external CDNs, fonts, tracking scripts, or network calls. Opens instantly and safely in any browser offline or in air-gapped CI/CD environments.
689
+ - **12 Comprehensive Sections**:
690
+ 1. **Overall Health Hero**: Health score, color-coded status badge, and repository metadata tags.
691
+ 2. **Category Health Breakdown**: Visual progress bars and weighted contributions for each health dimension.
692
+ 3. **Severity Distribution**: Proportional distribution bar across Critical, High, Medium, Low, and Info findings.
693
+ 4. **Top Actionable Priorities**: Callout cards highlighting high-confidence vulnerabilities and issues requiring immediate attention.
694
+ 5. **Regression & Baseline Banner**: Real-time diff metrics highlighting score regressions and newly introduced findings.
695
+ 6. **Architecture Overview**: Graph metrics, detected layers, and circular dependency cycle warnings.
696
+ 7. **Dependency Summary**: Direct vs transitive counts, duplicate versions, and lockfile status.
697
+ 8. **Testing Maturity**: Test-to-source ratio, detected test directories, and test script presence.
698
+ 9. **Git Hygiene**: Uncommitted working tree state, large binary files, and `.gitignore` status.
699
+ 10. **Documentation Matrix**: Readiness checklist for README, LICENSE, CONTRIBUTING, and SECURITY policy.
700
+ 11. **CI/CD Automation**: GitHub Actions workflow health and automation status.
701
+ 12. **Interactive Finding Explorer**: Real-time text search, severity filter toggles, category dropdown, multi-attribute sorting (severity, rule ID, file, confidence), and collapsible syntax-highlighted code evidence viewers.
702
+ - **Deterministic & XSS-Safe**: HTML output is deterministic byte-for-byte with strict entity escaping.
703
+
704
+ ---
705
+
706
+ ## 🛡️ Security Model
707
+
708
+ Fathom treats target repositories as **untrusted input**:
709
+ - ❌ Never executes repository code or binaries
710
+ - ❌ Never installs dependencies or runs build commands
711
+ - ❌ Never transmits code or data over the network
712
+ - ❌ Never leaks or logs detected secret values (only filenames and line numbers)
713
+ - ✅ Only performs strictly bounded, read-only file inspections
714
+
715
+ ---
716
+
717
+ ## 🤝 Contributing
718
+
719
+ Contributions are welcome! Please check out [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to add rules, analyzers, or test fixtures.
720
+
721
+ ---
722
+
723
+ ## 📄 License
724
+
725
+ MIT © [Fathom Contributors](LICENSE)