@vyuhlabs/dxkit 2.4.6 → 2.4.7

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 (345) hide show
  1. package/CHANGELOG.md +885 -0
  2. package/README.md +131 -26
  3. package/dist/analysis-result.d.ts +112 -0
  4. package/dist/analysis-result.d.ts.map +1 -0
  5. package/dist/analysis-result.js +52 -0
  6. package/dist/analysis-result.js.map +1 -0
  7. package/dist/analyzers/bom/detailed.d.ts.map +1 -1
  8. package/dist/analyzers/bom/detailed.js +19 -0
  9. package/dist/analyzers/bom/detailed.js.map +1 -1
  10. package/dist/analyzers/bom/gather.d.ts +27 -26
  11. package/dist/analyzers/bom/gather.d.ts.map +1 -1
  12. package/dist/analyzers/bom/gather.js +26 -87
  13. package/dist/analyzers/bom/gather.js.map +1 -1
  14. package/dist/analyzers/bom/index.d.ts +0 -7
  15. package/dist/analyzers/bom/index.d.ts.map +1 -1
  16. package/dist/analyzers/bom/index.js +98 -48
  17. package/dist/analyzers/bom/index.js.map +1 -1
  18. package/dist/analyzers/bom/types.d.ts +11 -13
  19. package/dist/analyzers/bom/types.d.ts.map +1 -1
  20. package/dist/analyzers/cache.d.ts +95 -0
  21. package/dist/analyzers/cache.d.ts.map +1 -0
  22. package/dist/analyzers/cache.js +309 -0
  23. package/dist/analyzers/cache.js.map +1 -0
  24. package/dist/analyzers/coverage-runner.d.ts +56 -0
  25. package/dist/analyzers/coverage-runner.d.ts.map +1 -0
  26. package/dist/analyzers/coverage-runner.js +72 -0
  27. package/dist/analyzers/coverage-runner.js.map +1 -0
  28. package/dist/analyzers/dashboard/index.d.ts +24 -0
  29. package/dist/analyzers/dashboard/index.d.ts.map +1 -0
  30. package/dist/analyzers/dashboard/index.js +666 -0
  31. package/dist/analyzers/dashboard/index.js.map +1 -0
  32. package/dist/analyzers/developer/gather.d.ts.map +1 -1
  33. package/dist/analyzers/developer/gather.js +205 -37
  34. package/dist/analyzers/developer/gather.js.map +1 -1
  35. package/dist/analyzers/developer/index.d.ts +1 -1
  36. package/dist/analyzers/developer/index.d.ts.map +1 -1
  37. package/dist/analyzers/developer/index.js +19 -8
  38. package/dist/analyzers/developer/index.js.map +1 -1
  39. package/dist/analyzers/dispatcher.d.ts +37 -0
  40. package/dist/analyzers/dispatcher.d.ts.map +1 -1
  41. package/dist/analyzers/dispatcher.js +56 -9
  42. package/dist/analyzers/dispatcher.js.map +1 -1
  43. package/dist/analyzers/docs/shallow.d.ts +17 -5
  44. package/dist/analyzers/docs/shallow.d.ts.map +1 -1
  45. package/dist/analyzers/docs/shallow.js +65 -2
  46. package/dist/analyzers/docs/shallow.js.map +1 -1
  47. package/dist/analyzers/dx/shallow.d.ts +17 -5
  48. package/dist/analyzers/dx/shallow.d.ts.map +1 -1
  49. package/dist/analyzers/dx/shallow.js +66 -2
  50. package/dist/analyzers/dx/shallow.js.map +1 -1
  51. package/dist/analyzers/health/actions.d.ts +1 -1
  52. package/dist/analyzers/health/actions.d.ts.map +1 -1
  53. package/dist/analyzers/health/actions.js +27 -9
  54. package/dist/analyzers/health/actions.js.map +1 -1
  55. package/dist/analyzers/health/detailed.d.ts +2 -1
  56. package/dist/analyzers/health/detailed.d.ts.map +1 -1
  57. package/dist/analyzers/health/detailed.js +11 -7
  58. package/dist/analyzers/health/detailed.js.map +1 -1
  59. package/dist/analyzers/health.d.ts +27 -0
  60. package/dist/analyzers/health.d.ts.map +1 -1
  61. package/dist/analyzers/health.js +271 -33
  62. package/dist/analyzers/health.js.map +1 -1
  63. package/dist/analyzers/licenses/gather.d.ts +35 -8
  64. package/dist/analyzers/licenses/gather.d.ts.map +1 -1
  65. package/dist/analyzers/licenses/gather.js +70 -13
  66. package/dist/analyzers/licenses/gather.js.map +1 -1
  67. package/dist/analyzers/licenses/index.d.ts +1 -1
  68. package/dist/analyzers/licenses/index.d.ts.map +1 -1
  69. package/dist/analyzers/licenses/index.js +52 -11
  70. package/dist/analyzers/licenses/index.js.map +1 -1
  71. package/dist/analyzers/licenses/types.d.ts +15 -0
  72. package/dist/analyzers/licenses/types.d.ts.map +1 -1
  73. package/dist/analyzers/maintainability/shallow.d.ts +17 -5
  74. package/dist/analyzers/maintainability/shallow.d.ts.map +1 -1
  75. package/dist/analyzers/maintainability/shallow.js +80 -2
  76. package/dist/analyzers/maintainability/shallow.js.map +1 -1
  77. package/dist/analyzers/quality/detailed.d.ts.map +1 -1
  78. package/dist/analyzers/quality/detailed.js +4 -6
  79. package/dist/analyzers/quality/detailed.js.map +1 -1
  80. package/dist/analyzers/quality/gather.d.ts +1 -14
  81. package/dist/analyzers/quality/gather.d.ts.map +1 -1
  82. package/dist/analyzers/quality/gather.js +48 -137
  83. package/dist/analyzers/quality/gather.js.map +1 -1
  84. package/dist/analyzers/quality/index.d.ts +9 -2
  85. package/dist/analyzers/quality/index.d.ts.map +1 -1
  86. package/dist/analyzers/quality/index.js +189 -117
  87. package/dist/analyzers/quality/index.js.map +1 -1
  88. package/dist/analyzers/quality/shallow.d.ts +50 -5
  89. package/dist/analyzers/quality/shallow.d.ts.map +1 -1
  90. package/dist/analyzers/quality/shallow.js +155 -2
  91. package/dist/analyzers/quality/shallow.js.map +1 -1
  92. package/dist/analyzers/quality/types.d.ts +14 -0
  93. package/dist/analyzers/quality/types.d.ts.map +1 -1
  94. package/dist/analyzers/security/actions.d.ts +11 -4
  95. package/dist/analyzers/security/actions.d.ts.map +1 -1
  96. package/dist/analyzers/security/actions.js +87 -37
  97. package/dist/analyzers/security/actions.js.map +1 -1
  98. package/dist/analyzers/security/aggregator.d.ts +236 -0
  99. package/dist/analyzers/security/aggregator.d.ts.map +1 -0
  100. package/dist/analyzers/security/aggregator.js +347 -0
  101. package/dist/analyzers/security/aggregator.js.map +1 -0
  102. package/dist/analyzers/security/detailed.d.ts +2 -2
  103. package/dist/analyzers/security/detailed.d.ts.map +1 -1
  104. package/dist/analyzers/security/detailed.js +10 -9
  105. package/dist/analyzers/security/detailed.js.map +1 -1
  106. package/dist/analyzers/security/gather.d.ts +103 -1
  107. package/dist/analyzers/security/gather.d.ts.map +1 -1
  108. package/dist/analyzers/security/gather.js +281 -9
  109. package/dist/analyzers/security/gather.js.map +1 -1
  110. package/dist/analyzers/security/index.d.ts +15 -0
  111. package/dist/analyzers/security/index.d.ts.map +1 -1
  112. package/dist/analyzers/security/index.js +463 -50
  113. package/dist/analyzers/security/index.js.map +1 -1
  114. package/dist/analyzers/security/shallow.d.ts +50 -6
  115. package/dist/analyzers/security/shallow.d.ts.map +1 -1
  116. package/dist/analyzers/security/shallow.js +154 -2
  117. package/dist/analyzers/security/shallow.js.map +1 -1
  118. package/dist/analyzers/security/types.d.ts +51 -0
  119. package/dist/analyzers/security/types.d.ts.map +1 -1
  120. package/dist/analyzers/tests/detailed.d.ts.map +1 -1
  121. package/dist/analyzers/tests/detailed.js +2 -3
  122. package/dist/analyzers/tests/detailed.js.map +1 -1
  123. package/dist/analyzers/tests/gather.d.ts +2 -1
  124. package/dist/analyzers/tests/gather.d.ts.map +1 -1
  125. package/dist/analyzers/tests/gather.js +98 -69
  126. package/dist/analyzers/tests/gather.js.map +1 -1
  127. package/dist/analyzers/tests/index.d.ts +11 -2
  128. package/dist/analyzers/tests/index.d.ts.map +1 -1
  129. package/dist/analyzers/tests/index.js +83 -18
  130. package/dist/analyzers/tests/index.js.map +1 -1
  131. package/dist/analyzers/tests/shallow.d.ts +19 -5
  132. package/dist/analyzers/tests/shallow.d.ts.map +1 -1
  133. package/dist/analyzers/tests/shallow.js +89 -2
  134. package/dist/analyzers/tests/shallow.js.map +1 -1
  135. package/dist/analyzers/tests/types.d.ts +41 -1
  136. package/dist/analyzers/tests/types.d.ts.map +1 -1
  137. package/dist/analyzers/tools/autogen-header.d.ts +8 -0
  138. package/dist/analyzers/tools/autogen-header.d.ts.map +1 -0
  139. package/dist/analyzers/tools/autogen-header.js +107 -0
  140. package/dist/analyzers/tools/autogen-header.js.map +1 -0
  141. package/dist/analyzers/tools/cloc.d.ts.map +1 -1
  142. package/dist/analyzers/tools/cloc.js +36 -5
  143. package/dist/analyzers/tools/cloc.js.map +1 -1
  144. package/dist/analyzers/tools/debug-statements.d.ts +17 -0
  145. package/dist/analyzers/tools/debug-statements.d.ts.map +1 -0
  146. package/dist/analyzers/tools/debug-statements.js +58 -0
  147. package/dist/analyzers/tools/debug-statements.js.map +1 -0
  148. package/dist/analyzers/tools/default-exclusions.gitignore +28 -0
  149. package/dist/analyzers/tools/exclusions.d.ts +33 -6
  150. package/dist/analyzers/tools/exclusions.d.ts.map +1 -1
  151. package/dist/analyzers/tools/exclusions.js +95 -26
  152. package/dist/analyzers/tools/exclusions.js.map +1 -1
  153. package/dist/analyzers/tools/generic.d.ts +17 -2
  154. package/dist/analyzers/tools/generic.d.ts.map +1 -1
  155. package/dist/analyzers/tools/generic.js +206 -109
  156. package/dist/analyzers/tools/generic.js.map +1 -1
  157. package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
  158. package/dist/analyzers/tools/gitleaks.js +48 -1
  159. package/dist/analyzers/tools/gitleaks.js.map +1 -1
  160. package/dist/analyzers/tools/graphify.d.ts +30 -2
  161. package/dist/analyzers/tools/graphify.d.ts.map +1 -1
  162. package/dist/analyzers/tools/graphify.js +131 -15
  163. package/dist/analyzers/tools/graphify.js.map +1 -1
  164. package/dist/analyzers/tools/jscpd.d.ts +12 -2
  165. package/dist/analyzers/tools/jscpd.d.ts.map +1 -1
  166. package/dist/analyzers/tools/jscpd.js +129 -6
  167. package/dist/analyzers/tools/jscpd.js.map +1 -1
  168. package/dist/analyzers/tools/minified-detection.d.ts +9 -0
  169. package/dist/analyzers/tools/minified-detection.d.ts.map +1 -0
  170. package/dist/analyzers/tools/minified-detection.js +147 -0
  171. package/dist/analyzers/tools/minified-detection.js.map +1 -0
  172. package/dist/analyzers/tools/nuget-package-reference.d.ts +131 -0
  173. package/dist/analyzers/tools/nuget-package-reference.d.ts.map +1 -0
  174. package/dist/analyzers/tools/nuget-package-reference.js +175 -0
  175. package/dist/analyzers/tools/nuget-package-reference.js.map +1 -0
  176. package/dist/analyzers/tools/osv-scanner-deps.d.ts +3 -2
  177. package/dist/analyzers/tools/osv-scanner-deps.d.ts.map +1 -1
  178. package/dist/analyzers/tools/osv-scanner-deps.js +32 -14
  179. package/dist/analyzers/tools/osv-scanner-deps.js.map +1 -1
  180. package/dist/analyzers/tools/osv.d.ts +36 -0
  181. package/dist/analyzers/tools/osv.d.ts.map +1 -1
  182. package/dist/analyzers/tools/osv.js +26 -0
  183. package/dist/analyzers/tools/osv.js.map +1 -1
  184. package/dist/analyzers/tools/parallel.d.ts +1 -1
  185. package/dist/analyzers/tools/parallel.d.ts.map +1 -1
  186. package/dist/analyzers/tools/parallel.js +2 -2
  187. package/dist/analyzers/tools/parallel.js.map +1 -1
  188. package/dist/analyzers/tools/risk-score.d.ts +7 -0
  189. package/dist/analyzers/tools/risk-score.d.ts.map +1 -1
  190. package/dist/analyzers/tools/risk-score.js +9 -2
  191. package/dist/analyzers/tools/risk-score.js.map +1 -1
  192. package/dist/analyzers/tools/run-tests-helper.d.ts +43 -0
  193. package/dist/analyzers/tools/run-tests-helper.d.ts.map +1 -0
  194. package/dist/analyzers/tools/run-tests-helper.js +156 -0
  195. package/dist/analyzers/tools/run-tests-helper.js.map +1 -0
  196. package/dist/analyzers/tools/runner.d.ts.map +1 -1
  197. package/dist/analyzers/tools/runner.js +75 -12
  198. package/dist/analyzers/tools/runner.js.map +1 -1
  199. package/dist/analyzers/tools/semgrep.d.ts +39 -2
  200. package/dist/analyzers/tools/semgrep.d.ts.map +1 -1
  201. package/dist/analyzers/tools/semgrep.js +131 -9
  202. package/dist/analyzers/tools/semgrep.js.map +1 -1
  203. package/dist/analyzers/tools/timing.d.ts +17 -3
  204. package/dist/analyzers/tools/timing.d.ts.map +1 -1
  205. package/dist/analyzers/tools/timing.js +36 -14
  206. package/dist/analyzers/tools/timing.js.map +1 -1
  207. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
  208. package/dist/analyzers/tools/tool-registry.js +11 -1
  209. package/dist/analyzers/tools/tool-registry.js.map +1 -1
  210. package/dist/analyzers/tools/tools-unavailable-prose.d.ts +18 -0
  211. package/dist/analyzers/tools/tools-unavailable-prose.d.ts.map +1 -0
  212. package/dist/analyzers/tools/tools-unavailable-prose.js +69 -0
  213. package/dist/analyzers/tools/tools-unavailable-prose.js.map +1 -0
  214. package/dist/analyzers/tools/upgrade-plan-resolver.d.ts.map +1 -1
  215. package/dist/analyzers/tools/upgrade-plan-resolver.js +7 -0
  216. package/dist/analyzers/tools/upgrade-plan-resolver.js.map +1 -1
  217. package/dist/analyzers/tools/vendored-advisor.d.ts +43 -0
  218. package/dist/analyzers/tools/vendored-advisor.d.ts.map +1 -0
  219. package/dist/analyzers/tools/vendored-advisor.js +107 -0
  220. package/dist/analyzers/tools/vendored-advisor.js.map +1 -0
  221. package/dist/analyzers/tools/walk-paths.d.ts +78 -0
  222. package/dist/analyzers/tools/walk-paths.d.ts.map +1 -0
  223. package/dist/analyzers/tools/walk-paths.js +150 -0
  224. package/dist/analyzers/tools/walk-paths.js.map +1 -0
  225. package/dist/analyzers/tools/walk-source-files.d.ts +70 -0
  226. package/dist/analyzers/tools/walk-source-files.d.ts.map +1 -0
  227. package/dist/analyzers/tools/walk-source-files.js +369 -0
  228. package/dist/analyzers/tools/walk-source-files.js.map +1 -0
  229. package/dist/analyzers/types.d.ts +204 -4
  230. package/dist/analyzers/types.d.ts.map +1 -1
  231. package/dist/analyzers/xlsx/bom.d.ts.map +1 -1
  232. package/dist/analyzers/xlsx/bom.js +8 -1
  233. package/dist/analyzers/xlsx/bom.js.map +1 -1
  234. package/dist/cli.d.ts.map +1 -1
  235. package/dist/cli.js +557 -189
  236. package/dist/cli.js.map +1 -1
  237. package/dist/detect.d.ts.map +1 -1
  238. package/dist/detect.js +24 -7
  239. package/dist/detect.js.map +1 -1
  240. package/dist/doctor.d.ts.map +1 -1
  241. package/dist/doctor.js +103 -53
  242. package/dist/doctor.js.map +1 -1
  243. package/dist/languages/capabilities/provider.d.ts +130 -1
  244. package/dist/languages/capabilities/provider.d.ts.map +1 -1
  245. package/dist/languages/capabilities/types.d.ts +68 -7
  246. package/dist/languages/capabilities/types.d.ts.map +1 -1
  247. package/dist/languages/csharp.d.ts +15 -1
  248. package/dist/languages/csharp.d.ts.map +1 -1
  249. package/dist/languages/csharp.js +624 -146
  250. package/dist/languages/csharp.js.map +1 -1
  251. package/dist/languages/go.d.ts.map +1 -1
  252. package/dist/languages/go.js +89 -11
  253. package/dist/languages/go.js.map +1 -1
  254. package/dist/languages/index.d.ts +131 -2
  255. package/dist/languages/index.d.ts.map +1 -1
  256. package/dist/languages/index.js +206 -0
  257. package/dist/languages/index.js.map +1 -1
  258. package/dist/languages/java.d.ts.map +1 -1
  259. package/dist/languages/java.js +113 -26
  260. package/dist/languages/java.js.map +1 -1
  261. package/dist/languages/kotlin.d.ts.map +1 -1
  262. package/dist/languages/kotlin.js +132 -26
  263. package/dist/languages/kotlin.js.map +1 -1
  264. package/dist/languages/python.d.ts.map +1 -1
  265. package/dist/languages/python.js +149 -44
  266. package/dist/languages/python.js.map +1 -1
  267. package/dist/languages/ruby.d.ts +39 -1
  268. package/dist/languages/ruby.d.ts.map +1 -1
  269. package/dist/languages/ruby.js +178 -44
  270. package/dist/languages/ruby.js.map +1 -1
  271. package/dist/languages/rust.d.ts.map +1 -1
  272. package/dist/languages/rust.js +103 -16
  273. package/dist/languages/rust.js.map +1 -1
  274. package/dist/languages/types.d.ts +228 -5
  275. package/dist/languages/types.d.ts.map +1 -1
  276. package/dist/languages/typescript.d.ts.map +1 -1
  277. package/dist/languages/typescript.js +201 -14
  278. package/dist/languages/typescript.js.map +1 -1
  279. package/dist/scoring/dimensions/documentation.d.ts +53 -0
  280. package/dist/scoring/dimensions/documentation.d.ts.map +1 -0
  281. package/dist/scoring/dimensions/documentation.js +106 -0
  282. package/dist/scoring/dimensions/documentation.js.map +1 -0
  283. package/dist/scoring/dimensions/dx.d.ts +53 -0
  284. package/dist/scoring/dimensions/dx.d.ts.map +1 -0
  285. package/dist/scoring/dimensions/dx.js +105 -0
  286. package/dist/scoring/dimensions/dx.js.map +1 -0
  287. package/dist/scoring/dimensions/maintainability.d.ts +53 -0
  288. package/dist/scoring/dimensions/maintainability.d.ts.map +1 -0
  289. package/dist/scoring/dimensions/maintainability.js +101 -0
  290. package/dist/scoring/dimensions/maintainability.js.map +1 -0
  291. package/dist/scoring/dimensions/quality.d.ts +108 -0
  292. package/dist/scoring/dimensions/quality.d.ts.map +1 -0
  293. package/dist/scoring/dimensions/quality.js +174 -0
  294. package/dist/scoring/dimensions/quality.js.map +1 -0
  295. package/dist/scoring/dimensions/security.d.ts +84 -0
  296. package/dist/scoring/dimensions/security.d.ts.map +1 -0
  297. package/dist/scoring/dimensions/security.js +135 -0
  298. package/dist/scoring/dimensions/security.js.map +1 -0
  299. package/dist/scoring/dimensions/testing.d.ts +56 -0
  300. package/dist/scoring/dimensions/testing.d.ts.map +1 -0
  301. package/dist/scoring/dimensions/testing.js +98 -0
  302. package/dist/scoring/dimensions/testing.js.map +1 -0
  303. package/dist/scoring/evaluator.d.ts +27 -0
  304. package/dist/scoring/evaluator.d.ts.map +1 -0
  305. package/dist/scoring/evaluator.js +124 -0
  306. package/dist/scoring/evaluator.js.map +1 -0
  307. package/dist/scoring/format.d.ts +34 -0
  308. package/dist/scoring/format.d.ts.map +1 -0
  309. package/dist/scoring/format.js +63 -0
  310. package/dist/scoring/format.js.map +1 -0
  311. package/dist/scoring/index.d.ts +37 -0
  312. package/dist/scoring/index.d.ts.map +1 -0
  313. package/dist/scoring/index.js +57 -0
  314. package/dist/scoring/index.js.map +1 -0
  315. package/dist/scoring/overall.d.ts +54 -0
  316. package/dist/scoring/overall.d.ts.map +1 -0
  317. package/dist/scoring/overall.js +76 -0
  318. package/dist/scoring/overall.js.map +1 -0
  319. package/dist/scoring/result.d.ts +111 -0
  320. package/dist/scoring/result.d.ts.map +1 -0
  321. package/dist/scoring/result.js +14 -0
  322. package/dist/scoring/result.js.map +1 -0
  323. package/dist/scoring/spec.d.ts +76 -0
  324. package/dist/scoring/spec.d.ts.map +1 -0
  325. package/dist/scoring/spec.js +22 -0
  326. package/dist/scoring/spec.js.map +1 -0
  327. package/dist/scoring/thresholds.d.ts +56 -0
  328. package/dist/scoring/thresholds.d.ts.map +1 -0
  329. package/dist/scoring/thresholds.js +75 -0
  330. package/dist/scoring/thresholds.js.map +1 -0
  331. package/dist/tools-cli.d.ts.map +1 -1
  332. package/dist/tools-cli.js +21 -2
  333. package/dist/tools-cli.js.map +1 -1
  334. package/dist/types.d.ts +16 -0
  335. package/dist/types.d.ts.map +1 -1
  336. package/package.json +1 -1
  337. package/templates/.claude/commands/dashboard.md +17 -9
  338. package/dist/analyzers/scoring.d.ts +0 -49
  339. package/dist/analyzers/scoring.d.ts.map +0 -1
  340. package/dist/analyzers/scoring.js +0 -422
  341. package/dist/analyzers/scoring.js.map +0 -1
  342. package/dist/analyzers/security/scoring.d.ts +0 -29
  343. package/dist/analyzers/security/scoring.d.ts.map +0 -1
  344. package/dist/analyzers/security/scoring.js +0 -40
  345. package/dist/analyzers/security/scoring.js.map +0 -1
@@ -54,9 +54,10 @@ exports.clearExclusionsCache = clearExclusionsCache;
54
54
  exports.isExcludedPath = isExcludedPath;
55
55
  exports.getFindExcludeFlags = getFindExcludeFlags;
56
56
  exports.getGrepExcludeDirFlags = getGrepExcludeDirFlags;
57
- exports.getClocExcludeDirs = getClocExcludeDirs;
57
+ exports.getClocExcludeFlags = getClocExcludeFlags;
58
58
  exports.getSemgrepExcludeFlags = getSemgrepExcludeFlags;
59
- exports.getPythonExcludeSet = getPythonExcludeSet;
59
+ exports.getJscpdIgnorePatterns = getJscpdIgnorePatterns;
60
+ exports.getPythonExcludeFilter = getPythonExcludeFilter;
60
61
  const fs = __importStar(require("fs"));
61
62
  const path = __importStar(require("path"));
62
63
  /** Memo: one entry per cwd so repeated helper calls don't re-read files. */
@@ -206,18 +207,33 @@ function getGrepExcludeDirFlags(cwd) {
206
207
  return dirs.map((d) => `--exclude-dir='${d}'`).join(' ');
207
208
  }
208
209
  /**
209
- * Build cloc `--exclude-dir` argument value (comma-separated basenames).
210
- * cloc matches basenames only, so multi-segment sourcePaths get flattened.
210
+ * Build cloc exclusion flags — `--exclude-dir` (basenames) PLUS
211
+ * `--fullpath --not-match-d` (Perl regex on full directory path) for
212
+ * multi-segment sourcePaths.
213
+ *
214
+ * D055 (2.4.7): pre-fix, multi-segment paths in `.dxkit-ignore` were
215
+ * flattened to basenames here, so `Dev/Addons/DPLAddon/SAPB1/` silently
216
+ * became `{Dev, Addons, DPLAddon, SAPB1}` — cloc then excluded EVERY
217
+ * directory named `Dev` in the tree, killing 90% of source visibility
218
+ * on dpl-studio. The split-flag construction preserves the path
219
+ * structure for cloc.
220
+ *
221
+ * The regex is anchored on path-segment boundaries with `(?:^|/)` /
222
+ * `(?:/|$)` so `Dev/Addons/Foo` doesn't accidentally match `Dev/AddonsX`
223
+ * or `XDev/Addons`. Path components are regex-escaped so `.`, `+`, etc.
224
+ * aren't interpreted as metachars.
211
225
  */
212
- function getClocExcludeDirs(cwd) {
226
+ function getClocExcludeFlags(cwd) {
213
227
  const { dirs, sourcePaths } = loadExclusions(cwd);
214
- const basenames = new Set(dirs);
215
- for (const p of sourcePaths) {
216
- for (const seg of p.split('/'))
217
- if (seg)
218
- basenames.add(seg);
228
+ const parts = [];
229
+ if (dirs.length > 0) {
230
+ parts.push(`--exclude-dir=${dirs.join(',')}`);
231
+ }
232
+ if (sourcePaths.length > 0) {
233
+ const escaped = sourcePaths.map(escapeRegex);
234
+ parts.push(`--fullpath --not-match-d='(?:^|/)(?:${escaped.join('|')})(?:/|$)'`);
219
235
  }
220
- return Array.from(basenames).join(',');
236
+ return parts.join(' ');
221
237
  }
222
238
  /**
223
239
  * Build semgrep `--exclude` flags (one per directory/pattern).
@@ -229,22 +245,75 @@ function getSemgrepExcludeFlags(cwd) {
229
245
  const fileFlags = filePatterns.map((p) => `--exclude '${p}'`).join(' ');
230
246
  return `${dirFlags} ${fileFlags}`;
231
247
  }
232
- /**
233
- * Python set literal for graphify script — basenames only (flattened paths).
234
- * Used as a template substitution in the embedded Python script.
235
- */
236
- function getPythonExcludeSet(cwd) {
237
- const { dirs, sourcePaths } = loadExclusions(cwd);
238
- const basenames = new Set(dirs);
248
+ // Build jscpd `--ignore` glob patterns from the centralized exclusion set.
249
+ //
250
+ // jscpd's `--ignore` accepts a comma-separated glob list. Each pattern is
251
+ // prefixed with the recursive-globstar segment so it matches at any
252
+ // directory depth — the same convention `gatherJscpdResult` already uses
253
+ // for autogen patterns.
254
+ //
255
+ // Mapping:
256
+ // - dirs (basenames) → recursive-glob/<name>/recursive-glob
257
+ // - sourcePaths (multi-seg) → recursive-glob/<path>/recursive-glob
258
+ // - filePatterns (globs) → recursive-glob/<glob>
259
+ //
260
+ // Plumbs the same exclusion set the in-process walkers honor (grep, cloc,
261
+ // semgrep, graphify's Python filter) into jscpd's subprocess argument
262
+ // builder. Without this, jscpd only saw the autogen patterns + `--gitignore`,
263
+ // which left it descending into committed-vendored trees that aren't in the
264
+ // project's `.gitignore` — token tables exhaust heap on minified bundles,
265
+ // jscpd gets OOM-killed before flushing its JSON report, and the report
266
+ // reads "Duplication unavailable" on the very repos that need it most.
267
+ //
268
+ // Returns an array so callers can union with tool-specific extras (e.g.
269
+ // `allAutogenSourcePatterns()` in jscpd's wrapper) before joining.
270
+ function getJscpdIgnorePatterns(cwd) {
271
+ const { dirs, sourcePaths, filePatterns } = loadExclusions(cwd);
272
+ const out = [];
273
+ for (const d of dirs) {
274
+ out.push(`**/${d}/**`);
275
+ }
239
276
  for (const p of sourcePaths) {
240
- for (const seg of p.split('/'))
241
- if (seg)
242
- basenames.add(seg);
277
+ const trimmed = p.replace(/\/+$/, '');
278
+ if (trimmed)
279
+ out.push(`**/${trimmed}/**`);
280
+ }
281
+ for (const f of filePatterns) {
282
+ out.push(`**/${f}`);
243
283
  }
244
- return ('{' +
245
- Array.from(basenames)
246
- .map((d) => `'${d}'`)
247
- .join(', ') +
248
- '}');
284
+ return out;
285
+ }
286
+ /**
287
+ * Python literals for the graphify walker — emits both a basename set
288
+ * (`EXCLUDE_DIRS`) and a multi-segment path list (`EXCLUDE_PATHS`) so
289
+ * the Python filter can preserve the path structure of multi-segment
290
+ * `.dxkit-ignore` entries.
291
+ *
292
+ * D055 (2.4.7): pre-fix, basenames-only flattening here meant
293
+ * `Dev/Addons/DPLAddon/SAPB1/` became `{Dev, Addons, DPLAddon, SAPB1}`
294
+ * — graphify then skipped every `Dev/` subtree in dpl-studio (10 files
295
+ * walked instead of ~1700, Functions=13). The two-set shape lets the
296
+ * walker check basenames via segment membership AND check paths via
297
+ * substring match on the file's relpath.
298
+ */
299
+ function getPythonExcludeFilter(cwd) {
300
+ const { dirs, sourcePaths, filePatterns } = loadExclusions(cwd);
301
+ // `set([...])` rather than `{...}` because `{}` is an empty dict in Python.
302
+ const dirsSet = `set([${dirs.map((d) => `'${d}'`).join(', ')}])`;
303
+ const pathsList = '[' + sourcePaths.map((p) => `'${p}'`).join(', ') + ']';
304
+ // File-glob patterns (`*.min.js`, `*.bundle.js`, `*.chunk.js`,
305
+ // `*.generated.ts`, `*.d.ts`). Pre-extension only `dirs` + `sourcePaths`
306
+ // were passed; the graphify walker enumerated every `*.min.js`
307
+ // matching basename and graphify's AST extractor analyzed them.
308
+ // Web-client's densest-file metric ranked
309
+ // `public/3DFileViewer/assets/index-j54KQSsm.js` (a webpack-hash
310
+ // bundle) as 4,606 "functions" — the kind of metric that makes the
311
+ // "split your densest file" recommendation read as a bug to anyone
312
+ // who knows what the file is.
313
+ const fileGlobsList = '[' + filePatterns.map((p) => `'${p}'`).join(', ') + ']';
314
+ return { dirsSet, pathsList, fileGlobsList };
315
+ }
316
+ function escapeRegex(s) {
317
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
249
318
  }
250
319
  //# sourceMappingURL=exclusions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"exclusions.js","sourceRoot":"","sources":["../../../src/analyzers/tools/exclusions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"exclusions.js","sourceRoot":"","sources":["../../../src/analyzers/tools/exclusions.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,19 @@
1
+ /**
2
+ * Generic tool runner -- uses grep, find, wc, git (and the canonical
3
+ * walkSourceFiles / countLineMatches helpers for source-line metrics).
4
+ * Works on any Unix machine with no external dependencies.
5
+ * This is Layer 0: always available.
6
+ */
1
7
  import { HealthMetrics } from '../types';
2
- /** Gather metrics using only built-in Unix tools. */
3
- export declare function gatherGenericMetrics(cwd: string): Partial<HealthMetrics>;
8
+ import type { DetectedStack } from '../../types';
9
+ /**
10
+ * Gather metrics using only built-in Unix tools + the canonical walker.
11
+ *
12
+ * `languageFlags` drives the architecturalShape-aware path counters
13
+ * (primary components, route handlers, data models). When omitted
14
+ * (legacy callers, tests) the path counters degrade to zero rather
15
+ * than silently using a hardcoded backend-centric default — every
16
+ * shipped caller in the codebase threads the active stack through.
17
+ */
18
+ export declare function gatherGenericMetrics(cwd: string, languageFlags?: DetectedStack['languages']): Partial<HealthMetrics>;
4
19
  //# sourceMappingURL=generic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/generic.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqDzC,qDAAqD;AACrD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA4KxE"}
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/generic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+DjD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,aAAa,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,GACzC,OAAO,CAAC,aAAa,CAAC,CAiOxB"}
@@ -34,137 +34,233 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.gatherGenericMetrics = gatherGenericMetrics;
37
- /**
38
- * Generic tool runner -- uses grep, find, wc, git.
39
- * Works on any Unix machine with no external dependencies.
40
- * This is Layer 0: always available.
41
- */
42
- const fs = __importStar(require("fs"));
43
37
  const runner_1 = require("./runner");
44
38
  const exclusions_1 = require("./exclusions");
39
+ const walk_source_files_1 = require("./walk-source-files");
40
+ const debug_statements_1 = require("./debug-statements");
45
41
  const languages_1 = require("../../languages");
46
- // grepCount uses a narrow filter (node_modules, dist, __pycache__, .d.ts) to
47
- // preserve pre-refactor byte-equality. The broader EXCLUDED_DIRS list from
48
- // exclusions.ts is used for find-based counts. Widening this filter would
49
- // change legitimate metric totals and should be a separate, intentional change.
50
- const GREP_PIPELINE_FILTER = 'grep -v node_modules | grep -v dist | grep -v __pycache__';
51
- /** Reliable grep count that avoids shell escaping issues by writing pattern to a temp file. */
52
- function grepCount(cwd, pattern, includes) {
53
- const patternFile = `/tmp/dxkit-grep-${Date.now()}-${Math.random().toString(36).slice(2)}.pat`;
54
- fs.writeFileSync(patternFile, pattern);
55
- const includeFlags = includes.map((i) => `--include='${i}'`).join(' ');
56
- const result = (0, runner_1.run)(`grep -rEf '${patternFile}' ${includeFlags} . 2>/dev/null | ${GREP_PIPELINE_FILTER} | grep -v '.d.ts' | wc -l`, cwd);
57
- try {
58
- fs.unlinkSync(patternFile);
59
- }
60
- catch {
61
- /* ignore */
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ // D055/D056/D072 (2.4.7): every per-source-file metric (rawSourceFiles,
45
+ // wc-l walk, jsConsoleCount, anyTypeCount, evalCount, docCommentFiles,
46
+ // tlsDisabledCount, testFiles) routes through walkSourceFiles +
47
+ // countLineMatches. Closes the class of "site-specific walker drift"
48
+ // (D075/D077) and "grep maxBuffer overflow" (D082/D083/D084) by
49
+ // construction: ONE walker, ONE counter, files pruned at the
50
+ // directory boundary so we never read minified .min.js into memory.
51
+ //
52
+ // `EXCLUDE = getFindExcludeFlags(cwd)` is retained below for find
53
+ // commands that count NON-source artifacts (controllers, models,
54
+ // directories, ciConfigCount) — those legitimately walk path
55
+ // patterns the walker doesn't model.
56
+ /**
57
+ * Resolve the git toplevel for `cwd`. D026 (2.4.7): cross-cutting repo
58
+ * artifacts (`.github/`, `README.md`, `CONTRIBUTING.md`, `Makefile`,
59
+ * `.env.example`, etc.) conventionally live at the repo root, not in
60
+ * the subdirectory a user happens to scan. dpl-studio's baseline F8:
61
+ * customer ran `dxkit health Code/Source/`; both Documentation and DX
62
+ * dimensions returned 0/100 because none of those probes found
63
+ * matches in `Code/Source/`. The fix scopes those probes to the
64
+ * git toplevel.
65
+ *
66
+ * Returns `cwd` unchanged when `git rev-parse --show-toplevel` fails
67
+ * (not in a git repo, or git missing) so non-git workflows keep
68
+ * working — they just don't get the toplevel-scoped improvement.
69
+ */
70
+ function resolveGitToplevel(cwd) {
71
+ const top = (0, runner_1.run)('git rev-parse --show-toplevel 2>/dev/null', cwd).trim();
72
+ return top.length > 0 ? top : cwd;
73
+ }
74
+ /**
75
+ * Count newlines in `content`. Equivalent to `wc -l` semantics:
76
+ * trailing newline NOT double-counted; file with no trailing newline
77
+ * still counts its last line.
78
+ */
79
+ function lineCount(content) {
80
+ if (content.length === 0)
81
+ return 0;
82
+ let count = 0;
83
+ for (let i = 0; i < content.length; i++) {
84
+ if (content.charCodeAt(i) === 10 /* \n */)
85
+ count++;
62
86
  }
63
- return parseInt(result) || 0;
87
+ // No trailing newline → the last partial line was a line too.
88
+ if (content.charCodeAt(content.length - 1) !== 10)
89
+ count++;
90
+ return count;
64
91
  }
65
- // EXCLUDE moved inside gatherGenericMetrics() — must be computed per-cwd now
66
- // so it picks up project-specific .gitignore / .dxkit-ignore entries.
67
- // Pack-driven find expressions (Phase 10i.0-LP.3). Replaces the
68
- // pre-LP hardcoded extension/pattern lists with iteration over the
69
- // language registry. Adding a 6th pack auto-extends both expressions.
70
- //
71
- // Behavior expansions vs pre-LP.3 (both more correct than before):
72
- // - `.mjs`/`.cjs` now counted as source files (TypeScript pack
73
- // declared them in `sourceExtensions`; the legacy hardcoded list
74
- // missed them).
75
- // - Rust integration tests under `tests/*.rs` now counted as test
76
- // files (Rust pack declared `tests/*.rs` as a path-anchored
77
- // pattern; the legacy used only `-name` and skipped path patterns).
78
- const SOURCE_EXTS = `\\( ${(0, languages_1.allSourceExtensions)()
79
- .map((e) => `-name "*${e}"`)
80
- .join(' -o ')} \\)`;
81
- const TEST_PATTERNS = (() => {
82
- const { nameOnly, pathAnchored } = (0, languages_1.splitTestFilePatterns)();
83
- const nameClauses = nameOnly.map((p) => `-name "${p}"`);
84
- const pathClauses = pathAnchored.map((p) => `-path "*/${p}"`);
85
- return `\\( ${[...nameClauses, ...pathClauses].join(' -o ')} \\)`;
86
- })();
87
- /** Gather metrics using only built-in Unix tools. */
88
- function gatherGenericMetrics(cwd) {
92
+ /**
93
+ * Gather metrics using only built-in Unix tools + the canonical walker.
94
+ *
95
+ * `languageFlags` drives the architecturalShape-aware path counters
96
+ * (primary components, route handlers, data models). When omitted
97
+ * (legacy callers, tests) the path counters degrade to zero rather
98
+ * than silently using a hardcoded backend-centric default — every
99
+ * shipped caller in the codebase threads the active stack through.
100
+ */
101
+ function gatherGenericMetrics(cwd, languageFlags) {
89
102
  const EXCLUDE = (0, exclusions_1.getFindExcludeFlags)(cwd);
90
- // File counts
91
- const sourceFiles = (0, runner_1.countLines)(`find . -type f ${SOURCE_EXTS} ${EXCLUDE}`, cwd);
92
- const testFiles = (0, runner_1.countLines)(`find . -type f ${TEST_PATTERNS} ${EXCLUDE}`, cwd);
93
- const testDirFiles = (0, runner_1.countLines)(`find . -type f ${SOURCE_EXTS} ${EXCLUDE} \\( -path "*/__tests__/*" -o -path "*/tests/*" -o -path "*/test/*" \\) 2>/dev/null`, cwd);
94
- // Total lines, largest file, files over 500 — single find+xargs wc pass
95
- const wcRaw = (0, runner_1.run)(`find . -type f ${SOURCE_EXTS} ${EXCLUDE} -print0 2>/dev/null | xargs -0 wc -l 2>/dev/null`, cwd, 120000);
103
+ // D026 (2.4.7): repo-level artifacts probed from git toplevel; code-
104
+ // level metrics (source-file counts, hygiene grep, semgrep) stay
105
+ // scoped to `cwd` so analyzing a subdirectory still measures that
106
+ // subdir's code quality.
107
+ const repoRoot = resolveGitToplevel(cwd);
108
+ // ─── Source / test file enumeration ───────────────────────────────────────
109
+ // ONE walker, every consumer routes through it. The walker's filter
110
+ // pipeline already applies: exclusions (.gitignore + .dxkit-ignore +
111
+ // bundled defaults), autogen basename globs (*.designer.cs etc.),
112
+ // autogen header markers (<auto-generated> / @generated / DO NOT EDIT),
113
+ // test-file patterns (per `includeTests`). Memoized per cwd+opts.
114
+ //
115
+ // 2.4.7 class-fix alignment: `sourceFiles` now excludes test files,
116
+ // matching test-gaps' definition. Pre-fix health included tests in
117
+ // `sourceFiles` (D075 same-label-different-meaning class). The
118
+ // Testing dimension's `testRatio = testFiles / sourceFiles` is
119
+ // mathematically equivalent (numerator drops to 0 simultaneously
120
+ // when there's a test file in the denominator), so user-visible
121
+ // scoring is unchanged in practice.
122
+ const sourceList = (0, walk_source_files_1.walkSourceFiles)(cwd);
123
+ const sourceListWithTests = (0, walk_source_files_1.walkSourceFiles)(cwd, { includeTests: true });
124
+ const testList = sourceListWithTests.filter((p) => !sourceList.includes(p));
125
+ // ─── Per-file line counts (replaces find + xargs wc -l) ───────────────────
126
+ // 2.4.7: pure in-process read. Catches the D028-header / autogen
127
+ // filtering at walker-time, so we don't need a second-pass header
128
+ // filter the way the old code did. Also: largestFiles + filesOver500.
129
+ const filteredFiles = [];
130
+ for (const relPath of sourceList) {
131
+ let content;
132
+ try {
133
+ content = fs.readFileSync(path.join(cwd, relPath), 'utf-8');
134
+ }
135
+ catch {
136
+ continue;
137
+ }
138
+ filteredFiles.push({ path: relPath, lines: lineCount(content) });
139
+ }
96
140
  let totalLines = 0;
97
141
  let largestFileLines = 0;
98
142
  let largestFilePath = '';
99
143
  let filesOver500Lines = 0;
100
- if (wcRaw) {
101
- for (const line of wcRaw.split('\n')) {
102
- const m = line.trim().match(/^(\d+)\s+(.+)$/);
103
- if (!m)
104
- continue;
105
- const lines = parseInt(m[1]);
106
- const file = m[2];
107
- if (file === 'total') {
108
- totalLines = lines;
109
- }
110
- else {
111
- if (lines > largestFileLines) {
112
- largestFileLines = lines;
113
- largestFilePath = file;
114
- }
115
- if (lines > 500)
116
- filesOver500Lines++;
117
- }
144
+ for (const f of filteredFiles) {
145
+ totalLines += f.lines;
146
+ if (f.lines > largestFileLines) {
147
+ largestFileLines = f.lines;
148
+ largestFilePath = f.path;
118
149
  }
119
- // If only one file, xargs wc won't print "total"
120
- if (totalLines === 0 && largestFileLines > 0)
121
- totalLines = largestFileLines;
150
+ if (f.lines > 500)
151
+ filesOver500Lines++;
122
152
  }
123
- // Console/debug statement count -- use grepCount helper for reliability
124
- const jsConsoleCount = grepCount(cwd, 'console\\.(log|error|warn)', ['*.ts', '*.tsx', '*.js']);
125
- const pyPrintCount = grepCount(cwd, '\\bprint\\(', ['*.py']);
126
- const goPrintCount = grepCount(cwd, 'fmt\\.Print', ['*.go']);
127
- const consoleLogCount = jsConsoleCount + pyPrintCount + goPrintCount;
128
- // TypeScript ": any" count
129
- const anyTypeCount = grepCount(cwd, ': any', ['*.ts', '*.tsx']);
130
- // Documentation
131
- const readmeExists = (0, runner_1.fileExists)(cwd, 'README.md', 'readme.md');
132
- const readmeLines = parseInt((0, runner_1.run)("wc -l README.md 2>/dev/null | awk '{print $1}'", cwd)) || 0;
133
- const docCommentFiles = (0, runner_1.countLines)("grep -rlE '/\\*\\*|^\"\"\"|^[[:space:]]*#[[:space:]]' --include='*.ts' --include='*.py' --include='*.go' . 2>/dev/null | grep -v node_modules | grep -v dist", cwd);
134
- const apiDocsExist = (0, runner_1.fileExists)(cwd, 'openapi.json', 'openapi.yaml', 'swagger.json', 'swagger.yaml');
135
- const architectureDocsExist = (0, runner_1.fileExists)(cwd, 'ARCHITECTURE.md', 'docs/', 'ADR/', 'adr/');
136
- const contributingExists = (0, runner_1.fileExists)(cwd, 'CONTRIBUTING.md');
137
- const changelogExists = (0, runner_1.fileExists)(cwd, 'CHANGELOG.md', 'CHANGES.md');
138
- // Security — secret scanning lives entirely under the SECRETS capability
139
- // (gitleaks, 800+ patterns). The 7-pattern grep fallback that used to
140
- // live here was deleted in Phase 10e.C.7 along with the legacy
141
- // `secretFindings` / `secretDetails` fields. When gitleaks is absent
142
- // the report surfaces that fact through `toolsUnavailable` and the
143
- // capability envelope is simply absent.
144
- const evalCount = parseInt((0, runner_1.run)("grep -rnE '\\beval\\(' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null | grep -v node_modules | grep -v dist | wc -l", cwd)) || 0;
153
+ const sourceFiles = sourceList.length;
154
+ const largestFiles = [...filteredFiles].sort((a, b) => b.lines - a.lines).slice(0, 10);
155
+ // ─── Console / debug / type-escape / eval counts (D074 closure) ───────────
156
+ // skipComments: true filters lines beginning with //, /*, or # so
157
+ // commented-out occurrences don't inflate the count.
158
+ //
159
+ // 2.4.7 D079 closure: `consoleLogCount` now routes through the shared
160
+ // `gatherDebugStatements` helper — same implementation in health AND
161
+ // quality, so the two reports cannot drift on this metric. Counts
162
+ // the print family across active languages (TS/JS/Py/Go).
163
+ const consoleLogCount = (0, debug_statements_1.gatherDebugStatements)(cwd).count;
164
+ // TypeScript escape-hatch count.
165
+ const tsFiles = (0, walk_source_files_1.walkSourceFiles)(cwd, {
166
+ extensions: ['.ts', '.tsx', '.js', '.jsx'],
167
+ includeTests: true,
168
+ });
169
+ // prettier-ignore
170
+ const anyTypeCount = (0, walk_source_files_1.countLineMatches)(cwd, tsFiles, [': any'], { skipComments: true }).lines; // slop-ok
171
+ // ─── Documentation ────────────────────────────────────────────────────────
172
+ // D026 (2.4.7): probe from repo root, not from cwd.
173
+ const readmeExists = (0, runner_1.fileExists)(repoRoot, 'README.md', 'readme.md');
174
+ const readmeLines = parseInt((0, runner_1.run)("wc -l README.md 2>/dev/null | awk '{print $1}'", repoRoot)) || 0;
175
+ // D027 (2.4.7): doc-comment regex + include flags derive from the
176
+ // language pack registry. countLineMatches mode='files' returns the
177
+ // file count. NO skipComments here — we explicitly WANT comment lines.
178
+ const docCommentPatterns = (0, languages_1.allDocCommentPatterns)();
179
+ const docCommentFiles = docCommentPatterns.length > 0
180
+ ? (0, walk_source_files_1.countLineMatches)(cwd, sourceList, docCommentPatterns, { mode: 'files' }).files
181
+ : 0;
182
+ const apiDocsExist = (0, runner_1.fileExists)(repoRoot, 'openapi.json', 'openapi.yaml', 'swagger.json', 'swagger.yaml');
183
+ const architectureDocsExist = (0, runner_1.fileExists)(repoRoot, 'ARCHITECTURE.md', 'docs/', 'ADR/', 'adr/');
184
+ const contributingExists = (0, runner_1.fileExists)(repoRoot, 'CONTRIBUTING.md');
185
+ const changelogExists = (0, runner_1.fileExists)(repoRoot, 'CHANGELOG.md', 'CHANGES.md');
186
+ // ─── Security (eval + TLS-bypass + cert/key files) ────────────────────────
187
+ // D056 (2.4.7): routed through the canonical counter so .dxkit-ignore /
188
+ // .gitignore / bundled defaults all apply. D074 (2.4.7): skipComments
189
+ // strips commented-out `eval(` and TLS-bypass idioms.
190
+ const evalFiles = (0, walk_source_files_1.walkSourceFiles)(cwd, {
191
+ extensions: ['.ts', '.tsx', '.js', '.jsx', '.py'],
192
+ includeTests: true,
193
+ });
194
+ const evalCount = (0, walk_source_files_1.countLineMatches)(cwd, evalFiles, ['\\beval\\('], {
195
+ skipComments: true,
196
+ }).lines;
145
197
  const privateKeyFiles = (0, runner_1.countLines)(`find . \\( -name "*.key" -o -name "*.pem" \\) ${EXCLUDE} 2>/dev/null`, cwd);
146
198
  const envFilesInGit = (0, runner_1.countLines)('git ls-files .env .env.* 2>/dev/null', cwd);
147
- const tlsDisabledCount = parseInt((0, runner_1.run)("grep -rnE 'NODE_TLS_REJECT_UNAUTHORIZED.*0|rejectUnauthorized.*false|VERIFY_SSL.*false' --include='*.ts' --include='*.js' --include='*.py' . 2>/dev/null | grep -v node_modules | wc -l", cwd)) || 0;
148
- // Maintainability
149
- const controllers = (0, runner_1.countLines)(`find . \\( -path "*/controllers/*" -name "*.ts" -o -path "*/handlers/*" -name "*.go" -o -path "*/views/*" -name "*.py" \\) ${EXCLUDE} 2>/dev/null`, cwd);
150
- const models = (0, runner_1.countLines)(`find . -path "*/models/*" -type f ${SOURCE_EXTS} ${EXCLUDE} 2>/dev/null`, cwd);
199
+ // D034 (2.4.7): TLS-bypass detection derives from the pack registry.
200
+ // D074 (2.4.7): skipComments closes the "vuln-scan rendered a
201
+ // `// NODE_TLS_REJECT_UNAUTHORIZED=0` comment as a HIGH finding"
202
+ // false-positive class on platform.
203
+ const tlsBypassPatterns = (0, languages_1.allTlsBypassPatterns)();
204
+ const tlsDisabledCount = tlsBypassPatterns.length > 0
205
+ ? (0, walk_source_files_1.countLineMatches)(cwd, sourceList, tlsBypassPatterns, { skipComments: true }).lines
206
+ : 0;
207
+ // ─── Maintainability (per-pack architectural counts) ───────────────────────
208
+ // Primary-component, route-handler, and data-model counts derive
209
+ // from the active language packs' `architecturalShape`. Pre-extension
210
+ // these were three hardcoded find commands keyed on backend-centric
211
+ // paths (`controllers/`, `handlers/`, `views/`, `models/`), so a pure
212
+ // React frontend or a .NET WinForms desktop app reported zero in all
213
+ // three counters regardless of how much primary architecture sat on
214
+ // disk. The walker visit already enumerated every source file; here
215
+ // we filter `sourceList` (pre-walked + autogen-excluded + exclusion-
216
+ // honoured) by case-insensitive substring match against the unioned
217
+ // pack contributions.
218
+ const flags = languageFlags ?? {};
219
+ const primaryPaths = (0, languages_1.allPrimaryComponentPaths)(flags).map((p) => p.toLowerCase());
220
+ const routePaths = (0, languages_1.allRoutePaths)(flags).map((p) => p.toLowerCase());
221
+ const modelPaths = (0, languages_1.allModelPaths)(flags).map((p) => p.toLowerCase());
222
+ const matchesAny = (p, needles) => {
223
+ if (needles.length === 0)
224
+ return false;
225
+ const lower = p.toLowerCase();
226
+ for (const n of needles) {
227
+ if (lower.includes(n))
228
+ return true;
229
+ }
230
+ return false;
231
+ };
232
+ let controllers = 0;
233
+ let routeHandlerFiles = 0;
234
+ let models = 0;
235
+ for (const rel of sourceList) {
236
+ // Match against the path with a leading slash so substring patterns
237
+ // like "/controllers/" anchor on a directory boundary, never on a
238
+ // filename like "controllers-helper.ts" floating outside such a dir.
239
+ const anchored = '/' + rel;
240
+ if (matchesAny(anchored, primaryPaths))
241
+ controllers++;
242
+ if (matchesAny(anchored, routePaths))
243
+ routeHandlerFiles++;
244
+ if (matchesAny(anchored, modelPaths))
245
+ models++;
246
+ }
151
247
  const directories = (0, runner_1.countLines)(`find . -type d ${EXCLUDE} 2>/dev/null`, cwd);
152
- // Developer Experience
153
- const ciConfigCount = (0, runner_1.countLines)('find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null; ls .gitlab-ci.yml Jenkinsfile .circleci/config.yml 2>/dev/null', cwd);
154
- const dockerConfigCount = (0, runner_1.countLines)('ls Dockerfile docker-compose.yml docker-compose.yaml .devcontainer/devcontainer.json 2>/dev/null', cwd);
155
- const precommitConfigCount = (0, runner_1.countLines)('ls -d .husky .pre-commit-config.yaml .git/hooks/pre-commit 2>/dev/null', cwd);
156
- const makefileExists = (0, runner_1.fileExists)(cwd, 'Makefile', 'justfile', 'Taskfile.yml');
157
- const envExampleExists = (0, runner_1.fileExists)(cwd, '.env.example', '.env.sample', '.env.template');
158
- // Coverage config
159
- const coverageConfigExists = (0, runner_1.fileExists)(cwd, '.nycrc', '.nycrc.json', '.c8rc', '.c8rc.json', 'jest.config.js', 'jest.config.ts', 'vitest.config.ts', 'vitest.config.js', '.coveragerc', 'setup.cfg', 'pytest.ini');
248
+ // ─── Developer Experience (repo-root scoped) ──────────────────────────────
249
+ const ciConfigCount = (0, runner_1.countLines)('find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null; ls .gitlab-ci.yml Jenkinsfile .circleci/config.yml 2>/dev/null', repoRoot);
250
+ const dockerConfigCount = (0, runner_1.countLines)('ls Dockerfile docker-compose.yml docker-compose.yaml .devcontainer/devcontainer.json 2>/dev/null', repoRoot);
251
+ const precommitConfigCount = (0, runner_1.countLines)('ls -d .husky .pre-commit-config.yaml .git/hooks/pre-commit 2>/dev/null', repoRoot);
252
+ const makefileExists = (0, runner_1.fileExists)(repoRoot, 'Makefile', 'justfile', 'Taskfile.yml');
253
+ const envExampleExists = (0, runner_1.fileExists)(repoRoot, '.env.example', '.env.sample', '.env.template');
254
+ const coverageConfigExists = (0, runner_1.fileExists)(repoRoot, '.nycrc', '.nycrc.json', '.c8rc', '.c8rc.json', 'jest.config.js', 'jest.config.ts', 'vitest.config.ts', 'vitest.config.js', '.coveragerc', 'setup.cfg', 'pytest.ini');
160
255
  return {
161
256
  sourceFiles,
162
- testFiles: testFiles + testDirFiles,
257
+ testFiles: testList.length,
163
258
  totalLines,
164
259
  coverageConfigExists,
165
260
  filesOver500Lines,
166
261
  largestFileLines,
167
262
  largestFilePath,
263
+ largestFiles,
168
264
  consoleLogCount,
169
265
  anyTypeCount,
170
266
  readmeExists,
@@ -180,6 +276,7 @@ function gatherGenericMetrics(cwd) {
180
276
  tlsDisabledCount,
181
277
  controllers,
182
278
  models,
279
+ routeHandlerFiles,
183
280
  directories,
184
281
  ciConfigCount,
185
282
  dockerConfigCount,