pr-checkmate 3.0.4 → 3.2.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 (384) 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/{core → cjs/core}/checks/languages/go-format.js +21 -21
  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/cjs/core/checks/quality/markdown-lint.js +147 -0
  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/profiles.js +1 -1
  118. package/dist/{core → cjs/core}/install/reuse.d.ts +1 -1
  119. package/dist/{core → cjs/core}/install/reuse.js +4 -4
  120. package/dist/{core → cjs/core}/registry.d.ts +1 -1
  121. package/dist/cjs/core/registry.js +112 -0
  122. package/dist/{core → cjs/core}/reporters.d.ts +1 -1
  123. package/dist/{core → cjs/core}/reporters.js +28 -28
  124. package/dist/{core → cjs/core}/run-checks.d.ts +2 -2
  125. package/dist/{core → cjs/core}/run-checks.js +31 -31
  126. package/dist/{core → cjs/core}/targets.d.ts +1 -1
  127. package/dist/{core → cjs/core}/targets.js +20 -20
  128. package/dist/{core → cjs/core}/types.d.ts +3 -3
  129. package/dist/cjs/index.d.ts +12 -0
  130. package/dist/{index.js → cjs/index.js} +18 -18
  131. package/dist/{init.js → cjs/init.js} +68 -56
  132. package/dist/{interfaces → cjs/interfaces}/index.d.ts +3 -3
  133. package/dist/cjs/package.json +1 -0
  134. package/dist/{scripts → cjs/scripts}/copy-configs.js +22 -7
  135. package/dist/{scripts → cjs/scripts}/generate-install-manifests.js +2 -2
  136. package/dist/{scripts → cjs/scripts}/publish-github.js +4 -4
  137. package/dist/{utils → cjs/utils}/detect-language.js +12 -12
  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/esm/core/checks/languages/go-format.js +163 -0
  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 +141 -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/esm/utils/execa.js +10 -0
  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/duplicate/package-lock.json +0 -12
  335. package/install-manifests/js/package-lock.json +17 -41
  336. package/install-manifests/js/package.json +1 -1
  337. package/install-manifests/markdown/package-lock.json +1 -492
  338. package/install-manifests/markdown/package.json +1 -1
  339. package/package.json +17 -15
  340. package/dist/core/checks/languages/lint.d.ts +0 -2
  341. package/dist/core/checks/quality/markdown-lint.js +0 -110
  342. package/dist/core/index.d.ts +0 -4
  343. package/dist/core/registry.js +0 -112
  344. package/dist/index.d.ts +0 -12
  345. package/dist/utils/index.d.ts +0 -15
  346. /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
  347. /package/dist/{config → cjs/config}/constants.d.ts +0 -0
  348. /package/dist/{config → cjs/config}/constants.js +0 -0
  349. /package/dist/{config → cjs/config}/pr-checkmate-workflow-docker.yml +0 -0
  350. /package/dist/{config → cjs/config}/pr-checkmate-workflow.yml +0 -0
  351. /package/dist/{core → cjs/core}/checks/languages/ruff-shared.d.ts +0 -0
  352. /package/dist/{core → cjs/core}/checks/languages/ruff-shared.js +0 -0
  353. /package/dist/{core → cjs/core}/commands.d.ts +0 -0
  354. /package/dist/{core → cjs/core}/commands.js +0 -0
  355. /package/dist/{core → cjs/core}/install/cache.d.ts +0 -0
  356. /package/dist/{core → cjs/core}/install/lock.d.ts +0 -0
  357. /package/dist/{core → cjs/core}/install/merge.d.ts +0 -0
  358. /package/dist/{core → cjs/core}/install/merge.js +0 -0
  359. /package/dist/{core → cjs/core}/types.js +0 -0
  360. /package/dist/{init.d.ts → cjs/init.d.ts} +0 -0
  361. /package/dist/{interfaces → cjs/interfaces}/index.js +0 -0
  362. /package/dist/{scripts → cjs/scripts}/copy-configs.d.ts +0 -0
  363. /package/dist/{scripts → cjs/scripts}/generate-install-manifests.d.ts +0 -0
  364. /package/dist/{scripts → cjs/scripts}/publish-github.d.ts +0 -0
  365. /package/dist/{utils → cjs/utils}/ci.d.ts +0 -0
  366. /package/dist/{utils → cjs/utils}/ci.js +0 -0
  367. /package/dist/{utils → cjs/utils}/detect-language.d.ts +0 -0
  368. /package/dist/{utils → cjs/utils}/direct-deps.d.ts +0 -0
  369. /package/dist/{utils → cjs/utils}/direct-deps.js +0 -0
  370. /package/dist/{utils → cjs/utils}/execa.d.ts +0 -0
  371. /package/dist/{utils → cjs/utils}/execa.js +0 -0
  372. /package/dist/{utils → cjs/utils}/git.d.ts +0 -0
  373. /package/dist/{utils → cjs/utils}/glob.d.ts +0 -0
  374. /package/dist/{utils → cjs/utils}/glob.js +0 -0
  375. /package/dist/{utils → cjs/utils}/http.d.ts +0 -0
  376. /package/dist/{utils → cjs/utils}/logger.d.ts +0 -0
  377. /package/dist/{utils → cjs/utils}/logger.js +0 -0
  378. /package/dist/{utils → cjs/utils}/package-version.d.ts +0 -0
  379. /package/dist/{utils → cjs/utils}/pool.d.ts +0 -0
  380. /package/dist/{utils → cjs/utils}/pool.js +0 -0
  381. /package/dist/{utils → cjs/utils}/resolve-bin.d.ts +0 -0
  382. /package/dist/{utils → cjs/utils}/result-collector.d.ts +0 -0
  383. /package/dist/{utils → cjs/utils}/result-collector.js +0 -0
  384. /package/dist/{utils → cjs/utils}/update-notifier.d.ts +0 -0
@@ -0,0 +1,421 @@
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 'fs';
5
+ import path from 'path';
6
+ import inquirer from 'inquirer';
7
+ import { DEAD_CODE_IGNORE_DEFAULTS, DEFAULT_COMMANDS, DIFF_SECURITY_IGNORE_DEFAULTS, documentation, DOCS_URL, DUPLICATE_IGNORE_DEFAULTS, FULL_CONFIG_URL, GENERATED_DOC_FILES, IGNORED_DIRS, } from './config/index.js';
8
+ import { DEFAULT_DATAFLOW_WINDOW } from './core/checks/findings.js';
9
+ import { logger, detectLanguages, findOwnPackageRoot } from './utils/index.js';
10
+ const CONFIG_FILE = path.resolve(process.cwd(), 'pr-checkmate.json');
11
+ /**
12
+ * Points editors at the bundled JSON schema. With the generated config reduced
13
+ * to the client's own decisions, this line is what makes every other option
14
+ * discoverable: the editor autocompletes each key and shows its description.
15
+ */
16
+ const SCHEMA_PATH = './node_modules/pr-checkmate/pr-checkmate.schema.json';
17
+ const MANUAL_ENTRY = 'Enter manually';
18
+ /** Prompt the user for the project source path, allowing a manual entry. */
19
+ async function promptSourcePath() {
20
+ const answers = await inquirer.prompt([
21
+ {
22
+ // inquirer v14 renamed the classic `list` prompt to `select`.
23
+ type: 'select',
24
+ name: 'sourcePath',
25
+ message: 'Where is your project source code?',
26
+ default: '.',
27
+ choices: [{ name: '. (entire repo — recommended)', value: '.' }, 'src', 'app', MANUAL_ENTRY],
28
+ },
29
+ {
30
+ type: 'input',
31
+ name: 'manualPath',
32
+ message: 'Enter path:',
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ when: (a) => a.sourcePath === MANUAL_ENTRY,
35
+ validate: (input) => input.trim().length > 0 || 'Cannot be empty',
36
+ },
37
+ ]);
38
+ return answers.sourcePath === MANUAL_ENTRY ? answers.manualPath : answers.sourcePath;
39
+ }
40
+ /**
41
+ * Ask whether the generated workflow should block merges.
42
+ *
43
+ * Two levers decide strictness and they are not interchangeable: this one says
44
+ * whether a failed run means anything to GitHub at all, while `severity` in
45
+ * pr-checkmate.json says which findings count as a failure. The recommended way
46
+ * into an existing codebase is a strict workflow plus a permissive config — the
47
+ * gate is real from day one, and checks are promoted one at a time.
48
+ */
49
+ async function promptGateMode() {
50
+ const { mode } = await inquirer.prompt([
51
+ {
52
+ type: 'select',
53
+ name: 'mode',
54
+ message: 'Should a failed check block the pull request?',
55
+ default: 'strict',
56
+ choices: [
57
+ { name: 'Yes — block the merge (recommended)', value: 'strict' },
58
+ { name: 'No — report only, never block', value: 'advisory' },
59
+ ],
60
+ },
61
+ ]);
62
+ return mode;
63
+ }
64
+ /** The banner an advisory workflow carries, so it reads as a decision, not an accident. */
65
+ const ADVISORY_NOTICE = [
66
+ ' # ADVISORY MODE — this run cannot block a merge.',
67
+ ' #',
68
+ ' # Chosen at `pr-checkmate init`. Reasonable while adopting the tool on an',
69
+ ' # existing codebase, but it also means a detected secret does not stop the',
70
+ ' # PR. To make this a real gate, delete the `continue-on-error` line below.',
71
+ ' #',
72
+ ' # Prefer the opposite arrangement: keep the gate real and relax individual',
73
+ ' # checks in pr-checkmate.json instead —',
74
+ ' # "severityDefaults": { "failOn": "warn" } everything advisory',
75
+ ' # "severity": { "Security Scan": "error" } promote one back to a gate',
76
+ ' # That way whatever you have already made clean stays enforced.',
77
+ ].join('\n');
78
+ /** Indented to sit inside the step, not beside it — YAML is unforgiving here. */
79
+ const ADVISORY_FLAG = ' continue-on-error: true';
80
+ /**
81
+ * Write the bundled GitHub Actions workflow into the consumer repo.
82
+ *
83
+ * Never overwrites an existing file. `init` is not a one-time command — the
84
+ * update notice asks people to re-run it after every upgrade — so clobbering
85
+ * would quietly discard whatever they had tuned, including the gate setting they
86
+ * were just asked about.
87
+ */
88
+ export function setupWorkflow(root, mode) {
89
+ // We can't know for sure whether a repo will end up depending on the npm
90
+ // package by the time this workflow first runs (that's a decision the client
91
+ // makes after `init`, e.g. by running `npm install pr-checkmate`), so instead
92
+ // of guessing we scaffold both variants and let them keep the one that
93
+ // matches, deleting the other:
94
+ //
95
+ // - the npm variant: `npx pr-checkmate` runs the copy the lockfile pins,
96
+ // which is fast and reproducible, but assumes the install happens;
97
+ // - the docker variant: works with no install, but `npx` (nothing to run
98
+ // locally) resolves to the newest release and downloads it on every job —
99
+ // 547 MB, about five minutes, and a major version can land without anyone
100
+ // changing a line.
101
+ const candidates = [
102
+ { source: 'pr-checkmate-workflow.yml', dest: 'pr-checkmate.yml', label: 'npm package' },
103
+ {
104
+ source: 'pr-checkmate-workflow-docker.yml',
105
+ dest: 'pr-checkmate-docker.yml',
106
+ label: 'Docker image',
107
+ },
108
+ ];
109
+ const workflowDir = path.join(root, '.github', 'workflows');
110
+ const recommended = installsPackage(root) ? candidates[0] : candidates[1];
111
+ for (const { source, dest, label } of candidates) {
112
+ const workflowSource = path.join(__dirname, 'config', source);
113
+ const workflowDest = path.join(workflowDir, dest);
114
+ if (!fs.existsSync(workflowSource)) {
115
+ logger.warn(`[init]: ⚠️ Workflow template ${source} not found, skipping`);
116
+ continue;
117
+ }
118
+ if (fs.existsSync(workflowDest)) {
119
+ logger.info(`[init]: ⏭️ .github/workflows/${dest} already exists — left untouched`);
120
+ continue;
121
+ }
122
+ if (!fs.existsSync(workflowDir)) {
123
+ fs.mkdirSync(workflowDir, { recursive: true });
124
+ }
125
+ const template = fs.readFileSync(workflowSource, 'utf-8').replace(/__IMAGE_TAG__/g, imageTag());
126
+ const workflow = mode === 'advisory'
127
+ ? template.replace(RUN_STEP_ANCHOR, `${ADVISORY_NOTICE}\n${RUN_STEP_ANCHOR}\n${ADVISORY_FLAG}`)
128
+ : template;
129
+ fs.writeFileSync(workflowDest, workflow);
130
+ const recommendedNote = dest === recommended.dest ? ', recommended for this repo' : '';
131
+ logger.info(`[init]: ✅ Created .github/workflows/${dest} (${label}${recommendedNote})`);
132
+ }
133
+ logger.info('[init]: ℹ️ Both workflow variants were created — keep the one that fits and delete the other, ' +
134
+ 'otherwise checks run twice on every PR.');
135
+ }
136
+ /**
137
+ * Whether this repository installs pr-checkmate rather than reaching for it on
138
+ * the pipeline. A missing or unreadable package.json answers "no", which is the
139
+ * safe way round: the container variant works either way, while the npm variant
140
+ * assumes an install that may not happen.
141
+ */
142
+ function installsPackage(root) {
143
+ try {
144
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));
145
+ return Boolean(pkg.dependencies?.['pr-checkmate'] ?? pkg.devDependencies?.['pr-checkmate']);
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ }
151
+ /**
152
+ * The image tag written into the generated workflow: our own major.
153
+ *
154
+ * Pinned to a major rather than to `latest`, so patches and features arrive on
155
+ * their own while a change that can start failing builds does not. Pinned to a
156
+ * major rather than an exact version, so a client is not left on a release with
157
+ * a known problem because nobody remembered to bump a YAML file.
158
+ */
159
+ function imageTag() {
160
+ try {
161
+ const manifest = path.join(findOwnPackageRoot() ?? path.resolve(__dirname, '..'), 'package.json');
162
+ const version = JSON.parse(fs.readFileSync(manifest, 'utf-8')).version;
163
+ return version.split('.')[0] || 'latest';
164
+ }
165
+ catch {
166
+ return 'latest';
167
+ }
168
+ }
169
+ /** Where the advisory banner is spliced in — the step that runs the checks. */
170
+ const RUN_STEP_ANCHOR = ' - name: Run PR CheckMate';
171
+ /** Create a tsconfig.json scaffold if the consumer repo lacks one. */
172
+ function setupTsConfig(root, sourcePath) {
173
+ const tsconfigPath = path.join(root, 'tsconfig.json');
174
+ if (fs.existsSync(tsconfigPath))
175
+ return;
176
+ const newTsConfig = {
177
+ compilerOptions: {
178
+ target: 'ES2020',
179
+ module: 'NodeNext',
180
+ outDir: 'dist',
181
+ strict: true,
182
+ rootDir: sourcePath,
183
+ moduleResolution: 'NodeNext',
184
+ esModuleInterop: true,
185
+ resolveJsonModule: true,
186
+ forceConsistentCasingInFileNames: true,
187
+ skipLibCheck: true,
188
+ types: ['node'],
189
+ },
190
+ include: [`${sourcePath}/**/*.ts`],
191
+ exclude: ['node_modules', 'dist'],
192
+ };
193
+ fs.writeFileSync(tsconfigPath, JSON.stringify(newTsConfig, null, 2));
194
+ logger.info('[init]: ✅ Created tsconfig.json using your sourcePath');
195
+ }
196
+ /**
197
+ * The file `init` writes for a new project — the client's decisions, nothing else.
198
+ *
199
+ * Every other setting is deliberately absent. The config is deep-merged over the
200
+ * built-in defaults when it is loaded, so a key that repeats a default changes
201
+ * nothing: it only lengthens the file and freezes today's value in someone
202
+ * else's repository. Three hundred generated lines also read as a wall of
203
+ * settings to maintain, when there is nothing to maintain.
204
+ *
205
+ * Discoverability moves to two places that cannot go stale — `$schema`, which
206
+ * makes an editor autocomplete every option with its description, and the
207
+ * annotated reference shipped inside the package.
208
+ */
209
+ /** The one-line answer to "how do I change this" — see {@link buildInitialConfig}. */
210
+ const REPORTING_HINT = [
211
+ 'Results post to the PR/MR automatically.',
212
+ 'GitHub: keep `permissions: pull-requests: write` AND pass the token to the step',
213
+ '(`env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`) — Actions does not provide it',
214
+ 'on its own, and without it the comment is silently skipped. The generated',
215
+ 'workflow already does both.',
216
+ 'GitLab: create a token (Project → Settings → Access Tokens, scope `api`) and add',
217
+ 'it as CI/CD variable GITLAB_TOKEN.',
218
+ 'Bitbucket: create a token (Repo → Settings → Access tokens, scope',
219
+ 'pull-requests:write) and add it as repo variable BITBUCKET_TOKEN.',
220
+ 'The token lives in YOUR CI variables, never in this file. Without it checks',
221
+ 'still run and print to the log — only the comment is skipped.',
222
+ ].join(' ');
223
+ /**
224
+ * Every check that fails the run out of the box, written into the generated
225
+ * config at its real default.
226
+ *
227
+ * Not a copy of a default for its own sake — this one is the gate's teeth, and
228
+ * the client is entitled to see which checks can stop their merge without
229
+ * reading our source or discovering it from a red pipeline. Written as `"error"`
230
+ * so the edit is in place: change the value, or delete the line to inherit
231
+ * whatever we ship next.
232
+ *
233
+ * Two things are deliberately absent. `Custom Rules` and `Banned Imports` can
234
+ * block too, but only for rules the client writes themselves, so listing them
235
+ * would suggest a gate that is inert until they act. And `Dockerfile Security`
236
+ * looks like it belongs here and does not: every one of its patterns is rated
237
+ * `warn`, so it never fails on its own.
238
+ *
239
+ * Keep in step with the checks' own defaults — `blocking-checks.test.ts` pins
240
+ * every name here to the registry, which catches a rename but not a change of
241
+ * heart about what should block.
242
+ */
243
+ export const BLOCKING_BY_DEFAULT = [
244
+ 'Security Scan',
245
+ 'Sensitive Files',
246
+ 'Diff Security',
247
+ 'Workflow Security',
248
+ 'Merge Conflict',
249
+ 'NPM Audit',
250
+ 'License Check',
251
+ 'Dependencies',
252
+ 'TypeScript',
253
+ 'ESLint',
254
+ 'YAML Lint',
255
+ ];
256
+ const HOW_TO = [
257
+ 'Only what differs from the defaults belongs here — everything else is implicit',
258
+ 'and stays current on upgrade, so this file stays short.',
259
+ 'Turn a check off: "severity": { "Spellcheck": "off" }',
260
+ 'Make one advisory: "severity": { "Sensitive Files": "warn" }',
261
+ 'Make everything advisory while adopting: "severityDefaults": { "failOn": "warn" }',
262
+ 'Skip a file or folder: "excludePaths": ["src/generated/**", "vendor/legacy.ts"]',
263
+ 'Check names are the ones printed in the report.',
264
+ `Every option, annotated, with its default: ${FULL_CONFIG_URL}`,
265
+ `Docs: ${DOCS_URL}`,
266
+ ].join(' ');
267
+ export function buildInitialConfig(sourcePath, languages) {
268
+ return {
269
+ $schema: SCHEMA_PATH,
270
+ '// how-to': HOW_TO,
271
+ commands: DEFAULT_COMMANDS,
272
+ '// reporting': REPORTING_HINT,
273
+ sourcePath,
274
+ // Which checks can stop a merge — named, but NOT written as values.
275
+ //
276
+ // Writing `"Workflow Security": "error"` reads like a statement of the
277
+ // default and is not one: the map promotes as well as demotes, so an entry
278
+ // of "error" turns that check's ADVISORY findings into failures too. On a
279
+ // real client repository that flipped 54 warnings into a red build. The
280
+ // names belong in a comment; the map stays empty until the client means
281
+ // something by it.
282
+ '// severity': [
283
+ `These checks fail a run by default: ${BLOCKING_BY_DEFAULT.join(', ')}.`,
284
+ 'To stand one down, add it below with "warn" (stays in the report, stops',
285
+ 'blocking) or "off" (does not run at all).',
286
+ 'Adding a check with "error" is not a restatement of the default — it also',
287
+ "PROMOTES that check's advisory findings to failures, which is stricter.",
288
+ ].join(' '),
289
+ severity: {},
290
+ // The knobs people reach for first.
291
+ //
292
+ // Two shapes appear here, and the difference is not cosmetic. A list whose
293
+ // values are APPENDED to the defaults is seeded empty: empty changes nothing,
294
+ // so it cannot freeze today's default in someone else's repository. A list
295
+ // that REPLACES its default is written out in full instead — seeded empty it
296
+ // would silently switch the default off, and left out entirely it would be
297
+ // invisible, which is how a repository ends up spellchecking its own
298
+ // CHANGELOG and reporting every test fixture as duplication.
299
+ //
300
+ // Written-out lists are a deliberate trade: they stop tracking the package,
301
+ // so a later release that adds a directory to the defaults will not reach a
302
+ // config that already spells the list out. That is the price of being able
303
+ // to see and edit the value, and it is the one people asked for.
304
+ excludePaths: [],
305
+ // REPLACES the default. Copied out so the list is editable in place —
306
+ // note that ESLint does not read it; ESLint honours `eslint.ignorePatterns`.
307
+ ignoreDirs: [...IGNORED_DIRS],
308
+ // Spelling: `words` and `ignorePaths` are both APPENDED to the bundled lists,
309
+ // so both stay empty. What the bundled list already skips is spelled out in
310
+ // the sibling comment rather than duplicated here.
311
+ '// cspell': `Already skipped by default: ${GENERATED_DOC_FILES.join(', ')}, test and mock paths, lockfiles, minified bundles, and every directory in "ignoreDirs". Anything listed below is ADDED to that.`,
312
+ cspell: { words: [], ignorePaths: [] },
313
+ // `max-len` is written out at its default rather than left implicit: it is
314
+ // the rule people hit first and tune first, and a line limit is a house
315
+ // style, not a defect — arguing with it through documentation wastes
316
+ // everyone's time when the number could just be sitting here, editable.
317
+ eslint: { rules: { 'max-len': ['warn', { code: 300 }] }, ignorePatterns: [] },
318
+ markdownlint: { ignores: [] },
319
+ dependency: { ignore: [] },
320
+ circularDeps: { ignore: [] },
321
+ yamlLint: { ignore: [] },
322
+ // The three lists that REPLACE their defaults, written out. Each one exists
323
+ // because test code trips a check that production code does not: suites
324
+ // repeat their setup, the runner is the only consumer of what they export,
325
+ // and a security test's whole job may be to call the dangerous function.
326
+ // Delete an entry to have that check start reporting on tests again.
327
+ duplicate: { ignore: [...DUPLICATE_IGNORE_DEFAULTS] },
328
+ deadCode: { ignoreFiles: [...DEAD_CODE_IGNORE_DEFAULTS] },
329
+ // `dataflowWindow` is written out at its default for the same reason as
330
+ // `max-len`: it is a number people will want to change, and a number nobody
331
+ // can see is a number nobody can change. It is also the one finding in this
332
+ // check produced by a heuristic rather than a pattern, so the caveat belongs
333
+ // next to the value — including the part that surprises people, which is what
334
+ // promoting the whole check to `error` does to it.
335
+ '// diffSecurity': [
336
+ '"ignorePaths" REPLACES the test-path defaults below — they are there because a security',
337
+ "test's job is to contain the exact constructs this check hunts for.",
338
+ '"dataflowWindow" is how many added lines a value stays tainted for, so an interpolated',
339
+ 'string assigned on one line and passed to a query on the next are still connected.',
340
+ 'It is a heuristic — no scopes, no reassignment tracking — so it only ever warns.',
341
+ 'Set it to 0 to switch it off. Note that "severity": { "Diff Security": "error" } promotes',
342
+ 'this warning to a failure along with the rest, so a repository that makes this check a',
343
+ 'gate and does not want the heuristic blocking should set dataflowWindow to 0.',
344
+ ].join(' '),
345
+ diffSecurity: {
346
+ dataflowWindow: DEFAULT_DATAFLOW_WINDOW,
347
+ ignorePaths: [...DIFF_SECURITY_IGNORE_DEFAULTS],
348
+ },
349
+ documentation,
350
+ languages,
351
+ };
352
+ }
353
+ /** First-run setup: prompt, write config, and scaffold workflow + tsconfig. */
354
+ async function createConfig(root) {
355
+ const sourcePath = await promptSourcePath();
356
+ const gateMode = await promptGateMode();
357
+ const languages = await detectLanguages(root);
358
+ logger.info(`[init]: 🔍 Detected languages: ${languages.length ? languages.join(', ') : 'none'}`);
359
+ const config = buildInitialConfig(sourcePath, languages);
360
+ fs.writeFileSync(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\n`);
361
+ logger.info(`[init]: ✅ Created pr-checkmate.json with sourcePath: ${sourcePath}`);
362
+ logger.info(`[init]: 💡 You can now customize ESLint rules, Prettier settings,
363
+ and cspell words in pr-checkmate.json`);
364
+ setupWorkflow(root, gateMode);
365
+ setupTsConfig(root, sourcePath);
366
+ }
367
+ /**
368
+ * Re-run setup: refresh the detected languages and leave everything else alone.
369
+ *
370
+ * It used to merge current defaults into the client's file, which is why the
371
+ * update notice insisted `init` must not be skipped after an upgrade. Defaults
372
+ * now apply when the config is loaded, so there is nothing to top up.
373
+ */
374
+ async function updateConfig(root) {
375
+ logger.info('[init]: pr-checkmate.json already exists — updating it.');
376
+ try {
377
+ const raw = fs.readFileSync(CONFIG_FILE, 'utf-8');
378
+ const json = JSON.parse(raw);
379
+ // Re-detection has to obey the config it is about to rewrite: a client who
380
+ // tuned `detect` (or `ignoreDirs`) precisely because detection was wrong
381
+ // would otherwise get the wrong answer written back over the right one on
382
+ // the next `init`.
383
+ const languages = await detectLanguages(root, json.ignoreDirs, json.detect);
384
+ logger.info(`[init]: 🔍 Detected languages: ${languages.length ? languages.join(', ') : 'none'}`);
385
+ // The client's file is left exactly as they wrote it. Defaults are no longer
386
+ // copied into it, because they never needed to be: they are merged in when
387
+ // the config is loaded, so a new default reaches every repository on upgrade
388
+ // without anyone editing anything. Writing them here only grew the file and
389
+ // made `init` a step nobody could safely skip after a release.
390
+ //
391
+ // `languages` is still refreshed — it is a fact about the repository, not a
392
+ // preference. `$schema` and the how-to hint are added when missing, because
393
+ // an existing config is exactly the case where nobody has seen them: the
394
+ // people who most need to know how to switch a check off are the ones whose
395
+ // file predates the advice.
396
+ const updated = {
397
+ $schema: json.$schema ?? SCHEMA_PATH,
398
+ '// how-to': json['// how-to'] ?? HOW_TO,
399
+ ...json,
400
+ languages,
401
+ };
402
+ fs.writeFileSync(CONFIG_FILE, `${JSON.stringify(updated, null, 2)}\n`);
403
+ logger.info('[init]: 🔧 Refreshed the detected languages in pr-checkmate.json.');
404
+ logger.info(`[init]: 💡 Everything else is left as you wrote it — defaults apply on their own. Options: ${DOCS_URL}`);
405
+ }
406
+ catch (e) {
407
+ logger.error(`[init]: ❌ Failed to update pr-checkmate.json: ${e}`);
408
+ }
409
+ }
410
+ /**
411
+ * Initialize (or refresh) pr-checkmate configuration in the current project.
412
+ */
413
+ export async function init() {
414
+ const root = process.cwd();
415
+ if (fs.existsSync(CONFIG_FILE)) {
416
+ await updateConfig(root);
417
+ }
418
+ else {
419
+ await createConfig(root);
420
+ }
421
+ }