@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,339 @@
1
+ // @fitness-ignore-file zod-schema-strictness -- flexible schema for external data
2
+ // @fitness-ignore-file null-safety -- Zod schema builder chains (z.string().regex(), z.object().passthrough().superRefine().pipe()) always return valid schema objects
3
+ /**
4
+ * @fileoverview Unified check configuration schema
5
+ *
6
+ * Defines the configuration types for fitness checks with three analysis modes:
7
+ * - analyze: Per-file analysis with content and path
8
+ * - analyzeAll: Multi-file analysis with lazy loading FileAccessor
9
+ * - command: External tool execution with output parsing
10
+ */
11
+
12
+ import { z } from 'zod'
13
+
14
+ import type { ItemType } from '../types/findings.js'
15
+
16
+ // =============================================================================
17
+ // CHECK SLUGS AND IDS
18
+ // =============================================================================
19
+
20
+ /** Zod schema for validating kebab-case check slugs. */
21
+ const CheckSlugSchema = z
22
+ .string()
23
+ .regex(/^[a-z][a-z0-9-]*(?:-[a-z0-9]+)*$/, 'Check slug must be kebab-case (e.g., no-console-log)')
24
+
25
+ /** Zod schema for validating UUID-format check IDs. */
26
+ const CheckIdSchema = z
27
+ .string()
28
+ .regex(
29
+ /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,
30
+ 'Check ID must be plain UUID format',
31
+ )
32
+
33
+ /** Type alias for a kebab-case check slug string. */
34
+ // eslint-disable-next-line sonarjs/redundant-type-aliases -- semantic alias documents intent ("a slug" vs raw string)
35
+ type CheckSlug = string
36
+
37
+ // =============================================================================
38
+ // RESOLVED SCOPE (glob-based file matching)
39
+ // =============================================================================
40
+
41
+ /**
42
+ * Resolved scope with concrete glob patterns for file matching.
43
+ * Produced by resolving a CheckScope against targets configuration.
44
+ */
45
+ export interface ResolvedScope {
46
+ readonly include: readonly string[]
47
+ readonly exclude: readonly string[]
48
+ readonly description: string
49
+ }
50
+
51
+ // =============================================================================
52
+ // CHECK SCOPE (semantic, marketplace-ready)
53
+ // =============================================================================
54
+
55
+ /**
56
+ * Semantic concern describing what kind of code a check targets.
57
+ * Used for automatic target matching: a check with `concerns: ['backend']`
58
+ * matches any target that declares `concerns: ['backend', ...]`.
59
+ */
60
+ // eslint-disable-next-line sonarjs/redundant-type-aliases -- semantic alias documents the marketplace concern dimension
61
+ export type CheckConcern = string
62
+
63
+ /**
64
+ * Language a check is designed for. Used for automatic target matching:
65
+ * a check with `languages: ['typescript']` matches any target with
66
+ * `languages: ['typescript', ...]`.
67
+ */
68
+ // eslint-disable-next-line sonarjs/redundant-type-aliases -- semantic alias documents the marketplace language dimension
69
+ export type CheckLanguage = string
70
+
71
+ /**
72
+ * Portable scope declaration for a fitness check.
73
+ *
74
+ * Instead of referencing project-specific target names, checks declare
75
+ * what kind of code they analyze. The platform matches this intent
76
+ * against project targets automatically.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * scope: {
81
+ * languages: ['typescript'],
82
+ * concerns: ['backend', 'server'],
83
+ * }
84
+ * ```
85
+ */
86
+ export interface CheckScope {
87
+ /** File type affinity — which languages this check analyzes. */
88
+ readonly languages: readonly CheckLanguage[]
89
+ /** Semantic hints — what kind of code this check targets. */
90
+ readonly concerns: readonly CheckConcern[]
91
+ }
92
+
93
+ // =============================================================================
94
+ // CHECK VIOLATION (AUTHOR'S RETURN TYPE)
95
+ // =============================================================================
96
+
97
+ /**
98
+ * Violation returned by check authors.
99
+ * This is the simplified shape - the framework converts it to a Signal.
100
+ */
101
+ export interface CheckViolation {
102
+ readonly line: number
103
+ readonly column?: number
104
+ readonly message: string
105
+ readonly severity: 'error' | 'warning'
106
+ readonly suggestion?: string
107
+ readonly match?: string
108
+ readonly type?: string
109
+ readonly filePath?: string
110
+ readonly fix?: {
111
+ readonly action: 'replace' | 'insert' | 'delete' | 'refactor' | 'configure' | 'investigate'
112
+ readonly replacement?: string
113
+ readonly confidence: number
114
+ }
115
+ }
116
+
117
+ // =============================================================================
118
+ // FILE ACCESSOR (FOR ANALYZE ALL MODE)
119
+ // =============================================================================
120
+
121
+ /**
122
+ * Lazy-loading file accessor for analyzeAll mode.
123
+ */
124
+ export interface FileAccessor {
125
+ /** List of matched file paths */
126
+ readonly paths: readonly string[]
127
+ /** Read a single file on demand (cached after first read) */
128
+ read(filePath: string): Promise<string>
129
+ /** Read multiple files in batch */
130
+ readMany(filePaths: readonly string[]): Promise<Map<string, string>>
131
+ /** Read all matched files */
132
+ readAll(): Promise<Map<string, string>>
133
+ }
134
+
135
+ // =============================================================================
136
+ // COMMAND MODE TYPES
137
+ // =============================================================================
138
+
139
+ /** Configuration for an external command-based check. */
140
+ export interface CommandConfig {
141
+ readonly bin: string
142
+ readonly args: readonly string[] | ((files: readonly string[]) => readonly string[])
143
+ parseOutput(
144
+ stdout: string,
145
+ stderr: string,
146
+ exitCode: number,
147
+ files: readonly string[],
148
+ cwd: string,
149
+ ): CheckViolation[]
150
+ readonly expectedExitCodes?: readonly number[]
151
+ }
152
+
153
+ const CommandArgsSchema = z.union([z.array(z.string()), z.function()])
154
+
155
+ /** Zod schema for validating command configurations. */
156
+ const CommandConfigSchema = z.object({
157
+ bin: z.string().min(1),
158
+ args: CommandArgsSchema,
159
+ parseOutput: z.function(),
160
+ expectedExitCodes: z.array(z.number().int()).optional(),
161
+ })
162
+
163
+ // =============================================================================
164
+ // ANALYSIS MODE SCHEMAS
165
+ // =============================================================================
166
+
167
+ const AnalyzeModeSchema = z.object({ analyze: z.function() })
168
+ const AnalyzeAllModeSchema = z.object({ analyzeAll: z.function() })
169
+ const CommandModeSchema = z.object({ command: CommandConfigSchema })
170
+
171
+ // =============================================================================
172
+ // BASE CHECK CONFIG
173
+ // =============================================================================
174
+
175
+ /** Common configuration fields shared by all check types. */
176
+ interface BaseCheckConfig {
177
+ readonly id: string
178
+ readonly slug: CheckSlug
179
+ readonly description: string
180
+ readonly longDescription?: string
181
+ readonly tags: readonly string[]
182
+ readonly docs?: string
183
+ readonly timeout?: number
184
+ readonly disabled?: boolean
185
+ readonly fileTypes?: readonly string[]
186
+ /** Signal provider name for external tool checks (default: 'opensip') */
187
+ readonly provider?: string
188
+ /** The type of items this check validates (default: 'files'). Used for display in results table. */
189
+ readonly itemType?: ItemType
190
+ /** Portable scope declaration for marketplace-ready target matching. */
191
+ readonly scope?: CheckScope
192
+ /**
193
+ * Content filtering mode for the analyze() function. Names describe
194
+ * what the filter strips so rule authors don't have to guess at intent.
195
+ *
196
+ * - 'raw' (default): Full file content, unchanged. Use for checks that
197
+ * need to analyze string content (e.g., hardcoded secrets, PII detection).
198
+ * - 'strip-strings': String literals replaced with whitespace,
199
+ * preserving line/column positions. COMMENTS PRESERVED — use when
200
+ * the check reads comment-based directives like the deprecation
201
+ * marker, the swallow-ok marker, or `// @fitness-ignore-...` (we
202
+ * don't reference those tag names verbatim in this JSDoc to avoid
203
+ * confusing static analyzers).
204
+ * - 'strip-strings-and-comments': BOTH string literals and comments
205
+ * replaced with whitespace, preserving line/column positions. Use
206
+ * for checks that pattern-match identifiers via regex and would
207
+ * false-positive on the same banned phrase appearing in JSDoc /
208
+ * line / block comments documenting the rule itself.
209
+ *
210
+ * The legacy `'code-only'` / `'no-strings-no-comments'` aliases were
211
+ * retained through 0.4.x for backwards-compat and removed in 0.5.0.
212
+ * Migrate any remaining call sites to the strip-* names.
213
+ */
214
+ readonly contentFilter?: 'raw' | 'strip-strings' | 'strip-strings-and-comments'
215
+ /**
216
+ * Confidence level of this check's findings. Consumers of opensip-tools
217
+ * signals (via --report-to) use this to decide how aggressively to act
218
+ * on findings; this package treats it as pure metadata.
219
+ *
220
+ * - 'high': AST-based or structurally guaranteed no false positives.
221
+ * - 'medium': Regex with context filtering — some false positives expected.
222
+ * - 'low': Naive regex or heuristic — surfaced in reports but easily noisy.
223
+ *
224
+ * Default: 'medium' (applied at runtime, not in schema).
225
+ */
226
+ readonly confidence?: 'high' | 'medium' | 'low'
227
+ }
228
+
229
+ /**
230
+ * Zod schema for validating check scope declarations.
231
+ *
232
+ * Empty `languages` and empty `concerns` are both valid and mean
233
+ * "matches any". This is how cross-language ("universal") checks
234
+ * declare themselves — see @opensip-tools/checks-universal.
235
+ *
236
+ * findByScope() in TargetRegistry treats empty arrays as match-any
237
+ * already; the schema mirrors that behavior so callers can author
238
+ * universal checks without inventing a wildcard sentinel.
239
+ */
240
+ const CheckScopeSchema = z.object({
241
+ languages: z.array(z.string()),
242
+ concerns: z.array(z.string()),
243
+ })
244
+
245
+ const BaseCheckConfigSchema = z.object({
246
+ id: CheckIdSchema,
247
+ slug: CheckSlugSchema,
248
+ description: z.string().min(1, 'Description is required'),
249
+ longDescription: z.string().optional(),
250
+ tags: z.array(z.string()).min(1, 'At least one tag is required'),
251
+ docs: z.string().optional(),
252
+ timeout: z.number().positive().optional(),
253
+ disabled: z.boolean().optional(),
254
+ fileTypes: z.array(z.string()).optional(),
255
+ provider: z.string().optional(),
256
+ scope: CheckScopeSchema.optional(),
257
+ contentFilter: z.enum(['raw', 'strip-strings', 'strip-strings-and-comments']).optional(),
258
+ confidence: z.enum(['high', 'medium', 'low']).optional(),
259
+ })
260
+
261
+ // =============================================================================
262
+ // UNIFIED CHECK CONFIG
263
+ // =============================================================================
264
+
265
+ /** Check config with per-file analysis mode. */
266
+ export interface AnalyzeCheckConfig extends BaseCheckConfig {
267
+ analyze(content: string, filePath: string): CheckViolation[]
268
+ }
269
+
270
+ /** Check config with multi-file analysis mode using FileAccessor. */
271
+ export interface AnalyzeAllCheckConfig extends BaseCheckConfig {
272
+ analyzeAll(files: FileAccessor): Promise<CheckViolation[]>
273
+ }
274
+
275
+ /** Check config with external command execution mode. */
276
+ export interface CommandCheckConfig extends BaseCheckConfig {
277
+ command: CommandConfig
278
+ }
279
+
280
+ /** Union of all check configuration types (analyze, analyzeAll, command). */
281
+ export type UnifiedCheckConfig = AnalyzeCheckConfig | AnalyzeAllCheckConfig | CommandCheckConfig
282
+
283
+ // =============================================================================
284
+ // VALIDATION
285
+ // =============================================================================
286
+
287
+ /** Zod schema for validating unified check configurations (exactly one analysis mode required). */
288
+ const UnifiedCheckConfigSchema = z
289
+ .object({})
290
+ .passthrough()
291
+ .superRefine((config, ctx) => {
292
+ const modes = ['analyze' in config, 'analyzeAll' in config, 'command' in config].filter(
293
+ Boolean,
294
+ ).length
295
+
296
+ if (modes === 0) {
297
+ ctx.addIssue({
298
+ code: z.ZodIssueCode.custom,
299
+ message: 'Check config must specify an analysis mode: analyze, analyzeAll, or command',
300
+ })
301
+ } else if (modes > 1) {
302
+ ctx.addIssue({
303
+ code: z.ZodIssueCode.custom,
304
+ message: 'Check config must specify exactly one analysis mode (found multiple)',
305
+ })
306
+ }
307
+ })
308
+ .pipe(
309
+ BaseCheckConfigSchema.and(
310
+ z.union([AnalyzeModeSchema, AnalyzeAllModeSchema, CommandModeSchema]),
311
+ ),
312
+ )
313
+
314
+ /** Validate and parse a check configuration, throwing on invalid input. */
315
+ export function validateCheckConfig(config: unknown): UnifiedCheckConfig {
316
+ return UnifiedCheckConfigSchema.parse(config) as UnifiedCheckConfig
317
+ }
318
+
319
+ /** Type guard for per-file analyze mode checks. */
320
+ export function isAnalyzeConfig(config: UnifiedCheckConfig): config is AnalyzeCheckConfig {
321
+ return 'analyze' in config && typeof config.analyze === 'function'
322
+ }
323
+
324
+ /** Type guard for multi-file analyzeAll mode checks. */
325
+ export function isAnalyzeAllConfig(config: UnifiedCheckConfig): config is AnalyzeAllCheckConfig {
326
+ return 'analyzeAll' in config && typeof config.analyzeAll === 'function'
327
+ }
328
+
329
+ /** Type guard for external command mode checks. */
330
+ export function isCommandConfig(config: UnifiedCheckConfig): config is CommandCheckConfig {
331
+ return 'command' in config && typeof config.command === 'object'
332
+ }
333
+
334
+ /** Determine which analysis mode a check config uses. */
335
+ export function getAnalysisMode(config: UnifiedCheckConfig): 'analyze' | 'analyzeAll' | 'command' {
336
+ if (isAnalyzeConfig(config)) return 'analyze'
337
+ if (isAnalyzeAllConfig(config)) return 'analyzeAll'
338
+ return 'command'
339
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @fileoverview Core type definitions for fitness checks
3
+ *
4
+ * Check interface is the return type of defineCheck.
5
+ * CheckConfig represents the internal configuration structure.
6
+ * CheckResult carries Signal[].
7
+ */
8
+
9
+
10
+ import type { CheckScope, ResolvedScope } from './check-config.js'
11
+ import type { ExecutionContext, RunOptions } from './execution-context.js'
12
+ import type { PathMatcher } from './path-matcher.js'
13
+ import type { CheckResult, ItemType } from '../types/findings.js'
14
+
15
+
16
+
17
+ /**
18
+ * Check configuration options.
19
+ */
20
+ export interface CheckConfig {
21
+ readonly id: string
22
+ readonly slug: string
23
+ readonly tags: readonly string[]
24
+ readonly description: string
25
+ readonly longDescription?: string | undefined
26
+ readonly analysisMode: 'analyze' | 'analyzeAll' | 'command'
27
+ readonly scope: ResolvedScope
28
+ readonly itemType: ItemType
29
+ readonly unit?: string | undefined
30
+ readonly additionalExcludes?: readonly string[] | undefined
31
+ readonly docs?: string | undefined
32
+ readonly disabled?: boolean | undefined
33
+ readonly confidence?: 'high' | 'medium' | 'low' | undefined
34
+ readonly timeout?: number | undefined
35
+ readonly scansFiles?: boolean | undefined
36
+ readonly fileTypes?: readonly string[] | undefined
37
+ /** Portable scope declaration for marketplace-ready target matching. */
38
+ readonly checkScope?: CheckScope | undefined
39
+ readonly execute: (ctx: ExecutionContext) => Promise<CheckResult>
40
+ }
41
+
42
+ /**
43
+ * A defined check, ready to run.
44
+ */
45
+ export interface Check {
46
+ readonly config: CheckConfig
47
+ readonly run: (cwd: string, options?: RunOptions) => Promise<CheckResult>
48
+ readonly getScope: () => ResolvedScope
49
+ readonly getMatcher: (cwd: string) => PathMatcher
50
+ }
51
+
52
+ /**
53
+ * Type guard: is this value a Check object?
54
+ *
55
+ * Checks for the shape of a Check object:
56
+ * - Has a `config` property that is an object
57
+ * - config has an `id` property that is a string
58
+ * - config has a `slug` property that is a string
59
+ * - config has an `execute` property that is a function
60
+ * - Has a `run` property that is a function
61
+ */
62
+ export function isCheck(value: unknown): value is Check {
63
+ if (value === null || typeof value !== 'object') return false
64
+
65
+ const obj = value as Record<string, unknown>
66
+ if (!obj.config || typeof obj.config !== 'object') return false
67
+
68
+ const config = obj.config as Record<string, unknown>
69
+ if (typeof config.id !== 'string') return false
70
+ if (typeof config.slug !== 'string') return false
71
+ if (typeof config.execute !== 'function') return false
72
+ if (typeof obj.run !== 'function') return false
73
+
74
+ return true
75
+ }
76
+
77
+ export {type ResolvedScope} from './check-config.js'
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @fileoverview Command executor for external tool checks
3
+ *
4
+ * Executes external commands (eslint, prettier, etc.) with abort
5
+ * and timeout support, then parses output into violations.
6
+ */
7
+
8
+ import { execAbortable, type AbortableExecOptions } from './abortable-exec.js'
9
+
10
+ import type { CheckViolation, CommandConfig } from './check-config.js'
11
+
12
+ // =============================================================================
13
+ // TYPES
14
+ // =============================================================================
15
+
16
+ /** Options for executing an external command. */
17
+ export interface CommandExecutorOptions {
18
+ readonly cwd: string
19
+ readonly signal?: AbortSignal | undefined
20
+ readonly timeout?: number | undefined
21
+ }
22
+
23
+ /** Result of executing an external command, including parsed violations. */
24
+ export interface CommandExecutionResult {
25
+ readonly violations: CheckViolation[]
26
+ readonly aborted: boolean
27
+ readonly exitCode: number | null
28
+ readonly error?: string
29
+ }
30
+
31
+ // =============================================================================
32
+ // EXECUTOR
33
+ // =============================================================================
34
+
35
+ const DEFAULT_EXPECTED_EXIT_CODES: readonly number[] = [0, 1]
36
+
37
+ /**
38
+ * Execute an external command and parse its output into violations.
39
+ */
40
+ export async function executeCommand(
41
+ config: CommandConfig,
42
+ files: readonly string[],
43
+ options: CommandExecutorOptions,
44
+ ): Promise<CommandExecutionResult> {
45
+ const { cwd, signal, timeout } = options
46
+
47
+ const args = typeof config.args === 'function' ? config.args(files) : config.args
48
+ const command = [config.bin, ...args]
49
+
50
+ const execOptions: AbortableExecOptions = { cwd, signal, timeout }
51
+
52
+ let result: Awaited<ReturnType<typeof execAbortable>>
53
+ try {
54
+ result = await execAbortable(command, execOptions)
55
+ } catch (error) {
56
+ // ENOENT = tool not installed (spawn fails before the process starts)
57
+ const message = error instanceof Error ? error.message : String(error)
58
+ if (message.includes('ENOENT') || message.includes('not found')) {
59
+ return {
60
+ violations: [],
61
+ aborted: false,
62
+ exitCode: null,
63
+ error: `${config.bin} is not installed. Install it to enable this check.`,
64
+ }
65
+ }
66
+ throw error
67
+ }
68
+
69
+ if (result.aborted) {
70
+ return { violations: [], aborted: true, exitCode: result.exitCode }
71
+ }
72
+
73
+ // Exit code 127 = command not found (shell mode)
74
+ if (result.exitCode === 127) {
75
+ return {
76
+ violations: [],
77
+ aborted: false,
78
+ exitCode: 127,
79
+ error: `${config.bin} is not installed. Install it to enable this check.`,
80
+ }
81
+ }
82
+
83
+ const expectedCodes = config.expectedExitCodes ?? DEFAULT_EXPECTED_EXIT_CODES
84
+ if (result.exitCode !== null && !expectedCodes.includes(result.exitCode)) {
85
+ return {
86
+ violations: [],
87
+ aborted: false,
88
+ exitCode: result.exitCode,
89
+ error:
90
+ `Command exited with unexpected code ${result.exitCode}. ` +
91
+ `Expected one of: ${expectedCodes.join(', ')}. ` +
92
+ `stderr: ${result.stderr.slice(0, 500)}${result.stderr.length > 500 ? ' [truncated]' : ''}`,
93
+ }
94
+ }
95
+
96
+ const violations = config.parseOutput(result.stdout, result.stderr, result.exitCode ?? 0, files, cwd)
97
+
98
+ return { violations, aborted: false, exitCode: result.exitCode }
99
+ }
100
+
@@ -0,0 +1,16 @@
1
+ // @fitness-ignore-file project-readme-existence -- internal module, not a package root
2
+ /**
3
+ * @fileoverview Shared constants for the fitness framework
4
+ */
5
+
6
+ /**
7
+ * Standard exclusion patterns for file matching across the framework.
8
+ * Used by execution context, directive inventory, and file cache.
9
+ */
10
+ export const DEFAULT_EXCLUSION_PATTERNS = [
11
+ '**/node_modules/**',
12
+ '**/dist/**',
13
+ '**/.git/**',
14
+ '**/coverage/**',
15
+ '**/*.tsbuildinfo',
16
+ ] as const