pr-checkmate 3.0.4 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/dist/{cli.js → cjs/cli.js} +30 -30
  2. package/dist/{config → cjs/config}/index.d.ts +2 -2
  3. package/dist/{config → cjs/config}/index.js +8 -7
  4. package/dist/{config → cjs/config}/loader.d.ts +1 -1
  5. package/dist/{config → cjs/config}/loader.js +8 -8
  6. package/dist/{core → cjs/core}/checks/dependencies/banned-imports.d.ts +1 -1
  7. package/dist/{core → cjs/core}/checks/dependencies/banned-imports.js +10 -10
  8. package/dist/{core → cjs/core}/checks/dependencies/circular-deps.d.ts +1 -1
  9. package/dist/{core → cjs/core}/checks/dependencies/circular-deps.js +27 -27
  10. package/dist/{core → cjs/core}/checks/dependencies/dependency-check.d.ts +1 -1
  11. package/dist/{core → cjs/core}/checks/dependencies/dependency-check.js +17 -17
  12. package/dist/{core → cjs/core}/checks/dependencies/grype-scan.d.ts +1 -1
  13. package/dist/{core → cjs/core}/checks/dependencies/grype-scan.js +18 -18
  14. package/dist/{core → cjs/core}/checks/dependencies/license-check.d.ts +1 -1
  15. package/dist/{core → cjs/core}/checks/dependencies/license-check.js +12 -12
  16. package/dist/{core → cjs/core}/checks/dependencies/npm-audit.d.ts +1 -1
  17. package/dist/{core → cjs/core}/checks/dependencies/npm-audit.js +14 -14
  18. package/dist/{core → cjs/core}/checks/dependencies/outdated-deps.d.ts +1 -1
  19. package/dist/{core → cjs/core}/checks/dependencies/outdated-deps.js +14 -14
  20. package/dist/{core → cjs/core}/checks/dependencies/vuln-scan.d.ts +1 -1
  21. package/dist/{core → cjs/core}/checks/dependencies/vuln-scan.js +14 -14
  22. package/dist/{core → cjs/core}/checks/findings.d.ts +1 -1
  23. package/dist/{core → cjs/core}/checks/findings.js +16 -16
  24. package/dist/{core → cjs/core}/checks/git/custom-rules.d.ts +1 -1
  25. package/dist/{core → cjs/core}/checks/git/custom-rules.js +19 -19
  26. package/dist/{core → cjs/core}/checks/git/diff-smell.d.ts +2 -2
  27. package/dist/{core → cjs/core}/checks/git/diff-smell.js +13 -13
  28. package/dist/{core → cjs/core}/checks/git/large-files.d.ts +1 -1
  29. package/dist/{core → cjs/core}/checks/git/large-files.js +15 -15
  30. package/dist/{core → cjs/core}/checks/git/leftover-debug.d.ts +1 -1
  31. package/dist/{core → cjs/core}/checks/git/leftover-debug.js +13 -13
  32. package/dist/{core → cjs/core}/checks/git/lockfile-drift.d.ts +1 -1
  33. package/dist/{core → cjs/core}/checks/git/lockfile-drift.js +12 -12
  34. package/dist/{core → cjs/core}/checks/git/merge-conflict.d.ts +1 -1
  35. package/dist/{core → cjs/core}/checks/git/merge-conflict.js +15 -15
  36. package/dist/{core → cjs/core}/checks/git/missing-tests.d.ts +1 -1
  37. package/dist/{core → cjs/core}/checks/git/missing-tests.js +15 -15
  38. package/dist/{core → cjs/core}/checks/git/todo-fixme.d.ts +1 -1
  39. package/dist/{core → cjs/core}/checks/git/todo-fixme.js +11 -11
  40. package/dist/{core → cjs/core}/checks/languages/cpp-format.d.ts +1 -1
  41. package/dist/{core → cjs/core}/checks/languages/cpp-format.js +18 -18
  42. package/dist/{core → cjs/core}/checks/languages/external-checks.d.ts +9 -9
  43. package/dist/{core → cjs/core}/checks/languages/external-checks.js +10 -10
  44. package/dist/{core → cjs/core}/checks/languages/external-runner.d.ts +2 -2
  45. package/dist/{core → cjs/core}/checks/languages/external-runner.js +21 -21
  46. package/dist/{core → cjs/core}/checks/languages/go-format.d.ts +1 -1
  47. package/dist/cjs/core/checks/languages/go-format.js +202 -0
  48. package/dist/cjs/core/checks/languages/lint.d.ts +2 -0
  49. package/dist/{core → cjs/core}/checks/languages/lint.js +21 -21
  50. package/dist/{core → cjs/core}/checks/languages/prettier.d.ts +1 -1
  51. package/dist/{core → cjs/core}/checks/languages/prettier.js +18 -18
  52. package/dist/{core → cjs/core}/checks/languages/python-format.d.ts +1 -1
  53. package/dist/{core → cjs/core}/checks/languages/python-format.js +14 -14
  54. package/dist/{core → cjs/core}/checks/languages/python-lint.d.ts +1 -1
  55. package/dist/{core → cjs/core}/checks/languages/python-lint.js +13 -13
  56. package/dist/{core → cjs/core}/checks/languages/python-typecheck.d.ts +1 -1
  57. package/dist/{core → cjs/core}/checks/languages/python-typecheck.js +29 -29
  58. package/dist/{core → cjs/core}/checks/languages/typecheck.d.ts +1 -1
  59. package/dist/{core → cjs/core}/checks/languages/typecheck.js +13 -13
  60. package/dist/{core → cjs/core}/checks/pr/commitlint.d.ts +1 -1
  61. package/dist/{core → cjs/core}/checks/pr/commitlint.js +12 -12
  62. package/dist/{core → cjs/core}/checks/pr/pr-body.d.ts +1 -1
  63. package/dist/{core → cjs/core}/checks/pr/pr-body.js +8 -8
  64. package/dist/{core → cjs/core}/checks/pr/pr-size-check.d.ts +1 -1
  65. package/dist/{core → cjs/core}/checks/pr/pr-size-check.js +10 -10
  66. package/dist/{core → cjs/core}/checks/pr/pr-title-lint.d.ts +1 -1
  67. package/dist/{core → cjs/core}/checks/pr/pr-title-lint.js +8 -8
  68. package/dist/{core → cjs/core}/checks/quality/case-collision.d.ts +1 -1
  69. package/dist/{core → cjs/core}/checks/quality/case-collision.js +7 -7
  70. package/dist/{core → cjs/core}/checks/quality/config-validation.d.ts +1 -1
  71. package/dist/{core → cjs/core}/checks/quality/config-validation.js +9 -9
  72. package/dist/{core → cjs/core}/checks/quality/coverage.d.ts +1 -1
  73. package/dist/{core → cjs/core}/checks/quality/coverage.js +4 -4
  74. package/dist/{core → cjs/core}/checks/quality/dead-code.d.ts +1 -1
  75. package/dist/{core → cjs/core}/checks/quality/dead-code.js +23 -23
  76. package/dist/{core → cjs/core}/checks/quality/duplicate-check.d.ts +1 -1
  77. package/dist/{core → cjs/core}/checks/quality/duplicate-check.js +22 -22
  78. package/dist/{core → cjs/core}/checks/quality/license-header.d.ts +1 -1
  79. package/dist/{core → cjs/core}/checks/quality/license-header.js +16 -16
  80. package/dist/{core → cjs/core}/checks/quality/markdown-lint.d.ts +1 -1
  81. package/dist/{core → cjs/core}/checks/quality/markdown-lint.js +17 -17
  82. package/dist/{core → cjs/core}/checks/quality/package-size.d.ts +1 -1
  83. package/dist/{core → cjs/core}/checks/quality/package-size.js +12 -12
  84. package/dist/{core → cjs/core}/checks/quality/spellcheck.d.ts +2 -2
  85. package/dist/{core → cjs/core}/checks/quality/spellcheck.js +18 -18
  86. package/dist/{core → cjs/core}/checks/quality/symlinks.d.ts +1 -1
  87. package/dist/{core → cjs/core}/checks/quality/symlinks.js +8 -8
  88. package/dist/{core → cjs/core}/checks/quality/yaml-lint.d.ts +1 -1
  89. package/dist/{core → cjs/core}/checks/quality/yaml-lint.js +12 -12
  90. package/dist/{core → cjs/core}/checks/security/diff-security.d.ts +1 -1
  91. package/dist/{core → cjs/core}/checks/security/diff-security.js +15 -15
  92. package/dist/{core → cjs/core}/checks/security/dockerfile-security.d.ts +1 -1
  93. package/dist/{core → cjs/core}/checks/security/dockerfile-security.js +16 -16
  94. package/dist/{core → cjs/core}/checks/security/migration-safety.d.ts +1 -1
  95. package/dist/{core → cjs/core}/checks/security/migration-safety.js +17 -17
  96. package/dist/{core → cjs/core}/checks/security/security.d.ts +1 -1
  97. package/dist/{core → cjs/core}/checks/security/security.js +21 -21
  98. package/dist/{core → cjs/core}/checks/security/sensitive-file-guard.d.ts +1 -1
  99. package/dist/{core → cjs/core}/checks/security/sensitive-file-guard.js +14 -14
  100. package/dist/{core → cjs/core}/checks/security/workflow-security.d.ts +2 -2
  101. package/dist/{core → cjs/core}/checks/security/workflow-security.js +14 -14
  102. package/dist/{core → cjs/core}/checks/tool-install.d.ts +1 -1
  103. package/dist/{core → cjs/core}/checks/tool-install.js +2 -2
  104. package/dist/{core → cjs/core}/context.d.ts +1 -1
  105. package/dist/{core → cjs/core}/context.js +16 -16
  106. package/dist/cjs/core/index.d.ts +4 -0
  107. package/dist/{core → cjs/core}/index.js +7 -7
  108. package/dist/{core → cjs/core}/install/cache.js +2 -2
  109. package/dist/{core → cjs/core}/install/doctor.d.ts +4 -4
  110. package/dist/{core → cjs/core}/install/doctor.js +34 -34
  111. package/dist/{core → cjs/core}/install/ensure.d.ts +2 -2
  112. package/dist/{core → cjs/core}/install/ensure.js +15 -14
  113. package/dist/{core → cjs/core}/install/lock.js +4 -4
  114. package/dist/{core → cjs/core}/install/prepare.d.ts +4 -4
  115. package/dist/{core → cjs/core}/install/prepare.js +13 -13
  116. package/dist/{core → cjs/core}/install/profiles.d.ts +2 -2
  117. package/dist/{core → cjs/core}/install/reuse.d.ts +1 -1
  118. package/dist/{core → cjs/core}/install/reuse.js +4 -4
  119. package/dist/{core → cjs/core}/registry.d.ts +1 -1
  120. package/dist/cjs/core/registry.js +112 -0
  121. package/dist/{core → cjs/core}/reporters.d.ts +1 -1
  122. package/dist/{core → cjs/core}/reporters.js +28 -28
  123. package/dist/{core → cjs/core}/run-checks.d.ts +2 -2
  124. package/dist/{core → cjs/core}/run-checks.js +31 -31
  125. package/dist/{core → cjs/core}/targets.d.ts +1 -1
  126. package/dist/{core → cjs/core}/targets.js +20 -20
  127. package/dist/{core → cjs/core}/types.d.ts +3 -3
  128. package/dist/cjs/index.d.ts +12 -0
  129. package/dist/{index.js → cjs/index.js} +18 -18
  130. package/dist/{init.js → cjs/init.js} +68 -56
  131. package/dist/{interfaces → cjs/interfaces}/index.d.ts +3 -3
  132. package/dist/cjs/package.json +1 -0
  133. package/dist/{scripts → cjs/scripts}/copy-configs.js +22 -7
  134. package/dist/{scripts → cjs/scripts}/generate-install-manifests.js +2 -2
  135. package/dist/{scripts → cjs/scripts}/publish-github.js +4 -4
  136. package/dist/{utils → cjs/utils}/detect-language.js +12 -12
  137. package/dist/cjs/utils/execa.js +46 -0
  138. package/dist/{utils → cjs/utils}/git.js +2 -2
  139. package/dist/{utils → cjs/utils}/http.js +2 -2
  140. package/dist/cjs/utils/index.d.ts +15 -0
  141. package/dist/{utils → cjs/utils}/index.js +13 -13
  142. package/dist/{utils → cjs/utils}/own-deps.d.ts +2 -0
  143. package/dist/{utils → cjs/utils}/own-deps.js +1 -0
  144. package/dist/{utils → cjs/utils}/package-version.js +2 -1
  145. package/dist/{utils → cjs/utils}/resolve-bin.js +2 -1
  146. package/dist/{utils → cjs/utils}/update-notifier.js +4 -4
  147. package/dist/esm/cli.d.ts +2 -0
  148. package/dist/esm/cli.js +137 -0
  149. package/dist/esm/config/constants.d.ts +153 -0
  150. package/dist/esm/config/constants.js +360 -0
  151. package/dist/esm/config/index.d.ts +40 -0
  152. package/dist/esm/config/index.js +60 -0
  153. package/dist/esm/config/loader.d.ts +6 -0
  154. package/dist/esm/config/loader.js +191 -0
  155. package/dist/esm/config/pr-checkmate-workflow-docker.yml +79 -0
  156. package/dist/esm/config/pr-checkmate-workflow.yml +92 -0
  157. package/dist/esm/core/checks/dependencies/banned-imports.d.ts +2 -0
  158. package/dist/esm/core/checks/dependencies/banned-imports.js +70 -0
  159. package/dist/esm/core/checks/dependencies/circular-deps.d.ts +2 -0
  160. package/dist/esm/core/checks/dependencies/circular-deps.js +155 -0
  161. package/dist/esm/core/checks/dependencies/dependency-check.d.ts +43 -0
  162. package/dist/esm/core/checks/dependencies/dependency-check.js +174 -0
  163. package/dist/esm/core/checks/dependencies/grype-scan.d.ts +22 -0
  164. package/dist/esm/core/checks/dependencies/grype-scan.js +112 -0
  165. package/dist/esm/core/checks/dependencies/license-check.d.ts +2 -0
  166. package/dist/esm/core/checks/dependencies/license-check.js +61 -0
  167. package/dist/esm/core/checks/dependencies/npm-audit.d.ts +6 -0
  168. package/dist/esm/core/checks/dependencies/npm-audit.js +80 -0
  169. package/dist/esm/core/checks/dependencies/outdated-deps.d.ts +2 -0
  170. package/dist/esm/core/checks/dependencies/outdated-deps.js +66 -0
  171. package/dist/esm/core/checks/dependencies/vuln-scan.d.ts +2 -0
  172. package/dist/esm/core/checks/dependencies/vuln-scan.js +54 -0
  173. package/dist/esm/core/checks/findings.d.ts +299 -0
  174. package/dist/esm/core/checks/findings.js +701 -0
  175. package/dist/esm/core/checks/git/custom-rules.d.ts +2 -0
  176. package/dist/esm/core/checks/git/custom-rules.js +106 -0
  177. package/dist/esm/core/checks/git/diff-smell.d.ts +19 -0
  178. package/dist/esm/core/checks/git/diff-smell.js +69 -0
  179. package/dist/esm/core/checks/git/large-files.d.ts +2 -0
  180. package/dist/esm/core/checks/git/large-files.js +112 -0
  181. package/dist/esm/core/checks/git/leftover-debug.d.ts +2 -0
  182. package/dist/esm/core/checks/git/leftover-debug.js +89 -0
  183. package/dist/esm/core/checks/git/lockfile-drift.d.ts +2 -0
  184. package/dist/esm/core/checks/git/lockfile-drift.js +114 -0
  185. package/dist/esm/core/checks/git/merge-conflict.d.ts +2 -0
  186. package/dist/esm/core/checks/git/merge-conflict.js +117 -0
  187. package/dist/esm/core/checks/git/missing-tests.d.ts +2 -0
  188. package/dist/esm/core/checks/git/missing-tests.js +105 -0
  189. package/dist/esm/core/checks/git/todo-fixme.d.ts +7 -0
  190. package/dist/esm/core/checks/git/todo-fixme.js +80 -0
  191. package/dist/esm/core/checks/languages/cpp-format.d.ts +7 -0
  192. package/dist/esm/core/checks/languages/cpp-format.js +91 -0
  193. package/dist/esm/core/checks/languages/external-checks.d.ts +77 -0
  194. package/dist/esm/core/checks/languages/external-checks.js +197 -0
  195. package/dist/esm/core/checks/languages/external-runner.d.ts +119 -0
  196. package/dist/esm/core/checks/languages/external-runner.js +138 -0
  197. package/dist/esm/core/checks/languages/go-format.d.ts +8 -0
  198. package/dist/{core → esm/core}/checks/languages/go-format.js +29 -35
  199. package/dist/esm/core/checks/languages/lint.d.ts +2 -0
  200. package/dist/esm/core/checks/languages/lint.js +92 -0
  201. package/dist/esm/core/checks/languages/prettier.d.ts +2 -0
  202. package/dist/esm/core/checks/languages/prettier.js +85 -0
  203. package/dist/esm/core/checks/languages/python-format.d.ts +7 -0
  204. package/dist/esm/core/checks/languages/python-format.js +61 -0
  205. package/dist/esm/core/checks/languages/python-lint.d.ts +9 -0
  206. package/dist/esm/core/checks/languages/python-lint.js +55 -0
  207. package/dist/esm/core/checks/languages/python-typecheck.d.ts +14 -0
  208. package/dist/esm/core/checks/languages/python-typecheck.js +184 -0
  209. package/dist/esm/core/checks/languages/ruff-shared.d.ts +10 -0
  210. package/dist/esm/core/checks/languages/ruff-shared.js +35 -0
  211. package/dist/esm/core/checks/languages/typecheck.d.ts +2 -0
  212. package/dist/esm/core/checks/languages/typecheck.js +61 -0
  213. package/dist/esm/core/checks/pr/commitlint.d.ts +2 -0
  214. package/dist/esm/core/checks/pr/commitlint.js +102 -0
  215. package/dist/esm/core/checks/pr/pr-body.d.ts +2 -0
  216. package/dist/esm/core/checks/pr/pr-body.js +43 -0
  217. package/dist/esm/core/checks/pr/pr-size-check.d.ts +2 -0
  218. package/dist/esm/core/checks/pr/pr-size-check.js +42 -0
  219. package/dist/esm/core/checks/pr/pr-title-lint.d.ts +2 -0
  220. package/dist/esm/core/checks/pr/pr-title-lint.js +31 -0
  221. package/dist/esm/core/checks/quality/case-collision.d.ts +8 -0
  222. package/dist/esm/core/checks/quality/case-collision.js +39 -0
  223. package/dist/esm/core/checks/quality/config-validation.d.ts +11 -0
  224. package/dist/esm/core/checks/quality/config-validation.js +188 -0
  225. package/dist/esm/core/checks/quality/coverage.d.ts +2 -0
  226. package/dist/esm/core/checks/quality/coverage.js +62 -0
  227. package/dist/esm/core/checks/quality/dead-code.d.ts +2 -0
  228. package/dist/esm/core/checks/quality/dead-code.js +124 -0
  229. package/dist/esm/core/checks/quality/duplicate-check.d.ts +2 -0
  230. package/dist/esm/core/checks/quality/duplicate-check.js +141 -0
  231. package/dist/esm/core/checks/quality/license-header.d.ts +7 -0
  232. package/dist/esm/core/checks/quality/license-header.js +81 -0
  233. package/dist/esm/core/checks/quality/markdown-lint.d.ts +2 -0
  234. package/dist/esm/core/checks/quality/markdown-lint.js +104 -0
  235. package/dist/esm/core/checks/quality/package-size.d.ts +36 -0
  236. package/dist/esm/core/checks/quality/package-size.js +196 -0
  237. package/dist/esm/core/checks/quality/spellcheck.d.ts +77 -0
  238. package/dist/esm/core/checks/quality/spellcheck.js +296 -0
  239. package/dist/esm/core/checks/quality/symlinks.d.ts +16 -0
  240. package/dist/esm/core/checks/quality/symlinks.js +57 -0
  241. package/dist/esm/core/checks/quality/yaml-lint.d.ts +20 -0
  242. package/dist/esm/core/checks/quality/yaml-lint.js +116 -0
  243. package/dist/esm/core/checks/security/diff-security.d.ts +2 -0
  244. package/dist/esm/core/checks/security/diff-security.js +354 -0
  245. package/dist/esm/core/checks/security/dockerfile-security.d.ts +2 -0
  246. package/dist/esm/core/checks/security/dockerfile-security.js +98 -0
  247. package/dist/esm/core/checks/security/migration-safety.d.ts +2 -0
  248. package/dist/esm/core/checks/security/migration-safety.js +137 -0
  249. package/dist/esm/core/checks/security/security.d.ts +63 -0
  250. package/dist/esm/core/checks/security/security.js +201 -0
  251. package/dist/esm/core/checks/security/sensitive-file-guard.d.ts +2 -0
  252. package/dist/esm/core/checks/security/sensitive-file-guard.js +160 -0
  253. package/dist/esm/core/checks/security/workflow-security.d.ts +12 -0
  254. package/dist/esm/core/checks/security/workflow-security.js +100 -0
  255. package/dist/esm/core/checks/tool-install.d.ts +102 -0
  256. package/dist/esm/core/checks/tool-install.js +66 -0
  257. package/dist/esm/core/commands.d.ts +27 -0
  258. package/dist/esm/core/commands.js +89 -0
  259. package/dist/esm/core/context.d.ts +62 -0
  260. package/dist/esm/core/context.js +241 -0
  261. package/dist/esm/core/index.d.ts +4 -0
  262. package/dist/esm/core/index.js +4 -0
  263. package/dist/esm/core/install/cache.d.ts +58 -0
  264. package/dist/esm/core/install/cache.js +142 -0
  265. package/dist/esm/core/install/doctor.d.ts +35 -0
  266. package/dist/esm/core/install/doctor.js +164 -0
  267. package/dist/esm/core/install/ensure.d.ts +77 -0
  268. package/dist/esm/core/install/ensure.js +269 -0
  269. package/dist/esm/core/install/lock.d.ts +34 -0
  270. package/dist/esm/core/install/lock.js +92 -0
  271. package/dist/esm/core/install/merge.d.ts +47 -0
  272. package/dist/esm/core/install/merge.js +85 -0
  273. package/dist/esm/core/install/prepare.d.ts +76 -0
  274. package/dist/esm/core/install/prepare.js +142 -0
  275. package/dist/esm/core/install/profiles.d.ts +78 -0
  276. package/dist/esm/core/install/profiles.js +192 -0
  277. package/dist/esm/core/install/reuse.d.ts +41 -0
  278. package/dist/esm/core/install/reuse.js +100 -0
  279. package/dist/esm/core/registry.d.ts +6 -0
  280. package/dist/esm/core/registry.js +109 -0
  281. package/dist/esm/core/reporters.d.ts +18 -0
  282. package/dist/esm/core/reporters.js +266 -0
  283. package/dist/esm/core/run-checks.d.ts +33 -0
  284. package/dist/esm/core/run-checks.js +293 -0
  285. package/dist/esm/core/targets.d.ts +140 -0
  286. package/dist/esm/core/targets.js +213 -0
  287. package/dist/esm/core/types.d.ts +195 -0
  288. package/dist/esm/core/types.js +38 -0
  289. package/dist/esm/index.d.ts +12 -0
  290. package/dist/esm/index.js +15 -0
  291. package/dist/esm/init.d.ts +38 -0
  292. package/dist/esm/init.js +421 -0
  293. package/dist/esm/interfaces/index.d.ts +432 -0
  294. package/dist/esm/interfaces/index.js +2 -0
  295. package/dist/esm/package.json +1 -0
  296. package/dist/esm/scripts/copy-configs.d.ts +1 -0
  297. package/dist/esm/scripts/copy-configs.js +64 -0
  298. package/dist/esm/scripts/generate-install-manifests.d.ts +39 -0
  299. package/dist/esm/scripts/generate-install-manifests.js +115 -0
  300. package/dist/esm/scripts/publish-github.d.ts +1 -0
  301. package/dist/esm/scripts/publish-github.js +45 -0
  302. package/dist/esm/utils/ci.d.ts +11 -0
  303. package/dist/esm/utils/ci.js +40 -0
  304. package/dist/esm/utils/detect-language.d.ts +48 -0
  305. package/dist/esm/utils/detect-language.js +234 -0
  306. package/dist/esm/utils/direct-deps.d.ts +21 -0
  307. package/dist/esm/utils/direct-deps.js +220 -0
  308. package/dist/esm/utils/execa.d.ts +22 -0
  309. package/dist/{utils → esm/utils}/execa.js +1 -4
  310. package/dist/esm/utils/git.d.ts +14 -0
  311. package/dist/esm/utils/git.js +21 -0
  312. package/dist/esm/utils/glob.d.ts +24 -0
  313. package/dist/esm/utils/glob.js +40 -0
  314. package/dist/esm/utils/http.d.ts +59 -0
  315. package/dist/esm/utils/http.js +115 -0
  316. package/dist/esm/utils/index.d.ts +15 -0
  317. package/dist/esm/utils/index.js +26 -0
  318. package/dist/esm/utils/logger.d.ts +65 -0
  319. package/dist/esm/utils/logger.js +157 -0
  320. package/dist/esm/utils/own-deps.d.ts +16 -0
  321. package/dist/esm/utils/own-deps.js +107 -0
  322. package/dist/esm/utils/package-version.d.ts +4 -0
  323. package/dist/esm/utils/package-version.js +38 -0
  324. package/dist/esm/utils/pool.d.ts +49 -0
  325. package/dist/esm/utils/pool.js +113 -0
  326. package/dist/esm/utils/resolve-bin.d.ts +67 -0
  327. package/dist/esm/utils/resolve-bin.js +156 -0
  328. package/dist/esm/utils/result-collector.d.ts +33 -0
  329. package/dist/esm/utils/result-collector.js +44 -0
  330. package/dist/esm/utils/update-notifier.d.ts +19 -0
  331. package/dist/esm/utils/update-notifier.js +108 -0
  332. package/install-manifests/core/package-lock.json +4 -4
  333. package/install-manifests/core/package.json +1 -1
  334. package/package.json +15 -13
  335. package/dist/core/checks/languages/lint.d.ts +0 -2
  336. package/dist/core/index.d.ts +0 -4
  337. package/dist/core/registry.js +0 -112
  338. package/dist/index.d.ts +0 -12
  339. package/dist/utils/index.d.ts +0 -15
  340. /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
  341. /package/dist/{config → cjs/config}/constants.d.ts +0 -0
  342. /package/dist/{config → cjs/config}/constants.js +0 -0
  343. /package/dist/{config → cjs/config}/pr-checkmate-workflow-docker.yml +0 -0
  344. /package/dist/{config → cjs/config}/pr-checkmate-workflow.yml +0 -0
  345. /package/dist/{core → cjs/core}/checks/languages/ruff-shared.d.ts +0 -0
  346. /package/dist/{core → cjs/core}/checks/languages/ruff-shared.js +0 -0
  347. /package/dist/{core → cjs/core}/commands.d.ts +0 -0
  348. /package/dist/{core → cjs/core}/commands.js +0 -0
  349. /package/dist/{core → cjs/core}/install/cache.d.ts +0 -0
  350. /package/dist/{core → cjs/core}/install/lock.d.ts +0 -0
  351. /package/dist/{core → cjs/core}/install/merge.d.ts +0 -0
  352. /package/dist/{core → cjs/core}/install/merge.js +0 -0
  353. /package/dist/{core → cjs/core}/install/profiles.js +0 -0
  354. /package/dist/{core → cjs/core}/types.js +0 -0
  355. /package/dist/{init.d.ts → cjs/init.d.ts} +0 -0
  356. /package/dist/{interfaces → cjs/interfaces}/index.js +0 -0
  357. /package/dist/{scripts → cjs/scripts}/copy-configs.d.ts +0 -0
  358. /package/dist/{scripts → cjs/scripts}/generate-install-manifests.d.ts +0 -0
  359. /package/dist/{scripts → cjs/scripts}/publish-github.d.ts +0 -0
  360. /package/dist/{utils → cjs/utils}/ci.d.ts +0 -0
  361. /package/dist/{utils → cjs/utils}/ci.js +0 -0
  362. /package/dist/{utils → cjs/utils}/detect-language.d.ts +0 -0
  363. /package/dist/{utils → cjs/utils}/direct-deps.d.ts +0 -0
  364. /package/dist/{utils → cjs/utils}/direct-deps.js +0 -0
  365. /package/dist/{utils → cjs/utils}/execa.d.ts +0 -0
  366. /package/dist/{utils → cjs/utils}/git.d.ts +0 -0
  367. /package/dist/{utils → cjs/utils}/glob.d.ts +0 -0
  368. /package/dist/{utils → cjs/utils}/glob.js +0 -0
  369. /package/dist/{utils → cjs/utils}/http.d.ts +0 -0
  370. /package/dist/{utils → cjs/utils}/logger.d.ts +0 -0
  371. /package/dist/{utils → cjs/utils}/logger.js +0 -0
  372. /package/dist/{utils → cjs/utils}/package-version.d.ts +0 -0
  373. /package/dist/{utils → cjs/utils}/pool.d.ts +0 -0
  374. /package/dist/{utils → cjs/utils}/pool.js +0 -0
  375. /package/dist/{utils → cjs/utils}/resolve-bin.d.ts +0 -0
  376. /package/dist/{utils → cjs/utils}/result-collector.d.ts +0 -0
  377. /package/dist/{utils → cjs/utils}/result-collector.js +0 -0
  378. /package/dist/{utils → cjs/utils}/update-notifier.d.ts +0 -0
@@ -0,0 +1,38 @@
1
+ import { fileURLToPath as __fileURLToPath } from 'node:url';
2
+ import { dirname as __dirnameFn } from 'node:path';
3
+ const __dirname = __dirnameFn(__fileURLToPath(import.meta.url));
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { findOwnPackageRoot } from './own-deps.js';
7
+ /**
8
+ * Our own name and version, read from the manifest that ships inside the package.
9
+ *
10
+ * Read from disk rather than baked in at build time so it is the *running* copy
11
+ * that answers. That distinction is the whole point: a stale global install
12
+ * (`npm i -g pr-checkmate`) shadows the project's own copy on `PATH`, and a repo
13
+ * pinned to the latest version can still be checked by a year-old binary without
14
+ * anything in the log saying so. One client spent a while reading an upgrade
15
+ * notice for a version they had already installed, because nothing printed which
16
+ * version was speaking.
17
+ *
18
+ * Falls back to placeholders rather than throwing: no caller here is important
19
+ * enough to fail a run over a manifest it could not read.
20
+ */
21
+ function readManifest() {
22
+ try {
23
+ const manifest = path.join(findOwnPackageRoot() ?? path.resolve(__dirname, '../../..'), 'package.json');
24
+ const parsed = JSON.parse(fs.readFileSync(manifest, 'utf-8'));
25
+ return { name: parsed.name ?? 'pr-checkmate', version: parsed.version ?? '0.0.0' };
26
+ }
27
+ catch {
28
+ return { name: 'pr-checkmate', version: '0.0.0' };
29
+ }
30
+ }
31
+ /** The version of pr-checkmate that is executing right now. */
32
+ export function packageVersion() {
33
+ return readManifest().version;
34
+ }
35
+ /** The package name that is executing right now — the one to query npm for. */
36
+ export function packageName() {
37
+ return readManifest().name;
38
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Run tasks with a bounded number in flight.
3
+ *
4
+ * `Promise.all` over a whole phase started every check at once — thirty-seven of
5
+ * them in the informational phase, many spawning heavy processes (cspell, jscpd,
6
+ * knip, dpdm, grype, tsc). On a two-core runner that is context-switch thrashing:
7
+ * the wall clock gets worse, not better, and a large monorepo can run the machine
8
+ * out of memory.
9
+ *
10
+ * Results come back in the order the tasks were given, so callers can pair them
11
+ * with their inputs.
12
+ */
13
+ export declare function runPool<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<Array<T | undefined>>;
14
+ /**
15
+ * Default concurrency for this machine.
16
+ *
17
+ * One core is left for the orchestrator and whatever else the runner is doing,
18
+ * and the ceiling of four keeps a 32-core developer laptop from starting thirty
19
+ * subprocesses that then fight over disk. On the standard two-core CI runner this
20
+ * resolves to 1, which is the case the old code handled worst.
21
+ */
22
+ export declare function defaultConcurrency(): number;
23
+ /** Resolve the client's `run.concurrency` setting into a number. */
24
+ export declare function resolveConcurrency(setting: number | 'auto' | 'unlimited' | undefined): number;
25
+ /**
26
+ * A counting semaphore, used to admit only a few expensive checks at a time.
27
+ *
28
+ * The overall limit is not enough on its own: four concurrent checks are fine
29
+ * when they are regex scans and ruinous when they are knip, jscpd, dpdm and tsc,
30
+ * each of which wants a core and a few hundred megabytes to itself.
31
+ */
32
+ export declare class Semaphore {
33
+ private available;
34
+ private readonly waiting;
35
+ constructor(limit: number);
36
+ /** Run `fn` once a slot is free, releasing it even if `fn` throws. */
37
+ run<T>(fn: () => Promise<T>): Promise<T>;
38
+ private acquire;
39
+ private release;
40
+ }
41
+ /**
42
+ * Race a promise against a timeout, resolving to `onTimeout` if it wins.
43
+ *
44
+ * A check that never returns used to hold the whole phase — and with it the run —
45
+ * open indefinitely. Note the underlying work is not killed: there is no portable
46
+ * way to do that here, so it is left to finish in the background while the run
47
+ * moves on and reports the timeout.
48
+ */
49
+ export declare function withTimeout<T>(work: Promise<T>, timeoutMs: number, onTimeout: () => T): Promise<T>;
@@ -0,0 +1,113 @@
1
+ import os from 'node:os';
2
+ /**
3
+ * Run tasks with a bounded number in flight.
4
+ *
5
+ * `Promise.all` over a whole phase started every check at once — thirty-seven of
6
+ * them in the informational phase, many spawning heavy processes (cspell, jscpd,
7
+ * knip, dpdm, grype, tsc). On a two-core runner that is context-switch thrashing:
8
+ * the wall clock gets worse, not better, and a large monorepo can run the machine
9
+ * out of memory.
10
+ *
11
+ * Results come back in the order the tasks were given, so callers can pair them
12
+ * with their inputs.
13
+ */
14
+ export async function runPool(tasks, limit) {
15
+ const bound = Math.max(1, Math.floor(limit));
16
+ const results = new Array(tasks.length);
17
+ let next = 0;
18
+ const worker = async () => {
19
+ while (next < tasks.length) {
20
+ const index = next++;
21
+ results[index] = await tasks[index]();
22
+ }
23
+ };
24
+ await Promise.all(Array.from({ length: Math.min(bound, tasks.length) }, worker));
25
+ return results;
26
+ }
27
+ /**
28
+ * Default concurrency for this machine.
29
+ *
30
+ * One core is left for the orchestrator and whatever else the runner is doing,
31
+ * and the ceiling of four keeps a 32-core developer laptop from starting thirty
32
+ * subprocesses that then fight over disk. On the standard two-core CI runner this
33
+ * resolves to 1, which is the case the old code handled worst.
34
+ */
35
+ export function defaultConcurrency() {
36
+ const cores = os.cpus()?.length ?? 2;
37
+ return Math.max(1, Math.min(4, cores - 1));
38
+ }
39
+ /** Resolve the client's `run.concurrency` setting into a number. */
40
+ export function resolveConcurrency(setting) {
41
+ const fromEnv = process.env.PR_CHECKMATE_CONCURRENCY;
42
+ const value = fromEnv ?? setting ?? 'auto';
43
+ if (value === 'unlimited')
44
+ return Number.MAX_SAFE_INTEGER;
45
+ if (value === 'auto')
46
+ return defaultConcurrency();
47
+ const parsed = typeof value === 'number' ? value : parseInt(value, 10);
48
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultConcurrency();
49
+ }
50
+ /**
51
+ * A counting semaphore, used to admit only a few expensive checks at a time.
52
+ *
53
+ * The overall limit is not enough on its own: four concurrent checks are fine
54
+ * when they are regex scans and ruinous when they are knip, jscpd, dpdm and tsc,
55
+ * each of which wants a core and a few hundred megabytes to itself.
56
+ */
57
+ export class Semaphore {
58
+ constructor(limit) {
59
+ this.waiting = [];
60
+ this.available = Math.max(1, limit);
61
+ }
62
+ /** Run `fn` once a slot is free, releasing it even if `fn` throws. */
63
+ async run(fn) {
64
+ await this.acquire();
65
+ try {
66
+ return await fn();
67
+ }
68
+ finally {
69
+ this.release();
70
+ }
71
+ }
72
+ async acquire() {
73
+ if (this.available > 0) {
74
+ this.available--;
75
+ return;
76
+ }
77
+ return new Promise(resolve => this.waiting.push(resolve));
78
+ }
79
+ release() {
80
+ const next = this.waiting.shift();
81
+ if (next)
82
+ next();
83
+ else
84
+ this.available++;
85
+ }
86
+ }
87
+ /**
88
+ * Race a promise against a timeout, resolving to `onTimeout` if it wins.
89
+ *
90
+ * A check that never returns used to hold the whole phase — and with it the run —
91
+ * open indefinitely. Note the underlying work is not killed: there is no portable
92
+ * way to do that here, so it is left to finish in the background while the run
93
+ * moves on and reports the timeout.
94
+ */
95
+ export async function withTimeout(work, timeoutMs, onTimeout) {
96
+ if (timeoutMs <= 0)
97
+ return work;
98
+ let timer;
99
+ try {
100
+ return await Promise.race([
101
+ work,
102
+ new Promise(resolve => {
103
+ timer = setTimeout(() => resolve(onTimeout()), timeoutMs);
104
+ // Do not keep the event loop alive purely for this timer.
105
+ timer.unref?.();
106
+ }),
107
+ ]);
108
+ }
109
+ finally {
110
+ if (timer)
111
+ clearTimeout(timer);
112
+ }
113
+ }
@@ -0,0 +1,67 @@
1
+ /** Where a tool was found, in the order the candidates are tried. */
2
+ export type ToolSource = 'client' | 'profile' | 'bundled';
3
+ /** A resolved tool binary, and which copy of it answered. */
4
+ export interface ResolvedTool {
5
+ bin: string;
6
+ source: ToolSource;
7
+ /** The search root that produced it; `undefined` for module-relative resolution. */
8
+ root?: string;
9
+ }
10
+ /**
11
+ * Point tool resolution at the profile directories fetched for this run.
12
+ *
13
+ * Called by the install layer once the cache is known. Passing an empty list —
14
+ * or never calling it at all — leaves resolution exactly as it was before
15
+ * profiles existed, which is what keeps a run that needs no fetching identical
16
+ * to a run from before there was anything to fetch.
17
+ */
18
+ export declare function registerToolPaths(dirs: string[]): void;
19
+ /** Drop every registered profile root. For tests, and for a second run in-process. */
20
+ export declare function clearToolPaths(): void;
21
+ /** The root of the installed pr-checkmate package — where our own tooling lives. */
22
+ export declare function ownPackageRoot(): string;
23
+ /**
24
+ * Whether a package is physically present in our own dependency tree.
25
+ *
26
+ * Checked by walking `node_modules` upwards rather than by `require.resolve`,
27
+ * because a package that restricts its `exports` map resolves for neither its
28
+ * main entry nor its `package.json` while being perfectly well installed —
29
+ * `cspell` is one. The question here is only "is it there", and the directory
30
+ * answers that without an opinion about what it chooses to export.
31
+ *
32
+ * Walking up matters as much as the check itself: installed as a dependency, our
33
+ * own packages are hoisted to the client's `node_modules`, one level above ours.
34
+ */
35
+ export declare function packagePresent(pkgName: string, from?: string): boolean;
36
+ /**
37
+ * Resolve a tool's binary and say which copy answered.
38
+ *
39
+ * Use this over {@link resolvePackageBin} when the answer is worth logging — the
40
+ * source is the difference between "the client's ESLint 8 ran" and "ours did",
41
+ * and that is the first thing anyone asks when a lint result looks wrong.
42
+ *
43
+ * @param pkgName Package whose binary to resolve (e.g. `eslint`).
44
+ * @param binRelPath Bin path relative to the package root (e.g. `bin/eslint.js`).
45
+ * @param options Resolution options.
46
+ * @param options.paths Roots to prefer ahead of everything else. Use
47
+ * `[process.cwd()]` to prefer the consumer project's copy.
48
+ */
49
+ export declare function resolveTool(pkgName: string, binRelPath: string, options?: {
50
+ paths?: string[];
51
+ }): ResolvedTool | null;
52
+ /**
53
+ * Resolves a binary path for a bundled package, bypassing exports map restrictions.
54
+ *
55
+ * Throws when no copy can be found anywhere, which is the honest outcome: a check
56
+ * that cannot find its tool has nothing to report, and the install layer turns
57
+ * that into a skip with a reason rather than letting it surface as a stack trace.
58
+ *
59
+ * @param pkgName - The package whose binary to resolve (e.g. `eslint`).
60
+ * @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
61
+ * @param options - Resolution options.
62
+ * @param options.paths - Directories to resolve from, preferred over everything
63
+ * else. Use `[process.cwd()]` to prefer the consumer project's copy.
64
+ */
65
+ export declare function resolvePackageBin(pkgName: string, binRelPath: string, options?: {
66
+ paths?: string[];
67
+ }): string;
@@ -0,0 +1,156 @@
1
+ import { fileURLToPath as __fileURLToPath } from 'node:url';
2
+ import { dirname as __dirnameFn } from 'node:path';
3
+ const __dirname = __dirnameFn(__fileURLToPath(import.meta.url));
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { findOwnPackageRoot } from './own-deps.js';
7
+ /**
8
+ * Extra roots to search, registered once per run by the install layer.
9
+ *
10
+ * Module state rather than a parameter threaded through fifteen call sites: a
11
+ * profile directory is a property of the *run*, not of any one check, and every
12
+ * check that resolves a binary would otherwise have to be handed a value it has
13
+ * no opinion about. `registerToolPaths` is called before the first check starts
14
+ * and never during one, so nothing observes it changing underneath.
15
+ */
16
+ let profileRoots = [];
17
+ /**
18
+ * Point tool resolution at the profile directories fetched for this run.
19
+ *
20
+ * Called by the install layer once the cache is known. Passing an empty list —
21
+ * or never calling it at all — leaves resolution exactly as it was before
22
+ * profiles existed, which is what keeps a run that needs no fetching identical
23
+ * to a run from before there was anything to fetch.
24
+ */
25
+ export function registerToolPaths(dirs) {
26
+ profileRoots = [...dirs];
27
+ }
28
+ /** Drop every registered profile root. For tests, and for a second run in-process. */
29
+ export function clearToolPaths() {
30
+ profileRoots = [];
31
+ }
32
+ /** The root of the installed pr-checkmate package — where our own tooling lives. */
33
+ export function ownPackageRoot() {
34
+ return findOwnPackageRoot() ?? path.resolve(__dirname, '../../..');
35
+ }
36
+ /**
37
+ * Whether a package is physically present in our own dependency tree.
38
+ *
39
+ * Checked by walking `node_modules` upwards rather than by `require.resolve`,
40
+ * because a package that restricts its `exports` map resolves for neither its
41
+ * main entry nor its `package.json` while being perfectly well installed —
42
+ * `cspell` is one. The question here is only "is it there", and the directory
43
+ * answers that without an opinion about what it chooses to export.
44
+ *
45
+ * Walking up matters as much as the check itself: installed as a dependency, our
46
+ * own packages are hoisted to the client's `node_modules`, one level above ours.
47
+ */
48
+ export function packagePresent(pkgName, from = ownPackageRoot()) {
49
+ let dir = from;
50
+ while (dir !== path.dirname(dir)) {
51
+ if (fs.existsSync(path.join(dir, 'node_modules', pkgName, 'package.json')))
52
+ return true;
53
+ dir = path.dirname(dir);
54
+ }
55
+ return false;
56
+ }
57
+ /** One resolution attempt against a single set of search paths. */
58
+ function tryResolve(pkgName, binRelPath, paths) {
59
+ const resolveOpts = paths ? { paths } : undefined;
60
+ // 1. Direct subpath — the fast path for packages that export their bin.
61
+ try {
62
+ return require.resolve(`${pkgName}/${binRelPath}`, resolveOpts);
63
+ }
64
+ catch { }
65
+ // 2. Via package.json — for packages that export `./package.json` but not the
66
+ // bin subpath (eslint).
67
+ try {
68
+ const pkgJsonPath = require.resolve(`${pkgName}/package.json`, resolveOpts);
69
+ return path.join(path.dirname(pkgJsonPath), binRelPath);
70
+ }
71
+ catch { }
72
+ // 3. Walk up from the main entry, matching the package name — for packages
73
+ // that export neither (cspell).
74
+ try {
75
+ let dir = path.dirname(require.resolve(pkgName, resolveOpts));
76
+ while (dir !== path.dirname(dir)) {
77
+ const pkgJsonPath = path.join(dir, 'package.json');
78
+ if (fs.existsSync(pkgJsonPath)) {
79
+ try {
80
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
81
+ if (pkg.name === pkgName)
82
+ return path.join(dir, binRelPath);
83
+ }
84
+ catch { }
85
+ }
86
+ dir = path.dirname(dir);
87
+ }
88
+ }
89
+ catch { }
90
+ return null;
91
+ }
92
+ /**
93
+ * The roots to try, in order, and what finding a tool in each one means.
94
+ *
95
+ * The order is the policy, and it is deliberate:
96
+ *
97
+ * 1. **The client's own copy**, when a caller asked for it. A repository pinned
98
+ * to ESLint 8 with a legacy `.eslintrc` must keep working, and only its copy
99
+ * can do that.
100
+ * 2. **A fetched profile**, for tooling that does not ship inside the package.
101
+ * 3. **Our bundle** — module-relative, exactly as resolution worked before
102
+ * profiles existed.
103
+ *
104
+ * Branch 3 is passed `undefined` rather than our package root on purpose: that is
105
+ * literally the previous behaviour, so a run with nothing registered resolves
106
+ * every tool along the identical path it always did.
107
+ */
108
+ function candidates(optPaths) {
109
+ const list = [];
110
+ if (optPaths && optPaths.length > 0)
111
+ list.push({ paths: optPaths, source: 'client' });
112
+ for (const root of profileRoots)
113
+ list.push({ paths: [root], source: 'profile' });
114
+ list.push({ source: 'bundled' });
115
+ return list;
116
+ }
117
+ /**
118
+ * Resolve a tool's binary and say which copy answered.
119
+ *
120
+ * Use this over {@link resolvePackageBin} when the answer is worth logging — the
121
+ * source is the difference between "the client's ESLint 8 ran" and "ours did",
122
+ * and that is the first thing anyone asks when a lint result looks wrong.
123
+ *
124
+ * @param pkgName Package whose binary to resolve (e.g. `eslint`).
125
+ * @param binRelPath Bin path relative to the package root (e.g. `bin/eslint.js`).
126
+ * @param options Resolution options.
127
+ * @param options.paths Roots to prefer ahead of everything else. Use
128
+ * `[process.cwd()]` to prefer the consumer project's copy.
129
+ */
130
+ export function resolveTool(pkgName, binRelPath, options) {
131
+ for (const candidate of candidates(options?.paths)) {
132
+ const bin = tryResolve(pkgName, binRelPath, candidate.paths);
133
+ if (bin)
134
+ return { bin, source: candidate.source, root: candidate.paths?.[0] };
135
+ }
136
+ return null;
137
+ }
138
+ /**
139
+ * Resolves a binary path for a bundled package, bypassing exports map restrictions.
140
+ *
141
+ * Throws when no copy can be found anywhere, which is the honest outcome: a check
142
+ * that cannot find its tool has nothing to report, and the install layer turns
143
+ * that into a skip with a reason rather than letting it surface as a stack trace.
144
+ *
145
+ * @param pkgName - The package whose binary to resolve (e.g. `eslint`).
146
+ * @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
147
+ * @param options - Resolution options.
148
+ * @param options.paths - Directories to resolve from, preferred over everything
149
+ * else. Use `[process.cwd()]` to prefer the consumer project's copy.
150
+ */
151
+ export function resolvePackageBin(pkgName, binRelPath, options) {
152
+ const resolved = resolveTool(pkgName, binRelPath, options);
153
+ if (resolved)
154
+ return resolved.bin;
155
+ throw new Error(`Cannot resolve binary "${binRelPath}" for package "${pkgName}"`);
156
+ }
@@ -0,0 +1,33 @@
1
+ export type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip';
2
+ export interface CheckResult {
3
+ name: string;
4
+ status: CheckStatus;
5
+ details?: string;
6
+ }
7
+ /**
8
+ *
9
+ */
10
+ export declare class ResultCollector {
11
+ private results;
12
+ /**
13
+ *
14
+ */
15
+ register(name: string, status: CheckStatus, details?: string): void;
16
+ /**
17
+ *
18
+ */
19
+ getResults(): CheckResult[];
20
+ /**
21
+ *
22
+ */
23
+ clear(): void;
24
+ /**
25
+ *
26
+ */
27
+ getSummary(): {
28
+ passed: number;
29
+ warned: number;
30
+ failed: number;
31
+ skipped: number;
32
+ };
33
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ *
3
+ */
4
+ export class ResultCollector {
5
+ constructor() {
6
+ this.results = [];
7
+ }
8
+ /**
9
+ *
10
+ */
11
+ register(name, status, details) {
12
+ const idx = this.results.findIndex(r => r.name === name);
13
+ const entry = { name, status, ...(details && { details }) };
14
+ if (idx >= 0) {
15
+ this.results[idx] = entry;
16
+ }
17
+ else {
18
+ this.results.push(entry);
19
+ }
20
+ }
21
+ /**
22
+ *
23
+ */
24
+ getResults() {
25
+ return [...this.results];
26
+ }
27
+ /**
28
+ *
29
+ */
30
+ clear() {
31
+ this.results = [];
32
+ }
33
+ /**
34
+ *
35
+ */
36
+ getSummary() {
37
+ return {
38
+ passed: this.results.filter(r => r.status === 'pass').length,
39
+ warned: this.results.filter(r => r.status === 'warn').length,
40
+ failed: this.results.filter(r => r.status === 'fail').length,
41
+ skipped: this.results.filter(r => r.status === 'skip').length,
42
+ };
43
+ }
44
+ }
@@ -0,0 +1,19 @@
1
+ /** True when the upgrade crosses a major version, i.e. behaviour may change. */
2
+ export declare function isMajorUpgrade(latest: string, current: string): boolean;
3
+ /**
4
+ * Best-effort check for a newer published version. Returns the notice lines when
5
+ * an update exists, or `null` (up-to-date, offline, timed out, or opted out).
6
+ * Non-blocking and fully silent on any failure: short timeout, swallowed errors,
7
+ * opt-out via `PR_CHECKMATE_NO_UPDATE_CHECK`. Returns lines instead of logging so
8
+ * the caller can print them at the very end — after the summary — where they're
9
+ * noticeable. Deliberately called ONLY from the CLI (not `runChecks`) so
10
+ * programmatic consumers (e.g. a wrapping SDK) never trigger a network call.
11
+ *
12
+ * The notice is framed like the run summary so it is noticed, but it is now a
13
+ * one-liner: upgrading is just installing. It used to demand `npx pr-checkmate
14
+ * init` afterwards, because `init` copied the release's new defaults into the
15
+ * client's config — a step nobody could safely skip, for a file that should
16
+ * never have held those defaults in the first place. They are merged in when the
17
+ * config loads, so the second step no longer exists.
18
+ */
19
+ export declare function getUpdateNotice(timeoutMs?: number): Promise<string[] | null>;
@@ -0,0 +1,108 @@
1
+ // Imported from the module rather than the `../config` barrel on purpose:
2
+ // `config/index.ts` imports `../utils`, so going through the barrel would make
3
+ // utils ⇄ config circular. `constants.ts` itself pulls in nothing from utils.
4
+ import { DOCS_URL } from '../config/constants.js';
5
+ import { packageName, packageVersion } from './package-version.js';
6
+ // Same widths as the run summary in `reporters.ts`, so the two boxes line up
7
+ // when both are printed at the end of a run.
8
+ const NOTICE_BORDER = '═'.repeat(63);
9
+ const NOTICE_RULE = '─'.repeat(63);
10
+ /** Compare dotted versions; true when `latest` is strictly greater than `current`. */
11
+ function isNewer(latest, current) {
12
+ const a = latest.split('.').map(n => parseInt(n, 10) || 0);
13
+ const b = current.split('.').map(n => parseInt(n, 10) || 0);
14
+ for (let i = 0; i < 3; i++) {
15
+ if ((a[i] ?? 0) !== (b[i] ?? 0))
16
+ return (a[i] ?? 0) > (b[i] ?? 0);
17
+ }
18
+ return false;
19
+ }
20
+ /** True when the upgrade crosses a major version, i.e. behaviour may change. */
21
+ export function isMajorUpgrade(latest, current) {
22
+ return (parseInt(latest.split('.')[0], 10) || 0) > (parseInt(current.split('.')[0], 10) || 0);
23
+ }
24
+ /**
25
+ * Extra lines for a major upgrade. A patch bump is a routine "install it"; a
26
+ * major one can change what fails a build, and finding that out from a red PR is
27
+ * the wrong way to learn it. Says what to read and how to stage the rollout,
28
+ * because the answer to "everything went red" should arrive before it happens.
29
+ */
30
+ function majorNotice(pkgName) {
31
+ return [
32
+ NOTICE_RULE,
33
+ ' ⚠️ MAJOR VERSION — behaviour changes, read before upgrading',
34
+ '',
35
+ ' Findings a check rates "error" now BLOCK the run. Previously they were',
36
+ ' reported and the run still passed, so a repo with existing findings will',
37
+ ' start failing its PRs.',
38
+ '',
39
+ ' To stage it, make everything advisory first and promote checks back one',
40
+ ' at a time — in pr-checkmate.json:',
41
+ ' "severityDefaults": { "failOn": "warn" }',
42
+ ' "severity": { "Security Scan": "error" }',
43
+ '',
44
+ ` Full notes: https://www.npmjs.com/package/${pkgName}?activeTab=versions`,
45
+ ];
46
+ }
47
+ /**
48
+ * Best-effort check for a newer published version. Returns the notice lines when
49
+ * an update exists, or `null` (up-to-date, offline, timed out, or opted out).
50
+ * Non-blocking and fully silent on any failure: short timeout, swallowed errors,
51
+ * opt-out via `PR_CHECKMATE_NO_UPDATE_CHECK`. Returns lines instead of logging so
52
+ * the caller can print them at the very end — after the summary — where they're
53
+ * noticeable. Deliberately called ONLY from the CLI (not `runChecks`) so
54
+ * programmatic consumers (e.g. a wrapping SDK) never trigger a network call.
55
+ *
56
+ * The notice is framed like the run summary so it is noticed, but it is now a
57
+ * one-liner: upgrading is just installing. It used to demand `npx pr-checkmate
58
+ * init` afterwards, because `init` copied the release's new defaults into the
59
+ * client's config — a step nobody could safely skip, for a file that should
60
+ * never have held those defaults in the first place. They are merged in when the
61
+ * config loads, so the second step no longer exists.
62
+ */
63
+ export async function getUpdateNotice(timeoutMs = 2500) {
64
+ if (process.env.PR_CHECKMATE_NO_UPDATE_CHECK)
65
+ return null;
66
+ try {
67
+ // The *running* copy's identity, not the project's declared dependency. A
68
+ // stale global install shadows the local one on `PATH`, and it is the stale
69
+ // copy that must own the notice it prints.
70
+ const pkg = { name: packageName(), version: packageVersion() };
71
+ const controller = new AbortController();
72
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
73
+ let latest;
74
+ try {
75
+ const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg.name)}/latest`, {
76
+ signal: controller.signal,
77
+ });
78
+ if (res.ok)
79
+ latest = (await res.json()).version;
80
+ }
81
+ finally {
82
+ clearTimeout(timer);
83
+ }
84
+ if (latest && isNewer(latest, pkg.version)) {
85
+ const major = isMajorUpgrade(latest, pkg.version);
86
+ return [
87
+ NOTICE_BORDER,
88
+ ` ⬆️ UPDATE AVAILABLE — ${pkg.name} ${pkg.version} → ${latest}`,
89
+ ...(major ? majorNotice(pkg.name) : []),
90
+ NOTICE_RULE,
91
+ ` Install: npm install ${pkg.name}@latest`,
92
+ '',
93
+ ' That is the whole upgrade. New checks and new defaults apply on their',
94
+ ' own — your pr-checkmate.json holds only what you changed, and nothing',
95
+ ' in it needs topping up.',
96
+ NOTICE_RULE,
97
+ ` 📚 Docs: ${DOCS_URL}`,
98
+ ` 📦 Release: https://www.npmjs.com/package/${pkg.name}`,
99
+ NOTICE_BORDER,
100
+ ];
101
+ }
102
+ return null;
103
+ }
104
+ catch {
105
+ // Best-effort only — never let an update check slow or break a run.
106
+ return null;
107
+ }
108
+ }
@@ -11,7 +11,7 @@
11
11
  "execa": "9.6.1",
12
12
  "yaml": "2.9.1",
13
13
  "inquirer": "14.2.2",
14
- "gitleaks-secret-scanner-fixed": "3.0.3"
14
+ "gitleaks-secret-scanner-fixed": "3.0.4"
15
15
  }
16
16
  },
17
17
  "node_modules/@inquirer/ansi": {
@@ -572,9 +572,9 @@
572
572
  }
573
573
  },
574
574
  "node_modules/gitleaks-secret-scanner-fixed": {
575
- "version": "3.0.3",
576
- "resolved": "https://registry.npmjs.org/gitleaks-secret-scanner-fixed/-/gitleaks-secret-scanner-fixed-3.0.3.tgz",
577
- "integrity": "sha512-j7cKwmZYmkeixE1danLi3GBq40PGMDGsxeXxBYQ35kyKa+ThcVeedt2lzTIoH4inFZsH4fG5vUqiwchXxalDnw==",
575
+ "version": "3.0.4",
576
+ "resolved": "https://registry.npmjs.org/gitleaks-secret-scanner-fixed/-/gitleaks-secret-scanner-fixed-3.0.4.tgz",
577
+ "integrity": "sha512-UxNQSWIcSIux7M6Ue/pcEDz+E/UQVicvpoa/a5TCq6PD32B3sSNe3WY7wIpiyddpJIUImF2gFkQbWM+wZQrKFQ==",
578
578
  "hasInstallScript": true,
579
579
  "license": "MIT",
580
580
  "dependencies": {
@@ -5,7 +5,7 @@
5
5
  "execa": "9.6.1",
6
6
  "yaml": "2.9.1",
7
7
  "inquirer": "14.2.2",
8
- "gitleaks-secret-scanner-fixed": "3.0.3"
8
+ "gitleaks-secret-scanner-fixed": "3.0.4"
9
9
  },
10
10
  "private": true
11
11
  }