@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,200 @@
1
+ /**
2
+ * @fileoverview Shared utilities for stripping string literal and comment
3
+ * content from source code. Used by fitness checks to avoid false positives
4
+ * from patterns appearing inside string literals or comments.
5
+ */
6
+
7
+ /**
8
+ * Strip string literal contents from a single line.
9
+ * Replaces content inside '...', "...", and `...` with empty strings.
10
+ * Used by checks for per-line pattern matching to avoid false positives
11
+ * from patterns appearing inside string literals.
12
+ */
13
+ export function stripStringLiterals(line: string): string {
14
+ return line
15
+ .replaceAll(/'(?:[^'\\]|\\.)*'/g, "''")
16
+ .replaceAll(/"(?:[^"\\]|\\.)*"/g, '""')
17
+ .replaceAll(/`(?:[^`\\]|\\.)*`/gs, '``')
18
+ }
19
+
20
+ /** Shared regex patterns for string literal replacement */
21
+ const SINGLE_QUOTE_RE = /'(?:[^'\\]|\\.)*'/g
22
+ const DOUBLE_QUOTE_RE = /"(?:[^"\\]|\\.)*"/g
23
+ const BACKTICK_RE = /`(?:[^`\\]|\\.)*`/gs
24
+
25
+ /**
26
+ * Strip string literals and single-line comments from full file content.
27
+ * Used by checks for quick-filter gates to avoid matching keywords
28
+ * that only appear in documentation strings or comments.
29
+ */
30
+ /**
31
+ * Check if a position in a line is inside a string literal.
32
+ * Scans characters before the match position for unescaped quotes/backticks.
33
+ * Used by checks to avoid false positives from suggestion/description text.
34
+ */
35
+ export function isInsideStringLiteral(line: string, matchIndex: number): boolean {
36
+ let inSingle = false
37
+ let inDouble = false
38
+ let inTemplate = false
39
+ let escaped = false
40
+
41
+ for (let i = 0; i < matchIndex; i++) {
42
+ const ch = line[i]
43
+
44
+ if (escaped) {
45
+ escaped = false
46
+ continue
47
+ }
48
+
49
+ if (ch === '\\' && (inSingle || inDouble || inTemplate)) {
50
+ escaped = true
51
+ continue
52
+ }
53
+
54
+ if (ch === "'" && !inDouble && !inTemplate) inSingle = !inSingle
55
+ else if (ch === '"' && !inSingle && !inTemplate) inDouble = !inDouble
56
+ else if (ch === '`' && !inSingle && !inDouble) inTemplate = !inTemplate
57
+ }
58
+
59
+ return inSingle || inDouble || inTemplate
60
+ }
61
+
62
+ /**
63
+ * Strip string literals and single-line comments from full file content.
64
+ * Used by checks for quick-filter gates to avoid matching keywords
65
+ * that only appear in documentation strings or comments.
66
+ */
67
+ export function stripStringsAndComments(content: string): string {
68
+ // Strip string literals first
69
+ let result = content
70
+ .replaceAll(SINGLE_QUOTE_RE, "''")
71
+ .replaceAll(DOUBLE_QUOTE_RE, '""')
72
+ .replaceAll(BACKTICK_RE, '``')
73
+ // Strip single-line comments (after string stripping to avoid matching // inside strings)
74
+ // eslint-disable-next-line sonarjs/slow-regex -- .*$ anchored to line end; linear scan
75
+ result = result.replaceAll(/\/\/.*$/gm, '')
76
+ return result
77
+ }
78
+
79
+ /**
80
+ * Strip strings, single-line comments, AND block comments while preserving
81
+ * BOTH character positions and line numbers. Each stripped character is
82
+ * replaced with a space (non-newline) so the output has identical length
83
+ * and line offsets to the input. Use this when downstream processing
84
+ * needs to map a match index back to a line number in the ORIGINAL
85
+ * source — `stripStringsAndComments` collapses string literals to empty
86
+ * pairs, which shifts indexes and breaks `getLineNumber(content, idx)`.
87
+ *
88
+ * Strips:
89
+ * - Single-quoted, double-quoted, and template-literal string contents
90
+ * - Single-line `// ...` comments (to end of line)
91
+ * - Block `/* ... *\/` comments (including JSDoc `/** ... *\/`)
92
+ *
93
+ * Preserves: newlines, total character count, character positions of
94
+ * code OUTSIDE these regions.
95
+ */
96
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- token-state-machine: single-pass tokenizer, branches reflect quote/comment state
97
+ export function stripStringsAndCommentsPreservingPositions(content: string): string {
98
+ const out: string[] = []
99
+ let i = 0
100
+ let inSingle = false
101
+ let inDouble = false
102
+ let inTemplate = false
103
+ let inLineComment = false
104
+ let inBlockComment = false
105
+ let escaped = false
106
+
107
+ while (i < content.length) {
108
+ const ch = content[i]
109
+ const next = content[i + 1]
110
+
111
+ // Inside any string: blank out chars (preserve newlines) until terminator.
112
+ if (inSingle || inDouble || inTemplate) {
113
+ if (escaped) {
114
+ out.push(ch === '\n' ? '\n' : ' ')
115
+ escaped = false
116
+ i++
117
+ continue
118
+ }
119
+ if (ch === '\\') {
120
+ out.push(' ')
121
+ escaped = true
122
+ i++
123
+ continue
124
+ }
125
+ if ((ch === "'" && inSingle) || (ch === '"' && inDouble) || (ch === '`' && inTemplate)) {
126
+ // Keep terminator for symmetry — replace with space too. The
127
+ // string itself is gone; outer code doesn't care about the quote.
128
+ out.push(' ')
129
+ inSingle = inDouble = inTemplate = false
130
+ i++
131
+ continue
132
+ }
133
+ out.push(ch === '\n' ? '\n' : ' ')
134
+ i++
135
+ continue
136
+ }
137
+
138
+ // Inside line comment: blank to end of line.
139
+ if (inLineComment) {
140
+ if (ch === '\n') {
141
+ inLineComment = false
142
+ out.push('\n')
143
+ } else {
144
+ out.push(' ')
145
+ }
146
+ i++
147
+ continue
148
+ }
149
+
150
+ // Inside block comment: blank until `*/`.
151
+ if (inBlockComment) {
152
+ if (ch === '*' && next === '/') {
153
+ out.push(' ')
154
+ inBlockComment = false
155
+ i += 2
156
+ continue
157
+ }
158
+ out.push(ch === '\n' ? '\n' : ' ')
159
+ i++
160
+ continue
161
+ }
162
+
163
+ // Outside any region: detect openers.
164
+ if (ch === '/' && next === '/') {
165
+ out.push(' ')
166
+ inLineComment = true
167
+ i += 2
168
+ continue
169
+ }
170
+ if (ch === '/' && next === '*') {
171
+ out.push(' ')
172
+ inBlockComment = true
173
+ i += 2
174
+ continue
175
+ }
176
+ if (ch === "'") {
177
+ out.push(' ')
178
+ inSingle = true
179
+ i++
180
+ continue
181
+ }
182
+ if (ch === '"') {
183
+ out.push(' ')
184
+ inDouble = true
185
+ i++
186
+ continue
187
+ }
188
+ if (ch === '`') {
189
+ out.push(' ')
190
+ inTemplate = true
191
+ i++
192
+ continue
193
+ }
194
+
195
+ out.push(ch)
196
+ i++
197
+ }
198
+
199
+ return out.join('')
200
+ }
package/src/gate.ts ADDED
@@ -0,0 +1,337 @@
1
+ /**
2
+ * Architecture-gate primitive — pre/post-fix regression detection.
3
+ *
4
+ * Operations:
5
+ * - saveBaseline(output, path) — persist current SARIF as the baseline
6
+ * - compareToBaseline(output, path) — diff current SARIF against baseline
7
+ * - renderGateCompareOutput(result) — pretty-print the diff for stdout
8
+ *
9
+ * Wired into the `fit` command via `--gate-save` and `--gate-compare` flags
10
+ * (see commands/fit.ts and index.ts).
11
+ *
12
+ * The baseline is opensip-tools' own SARIF document (built via buildSarifLog),
13
+ * persisted as a file. Diffs match by (filePath, ruleId, message) — line
14
+ * numbers are intentionally NOT in the matching key so unrelated line shifts
15
+ * don't register as added/resolved violations.
16
+ */
17
+
18
+ import { createHash } from 'node:crypto';
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
20
+ import { dirname } from 'node:path';
21
+
22
+ import { logger } from '@opensip-tools/core';
23
+
24
+ import { buildSarifLog } from './sarif.js';
25
+
26
+ import type { CliOutput } from '@opensip-tools/contracts';
27
+
28
+ // ---------------------------------------------------------------------------
29
+ // Types
30
+ // ---------------------------------------------------------------------------
31
+
32
+ /** A single violation as it appears in the gate diff. */
33
+ interface GateViolation {
34
+ /** sha256(filePath + '\n' + ruleId + '\n' + message) — opaque identity */
35
+ readonly hash: string;
36
+ readonly ruleId: string;
37
+ readonly message: string;
38
+ readonly filePath: string;
39
+ /** Line number — informational only, NOT used in identity */
40
+ readonly line?: number;
41
+ readonly severity: 'error' | 'warning';
42
+ }
43
+
44
+ /** Result of comparing current state to a saved baseline. */
45
+ export interface GateCompareResult {
46
+ readonly baselinePath: string;
47
+ /** Violations present now but not in baseline. */
48
+ readonly added: readonly GateViolation[];
49
+ /** Violations present in baseline but not now. */
50
+ readonly resolved: readonly GateViolation[];
51
+ /** Violations present in both. */
52
+ readonly unchanged: readonly GateViolation[];
53
+ /** True iff `added` is non-empty — the gate decision. */
54
+ readonly degraded: boolean;
55
+ }
56
+
57
+ /** Thrown when --gate-compare is invoked but the baseline file doesn't exist. */
58
+ export class GateBaselineMissingError extends Error {
59
+ readonly baselinePath: string;
60
+ constructor(baselinePath: string) {
61
+ super(
62
+ `Gate baseline not found at ${baselinePath}. ` +
63
+ `Run \`opensip-tools fit --gate-save\` first to create one, ` +
64
+ `or pass --baseline <path> if it lives elsewhere.`,
65
+ );
66
+ this.name = 'GateBaselineMissingError';
67
+ this.baselinePath = baselinePath;
68
+ }
69
+ }
70
+
71
+ /** Thrown when the baseline file exists but isn't a parseable SARIF document. */
72
+ export class GateBaselineInvalidError extends Error {
73
+ readonly baselinePath: string;
74
+ constructor(baselinePath: string, reason: string) {
75
+ super(`Gate baseline at ${baselinePath} is invalid: ${reason}`);
76
+ this.name = 'GateBaselineInvalidError';
77
+ this.baselinePath = baselinePath;
78
+ }
79
+ }
80
+
81
+ // ---------------------------------------------------------------------------
82
+ // Default baseline path
83
+ // ---------------------------------------------------------------------------
84
+
85
+ /**
86
+ * Default location for the baseline file when --baseline is not
87
+ * specified. Lives under the per-project gitignored runtime dir.
88
+ */
89
+ export const DEFAULT_BASELINE_PATH = 'opensip-tools/.runtime/baseline.sarif';
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // saveBaseline
93
+ // ---------------------------------------------------------------------------
94
+
95
+ /**
96
+ * Persist the current run's findings as a baseline SARIF document.
97
+ * Creates parent directories as needed. Overwrites any existing baseline.
98
+ */
99
+ export function saveBaseline(output: CliOutput, baselinePath: string): void {
100
+ const sarif = buildSarifLog(output);
101
+ const dir = dirname(baselinePath);
102
+ // mkdirSync with recursive: true is idempotent — no need to check existsSync first.
103
+ mkdirSync(dir, { recursive: true });
104
+ writeFileSync(baselinePath, JSON.stringify(sarif, null, 2), 'utf8');
105
+
106
+ const findingCount = output.checks.reduce((n, c) => n + c.findings.length, 0);
107
+ logger.info({
108
+ evt: 'cli.gate.save.complete',
109
+ module: 'cli:gate',
110
+ baselinePath,
111
+ findingCount,
112
+ checkCount: output.checks.length,
113
+ });
114
+ }
115
+
116
+ // ---------------------------------------------------------------------------
117
+ // compareToBaseline
118
+ // ---------------------------------------------------------------------------
119
+
120
+ /**
121
+ * Compare current findings against a saved baseline. Returns a structured
122
+ * diff of added / resolved / unchanged violations.
123
+ *
124
+ * @throws {GateBaselineMissingError} when the baseline file doesn't exist
125
+ * @throws {GateBaselineInvalidError} when the baseline isn't valid SARIF
126
+ */
127
+ export function compareToBaseline(output: CliOutput, baselinePath: string): GateCompareResult {
128
+ if (!existsSync(baselinePath)) {
129
+ throw new GateBaselineMissingError(baselinePath);
130
+ }
131
+
132
+ const baselineRaw = readFileSync(baselinePath, 'utf8');
133
+ let baselineDoc: unknown;
134
+ try {
135
+ baselineDoc = JSON.parse(baselineRaw);
136
+ } catch (error) {
137
+ const reason = error instanceof Error ? error.message : String(error);
138
+ throw new GateBaselineInvalidError(baselinePath, `not valid JSON (${reason})`);
139
+ }
140
+
141
+ const baselineViolations = extractViolationsFromSarif(baselineDoc, baselinePath);
142
+ const currentViolations = extractViolationsFromCliOutput(output);
143
+
144
+ const baselineByHash = new Map(baselineViolations.map((v) => [v.hash, v]));
145
+ const currentByHash = new Map(currentViolations.map((v) => [v.hash, v]));
146
+
147
+ const added: GateViolation[] = [];
148
+ const unchanged: GateViolation[] = [];
149
+ for (const [hash, v] of currentByHash) {
150
+ if (baselineByHash.has(hash)) {
151
+ unchanged.push(v);
152
+ } else {
153
+ added.push(v);
154
+ }
155
+ }
156
+
157
+ const resolved: GateViolation[] = [];
158
+ for (const [hash, v] of baselineByHash) {
159
+ if (!currentByHash.has(hash)) {
160
+ resolved.push(v);
161
+ }
162
+ }
163
+
164
+ const result: GateCompareResult = {
165
+ baselinePath,
166
+ added,
167
+ resolved,
168
+ unchanged,
169
+ degraded: added.length > 0,
170
+ };
171
+
172
+ logger.info({
173
+ evt: 'cli.gate.compare.complete',
174
+ module: 'cli:gate',
175
+ baselinePath,
176
+ addedCount: added.length,
177
+ resolvedCount: resolved.length,
178
+ unchangedCount: unchanged.length,
179
+ degraded: result.degraded,
180
+ });
181
+
182
+ return result;
183
+ }
184
+
185
+ // ---------------------------------------------------------------------------
186
+ // renderGateCompareOutput
187
+ // ---------------------------------------------------------------------------
188
+
189
+ /**
190
+ * Pretty-print a gate compare result for stdout. Caller sets the exit code.
191
+ */
192
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- multi-section diff renderer: added/removed/changed sections each shape output; flatter form would scatter formatting
193
+ export function renderGateCompareOutput(result: GateCompareResult): string {
194
+ const lines: string[] = [ 'opensip-tools gate compare', ''];
195
+
196
+ if (result.added.length > 0) {
197
+ lines.push(`Added (${result.added.length}):`);
198
+ for (const v of sortViolations(result.added)) {
199
+ lines.push(` ✗ ${v.ruleId.padEnd(40)} ${formatLocation(v)}`);
200
+ if (v.message && v.message !== v.ruleId) {
201
+ lines.push(` ${truncate(v.message, 120)}`);
202
+ }
203
+ }
204
+ lines.push('');
205
+ }
206
+
207
+ if (result.resolved.length > 0) {
208
+ lines.push(`Resolved (${result.resolved.length}):`);
209
+ for (const v of sortViolations(result.resolved)) {
210
+ lines.push(` ✓ ${v.ruleId.padEnd(40)} ${formatLocation(v)}`);
211
+ }
212
+ lines.push('');
213
+ }
214
+
215
+ if (result.unchanged.length > 0) {
216
+ lines.push(`Unchanged (${result.unchanged.length}):`);
217
+ // Truncate unchanged list — usually long and not actionable.
218
+ const sample = sortViolations(result.unchanged).slice(0, 5);
219
+ for (const v of sample) {
220
+ lines.push(` · ${v.ruleId.padEnd(40)} ${formatLocation(v)}`);
221
+ }
222
+ if (result.unchanged.length > sample.length) {
223
+ lines.push(` · ... and ${result.unchanged.length - sample.length} more`);
224
+ }
225
+ lines.push('');
226
+ }
227
+
228
+ if (result.degraded) {
229
+ lines.push(`✗ DEGRADED — ${result.added.length} new violation${result.added.length === 1 ? '' : 's'}`);
230
+ } else if (result.resolved.length > 0) {
231
+ lines.push(`✓ IMPROVED — ${result.resolved.length} violation${result.resolved.length === 1 ? '' : 's'} resolved, none added`);
232
+ } else {
233
+ lines.push(`✓ STABLE — no change`);
234
+ }
235
+
236
+ return lines.join('\n');
237
+ }
238
+
239
+ // ---------------------------------------------------------------------------
240
+ // Internal helpers
241
+ // ---------------------------------------------------------------------------
242
+
243
+ function hashViolation(filePath: string, ruleId: string, message: string): string {
244
+ return createHash('sha256').update(`${filePath}\n${ruleId}\n${message}`).digest('hex');
245
+ }
246
+
247
+ function extractViolationsFromCliOutput(output: CliOutput): GateViolation[] {
248
+ const violations: GateViolation[] = [];
249
+ for (const check of output.checks) {
250
+ for (const f of check.findings) {
251
+ const filePath = f.filePath ?? '';
252
+ violations.push({
253
+ hash: hashViolation(filePath, f.ruleId, f.message),
254
+ ruleId: f.ruleId,
255
+ message: f.message,
256
+ filePath,
257
+ line: f.line,
258
+ severity: f.severity,
259
+ });
260
+ }
261
+ }
262
+ return violations;
263
+ }
264
+
265
+ interface SarifResult {
266
+ ruleId?: string;
267
+ level?: string;
268
+ message?: { text?: string };
269
+ locations?: readonly {
270
+ physicalLocation?: {
271
+ artifactLocation?: { uri?: string };
272
+ region?: { startLine?: number };
273
+ };
274
+ }[];
275
+ }
276
+
277
+ interface SarifRun {
278
+ tool?: { driver?: { name?: string } };
279
+ results?: readonly SarifResult[];
280
+ }
281
+
282
+ interface SarifDoc {
283
+ version?: string;
284
+ runs?: readonly SarifRun[];
285
+ }
286
+
287
+ function extractViolationsFromSarif(doc: unknown, baselinePath: string): GateViolation[] {
288
+ if (typeof doc !== 'object' || doc === null) {
289
+ throw new GateBaselineInvalidError(baselinePath, 'top-level value is not an object');
290
+ }
291
+ const sarif = doc as SarifDoc;
292
+ if (sarif.runs === undefined || !Array.isArray(sarif.runs)) {
293
+ throw new GateBaselineInvalidError(baselinePath, 'missing or non-array `runs`');
294
+ }
295
+
296
+ const runs: readonly SarifRun[] = sarif.runs;
297
+ const violations: GateViolation[] = [];
298
+ for (const run of runs) {
299
+ const results: readonly SarifResult[] | undefined = run.results;
300
+ if (results === undefined) continue;
301
+ for (const result of results) {
302
+ const ruleId = result.ruleId ?? '';
303
+ const message = result.message?.text ?? '';
304
+ const loc = result.locations?.[0]?.physicalLocation;
305
+ const filePath = loc?.artifactLocation?.uri ?? '';
306
+ const line = loc?.region?.startLine;
307
+ const severity = result.level === 'error' ? 'error' : 'warning';
308
+ violations.push({
309
+ hash: hashViolation(filePath, ruleId, message),
310
+ ruleId,
311
+ message,
312
+ filePath,
313
+ line,
314
+ severity,
315
+ });
316
+ }
317
+ }
318
+ return violations;
319
+ }
320
+
321
+ function formatLocation(v: GateViolation): string {
322
+ if (!v.filePath) return '(no location)';
323
+ return v.line == null ? v.filePath : `${v.filePath}:${v.line}`;
324
+ }
325
+
326
+ function sortViolations(vs: readonly GateViolation[]): GateViolation[] {
327
+ return [...vs].sort((a, b) => {
328
+ if (a.ruleId !== b.ruleId) return a.ruleId.localeCompare(b.ruleId);
329
+ if (a.filePath !== b.filePath) return a.filePath.localeCompare(b.filePath);
330
+ return (a.line ?? 0) - (b.line ?? 0);
331
+ });
332
+ }
333
+
334
+ function truncate(s: string, max: number): string {
335
+ if (s.length <= max) return s;
336
+ return s.slice(0, max - 1) + '…';
337
+ }
package/src/index.ts ADDED
@@ -0,0 +1,110 @@
1
+ // Framework — check definition API
2
+ export { defineCheck } from './framework/define-check.js';
3
+ export { CheckRegistry, defaultRegistry } from './framework/registry.js';
4
+ export { registerChecks } from './framework/register-helpers.js';
5
+
6
+ // Framework types — the real check API types
7
+ export type { CheckViolation, CheckScope, FileAccessor, CheckConcern, CheckLanguage } from './framework/check-config.js';
8
+ export type { Check, CheckConfig, ResolvedScope } from './framework/check-types.js';
9
+ export { isCheck } from './framework/check-types.js';
10
+ export type { ExecutionContext, RunOptions } from './framework/execution-context.js';
11
+
12
+ // Framework utilities used by checks
13
+ export { getLineNumber, extractSnippet, isAPIFile } from './framework/result-builder.js';
14
+ export {
15
+ parseSource, walkNodes,
16
+ getLineNumber as getASTLineNumber,
17
+ getIdentifierName, getPropertyChain,
18
+ isInStringLiteral,
19
+ isLiteral, isPropertyAccess,
20
+ } from './framework/ast-utilities.js';
21
+ export { execAbortable } from './framework/abortable-exec.js';
22
+ // File cache (used by checks for content access; tests may seed/clear).
23
+ export { fileCache, DEFAULT_PREWARM_PATTERNS } from './framework/file-cache.js';
24
+ export { buildImportGraph, findStronglyConnectedComponents } from './framework/import-graph.js';
25
+ export type { ImportGraph } from './framework/import-graph.js';
26
+ export { isInsideStringLiteral, stripStringLiterals, stripStringsAndComments, stripStringsAndCommentsPreservingPositions } from './framework/strip-literals.js';
27
+ export { filterContent, clearFilterCache } from './framework/content-filter.js';
28
+ export type { FilteredContent } from './framework/content-filter.js';
29
+ // Re-export TypeScript compiler API for AST-based checks. The typescript module
30
+ // uses `export =`, so `export * as ts from 'typescript'` is invalid; the
31
+ // import-then-rename-export form works under esModuleInterop.
32
+ /* eslint-disable unicorn/prefer-export-from -- `export * as ts from 'typescript'` is invalid (the module uses `export =`); the namespace import + named export is the only working shape */
33
+ import * as _ts from 'typescript';
34
+ export { _ts as ts };
35
+ /* eslint-enable unicorn/prefer-export-from */
36
+
37
+
38
+ // Types — findings output
39
+ export type { Finding, Severity, FindingSeverity, ToolOutput, CheckResult, CheckInfo, CheckResultMetadata, ItemType } from './types/findings.js';
40
+ export { createResultWithSignals, createErrorResult, createPassingResult, CheckInfoFactory } from './types/findings.js';
41
+
42
+ // Recipe service
43
+ export { FitnessRecipeService } from './recipes/service.js';
44
+ export type { FitnessRecipeServiceConfig, FitnessRecipeServiceCallbacks, CheckSummary } from './recipes/service-types.js';
45
+ export type { FitnessRecipeResult, RecipeCheckResult, RecipeCheckConfigMap } from './recipes/types.js';
46
+ export { builtInRecipesByName } from './recipes/built-in-recipes.js';
47
+ export { defaultRecipeRegistry, FitnessRecipeRegistry } from './recipes/registry.js';
48
+ export { getCheckConfig, setCurrentRecipeCheckConfig, clearCurrentRecipeCheckConfig } from './recipes/check-config.js';
49
+
50
+ // Targets and signalers
51
+ export { loadTargetsConfig, resolveTargetFiles } from './targets/index.js';
52
+ export type { TargetsConfig } from './targets/types.js';
53
+ export { TargetRegistry } from './targets/target-registry.js';
54
+ export { buildScopeBasedFileMap } from './framework/scope-resolver.js';
55
+ export { loadSignalersConfig } from './signalers/index.js';
56
+ export type { SignalersConfig } from './signalers/types.js';
57
+
58
+ // Plugin loader (fitness owns the dispatcher; lang plugins also flow through
59
+ // it because lang adapter loading currently shares the same orchestration).
60
+ export { loadPlugin, loadAllPlugins } from './plugins/loader.js';
61
+ export type { FitPluginExports } from './plugins/types.js';
62
+
63
+ // Check-package discovery (fitness-specific — scans @opensip-tools/checks-* packages).
64
+ export {
65
+ discoverCheckPackages,
66
+ readCheckPackageMetadata,
67
+ readCheckPackagePreferences,
68
+ } from './plugins/check-package-discovery.js';
69
+ export type {
70
+ CheckPackageDiscoveryOptions,
71
+ DiscoveredCheckPackage,
72
+ CheckPackageMetadata,
73
+ } from './plugins/check-package-discovery.js';
74
+
75
+ // Tool plugin export — fitness as a Tool.
76
+ export { fitnessTool } from './tool.js';
77
+
78
+ // CLI command implementations — re-exported for the Phase 2 CLI which
79
+ // still drives commands directly. Phase 4 will collapse these behind
80
+ // the Tool contract.
81
+ export {
82
+ executeFit,
83
+ ensureChecksLoaded,
84
+ getDisplayName,
85
+ getEnabledCheckCount,
86
+ getIcon,
87
+ getPluginLoadErrors,
88
+ setPreLoadHook,
89
+ formatDuration,
90
+ formatValidatedColumn,
91
+ } from './cli/fit.js';
92
+ export type { PreLoadHook } from './cli/fit.js';
93
+ export { openDashboard } from './cli/dashboard.js';
94
+ export { listChecks } from './cli/list-checks.js';
95
+ export { listRecipes } from './cli/list-recipes.js';
96
+
97
+ // Architecture-gate primitives (baseline save / compare) and SARIF
98
+ // upload — both operate on fitness's CliOutput. Wired into the `fit`
99
+ // subcommand by the tool's register() handler.
100
+ export {
101
+ saveBaseline,
102
+ compareToBaseline,
103
+ renderGateCompareOutput,
104
+ GateBaselineMissingError,
105
+ GateBaselineInvalidError,
106
+ DEFAULT_BASELINE_PATH,
107
+ } from './gate.js';
108
+ export type { GateCompareResult } from './gate.js';
109
+ export { buildSarifLog, chunkSarifRuns, reportToCloud } from './sarif.js';
110
+ export type { ReportResult } from './sarif.js';