pr-checkmate 3.0.3 → 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 (380) 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/install-manifests/cpp/package-lock.json +4 -4
  335. package/install-manifests/cpp/package.json +1 -1
  336. package/package.json +16 -14
  337. package/dist/core/checks/languages/lint.d.ts +0 -2
  338. package/dist/core/index.d.ts +0 -4
  339. package/dist/core/registry.js +0 -112
  340. package/dist/index.d.ts +0 -12
  341. package/dist/utils/index.d.ts +0 -15
  342. /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
  343. /package/dist/{config → cjs/config}/constants.d.ts +0 -0
  344. /package/dist/{config → cjs/config}/constants.js +0 -0
  345. /package/dist/{config → cjs/config}/pr-checkmate-workflow-docker.yml +0 -0
  346. /package/dist/{config → cjs/config}/pr-checkmate-workflow.yml +0 -0
  347. /package/dist/{core → cjs/core}/checks/languages/ruff-shared.d.ts +0 -0
  348. /package/dist/{core → cjs/core}/checks/languages/ruff-shared.js +0 -0
  349. /package/dist/{core → cjs/core}/commands.d.ts +0 -0
  350. /package/dist/{core → cjs/core}/commands.js +0 -0
  351. /package/dist/{core → cjs/core}/install/cache.d.ts +0 -0
  352. /package/dist/{core → cjs/core}/install/lock.d.ts +0 -0
  353. /package/dist/{core → cjs/core}/install/merge.d.ts +0 -0
  354. /package/dist/{core → cjs/core}/install/merge.js +0 -0
  355. /package/dist/{core → cjs/core}/install/profiles.js +0 -0
  356. /package/dist/{core → cjs/core}/types.js +0 -0
  357. /package/dist/{init.d.ts → cjs/init.d.ts} +0 -0
  358. /package/dist/{interfaces → cjs/interfaces}/index.js +0 -0
  359. /package/dist/{scripts → cjs/scripts}/copy-configs.d.ts +0 -0
  360. /package/dist/{scripts → cjs/scripts}/generate-install-manifests.d.ts +0 -0
  361. /package/dist/{scripts → cjs/scripts}/publish-github.d.ts +0 -0
  362. /package/dist/{utils → cjs/utils}/ci.d.ts +0 -0
  363. /package/dist/{utils → cjs/utils}/ci.js +0 -0
  364. /package/dist/{utils → cjs/utils}/detect-language.d.ts +0 -0
  365. /package/dist/{utils → cjs/utils}/direct-deps.d.ts +0 -0
  366. /package/dist/{utils → cjs/utils}/direct-deps.js +0 -0
  367. /package/dist/{utils → cjs/utils}/execa.d.ts +0 -0
  368. /package/dist/{utils → cjs/utils}/git.d.ts +0 -0
  369. /package/dist/{utils → cjs/utils}/glob.d.ts +0 -0
  370. /package/dist/{utils → cjs/utils}/glob.js +0 -0
  371. /package/dist/{utils → cjs/utils}/http.d.ts +0 -0
  372. /package/dist/{utils → cjs/utils}/logger.d.ts +0 -0
  373. /package/dist/{utils → cjs/utils}/logger.js +0 -0
  374. /package/dist/{utils → cjs/utils}/package-version.d.ts +0 -0
  375. /package/dist/{utils → cjs/utils}/pool.d.ts +0 -0
  376. /package/dist/{utils → cjs/utils}/pool.js +0 -0
  377. /package/dist/{utils → cjs/utils}/resolve-bin.d.ts +0 -0
  378. /package/dist/{utils → cjs/utils}/result-collector.d.ts +0 -0
  379. /package/dist/{utils → cjs/utils}/result-collector.js +0 -0
  380. /package/dist/{utils → cjs/utils}/update-notifier.d.ts +0 -0
@@ -0,0 +1,9 @@
1
+ import { Check } from '../../types.js';
2
+ /**
3
+ * Lints changed Python files with Ruff, bundled as a self-contained WASM module
4
+ * (`@astral-sh/ruff-wasm-nodejs`) so it runs on a bare Node image with no Python
5
+ * or pip install. Informational by design — reports issues without failing the
6
+ * build, matching how formatting checks roll out; promote to blocking per repo
7
+ * once teams have adopted it. Uses Ruff's default rule set (pyflakes + pycodestyle).
8
+ */
9
+ export declare const pythonLintCheck: Check;
@@ -0,0 +1,55 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { logger } from '../../../utils/index.js';
4
+ import { resolveTargetFiles } from '../../targets.js';
5
+ import { pass, warn, skip } from '../../types.js';
6
+ import { PY_GLOBS, createRuffWorkspace } from './ruff-shared.js';
7
+ /**
8
+ * Lints changed Python files with Ruff, bundled as a self-contained WASM module
9
+ * (`@astral-sh/ruff-wasm-nodejs`) so it runs on a bare Node image with no Python
10
+ * or pip install. Informational by design — reports issues without failing the
11
+ * build, matching how formatting checks roll out; promote to blocking per repo
12
+ * once teams have adopted it. Uses Ruff's default rule set (pyflakes + pycodestyle).
13
+ */
14
+ export const pythonLintCheck = {
15
+ name: 'Ruff Lint',
16
+ phase: 'informational',
17
+ applies(ctx) {
18
+ return (ctx.config.python?.enabled !== false &&
19
+ ctx.config.python?.ruff?.lint !== false &&
20
+ ctx.languages.includes('python'));
21
+ },
22
+ async run(ctx) {
23
+ const targets = await resolveTargetFiles(ctx, PY_GLOBS);
24
+ if (targets === null)
25
+ return skip('git unavailable');
26
+ if (targets.length === 0)
27
+ return pass('no Python files changed');
28
+ const workspace = createRuffWorkspace();
29
+ let totalIssues = 0;
30
+ let filesWithIssues = 0;
31
+ for (const rel of targets) {
32
+ let content;
33
+ try {
34
+ content = fs.readFileSync(path.join(ctx.cwd, rel), 'utf-8');
35
+ }
36
+ catch {
37
+ continue; // renamed/removed between diff and read — skip
38
+ }
39
+ const diagnostics = workspace.check(content);
40
+ if (diagnostics.length === 0)
41
+ continue;
42
+ filesWithIssues += 1;
43
+ totalIssues += diagnostics.length;
44
+ logger.warn(`[Ruff Lint]: ⚠️ ${rel}: ${diagnostics.length} issue(s)`);
45
+ diagnostics
46
+ .slice(0, 5)
47
+ .forEach((d) => logger.warn(` ${rel}:${d.start_location.row} ${d.code ?? '?'} ${d.message}`));
48
+ if (diagnostics.length > 5)
49
+ logger.warn(` ... and ${diagnostics.length - 5} more`);
50
+ }
51
+ if (totalIssues === 0)
52
+ return pass();
53
+ return warn(`${totalIssues} issue(s) in ${filesWithIssues} file(s)`);
54
+ },
55
+ };
@@ -0,0 +1,14 @@
1
+ import { Check } from '../../types.js';
2
+ /**
3
+ * Type-checks changed Python files — the Python analogue of `tsc --noEmit`.
4
+ *
5
+ * Two checkers, and the order is the policy. **mypy first**, because a repository
6
+ * that installed mypy configured it too (`mypy.ini`, `[tool.mypy]`), and its
7
+ * settled opinion about its own code beats ours. **Our bundled pyright
8
+ * otherwise**, which is what stopped `⏭️ mypy/pyright not installed` from being
9
+ * the answer on every runner: pyright is a Node bundle carrying its own typeshed,
10
+ * so it needs neither Python nor pip. Force either with `python.typeChecker`.
11
+ *
12
+ * Informational by design, like Ruff lint, so teams can adopt gradually.
13
+ */
14
+ export declare const pythonTypecheckCheck: Check;
@@ -0,0 +1,184 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { logger, resolvePackageBin } from '../../../utils/index.js';
4
+ import { resolveTargetFiles } from '../../targets.js';
5
+ import { pass, skip, warn } from '../../types.js';
6
+ import { logSample } from '../findings.js';
7
+ import { notInstalled } from '../tool-install.js';
8
+ import { runTool } from './external-runner.js';
9
+ import { PY_GLOBS } from './ruff-shared.js';
10
+ /** How many diagnostics reach the log before the rest are counted instead. */
11
+ const MAX_LOGGED = 10;
12
+ /** The check's display name — the log prefix, and the row in the report. */
13
+ const NAME = 'Python Types';
14
+ /**
15
+ * Diagnostics that mean pyright could not see the repository's dependencies.
16
+ *
17
+ * Their presence is a verdict about the *setup*, not about the code, and the
18
+ * first attempt at this got it backwards: it dropped these two rules and
19
+ * reported everything else. That removes the cause and keeps the consequences,
20
+ * which is worse than either extreme — on a real client repository (ticket 076)
21
+ * it produced fifteen confident "type errors" of which nine were one cascade:
22
+ *
23
+ * ```python
24
+ * @click.group()
25
+ * def main() -> None: ...
26
+ *
27
+ * @main.command("list-jobs") # nine of these
28
+ * def list_jobs() -> None: ...
29
+ * ```
30
+ *
31
+ * With `click` absent, pyright sees `main` as a plain `FunctionType` and every
32
+ * `@main.command(...)` becomes an error. Pyright is answering correctly; the
33
+ * question is wrong. The same shape follows from typer, flask, celery and pytest
34
+ * fixtures — most Python projects, in any CI job that does not install first.
35
+ *
36
+ * So an unresolved import means we cannot type-check at all, and the honest
37
+ * answer is a skip that says so. That is exactly what the TypeScript check does
38
+ * with a missing `node_modules`, in the same words.
39
+ */
40
+ const UNRESOLVED_IMPORT_RULES = new Set(['reportMissingImports', 'reportMissingModuleSource']);
41
+ /** How many unresolved module names the skip message names before stopping. */
42
+ const NAMED_IMPORTS = 3;
43
+ /** The module a `reportMissingImports` diagnostic is about, for the skip message. */
44
+ function unresolvedModule(message) {
45
+ return /"([^"]+)"/.exec(message)?.[1] ?? null;
46
+ }
47
+ /** Whether the repository configures pyright itself. */
48
+ function hasOwnPyrightConfig(cwd) {
49
+ if (fs.existsSync(path.join(cwd, 'pyrightconfig.json')))
50
+ return true;
51
+ try {
52
+ return fs.readFileSync(path.join(cwd, 'pyproject.toml'), 'utf-8').includes('[tool.pyright]');
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ /** Where our copy of pyright lives — bundled, or in a fetched profile. */
59
+ function resolvePyright() {
60
+ try {
61
+ return resolvePackageBin('pyright', 'index.js');
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ /** Read mypy's text output: one diagnostic per line, with its own final count. */
68
+ function reportMypy(output) {
69
+ const lines = output.split('\n').filter(line => /\berror\b|\bwarning\b/i.test(line));
70
+ if (lines.length === 0)
71
+ return pass();
72
+ // "Found 3 errors in 1 file (checked 12 source files)" — mypy's own count says
73
+ // more than a tally of lines that merely contained the word.
74
+ const summary = lines.find(line => /found\s+\d+\s+error/i.test(line))?.trim();
75
+ logSample(NAME, 'type issues (mypy):', lines);
76
+ return warn(summary ?? `${lines.length} type issue(s)`);
77
+ }
78
+ /**
79
+ * Type-check with our own pyright, and report only what the client can act on.
80
+ *
81
+ * Pyright is a Node bundle, so it runs through `process.execPath` rather than as
82
+ * a binary on the path — the same reason clang-format does.
83
+ */
84
+ function reportPyright(ctx, stdout) {
85
+ let report;
86
+ try {
87
+ report = JSON.parse(stdout);
88
+ }
89
+ catch {
90
+ // Pyright exits non-zero for a bad invocation too, and calling that a type
91
+ // error would put a finding in the report that is really our own bug.
92
+ logger.warn(`[${NAME}]: ⚠️ pyright produced no readable report`);
93
+ return skip('pyright produced no readable report');
94
+ }
95
+ const diagnostics = (report.generalDiagnostics ?? []).filter(diagnostic => diagnostic.severity !== 'information');
96
+ // Nothing downstream of an unresolved import can be trusted, so this is
97
+ // checked before anything is reported — and skipped rather than filtered.
98
+ //
99
+ // Not applied to a repository that configures pyright itself: having written
100
+ // `pyrightconfig.json` (or a `[tool.pyright]` section) is having an opinion
101
+ // about import resolution — a `venvPath`, or these rules downgraded on
102
+ // purpose — and overriding it with a skip would ignore the one client who
103
+ // said what they wanted.
104
+ const unresolved = diagnostics.filter(diagnostic => UNRESOLVED_IMPORT_RULES.has(diagnostic.rule ?? ''));
105
+ if (unresolved.length > 0 && !hasOwnPyrightConfig(ctx.cwd)) {
106
+ const modules = [
107
+ ...new Set(unresolved
108
+ .map(diagnostic => unresolvedModule(diagnostic.message))
109
+ .filter((name) => Boolean(name))),
110
+ ];
111
+ const named = modules.slice(0, NAMED_IMPORTS).join(', ');
112
+ const rest = modules.length > NAMED_IMPORTS ? ` and ${modules.length - NAMED_IMPORTS} more` : '';
113
+ logger.warn(`[${NAME}]: ⚠️ ${unresolved.length} import(s) could not be resolved — not type-checking`);
114
+ return skip(`project dependencies not installed (${named || `${unresolved.length} import(s)`}${rest}) ` +
115
+ '— run `pip install` before typecheck');
116
+ }
117
+ if (diagnostics.length === 0) {
118
+ logger.info(`[${NAME}]: ✅ No type errors (pyright)`);
119
+ return pass();
120
+ }
121
+ const errors = diagnostics.filter(diagnostic => diagnostic.severity === 'error').length;
122
+ const summary = `${errors} error(s), ${diagnostics.length - errors} warning(s)`;
123
+ logSample(NAME, `type issues (pyright): ${summary}`, diagnostics.slice(0, MAX_LOGGED).map(diagnostic => {
124
+ const rel = path.relative(ctx.cwd, diagnostic.file) || diagnostic.file;
125
+ // Pyright counts lines from zero; every other tool in the report counts
126
+ // from one, and a line number that is off by one is worse than none.
127
+ const line = (diagnostic.range?.start?.line ?? 0) + 1;
128
+ return `${rel}:${line} ${diagnostic.severity}: ${diagnostic.message.split('\n')[0]}`;
129
+ }));
130
+ return warn(summary);
131
+ }
132
+ /**
133
+ * Type-checks changed Python files — the Python analogue of `tsc --noEmit`.
134
+ *
135
+ * Two checkers, and the order is the policy. **mypy first**, because a repository
136
+ * that installed mypy configured it too (`mypy.ini`, `[tool.mypy]`), and its
137
+ * settled opinion about its own code beats ours. **Our bundled pyright
138
+ * otherwise**, which is what stopped `⏭️ mypy/pyright not installed` from being
139
+ * the answer on every runner: pyright is a Node bundle carrying its own typeshed,
140
+ * so it needs neither Python nor pip. Force either with `python.typeChecker`.
141
+ *
142
+ * Informational by design, like Ruff lint, so teams can adopt gradually.
143
+ */
144
+ export const pythonTypecheckCheck = {
145
+ name: NAME,
146
+ phase: 'informational',
147
+ applies(ctx) {
148
+ return (ctx.config.python?.enabled !== false &&
149
+ ctx.config.python?.typecheck !== false &&
150
+ ctx.languages.includes('python'));
151
+ },
152
+ async run(ctx) {
153
+ const targets = await resolveTargetFiles(ctx, PY_GLOBS);
154
+ if (targets === null)
155
+ return skip('git unavailable');
156
+ if (targets.length === 0)
157
+ return pass('no Python files changed');
158
+ const forced = ctx.config.python?.typeChecker;
159
+ if (forced !== 'pyright') {
160
+ const mypy = await runTool(ctx, 'mypy', targets);
161
+ if (!mypy.missing) {
162
+ if (mypy.exitCode === 0) {
163
+ logger.info(`[${NAME}]: ✅ No type errors (mypy)`);
164
+ return pass();
165
+ }
166
+ return reportMypy([mypy.stdout, mypy.stderr].filter(Boolean).join('\n'));
167
+ }
168
+ // Asking for mypy by name and not having it is a configuration error the
169
+ // client meant to make visible; falling back to pyright would hide it.
170
+ if (forced === 'mypy')
171
+ return notInstalled('mypy', 'mypy');
172
+ }
173
+ const entry = resolvePyright();
174
+ if (!entry)
175
+ return notInstalled('pyright', 'pyright');
176
+ const result = await runTool(ctx, process.execPath, [entry, '--outputjson', ...targets]);
177
+ // The binary here is the Node running this process, so `missing` is not a
178
+ // reachable state — it is a case of the type, folded in rather than asserted
179
+ // away.
180
+ if (result.missing)
181
+ return notInstalled('pyright', 'pyright');
182
+ return reportPyright(ctx, result.stdout);
183
+ },
184
+ };
@@ -0,0 +1,10 @@
1
+ type RuffModule = typeof import('@astral-sh/ruff-wasm-nodejs');
2
+ type RuffWorkspace = InstanceType<RuffModule['Workspace']>;
3
+ export declare const PY_GLOBS: string[];
4
+ /**
5
+ * Instantiate a Ruff WASM workspace. Shared by the Ruff lint and format checks so
6
+ * their setup stays identical, and kept as a function (not a module-level
7
+ * singleton) so the WASM module loads only when a check runs.
8
+ */
9
+ export declare function createRuffWorkspace(): RuffWorkspace;
10
+ export {};
@@ -0,0 +1,35 @@
1
+ import { createRequire as __createRequire } from 'node:module';
2
+ const require = __createRequire(import.meta.url);
3
+ export const PY_GLOBS = ['*.py'];
4
+ /**
5
+ * The rules we lint Python with — pinned here rather than left to Ruff's defaults.
6
+ *
7
+ * `E4`/`E7`/`E9` (import placement, statement style, syntax) plus `F` (pyflakes:
8
+ * undefined names, unused imports, unreachable code) — the set Ruff itself
9
+ * shipped as its default through 0.15.
10
+ *
11
+ * Written down because leaving it implicit made our verdict change under us.
12
+ * Ruff 0.16 added the isort rules (`I`) to its defaults, and a routine dependency
13
+ * bump turned that into a 5- to 48-fold increase in findings across seventeen
14
+ * Python repositories — every one of them `I001`, "import block is un-sorted".
15
+ * Two repositories went from a clean report to a warning on code nobody had
16
+ * touched. Import order is a matter of taste, and a check that fires on every
17
+ * file in a repository is how people learn to ignore the whole report.
18
+ *
19
+ * Adding a rule to this list is a decision with a measurement behind it, which
20
+ * is the point: it is ours to make, not our dependency's to make for us.
21
+ */
22
+ const SELECTED_RULES = ['E4', 'E7', 'E9', 'F'];
23
+ /**
24
+ * Instantiate a Ruff WASM workspace. Shared by the Ruff lint and format checks so
25
+ * their setup stays identical, and kept as a function (not a module-level
26
+ * singleton) so the WASM module loads only when a check runs.
27
+ */
28
+ export function createRuffWorkspace() {
29
+ const { Workspace, PositionEncoding } = require('@astral-sh/ruff-wasm-nodejs');
30
+ const settings = {
31
+ ...Workspace.defaultSettings(),
32
+ lint: { select: SELECTED_RULES },
33
+ };
34
+ return new Workspace(settings, PositionEncoding.Utf16);
35
+ }
@@ -0,0 +1,2 @@
1
+ import { Check } from '../../types.js';
2
+ export declare const typecheckCheck: Check;
@@ -0,0 +1,61 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { execa } from '../../../utils/execa.js';
4
+ import { logger, resolvePackageBin } from '../../../utils/index.js';
5
+ import { clientToolPaths } from '../../install/reuse.js';
6
+ import { pass, fail, warn, skip } from '../../types.js';
7
+ /**
8
+ * Prefer the consumer project's own TypeScript so its tsconfig is compiled by the
9
+ * version it was written for; fall back to the compiler bundled with pr-checkmate.
10
+ */
11
+ function resolveTsc(ctx) {
12
+ // `clientOwnsConfig` unconditionally: this check does not apply without a
13
+ // `tsconfig.json` in the repository, so the compiler their config was written
14
+ // for is always theirs. `install.reuseLocal: "off"` still overrides, for a
15
+ // client who wants our pinned compiler for reproducibility.
16
+ return resolvePackageBin('typescript', 'bin/tsc', {
17
+ paths: clientToolPaths('typescript', ctx, { clientOwnsConfig: true }),
18
+ });
19
+ }
20
+ export const typecheckCheck = {
21
+ name: 'TypeScript',
22
+ phase: 'blocking',
23
+ weight: 'heavy',
24
+ applies(ctx) {
25
+ if (ctx.config.typecheck?.enabled === false)
26
+ return false;
27
+ if (!ctx.languages.includes('typescript'))
28
+ return false;
29
+ return fs.existsSync(path.join(ctx.cwd, 'tsconfig.json'));
30
+ },
31
+ async run(ctx) {
32
+ // tsc needs the project's installed type declarations — everything listed in
33
+ // tsconfig's `types`, plus every imported @types package — to resolve. When the
34
+ // project's dependencies aren't installed (e.g. a CI step that runs pr-checkmate
35
+ // via npx without a prior `npm ci`), tsc emits a wall of cryptic TS2688
36
+ // "cannot find type definition file" errors that look like code problems but are
37
+ // really a setup gap. Skip with an actionable message instead of failing the PR.
38
+ if (!fs.existsSync(path.join(ctx.cwd, 'node_modules'))) {
39
+ return skip('project dependencies not installed (no node_modules) — run `npm ci` before typecheck');
40
+ }
41
+ const tscBin = resolveTsc(ctx);
42
+ const result = await execa(process.execPath, [tscBin, '--noEmit'], {
43
+ cwd: ctx.cwd,
44
+ reject: false,
45
+ });
46
+ if (result.exitCode === 0)
47
+ return pass();
48
+ const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
49
+ const errorCount = (output.match(/error TS\d+/g) ?? []).length;
50
+ if (output)
51
+ logger.warn(output);
52
+ // A non-zero exit with no diagnostic in it is not a type error — tsc was
53
+ // killed (OOM on a large project), crashed, or never started. Reporting that
54
+ // as `0 type error(s)` blocked PRs with a message naming nothing to fix.
55
+ if (errorCount === 0) {
56
+ logger.warn(`[TypeScript]: ⚠️ tsc exited ${result.exitCode ?? 'abnormally'} without reporting a type error — treating as a tooling failure, not a type error`);
57
+ return warn(`tsc failed to run (exit ${result.exitCode ?? 'killed'})`);
58
+ }
59
+ return fail(`${errorCount} type error(s)`);
60
+ },
61
+ };
@@ -0,0 +1,2 @@
1
+ import { Check } from '../../types.js';
2
+ export declare const commitlintCheck: Check;
@@ -0,0 +1,102 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { hasLocalConfig } from '../../../config/index.js';
5
+ import { execa } from '../../../utils/execa.js';
6
+ import { logger, resolveGitRef, resolvePackageBin } from '../../../utils/index.js';
7
+ import { pass, skip, warn } from '../../types.js';
8
+ const LOCAL_CONFIG_FILES = [
9
+ 'commitlint.config.cjs',
10
+ 'commitlint.config.js',
11
+ 'commitlint.config.mjs',
12
+ 'commitlint.config.ts',
13
+ '.commitlintrc',
14
+ '.commitlintrc.json',
15
+ '.commitlintrc.yaml',
16
+ '.commitlintrc.yml',
17
+ '.commitlintrc.js',
18
+ '.commitlintrc.cjs',
19
+ ];
20
+ const DEFAULT_TYPES = [
21
+ 'feat',
22
+ 'fix',
23
+ 'docs',
24
+ 'chore',
25
+ 'ci',
26
+ 'refactor',
27
+ 'perf',
28
+ 'style',
29
+ 'revert',
30
+ 'test',
31
+ 'build',
32
+ ];
33
+ const DEFAULT_IGNORES = ['^Release\\b', '^chore\\(release\\):'];
34
+ function buildTempConfig(types, ignores) {
35
+ // Emit a CJS module so `ignores` can hold functions — commitlint requires
36
+ // predicate functions there, which a JSON config cannot express.
37
+ // Resolve config-conventional via Node module resolution — robust to hoisting.
38
+ const configConventional = require.resolve('@commitlint/config-conventional');
39
+ const content = `const patterns = ${JSON.stringify(ignores)}.map((p) => new RegExp(p, 'i'));
40
+ module.exports = {
41
+ extends: [${JSON.stringify(configConventional)}],
42
+ rules: { 'type-enum': [2, 'always', ${JSON.stringify(types)}] },
43
+ ignores: [(commit) => patterns.some((re) => re.test(commit))],
44
+ };
45
+ `;
46
+ const tmpFile = path.join(os.tmpdir(), `.commitlint-${process.pid}.cjs`);
47
+ fs.writeFileSync(tmpFile, content);
48
+ return tmpFile;
49
+ }
50
+ export const commitlintCheck = {
51
+ name: 'Commitlint',
52
+ phase: 'informational',
53
+ applies(ctx) {
54
+ return ctx.config.commitlint?.enabled !== false;
55
+ },
56
+ async run(ctx) {
57
+ // This check needs a commit to lint. Without a repository `--last` finds
58
+ // none, commitlint prints nothing and exits 0, and we reported `pass` — a
59
+ // verdict on a commit message that does not exist. Ticket 072: a check that
60
+ // examined nothing must not read as a check that found nothing.
61
+ if (!(await resolveGitRef(ctx.cwd, 'HEAD')))
62
+ return skip('git unavailable');
63
+ const commitlintBin = resolvePackageBin('@commitlint/cli', 'cli.js');
64
+ const hasLocal = hasLocalConfig(LOCAL_CONFIG_FILES, ctx.cwd);
65
+ let tempConfigFile = null;
66
+ // With no diff range (a full-repo review, or `--full`) the check still has a
67
+ // meaningful subject: the newest commit message. `HEAD~1` cannot be assumed to
68
+ // exist, though — it is absent on a repository's first commit and in a shallow
69
+ // clone (`actions/checkout` fetches depth 1 by default). Passing it blind made
70
+ // commitlint die with an unhandled "ambiguous argument 'HEAD~1..HEAD'" stack
71
+ // trace in the client's log, and the check then reported "commit message
72
+ // violations found" — a verdict about code quality for what was a crash.
73
+ // `--last` lints exactly the newest commit and needs no ancestor.
74
+ const range = ctx.baseSha
75
+ ? ['--from', ctx.baseSha, '--to', ctx.headSha ?? 'HEAD']
76
+ : (await resolveGitRef(ctx.cwd, 'HEAD~1'))
77
+ ? ['--from', 'HEAD~1', '--to', ctx.headSha ?? 'HEAD']
78
+ : ['--last'];
79
+ const args = [...range, '--verbose'];
80
+ try {
81
+ if (hasLocal) {
82
+ logger.info('[Commitlint]: Using local config');
83
+ }
84
+ else {
85
+ const types = ctx.config.commitlint?.types ?? DEFAULT_TYPES;
86
+ const ignores = ctx.config.commitlint?.ignores ?? DEFAULT_IGNORES;
87
+ tempConfigFile = buildTempConfig(types, ignores);
88
+ args.push('--config', tempConfigFile);
89
+ }
90
+ const result = await execa(process.execPath, [commitlintBin, ...args], {
91
+ cwd: ctx.cwd,
92
+ reject: false,
93
+ stdio: 'inherit',
94
+ });
95
+ return result.exitCode === 0 ? pass() : warn('commit message violations found');
96
+ }
97
+ finally {
98
+ if (tempConfigFile && fs.existsSync(tempConfigFile))
99
+ fs.unlinkSync(tempConfigFile);
100
+ }
101
+ },
102
+ };
@@ -0,0 +1,2 @@
1
+ import { Check } from '../../types.js';
2
+ export declare const prBodyCheck: Check;
@@ -0,0 +1,43 @@
1
+ import fs from 'node:fs';
2
+ import { logger } from '../../../utils/index.js';
3
+ import { pass, warn, skip } from '../../types.js';
4
+ // Matches "Closes #123", "Fixes #45", "Resolves #7" or JIRA-style "PROJ-456".
5
+ const TICKET_PATTERN = /(?:closes?|fixes?|resolves?)\s+#\d+|[A-Z][A-Z0-9]+-\d+/i;
6
+ export const prBodyCheck = {
7
+ name: 'PR Body',
8
+ phase: 'informational',
9
+ applies(ctx) {
10
+ if (ctx.config.prBody?.enabled === false)
11
+ return false;
12
+ const eventPath = process.env.GITHUB_EVENT_PATH;
13
+ return Boolean(eventPath && fs.existsSync(eventPath));
14
+ },
15
+ async run(ctx) {
16
+ const minLength = ctx.config.prBody?.minLength ?? 20;
17
+ const requireTicket = ctx.config.prBody?.requireTicket ?? true;
18
+ let event;
19
+ try {
20
+ event = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, 'utf-8'));
21
+ }
22
+ catch (err) {
23
+ logger.warn(`[PR Body]: ⚠️ Could not read GitHub event\n${err}`);
24
+ return skip('event unreadable');
25
+ }
26
+ const pr = event.pull_request;
27
+ if (!pr)
28
+ return skip('no PR data');
29
+ const trimmed = (pr.body ?? '').trim();
30
+ const issues = [];
31
+ if (trimmed.length < minLength) {
32
+ issues.push(`description too short (${trimmed.length}/${minLength} chars min)`);
33
+ }
34
+ if (requireTicket && trimmed && !TICKET_PATTERN.test(trimmed)) {
35
+ issues.push('no ticket reference (e.g. "Closes #123" or "PROJ-456")');
36
+ }
37
+ if (issues.length > 0) {
38
+ issues.forEach(i => logger.warn(`[PR Body]: ⚠️ ${i}`));
39
+ return warn(issues.join('; '));
40
+ }
41
+ return pass();
42
+ },
43
+ };
@@ -0,0 +1,2 @@
1
+ import { Check } from '../../types.js';
2
+ export declare const prSizeCheck: Check;
@@ -0,0 +1,42 @@
1
+ import { execa } from '../../../utils/execa.js';
2
+ import { logger } from '../../../utils/index.js';
3
+ import { pass, warn, skip } from '../../types.js';
4
+ const DEFAULT_MAX_FILES = 50;
5
+ const DEFAULT_MAX_LINES = 1000;
6
+ export const prSizeCheck = {
7
+ name: 'PR Size',
8
+ phase: 'informational',
9
+ requiresDiff: true,
10
+ applies(ctx) {
11
+ return ctx.config.prSize?.enabled !== false;
12
+ },
13
+ async run(ctx) {
14
+ const maxFiles = ctx.config.prSize?.maxFiles ?? DEFAULT_MAX_FILES;
15
+ const maxLines = ctx.config.prSize?.maxLines ?? DEFAULT_MAX_LINES;
16
+ try {
17
+ const { stdout } = await execa('git', ['diff', '--shortstat', ctx.baseSha, ctx.headSha ?? 'HEAD'], {
18
+ cwd: ctx.cwd,
19
+ });
20
+ // "5 files changed, 123 insertions(+), 45 deletions(-)"
21
+ const fileCount = parseInt(stdout.match(/(\d+) files? changed/)?.[1] ?? '0', 10);
22
+ const insertions = parseInt(stdout.match(/(\d+) insertion/)?.[1] ?? '0', 10);
23
+ const deletions = parseInt(stdout.match(/(\d+) deletion/)?.[1] ?? '0', 10);
24
+ const lines = insertions + deletions;
25
+ logger.info(`[PR Size]: ${fileCount} files changed, ${lines} lines`);
26
+ const issues = [];
27
+ if (fileCount > maxFiles)
28
+ issues.push(`${fileCount} files (recommended < ${maxFiles})`);
29
+ if (lines > maxLines)
30
+ issues.push(`${lines} lines (recommended < ${maxLines})`);
31
+ if (issues.length > 0) {
32
+ issues.forEach(i => logger.warn(`[PR Size]: ⚠️ Large PR: ${i}`));
33
+ return warn(issues.join(', '));
34
+ }
35
+ return pass();
36
+ }
37
+ catch (err) {
38
+ logger.warn(`[PR Size]: ⚠️ Could not measure PR size\n${err}`);
39
+ return skip('diff unavailable');
40
+ }
41
+ },
42
+ };
@@ -0,0 +1,2 @@
1
+ import { Check } from '../../types.js';
2
+ export declare const prTitleLintCheck: Check;
@@ -0,0 +1,31 @@
1
+ import fs from 'node:fs';
2
+ import { logger } from '../../../utils/index.js';
3
+ import { pass, warn, skip } from '../../types.js';
4
+ const CONVENTIONAL_PREFIX = /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?!?: .+/;
5
+ export const prTitleLintCheck = {
6
+ name: 'PR Title',
7
+ phase: 'informational',
8
+ applies() {
9
+ const eventPath = process.env.GITHUB_EVENT_PATH;
10
+ return Boolean(eventPath && fs.existsSync(eventPath));
11
+ },
12
+ async run() {
13
+ let event;
14
+ try {
15
+ event = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, 'utf-8'));
16
+ }
17
+ catch (err) {
18
+ logger.warn(`[PR Title]: ⚠️ Could not read GitHub event\n${err}`);
19
+ return skip('event unreadable');
20
+ }
21
+ const pr = event.pull_request;
22
+ if (!pr?.title)
23
+ return skip('no PR title');
24
+ const title = pr.title;
25
+ if (!CONVENTIONAL_PREFIX.test(title)) {
26
+ logger.warn(`[PR Title]: ⚠️ Not Conventional Commits: "${title}"`);
27
+ return warn('title does not follow Conventional Commits');
28
+ }
29
+ return pass();
30
+ },
31
+ };
@@ -0,0 +1,8 @@
1
+ import { Check } from '../../types.js';
2
+ /**
3
+ * Flags tracked files whose paths differ only by case (e.g. `Foo.ts` vs
4
+ * `foo.ts`). Such pairs coexist on Linux (case-sensitive) but collide on macOS/
5
+ * Windows and in many Docker layers, silently breaking checkouts and builds.
6
+ * Whole-repo scan (not delta), scoped to `sourcePath` and honouring `ignoreDirs`.
7
+ */
8
+ export declare const caseCollisionCheck: Check;