pr-checkmate 1.22.0 → 1.22.2

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 (57) hide show
  1. package/README.md +0 -2
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/config/config.d.ts +2 -0
  4. package/dist/config/constants.d.ts +44 -0
  5. package/dist/config/index.d.ts +23 -0
  6. package/dist/config/loader.d.ts +14 -0
  7. package/dist/core/checks/circular-deps.d.ts +2 -0
  8. package/dist/core/checks/commitlint.d.ts +2 -0
  9. package/dist/core/checks/cpp-format.d.ts +7 -0
  10. package/dist/core/checks/dead-code.d.ts +2 -0
  11. package/dist/core/checks/dependency-check.d.ts +2 -0
  12. package/dist/core/checks/diff-security.d.ts +2 -0
  13. package/dist/core/checks/diff-smell.d.ts +2 -0
  14. package/dist/core/checks/duplicate-check.d.ts +2 -0
  15. package/dist/core/checks/findings.d.ts +40 -0
  16. package/dist/core/checks/kotlin-lint.d.ts +2 -0
  17. package/dist/core/checks/license-check.d.ts +2 -0
  18. package/dist/core/checks/lint.d.ts +2 -0
  19. package/dist/core/checks/markdown-lint.d.ts +2 -0
  20. package/dist/core/checks/npm-audit.d.ts +6 -0
  21. package/dist/core/checks/outdated-deps.d.ts +2 -0
  22. package/dist/core/checks/pr-body.d.ts +2 -0
  23. package/dist/core/checks/pr-size-check.d.ts +2 -0
  24. package/dist/core/checks/pr-title-lint.d.ts +2 -0
  25. package/dist/core/checks/prettier.d.ts +2 -0
  26. package/dist/core/checks/python-format.d.ts +7 -0
  27. package/dist/core/checks/python-lint.d.ts +9 -0
  28. package/dist/core/checks/security.d.ts +7 -0
  29. package/dist/core/checks/sensitive-file-guard.d.ts +2 -0
  30. package/dist/core/checks/spellcheck.d.ts +2 -0
  31. package/dist/core/checks/swift-lint.d.ts +2 -0
  32. package/dist/core/checks/typecheck.d.ts +2 -0
  33. package/dist/core/checks/typecheck.js +9 -0
  34. package/dist/core/context.d.ts +6 -0
  35. package/dist/core/index.d.ts +4 -0
  36. package/dist/core/registry.d.ts +6 -0
  37. package/dist/core/reporters.d.ts +7 -0
  38. package/dist/core/run-checks.d.ts +9 -0
  39. package/dist/core/run-checks.js +31 -3
  40. package/dist/core/targets.d.ts +11 -0
  41. package/dist/core/types.d.ts +102 -0
  42. package/dist/core/types.js +7 -1
  43. package/dist/index.d.ts +9 -0
  44. package/dist/index.js +8 -1
  45. package/dist/init.d.ts +5 -0
  46. package/dist/init.js +5 -1
  47. package/dist/interfaces/index.d.ts +129 -0
  48. package/dist/scripts/copy-configs.d.ts +5 -0
  49. package/dist/scripts/publish-github.d.ts +1 -0
  50. package/dist/utils/delta.d.ts +5 -0
  51. package/dist/utils/detect-language.d.ts +10 -0
  52. package/dist/utils/index.d.ts +10 -0
  53. package/dist/utils/logger.d.ts +20 -0
  54. package/dist/utils/own-deps.d.ts +14 -0
  55. package/dist/utils/resolve-bin.d.ts +17 -0
  56. package/dist/utils/result-collector.d.ts +33 -0
  57. package/package.json +10 -2
package/README.md CHANGED
@@ -1,9 +1,7 @@
1
1
  # ♟️ PR CheckMate
2
2
 
3
3
  ![Build](https://img.shields.io/github/actions/workflow/status/Mybono/sdk_automation/publish.yml?branch=main&label=CI&color=blue)
4
- ![npm](https://img.shields.io/npm/v/pr-checkmate?color=blue&label=npm)
5
4
  ![License](https://img.shields.io/badge/license-Proprietary-lightgrey)
6
-
7
5
  ![ESLint](https://img.shields.io/badge/ESLint-10-4B32C3?logo=eslint&logoColor=white)
8
6
  ![Prettier](https://img.shields.io/badge/Prettier-3-F7B93E?logo=prettier&logoColor=white)
9
7
  ![TypeScript](https://img.shields.io/badge/TypeScript-6-3178C6?logo=typescript&logoColor=white)
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare const config: any;
2
+ export declare const SOURCE_PATH: any;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Common patterns to ignore in all checks
3
+ */
4
+ export declare const IGNORE_PATTERNS: string[];
5
+ export declare const CONFIG_FILE_PATTERNS: string[];
6
+ /**
7
+ * File extensions to check
8
+ */
9
+ export declare const SOURCE_EXTENSIONS: {
10
+ typescript: string[];
11
+ javascript: string[];
12
+ markdown: string[];
13
+ json: string[];
14
+ all: string[];
15
+ };
16
+ export declare const DEFAULT_COMMANDS: {
17
+ 'npx pr-checkmate init': string;
18
+ 'npx pr-checkmate all': string;
19
+ 'npx pr-checkmate lint': string;
20
+ 'npx pr-checkmate prettier': string;
21
+ 'npx pr-checkmate deps': string;
22
+ 'npx pr-checkmate npm-audit': string;
23
+ 'npx pr-checkmate security': string;
24
+ 'npx pr-checkmate spellcheck': string;
25
+ 'npx pr-checkmate typecheck': string;
26
+ 'npx pr-checkmate diff-smell': string;
27
+ 'npx pr-checkmate pr-body': string;
28
+ 'npx pr-checkmate duplicate': string;
29
+ };
30
+ /**
31
+ * Packages allow-listed for the license check by default.
32
+ *
33
+ * These are pr-checkmate's own bundled cspell dictionaries. Some ship under
34
+ * copyleft licenses (GPL/LGPL), but they are pr-checkmate dependencies — not
35
+ * the consumer's — so clients should never have to allow-list them manually.
36
+ */
37
+ export declare const DEFAULT_ALLOW_PACKAGES: string[];
38
+ export declare const documentation: {
39
+ eslint: string;
40
+ typescriptEslint: string;
41
+ prettier: string;
42
+ cspell: string;
43
+ };
44
+ export declare const CONFIG_FILE: string;
@@ -0,0 +1,23 @@
1
+ export * from './constants';
2
+ export { loadProjectConfig } from '../config/loader';
3
+ /**
4
+ * Get SOURCE_PATH dynamically
5
+ * This ensures fresh config is always read
6
+ */
7
+ export declare function getSourcePath(): string;
8
+ /**
9
+ * Get path to package config files
10
+ */
11
+ export declare function getPackageConfigPath(fileName: string): string;
12
+ /**
13
+ * Check if project has local config
14
+ */
15
+ export declare function hasLocalConfig(configNames: string[]): boolean;
16
+ /**
17
+ * For backward compatibility, also export as constant
18
+ * But this will be evaluated at module load time
19
+ */
20
+ export declare const config: {
21
+ sourcePath: string;
22
+ };
23
+ export declare const SOURCE_PATH: string;
@@ -0,0 +1,14 @@
1
+ import { PRCheckMateConfig } from '../interfaces';
2
+ /**
3
+ * Load project configuration from pr-checkmate.json
4
+ * Falls back to defaults if not found
5
+ */
6
+ export declare function loadProjectConfig(): PRCheckMateConfig;
7
+ /**
8
+ * Get default configuration
9
+ */
10
+ export declare function getDefaultConfig(): PRCheckMateConfig;
11
+ /**
12
+ * Export config for external use
13
+ */
14
+ export declare const DEFAULT_CONFIG: PRCheckMateConfig;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const circularDepsCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const commitlintCheck: Check;
@@ -0,0 +1,7 @@
1
+ import { Check } from '../types';
2
+ /**
3
+ * Formats C/C++ code with clang-format, bundled as a self-contained WASM CLI
4
+ * (`@wasm-fmt/clang-format`) so it runs on a bare Node image with no system
5
+ * clang install. Read-only in check mode; rewrites files in place when `write`.
6
+ */
7
+ export declare const cppFormatCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const deadCodeCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const dependencyCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const diffSecurityCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const diffSmellCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const duplicateCheck: Check;
@@ -0,0 +1,40 @@
1
+ import { CheckContext, CheckOutcome } from '../types';
2
+ /** Findings grouped by label → matching sample strings. */
3
+ export type FindingBucket = Record<string, string[]>;
4
+ /**
5
+ * Run `git diff` over the given file globs, returning the raw unified diff
6
+ * (zero context, added/copied/modified/renamed files) for added-line scanning.
7
+ */
8
+ export declare function diffAddedLines(ctx: CheckContext, globs: string[]): Promise<string>;
9
+ /** Total number of findings across all labels in a bucket. */
10
+ export declare function bucketTotal(bucket: FindingBucket): number;
11
+ interface LogOptions {
12
+ /** Log prefix, e.g. 'Diff Security'. */
13
+ prefix: string;
14
+ /** Use logger.error + ❌ instead of logger.warn + ⚠️. */
15
+ isError?: boolean;
16
+ /** Append ": N occurrence(s)" after the label (default true). */
17
+ showCount?: boolean;
18
+ /** Max samples printed per label; omit to print all. */
19
+ sampleLimit?: number;
20
+ }
21
+ /** Log one bucket of findings using the shared check format. */
22
+ export declare function logFindings(bucket: FindingBucket, opts: LogOptions): void;
23
+ interface SeverityReportOptions {
24
+ /** Log prefix, e.g. 'Diff Security'. */
25
+ prefix: string;
26
+ /** Summary phrasing given the error count. */
27
+ errorSummary: (n: number) => string;
28
+ /** Summary phrasing given the warning count. */
29
+ warningSummary: (n: number) => string;
30
+ /** Append ": N occurrence(s)" after each label (default true). */
31
+ showCount?: boolean;
32
+ /** Max samples printed per label; omit to print all. */
33
+ sampleLimit?: number;
34
+ }
35
+ /**
36
+ * Report error/warning finding buckets: log both, then produce the outcome.
37
+ * Returns pass() when both buckets are empty, otherwise warn() with a summary.
38
+ */
39
+ export declare function reportSeverityBuckets(errors: FindingBucket, warnings: FindingBucket, opts: SeverityReportOptions): CheckOutcome;
40
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const kotlinLintCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const licenseCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const lintCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const markdownLintCheck: Check;
@@ -0,0 +1,6 @@
1
+ import { Check } from '../types';
2
+ /**
3
+ * npm audit — only direct-dependency vulnerabilities block. Transitive ones and
4
+ * vulnerabilities in pr-checkmate itself are ignored (the client cannot fix those).
5
+ */
6
+ export declare const npmAuditCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const outdatedDepsCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const prBodyCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const prSizeCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const prTitleLintCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const prettierCheck: Check;
@@ -0,0 +1,7 @@
1
+ import { Check } from '../types';
2
+ /**
3
+ * Formats changed Python files with Ruff's formatter (WASM, no Python/pip needed).
4
+ * Read-only in check mode (`warn` when files differ from formatted output); rewrites
5
+ * files in place when `write` so CI can auto-commit — mirrors the Prettier/C++ checks.
6
+ */
7
+ export declare const pythonFormatCheck: Check;
@@ -0,0 +1,9 @@
1
+ import { Check } from '../types';
2
+ /**
3
+ * Lints changed Python files with Ruff, bundled as a self-contained WASM module
4
+ * (`@astral-sh/ruff-wasm-nodejs`) so it runs on a bare Node image with no Python
5
+ * or pip install. Informational by design — reports issues without failing the
6
+ * build, matching how formatting checks roll out; promote to blocking per repo
7
+ * once teams have adopted it. Uses Ruff's default rule set (pyflakes + pycodestyle).
8
+ */
9
+ export declare const pythonLintCheck: Check;
@@ -0,0 +1,7 @@
1
+ import { Check } from '../types';
2
+ /**
3
+ * Secret scanning via the bundled gitleaks package. Language-agnostic — runs on
4
+ * every repo (Node, Python, C++, mobile). Secrets found → fail (blocking).
5
+ * Tooling/infra errors → warn, so a scanner hiccup never blocks an unrelated PR.
6
+ */
7
+ export declare const securityCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const sensitiveFileGuardCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const spellcheckCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const swiftLintCheck: Check;
@@ -0,0 +1,2 @@
1
+ import { Check } from '../types';
2
+ export declare const typecheckCheck: Check;
@@ -32,6 +32,15 @@ exports.typecheckCheck = {
32
32
  return node_fs_1.default.existsSync(node_path_1.default.join(ctx.cwd, 'tsconfig.json'));
33
33
  },
34
34
  async run(ctx) {
35
+ // tsc needs the project's installed type declarations — everything listed in
36
+ // tsconfig's `types`, plus every imported @types package — to resolve. When the
37
+ // project's dependencies aren't installed (e.g. a CI step that runs pr-checkmate
38
+ // via npx without a prior `npm ci`), tsc emits a wall of cryptic TS2688
39
+ // "cannot find type definition file" errors that look like code problems but are
40
+ // really a setup gap. Skip with an actionable message instead of failing the PR.
41
+ if (!node_fs_1.default.existsSync(node_path_1.default.join(ctx.cwd, 'node_modules'))) {
42
+ return (0, types_1.skip)('project dependencies not installed (no node_modules) — run `npm ci` before typecheck');
43
+ }
35
44
  const tscBin = resolveTsc(ctx.cwd);
36
45
  const result = await (0, execa_1.execa)(process.execPath, [tscBin, '--noEmit'], {
37
46
  cwd: ctx.cwd,
@@ -0,0 +1,6 @@
1
+ import type { CheckContext, RunOptions } from './types';
2
+ /**
3
+ * Assemble the shared CheckContext once per run. Language detection is skipped
4
+ * when the caller supplies `languages` (e.g. PRValidator passes its ProjectType).
5
+ */
6
+ export declare function buildContext(opts?: RunOptions): Promise<CheckContext>;
@@ -0,0 +1,4 @@
1
+ export { runChecks } from './run-checks';
2
+ export { buildContext } from './context';
3
+ export { REGISTRY } from './registry';
4
+ export * from './types';
@@ -0,0 +1,6 @@
1
+ import { Check } from './types';
2
+ /**
3
+ * Every check, in declaration order. The orchestrator groups them by `phase`
4
+ * (blocking → informational → format) and runs each phase's checks in parallel.
5
+ */
6
+ export declare const REGISTRY: Check[];
@@ -0,0 +1,7 @@
1
+ import type { CheckReport, CheckResult } from './types';
2
+ /**
3
+ * Emit the report through the selected channel.
4
+ * none: nothing · stdout: console table · github: table + upsert PR comment.
5
+ */
6
+ export declare function report(kind: 'none' | 'stdout' | 'github', result: CheckReport): Promise<void>;
7
+ export type { CheckResult };
@@ -0,0 +1,9 @@
1
+ import { CheckReport, RunOptions } from './types';
2
+ /**
3
+ * Run all applicable checks and return a structured report.
4
+ *
5
+ * Never throws for check violations and never calls `process.exit` — callers
6
+ * (CLI, PRValidator) decide what a failure means. Phases run in order; checks
7
+ * within a phase run in parallel.
8
+ */
9
+ export declare function runChecks(opts?: RunOptions): Promise<CheckReport>;
@@ -7,7 +7,35 @@ const context_1 = require("./context");
7
7
  const registry_1 = require("./registry");
8
8
  const reporters_1 = require("./reporters");
9
9
  const types_1 = require("./types");
10
- /** Apply only/skip filters to the registry. */
10
+ /**
11
+ * Resolve which checks to run: the built-in registry, custom `opts.checks`, or a mix.
12
+ * - no custom checks → the built-in registry
13
+ * - `extendRegistry !== false` → registry + custom (a custom check overrides a
14
+ * built-in one sharing its name)
15
+ * - `extendRegistry === false` → only the provided custom checks
16
+ */
17
+ function resolveChecks(opts) {
18
+ const custom = opts.checks ?? [];
19
+ if (opts.extendRegistry === false)
20
+ return custom;
21
+ if (custom.length === 0)
22
+ return registry_1.REGISTRY;
23
+ const byName = new Map();
24
+ for (const c of registry_1.REGISTRY)
25
+ byName.set(c.name, c);
26
+ for (const c of custom)
27
+ byName.set(c.name, c); // custom wins on name clash
28
+ return [...byName.values()];
29
+ }
30
+ /** Emit the report via a preset channel or a custom reporter function. */
31
+ async function emitReport(reporter, result) {
32
+ if (typeof reporter === 'function') {
33
+ await reporter(result);
34
+ return;
35
+ }
36
+ await (0, reporters_1.report)(reporter ?? 'stdout', result);
37
+ }
38
+ /** Apply only/skip filters to the resolved check set. */
11
39
  function selectChecks(checks, opts) {
12
40
  const only = opts.only && opts.only.length > 0 ? new Set(opts.only) : null;
13
41
  const skip = new Set(opts.skip ?? []);
@@ -49,7 +77,7 @@ async function runOne(check, ctx, collector) {
49
77
  */
50
78
  async function runChecks(opts = {}) {
51
79
  const ctx = await (0, context_1.buildContext)(opts);
52
- const selected = selectChecks(registry_1.REGISTRY, opts);
80
+ const selected = selectChecks(resolveChecks(opts), opts);
53
81
  const collector = new result_collector_1.ResultCollector();
54
82
  for (const phase of types_1.PHASES) {
55
83
  const inPhase = selected.filter(c => c.phase === phase);
@@ -61,6 +89,6 @@ async function runChecks(opts = {}) {
61
89
  summary,
62
90
  ok: summary.failed === 0,
63
91
  };
64
- await (0, reporters_1.report)(opts.reporter ?? 'stdout', result);
92
+ await emitReport(opts.reporter, result);
65
93
  return result;
66
94
  }
@@ -0,0 +1,11 @@
1
+ import type { CheckContext } from './types';
2
+ /**
3
+ * Lists the files a language check should operate on, matched by pathspec `globs`
4
+ * (e.g. `['*.py']`). Uses the PR diff range when available (delta mode), else
5
+ * scans all tracked files. Returns an empty array when nothing matches, and
6
+ * `null` when git itself is unusable (caller should `skip`).
7
+ *
8
+ * Only ACMR files are returned (Added/Copied/Modified/Renamed) — deletions are
9
+ * excluded, so every returned path exists on disk and is safe to read.
10
+ */
11
+ export declare function resolveTargetFiles(ctx: CheckContext, globs: string[]): Promise<string[] | null>;
@@ -0,0 +1,102 @@
1
+ import type { PRCheckMateConfig } from '../interfaces';
2
+ import type { Language } from '../utils/detect-language';
3
+ import type { CheckResult, CheckStatus } from '../utils/result-collector';
4
+ export type { CheckResult, CheckStatus, Language };
5
+ /**
6
+ * Execution phases, run strictly in order. Within a phase checks run in parallel.
7
+ * `format` runs last because formatters (prettier) may write files.
8
+ */
9
+ export type Phase = 'blocking' | 'informational' | 'format';
10
+ export declare const PHASES: readonly Phase[];
11
+ /**
12
+ * Everything a check needs to run. Assembled once by `buildContext` and shared
13
+ * across all checks — no check reads `process.cwd()` or `process.env` directly.
14
+ */
15
+ export interface CheckContext {
16
+ /** Repository root the checks operate on. */
17
+ cwd: string;
18
+ /** Languages detected (or supplied) for this repo — drives `applies` gating. */
19
+ languages: Language[];
20
+ /** Merged pr-checkmate.json + defaults. */
21
+ config: PRCheckMateConfig;
22
+ /** When false, checks that would modify files (prettier, --fix) run read-only or skip the write. */
23
+ write: boolean;
24
+ /** Diff range for delta-aware checks; undefined → full-repo scan. */
25
+ baseSha?: string;
26
+ headSha?: string;
27
+ }
28
+ /** Outcome of a single check — the name is attached by the orchestrator. */
29
+ export interface CheckOutcome {
30
+ status: CheckStatus;
31
+ details?: string;
32
+ }
33
+ /**
34
+ * A single quality gate. `applies` decides relevance (language/marker gating);
35
+ * `run` performs the check and returns an outcome. `run` must NOT throw for
36
+ * violations — return `fail`/`warn` instead. Thrown errors are caught by the
37
+ * orchestrator and recorded as `fail`.
38
+ */
39
+ export interface Check {
40
+ name: string;
41
+ phase: Phase;
42
+ applies(ctx: CheckContext): boolean | Promise<boolean>;
43
+ run(ctx: CheckContext): Promise<CheckOutcome>;
44
+ }
45
+ export type ReporterKind = 'none' | 'stdout' | 'github';
46
+ /** Custom reporter: receives the final report to emit however the consumer wants. */
47
+ export type ReporterFn = (report: CheckReport) => void | Promise<void>;
48
+ export interface RunOptions {
49
+ cwd?: string;
50
+ /** Override language detection (e.g. PRValidator passes its already-detected type). */
51
+ languages?: Language[];
52
+ /** Whitelist of check names — when set, only these run. */
53
+ only?: string[];
54
+ /** Blacklist of check names — always excluded. */
55
+ skip?: string[];
56
+ /**
57
+ * Extra checks to run. Combined with the built-in registry per `extendRegistry`.
58
+ * Lets consumers (e.g. PRValidator) plug their own `Check`s into the same pipeline.
59
+ */
60
+ checks?: Check[];
61
+ /**
62
+ * How `checks` combines with the built-in registry:
63
+ * - `true` (default when `checks` is set): append; a custom check overrides a
64
+ * built-in one with the same name.
65
+ * - `false`: run ONLY the provided `checks`, ignoring the built-in registry.
66
+ */
67
+ extendRegistry?: boolean;
68
+ /**
69
+ * Where the report goes:
70
+ * - `'none'`: nothing (just return the report)
71
+ * - `'stdout'`: print the summary table
72
+ * - `'github'`: print + upsert a PR comment
73
+ * - a function: receives the `CheckReport` (e.g. forward to Slack).
74
+ */
75
+ reporter?: ReporterKind | ReporterFn;
76
+ /** Allow file-modifying checks to write. Default false. */
77
+ write?: boolean;
78
+ config?: PRCheckMateConfig;
79
+ baseSha?: string;
80
+ headSha?: string;
81
+ }
82
+ export interface CheckReport {
83
+ results: CheckResult[];
84
+ summary: {
85
+ passed: number;
86
+ warned: number;
87
+ failed: number;
88
+ skipped: number;
89
+ };
90
+ /** True when no check failed (warnings/skips do not affect it). */
91
+ ok: boolean;
92
+ }
93
+ /** Outcome constructors — keep check bodies terse. */
94
+ export declare const pass: (details?: string) => CheckOutcome;
95
+ export declare const warn: (details: string) => CheckOutcome;
96
+ export declare const fail: (details: string) => CheckOutcome;
97
+ export declare const skip: (details: string) => CheckOutcome;
98
+ /**
99
+ * Identity helper for authoring a `Check` with full type inference and checking.
100
+ * Purely ergonomic — `defineCheck({ ... })` is equivalent to `{ ... } satisfies Check`.
101
+ */
102
+ export declare const defineCheck: (check: Check) => Check;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.skip = exports.fail = exports.warn = exports.pass = exports.PHASES = void 0;
3
+ exports.defineCheck = exports.skip = exports.fail = exports.warn = exports.pass = exports.PHASES = void 0;
4
4
  exports.PHASES = ['blocking', 'informational', 'format'];
5
5
  /** Outcome constructors — keep check bodies terse. */
6
6
  const pass = (details) => ({
@@ -14,3 +14,9 @@ const fail = (details) => ({ status: 'fail', details });
14
14
  exports.fail = fail;
15
15
  const skip = (details) => ({ status: 'skip', details });
16
16
  exports.skip = skip;
17
+ /**
18
+ * Identity helper for authoring a `Check` with full type inference and checking.
19
+ * Purely ergonomic — `defineCheck({ ... })` is equivalent to `{ ... } satisfies Check`.
20
+ */
21
+ const defineCheck = (check) => check;
22
+ exports.defineCheck = defineCheck;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * PR CheckMate — automated PR quality checks.
3
+ *
4
+ * @module pr-checkmate
5
+ */
6
+ export { runChecks, buildContext, REGISTRY } from './core';
7
+ export { pass, warn, fail, skip, defineCheck } from './core';
8
+ export type { Check, CheckContext, CheckOutcome, CheckReport, CheckResult, CheckStatus, Language, Phase, ReporterFn, ReporterKind, RunOptions, } from './core';
9
+ export { getSourcePath, getPackageConfigPath, hasLocalConfig } from './config';
package/dist/index.js CHANGED
@@ -5,13 +5,20 @@
5
5
  * @module pr-checkmate
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.hasLocalConfig = exports.getPackageConfigPath = exports.getSourcePath = exports.REGISTRY = exports.buildContext = exports.runChecks = void 0;
8
+ exports.hasLocalConfig = exports.getPackageConfigPath = exports.getSourcePath = exports.defineCheck = exports.skip = exports.fail = exports.warn = exports.pass = exports.REGISTRY = exports.buildContext = exports.runChecks = void 0;
9
9
  // Primary programmatic API: run checks and receive a structured report.
10
10
  // Never throws for violations, never calls process.exit — the caller decides.
11
11
  var core_1 = require("./core");
12
12
  Object.defineProperty(exports, "runChecks", { enumerable: true, get: function () { return core_1.runChecks; } });
13
13
  Object.defineProperty(exports, "buildContext", { enumerable: true, get: function () { return core_1.buildContext; } });
14
14
  Object.defineProperty(exports, "REGISTRY", { enumerable: true, get: function () { return core_1.REGISTRY; } });
15
+ // Authoring helpers for consumers writing their own checks (plugins).
16
+ var core_2 = require("./core");
17
+ Object.defineProperty(exports, "pass", { enumerable: true, get: function () { return core_2.pass; } });
18
+ Object.defineProperty(exports, "warn", { enumerable: true, get: function () { return core_2.warn; } });
19
+ Object.defineProperty(exports, "fail", { enumerable: true, get: function () { return core_2.fail; } });
20
+ Object.defineProperty(exports, "skip", { enumerable: true, get: function () { return core_2.skip; } });
21
+ Object.defineProperty(exports, "defineCheck", { enumerable: true, get: function () { return core_2.defineCheck; } });
15
22
  // Config helpers for consumers embedding pr-checkmate.
16
23
  var config_1 = require("./config");
17
24
  Object.defineProperty(exports, "getSourcePath", { enumerable: true, get: function () { return config_1.getSourcePath; } });
package/dist/init.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare const CONFIG_FILE: string;
2
+ /**
3
+ * Initialize (or refresh) pr-checkmate configuration in the current project.
4
+ */
5
+ export declare function init(): Promise<void>;
package/dist/init.js CHANGED
@@ -19,7 +19,11 @@ const DEFAULT_CONFIG = {
19
19
  commands: config_1.DEFAULT_COMMANDS,
20
20
  // ESLint customization
21
21
  eslint: {
22
- rules: {},
22
+ rules: {
23
+ // Off by default: its `--fix` injects empty `/** */` JSDoc stubs into
24
+ // client source files. Set to 'warn'/'error' to opt into doc enforcement.
25
+ 'jsdoc/require-jsdoc': 'off',
26
+ },
23
27
  ignorePatterns: [],
24
28
  },
25
29
  // Prettier customization
@@ -0,0 +1,129 @@
1
+ import type { Language } from '../utils/detect-language';
2
+ export interface ConfigFile {
3
+ source: string;
4
+ dest: string;
5
+ }
6
+ export interface PrettierConfig {
7
+ semi: boolean;
8
+ singleQuote: boolean;
9
+ trailingComma: string;
10
+ bracketSpacing: boolean;
11
+ arrowParens: string;
12
+ printWidth: number;
13
+ }
14
+ export interface CspellConfig {
15
+ version: string;
16
+ language: string;
17
+ import?: string[];
18
+ words: string[];
19
+ ignorePaths: string[];
20
+ enableFiletypes: string[];
21
+ ignoreRegExpList: string[];
22
+ }
23
+ export interface PRCheckMateConfig {
24
+ sourcePath: string;
25
+ languages?: Language[];
26
+ lint?: {
27
+ rules?: Record<string, any>;
28
+ ignorePatterns?: string[];
29
+ };
30
+ prettier?: {
31
+ config?: Record<string, any>;
32
+ };
33
+ spellcheck?: {
34
+ words?: string[];
35
+ ignoreWords?: string[];
36
+ ignorePaths?: string[];
37
+ };
38
+ security?: {
39
+ gitleaks?: {
40
+ enabled: boolean;
41
+ };
42
+ 'npm-audit'?: {
43
+ enabled: boolean;
44
+ auditLevel: string;
45
+ };
46
+ };
47
+ typecheck?: {
48
+ enabled?: boolean;
49
+ };
50
+ cpp?: {
51
+ enabled?: boolean;
52
+ clangFormat?: {
53
+ style?: string;
54
+ };
55
+ };
56
+ python?: {
57
+ enabled?: boolean;
58
+ ruff?: {
59
+ lint?: boolean;
60
+ format?: boolean;
61
+ };
62
+ };
63
+ diffSmell?: {
64
+ enabled?: boolean;
65
+ };
66
+ prBody?: {
67
+ enabled?: boolean;
68
+ minLength?: number;
69
+ requireTicket?: boolean;
70
+ };
71
+ duplicate?: {
72
+ enabled?: boolean;
73
+ minLines?: number;
74
+ minTokens?: number;
75
+ };
76
+ commitlint?: {
77
+ enabled?: boolean;
78
+ types?: string[];
79
+ /**
80
+ * Regex sources (matched case-insensitively) for commit messages to skip,
81
+ * e.g. release PRs or squash-merge titles that don't follow conventional
82
+ * commits. Applied in addition to commitlint's built-in merge/revert ignores.
83
+ */
84
+ ignores?: string[];
85
+ };
86
+ diffSecurity?: {
87
+ enabled?: boolean;
88
+ };
89
+ sensitiveFileGuard?: {
90
+ enabled?: boolean;
91
+ };
92
+ swift?: {
93
+ enabled?: boolean;
94
+ };
95
+ kotlin?: {
96
+ enabled?: boolean;
97
+ };
98
+ deadCode?: {
99
+ enabled?: boolean;
100
+ };
101
+ licenseCheck?: {
102
+ allowPackages?: string[];
103
+ allowLicenses?: string[];
104
+ };
105
+ }
106
+ export interface CheckmateConfig {
107
+ skipLint?: boolean;
108
+ skipDeps?: boolean;
109
+ skipFormat?: boolean;
110
+ skipSpell?: boolean;
111
+ skipSecurity?: boolean;
112
+ skipNpmAudit?: boolean;
113
+ skipCircularDeps?: boolean;
114
+ skipLicense?: boolean;
115
+ skipPrSize?: boolean;
116
+ skipPrTitle?: boolean;
117
+ skipOutdated?: boolean;
118
+ skipMarkdown?: boolean;
119
+ skipTypecheck?: boolean;
120
+ skipDiffSmell?: boolean;
121
+ skipPrBody?: boolean;
122
+ skipDuplicate?: boolean;
123
+ skipDiffSecurity?: boolean;
124
+ skipSensitiveFiles?: boolean;
125
+ skipDeadCode?: boolean;
126
+ autoCommit?: boolean;
127
+ }
128
+ export type { CheckStatus, CheckResult } from '../utils/result-collector';
129
+ export type { Language } from '../utils/detect-language';
@@ -0,0 +1,5 @@
1
+ /**
2
+ *
3
+ */
4
+ declare function copyConfigs(): void;
5
+ export { copyConfigs };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns list of changed files in the current PR filtered by extension.
3
+ * Returns null when not in a GitHub PR context (falls back to full-project scan).
4
+ */
5
+ export declare function getChangedFiles(extensions: string[]): Promise<string[] | null>;
@@ -0,0 +1,10 @@
1
+ export type Language = 'typescript' | 'javascript' | 'python' | 'cpp' | 'swift' | 'kotlin';
2
+ /**
3
+ * Detects which languages a repository uses, combining marker files (definitive)
4
+ * with tracked source-file counts (breadth). A language is reported when it has a
5
+ * marker file OR at least one tracked source file.
6
+ *
7
+ * @returns languages ordered by tracked file count (most-used first). `.h` headers
8
+ * are intentionally excluded from the C++ count since they are ambiguous with C.
9
+ */
10
+ export declare function detectLanguages(root?: string): Promise<Language[]>;
@@ -0,0 +1,10 @@
1
+ export * from './logger';
2
+ export * from './delta';
3
+ export * from './result-collector';
4
+ export * from './resolve-bin';
5
+ export * from './own-deps';
6
+ export * from './detect-language';
7
+ /**
8
+ *
9
+ */
10
+ export declare function cleanupTempFile(filePath: string): void;
@@ -0,0 +1,20 @@
1
+ type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';
2
+ declare class Logger {
3
+ private logs;
4
+ private levelOrder;
5
+ private currentLevel;
6
+ private getTimestamp;
7
+ private shouldLog;
8
+ private colorize;
9
+ private logMessage;
10
+ log(msg: string): void;
11
+ info(msg: string): void;
12
+ warn(msg: string): void;
13
+ error(msg: string, err?: unknown): void;
14
+ debug(msg: string): void;
15
+ getLogs(): string[];
16
+ setLevel(level: LogLevel): void;
17
+ clear(): void;
18
+ }
19
+ export declare const logger: Logger;
20
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Compute the full set of package names in pr-checkmate's own dependency
3
+ * closure (direct + transitive runtime dependencies), plus pr-checkmate itself.
4
+ *
5
+ * pr-checkmate installs into the consumer's node_modules, so its own runtime
6
+ * deps (eslint plugins, cspell dictionaries, …) become part of the consumer's
7
+ * production dependency tree. Some carry copyleft licenses that would otherwise
8
+ * trip pr-checkmate's own license check against an innocent client. These are
9
+ * pr-checkmate's dependencies, not the client's, so they must be exempt.
10
+ *
11
+ * Result is cached for the process. Returns a set containing only pr-checkmate
12
+ * itself if the package root cannot be located (defensive; never throws).
13
+ */
14
+ export declare function getOwnDependencyClosure(): Set<string>;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Resolves a binary path for a bundled package, bypassing exports map restrictions.
3
+ *
4
+ * Strategy (tries each in order):
5
+ * 1. Direct subpath — fast path for packages that explicitly export their bin
6
+ * 2. Via package.json — for packages that export ./package.json but not the bin subpath (e.g. eslint)
7
+ * 3. Walk up from main entry — for packages that export neither (e.g. cspell)
8
+ *
9
+ * @param pkgName - The package whose binary to resolve (e.g. `eslint`).
10
+ * @param binRelPath - The bin path relative to the package root (e.g. `bin/eslint.js`).
11
+ * @param options - Resolution options.
12
+ * @param options.paths - Directories to resolve from (passed to `require.resolve`).
13
+ * Use `[process.cwd()]` to prefer the consumer project's copy of the package.
14
+ */
15
+ export declare function resolvePackageBin(pkgName: string, binRelPath: string, options?: {
16
+ paths?: string[];
17
+ }): string;
@@ -0,0 +1,33 @@
1
+ export type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip';
2
+ export interface CheckResult {
3
+ name: string;
4
+ status: CheckStatus;
5
+ details?: string;
6
+ }
7
+ /**
8
+ *
9
+ */
10
+ export declare class ResultCollector {
11
+ private results;
12
+ /**
13
+ *
14
+ */
15
+ register(name: string, status: CheckStatus, details?: string): void;
16
+ /**
17
+ *
18
+ */
19
+ getResults(): CheckResult[];
20
+ /**
21
+ *
22
+ */
23
+ clear(): void;
24
+ /**
25
+ *
26
+ */
27
+ getSummary(): {
28
+ passed: number;
29
+ warned: number;
30
+ failed: number;
31
+ skipped: number;
32
+ };
33
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pr-checkmate",
3
- "version": "1.22.0",
3
+ "version": "1.22.2",
4
4
  "description": "Automated PR quality checks: linting, formatting, dependency analysis, and spellcheck",
5
5
  "keywords": [
6
6
  "github-actions",
@@ -11,11 +11,19 @@
11
11
  "code-quality",
12
12
  "automation"
13
13
  ],
14
- "main": "./dist/cli.js",
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
15
16
  "type": "commonjs",
16
17
  "bin": {
17
18
  "pr-checkmate": "dist/cli.js"
18
19
  },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ },
25
+ "./package.json": "./package.json"
26
+ },
19
27
  "files": [
20
28
  "dist",
21
29
  "README.md",