@opensip-tools/fitness 1.0.4

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 (461) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-typecheck.log +4 -0
  3. package/LICENSE +21 -0
  4. package/dist/__tests__/gate.test.d.ts +13 -0
  5. package/dist/__tests__/gate.test.d.ts.map +1 -0
  6. package/dist/__tests__/gate.test.js +422 -0
  7. package/dist/__tests__/gate.test.js.map +1 -0
  8. package/dist/__tests__/sarif.test.d.ts +2 -0
  9. package/dist/__tests__/sarif.test.d.ts.map +1 -0
  10. package/dist/__tests__/sarif.test.js +169 -0
  11. package/dist/__tests__/sarif.test.js.map +1 -0
  12. package/dist/cli/dashboard.d.ts +6 -0
  13. package/dist/cli/dashboard.d.ts.map +1 -0
  14. package/dist/cli/dashboard.js +77 -0
  15. package/dist/cli/dashboard.js.map +1 -0
  16. package/dist/cli/fit.d.ts +37 -0
  17. package/dist/cli/fit.d.ts.map +1 -0
  18. package/dist/cli/fit.js +539 -0
  19. package/dist/cli/fit.js.map +1 -0
  20. package/dist/cli/list-checks.d.ts +6 -0
  21. package/dist/cli/list-checks.d.ts.map +1 -0
  22. package/dist/cli/list-checks.js +23 -0
  23. package/dist/cli/list-checks.js.map +1 -0
  24. package/dist/cli/list-recipes.d.ts +6 -0
  25. package/dist/cli/list-recipes.d.ts.map +1 -0
  26. package/dist/cli/list-recipes.js +31 -0
  27. package/dist/cli/list-recipes.js.map +1 -0
  28. package/dist/framework/__tests__/ast-utilities.test.d.ts +2 -0
  29. package/dist/framework/__tests__/ast-utilities.test.d.ts.map +1 -0
  30. package/dist/framework/__tests__/ast-utilities.test.js +153 -0
  31. package/dist/framework/__tests__/ast-utilities.test.js.map +1 -0
  32. package/dist/framework/__tests__/check-config.test.d.ts +2 -0
  33. package/dist/framework/__tests__/check-config.test.d.ts.map +1 -0
  34. package/dist/framework/__tests__/check-config.test.js +56 -0
  35. package/dist/framework/__tests__/check-config.test.js.map +1 -0
  36. package/dist/framework/__tests__/command-executor.test.d.ts +2 -0
  37. package/dist/framework/__tests__/command-executor.test.d.ts.map +1 -0
  38. package/dist/framework/__tests__/command-executor.test.js +71 -0
  39. package/dist/framework/__tests__/command-executor.test.js.map +1 -0
  40. package/dist/framework/__tests__/content-filter-dispatch.test.d.ts +2 -0
  41. package/dist/framework/__tests__/content-filter-dispatch.test.d.ts.map +1 -0
  42. package/dist/framework/__tests__/content-filter-dispatch.test.js +104 -0
  43. package/dist/framework/__tests__/content-filter-dispatch.test.js.map +1 -0
  44. package/dist/framework/__tests__/content-filter.test.d.ts +2 -0
  45. package/dist/framework/__tests__/content-filter.test.d.ts.map +1 -0
  46. package/dist/framework/__tests__/content-filter.test.js +126 -0
  47. package/dist/framework/__tests__/content-filter.test.js.map +1 -0
  48. package/dist/framework/__tests__/define-check.test.d.ts +2 -0
  49. package/dist/framework/__tests__/define-check.test.d.ts.map +1 -0
  50. package/dist/framework/__tests__/define-check.test.js +155 -0
  51. package/dist/framework/__tests__/define-check.test.js.map +1 -0
  52. package/dist/framework/__tests__/directive-inventory.test.d.ts +2 -0
  53. package/dist/framework/__tests__/directive-inventory.test.d.ts.map +1 -0
  54. package/dist/framework/__tests__/directive-inventory.test.js +44 -0
  55. package/dist/framework/__tests__/directive-inventory.test.js.map +1 -0
  56. package/dist/framework/__tests__/execution-context.test.d.ts +2 -0
  57. package/dist/framework/__tests__/execution-context.test.d.ts.map +1 -0
  58. package/dist/framework/__tests__/execution-context.test.js +62 -0
  59. package/dist/framework/__tests__/execution-context.test.js.map +1 -0
  60. package/dist/framework/__tests__/file-accessor.test.d.ts +2 -0
  61. package/dist/framework/__tests__/file-accessor.test.d.ts.map +1 -0
  62. package/dist/framework/__tests__/file-accessor.test.js +106 -0
  63. package/dist/framework/__tests__/file-accessor.test.js.map +1 -0
  64. package/dist/framework/__tests__/file-cache.test.d.ts +2 -0
  65. package/dist/framework/__tests__/file-cache.test.d.ts.map +1 -0
  66. package/dist/framework/__tests__/file-cache.test.js +122 -0
  67. package/dist/framework/__tests__/file-cache.test.js.map +1 -0
  68. package/dist/framework/__tests__/import-graph.test.d.ts +15 -0
  69. package/dist/framework/__tests__/import-graph.test.d.ts.map +1 -0
  70. package/dist/framework/__tests__/import-graph.test.js +164 -0
  71. package/dist/framework/__tests__/import-graph.test.js.map +1 -0
  72. package/dist/framework/__tests__/path-matcher.test.d.ts +2 -0
  73. package/dist/framework/__tests__/path-matcher.test.d.ts.map +1 -0
  74. package/dist/framework/__tests__/path-matcher.test.js +113 -0
  75. package/dist/framework/__tests__/path-matcher.test.js.map +1 -0
  76. package/dist/framework/__tests__/register-helpers.test.d.ts +2 -0
  77. package/dist/framework/__tests__/register-helpers.test.d.ts.map +1 -0
  78. package/dist/framework/__tests__/register-helpers.test.js +42 -0
  79. package/dist/framework/__tests__/register-helpers.test.js.map +1 -0
  80. package/dist/framework/__tests__/registry.test.d.ts +2 -0
  81. package/dist/framework/__tests__/registry.test.d.ts.map +1 -0
  82. package/dist/framework/__tests__/registry.test.js +208 -0
  83. package/dist/framework/__tests__/registry.test.js.map +1 -0
  84. package/dist/framework/__tests__/result-builder.test.d.ts +2 -0
  85. package/dist/framework/__tests__/result-builder.test.d.ts.map +1 -0
  86. package/dist/framework/__tests__/result-builder.test.js +153 -0
  87. package/dist/framework/__tests__/result-builder.test.js.map +1 -0
  88. package/dist/framework/__tests__/scope-resolver.test.d.ts +2 -0
  89. package/dist/framework/__tests__/scope-resolver.test.d.ts.map +1 -0
  90. package/dist/framework/__tests__/scope-resolver.test.js +140 -0
  91. package/dist/framework/__tests__/scope-resolver.test.js.map +1 -0
  92. package/dist/framework/__tests__/severity-mapping.test.d.ts +2 -0
  93. package/dist/framework/__tests__/severity-mapping.test.d.ts.map +1 -0
  94. package/dist/framework/__tests__/severity-mapping.test.js +42 -0
  95. package/dist/framework/__tests__/severity-mapping.test.js.map +1 -0
  96. package/dist/framework/__tests__/strip-literals.test.d.ts +2 -0
  97. package/dist/framework/__tests__/strip-literals.test.d.ts.map +1 -0
  98. package/dist/framework/__tests__/strip-literals.test.js +87 -0
  99. package/dist/framework/__tests__/strip-literals.test.js.map +1 -0
  100. package/dist/framework/abortable-exec.d.ts +34 -0
  101. package/dist/framework/abortable-exec.d.ts.map +1 -0
  102. package/dist/framework/abortable-exec.js +136 -0
  103. package/dist/framework/abortable-exec.js.map +1 -0
  104. package/dist/framework/ast-utilities.d.ts +41 -0
  105. package/dist/framework/ast-utilities.d.ts.map +1 -0
  106. package/dist/framework/ast-utilities.js +106 -0
  107. package/dist/framework/ast-utilities.js.map +1 -0
  108. package/dist/framework/check-config.d.ts +171 -0
  109. package/dist/framework/check-config.d.ts.map +1 -0
  110. package/dist/framework/check-config.js +114 -0
  111. package/dist/framework/check-config.js.map +1 -0
  112. package/dist/framework/check-types.d.ts +57 -0
  113. package/dist/framework/check-types.d.ts.map +1 -0
  114. package/dist/framework/check-types.js +35 -0
  115. package/dist/framework/check-types.js.map +1 -0
  116. package/dist/framework/command-executor.d.ts +25 -0
  117. package/dist/framework/command-executor.d.ts.map +1 -0
  118. package/dist/framework/command-executor.js +63 -0
  119. package/dist/framework/command-executor.js.map +1 -0
  120. package/dist/framework/constants.d.ts +9 -0
  121. package/dist/framework/constants.d.ts.map +1 -0
  122. package/dist/framework/constants.js +16 -0
  123. package/dist/framework/constants.js.map +1 -0
  124. package/dist/framework/content-filter.d.ts +33 -0
  125. package/dist/framework/content-filter.d.ts.map +1 -0
  126. package/dist/framework/content-filter.js +236 -0
  127. package/dist/framework/content-filter.js.map +1 -0
  128. package/dist/framework/define-check.d.ts +38 -0
  129. package/dist/framework/define-check.d.ts.map +1 -0
  130. package/dist/framework/define-check.js +252 -0
  131. package/dist/framework/define-check.js.map +1 -0
  132. package/dist/framework/directive-inventory.d.ts +34 -0
  133. package/dist/framework/directive-inventory.d.ts.map +1 -0
  134. package/dist/framework/directive-inventory.js +77 -0
  135. package/dist/framework/directive-inventory.js.map +1 -0
  136. package/dist/framework/directive-parsing.d.ts +20 -0
  137. package/dist/framework/directive-parsing.d.ts.map +1 -0
  138. package/dist/framework/directive-parsing.js +121 -0
  139. package/dist/framework/directive-parsing.js.map +1 -0
  140. package/dist/framework/execution-context.d.ts +95 -0
  141. package/dist/framework/execution-context.d.ts.map +1 -0
  142. package/dist/framework/execution-context.js +122 -0
  143. package/dist/framework/execution-context.js.map +1 -0
  144. package/dist/framework/file-accessor.d.ts +20 -0
  145. package/dist/framework/file-accessor.d.ts.map +1 -0
  146. package/dist/framework/file-accessor.js +122 -0
  147. package/dist/framework/file-accessor.js.map +1 -0
  148. package/dist/framework/file-cache.d.ts +70 -0
  149. package/dist/framework/file-cache.d.ts.map +1 -0
  150. package/dist/framework/file-cache.js +178 -0
  151. package/dist/framework/file-cache.js.map +1 -0
  152. package/dist/framework/file-type-filter.d.ts +11 -0
  153. package/dist/framework/file-type-filter.d.ts.map +1 -0
  154. package/dist/framework/file-type-filter.js +21 -0
  155. package/dist/framework/file-type-filter.js.map +1 -0
  156. package/dist/framework/ignore-processing.d.ts +22 -0
  157. package/dist/framework/ignore-processing.d.ts.map +1 -0
  158. package/dist/framework/ignore-processing.js +241 -0
  159. package/dist/framework/ignore-processing.js.map +1 -0
  160. package/dist/framework/import-graph.d.ts +51 -0
  161. package/dist/framework/import-graph.d.ts.map +1 -0
  162. package/dist/framework/import-graph.js +216 -0
  163. package/dist/framework/import-graph.js.map +1 -0
  164. package/dist/framework/memory-profiler.d.ts +53 -0
  165. package/dist/framework/memory-profiler.d.ts.map +1 -0
  166. package/dist/framework/memory-profiler.js +92 -0
  167. package/dist/framework/memory-profiler.js.map +1 -0
  168. package/dist/framework/parse-cache.d.ts +23 -0
  169. package/dist/framework/parse-cache.d.ts.map +1 -0
  170. package/dist/framework/parse-cache.js +37 -0
  171. package/dist/framework/parse-cache.js.map +1 -0
  172. package/dist/framework/path-matcher.d.ts +86 -0
  173. package/dist/framework/path-matcher.d.ts.map +1 -0
  174. package/dist/framework/path-matcher.js +138 -0
  175. package/dist/framework/path-matcher.js.map +1 -0
  176. package/dist/framework/register-helpers.d.ts +10 -0
  177. package/dist/framework/register-helpers.d.ts.map +1 -0
  178. package/dist/framework/register-helpers.js +17 -0
  179. package/dist/framework/register-helpers.js.map +1 -0
  180. package/dist/framework/registry.d.ts +41 -0
  181. package/dist/framework/registry.d.ts.map +1 -0
  182. package/dist/framework/registry.js +103 -0
  183. package/dist/framework/registry.js.map +1 -0
  184. package/dist/framework/result-builder.d.ts +74 -0
  185. package/dist/framework/result-builder.d.ts.map +1 -0
  186. package/dist/framework/result-builder.js +154 -0
  187. package/dist/framework/result-builder.js.map +1 -0
  188. package/dist/framework/scope-resolver.d.ts +23 -0
  189. package/dist/framework/scope-resolver.d.ts.map +1 -0
  190. package/dist/framework/scope-resolver.js +201 -0
  191. package/dist/framework/scope-resolver.js.map +1 -0
  192. package/dist/framework/severity-mapping.d.ts +13 -0
  193. package/dist/framework/severity-mapping.d.ts.map +1 -0
  194. package/dist/framework/severity-mapping.js +51 -0
  195. package/dist/framework/severity-mapping.js.map +1 -0
  196. package/dist/framework/strip-literals.d.ts +48 -0
  197. package/dist/framework/strip-literals.d.ts.map +1 -0
  198. package/dist/framework/strip-literals.js +188 -0
  199. package/dist/framework/strip-literals.js.map +1 -0
  200. package/dist/gate.d.ts +74 -0
  201. package/dist/gate.d.ts.map +1 -0
  202. package/dist/gate.js +257 -0
  203. package/dist/gate.js.map +1 -0
  204. package/dist/index.d.ts +47 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +51 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/plugins/__tests__/check-package-discovery.test.d.ts +2 -0
  209. package/dist/plugins/__tests__/check-package-discovery.test.d.ts.map +1 -0
  210. package/dist/plugins/__tests__/check-package-discovery.test.js +170 -0
  211. package/dist/plugins/__tests__/check-package-discovery.test.js.map +1 -0
  212. package/dist/plugins/__tests__/lang-domain.test.d.ts +2 -0
  213. package/dist/plugins/__tests__/lang-domain.test.d.ts.map +1 -0
  214. package/dist/plugins/__tests__/lang-domain.test.js +171 -0
  215. package/dist/plugins/__tests__/lang-domain.test.js.map +1 -0
  216. package/dist/plugins/__tests__/loader.test.d.ts +2 -0
  217. package/dist/plugins/__tests__/loader.test.d.ts.map +1 -0
  218. package/dist/plugins/__tests__/loader.test.js +194 -0
  219. package/dist/plugins/__tests__/loader.test.js.map +1 -0
  220. package/dist/plugins/check-package-discovery.d.ts +73 -0
  221. package/dist/plugins/check-package-discovery.d.ts.map +1 -0
  222. package/dist/plugins/check-package-discovery.js +212 -0
  223. package/dist/plugins/check-package-discovery.js.map +1 -0
  224. package/dist/plugins/loader.d.ts +31 -0
  225. package/dist/plugins/loader.d.ts.map +1 -0
  226. package/dist/plugins/loader.js +290 -0
  227. package/dist/plugins/loader.js.map +1 -0
  228. package/dist/plugins/types.d.ts +23 -0
  229. package/dist/plugins/types.d.ts.map +1 -0
  230. package/dist/plugins/types.js +9 -0
  231. package/dist/plugins/types.js.map +1 -0
  232. package/dist/recipes/__tests__/built-in-recipes.test.d.ts +2 -0
  233. package/dist/recipes/__tests__/built-in-recipes.test.d.ts.map +1 -0
  234. package/dist/recipes/__tests__/built-in-recipes.test.js +93 -0
  235. package/dist/recipes/__tests__/built-in-recipes.test.js.map +1 -0
  236. package/dist/recipes/__tests__/check-config.test.d.ts +5 -0
  237. package/dist/recipes/__tests__/check-config.test.d.ts.map +1 -0
  238. package/dist/recipes/__tests__/check-config.test.js +37 -0
  239. package/dist/recipes/__tests__/check-config.test.js.map +1 -0
  240. package/dist/recipes/__tests__/check-resolution.test.d.ts +2 -0
  241. package/dist/recipes/__tests__/check-resolution.test.d.ts.map +1 -0
  242. package/dist/recipes/__tests__/check-resolution.test.js +135 -0
  243. package/dist/recipes/__tests__/check-resolution.test.js.map +1 -0
  244. package/dist/recipes/__tests__/registry.test.d.ts +2 -0
  245. package/dist/recipes/__tests__/registry.test.d.ts.map +1 -0
  246. package/dist/recipes/__tests__/registry.test.js +97 -0
  247. package/dist/recipes/__tests__/registry.test.js.map +1 -0
  248. package/dist/recipes/__tests__/retry.test.d.ts +2 -0
  249. package/dist/recipes/__tests__/retry.test.d.ts.map +1 -0
  250. package/dist/recipes/__tests__/retry.test.js +75 -0
  251. package/dist/recipes/__tests__/retry.test.js.map +1 -0
  252. package/dist/recipes/__tests__/service.test.d.ts +11 -0
  253. package/dist/recipes/__tests__/service.test.d.ts.map +1 -0
  254. package/dist/recipes/__tests__/service.test.js +482 -0
  255. package/dist/recipes/__tests__/service.test.js.map +1 -0
  256. package/dist/recipes/built-in-recipes.d.ts +14 -0
  257. package/dist/recipes/built-in-recipes.d.ts.map +1 -0
  258. package/dist/recipes/built-in-recipes.js +247 -0
  259. package/dist/recipes/built-in-recipes.js.map +1 -0
  260. package/dist/recipes/check-config.d.ts +40 -0
  261. package/dist/recipes/check-config.d.ts.map +1 -0
  262. package/dist/recipes/check-config.js +61 -0
  263. package/dist/recipes/check-config.js.map +1 -0
  264. package/dist/recipes/check-resolution.d.ts +21 -0
  265. package/dist/recipes/check-resolution.d.ts.map +1 -0
  266. package/dist/recipes/check-resolution.js +121 -0
  267. package/dist/recipes/check-resolution.js.map +1 -0
  268. package/dist/recipes/check-result-processor.d.ts +51 -0
  269. package/dist/recipes/check-result-processor.d.ts.map +1 -0
  270. package/dist/recipes/check-result-processor.js +158 -0
  271. package/dist/recipes/check-result-processor.js.map +1 -0
  272. package/dist/recipes/parallel-execution.d.ts +33 -0
  273. package/dist/recipes/parallel-execution.d.ts.map +1 -0
  274. package/dist/recipes/parallel-execution.js +142 -0
  275. package/dist/recipes/parallel-execution.js.map +1 -0
  276. package/dist/recipes/registry.d.ts +81 -0
  277. package/dist/recipes/registry.d.ts.map +1 -0
  278. package/dist/recipes/registry.js +131 -0
  279. package/dist/recipes/registry.js.map +1 -0
  280. package/dist/recipes/retry.d.ts +25 -0
  281. package/dist/recipes/retry.d.ts.map +1 -0
  282. package/dist/recipes/retry.js +44 -0
  283. package/dist/recipes/retry.js.map +1 -0
  284. package/dist/recipes/sequential-execution.d.ts +10 -0
  285. package/dist/recipes/sequential-execution.d.ts.map +1 -0
  286. package/dist/recipes/sequential-execution.js +122 -0
  287. package/dist/recipes/sequential-execution.js.map +1 -0
  288. package/dist/recipes/service-types.d.ts +84 -0
  289. package/dist/recipes/service-types.d.ts.map +1 -0
  290. package/dist/recipes/service-types.js +8 -0
  291. package/dist/recipes/service-types.js.map +1 -0
  292. package/dist/recipes/service.d.ts +71 -0
  293. package/dist/recipes/service.d.ts.map +1 -0
  294. package/dist/recipes/service.js +331 -0
  295. package/dist/recipes/service.js.map +1 -0
  296. package/dist/recipes/types.d.ts +154 -0
  297. package/dist/recipes/types.d.ts.map +1 -0
  298. package/dist/recipes/types.js +54 -0
  299. package/dist/recipes/types.js.map +1 -0
  300. package/dist/sarif.d.ts +34 -0
  301. package/dist/sarif.d.ts.map +1 -0
  302. package/dist/sarif.js +192 -0
  303. package/dist/sarif.js.map +1 -0
  304. package/dist/signalers/__tests__/loader.test.d.ts +2 -0
  305. package/dist/signalers/__tests__/loader.test.d.ts.map +1 -0
  306. package/dist/signalers/__tests__/loader.test.js +74 -0
  307. package/dist/signalers/__tests__/loader.test.js.map +1 -0
  308. package/dist/signalers/index.d.ts +8 -0
  309. package/dist/signalers/index.d.ts.map +1 -0
  310. package/dist/signalers/index.js +9 -0
  311. package/dist/signalers/index.js.map +1 -0
  312. package/dist/signalers/loader.d.ts +24 -0
  313. package/dist/signalers/loader.d.ts.map +1 -0
  314. package/dist/signalers/loader.js +108 -0
  315. package/dist/signalers/loader.js.map +1 -0
  316. package/dist/signalers/schema.d.ts +288 -0
  317. package/dist/signalers/schema.d.ts.map +1 -0
  318. package/dist/signalers/schema.js +99 -0
  319. package/dist/signalers/schema.js.map +1 -0
  320. package/dist/signalers/types.d.ts +13 -0
  321. package/dist/signalers/types.d.ts.map +1 -0
  322. package/dist/signalers/types.js +5 -0
  323. package/dist/signalers/types.js.map +1 -0
  324. package/dist/targets/__tests__/loader.test.d.ts +2 -0
  325. package/dist/targets/__tests__/loader.test.d.ts.map +1 -0
  326. package/dist/targets/__tests__/loader.test.js +127 -0
  327. package/dist/targets/__tests__/loader.test.js.map +1 -0
  328. package/dist/targets/__tests__/resolver.test.d.ts +2 -0
  329. package/dist/targets/__tests__/resolver.test.d.ts.map +1 -0
  330. package/dist/targets/__tests__/resolver.test.js +54 -0
  331. package/dist/targets/__tests__/resolver.test.js.map +1 -0
  332. package/dist/targets/__tests__/target-registry.test.d.ts +2 -0
  333. package/dist/targets/__tests__/target-registry.test.d.ts.map +1 -0
  334. package/dist/targets/__tests__/target-registry.test.js +89 -0
  335. package/dist/targets/__tests__/target-registry.test.js.map +1 -0
  336. package/dist/targets/index.d.ts +10 -0
  337. package/dist/targets/index.d.ts.map +1 -0
  338. package/dist/targets/index.js +12 -0
  339. package/dist/targets/index.js.map +1 -0
  340. package/dist/targets/loader.d.ts +19 -0
  341. package/dist/targets/loader.d.ts.map +1 -0
  342. package/dist/targets/loader.js +159 -0
  343. package/dist/targets/loader.js.map +1 -0
  344. package/dist/targets/resolver.d.ts +19 -0
  345. package/dist/targets/resolver.d.ts.map +1 -0
  346. package/dist/targets/resolver.js +37 -0
  347. package/dist/targets/resolver.js.map +1 -0
  348. package/dist/targets/target-registry.d.ts +61 -0
  349. package/dist/targets/target-registry.d.ts.map +1 -0
  350. package/dist/targets/target-registry.js +93 -0
  351. package/dist/targets/target-registry.js.map +1 -0
  352. package/dist/targets/types.d.ts +85 -0
  353. package/dist/targets/types.d.ts.map +1 -0
  354. package/dist/targets/types.js +5 -0
  355. package/dist/targets/types.js.map +1 -0
  356. package/dist/tool.d.ts +17 -0
  357. package/dist/tool.d.ts.map +1 -0
  358. package/dist/tool.js +282 -0
  359. package/dist/tool.js.map +1 -0
  360. package/dist/types/findings.d.ts +117 -0
  361. package/dist/types/findings.d.ts.map +1 -0
  362. package/dist/types/findings.js +93 -0
  363. package/dist/types/findings.js.map +1 -0
  364. package/dist/types/severity.d.ts +15 -0
  365. package/dist/types/severity.d.ts.map +1 -0
  366. package/dist/types/severity.js +36 -0
  367. package/dist/types/severity.js.map +1 -0
  368. package/package.json +45 -0
  369. package/src/__tests__/gate.test.ts +537 -0
  370. package/src/__tests__/sarif.test.ts +201 -0
  371. package/src/cli/dashboard.ts +93 -0
  372. package/src/cli/fit.ts +612 -0
  373. package/src/cli/list-checks.ts +32 -0
  374. package/src/cli/list-recipes.ts +38 -0
  375. package/src/framework/__tests__/ast-utilities.test.ts +157 -0
  376. package/src/framework/__tests__/check-config.test.ts +65 -0
  377. package/src/framework/__tests__/command-executor.test.ts +79 -0
  378. package/src/framework/__tests__/content-filter-dispatch.test.ts +132 -0
  379. package/src/framework/__tests__/content-filter.test.ts +136 -0
  380. package/src/framework/__tests__/define-check.test.ts +180 -0
  381. package/src/framework/__tests__/directive-inventory.test.ts +53 -0
  382. package/src/framework/__tests__/execution-context.test.ts +80 -0
  383. package/src/framework/__tests__/file-accessor.test.ts +121 -0
  384. package/src/framework/__tests__/file-cache.test.ts +142 -0
  385. package/src/framework/__tests__/import-graph.test.ts +282 -0
  386. package/src/framework/__tests__/path-matcher.test.ts +130 -0
  387. package/src/framework/__tests__/register-helpers.test.ts +51 -0
  388. package/src/framework/__tests__/registry.test.ts +243 -0
  389. package/src/framework/__tests__/result-builder.test.ts +178 -0
  390. package/src/framework/__tests__/scope-resolver.test.ts +208 -0
  391. package/src/framework/__tests__/severity-mapping.test.ts +50 -0
  392. package/src/framework/__tests__/strip-literals.test.ts +109 -0
  393. package/src/framework/abortable-exec.ts +177 -0
  394. package/src/framework/ast-utilities.ts +112 -0
  395. package/src/framework/check-config.ts +339 -0
  396. package/src/framework/check-types.ts +77 -0
  397. package/src/framework/command-executor.ts +100 -0
  398. package/src/framework/constants.ts +16 -0
  399. package/src/framework/content-filter.ts +288 -0
  400. package/src/framework/define-check.ts +336 -0
  401. package/src/framework/directive-inventory.ts +110 -0
  402. package/src/framework/directive-parsing.ts +152 -0
  403. package/src/framework/execution-context.ts +247 -0
  404. package/src/framework/file-accessor.ts +171 -0
  405. package/src/framework/file-cache.ts +220 -0
  406. package/src/framework/file-type-filter.ts +25 -0
  407. package/src/framework/ignore-processing.ts +350 -0
  408. package/src/framework/import-graph.ts +280 -0
  409. package/src/framework/memory-profiler.ts +145 -0
  410. package/src/framework/parse-cache.ts +38 -0
  411. package/src/framework/path-matcher.ts +191 -0
  412. package/src/framework/register-helpers.ts +20 -0
  413. package/src/framework/registry.ts +125 -0
  414. package/src/framework/result-builder.ts +225 -0
  415. package/src/framework/scope-resolver.ts +262 -0
  416. package/src/framework/severity-mapping.ts +56 -0
  417. package/src/framework/strip-literals.ts +200 -0
  418. package/src/gate.ts +337 -0
  419. package/src/index.ts +110 -0
  420. package/src/plugins/__tests__/check-package-discovery.test.ts +204 -0
  421. package/src/plugins/__tests__/lang-domain.test.ts +198 -0
  422. package/src/plugins/__tests__/loader.test.ts +226 -0
  423. package/src/plugins/check-package-discovery.ts +242 -0
  424. package/src/plugins/loader.ts +327 -0
  425. package/src/plugins/types.ts +25 -0
  426. package/src/recipes/__tests__/built-in-recipes.test.ts +107 -0
  427. package/src/recipes/__tests__/check-config.test.ts +51 -0
  428. package/src/recipes/__tests__/check-resolution.test.ts +185 -0
  429. package/src/recipes/__tests__/registry.test.ts +115 -0
  430. package/src/recipes/__tests__/retry.test.ts +83 -0
  431. package/src/recipes/__tests__/service.test.ts +572 -0
  432. package/src/recipes/built-in-recipes.ts +273 -0
  433. package/src/recipes/check-config.ts +64 -0
  434. package/src/recipes/check-resolution.ts +169 -0
  435. package/src/recipes/check-result-processor.ts +258 -0
  436. package/src/recipes/parallel-execution.ts +220 -0
  437. package/src/recipes/registry.ts +192 -0
  438. package/src/recipes/retry.ts +69 -0
  439. package/src/recipes/sequential-execution.ts +139 -0
  440. package/src/recipes/service-types.ts +105 -0
  441. package/src/recipes/service.ts +400 -0
  442. package/src/recipes/types.ts +247 -0
  443. package/src/sarif.ts +232 -0
  444. package/src/signalers/__tests__/loader.test.ts +99 -0
  445. package/src/signalers/index.ts +9 -0
  446. package/src/signalers/loader.ts +141 -0
  447. package/src/signalers/schema.ts +117 -0
  448. package/src/signalers/types.ts +15 -0
  449. package/src/targets/__tests__/loader.test.ts +170 -0
  450. package/src/targets/__tests__/resolver.test.ts +74 -0
  451. package/src/targets/__tests__/target-registry.test.ts +103 -0
  452. package/src/targets/index.ts +13 -0
  453. package/src/targets/loader.ts +214 -0
  454. package/src/targets/resolver.ts +44 -0
  455. package/src/targets/target-registry.ts +111 -0
  456. package/src/targets/types.ts +89 -0
  457. package/src/tool.ts +302 -0
  458. package/src/types/findings.ts +239 -0
  459. package/src/types/severity.ts +39 -0
  460. package/tsconfig.json +8 -0
  461. package/vitest.config.ts +33 -0
@@ -0,0 +1,241 @@
1
+ // @fitness-ignore-file batch-operation-limits -- iterates bounded collections (config entries, registry items, or small analysis results)
2
+ // @fitness-ignore-file concurrency-safety -- Single-threaded Node.js; Map-based caches are safe without synchronization
3
+ /**
4
+ * @fileoverview Ignore directive processing for fitness checks
5
+ *
6
+ * Filters signals based on file-level and line-level ignore directives.
7
+ * Signals pointing at lines that contain @fitness-ignore directives are
8
+ * never suppressed — this prevents recursive suppression loops where
9
+ * directive-auditing checks would otherwise flag their own suppressions.
10
+ */
11
+ import { logger } from '@opensip-tools/core';
12
+ import { countErrors, countWarnings } from '../types/severity.js';
13
+ import { extractGroup, isWeakReason, parseDirectiveLine } from './directive-inventory.js';
14
+ import { parseFileIgnoreDirective, parseIgnoreDirectives } from './directive-parsing.js';
15
+ import { fileCache } from './file-cache.js';
16
+ // =============================================================================
17
+ // DIRECTIVE LINE DETECTION
18
+ // =============================================================================
19
+ /**
20
+ * Scan file content and return the set of 1-based line numbers that contain
21
+ * @fitness-ignore directives. These lines are framework infrastructure and
22
+ * must never be suppressed by other directives (prevents recursive loops).
23
+ */
24
+ function findDirectiveLines(content) {
25
+ const directiveLines = new Set();
26
+ const lines = content.split('\n');
27
+ for (const [i, line] of lines.entries()) {
28
+ const trimmed = (line ?? '').trimStart();
29
+ if ((trimmed.startsWith('//') || trimmed.startsWith('/*')) &&
30
+ trimmed.includes('@fitness-ignore')) {
31
+ directiveLines.add(i + 1);
32
+ }
33
+ }
34
+ return directiveLines;
35
+ }
36
+ /**
37
+ * Processes file ignore status and caches the result.
38
+ */
39
+ async function processFileIgnoreStatus(filePath, checkId, fileIgnoreCache, lineIgnoreCache, directiveLineCache) {
40
+ // in-memory: single-threaded Node.js access pattern
41
+ const fileIgnored = fileIgnoreCache.get(filePath);
42
+ if (fileIgnored !== undefined) {
43
+ return {
44
+ fileIgnored,
45
+ ignoredLines: lineIgnoreCache.get(filePath) ?? null,
46
+ directiveLines: directiveLineCache?.get(filePath) ?? new Set(),
47
+ };
48
+ }
49
+ try {
50
+ const content = await fileCache.get(filePath);
51
+ const isIgnored = parseFileIgnoreDirective(content, checkId);
52
+ fileIgnoreCache.set(filePath, isIgnored);
53
+ // Always scan for directive lines (needed for recursive loop prevention)
54
+ const dirLines = findDirectiveLines(content);
55
+ directiveLineCache?.set(filePath, dirLines);
56
+ let ignoredLines = null;
57
+ if (!isIgnored) {
58
+ ignoredLines = parseIgnoreDirectives(content, checkId);
59
+ lineIgnoreCache.set(filePath, ignoredLines);
60
+ }
61
+ return { fileIgnored: isIgnored, ignoredLines, directiveLines: dirLines };
62
+ }
63
+ catch (error) {
64
+ logger.warn('fitness.ignore.file_read.failed', { evt: 'fitness.ignore.file_read.failed', module: 'fitness:ignore-processing', filePath, err: error });
65
+ fileIgnoreCache.set(filePath, false);
66
+ return { fileIgnored: false, ignoredLines: null, directiveLines: new Set() };
67
+ }
68
+ }
69
+ function classifySignals(signals, initialIgnoredCount, fileIgnoreCache, lineIgnoreCache, directiveLineCache) {
70
+ const filteredSignals = [];
71
+ let ignoredCount = initialIgnoredCount;
72
+ const appliedFileIgnores = new Set();
73
+ const appliedLineIgnores = new Map();
74
+ for (const signal of signals) {
75
+ if (!isSignalIgnored(signal, fileIgnoreCache, lineIgnoreCache, directiveLineCache)) {
76
+ filteredSignals.push(signal);
77
+ continue;
78
+ }
79
+ ignoredCount++;
80
+ const filePath = signal.code?.file;
81
+ if (!filePath)
82
+ continue;
83
+ if (fileIgnoreCache.get(filePath)) {
84
+ appliedFileIgnores.add(filePath);
85
+ }
86
+ else {
87
+ const line = signal.code?.line;
88
+ if (line) {
89
+ let lineSet = appliedLineIgnores.get(filePath);
90
+ if (!lineSet) {
91
+ lineSet = new Set();
92
+ appliedLineIgnores.set(filePath, lineSet);
93
+ }
94
+ lineSet.add(line);
95
+ }
96
+ }
97
+ }
98
+ return { filteredSignals, ignoredCount, appliedFileIgnores, appliedLineIgnores };
99
+ }
100
+ /** Filter signals based on file-level and line-level @fitness-ignore directives */
101
+ export async function filterSignalsByDirectives(signals, checkId, initialIgnoredCount) {
102
+ const fileIgnoreCache = new Map();
103
+ const lineIgnoreCache = new Map();
104
+ const directiveLineCache = new Map();
105
+ // Pre-populate file ignore status for all unique file paths in parallel
106
+ const uniqueFiles = new Set();
107
+ for (const signal of signals) {
108
+ const filePath = signal.code?.file;
109
+ if (filePath)
110
+ uniqueFiles.add(filePath);
111
+ }
112
+ await Promise.all([...uniqueFiles].map((filePath) => processFileIgnoreStatus(filePath, checkId, fileIgnoreCache, lineIgnoreCache, directiveLineCache)));
113
+ const { filteredSignals, ignoredCount, appliedFileIgnores, appliedLineIgnores } = classifySignals(signals, initialIgnoredCount, fileIgnoreCache, lineIgnoreCache, directiveLineCache);
114
+ const appliedDirectives = await collectAppliedDirectives(checkId, appliedFileIgnores, appliedLineIgnores);
115
+ return { filteredSignals, ignoredCount, appliedDirectives };
116
+ }
117
+ /**
118
+ * Determines whether a single signal should be ignored based on cached directive data.
119
+ *
120
+ * File-level ignores always apply (the entire file is suppressed).
121
+ * Line-level ignores apply unless the signal points at a directive line itself
122
+ * (prevents recursive loops where directive-auditing checks suppress their own findings).
123
+ */
124
+ function isSignalIgnored(signal, fileIgnoreCache, lineIgnoreCache, directiveLineCache) {
125
+ const filePath = signal.code?.file;
126
+ if (!filePath)
127
+ return false;
128
+ // File-level ignores always apply — no anti-recursion needed
129
+ if (fileIgnoreCache.get(filePath))
130
+ return true;
131
+ const signalLine = signal.code?.line;
132
+ const dirLines = directiveLineCache.get(filePath);
133
+ // For line-level ignores: never suppress signals pointing at directive lines (anti-recursion)
134
+ if (signalLine && dirLines?.has(signalLine))
135
+ return false;
136
+ const ignoredLines = lineIgnoreCache.get(filePath);
137
+ if (signalLine && ignoredLines?.has(signalLine))
138
+ return true;
139
+ return false;
140
+ }
141
+ // =============================================================================
142
+ // APPLIED DIRECTIVE COLLECTION
143
+ // =============================================================================
144
+ function toDirectiveEntry(filePath, lineNumber, parsed) {
145
+ return {
146
+ filePath,
147
+ lineNumber,
148
+ type: parsed.type,
149
+ checkId: parsed.checkId,
150
+ group: extractGroup(parsed.checkId),
151
+ reason: parsed.reason,
152
+ weakReason: isWeakReason(parsed.reason),
153
+ };
154
+ }
155
+ async function collectFileIgnoreDirectives(checkId, appliedFileIgnores) {
156
+ const results = await Promise.all([...appliedFileIgnores].map(async (filePath) => {
157
+ try {
158
+ const content = await fileCache.get(filePath);
159
+ const lines = content.split('\n');
160
+ for (let i = 0; i < Math.min(lines.length, 50); i++) {
161
+ const parsed = parseDirectiveLine(lines[i] ?? '');
162
+ if (parsed?.type === 'file' && parsed.checkId === checkId) {
163
+ return toDirectiveEntry(filePath, i + 1, parsed);
164
+ }
165
+ }
166
+ }
167
+ catch (error) {
168
+ logger.warn('fitness.ignore.directive_read.failed', { evt: 'fitness.ignore.directive_read.failed', module: 'fitness:ignore-processing', err: error });
169
+ }
170
+ return null;
171
+ }));
172
+ return results.filter((d) => d !== null);
173
+ }
174
+ async function collectLineIgnoreDirectives(checkId, appliedLineIgnores) {
175
+ const results = await Promise.all([...appliedLineIgnores.entries()].map(async ([filePath, suppressedLines]) => {
176
+ const found = [];
177
+ try {
178
+ const content = await fileCache.get(filePath);
179
+ const lines = content.split('\n');
180
+ for (let i = 0; i < lines.length; i++) {
181
+ const parsed = parseDirectiveLine(lines[i] ?? '');
182
+ if (parsed?.type !== 'next-line' || parsed.checkId !== checkId)
183
+ continue;
184
+ let targetLine = i + 1;
185
+ while (targetLine < lines.length && (lines[targetLine] ?? '').trimStart().startsWith('//')) {
186
+ targetLine++;
187
+ }
188
+ if (suppressedLines.has(targetLine + 1)) {
189
+ found.push(toDirectiveEntry(filePath, i + 1, parsed));
190
+ }
191
+ }
192
+ }
193
+ catch (error) {
194
+ logger.warn('fitness.ignore.directive_read.failed', { evt: 'fitness.ignore.directive_read.failed', module: 'fitness:ignore-processing', err: error });
195
+ }
196
+ return found;
197
+ }));
198
+ const directives = [];
199
+ for (const batch of results) {
200
+ for (const d of batch) {
201
+ directives.push(d);
202
+ }
203
+ }
204
+ return directives;
205
+ }
206
+ async function collectAppliedDirectives(checkId, appliedFileIgnores, appliedLineIgnores) {
207
+ const [fileDirectives, lineDirectives] = await Promise.all([
208
+ collectFileIgnoreDirectives(checkId, appliedFileIgnores),
209
+ collectLineIgnoreDirectives(checkId, appliedLineIgnores),
210
+ ]);
211
+ return [...fileDirectives, ...lineDirectives];
212
+ }
213
+ // =============================================================================
214
+ // RESULT BUILDING
215
+ // =============================================================================
216
+ /**
217
+ * Builds the filtered result from the original result and filtered signals.
218
+ */
219
+ export function buildFilteredResult(result, filteredSignals, ignoredCount, start) {
220
+ if (!Array.isArray(filteredSignals)) {
221
+ return result;
222
+ }
223
+ const durationMs = result.metadata.durationMs ?? Date.now() - start;
224
+ const filteredErrors = countErrors(filteredSignals);
225
+ const filteredWarnings = countWarnings(filteredSignals);
226
+ const filteredResult = {
227
+ ...result,
228
+ passed: filteredErrors === 0,
229
+ errors: filteredErrors,
230
+ warnings: filteredWarnings,
231
+ signals: filteredSignals,
232
+ metadata: {
233
+ ...result.metadata,
234
+ durationMs,
235
+ signals: filteredSignals,
236
+ },
237
+ ...(ignoredCount > 0 ? { ignoredCount } : {}),
238
+ };
239
+ return filteredResult;
240
+ }
241
+ //# sourceMappingURL=ignore-processing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore-processing.js","sourceRoot":"","sources":["../../src/framework/ignore-processing.ts"],"names":[],"mappings":"AAAA,0IAA0I;AAC1I,wHAAwH;AACxH;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAG5C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAM3C,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,CAAA;QACxC,IACE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EACnC,CAAC;YACD,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC;AAaD;;GAEG;AACH,KAAK,UAAU,uBAAuB,CACpC,QAAgB,EAChB,OAAe,EACf,eAAqC,EACrC,eAAyC,EACzC,kBAA6C;IAE7C,oDAAoD;IACpD,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAEjD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;YACL,WAAW;YACX,YAAY,EAAE,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI;YACnD,cAAc,EAAE,kBAAkB,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,EAAE;SAC/D,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7C,MAAM,SAAS,GAAG,wBAAwB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC5D,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;QAExC,yEAAyE;QACzE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;QAC5C,kBAAkB,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAE3C,IAAI,YAAY,GAAuB,IAAI,CAAA;QAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,YAAY,GAAG,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACtD,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAC7C,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAA;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,GAAG,EAAE,iCAAiC,EAAE,MAAM,EAAE,2BAA2B,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACtJ,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACpC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,GAAG,EAAE,EAAE,CAAA;IAC9E,CAAC;AACH,CAAC;AAqBD,SAAS,eAAe,CACtB,OAA0B,EAC1B,mBAA2B,EAC3B,eAAqC,EACrC,eAAyC,EACzC,kBAA4C;IAE5C,MAAM,eAAe,GAAa,EAAE,CAAA;IACpC,IAAI,YAAY,GAAG,mBAAmB,CAAA;IACtC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAA;IAC5C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAuB,CAAA;IAEzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,CAAC,EAAE,CAAC;YACnF,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC5B,SAAQ;QACV,CAAC;QACD,YAAY,EAAE,CAAA;QACd,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAA;QAClC,IAAI,CAAC,QAAQ;YAAE,SAAQ;QAEvB,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAA;YAC9B,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,GAAG,IAAI,GAAG,EAAE,CAAA;oBACnB,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;gBAC3C,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAA;AAClF,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAA0B,EAC1B,OAAe,EACf,mBAA2B;IAE3B,MAAM,eAAe,GAAG,IAAI,GAAG,EAAmB,CAAA;IAClD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAuB,CAAA;IACtD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAuB,CAAA;IAEzD,wEAAwE;IACxE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IACrC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAA;QAClC,IAAI,QAAQ;YAAE,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACzC,CAAC;IACD,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAChC,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,CAAC,CACjG,CACF,CAAA;IAED,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,GAC7E,eAAe,CAAC,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAA;IAErG,MAAM,iBAAiB,GAAG,MAAM,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAAA;IAEzG,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,MAAc,EACd,eAAqC,EACrC,eAAyC,EACzC,kBAA4C;IAE5C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAA;IAClC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAA;IAE3B,6DAA6D;IAC7D,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IAE9C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAA;IACpC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACjD,8FAA8F;IAC9F,IAAI,UAAU,IAAI,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IAEzD,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClD,IAAI,UAAU,IAAI,YAAY,EAAE,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAA;IAE5D,OAAO,KAAK,CAAA;AACd,CAAC;AAED,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,SAAS,gBAAgB,CACvB,QAAgB,EAChB,UAAkB,EAClB,MAA8E;IAE9E,OAAO;QACL,QAAQ;QACR,UAAU;QACV,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;QACnC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC;KACxC,CAAA;AACH,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,OAAe,EACf,kBAA+B;IAE/B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,CAAC,GAAG,kBAAkB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAkC,EAAE;QAC7E,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;gBACjD,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;oBAC1D,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,EAAE,GAAG,EAAE,sCAAsC,EAAE,MAAM,EAAE,2BAA2B,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACxJ,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CACH,CAAA;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;AAC/D,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,OAAe,EACf,kBAA4C;IAE5C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,CAAC,GAAG,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,EAA6B,EAAE;QACrG,MAAM,KAAK,GAAqB,EAAE,CAAA;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;gBACjD,IAAI,MAAM,EAAE,IAAI,KAAK,WAAW,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO;oBAAE,SAAQ;gBACxE,IAAI,UAAU,GAAG,CAAC,GAAG,CAAC,CAAA;gBACtB,OAAO,UAAU,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3F,UAAU,EAAE,CAAA;gBACd,CAAC;gBACD,IAAI,eAAe,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;gBACvD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,EAAE,GAAG,EAAE,sCAAsC,EAAE,MAAM,EAAE,2BAA2B,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACxJ,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CACH,CAAA;IACD,MAAM,UAAU,GAAqB,EAAE,CAAA;IACvC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,OAAe,EACf,kBAA+B,EAC/B,kBAA4C;IAE5C,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,2BAA2B,CAAC,OAAO,EAAE,kBAAkB,CAAC;QACxD,2BAA2B,CAAC,OAAO,EAAE,kBAAkB,CAAC;KACzD,CAAC,CAAA;IACF,OAAO,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC,CAAA;AAC/C,CAAC;AAED,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAmB,EACnB,eAAyB,EACzB,YAAoB,EACpB,KAAa;IAEb,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;IACnE,MAAM,cAAc,GAAG,WAAW,CAAC,eAAe,CAAC,CAAA;IACnD,MAAM,gBAAgB,GAAG,aAAa,CAAC,eAAe,CAAC,CAAA;IAEvD,MAAM,cAAc,GAAgB;QAClC,GAAG,MAAM;QACT,MAAM,EAAE,cAAc,KAAK,CAAC;QAC5B,MAAM,EAAE,cAAc;QACtB,QAAQ,EAAE,gBAAgB;QAC1B,OAAO,EAAE,eAAe;QACxB,QAAQ,EAAE;YACR,GAAG,MAAM,CAAC,QAAQ;YAClB,UAAU;YACV,OAAO,EAAE,eAAe;SACzB;QACD,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAA;IAED,OAAO,cAAc,CAAA;AACvB,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @fileoverview Project-wide import graph builder.
3
+ *
4
+ * Builds a file-level dependency graph from a set of TypeScript/JavaScript
5
+ * source files, plus a Tarjan's strongly-connected-components implementation
6
+ * for cycle detection. Used by structural-drift checks like
7
+ * circular-import-detection and module-coupling-fan-out.
8
+ *
9
+ * Module resolution is deliberately a heuristic: relative imports are
10
+ * resolved by trying common extension/index.ts suffixes; bare specifiers
11
+ * (npm packages) are dropped; tsconfig path aliases are NOT resolved
12
+ * (treated as unresolved — they simply don't appear as edges in the graph).
13
+ *
14
+ * This matches the heuristic the existing `phantom-dependency-detection`
15
+ * check uses, which has been shipping reliably. Adding tsconfig-aware
16
+ * resolution is a follow-up plan.
17
+ */
18
+ /** A file-level import graph for a project. */
19
+ export interface ImportGraph {
20
+ /** All node file paths (absolute, as supplied by the caller). */
21
+ readonly nodes: ReadonlySet<string>;
22
+ /** Adjacency: file → set of files it imports (intra-project edges only). */
23
+ readonly outbound: ReadonlyMap<string, ReadonlySet<string>>;
24
+ /** Reverse adjacency: file → set of files that import it. */
25
+ readonly inbound: ReadonlyMap<string, ReadonlySet<string>>;
26
+ }
27
+ /**
28
+ * Build an import graph from a collection of file paths and their content.
29
+ *
30
+ * Each file's TS AST is walked for top-level `import` and `export ... from`
31
+ * declarations. Relative specifiers (`./foo`, `../bar/baz.js`) are resolved
32
+ * against the importing file's directory using the heuristic in
33
+ * `resolveRelativeSpecifier`. Bare specifiers (`react`, `lodash`) are
34
+ * dropped — they don't represent intra-project edges.
35
+ *
36
+ * Files that fail to parse are still added as nodes (with no edges) so the
37
+ * graph remains complete.
38
+ */
39
+ export declare function buildImportGraph(files: ReadonlyMap<string, string>): ImportGraph;
40
+ /**
41
+ * Find strongly-connected components in the graph using Tarjan's algorithm.
42
+ *
43
+ * Returns an array of SCCs, each represented as an array of node names. SCCs
44
+ * of size 1 represent a node with no cycle (or a self-loop, which is rare in
45
+ * import graphs). Cycle-detection callers typically filter to `scc.length > 1`
46
+ * to get only real multi-file cycles.
47
+ *
48
+ * Algorithm: standard iterative Tarjan's SCC. O(V + E), single pass.
49
+ */
50
+ export declare function findStronglyConnectedComponents(graph: ImportGraph): readonly (readonly string[])[];
51
+ //# sourceMappingURL=import-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-graph.d.ts","sourceRoot":"","sources":["../../src/framework/import-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3D,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;CAC3D;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAwBhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,WAAW,GACjB,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAiGhC"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @fileoverview Project-wide import graph builder.
3
+ *
4
+ * Builds a file-level dependency graph from a set of TypeScript/JavaScript
5
+ * source files, plus a Tarjan's strongly-connected-components implementation
6
+ * for cycle detection. Used by structural-drift checks like
7
+ * circular-import-detection and module-coupling-fan-out.
8
+ *
9
+ * Module resolution is deliberately a heuristic: relative imports are
10
+ * resolved by trying common extension/index.ts suffixes; bare specifiers
11
+ * (npm packages) are dropped; tsconfig path aliases are NOT resolved
12
+ * (treated as unresolved — they simply don't appear as edges in the graph).
13
+ *
14
+ * This matches the heuristic the existing `phantom-dependency-detection`
15
+ * check uses, which has been shipping reliably. Adding tsconfig-aware
16
+ * resolution is a follow-up plan.
17
+ */
18
+ import * as path from 'node:path';
19
+ import ts from 'typescript';
20
+ import { getSharedSourceFile } from './parse-cache.js';
21
+ // =============================================================================
22
+ // PUBLIC API
23
+ // =============================================================================
24
+ /**
25
+ * Build an import graph from a collection of file paths and their content.
26
+ *
27
+ * Each file's TS AST is walked for top-level `import` and `export ... from`
28
+ * declarations. Relative specifiers (`./foo`, `../bar/baz.js`) are resolved
29
+ * against the importing file's directory using the heuristic in
30
+ * `resolveRelativeSpecifier`. Bare specifiers (`react`, `lodash`) are
31
+ * dropped — they don't represent intra-project edges.
32
+ *
33
+ * Files that fail to parse are still added as nodes (with no edges) so the
34
+ * graph remains complete.
35
+ */
36
+ export function buildImportGraph(files) {
37
+ const nodes = new Set(files.keys());
38
+ const outbound = new Map();
39
+ const inbound = new Map();
40
+ // Initialize empty edge sets for every node so callers can safely
41
+ // outbound.get(file) without checking for undefined.
42
+ for (const node of nodes) {
43
+ outbound.set(node, new Set());
44
+ inbound.set(node, new Set());
45
+ }
46
+ for (const [filePath, content] of files) {
47
+ const specifiers = extractImportSpecifiers(filePath, content);
48
+ for (const spec of specifiers) {
49
+ const resolved = resolveRelativeSpecifier(filePath, spec, nodes);
50
+ if (resolved !== null) {
51
+ outbound.get(filePath).add(resolved);
52
+ inbound.get(resolved).add(filePath);
53
+ }
54
+ }
55
+ }
56
+ return { nodes, outbound, inbound };
57
+ }
58
+ /**
59
+ * Find strongly-connected components in the graph using Tarjan's algorithm.
60
+ *
61
+ * Returns an array of SCCs, each represented as an array of node names. SCCs
62
+ * of size 1 represent a node with no cycle (or a self-loop, which is rare in
63
+ * import graphs). Cycle-detection callers typically filter to `scc.length > 1`
64
+ * to get only real multi-file cycles.
65
+ *
66
+ * Algorithm: standard iterative Tarjan's SCC. O(V + E), single pass.
67
+ */
68
+ export function findStronglyConnectedComponents(graph) {
69
+ const indexOf = new Map();
70
+ const lowlinkOf = new Map();
71
+ const onStack = new Set();
72
+ const stack = [];
73
+ const sccs = [];
74
+ let nextIndex = 0;
75
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- iterative Tarjan SCC: explicit stack to avoid recursion; the algorithm is canonical and reads cleanest as a single function
76
+ function strongConnect(start) {
77
+ const callStack = [];
78
+ indexOf.set(start, nextIndex);
79
+ lowlinkOf.set(start, nextIndex);
80
+ nextIndex++;
81
+ stack.push(start);
82
+ onStack.add(start);
83
+ callStack.push({
84
+ node: start,
85
+ neighbors: [...(graph.outbound.get(start) ?? [])],
86
+ next: 0,
87
+ });
88
+ while (callStack.length > 0) {
89
+ const frame = callStack.at(-1);
90
+ if (frame.next < frame.neighbors.length) {
91
+ const w = frame.neighbors[frame.next];
92
+ frame.next++;
93
+ if (!indexOf.has(w)) {
94
+ // Recurse into w.
95
+ indexOf.set(w, nextIndex);
96
+ lowlinkOf.set(w, nextIndex);
97
+ nextIndex++;
98
+ stack.push(w);
99
+ onStack.add(w);
100
+ callStack.push({
101
+ node: w,
102
+ neighbors: [...(graph.outbound.get(w) ?? [])],
103
+ next: 0,
104
+ });
105
+ continue;
106
+ }
107
+ if (onStack.has(w)) {
108
+ // Back edge — update v's lowlink.
109
+ const vLow = lowlinkOf.get(frame.node);
110
+ const wIdx = indexOf.get(w);
111
+ if (wIdx < vLow)
112
+ lowlinkOf.set(frame.node, wIdx);
113
+ }
114
+ continue;
115
+ }
116
+ // All neighbors processed — finalize this node.
117
+ const v = frame.node;
118
+ const vLow = lowlinkOf.get(v);
119
+ const vIdx = indexOf.get(v);
120
+ if (vLow === vIdx) {
121
+ // v is the root of an SCC — pop until v is removed.
122
+ const scc = [];
123
+ let w;
124
+ do {
125
+ w = stack.pop();
126
+ onStack.delete(w);
127
+ scc.push(w);
128
+ } while (w !== v);
129
+ sccs.push(scc);
130
+ }
131
+ callStack.pop();
132
+ // Propagate lowlink up to the parent frame.
133
+ if (callStack.length > 0) {
134
+ const parent = callStack.at(-1);
135
+ const parentLow = lowlinkOf.get(parent.node);
136
+ if (vLow < parentLow)
137
+ lowlinkOf.set(parent.node, vLow);
138
+ }
139
+ }
140
+ }
141
+ for (const node of graph.nodes) {
142
+ if (!indexOf.has(node)) {
143
+ strongConnect(node);
144
+ }
145
+ }
146
+ return sccs;
147
+ }
148
+ // =============================================================================
149
+ // INTERNAL HELPERS
150
+ // =============================================================================
151
+ /** Walk the AST and collect top-level import / export-from specifiers. */
152
+ function extractImportSpecifiers(filePath, content) {
153
+ const sourceFile = getSharedSourceFile(filePath, content);
154
+ if (sourceFile === null)
155
+ return [];
156
+ const specifiers = [];
157
+ for (const stmt of sourceFile.statements) {
158
+ // import foo from './bar'; import './side-effect'; import * as ns from './m';
159
+ if (ts.isImportDeclaration(stmt) && ts.isStringLiteral(stmt.moduleSpecifier)) {
160
+ specifiers.push(stmt.moduleSpecifier.text);
161
+ continue;
162
+ }
163
+ // export * from './foo'; export { x } from './foo';
164
+ if (ts.isExportDeclaration(stmt) &&
165
+ stmt.moduleSpecifier !== undefined &&
166
+ ts.isStringLiteral(stmt.moduleSpecifier)) {
167
+ specifiers.push(stmt.moduleSpecifier.text);
168
+ }
169
+ }
170
+ return specifiers;
171
+ }
172
+ /**
173
+ * Resolve a module specifier to an actual file path in the project, or
174
+ * return null if the specifier is non-relative (npm package, path alias) or
175
+ * doesn't resolve to a known project file.
176
+ *
177
+ * Supports:
178
+ * - `./foo` → `<dir>/foo.ts`, `.tsx`, `/index.ts`, `/index.tsx`
179
+ * - `./foo.js` → `<dir>/foo.ts` (ESM extension swap, common in TS+ESM)
180
+ * - `./foo.ts` → `<dir>/foo.ts` (literal)
181
+ * - `../bar/baz` → resolved relative to importer's directory
182
+ *
183
+ * Does NOT support:
184
+ * - tsconfig `paths` aliases (deferred per plan)
185
+ * - npm packages (correctly dropped — out of scope for intra-project graph)
186
+ */
187
+ function resolveRelativeSpecifier(importerPath, specifier, knownPaths) {
188
+ // Only relative specifiers participate in the intra-project graph.
189
+ if (!specifier.startsWith('.'))
190
+ return null;
191
+ const importerDir = path.dirname(importerPath);
192
+ const base = path.resolve(importerDir, specifier);
193
+ // Try the candidate paths in priority order. The first one that exists in
194
+ // the project's file set wins.
195
+ const candidates = [base];
196
+ // 1. Literal path (specifier already includes extension).
197
+ // 2. ESM extension swap: `.js` → `.ts` / `.tsx` (TypeScript ESM convention).
198
+ if (base.endsWith('.js')) {
199
+ candidates.push(base.slice(0, -3) + '.ts', base.slice(0, -3) + '.tsx');
200
+ }
201
+ if (base.endsWith('.jsx')) {
202
+ candidates.push(base.slice(0, -4) + '.tsx');
203
+ }
204
+ // 3. Append common extensions if the specifier was extension-less.
205
+ const hasExt = path.extname(base) !== '';
206
+ if (!hasExt) {
207
+ // Direct extensions and index resolution.
208
+ candidates.push(base + '.ts', base + '.tsx', base + '.js', base + '.jsx', path.join(base, 'index.ts'), path.join(base, 'index.tsx'), path.join(base, 'index.js'), path.join(base, 'index.jsx'));
209
+ }
210
+ for (const candidate of candidates) {
211
+ if (knownPaths.has(candidate))
212
+ return candidate;
213
+ }
214
+ return null;
215
+ }
216
+ //# sourceMappingURL=import-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-graph.js","sourceRoot":"","sources":["../../src/framework/import-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @fileoverview Memory profiler for fitness checks
3
+ *
4
+ * Always-on, low-overhead memory tracking for check execution.
5
+ * Collects per-check profiles for trending analysis.
6
+ */
7
+ /** Memory usage profile recorded for a single check execution */
8
+ export interface CheckMemoryProfile {
9
+ readonly checkId: string;
10
+ readonly memoryBeforeMB: number;
11
+ readonly memoryAfterMB: number;
12
+ readonly memoryDeltaMB: number;
13
+ readonly violationCount: number;
14
+ readonly durationMs: number;
15
+ }
16
+ /** Aggregated memory profiling summary across all check executions */
17
+ interface MemoryProfileSummary {
18
+ readonly prewarmMemoryMB: number;
19
+ readonly peakMemoryMB: number;
20
+ readonly checksExceedingThreshold: number;
21
+ readonly topConsumers: readonly CheckMemoryProfile[];
22
+ readonly allProfiles: readonly CheckMemoryProfile[];
23
+ }
24
+ /** Low-overhead memory profiler that tracks per-check heap usage during fitness runs */
25
+ declare class MemoryProfiler {
26
+ private readonly profiles;
27
+ private prewarmMemoryMB;
28
+ private peakMemoryMB;
29
+ private readonly warningThresholdMB;
30
+ constructor(warningThresholdMB?: number);
31
+ private takeSnapshot;
32
+ private bytesToMB;
33
+ /** Record memory baseline after cache prewarm completes */
34
+ recordPrewarmComplete(): void;
35
+ /** Return current heap usage in megabytes */
36
+ getCurrentMemoryMB(): number;
37
+ /** Record memory before a check starts; returns the pre-check heap in MB */
38
+ recordCheckStart(): number;
39
+ /** Record memory after a check completes and return the check's memory profile */
40
+ recordCheckComplete(checkId: string, memoryBeforeMB: number, violationCount: number, durationMs: number): CheckMemoryProfile;
41
+ /** Check whether a memory delta exceeds the configured warning threshold */
42
+ exceedsThreshold(deltaMB: number): boolean;
43
+ /** Return the configured warning threshold in megabytes */
44
+ getWarningThresholdMB(): number;
45
+ /** Build and return an aggregated summary of all recorded check profiles */
46
+ getSummary(): MemoryProfileSummary;
47
+ /** Reset all recorded profiles and counters */
48
+ reset(): void;
49
+ }
50
+ /** Shared singleton memory profiler instance used across fitness check runs */
51
+ export declare const memoryProfiler: MemoryProfiler;
52
+ export {};
53
+ //# sourceMappingURL=memory-profiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-profiler.d.ts","sourceRoot":"","sources":["../../src/framework/memory-profiler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,iEAAiE;AACjE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,sEAAsE;AACtE,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAA;IACzC,QAAQ,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACpD,QAAQ,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAA;CACpD;AAID,wFAAwF;AACxF,cAAM,cAAc;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAQ;gBAE/B,kBAAkB,SAAsC;IAIpE,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,SAAS;IAIjB,2DAA2D;IAC3D,qBAAqB,IAAI,IAAI;IAM7B,6CAA6C;IAC7C,kBAAkB,IAAI,MAAM;IAK5B,4EAA4E;IAC5E,gBAAgB,IAAI,MAAM;IAI1B,kFAAkF;IAClF,mBAAmB,CACjB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GACjB,kBAAkB;IAqBrB,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI1C,2DAA2D;IAC3D,qBAAqB,IAAI,MAAM;IAI/B,4EAA4E;IAC5E,UAAU,IAAI,oBAAoB;IAgBlC,+CAA+C;IAC/C,KAAK,IAAI,IAAI;CAKd;AAED,+EAA+E;AAC/E,eAAO,MAAM,cAAc,gBAAuB,CAAA"}