pr-checkmate 3.3.0 → 4.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.
- package/LICENSE +8 -3
- package/README.md +53 -4
- package/dist/cjs/agent/hook.d.ts +37 -0
- package/dist/cjs/agent/hook.js +175 -0
- package/dist/cjs/agent/registration.d.ts +10 -0
- package/dist/cjs/agent/registration.js +28 -0
- package/dist/cjs/agent/setup.d.ts +20 -0
- package/dist/cjs/agent/setup.js +229 -0
- package/dist/cjs/cli.js +88 -0
- package/dist/cjs/config/constants.d.ts +2 -0
- package/dist/cjs/config/constants.js +5 -1
- package/dist/cjs/config/pr-checkmate.template.json +10 -0
- package/dist/cjs/core/checks/findings.js +33 -7
- package/dist/cjs/core/checks/git/large-files.d.ts +1 -0
- package/dist/cjs/core/checks/git/large-files.js +3 -3
- package/dist/cjs/core/checks/pr/pr-size-check.d.ts +2 -0
- package/dist/cjs/core/checks/pr/pr-size-check.js +5 -5
- package/dist/cjs/core/checks/security/agent-instructions.d.ts +4 -0
- package/dist/cjs/core/checks/security/agent-instructions.js +149 -0
- package/dist/cjs/core/checks/security/diff-security.d.ts +7 -0
- package/dist/cjs/core/checks/security/diff-security.js +21 -1
- package/dist/cjs/core/checks/security/security.d.ts +0 -13
- package/dist/cjs/core/checks/security/security.js +27 -0
- package/dist/cjs/core/checks/security/workflow-security.js +33 -0
- package/dist/cjs/core/commands.d.ts +6 -0
- package/dist/cjs/core/commands.js +11 -1
- package/dist/cjs/core/finding-store.d.ts +16 -0
- package/dist/cjs/core/finding-store.js +73 -0
- package/dist/cjs/core/registry.js +2 -0
- package/dist/cjs/core/reporters.js +9 -0
- package/dist/cjs/core/run-checks.js +15 -5
- package/dist/cjs/core/sarif.d.ts +13 -0
- package/dist/cjs/core/sarif.js +60 -0
- package/dist/cjs/core/types.d.ts +7 -2
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/init.js +11 -0
- package/dist/cjs/interfaces/index.d.ts +12 -0
- package/dist/cjs/mcp/config-tools.d.ts +30 -0
- package/dist/cjs/mcp/config-tools.js +320 -0
- package/dist/cjs/mcp/dependency.d.ts +33 -0
- package/dist/cjs/mcp/dependency.js +407 -0
- package/dist/cjs/mcp/protocol.d.ts +97 -0
- package/dist/cjs/mcp/protocol.js +181 -0
- package/dist/cjs/mcp/review.d.ts +63 -0
- package/dist/cjs/mcp/review.js +150 -0
- package/dist/cjs/mcp/serve.d.ts +8 -0
- package/dist/cjs/mcp/serve.js +49 -0
- package/dist/cjs/mcp/settings.d.ts +13 -0
- package/dist/cjs/mcp/settings.js +50 -0
- package/dist/cjs/mcp/tools.d.ts +23 -0
- package/dist/cjs/mcp/tools.js +633 -0
- package/dist/cjs/utils/execa.d.ts +7 -0
- package/dist/cjs/utils/execa.js +41 -1
- package/dist/cjs/utils/result-collector.d.ts +17 -1
- package/dist/cjs/utils/result-collector.js +7 -2
- package/dist/esm/agent/hook.d.ts +37 -0
- package/dist/esm/agent/hook.js +167 -0
- package/dist/esm/agent/registration.d.ts +10 -0
- package/dist/esm/agent/registration.js +21 -0
- package/dist/esm/agent/setup.d.ts +20 -0
- package/dist/esm/agent/setup.js +220 -0
- package/dist/esm/cli.js +86 -1
- package/dist/esm/config/constants.d.ts +2 -0
- package/dist/esm/config/constants.js +4 -0
- package/dist/esm/config/pr-checkmate.template.json +10 -0
- package/dist/esm/core/checks/findings.js +33 -7
- package/dist/esm/core/checks/git/large-files.d.ts +1 -0
- package/dist/esm/core/checks/git/large-files.js +1 -1
- package/dist/esm/core/checks/pr/pr-size-check.d.ts +2 -0
- package/dist/esm/core/checks/pr/pr-size-check.js +2 -2
- package/dist/esm/core/checks/security/agent-instructions.d.ts +4 -0
- package/dist/esm/core/checks/security/agent-instructions.js +146 -0
- package/dist/esm/core/checks/security/diff-security.d.ts +7 -0
- package/dist/esm/core/checks/security/diff-security.js +20 -0
- package/dist/esm/core/checks/security/security.d.ts +0 -13
- package/dist/esm/core/checks/security/security.js +27 -0
- package/dist/esm/core/checks/security/workflow-security.js +33 -0
- package/dist/esm/core/commands.d.ts +6 -0
- package/dist/esm/core/commands.js +10 -0
- package/dist/esm/core/finding-store.d.ts +16 -0
- package/dist/esm/core/finding-store.js +67 -0
- package/dist/esm/core/registry.js +2 -0
- package/dist/esm/core/reporters.js +9 -0
- package/dist/esm/core/run-checks.js +15 -5
- package/dist/esm/core/sarif.d.ts +13 -0
- package/dist/esm/core/sarif.js +57 -0
- package/dist/esm/core/types.d.ts +7 -2
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/init.js +12 -1
- package/dist/esm/interfaces/index.d.ts +12 -0
- package/dist/esm/mcp/config-tools.d.ts +30 -0
- package/dist/esm/mcp/config-tools.js +310 -0
- package/dist/esm/mcp/dependency.d.ts +33 -0
- package/dist/esm/mcp/dependency.js +402 -0
- package/dist/esm/mcp/protocol.d.ts +97 -0
- package/dist/esm/mcp/protocol.js +175 -0
- package/dist/esm/mcp/review.d.ts +63 -0
- package/dist/esm/mcp/review.js +139 -0
- package/dist/esm/mcp/serve.d.ts +8 -0
- package/dist/esm/mcp/serve.js +43 -0
- package/dist/esm/mcp/settings.d.ts +13 -0
- package/dist/esm/mcp/settings.js +43 -0
- package/dist/esm/mcp/tools.d.ts +23 -0
- package/dist/esm/mcp/tools.js +626 -0
- package/dist/esm/utils/execa.d.ts +7 -0
- package/dist/esm/utils/execa.js +40 -1
- package/dist/esm/utils/result-collector.d.ts +17 -1
- package/dist/esm/utils/result-collector.js +7 -2
- package/package.json +6 -2
- package/pr-checkmate.schema.json +35 -0
- package/src/config/pr-checkmate.schema.json +35 -0
package/dist/esm/utils/execa.js
CHANGED
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether children that would inherit our standard streams are kept off them.
|
|
3
|
+
*
|
|
4
|
+
* A few checks run a tool with `stdio: 'inherit'` so its output reaches the
|
|
5
|
+
* terminal. That is right for the CLI and fatal for the MCP server, whose stdout
|
|
6
|
+
* *is* the protocol: gitleaks printing its banner there is a line that is not
|
|
7
|
+
* JSON, and the client drops the connection. Swapping `process.stdout.write`
|
|
8
|
+
* cannot help, because an inherited descriptor never passes through it — so the
|
|
9
|
+
* redirection has to happen where the child is spawned.
|
|
10
|
+
*/
|
|
11
|
+
let childOutput = null;
|
|
12
|
+
/**
|
|
13
|
+
* Keep children that would inherit our streams off them, and stop them sharing
|
|
14
|
+
* stdin. `stderr` (the MCP server) keeps their output as the server's log;
|
|
15
|
+
* `discard` (the commit hook) drops it, because a hook's stderr is read by the
|
|
16
|
+
* model and tool banners are not what it needs to hear. No other command is affected.
|
|
17
|
+
*/
|
|
18
|
+
export function isolateInheritedStdio(output = 'stderr') {
|
|
19
|
+
childOutput = output === 'stderr' ? 2 : 'ignore';
|
|
20
|
+
}
|
|
21
|
+
/** Redirect inherited stdout/stderr per {@link isolateInheritedStdio}; stdin is never ours to give away. */
|
|
22
|
+
function isolated(options) {
|
|
23
|
+
if (childOutput === null || !options)
|
|
24
|
+
return options;
|
|
25
|
+
const { stdio } = options;
|
|
26
|
+
if (stdio === 'inherit')
|
|
27
|
+
return { ...options, stdio: ['ignore', childOutput, childOutput] };
|
|
28
|
+
if (Array.isArray(stdio)) {
|
|
29
|
+
const next = stdio.map((entry, fd) => {
|
|
30
|
+
if (fd === 0 && entry === 'inherit')
|
|
31
|
+
return 'ignore';
|
|
32
|
+
if ((fd === 1 || fd === 2) && entry === 'inherit')
|
|
33
|
+
return childOutput;
|
|
34
|
+
return entry;
|
|
35
|
+
});
|
|
36
|
+
return { ...options, stdio: next };
|
|
37
|
+
}
|
|
38
|
+
return options;
|
|
39
|
+
}
|
|
1
40
|
/**
|
|
2
41
|
* Run a command via execa, loading the module lazily on first call.
|
|
3
42
|
*
|
|
@@ -6,5 +45,5 @@
|
|
|
6
45
|
*/
|
|
7
46
|
export async function execa(file, args, options) {
|
|
8
47
|
const { execa: run } = await import('execa');
|
|
9
|
-
return (await run(file, args, options));
|
|
48
|
+
return (await run(file, args, isolated(options)));
|
|
10
49
|
}
|
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
export type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip';
|
|
2
|
+
/**
|
|
3
|
+
* One thing a check found, with where it is. Optional on every result: only the
|
|
4
|
+
* checks that can say where report it, and a result without any is not an error —
|
|
5
|
+
* it just has a summary and no location.
|
|
6
|
+
*/
|
|
7
|
+
export interface Finding {
|
|
8
|
+
file: string;
|
|
9
|
+
/** 1-based line in the file as it will be committed. */
|
|
10
|
+
line?: number;
|
|
11
|
+
/** Which rule or pattern matched, as the check names it. */
|
|
12
|
+
rule: string;
|
|
13
|
+
/** The offending text, shortened. Never a secret: scanners that find those leave it out. */
|
|
14
|
+
snippet?: string;
|
|
15
|
+
severity: 'error' | 'warn';
|
|
16
|
+
}
|
|
2
17
|
export interface CheckResult {
|
|
3
18
|
name: string;
|
|
4
19
|
status: CheckStatus;
|
|
5
20
|
details?: string;
|
|
21
|
+
findings?: Finding[];
|
|
6
22
|
}
|
|
7
23
|
/**
|
|
8
24
|
*
|
|
@@ -12,7 +28,7 @@ export declare class ResultCollector {
|
|
|
12
28
|
/**
|
|
13
29
|
*
|
|
14
30
|
*/
|
|
15
|
-
register(name: string, status: CheckStatus, details?: string): void;
|
|
31
|
+
register(name: string, status: CheckStatus, details?: string, findings?: Finding[]): void;
|
|
16
32
|
/**
|
|
17
33
|
*
|
|
18
34
|
*/
|
|
@@ -8,9 +8,14 @@ export class ResultCollector {
|
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
|
-
register(name, status, details) {
|
|
11
|
+
register(name, status, details, findings) {
|
|
12
12
|
const idx = this.results.findIndex(r => r.name === name);
|
|
13
|
-
const entry = {
|
|
13
|
+
const entry = {
|
|
14
|
+
name,
|
|
15
|
+
status,
|
|
16
|
+
...(details && { details }),
|
|
17
|
+
...(findings && findings.length > 0 && { findings }),
|
|
18
|
+
};
|
|
14
19
|
if (idx >= 0) {
|
|
15
20
|
this.results[idx] = entry;
|
|
16
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-checkmate",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Security-first PR gate for CI: secret scanning, grype dependency scanning, SBOM — plus linting and formatting across 11 languages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github-actions",
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
"eslint",
|
|
10
10
|
"prettier",
|
|
11
11
|
"code-quality",
|
|
12
|
-
"automation"
|
|
12
|
+
"automation",
|
|
13
|
+
"mcp",
|
|
14
|
+
"model-context-protocol",
|
|
15
|
+
"ai-agents",
|
|
16
|
+
"claude-code"
|
|
13
17
|
],
|
|
14
18
|
"main": "./dist/cjs/index.js",
|
|
15
19
|
"module": "./dist/esm/index.js",
|
package/pr-checkmate.schema.json
CHANGED
|
@@ -309,6 +309,41 @@
|
|
|
309
309
|
"dockerfileSecurity": {
|
|
310
310
|
"$ref": "#/$defs/toggleIgnorePaths"
|
|
311
311
|
},
|
|
312
|
+
"agentInstructions": {
|
|
313
|
+
"$ref": "#/$defs/toggleIgnorePaths"
|
|
314
|
+
},
|
|
315
|
+
"mcp": {
|
|
316
|
+
"type": "object",
|
|
317
|
+
"description": "What the pr-checkmate MCP server offers an AI agent working in this project. Changes apply to the agent's next request.",
|
|
318
|
+
"additionalProperties": false,
|
|
319
|
+
"properties": {
|
|
320
|
+
"enabled": {
|
|
321
|
+
"type": "boolean",
|
|
322
|
+
"description": "false turns the server off for this project: it still connects, but offers no tools, resources or prompts. Default true."
|
|
323
|
+
},
|
|
324
|
+
"disabledTools": {
|
|
325
|
+
"type": "array",
|
|
326
|
+
"description": "Tools to hide from the agent.",
|
|
327
|
+
"items": {
|
|
328
|
+
"enum": [
|
|
329
|
+
"get_rules",
|
|
330
|
+
"check_changes",
|
|
331
|
+
"apply_fixes",
|
|
332
|
+
"scan_secrets",
|
|
333
|
+
"check_dependency",
|
|
334
|
+
"suggest_config",
|
|
335
|
+
"write_config",
|
|
336
|
+
"explain_config",
|
|
337
|
+
"verify"
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
"readOnly": {
|
|
342
|
+
"type": "boolean",
|
|
343
|
+
"description": "Hide the tools that write files (apply_fixes, write_config), so the agent can only read and report. Default false."
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
312
347
|
"migrationSafety": {
|
|
313
348
|
"$ref": "#/$defs/toggleSeverity"
|
|
314
349
|
},
|
|
@@ -309,6 +309,41 @@
|
|
|
309
309
|
"dockerfileSecurity": {
|
|
310
310
|
"$ref": "#/$defs/toggleIgnorePaths"
|
|
311
311
|
},
|
|
312
|
+
"agentInstructions": {
|
|
313
|
+
"$ref": "#/$defs/toggleIgnorePaths"
|
|
314
|
+
},
|
|
315
|
+
"mcp": {
|
|
316
|
+
"type": "object",
|
|
317
|
+
"description": "What the pr-checkmate MCP server offers an AI agent working in this project. Changes apply to the agent's next request.",
|
|
318
|
+
"additionalProperties": false,
|
|
319
|
+
"properties": {
|
|
320
|
+
"enabled": {
|
|
321
|
+
"type": "boolean",
|
|
322
|
+
"description": "false turns the server off for this project: it still connects, but offers no tools, resources or prompts. Default true."
|
|
323
|
+
},
|
|
324
|
+
"disabledTools": {
|
|
325
|
+
"type": "array",
|
|
326
|
+
"description": "Tools to hide from the agent.",
|
|
327
|
+
"items": {
|
|
328
|
+
"enum": [
|
|
329
|
+
"get_rules",
|
|
330
|
+
"check_changes",
|
|
331
|
+
"apply_fixes",
|
|
332
|
+
"scan_secrets",
|
|
333
|
+
"check_dependency",
|
|
334
|
+
"suggest_config",
|
|
335
|
+
"write_config",
|
|
336
|
+
"explain_config",
|
|
337
|
+
"verify"
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
"readOnly": {
|
|
342
|
+
"type": "boolean",
|
|
343
|
+
"description": "Hide the tools that write files (apply_fixes, write_config), so the agent can only read and report. Default false."
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
312
347
|
"migrationSafety": {
|
|
313
348
|
"$ref": "#/$defs/toggleSeverity"
|
|
314
349
|
},
|