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,21 @@
1
+ import { execa } from './execa.js';
2
+ /**
3
+ * Resolve a git ref to a concrete commit SHA, or `undefined` when this clone
4
+ * cannot resolve it.
5
+ *
6
+ * `--verify --quiet` emits nothing (rather than echoing the literal ref) and exits
7
+ * non-zero for a missing ref, so the caller gets a clear "not here" instead of a
8
+ * string that looks like a ref but resolves to nothing. Refs go missing more often
9
+ * than it seems: `HEAD^` on a repository's first commit, and any ancestor in a
10
+ * shallow CI clone — `actions/checkout` fetches depth 1 by default.
11
+ *
12
+ * Every caller must degrade rather than fail when this returns `undefined`: a
13
+ * missing base means "review everything", never "review nothing".
14
+ */
15
+ export async function resolveGitRef(cwd, ref) {
16
+ const { stdout } = await execa('git', ['rev-parse', '--verify', '--quiet', `${ref}^{commit}`], {
17
+ cwd,
18
+ reject: false,
19
+ });
20
+ return stdout.trim() || undefined;
21
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Minimal glob → RegExp for path matching against config patterns. Supports `*`
3
+ * (matches within a path segment), `**` (across segments), and a leading `** /`
4
+ * that also matches the repo root (zero segments). Anchored to the whole path.
5
+ * Not a full glob implementation — enough for the allow/ignore lists in
6
+ * pr-checkmate.json (e.g. "assets/**", "*.png", "** / *.d.ts").
7
+ */
8
+ export declare function globToRegExp(glob: string): RegExp;
9
+ /** True when `file` matches any of the glob `patterns`. */
10
+ export declare function matchesAnyGlob(file: string, patterns: string[]): boolean;
11
+ /**
12
+ * True when any segment of a repo-relative path names an excluded directory —
13
+ * `node_modules/x/y.py` for `node_modules`, at any nesting depth.
14
+ *
15
+ * Shared so the two consumers cannot drift: the file list every check operates on
16
+ * (`excludeIgnoredDirs` in core/targets.ts) and language detection, which counts
17
+ * tracked source files. They disagreed once — detection counted a repository that
18
+ * commits its dependencies as a Python/Go/PHP project and switched on the checks
19
+ * for languages nobody had written a line of.
20
+ *
21
+ * @param file Repo-relative path, forward slashes.
22
+ * @param ignoredDirs Directory NAMES (not globs) to exclude.
23
+ */
24
+ export declare function isUnderIgnoredDir(file: string, ignoredDirs: Iterable<string>): boolean;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Minimal glob → RegExp for path matching against config patterns. Supports `*`
3
+ * (matches within a path segment), `**` (across segments), and a leading `** /`
4
+ * that also matches the repo root (zero segments). Anchored to the whole path.
5
+ * Not a full glob implementation — enough for the allow/ignore lists in
6
+ * pr-checkmate.json (e.g. "assets/**", "*.png", "** / *.d.ts").
7
+ */
8
+ export function globToRegExp(glob) {
9
+ const re = glob
10
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&') // escape regex specials (not * or /)
11
+ .replace(/\*\*\//g, ' dir ') // `**/` → optional leading dirs (matches root too)
12
+ .replace(/\*\*/g, ' any ') // bare `**` → across segments
13
+ .replace(/\*/g, '[^/]*') // `*` → within a segment
14
+ .replace(/ dir /g, '(?:.*/)?')
15
+ .replace(/ any /g, '.*');
16
+ return new RegExp(`^${re}$`);
17
+ }
18
+ /** True when `file` matches any of the glob `patterns`. */
19
+ export function matchesAnyGlob(file, patterns) {
20
+ return patterns.some(p => globToRegExp(p).test(file));
21
+ }
22
+ /**
23
+ * True when any segment of a repo-relative path names an excluded directory —
24
+ * `node_modules/x/y.py` for `node_modules`, at any nesting depth.
25
+ *
26
+ * Shared so the two consumers cannot drift: the file list every check operates on
27
+ * (`excludeIgnoredDirs` in core/targets.ts) and language detection, which counts
28
+ * tracked source files. They disagreed once — detection counted a repository that
29
+ * commits its dependencies as a Python/Go/PHP project and switched on the checks
30
+ * for languages nobody had written a line of.
31
+ *
32
+ * @param file Repo-relative path, forward slashes.
33
+ * @param ignoredDirs Directory NAMES (not globs) to exclude.
34
+ */
35
+ export function isUnderIgnoredDir(file, ignoredDirs) {
36
+ const ignored = ignoredDirs instanceof Set ? ignoredDirs : new Set(ignoredDirs);
37
+ if (ignored.size === 0)
38
+ return false;
39
+ return file.split('/').some(segment => ignored.has(segment));
40
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Outcome of one request: never throws, so a reporting hiccup cannot kill a run.
3
+ *
4
+ * Internal to this module — `utils/index.ts` does not re-export `http`, and the
5
+ * reporters consume the result inline rather than naming the type.
6
+ */
7
+ interface HttpResult<T = unknown> {
8
+ ok: boolean;
9
+ /** 0 when the request never reached a server (timeout, DNS, offline). */
10
+ status: number;
11
+ body?: T;
12
+ /** Human-readable reason, present whenever `ok` is false. */
13
+ error?: string;
14
+ }
15
+ export interface HttpOptions {
16
+ /** Per-attempt timeout. A hung API must not hold the process open. */
17
+ timeoutMs?: number;
18
+ /** Attempts for retryable failures (5xx, 429, network). 1 disables retrying. */
19
+ retries?: number;
20
+ /** Label used in log lines, e.g. `GitHub`. */
21
+ label?: string;
22
+ }
23
+ /**
24
+ * One HTTP request with a timeout and bounded retries, returning a result rather
25
+ * than throwing.
26
+ *
27
+ * The reason this exists: every write in the reporter used to be a bare `await
28
+ * fetch(...)` whose result was discarded, followed by a log line claiming
29
+ * success. A 403 from a workflow missing `pull-requests: write` produced
30
+ * "✅ Posted PR CheckMate summary" and no comment — the user had nothing to
31
+ * debug from.
32
+ */
33
+ export declare function request<T = unknown>(url: string, init?: RequestInit, opts?: HttpOptions): Promise<HttpResult<T>>;
34
+ /**
35
+ * Walk a paginated collection until `nextUrl` returns nothing or `maxPages` is
36
+ * reached, returning every item found.
37
+ *
38
+ * Without this the reporter read only the first page — 30 comments on GitHub, 20
39
+ * on GitLab — so on any PR with more discussion than that its own marker fell off
40
+ * the end, the upsert became an insert, and every push added another comment.
41
+ *
42
+ * Stopping at `maxPages` is logged rather than silent: a truncated search can
43
+ * only produce a duplicate comment, and that should be explainable.
44
+ */
45
+ export declare function paginate<T>(firstUrl: string, init: RequestInit, extract: (body: unknown) => T[],
46
+ /**
47
+ * URL of the page after this one, or null when the collection is exhausted.
48
+ * Receives the page's item count so page-number APIs (GitHub, GitLab) can stop
49
+ * on a short page, while cursor APIs (Bitbucket) read a link out of the body.
50
+ */
51
+ nextUrl: (body: unknown, page: number, count: number) => string | null, opts?: HttpOptions & {
52
+ maxPages?: number;
53
+ }): Promise<{
54
+ items: T[];
55
+ ok: boolean;
56
+ truncated: boolean;
57
+ error?: string;
58
+ }>;
59
+ export {};
@@ -0,0 +1,115 @@
1
+ import { logger } from './logger.js';
2
+ const DEFAULT_TIMEOUT_MS = 10000;
3
+ const DEFAULT_RETRIES = 3;
4
+ /** 5xx and 429 are worth another attempt; a 4xx will fail identically forever. */
5
+ function isRetryable(status) {
6
+ return status === 0 || status === 429 || status >= 500;
7
+ }
8
+ /**
9
+ * Turn a response into a diagnosis a person can act on.
10
+ *
11
+ * "Could not post comment: 403" sends someone hunting through Actions docs;
12
+ * naming the likely cause is the difference between a fixable message and a
13
+ * shrug. These three account for nearly every real failure.
14
+ */
15
+ function explain(status, body) {
16
+ if (status === 401 || status === 403) {
17
+ return `${status} — token missing, expired, or lacking write scope (GitHub needs \`permissions: pull-requests: write\` AND \`env: GITHUB_TOKEN\`)`;
18
+ }
19
+ if (status === 404)
20
+ return `${status} — repository or PR not found, or the token cannot see it`;
21
+ if (status === 429)
22
+ return `${status} — rate limited`;
23
+ return `${status}${body ? ` — ${body.slice(0, 200)}` : ''}`;
24
+ }
25
+ /**
26
+ * Never let a token reach a log line, whatever an API decides to echo back.
27
+ *
28
+ * `pousr` and `glpat` below are not words: the first is the character class of
29
+ * GitHub's token prefixes (`ghp_`/`gho_`/`ghu_`/`ghs_`/`ghr_`), the second is
30
+ * GitLab's literal `glpat-`. Muted here rather than in the dictionary, which
31
+ * ships to every client and should not carry our regex fragments.
32
+ * cspell:ignore pousr glpat
33
+ */
34
+ function redact(text) {
35
+ return text.replace(/\b(gh[pousr]_|glpat-|xox[baprs]-)[A-Za-z0-9_-]{8,}/g, '$1***');
36
+ }
37
+ /**
38
+ * One HTTP request with a timeout and bounded retries, returning a result rather
39
+ * than throwing.
40
+ *
41
+ * The reason this exists: every write in the reporter used to be a bare `await
42
+ * fetch(...)` whose result was discarded, followed by a log line claiming
43
+ * success. A 403 from a workflow missing `pull-requests: write` produced
44
+ * "✅ Posted PR CheckMate summary" and no comment — the user had nothing to
45
+ * debug from.
46
+ */
47
+ export async function request(url, init = {}, opts = {}) {
48
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
49
+ const attempts = Math.max(1, opts.retries ?? DEFAULT_RETRIES);
50
+ const label = opts.label ? `[${opts.label}] ` : '';
51
+ let last = { ok: false, status: 0, error: 'no attempt made' };
52
+ for (let attempt = 1; attempt <= attempts; attempt++) {
53
+ last = await attempt_(url, init, timeoutMs);
54
+ if (last.ok || !isRetryable(last.status))
55
+ return last;
56
+ if (attempt < attempts) {
57
+ // Exponential backoff, capped so three attempts stay well inside a CI step.
58
+ const waitMs = Math.min(2000, 250 * 2 ** (attempt - 1));
59
+ logger.warn(`${label}retrying after ${last.error} (attempt ${attempt}/${attempts})`);
60
+ await new Promise(resolve => setTimeout(resolve, waitMs));
61
+ }
62
+ }
63
+ return last;
64
+ }
65
+ /** A single attempt, with every failure mode flattened into an HttpResult. */
66
+ async function attempt_(url, init, timeoutMs) {
67
+ try {
68
+ const res = await fetch(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
69
+ if (!res.ok) {
70
+ const text = await res.text().catch(() => '');
71
+ return { ok: false, status: res.status, error: redact(explain(res.status, text)) };
72
+ }
73
+ // A successful response with an unreadable body is still a successful write;
74
+ // only callers that need the body care, and they check for `undefined`.
75
+ const body = (await res.json().catch(() => undefined));
76
+ return { ok: true, status: res.status, body };
77
+ }
78
+ catch (err) {
79
+ const reason = err instanceof Error ? err.message : String(err);
80
+ return { ok: false, status: 0, error: redact(`request failed — ${reason}`) };
81
+ }
82
+ }
83
+ /**
84
+ * Walk a paginated collection until `nextUrl` returns nothing or `maxPages` is
85
+ * reached, returning every item found.
86
+ *
87
+ * Without this the reporter read only the first page — 30 comments on GitHub, 20
88
+ * on GitLab — so on any PR with more discussion than that its own marker fell off
89
+ * the end, the upsert became an insert, and every push added another comment.
90
+ *
91
+ * Stopping at `maxPages` is logged rather than silent: a truncated search can
92
+ * only produce a duplicate comment, and that should be explainable.
93
+ */
94
+ export async function paginate(firstUrl, init, extract,
95
+ /**
96
+ * URL of the page after this one, or null when the collection is exhausted.
97
+ * Receives the page's item count so page-number APIs (GitHub, GitLab) can stop
98
+ * on a short page, while cursor APIs (Bitbucket) read a link out of the body.
99
+ */
100
+ nextUrl, opts = {}) {
101
+ const maxPages = Math.max(1, opts.maxPages ?? 10);
102
+ const items = [];
103
+ let url = firstUrl;
104
+ for (let page = 1; page <= maxPages; page++) {
105
+ const res = await request(url, init, opts);
106
+ if (!res.ok)
107
+ return { items, ok: false, truncated: false, error: res.error };
108
+ const pageItems = extract(res.body);
109
+ items.push(...pageItems);
110
+ url = nextUrl(res.body, page, pageItems.length);
111
+ if (!url)
112
+ return { items, ok: true, truncated: false };
113
+ }
114
+ return { items, ok: true, truncated: true };
115
+ }
@@ -0,0 +1,15 @@
1
+ export * from './logger.js';
2
+ export * from './result-collector.js';
3
+ export * from './resolve-bin.js';
4
+ export * from './own-deps.js';
5
+ export * from './direct-deps.js';
6
+ export * from './detect-language.js';
7
+ export * from './glob.js';
8
+ export * from './update-notifier.js';
9
+ export * from './package-version.js';
10
+ export * from './ci.js';
11
+ export * from './git.js';
12
+ /**
13
+ *
14
+ */
15
+ export declare function cleanupTempFile(filePath: string): void;
@@ -0,0 +1,26 @@
1
+ import fs from 'node:fs';
2
+ import { logger } from './logger.js';
3
+ export * from './logger.js';
4
+ export * from './result-collector.js';
5
+ export * from './resolve-bin.js';
6
+ export * from './own-deps.js';
7
+ export * from './direct-deps.js';
8
+ export * from './detect-language.js';
9
+ export * from './glob.js';
10
+ export * from './update-notifier.js';
11
+ export * from './package-version.js';
12
+ export * from './ci.js';
13
+ export * from './git.js';
14
+ /**
15
+ *
16
+ */
17
+ export function cleanupTempFile(filePath) {
18
+ try {
19
+ if (fs.existsSync(filePath)) {
20
+ fs.unlinkSync(filePath);
21
+ }
22
+ }
23
+ catch (err) {
24
+ logger.warn(`[cleanupTempFile]: ⚠️ Failed cleanup: ${filePath}\n${err}`);
25
+ }
26
+ }
@@ -0,0 +1,65 @@
1
+ /** Destination for log lines; see {@link Logger.setSink}. */
2
+ export interface LogSink {
3
+ out(chunk: string): void;
4
+ err(chunk: string): void;
5
+ }
6
+ export type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';
7
+ /** How a line is rendered. */
8
+ export type LogFormat = 'pretty' | 'ci' | 'json';
9
+ export interface LoggerOptions {
10
+ level?: LogLevel;
11
+ format?: LogFormat;
12
+ color?: 'auto' | 'always' | 'never';
13
+ timestamps?: boolean;
14
+ /** Levels routed to stderr rather than stdout. */
15
+ stderrLevels?: LogLevel[];
16
+ }
17
+ export declare class Logger {
18
+ private currentLevel;
19
+ private format;
20
+ private color;
21
+ private timestamps;
22
+ private stderrLevels;
23
+ constructor(options?: LoggerOptions);
24
+ /** Apply options; unset fields keep their current value. */
25
+ configure(options: LoggerOptions): void;
26
+ private shouldLog;
27
+ private streamFor;
28
+ /**
29
+ * Where lines actually go. Swappable so tests can capture output without
30
+ * touching `process.stdout`.
31
+ *
32
+ * That distinction is not stylistic. Node's test runner reports each file's
33
+ * results to the parent process over stdout, so a test that replaces
34
+ * `process.stdout.write` and swallows what it receives also swallows those
35
+ * frames: the parent then waits forever for a file that already finished. It
36
+ * only shows up under load — on a two-core CI runner the frames land inside
37
+ * the capture window, on a developer's machine they usually do not — which
38
+ * made it a three-hour hang that never reproduced locally.
39
+ */
40
+ private sink;
41
+ /**
42
+ * Redirect output, returning the previous sink so the caller can restore it.
43
+ * Passing `null` restores the real streams.
44
+ */
45
+ setSink(sink: LogSink | null): LogSink | null;
46
+ private emit;
47
+ private render;
48
+ private logMessage;
49
+ log(msg: string): void;
50
+ info(msg: string): void;
51
+ warn(msg: string): void;
52
+ error(msg: string, err?: unknown): void;
53
+ debug(msg: string): void;
54
+ /**
55
+ * Product output: the run summary, printed verbatim.
56
+ *
57
+ * Distinct from `info` because the summary is the thing the run exists to
58
+ * produce, not a note about producing it. Routing it through the log formatter
59
+ * prefixed every line with a timestamp and a level, which pushed the box
60
+ * borders out of alignment and made the headline artefact look broken.
61
+ */
62
+ print(msg: string): void;
63
+ setLevel(level: LogLevel): void;
64
+ }
65
+ export declare const logger: Logger;
@@ -0,0 +1,157 @@
1
+ const LEVEL_ORDER = {
2
+ error: 0,
3
+ warn: 1,
4
+ info: 2,
5
+ log: 2,
6
+ debug: 3,
7
+ };
8
+ const COLORS = {
9
+ error: '\x1b[31m', // red
10
+ warn: '\x1b[33m', // yellow
11
+ info: '\x1b[32m', // green
12
+ log: '\x1b[37m', // white
13
+ debug: '\x1b[36m', // cyan
14
+ };
15
+ const RESET = '\x1b[0m';
16
+ /**
17
+ * Whether ANSI colour is wanted on `stream`.
18
+ *
19
+ * Colour used to be emitted unconditionally, so a piped or redirected run — and
20
+ * every CI log — was littered with escape sequences. `NO_COLOR` is the de-facto
21
+ * standard (no-color.org) and `FORCE_COLOR` the usual override; both are honoured
22
+ * here, and the TTY test asks about the stream actually being written to.
23
+ */
24
+ function wantsColor(mode, stream) {
25
+ if (mode === 'never')
26
+ return false;
27
+ if (mode === 'always')
28
+ return true;
29
+ if (process.env.FORCE_COLOR)
30
+ return process.env.FORCE_COLOR !== '0';
31
+ if (process.env.NO_COLOR !== undefined)
32
+ return false;
33
+ return Boolean(stream.isTTY);
34
+ }
35
+ export class Logger {
36
+ constructor(options = {}) {
37
+ this.currentLevel = 'info';
38
+ this.color = 'auto';
39
+ this.stderrLevels = new Set(['error', 'warn']);
40
+ /**
41
+ * Where lines actually go. Swappable so tests can capture output without
42
+ * touching `process.stdout`.
43
+ *
44
+ * That distinction is not stylistic. Node's test runner reports each file's
45
+ * results to the parent process over stdout, so a test that replaces
46
+ * `process.stdout.write` and swallows what it receives also swallows those
47
+ * frames: the parent then waits forever for a file that already finished. It
48
+ * only shows up under load — on a two-core CI runner the frames land inside
49
+ * the capture window, on a developer's machine they usually do not — which
50
+ * made it a three-hour hang that never reproduced locally.
51
+ */
52
+ this.sink = null;
53
+ // CI logs are read long after the fact and benefit from timestamps; a
54
+ // terminal is read as it scrolls, where they are noise that also breaks the
55
+ // alignment of the summary box.
56
+ const inCi = Boolean(process.env.CI);
57
+ this.format = options.format ?? (inCi ? 'ci' : 'pretty');
58
+ this.timestamps = options.timestamps ?? this.format === 'ci';
59
+ this.configure(options);
60
+ }
61
+ /** Apply options; unset fields keep their current value. */
62
+ configure(options) {
63
+ if (options.level)
64
+ this.currentLevel = options.level;
65
+ if (options.format) {
66
+ this.format = options.format;
67
+ if (options.timestamps === undefined)
68
+ this.timestamps = options.format === 'ci';
69
+ }
70
+ if (options.color)
71
+ this.color = options.color;
72
+ if (options.timestamps !== undefined)
73
+ this.timestamps = options.timestamps;
74
+ if (options.stderrLevels)
75
+ this.stderrLevels = new Set(options.stderrLevels);
76
+ }
77
+ shouldLog(level) {
78
+ return LEVEL_ORDER[level] <= LEVEL_ORDER[this.currentLevel];
79
+ }
80
+ streamFor(level) {
81
+ return this.stderrLevels.has(level) ? process.stderr : process.stdout;
82
+ }
83
+ /**
84
+ * Redirect output, returning the previous sink so the caller can restore it.
85
+ * Passing `null` restores the real streams.
86
+ */
87
+ setSink(sink) {
88
+ const previous = this.sink;
89
+ this.sink = sink;
90
+ return previous;
91
+ }
92
+ emit(stream, text) {
93
+ if (!this.sink) {
94
+ stream.write(text);
95
+ return;
96
+ }
97
+ if (stream === process.stderr)
98
+ this.sink.err(text);
99
+ else
100
+ this.sink.out(text);
101
+ }
102
+ render(level, message, error) {
103
+ const stack = error instanceof Error ? `\n${error.stack}` : '';
104
+ if (this.format === 'json') {
105
+ return JSON.stringify({
106
+ level,
107
+ message,
108
+ ...(stack ? { stack: stack.trim() } : {}),
109
+ time: new Date().toISOString(),
110
+ });
111
+ }
112
+ const time = this.timestamps ? `[${new Date().toISOString()}] ` : '';
113
+ const tag = this.format === 'ci' ? `[${level.toUpperCase()}] ` : '';
114
+ return `${time}${tag}${message}${stack}`;
115
+ }
116
+ logMessage(level, message, error) {
117
+ if (!this.shouldLog(level))
118
+ return;
119
+ const stream = this.streamFor(level);
120
+ const line = this.render(level, message, error);
121
+ // JSON output is meant to be parsed; coloring it would corrupt the payload.
122
+ const colored = this.format !== 'json' && wantsColor(this.color, stream)
123
+ ? `${COLORS[level]}${line}${RESET}`
124
+ : line;
125
+ this.emit(stream, `${colored}\n`);
126
+ }
127
+ log(msg) {
128
+ this.logMessage('log', msg);
129
+ }
130
+ info(msg) {
131
+ this.logMessage('info', msg);
132
+ }
133
+ warn(msg) {
134
+ this.logMessage('warn', msg);
135
+ }
136
+ error(msg, err) {
137
+ this.logMessage('error', msg, err);
138
+ }
139
+ debug(msg) {
140
+ this.logMessage('debug', msg);
141
+ }
142
+ /**
143
+ * Product output: the run summary, printed verbatim.
144
+ *
145
+ * Distinct from `info` because the summary is the thing the run exists to
146
+ * produce, not a note about producing it. Routing it through the log formatter
147
+ * prefixed every line with a timestamp and a level, which pushed the box
148
+ * borders out of alignment and made the headline artefact look broken.
149
+ */
150
+ print(msg) {
151
+ this.emit(process.stdout, `${msg}\n`);
152
+ }
153
+ setLevel(level) {
154
+ this.currentLevel = level;
155
+ }
156
+ }
157
+ export const logger = new Logger();
@@ -0,0 +1,16 @@
1
+ /** Walk up from this module until we find pr-checkmate's own package root. */
2
+ export declare function findOwnPackageRoot(): string | null;
3
+ /**
4
+ * Compute the full set of package names in pr-checkmate's own dependency
5
+ * closure (direct + transitive runtime dependencies), plus pr-checkmate itself.
6
+ *
7
+ * pr-checkmate installs into the consumer's node_modules, so its own runtime
8
+ * deps (eslint plugins, cspell dictionaries, …) become part of the consumer's
9
+ * production dependency tree. Some carry copyleft licenses that would otherwise
10
+ * trip pr-checkmate's own license check against an innocent client. These are
11
+ * pr-checkmate's dependencies, not the client's, so they must be exempt.
12
+ *
13
+ * Result is cached for the process. Returns a set containing only pr-checkmate
14
+ * itself if the package root cannot be located (defensive; never throws).
15
+ */
16
+ export declare function getOwnDependencyClosure(): Set<string>;
@@ -0,0 +1,107 @@
1
+ import { fileURLToPath as __fileURLToPath } from 'node:url';
2
+ import { dirname as __dirnameFn } from 'node:path';
3
+ const __dirname = __dirnameFn(__fileURLToPath(import.meta.url));
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ const OWN_PACKAGE_NAME = 'pr-checkmate';
7
+ const PACKAGE_JSON = 'package.json';
8
+ let cachedClosure;
9
+ /** Read a package.json's `dependencies` keys, tolerating missing/broken files. */
10
+ function readDependencyNames(pkgDir) {
11
+ try {
12
+ const pkg = JSON.parse(fs.readFileSync(path.join(pkgDir, PACKAGE_JSON), 'utf-8'));
13
+ return Object.keys(pkg.dependencies ?? {});
14
+ }
15
+ catch {
16
+ return [];
17
+ }
18
+ }
19
+ /**
20
+ * Walk up from `startDir` (inclusive) toward the filesystem root, returning the
21
+ * first directory whose package.json declares `name === expectedName`, or null.
22
+ * Broken/missing package.json files are skipped rather than thrown.
23
+ */
24
+ function findPackageRootByName(startDir, expectedName) {
25
+ let dir = startDir;
26
+ while (dir !== path.dirname(dir)) {
27
+ const pkgJsonPath = path.join(dir, PACKAGE_JSON);
28
+ if (fs.existsSync(pkgJsonPath)) {
29
+ try {
30
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
31
+ if (pkg.name === expectedName)
32
+ return dir;
33
+ }
34
+ catch { }
35
+ }
36
+ dir = path.dirname(dir);
37
+ }
38
+ return null;
39
+ }
40
+ /** Walk up from this module until we find pr-checkmate's own package root. */
41
+ export function findOwnPackageRoot() {
42
+ return findPackageRootByName(__dirname, OWN_PACKAGE_NAME);
43
+ }
44
+ /**
45
+ * Resolve a dependency's install directory by name, starting the search from
46
+ * `fromDir`. Relies on Node's upward node_modules walk so hoisted packages are
47
+ * found regardless of physical layout.
48
+ */
49
+ function resolvePackageDir(name, fromDir) {
50
+ // Prefer the explicit package.json subpath.
51
+ try {
52
+ return path.dirname(require.resolve(`${name}/package.json`, { paths: [fromDir] }));
53
+ }
54
+ catch { }
55
+ // Fallback for packages whose exports map hides ./package.json: resolve the
56
+ // entry point and walk up to the package's own root.
57
+ try {
58
+ const entryDir = path.dirname(require.resolve(name, { paths: [fromDir] }));
59
+ return findPackageRootByName(entryDir, name);
60
+ }
61
+ catch { }
62
+ return null;
63
+ }
64
+ /**
65
+ * Compute the full set of package names in pr-checkmate's own dependency
66
+ * closure (direct + transitive runtime dependencies), plus pr-checkmate itself.
67
+ *
68
+ * pr-checkmate installs into the consumer's node_modules, so its own runtime
69
+ * deps (eslint plugins, cspell dictionaries, …) become part of the consumer's
70
+ * production dependency tree. Some carry copyleft licenses that would otherwise
71
+ * trip pr-checkmate's own license check against an innocent client. These are
72
+ * pr-checkmate's dependencies, not the client's, so they must be exempt.
73
+ *
74
+ * Result is cached for the process. Returns a set containing only pr-checkmate
75
+ * itself if the package root cannot be located (defensive; never throws).
76
+ */
77
+ export function getOwnDependencyClosure() {
78
+ if (cachedClosure)
79
+ return cachedClosure;
80
+ const closure = new Set([OWN_PACKAGE_NAME]);
81
+ const root = findOwnPackageRoot();
82
+ if (!root) {
83
+ cachedClosure = closure;
84
+ return closure;
85
+ }
86
+ // BFS over the dependency graph, resolving each package relative to the parent
87
+ // that declared it so nested (non-hoisted) installs resolve correctly.
88
+ const queue = readDependencyNames(root).map(name => ({
89
+ name,
90
+ fromDir: root,
91
+ }));
92
+ while (queue.length > 0) {
93
+ const { name, fromDir } = queue.shift();
94
+ if (closure.has(name))
95
+ continue;
96
+ closure.add(name);
97
+ const depDir = resolvePackageDir(name, fromDir);
98
+ if (!depDir)
99
+ continue;
100
+ for (const child of readDependencyNames(depDir)) {
101
+ if (!closure.has(child))
102
+ queue.push({ name: child, fromDir: depDir });
103
+ }
104
+ }
105
+ cachedClosure = closure;
106
+ return closure;
107
+ }
@@ -0,0 +1,4 @@
1
+ /** The version of pr-checkmate that is executing right now. */
2
+ export declare function packageVersion(): string;
3
+ /** The package name that is executing right now — the one to query npm for. */
4
+ export declare function packageName(): string;