pr-checkmate 1.23.24 → 2.0.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 (98) hide show
  1. package/README.md +61 -11
  2. package/cspell.json +3 -8
  3. package/dist/cli.js +37 -64
  4. package/dist/config/constants.d.ts +21 -3
  5. package/dist/config/constants.js +33 -6
  6. package/dist/config/pr-checkmate-workflow.yml +33 -327
  7. package/dist/core/checks/dependencies/banned-imports.js +23 -24
  8. package/dist/core/checks/dependencies/circular-deps.js +1 -0
  9. package/dist/core/checks/dependencies/dependency-check.js +1 -0
  10. package/dist/core/checks/dependencies/grype-scan.js +1 -0
  11. package/dist/core/checks/dependencies/npm-audit.js +6 -1
  12. package/dist/core/checks/dependencies/vuln-scan.js +1 -0
  13. package/dist/core/checks/findings.d.ts +198 -19
  14. package/dist/core/checks/findings.js +474 -22
  15. package/dist/core/checks/git/custom-rules.js +21 -16
  16. package/dist/core/checks/git/diff-smell.d.ts +17 -0
  17. package/dist/core/checks/git/diff-smell.js +43 -24
  18. package/dist/core/checks/git/large-files.js +14 -2
  19. package/dist/core/checks/git/leftover-debug.js +23 -14
  20. package/dist/core/checks/git/lockfile-drift.js +2 -1
  21. package/dist/core/checks/git/merge-conflict.js +19 -8
  22. package/dist/core/checks/git/missing-tests.js +22 -6
  23. package/dist/core/checks/git/todo-fixme.js +10 -9
  24. package/dist/core/checks/languages/shellcheck.d.ts +1 -1
  25. package/dist/core/checks/languages/shellcheck.js +1 -1
  26. package/dist/core/checks/languages/typecheck.js +1 -0
  27. package/dist/core/checks/pr/pr-size-check.js +2 -1
  28. package/dist/core/checks/quality/config-validation.d.ts +14 -4
  29. package/dist/core/checks/quality/config-validation.js +119 -17
  30. package/dist/core/checks/quality/dead-code.js +1 -0
  31. package/dist/core/checks/quality/duplicate-check.js +1 -0
  32. package/dist/core/checks/quality/license-header.js +12 -2
  33. package/dist/core/checks/quality/spellcheck.d.ts +50 -0
  34. package/dist/core/checks/quality/spellcheck.js +141 -13
  35. package/dist/core/checks/quality/yaml-lint.js +22 -9
  36. package/dist/core/checks/security/diff-security.js +111 -28
  37. package/dist/core/checks/security/dockerfile-security.js +23 -20
  38. package/dist/core/checks/security/migration-safety.js +19 -17
  39. package/dist/core/checks/security/sensitive-file-guard.js +37 -5
  40. package/dist/core/checks/security/workflow-security.d.ts +10 -0
  41. package/dist/core/checks/security/workflow-security.js +48 -26
  42. package/dist/core/commands.d.ts +27 -0
  43. package/dist/core/commands.js +91 -0
  44. package/dist/core/context.d.ts +12 -3
  45. package/dist/core/context.js +118 -16
  46. package/dist/core/install/cache.d.ts +39 -0
  47. package/dist/core/install/cache.js +99 -0
  48. package/dist/core/install/doctor.d.ts +35 -0
  49. package/dist/core/install/doctor.js +145 -0
  50. package/dist/core/install/ensure.d.ts +60 -0
  51. package/dist/core/install/ensure.js +169 -0
  52. package/dist/core/install/lock.d.ts +33 -0
  53. package/dist/core/install/lock.js +99 -0
  54. package/dist/core/install/profiles.d.ts +64 -0
  55. package/dist/core/install/profiles.js +170 -0
  56. package/dist/core/reporters.d.ts +13 -2
  57. package/dist/core/reporters.js +145 -104
  58. package/dist/core/run-checks.js +91 -14
  59. package/dist/core/targets.js +26 -4
  60. package/dist/core/types.d.ts +49 -1
  61. package/dist/init.d.ts +29 -14
  62. package/dist/init.js +204 -262
  63. package/dist/interfaces/index.d.ts +120 -0
  64. package/dist/scripts/generate-install-manifests.d.ts +39 -0
  65. package/dist/scripts/generate-install-manifests.js +121 -0
  66. package/dist/scripts/publish-github.js +18 -4
  67. package/dist/utils/detect-language.d.ts +37 -4
  68. package/dist/utils/detect-language.js +113 -19
  69. package/dist/utils/http.d.ts +59 -0
  70. package/dist/utils/http.js +119 -0
  71. package/dist/utils/logger.d.ts +52 -6
  72. package/dist/utils/logger.js +125 -33
  73. package/dist/utils/pool.d.ts +49 -0
  74. package/dist/utils/pool.js +124 -0
  75. package/dist/utils/update-notifier.d.ts +9 -0
  76. package/dist/utils/update-notifier.js +57 -3
  77. package/eslint.config.mjs +14 -2
  78. package/install-manifests/commitlint/package-lock.json +1028 -0
  79. package/install-manifests/commitlint/package.json +9 -0
  80. package/install-manifests/core/package-lock.json +1335 -0
  81. package/install-manifests/core/package.json +11 -0
  82. package/install-manifests/cpp/package-lock.json +29 -0
  83. package/install-manifests/cpp/package.json +8 -0
  84. package/install-manifests/duplicate/package-lock.json +113 -0
  85. package/install-manifests/duplicate/package.json +8 -0
  86. package/install-manifests/js/package-lock.json +5099 -0
  87. package/install-manifests/js/package.json +26 -0
  88. package/install-manifests/markdown/package-lock.json +1281 -0
  89. package/install-manifests/markdown/package.json +8 -0
  90. package/install-manifests/python/package-lock.json +21 -0
  91. package/install-manifests/python/package.json +8 -0
  92. package/install-manifests/spellcheck/package-lock.json +1047 -0
  93. package/install-manifests/spellcheck/package.json +8 -0
  94. package/package.json +13 -28
  95. package/pr-checkmate.schema.json +1062 -104
  96. package/src/config/cspell.json +3 -8
  97. package/src/config/pr-checkmate-workflow.yml +33 -327
  98. package/src/config/pr-checkmate.schema.json +1062 -104
package/README.md CHANGED
@@ -153,8 +153,9 @@ installed version.
153
153
 
154
154
  ## GitHub Actions
155
155
 
156
- Every workflow follows the same shape: checkout, set up Node, install, run. The
157
- TypeScript setup is the baseline:
156
+ `init` generates this workflow; it is reproduced here so nothing about it is a
157
+ surprise. One job runs the whole registry — which checks run is decided in
158
+ `pr-checkmate.json`, not by copying YAML.
158
159
 
159
160
  ```yaml
160
161
  name: PR CheckMate
@@ -163,21 +164,57 @@ on:
163
164
  branches: [main]
164
165
 
165
166
  permissions:
166
- contents: write
167
+ contents: read
167
168
  pull-requests: write
168
169
 
169
170
  jobs:
170
- quality:
171
+ pr-checkmate:
171
172
  runs-on: ubuntu-latest
172
173
  steps:
173
- - uses: actions/checkout@v4
174
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
174
175
  with: { fetch-depth: 0 }
175
- - uses: actions/setup-node@v4
176
- with: { node-version: 24 }
176
+ - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
177
+ with: { node-version: 24, cache: 'npm' }
177
178
  - run: npm ci
178
- - run: npx pr-checkmate all
179
+ - name: Run PR CheckMate
180
+ env:
181
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
182
+ run: npx pr-checkmate all
179
183
  ```
180
184
 
185
+ Three lines are load-bearing:
186
+
187
+ - `fetch-depth: 0` — without the full history the PR base is not in the clone, no
188
+ diff range can be built, and every diff-based check skips itself. The run says so
189
+ (`Scan Scope: … set fetch-depth: 0`) rather than reporting a clean pass.
190
+ - `GITHUB_TOKEN` — Actions does not put it in the environment on its own. Without it
191
+ the checks still run, but the summary comment never reaches the PR.
192
+ - no `continue-on-error` — a gate that cannot fail the job is not a gate.
193
+
194
+ ### Adopting it on an existing codebase
195
+
196
+ The instinct on an existing codebase is to soften the workflow. Do the opposite: keep
197
+ the gate real and relax individual checks in `pr-checkmate.json`, so whatever you have
198
+ already made clean stays enforced.
199
+
200
+ ```jsonc
201
+ {
202
+ // everything advisory to begin with…
203
+ "severityDefaults": { "failOn": "warn" },
204
+ // …except the ones you are ready to enforce
205
+ "severity": {
206
+ "Security Scan": "error",
207
+ "Diff Security": "error",
208
+ "Duplicate Code": "off"
209
+ }
210
+ }
211
+ ```
212
+
213
+ Promote checks one at a time as the codebase catches up. `pr-checkmate init` also
214
+ offers an advisory workflow if you would rather start there, and it writes a banner
215
+ explaining how to leave that mode. Either way, `init` never overwrites a workflow file
216
+ that already exists.
217
+
181
218
  For a runner-dependency language, add its toolchain setup step before the run: Go with
182
219
  `actions/setup-go`, Rust with `dtolnay/rust-toolchain`, C# with `actions/setup-dotnet`,
183
220
  Ruby with `ruby/setup-ruby` (plus `gem install rubocop`), PHP with
@@ -209,8 +246,21 @@ covering when it runs, the config keys it reads, and how to turn it off.
209
246
 
210
247
  ## Configuration
211
248
 
212
- Everything lives in `pr-checkmate.json`. Run `npx pr-checkmate init` to scaffold the
213
- full file for your detected languages.
249
+ Everything lives in one file, `pr-checkmate.json`. Run `npx pr-checkmate init` to
250
+ scaffold it for your detected languages.
251
+
252
+ The generated file is short on purpose: it holds your decisions plus a few empty
253
+ blocks for the settings people tune most. Everything else stays implicit — the
254
+ config is merged over the built-in defaults at load time, so new defaults reach
255
+ you on upgrade without editing anything, and `init` is a first-run step rather
256
+ than something to repeat after every release.
257
+
258
+ **[The full configuration, annotated, with every option at its default →](https://github.com/Mybono/pr_checkmate_public/blob/main/pr-checkmate.json)**
259
+ Copy the block you need into your file. The `$schema` line in the generated
260
+ config also gives your editor autocomplete and a description for every key.
261
+
262
+ Three settings REPLACE their default rather than extending it, so copy the
263
+ default before editing: `ignoreDirs`, `duplicate.ignore`, `deadCode.ignoreFiles`.
214
264
 
215
265
  - Severity map. The one universal control. Key any check by its display name (as it
216
266
  appears in the report) and set `"error"` to fail the run, `"warn"` for advisory, or
@@ -272,4 +322,4 @@ affect it.
272
322
 
273
323
  LicenseRef Proprietary © 2025-2026 Artur Polishchuk. Free to install and run via the
274
324
  published npm package (see [LICENSE](LICENSE) for the exact grant); the source is not
275
- open-source and is not licensed for copying, modification, or redistribution.
325
+ open-source and is not licensed for copying, modification, or redistribution.
package/cspell.json CHANGED
@@ -1,13 +1,6 @@
1
1
  {
2
2
  "version": "0.2",
3
- "language": "en,ru,uk,he,fr,es",
4
- "import": [
5
- "@cspell/dict-ru_ru/cspell-ext.json",
6
- "@cspell/dict-uk-ua/cspell-ext.json",
7
- "@cspell/dict-he/cspell-ext.json",
8
- "@cspell/dict-fr-fr/cspell-ext.json",
9
- "@cspell/dict-es-es/cspell-ext.json"
10
- ],
3
+ "language": "en,en-GB",
11
4
  "words": [
12
5
  "absdiff",
13
6
  "abspath",
@@ -467,6 +460,7 @@
467
460
  "eficiente",
468
461
  "eigen",
469
462
  "EIGEN",
463
+ "EINTEGRITY",
470
464
  "EKNFFL",
471
465
  "elbert",
472
466
  "elementwise",
@@ -1057,6 +1051,7 @@
1057
1051
  "oaep",
1058
1052
  "Obagi",
1059
1053
  "objdetect",
1054
+ "Octo",
1060
1055
  "octocat",
1061
1056
  "ohlc",
1062
1057
  "ohlcv",
package/dist/cli.js CHANGED
@@ -2,66 +2,10 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const core_1 = require("./core");
5
+ const commands_1 = require("./core/commands");
6
+ const doctor_1 = require("./core/install/doctor");
5
7
  const init_1 = require("./init");
6
8
  const utils_1 = require("./utils");
7
- /** Maps short CLI command names to their registry check names. */
8
- const COMMAND_TO_CHECK = {
9
- lint: 'ESLint',
10
- deps: 'Dependencies',
11
- dependencies: 'Dependencies',
12
- 'npm-audit': 'NPM Audit',
13
- prettier: 'Prettier',
14
- spellcheck: 'Spellcheck',
15
- security: 'Security Scan',
16
- circular: 'Circular Deps',
17
- license: 'License Check',
18
- 'pr-size': 'PR Size',
19
- 'pr-title': 'PR Title',
20
- outdated: 'Outdated Deps',
21
- markdown: 'Markdown',
22
- 'yaml-lint': 'YAML Lint',
23
- symlinks: 'Broken Symlinks',
24
- shellcheck: 'ShellCheck',
25
- typecheck: 'TypeScript',
26
- 'diff-smell': 'Diff Smells',
27
- 'diff-security': 'Diff Security',
28
- 'workflow-security': 'Workflow Security',
29
- 'custom-rules': 'Custom Rules',
30
- 'banned-imports': 'Banned Imports',
31
- 'license-header': 'License Header',
32
- 'config-validation': 'Config Validation',
33
- 'dockerfile-security': 'Dockerfile Security',
34
- 'case-collision': 'Case Collision',
35
- 'vuln-scan': 'Vuln Scan',
36
- 'leftover-debug': 'Leftover Debug',
37
- 'lockfile-drift': 'Lockfile Drift',
38
- 'large-files': 'Large Files',
39
- 'todo-fixme': 'TODO/FIXME',
40
- 'missing-tests': 'Missing Tests',
41
- coverage: 'Coverage',
42
- 'migration-safety': 'Migration Safety',
43
- 'sensitive-files': 'Sensitive Files',
44
- 'pr-body': 'PR Body',
45
- duplicate: 'Duplicate Code',
46
- commitlint: 'Commitlint',
47
- 'cpp-format': 'C++ Format',
48
- 'python-lint': 'Ruff Lint',
49
- 'python-format': 'Ruff Format',
50
- 'python-typecheck': 'Python Types',
51
- 'go-lint': 'Go Vet',
52
- 'go-format': 'Go Format',
53
- 'rust-lint': 'Clippy',
54
- 'rust-format': 'Rustfmt',
55
- 'csharp-format': 'C# Format',
56
- 'ruby-lint': 'RuboCop',
57
- 'php-format': 'PHP CS Fixer',
58
- };
59
- /** Commands that run the whole pipeline (or no pipeline at all) and take no siblings. */
60
- const STANDALONE_COMMANDS = ['init', 'all', 'precommit'];
61
- /** Flags accepted anywhere on the command line, with what each one means. */
62
- const FLAGS = {
63
- '--full': 'review every tracked file instead of the diff (the default outside CI)',
64
- };
65
9
  const argv = process.argv.slice(2);
66
10
  /**
67
11
  * Flags are separated from positional arguments so they compose with every command
@@ -77,10 +21,10 @@ const cmd = args[0];
77
21
  * diff and print a green summary.
78
22
  */
79
23
  function rejectUnknownFlags() {
80
- const unknown = flags.filter(flag => !FLAGS[flag]);
24
+ const unknown = flags.filter(flag => !commands_1.FLAGS[flag]);
81
25
  if (unknown.length === 0)
82
26
  return;
83
- const known = Object.entries(FLAGS)
27
+ const known = Object.entries(commands_1.FLAGS)
84
28
  .map(([flag, help]) => `${flag} (${help})`)
85
29
  .join(', ');
86
30
  utils_1.logger.error(`[cli]: Unknown flag(s) "${unknown.join('", "')}". Available: ${known}`);
@@ -101,6 +45,17 @@ function rejectConflictingScope() {
101
45
  utils_1.logger.error(`[cli]: "init" takes no flags, got: ${flags.join(', ')}.`);
102
46
  process.exit(1);
103
47
  }
48
+ // `--all` belongs to `install` alone. Accepting it elsewhere would look like a
49
+ // scope flag and quietly do nothing, which is the failure mode
50
+ // `rejectUnknownFlags` exists to prevent.
51
+ if (flags.includes('--all') && cmd !== 'install') {
52
+ utils_1.logger.error('[cli]: "--all" applies only to "install". Did you mean "--full"?');
53
+ process.exit(1);
54
+ }
55
+ if (flags.includes('--full') && commands_1.TOOLING_COMMANDS.includes(cmd ?? '')) {
56
+ utils_1.logger.error(`[cli]: "${cmd}" manages tooling and reviews nothing, so "--full" has no meaning.`);
57
+ process.exit(1);
58
+ }
104
59
  }
105
60
  const full = flags.includes('--full');
106
61
  /**
@@ -113,7 +68,7 @@ const full = flags.includes('--full');
113
68
  * added to the list but not to the branch.
114
69
  */
115
70
  function rejectExtraArgs() {
116
- if (!cmd || !STANDALONE_COMMANDS.includes(cmd) || args.length <= 1)
71
+ if (!cmd || !commands_1.STANDALONE_COMMANDS.includes(cmd) || args.length <= 1)
117
72
  return;
118
73
  utils_1.logger.error(`[cli]: "${cmd}" takes no other arguments, got: ${args.slice(1).join(', ')}. Run them as a separate command.`);
119
74
  process.exit(1);
@@ -127,6 +82,24 @@ void (async () => {
127
82
  await (0, init_1.init)();
128
83
  process.exit(0);
129
84
  }
85
+ // Tooling management. These run no checks — they prepare, inspect or clean
86
+ // up what the checks need, so they never touch the diff or the reporter.
87
+ if (cmd === 'install') {
88
+ const results = await (0, doctor_1.installProfiles)(process.cwd(), flags.includes('--all'));
89
+ const failed = results.filter(r => r.status === 'failed');
90
+ for (const result of failed) {
91
+ utils_1.logger.error(`[install]: ❌ ${result.profile}: ${result.reason}`);
92
+ }
93
+ process.exit(failed.length > 0 ? 1 : 0);
94
+ }
95
+ if (cmd === 'doctor') {
96
+ await (0, doctor_1.runDoctor)();
97
+ process.exit(0);
98
+ }
99
+ if (cmd === 'cache-prune') {
100
+ (0, doctor_1.pruneCache)();
101
+ process.exit(0);
102
+ }
130
103
  // Full run: auto-detect the CI platform (GitHub/GitLab/Bitbucket), post the
131
104
  // summary to its PR/MR, and allow formatters to write.
132
105
  if (!cmd || cmd === 'all') {
@@ -150,12 +123,12 @@ void (async () => {
150
123
  // Every remaining argument is a check name, so `pr-checkmate lint spellcheck`
151
124
  // runs both in one pass. Unknown names abort the whole run — a typo must never
152
125
  // shrink the requested check set silently.
153
- const unknown = args.filter(arg => !COMMAND_TO_CHECK[arg]);
126
+ const unknown = args.filter(arg => !commands_1.COMMAND_TO_CHECK[arg]);
154
127
  if (unknown.length > 0) {
155
- utils_1.logger.error(`[cli]: Unknown command(s) "${unknown.join('", "')}". Available: ${STANDALONE_COMMANDS.join(', ')}, ${Object.keys(COMMAND_TO_CHECK).join(', ')}`);
128
+ utils_1.logger.error(`[cli]: Unknown command(s) "${unknown.join('", "')}". Available: ${commands_1.STANDALONE_COMMANDS.join(', ')}, ${Object.keys(commands_1.COMMAND_TO_CHECK).join(', ')}`);
156
129
  process.exit(1);
157
130
  }
158
- const checkNames = [...new Set(args.map(arg => COMMAND_TO_CHECK[arg]))];
131
+ const checkNames = [...new Set(args.map(arg => commands_1.COMMAND_TO_CHECK[arg]))];
159
132
  const report = await (0, core_1.runChecks)({ only: checkNames, reporter: 'stdout', write: true, full });
160
133
  process.exit(report.ok ? 0 : 1);
161
134
  }
@@ -70,12 +70,30 @@ export declare const DEFAULT_COMMANDS: {
70
70
  /**
71
71
  * Packages allow-listed for the license check by default.
72
72
  *
73
- * These are pr-checkmate's own bundled cspell dictionaries. Some ship under
74
- * copyleft licenses (GPL/LGPL), but they are pr-checkmate dependencies — not
75
- * the consumer's — so clients should never have to allow-list them manually.
73
+ * These are the optional cspell language dictionaries. Some ship under copyleft
74
+ * licenses (GPL/LGPL), and a client who installs one to spellcheck their own
75
+ * language should not have that turn into a licence finding: the dictionary is
76
+ * data for our check, not code they ship.
76
77
  */
77
78
  export declare const DEFAULT_ALLOW_PACKAGES: string[];
79
+ /**
80
+ * Canonical entry point to the PR CheckMate docs. Single source of truth: it is
81
+ * written into every generated `pr-checkmate.json` (via {@link documentation})
82
+ * and printed in the "new version available" notice, so the two can never drift.
83
+ */
84
+ export declare const DOCS_URL = "https://github.com/Mybono/pr_checkmate_public/tree/main/documentation";
85
+ /**
86
+ * The fully annotated configuration, with every option at its default value.
87
+ *
88
+ * A URL rather than a file inside the package on purpose: half the audience runs
89
+ * pr-checkmate through `npx` on a pipeline and has no `node_modules` at all, so
90
+ * a path into the installed package is a dead end for them. The release workflow
91
+ * publishes `src/config/pr-checkmate.template.json` to the public mirror under
92
+ * this name, which keeps one copy for everyone.
93
+ */
94
+ export declare const FULL_CONFIG_URL = "https://github.com/Mybono/pr_checkmate_public/blob/main/pr-checkmate.json";
78
95
  export declare const documentation: {
96
+ pr_checkmate: string;
79
97
  eslint: string;
80
98
  typescriptEslint: string;
81
99
  prettier: string;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.KNOWN_CONFIG_KEYS = exports.CONFIG_FILE = exports.documentation = exports.DEFAULT_ALLOW_PACKAGES = exports.DEFAULT_COMMANDS = exports.SOURCE_EXTENSIONS = exports.DUPLICATE_CODE_FORMATS = exports.CONFIG_FILE_PATTERNS = exports.DEAD_CODE_IGNORE_DEFAULTS = exports.DUPLICATE_IGNORE_DEFAULTS = exports.IGNORE_PATTERNS = exports.IGNORED_DIRS = void 0;
6
+ exports.KNOWN_CONFIG_KEYS = exports.CONFIG_FILE = exports.documentation = exports.FULL_CONFIG_URL = exports.DOCS_URL = exports.DEFAULT_ALLOW_PACKAGES = exports.DEFAULT_COMMANDS = exports.SOURCE_EXTENSIONS = exports.DUPLICATE_CODE_FORMATS = exports.CONFIG_FILE_PATTERNS = exports.DEAD_CODE_IGNORE_DEFAULTS = exports.DUPLICATE_IGNORE_DEFAULTS = exports.IGNORE_PATTERNS = exports.IGNORED_DIRS = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  /**
9
9
  * Build output, dependency, tooling, and report directories that are never
@@ -180,8 +180,8 @@ exports.SOURCE_EXTENSIONS = {
180
180
  all: ['.ts', '.tsx', '.js', '.jsx', '.json', '.md', '.mdx'],
181
181
  };
182
182
  exports.DEFAULT_COMMANDS = {
183
- 'npx pr-checkmate init': 'Update pr-checkmate.json',
184
- 'npx pr-checkmate all': 'Run all checks (the PR diff in CI, every tracked file locally)',
183
+ 'npx pr-checkmate init': 'Create pr-checkmate.json and the CI workflow (first-run setup)',
184
+ 'npx pr-checkmate all': 'Run all checks over the changes — the PR diff in CI, your branch changes locally',
185
185
  'npx pr-checkmate all --full': 'Run all checks over every tracked file, CI included',
186
186
  'npx pr-checkmate lint': 'Lint code using ESLint',
187
187
  'npx pr-checkmate prettier': 'Format code using Prettier',
@@ -197,9 +197,10 @@ exports.DEFAULT_COMMANDS = {
197
197
  /**
198
198
  * Packages allow-listed for the license check by default.
199
199
  *
200
- * These are pr-checkmate's own bundled cspell dictionaries. Some ship under
201
- * copyleft licenses (GPL/LGPL), but they are pr-checkmate dependencies — not
202
- * the consumer's — so clients should never have to allow-list them manually.
200
+ * These are the optional cspell language dictionaries. Some ship under copyleft
201
+ * licenses (GPL/LGPL), and a client who installs one to spellcheck their own
202
+ * language should not have that turn into a licence finding: the dictionary is
203
+ * data for our check, not code they ship.
203
204
  */
204
205
  exports.DEFAULT_ALLOW_PACKAGES = [
205
206
  '@cspell/dict-es-es',
@@ -208,7 +209,24 @@ exports.DEFAULT_ALLOW_PACKAGES = [
208
209
  '@cspell/dict-ru_ru',
209
210
  '@cspell/dict-uk-ua',
210
211
  ];
212
+ /**
213
+ * Canonical entry point to the PR CheckMate docs. Single source of truth: it is
214
+ * written into every generated `pr-checkmate.json` (via {@link documentation})
215
+ * and printed in the "new version available" notice, so the two can never drift.
216
+ */
217
+ exports.DOCS_URL = 'https://github.com/Mybono/pr_checkmate_public/tree/main/documentation';
218
+ /**
219
+ * The fully annotated configuration, with every option at its default value.
220
+ *
221
+ * A URL rather than a file inside the package on purpose: half the audience runs
222
+ * pr-checkmate through `npx` on a pipeline and has no `node_modules` at all, so
223
+ * a path into the installed package is a dead end for them. The release workflow
224
+ * publishes `src/config/pr-checkmate.template.json` to the public mirror under
225
+ * this name, which keeps one copy for everyone.
226
+ */
227
+ exports.FULL_CONFIG_URL = 'https://github.com/Mybono/pr_checkmate_public/blob/main/pr-checkmate.json';
211
228
  exports.documentation = {
229
+ pr_checkmate: exports.DOCS_URL,
212
230
  eslint: 'https://eslint.org/docs/latest/rules/',
213
231
  typescriptEslint: 'https://typescript-eslint.io/rules/',
214
232
  prettier: 'https://prettier.io/docs/en/options.html',
@@ -227,8 +245,15 @@ exports.KNOWN_CONFIG_KEYS = new Set([
227
245
  // core
228
246
  'sourcePath',
229
247
  'ignoreDirs',
248
+ 'excludePaths',
230
249
  'languages',
250
+ 'detect',
251
+ 'install',
231
252
  'severity',
253
+ 'severityDefaults',
254
+ 'run',
255
+ 'reporter',
256
+ 'log',
232
257
  'customRules',
233
258
  '$schema',
234
259
  'commands',
@@ -242,6 +267,8 @@ exports.KNOWN_CONFIG_KEYS = new Set([
242
267
  'cspell',
243
268
  'markdownlint',
244
269
  'yamlLint',
270
+ 'shellcheck',
271
+ 'symlinks',
245
272
  'typecheck',
246
273
  // security
247
274
  'security',