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,27 @@
1
+ /**
2
+ * CLI vocabulary, kept out of `cli.ts` so it can be imported without side
3
+ * effects: that module is an executable entry point — it parses `process.argv`
4
+ * and calls `process.exit` at import time, so anything importing it to read
5
+ * these tables would run the CLI instead.
6
+ *
7
+ * Separating them is what lets `commands.test.ts` assert the invariant that
8
+ * matters here: every command must resolve to a check that actually exists.
9
+ * A command pointing at a name no longer in the registry does not error — the
10
+ * `only` filter simply matches nothing, every check is filtered out, and the run
11
+ * reports success having verified nothing at all.
12
+ */
13
+ /** Maps short CLI command names to their registry check names. */
14
+ export declare const COMMAND_TO_CHECK: Record<string, string>;
15
+ /**
16
+ * Commands that run the whole pipeline (or no pipeline at all) and take no siblings.
17
+ *
18
+ * The three install commands are here rather than in {@link COMMAND_TO_CHECK}
19
+ * because they run no checks at all: they manage the tooling the checks need.
20
+ * `doctor` in particular is the answer to "why did my typecheck not run" once
21
+ * tooling is fetched on demand — a question that must have a command behind it
22
+ * and not a reading of our source.
23
+ */
24
+ export declare const TOOLING_COMMANDS: readonly string[];
25
+ export declare const STANDALONE_COMMANDS: readonly string[];
26
+ /** Flags accepted anywhere on the command line, with what each one means. */
27
+ export declare const FLAGS: Record<string, string>;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * CLI vocabulary, kept out of `cli.ts` so it can be imported without side
3
+ * effects: that module is an executable entry point — it parses `process.argv`
4
+ * and calls `process.exit` at import time, so anything importing it to read
5
+ * these tables would run the CLI instead.
6
+ *
7
+ * Separating them is what lets `commands.test.ts` assert the invariant that
8
+ * matters here: every command must resolve to a check that actually exists.
9
+ * A command pointing at a name no longer in the registry does not error — the
10
+ * `only` filter simply matches nothing, every check is filtered out, and the run
11
+ * reports success having verified nothing at all.
12
+ */
13
+ /** Maps short CLI command names to their registry check names. */
14
+ export const COMMAND_TO_CHECK = {
15
+ // Every check that can fail a run is reachable on its own, so "why does this
16
+ // block me" is answered by running that one check instead of the whole suite.
17
+ 'merge-conflict': 'Merge Conflict',
18
+ lint: 'ESLint',
19
+ deps: 'Dependencies',
20
+ dependencies: 'Dependencies',
21
+ 'npm-audit': 'NPM Audit',
22
+ prettier: 'Prettier',
23
+ spellcheck: 'Spellcheck',
24
+ security: 'Security Scan',
25
+ circular: 'Circular Deps',
26
+ license: 'License Check',
27
+ 'pr-size': 'PR Size',
28
+ 'pr-title': 'PR Title',
29
+ outdated: 'Outdated Deps',
30
+ markdown: 'Markdown',
31
+ 'yaml-lint': 'YAML Lint',
32
+ symlinks: 'Broken Symlinks',
33
+ 'package-size': 'Package Size',
34
+ shellcheck: 'ShellCheck',
35
+ typecheck: 'TypeScript',
36
+ 'diff-smell': 'Diff Smells',
37
+ 'diff-security': 'Diff Security',
38
+ 'workflow-security': 'Workflow Security',
39
+ 'custom-rules': 'Custom Rules',
40
+ 'banned-imports': 'Banned Imports',
41
+ 'license-header': 'License Header',
42
+ 'config-validation': 'Config Validation',
43
+ 'dockerfile-security': 'Dockerfile Security',
44
+ 'case-collision': 'Case Collision',
45
+ 'vuln-scan': 'Vuln Scan',
46
+ 'leftover-debug': 'Leftover Debug',
47
+ 'lockfile-drift': 'Lockfile Drift',
48
+ 'large-files': 'Large Files',
49
+ 'todo-fixme': 'TODO/FIXME',
50
+ 'missing-tests': 'Missing Tests',
51
+ coverage: 'Coverage',
52
+ 'migration-safety': 'Migration Safety',
53
+ 'sensitive-files': 'Sensitive Files',
54
+ 'pr-body': 'PR Body',
55
+ duplicate: 'Duplicate Code',
56
+ commitlint: 'Commitlint',
57
+ 'cpp-format': 'C++ Format',
58
+ 'python-lint': 'Ruff Lint',
59
+ 'python-format': 'Ruff Format',
60
+ 'python-typecheck': 'Python Types',
61
+ 'go-lint': 'Go Vet',
62
+ 'go-format': 'Go Format',
63
+ 'rust-lint': 'Clippy',
64
+ 'rust-format': 'Rustfmt',
65
+ 'csharp-format': 'C# Format',
66
+ 'ruby-lint': 'RuboCop',
67
+ 'php-format': 'PHP CS Fixer',
68
+ };
69
+ /**
70
+ * Commands that run the whole pipeline (or no pipeline at all) and take no siblings.
71
+ *
72
+ * The three install commands are here rather than in {@link COMMAND_TO_CHECK}
73
+ * because they run no checks at all: they manage the tooling the checks need.
74
+ * `doctor` in particular is the answer to "why did my typecheck not run" once
75
+ * tooling is fetched on demand — a question that must have a command behind it
76
+ * and not a reading of our source.
77
+ */
78
+ export const TOOLING_COMMANDS = ['install', 'doctor', 'cache-prune'];
79
+ export const STANDALONE_COMMANDS = [
80
+ 'init',
81
+ 'all',
82
+ 'precommit',
83
+ ...TOOLING_COMMANDS,
84
+ ];
85
+ /** Flags accepted anywhere on the command line, with what each one means. */
86
+ export const FLAGS = {
87
+ '--full': 'review every tracked file instead of the diff (the default outside CI)',
88
+ '--all': 'with "install": fetch every profile, not only the ones this repository needs',
89
+ };
@@ -0,0 +1,62 @@
1
+ import type { CheckContext, RunOptions } from './types.js';
2
+ /**
3
+ * What a run should look at, before any git call is made. Separated from
4
+ * {@link resolveDiffRange} so the precedence rules are a pure function of the
5
+ * options and the environment — the part worth pinning with tests.
6
+ *
7
+ * - `full` — every tracked file. Checks fall back to `git ls-files` when the range
8
+ * is undefined, so this is expressed by resolving to no SHAs at all.
9
+ * - `staged` — index vs HEAD (pre-commit).
10
+ * - `explicit` — SHAs the caller supplied.
11
+ * - `github-event` — base SHA from the pull_request event payload.
12
+ * - `ref` — diff against a named ref (a PR's destination branch, or `HEAD^`).
13
+ */
14
+ type RangePlan = {
15
+ kind: 'full';
16
+ reason: string;
17
+ } | {
18
+ kind: 'staged';
19
+ } | {
20
+ kind: 'explicit';
21
+ baseSha?: string;
22
+ headSha?: string;
23
+ } | {
24
+ kind: 'github-event';
25
+ } | {
26
+ kind: 'branch';
27
+ } | {
28
+ kind: 'ref';
29
+ ref: string;
30
+ reason: string;
31
+ };
32
+ /**
33
+ * Decide what to look at. Order matters and is the contract:
34
+ *
35
+ * 1. `full` wins over everything — an explicit "check all of it" must not be
36
+ * quietly narrowed by a CI variable that happens to be set.
37
+ * 2. `staged`, then caller-supplied SHAs.
38
+ * 3. The CI platform's PR context (GitHub event payload, Bitbucket destination
39
+ * branch) — a gate exists to judge the diff.
40
+ * 4. A CI build with no PR context still diffs `HEAD^`: it is a push/branch build,
41
+ * and delta is why CI runs are fast.
42
+ * 5. Anything else is a human at a terminal, working on a branch → review what the
43
+ * branch changed, i.e. everything since it diverged from the default branch.
44
+ * That is the same set of changes a pull request would show, which is what
45
+ * someone running the tool before opening one is asking about.
46
+ *
47
+ * `HEAD^` was tried here once and was wrong for a different reason: it judged
48
+ * only the last commit, so a `debugger` committed earlier on the branch passed.
49
+ * The merge base has neither problem — it covers every commit on the branch —
50
+ * and on the default branch itself, where there is nothing to diverge from,
51
+ * {@link resolveDiffRange} falls back to a full scan.
52
+ *
53
+ * @param opts Run options as passed to `runChecks`.
54
+ * @param env Environment to read CI markers from. Defaults to the current process.
55
+ */
56
+ export declare function planDiffRange(opts: RunOptions, env?: NodeJS.ProcessEnv): RangePlan;
57
+ /**
58
+ * Assemble the shared CheckContext once per run. Language detection is skipped
59
+ * when the caller supplies `languages` (e.g. PRValidator passes its ProjectType).
60
+ */
61
+ export declare function buildContext(opts?: RunOptions): Promise<CheckContext>;
62
+ export {};
@@ -0,0 +1,241 @@
1
+ import fs from 'node:fs';
2
+ import { loadProjectConfig } from '../config/loader.js';
3
+ import { detectLanguageUsage } from '../utils/detect-language.js';
4
+ import { execa } from '../utils/execa.js';
5
+ import { isCiEnvironment, logger, resolveGitRef } from '../utils/index.js';
6
+ /**
7
+ * Decide what to look at. Order matters and is the contract:
8
+ *
9
+ * 1. `full` wins over everything — an explicit "check all of it" must not be
10
+ * quietly narrowed by a CI variable that happens to be set.
11
+ * 2. `staged`, then caller-supplied SHAs.
12
+ * 3. The CI platform's PR context (GitHub event payload, Bitbucket destination
13
+ * branch) — a gate exists to judge the diff.
14
+ * 4. A CI build with no PR context still diffs `HEAD^`: it is a push/branch build,
15
+ * and delta is why CI runs are fast.
16
+ * 5. Anything else is a human at a terminal, working on a branch → review what the
17
+ * branch changed, i.e. everything since it diverged from the default branch.
18
+ * That is the same set of changes a pull request would show, which is what
19
+ * someone running the tool before opening one is asking about.
20
+ *
21
+ * `HEAD^` was tried here once and was wrong for a different reason: it judged
22
+ * only the last commit, so a `debugger` committed earlier on the branch passed.
23
+ * The merge base has neither problem — it covers every commit on the branch —
24
+ * and on the default branch itself, where there is nothing to diverge from,
25
+ * {@link resolveDiffRange} falls back to a full scan.
26
+ *
27
+ * @param opts Run options as passed to `runChecks`.
28
+ * @param env Environment to read CI markers from. Defaults to the current process.
29
+ */
30
+ export function planDiffRange(opts, env = process.env) {
31
+ if (opts.full)
32
+ return { kind: 'full', reason: 'requested' };
33
+ if (opts.staged)
34
+ return { kind: 'staged' };
35
+ if (opts.baseSha || opts.headSha) {
36
+ return { kind: 'explicit', baseSha: opts.baseSha, headSha: opts.headSha };
37
+ }
38
+ if (env.GITHUB_EVENT_NAME === 'pull_request' && env.GITHUB_EVENT_PATH) {
39
+ return { kind: 'github-event' };
40
+ }
41
+ if (env.BITBUCKET_PR_DESTINATION_BRANCH) {
42
+ return {
43
+ kind: 'ref',
44
+ ref: `origin/${env.BITBUCKET_PR_DESTINATION_BRANCH}`,
45
+ reason: 'PR build',
46
+ };
47
+ }
48
+ if (isCiEnvironment(env))
49
+ return { kind: 'ref', ref: 'HEAD^', reason: 'CI build, no PR context' };
50
+ return { kind: 'branch' };
51
+ }
52
+ /** A full scan the caller or the environment asked for, not one we fell back to. */
53
+ const intended = (reason) => ({ kind: 'full', reason, degraded: false });
54
+ /**
55
+ * A full scan we ended up with because a diff range could not be built. The
56
+ * distinction matters: the delta-only checks drop out either way, but here that
57
+ * is a symptom (shallow clone, missing base) rather than the intent — and it is
58
+ * the case worth telling the client about, because it silently removes most of
59
+ * the security surface.
60
+ */
61
+ const degraded = (reason) => ({ kind: 'full', reason, degraded: true });
62
+ /**
63
+ * Carry out a {@link RangePlan}. Every path that cannot produce a usable base
64
+ * commit returns no SHAs, which the checks read as "scan everything" — degrading
65
+ * to a full scan is always safer than diffing against a ref that isn't there and
66
+ * silently reviewing nothing.
67
+ *
68
+ * @returns The resolved range, plus the scope that produced it.
69
+ */
70
+ async function resolveDiffRange(cwd, opts) {
71
+ const plan = planDiffRange(opts, process.env);
72
+ if (plan.kind === 'full')
73
+ return { scope: intended(plan.reason) };
74
+ // Pre-commit mode: diff HEAD against the current index. `git write-tree`
75
+ // materialises the staged index as a real tree object, so every check that
76
+ // diffs baseSha..headSha sees exactly the staged changes — no per-check code.
77
+ if (plan.kind === 'staged') {
78
+ try {
79
+ const head = (await execa('git', ['rev-parse', 'HEAD'], { cwd })).stdout.trim();
80
+ const tree = (await execa('git', ['write-tree'], { cwd })).stdout.trim();
81
+ return { baseSha: head, headSha: tree, scope: { kind: 'staged', degraded: false } };
82
+ }
83
+ catch {
84
+ return { scope: degraded('no staged range') };
85
+ }
86
+ }
87
+ if (plan.kind === 'explicit') {
88
+ return {
89
+ baseSha: plan.baseSha,
90
+ headSha: plan.headSha,
91
+ scope: { kind: 'delta', reason: 'explicit', degraded: false },
92
+ };
93
+ }
94
+ let headSha;
95
+ try {
96
+ const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd });
97
+ headSha = stdout.trim();
98
+ }
99
+ catch {
100
+ return { scope: degraded('no HEAD') };
101
+ }
102
+ // GitHub Actions: the PR event payload carries the base branch SHA. Read it
103
+ // directly so delta works without relying on any client-set variable
104
+ // (GITHUB_EVENT_* are injected by the runner).
105
+ if (plan.kind === 'github-event') {
106
+ try {
107
+ const event = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, 'utf-8'));
108
+ const eventBase = event?.pull_request?.base?.sha;
109
+ // Only use it if the commit is actually present in this clone; otherwise
110
+ // fall through so a shallow clone degrades to a full scan, not 0 files.
111
+ const baseSha = eventBase ? await resolveGitRef(cwd, eventBase) : undefined;
112
+ if (baseSha) {
113
+ return { baseSha, headSha, scope: { kind: 'delta', reason: 'PR event', degraded: false } };
114
+ }
115
+ }
116
+ catch {
117
+ // Malformed/unreadable event — fall through to a full scan below.
118
+ }
119
+ return { headSha, scope: degraded('PR base unavailable') };
120
+ }
121
+ if (plan.kind === 'branch')
122
+ return resolveBranchRange(cwd, headSha);
123
+ const baseSha = await resolveGitRef(cwd, plan.ref);
124
+ if (!baseSha)
125
+ return { headSha, scope: degraded(`${plan.ref} unresolvable`) };
126
+ return {
127
+ baseSha,
128
+ headSha,
129
+ scope: { kind: 'delta', reason: `${plan.ref}, ${plan.reason}`, degraded: false },
130
+ };
131
+ }
132
+ /** Branches a repository's trunk is normally called, most likely first. */
133
+ const DEFAULT_BRANCHES = ['main', 'master', 'develop'];
134
+ /**
135
+ * Where this branch diverged from the trunk, or nothing when it has not.
136
+ *
137
+ * Prefers `origin/HEAD` — the remote's own answer to "what is the default
138
+ * branch" — and falls back to the usual names, local or remote. Returns
139
+ * `undefined` when no trunk is found or when HEAD is already on it, which the
140
+ * caller turns into a full scan: on the trunk there is no branch to review.
141
+ */
142
+ async function findMergeBase(cwd, headSha) {
143
+ const candidates = ['origin/HEAD'];
144
+ for (const name of DEFAULT_BRANCHES)
145
+ candidates.push(`origin/${name}`, name);
146
+ for (const candidate of candidates) {
147
+ const ref = await resolveGitRef(cwd, candidate);
148
+ // A candidate that resolves to HEAD is the branch we are on, not a base.
149
+ if (!ref || ref === headSha)
150
+ continue;
151
+ const { stdout } = await execa('git', ['merge-base', headSha, ref], { cwd, reject: false });
152
+ const base = stdout.trim();
153
+ // An unrelated history has no merge base, and a base equal to HEAD means the
154
+ // branch is behind rather than ahead — neither describes local changes.
155
+ if (base && base !== headSha)
156
+ return base;
157
+ }
158
+ return undefined;
159
+ }
160
+ /**
161
+ * Local run on a branch: review what the branch changed.
162
+ *
163
+ * On the trunk itself there is nothing to diff against, so this degrades to a
164
+ * full scan — deliberately not marked `degraded`, because it is the expected
165
+ * answer there rather than a configuration problem worth warning about.
166
+ */
167
+ async function resolveBranchRange(cwd, headSha) {
168
+ const baseSha = await findMergeBase(cwd, headSha);
169
+ if (!baseSha)
170
+ return { headSha, scope: intended('no branch base — on the default branch?') };
171
+ return {
172
+ baseSha,
173
+ headSha,
174
+ scope: { kind: 'delta', reason: 'branch changes', degraded: false },
175
+ };
176
+ }
177
+ /**
178
+ * Assemble the shared CheckContext once per run. Language detection is skipped
179
+ * when the caller supplies `languages` (e.g. PRValidator passes its ProjectType).
180
+ */
181
+ export async function buildContext(opts = {}) {
182
+ const cwd = opts.cwd ?? process.cwd();
183
+ const config = opts.config ?? loadProjectConfig();
184
+ // Detection reads the client's `ignoreDirs` from the config already loaded here,
185
+ // rather than calling getIgnoredDirs() — that one resolves against process.cwd(),
186
+ // which is not necessarily the `cwd` under review.
187
+ applyLogConfig(config);
188
+ // Detected as usage (language + file count), not as a bare list: the same scan
189
+ // answers two different questions, and the install layer needs the counts. A
190
+ // `Cargo.toml` beside zero `.rs` files is enough to run Rust checks and not
191
+ // enough to download a toolchain — see `detectLanguageUsage`.
192
+ const usage = opts.languages
193
+ ? opts.languages.map(lang => ({ lang, files: 1, marker: true }))
194
+ : await detectLanguageUsage(cwd, config.ignoreDirs, config.detect);
195
+ const languages = usage.map(u => u.lang);
196
+ const { baseSha, headSha, scope } = await resolveDiffRange(cwd, opts);
197
+ // `scope` is logged because it decides what the whole run looks at, and getting
198
+ // it wrong is invisible in the results: a run that reviewed one commit and one
199
+ // that reviewed the repository both just print passes.
200
+ logger.info(`[buildContext]: cwd=${cwd} languages=[${languages.join(', ') || 'none'}] write=${opts.write ?? false} scope=${describeScope(scope)}`);
201
+ return {
202
+ cwd,
203
+ languages,
204
+ usage,
205
+ config,
206
+ write: opts.write ?? false,
207
+ baseSha,
208
+ headSha,
209
+ scope,
210
+ cache: new Map(),
211
+ };
212
+ }
213
+ /**
214
+ * Human-readable one-liner for a scope, e.g. `full (PR base unavailable)`.
215
+ *
216
+ * Deliberately not exported: `buildContext` is the only caller, and the scope it
217
+ * describes already travels on the context for anyone who wants to phrase it
218
+ * differently. An `export` here would only be API surface Dead Code reports.
219
+ */
220
+ function describeScope(scope) {
221
+ return scope.reason ? `${scope.kind} (${scope.reason})` : scope.kind;
222
+ }
223
+ /**
224
+ * Apply the client's `log` block, with environment variables taking precedence.
225
+ *
226
+ * Env wins because the config file is committed and the environment is not: a
227
+ * one-off `PR_CHECKMATE_LOG_LEVEL=debug` to diagnose a CI run should not require
228
+ * editing — and later reverting — a tracked file.
229
+ */
230
+ function applyLogConfig(config) {
231
+ const log = config.log ?? {};
232
+ const level = process.env.PR_CHECKMATE_LOG_LEVEL ?? log.level;
233
+ const format = process.env.PR_CHECKMATE_LOG_FORMAT ?? log.format;
234
+ logger.configure({
235
+ ...(level ? { level } : {}),
236
+ ...(format ? { format } : {}),
237
+ ...(log.color ? { color: log.color } : {}),
238
+ ...(log.timestamps !== undefined ? { timestamps: log.timestamps } : {}),
239
+ ...(log.stderrLevels ? { stderrLevels: log.stderrLevels } : {}),
240
+ });
241
+ }
@@ -0,0 +1,4 @@
1
+ export { runChecks } from './run-checks.js';
2
+ export { buildContext } from './context.js';
3
+ export { REGISTRY } from './registry.js';
4
+ export * from './types.js';
@@ -0,0 +1,4 @@
1
+ export { runChecks } from './run-checks.js';
2
+ export { buildContext } from './context.js';
3
+ export { REGISTRY } from './registry.js';
4
+ export * from './types.js';
@@ -0,0 +1,58 @@
1
+ /** Where fetched tooling lives, and why it ended up there. */
2
+ export interface CacheLocation {
3
+ dir: string;
4
+ /** `false` when the configured location was unusable and this is a fallback. */
5
+ preferred: boolean;
6
+ reason?: string;
7
+ }
8
+ /**
9
+ * Expand a leading `~`.
10
+ *
11
+ * Config files are written by hand, `~/.cache/pr-checkmate` is what a person
12
+ * writes, and nothing in Node expands it — the directory would be created
13
+ * literally, as a folder named `~`, in whatever the working directory happened
14
+ * to be.
15
+ */
16
+ export declare function expandHome(dir: string, home?: string): string;
17
+ /**
18
+ * Resolve the cache directory, falling back rather than failing.
19
+ *
20
+ * Every candidate below is a real environment: containers without `HOME`, CI
21
+ * images with a read-only home, and runners where only the temp directory is
22
+ * writable. A tool that refuses to work in any of them is a tool that fails on
23
+ * CI for reasons the client cannot see.
24
+ *
25
+ * @param version The pr-checkmate version, kept in the path so two projects on
26
+ * different versions never share fetched tooling.
27
+ * @param configured `install.cacheDir`, if the client set one.
28
+ */
29
+ export declare function resolveCacheDir(version: string, configured?: string, env?: NodeJS.ProcessEnv): CacheLocation | null;
30
+ /**
31
+ * Where fetched tooling is installed — one tree for the whole run, not one per profile.
32
+ *
33
+ * A directory per profile left npm nothing to deduplicate, and the profiles
34
+ * overlap heavily: `commitlint` and `js` share 30 MB, so two trees fetched both
35
+ * copies. Measured on a JavaScript repository, per-profile directories came to
36
+ * 267 MB where a single merged tree costs 213 (ticket 087).
37
+ *
38
+ * The name is deliberately not derived from which profiles are inside. What is
39
+ * installed is recorded in the directory's own stamp and checked as a superset,
40
+ * so a cache warmed by `install --all` serves every narrower run — a path keyed
41
+ * by the profile set would miss on the first one.
42
+ */
43
+ export declare function toolingDir(cacheDir: string): string;
44
+ /**
45
+ * Where a single profile's tooling used to be installed.
46
+ *
47
+ * Kept only so `cache prune` can still recognise and remove the directories left
48
+ * by versions that used the per-profile layout.
49
+ */
50
+ export declare function profileDir(cacheDir: string, profile: string): string;
51
+ /**
52
+ * Profile directories left behind by other versions of pr-checkmate.
53
+ *
54
+ * Nothing removes these automatically: an upgrade must not delete tooling a
55
+ * concurrently running older version is in the middle of using. `cache prune`
56
+ * is the deliberate, separate act.
57
+ */
58
+ export declare function stalePaths(version: string, configured?: string): string[];
@@ -0,0 +1,142 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { logger } from '../../utils/logger.js';
5
+ /**
6
+ * Expand a leading `~`.
7
+ *
8
+ * Config files are written by hand, `~/.cache/pr-checkmate` is what a person
9
+ * writes, and nothing in Node expands it — the directory would be created
10
+ * literally, as a folder named `~`, in whatever the working directory happened
11
+ * to be.
12
+ */
13
+ export function expandHome(dir, home = os.homedir()) {
14
+ if (dir === '~')
15
+ return home;
16
+ return dir.startsWith('~/') ? path.join(home, dir.slice(2)) : dir;
17
+ }
18
+ /** A directory we can actually write to. */
19
+ function writable(dir) {
20
+ try {
21
+ fs.mkdirSync(dir, { recursive: true });
22
+ // Existence is not permission, and finding that out here rather than at write
23
+ // time is the difference between a clear message and a stack trace halfway
24
+ // through fetching.
25
+ fs.accessSync(dir, fs.constants.W_OK);
26
+ return true;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * A directory that already exists and can at least be read.
34
+ *
35
+ * Only ever asked of a cache path the client named explicitly, and only after
36
+ * {@link writable} has said no. That combination has exactly one meaning: a cache
37
+ * baked into a container image, read-only on purpose, holding tooling somebody
38
+ * warmed at build time. Reading it needs no write permission, and refusing it
39
+ * because a *future* fetch could not write there discards the tooling that is
40
+ * sitting right there — which is how our own image lost `Python Types` under
41
+ * `--user` (ticket 083).
42
+ *
43
+ * A fetch into such a directory still fails, in `ensureProfile`, with the path it
44
+ * could not create. That is the clear message the write check was for; it is just
45
+ * no longer paid for by every read.
46
+ */
47
+ function readable(dir) {
48
+ try {
49
+ fs.accessSync(dir, fs.constants.R_OK | fs.constants.X_OK);
50
+ return fs.statSync(dir).isDirectory();
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ /**
57
+ * Resolve the cache directory, falling back rather than failing.
58
+ *
59
+ * Every candidate below is a real environment: containers without `HOME`, CI
60
+ * images with a read-only home, and runners where only the temp directory is
61
+ * writable. A tool that refuses to work in any of them is a tool that fails on
62
+ * CI for reasons the client cannot see.
63
+ *
64
+ * @param version The pr-checkmate version, kept in the path so two projects on
65
+ * different versions never share fetched tooling.
66
+ * @param configured `install.cacheDir`, if the client set one.
67
+ */
68
+ export function resolveCacheDir(version, configured, env = process.env) {
69
+ const explicit = env.PR_CHECKMATE_CACHE_DIR ?? configured;
70
+ const candidates = [];
71
+ if (explicit)
72
+ candidates.push({ dir: expandHome(explicit), reason: 'configured' });
73
+ // `homedir()` on a container without HOME returns something like `/` — hence
74
+ // the write check rather than a bare existence test.
75
+ candidates.push({ dir: path.join(os.homedir(), '.cache', 'pr-checkmate'), reason: 'home cache' });
76
+ candidates.push({ dir: path.join(os.tmpdir(), 'pr-checkmate-cache'), reason: 'temp directory' });
77
+ for (const [index, candidate] of candidates.entries()) {
78
+ const dir = path.join(candidate.dir, version);
79
+ if (writable(dir)) {
80
+ if (index > 0) {
81
+ logger.warn(`[install]: ⚠️ cache directory "${candidates[0].dir}" is not writable — using ${candidate.reason} (${dir}). Fetched tooling will not survive a container rebuild.`);
82
+ }
83
+ return { dir, preferred: index === 0, reason: candidate.reason };
84
+ }
85
+ // An explicitly named cache that cannot be written but CAN be read is still
86
+ // the answer — see {@link readable} — and it has to win here rather than in a
87
+ // second pass at the end. Otherwise the writable-but-empty temp directory two
88
+ // candidates down takes precedence over a read-only cache holding the very
89
+ // tooling this run needs, which is the shape our own image has.
90
+ if (index === 0 && explicit && readable(dir)) {
91
+ return { dir, preferred: true, reason: 'configured, read-only' };
92
+ }
93
+ }
94
+ return null;
95
+ }
96
+ /**
97
+ * Where fetched tooling is installed — one tree for the whole run, not one per profile.
98
+ *
99
+ * A directory per profile left npm nothing to deduplicate, and the profiles
100
+ * overlap heavily: `commitlint` and `js` share 30 MB, so two trees fetched both
101
+ * copies. Measured on a JavaScript repository, per-profile directories came to
102
+ * 267 MB where a single merged tree costs 213 (ticket 087).
103
+ *
104
+ * The name is deliberately not derived from which profiles are inside. What is
105
+ * installed is recorded in the directory's own stamp and checked as a superset,
106
+ * so a cache warmed by `install --all` serves every narrower run — a path keyed
107
+ * by the profile set would miss on the first one.
108
+ */
109
+ export function toolingDir(cacheDir) {
110
+ return path.join(cacheDir, 'tooling');
111
+ }
112
+ /**
113
+ * Where a single profile's tooling used to be installed.
114
+ *
115
+ * Kept only so `cache prune` can still recognise and remove the directories left
116
+ * by versions that used the per-profile layout.
117
+ */
118
+ export function profileDir(cacheDir, profile) {
119
+ return path.join(cacheDir, profile);
120
+ }
121
+ /**
122
+ * Profile directories left behind by other versions of pr-checkmate.
123
+ *
124
+ * Nothing removes these automatically: an upgrade must not delete tooling a
125
+ * concurrently running older version is in the middle of using. `cache prune`
126
+ * is the deliberate, separate act.
127
+ */
128
+ export function stalePaths(version, configured) {
129
+ const location = resolveCacheDir(version, configured);
130
+ if (!location)
131
+ return [];
132
+ const root = path.dirname(location.dir);
133
+ try {
134
+ return fs
135
+ .readdirSync(root, { withFileTypes: true })
136
+ .filter(entry => entry.isDirectory() && entry.name !== version)
137
+ .map(entry => path.join(root, entry.name));
138
+ }
139
+ catch {
140
+ return [];
141
+ }
142
+ }
@@ -0,0 +1,35 @@
1
+ import { type LanguageUsage } from '../../utils/detect-language.js';
2
+ import { packageVersion } from '../../utils/package-version.js';
3
+ import { type EnsureResult } from './ensure.js';
4
+ import { type ProfileDecision } from './profiles.js';
5
+ export { packageVersion };
6
+ /**
7
+ * Everything the install layer knows about this repository, in one shot.
8
+ *
9
+ * `usage` is a parameter rather than always detected here so a caller that
10
+ * already has it — `doctor` prints it — does not scan the repository twice and
11
+ * log two contradictory-looking detection lines for one command.
12
+ */
13
+ export declare function planInstall(cwd?: string, usage?: LanguageUsage[]): Promise<{
14
+ decisions: ProfileDecision[];
15
+ cacheDir: string | null;
16
+ }>;
17
+ /**
18
+ * Fetch every profile this repository needs.
19
+ *
20
+ * Shared by the `install` command and by the run itself, so a client who never
21
+ * runs `install` gets the same result lazily. `all` is what a container build or
22
+ * an air-gapped mirror wants: everything, regardless of what this repository
23
+ * happens to contain.
24
+ */
25
+ export declare function installProfiles(cwd?: string, all?: boolean): Promise<EnsureResult[]>;
26
+ /**
27
+ * Explain what this repository needs, what it has, and what is missing — and why.
28
+ *
29
+ * The command exists because adaptive installation makes "why did my typecheck
30
+ * not run" a routine question, and the answer must be a command rather than a
31
+ * reading of our source.
32
+ */
33
+ export declare function runDoctor(cwd?: string): Promise<void>;
34
+ /** Remove cached tooling belonging to other versions of pr-checkmate. */
35
+ export declare function pruneCache(): void;