check-my-toolkit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +116 -0
- package/dist/cli.js.map +1 -0
- package/dist/code/audit.d.ts +14 -0
- package/dist/code/audit.d.ts.map +1 -0
- package/dist/code/audit.js +130 -0
- package/dist/code/audit.js.map +1 -0
- package/dist/code/index.d.ts +13 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/index.js +49 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code/linting.d.ts +10 -0
- package/dist/code/linting.d.ts.map +1 -0
- package/dist/code/linting.js +233 -0
- package/dist/code/linting.js.map +1 -0
- package/dist/code/tools/base.d.ts +52 -0
- package/dist/code/tools/base.d.ts.map +1 -0
- package/dist/code/tools/base.js +83 -0
- package/dist/code/tools/base.js.map +1 -0
- package/dist/code/tools/eslint.d.ts +15 -0
- package/dist/code/tools/eslint.d.ts.map +1 -0
- package/dist/code/tools/eslint.js +79 -0
- package/dist/code/tools/eslint.js.map +1 -0
- package/dist/code/tools/index.d.ts +5 -0
- package/dist/code/tools/index.d.ts.map +1 -0
- package/dist/code/tools/index.js +5 -0
- package/dist/code/tools/index.js.map +1 -0
- package/dist/code/tools/ruff.d.ts +26 -0
- package/dist/code/tools/ruff.d.ts.map +1 -0
- package/dist/code/tools/ruff.js +149 -0
- package/dist/code/tools/ruff.js.map +1 -0
- package/dist/code/tools/tsc.d.ts +20 -0
- package/dist/code/tools/tsc.d.ts.map +1 -0
- package/dist/code/tools/tsc.js +90 -0
- package/dist/code/tools/tsc.js.map +1 -0
- package/dist/code/types.d.ts +6 -0
- package/dist/code/types.d.ts.map +1 -0
- package/dist/code/types.js +132 -0
- package/dist/code/types.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +21 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +118 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +1217 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +190 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/output/index.d.ts +15 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +98 -0
- package/dist/output/index.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +116 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/code/index.d.ts +13 -0
- package/dist/src/code/index.d.ts.map +1 -0
- package/dist/src/code/index.js +53 -0
- package/dist/src/code/index.js.map +1 -0
- package/dist/src/code/tools/base.d.ts +52 -0
- package/dist/src/code/tools/base.d.ts.map +1 -0
- package/dist/src/code/tools/base.js +83 -0
- package/dist/src/code/tools/base.js.map +1 -0
- package/dist/src/code/tools/eslint.d.ts +15 -0
- package/dist/src/code/tools/eslint.d.ts.map +1 -0
- package/dist/src/code/tools/eslint.js +79 -0
- package/dist/src/code/tools/eslint.js.map +1 -0
- package/dist/src/code/tools/index.d.ts +5 -0
- package/dist/src/code/tools/index.d.ts.map +1 -0
- package/dist/src/code/tools/index.js +5 -0
- package/dist/src/code/tools/index.js.map +1 -0
- package/dist/src/code/tools/ruff.d.ts +26 -0
- package/dist/src/code/tools/ruff.d.ts.map +1 -0
- package/dist/src/code/tools/ruff.js +149 -0
- package/dist/src/code/tools/ruff.js.map +1 -0
- package/dist/src/code/tools/tsc.d.ts +21 -0
- package/dist/src/code/tools/tsc.d.ts.map +1 -0
- package/dist/src/code/tools/tsc.js +94 -0
- package/dist/src/code/tools/tsc.js.map +1 -0
- package/dist/src/config/index.d.ts +3 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +3 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/loader.d.ts +22 -0
- package/dist/src/config/loader.d.ts.map +1 -0
- package/dist/src/config/loader.js +124 -0
- package/dist/src/config/loader.js.map +1 -0
- package/dist/src/config/schema.d.ts +503 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +190 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +16 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/output/index.d.ts +15 -0
- package/dist/src/output/index.d.ts.map +1 -0
- package/dist/src/output/index.js +96 -0
- package/dist/src/output/index.js.map +1 -0
- package/dist/src/types/index.d.ts +96 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +89 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/tests/e2e/e2e.test.d.ts +2 -0
- package/dist/tests/e2e/e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/e2e.test.js +398 -0
- package/dist/tests/e2e/e2e.test.js.map +1 -0
- package/dist/types/index.d.ts +96 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +89 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { CheckResult, type IToolRunner, type Violation } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for tool runners.
|
|
4
|
+
* Provides common functionality for checking configs and handling errors.
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class BaseToolRunner implements IToolRunner {
|
|
7
|
+
abstract readonly name: string;
|
|
8
|
+
abstract readonly rule: string;
|
|
9
|
+
abstract readonly toolId: string;
|
|
10
|
+
abstract readonly configFiles: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Check if any of the config files exist
|
|
13
|
+
*/
|
|
14
|
+
protected hasConfig(projectRoot: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Find which config file exists (if any)
|
|
17
|
+
*/
|
|
18
|
+
protected findConfig(projectRoot: string): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Check if an error indicates the tool is not installed
|
|
21
|
+
*/
|
|
22
|
+
protected isNotInstalledError(error: unknown): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Create a skip result for when config is missing
|
|
25
|
+
*/
|
|
26
|
+
protected skipNoConfig(duration: number): CheckResult;
|
|
27
|
+
/**
|
|
28
|
+
* Create a skip result for when tool is not installed
|
|
29
|
+
*/
|
|
30
|
+
protected skipNotInstalled(duration: number): CheckResult;
|
|
31
|
+
/**
|
|
32
|
+
* Create a pass result
|
|
33
|
+
*/
|
|
34
|
+
protected pass(duration: number): CheckResult;
|
|
35
|
+
/**
|
|
36
|
+
* Create a fail result from violations
|
|
37
|
+
*/
|
|
38
|
+
protected fail(violations: Violation[], duration: number): CheckResult;
|
|
39
|
+
/**
|
|
40
|
+
* Create a result from violations (pass if empty, fail otherwise)
|
|
41
|
+
*/
|
|
42
|
+
protected fromViolations(violations: Violation[], duration: number): CheckResult;
|
|
43
|
+
/**
|
|
44
|
+
* Run the tool - must be implemented by subclasses
|
|
45
|
+
*/
|
|
46
|
+
abstract run(projectRoot: string): Promise<CheckResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Default audit implementation - checks if config exists
|
|
49
|
+
*/
|
|
50
|
+
audit(projectRoot: string): Promise<CheckResult>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/code/tools/base.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAE9B;;;GAGG;AACH,8BAAsB,cAAe,YAAW,WAAW;IACzD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAExC;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAMjD;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASxD;;OAEG;IACH,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAMtD;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW;IASrD;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW;IASzD;;OAEG;IACH,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW;IAI7C;;OAEG;IACH,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW;IAItE;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW;IAIhF;;OAEG;IACH,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAEvD;;OAEG;IACG,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAqBvD"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { CheckResult, } from "../../types/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Abstract base class for tool runners.
|
|
6
|
+
* Provides common functionality for checking configs and handling errors.
|
|
7
|
+
*/
|
|
8
|
+
export class BaseToolRunner {
|
|
9
|
+
/**
|
|
10
|
+
* Check if any of the config files exist
|
|
11
|
+
*/
|
|
12
|
+
hasConfig(projectRoot) {
|
|
13
|
+
return this.configFiles.some((config) => fs.existsSync(path.join(projectRoot, config)));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Find which config file exists (if any)
|
|
17
|
+
*/
|
|
18
|
+
findConfig(projectRoot) {
|
|
19
|
+
for (const config of this.configFiles) {
|
|
20
|
+
if (fs.existsSync(path.join(projectRoot, config))) {
|
|
21
|
+
return config;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if an error indicates the tool is not installed
|
|
28
|
+
*/
|
|
29
|
+
isNotInstalledError(error) {
|
|
30
|
+
if (!(error instanceof Error))
|
|
31
|
+
return false;
|
|
32
|
+
const message = error.message.toLowerCase();
|
|
33
|
+
return message.includes("enoent") || message.includes("not found");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a skip result for when config is missing
|
|
37
|
+
*/
|
|
38
|
+
skipNoConfig(duration) {
|
|
39
|
+
return CheckResult.skip(this.name, this.rule, `No ${this.name} config found`, duration);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a skip result for when tool is not installed
|
|
43
|
+
*/
|
|
44
|
+
skipNotInstalled(duration) {
|
|
45
|
+
return CheckResult.skip(this.name, this.rule, `${this.name} not installed`, duration);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create a pass result
|
|
49
|
+
*/
|
|
50
|
+
pass(duration) {
|
|
51
|
+
return CheckResult.pass(this.name, this.rule, duration);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a fail result from violations
|
|
55
|
+
*/
|
|
56
|
+
fail(violations, duration) {
|
|
57
|
+
return CheckResult.fail(this.name, this.rule, violations, duration);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create a result from violations (pass if empty, fail otherwise)
|
|
61
|
+
*/
|
|
62
|
+
fromViolations(violations, duration) {
|
|
63
|
+
return CheckResult.fromViolations(this.name, this.rule, violations, duration);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Default audit implementation - checks if config exists
|
|
67
|
+
*/
|
|
68
|
+
async audit(projectRoot) {
|
|
69
|
+
const startTime = Date.now();
|
|
70
|
+
if (this.hasConfig(projectRoot)) {
|
|
71
|
+
return CheckResult.pass(`${this.name} Config`, this.rule, Date.now() - startTime);
|
|
72
|
+
}
|
|
73
|
+
return CheckResult.fail(`${this.name} Config`, this.rule, [
|
|
74
|
+
{
|
|
75
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
76
|
+
tool: "audit",
|
|
77
|
+
message: `${this.name} config not found. Expected one of: ${this.configFiles.join(", ")}`,
|
|
78
|
+
severity: "error",
|
|
79
|
+
},
|
|
80
|
+
], Date.now() - startTime);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/code/tools/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CheckResult } from "../../types/index.js";
|
|
2
|
+
import { BaseToolRunner } from "./base.js";
|
|
3
|
+
/**
|
|
4
|
+
* ESLint tool runner
|
|
5
|
+
*/
|
|
6
|
+
export declare class ESLintRunner extends BaseToolRunner {
|
|
7
|
+
readonly name = "ESLint";
|
|
8
|
+
readonly rule = "code.linting";
|
|
9
|
+
readonly toolId = "eslint";
|
|
10
|
+
readonly configFiles: string[];
|
|
11
|
+
run(projectRoot: string): Promise<CheckResult>;
|
|
12
|
+
private parseOutput;
|
|
13
|
+
private createErrorViolation;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=eslint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../../../src/code/tools/eslint.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAiB3C;;GAEG;AACH,qBAAa,YAAa,SAAQ,cAAc;IAC9C,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,MAAM,YAAY;IAC3B,QAAQ,CAAC,WAAW,WAQlB;IAEI,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsCpD,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,oBAAoB;CAQ7B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import { BaseToolRunner } from "./base.js";
|
|
4
|
+
/**
|
|
5
|
+
* ESLint tool runner
|
|
6
|
+
*/
|
|
7
|
+
export class ESLintRunner extends BaseToolRunner {
|
|
8
|
+
name = "ESLint";
|
|
9
|
+
rule = "code.linting";
|
|
10
|
+
toolId = "eslint";
|
|
11
|
+
configFiles = [
|
|
12
|
+
"eslint.config.js",
|
|
13
|
+
"eslint.config.mjs",
|
|
14
|
+
"eslint.config.cjs",
|
|
15
|
+
".eslintrc.js",
|
|
16
|
+
".eslintrc.json",
|
|
17
|
+
".eslintrc.yml",
|
|
18
|
+
".eslintrc.yaml",
|
|
19
|
+
];
|
|
20
|
+
async run(projectRoot) {
|
|
21
|
+
const startTime = Date.now();
|
|
22
|
+
if (!this.hasConfig(projectRoot)) {
|
|
23
|
+
return this.skipNoConfig(Date.now() - startTime);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const result = await execa("npx", ["eslint", ".", "--format", "json"], {
|
|
27
|
+
cwd: projectRoot,
|
|
28
|
+
reject: false,
|
|
29
|
+
timeout: 5 * 60 * 1000,
|
|
30
|
+
});
|
|
31
|
+
const violations = this.parseOutput(result.stdout, projectRoot);
|
|
32
|
+
// Handle parse failure with non-zero exit
|
|
33
|
+
if (violations === null && result.exitCode !== 0 && result.stderr) {
|
|
34
|
+
return this.fail([this.createErrorViolation(`ESLint error: ${result.stderr}`)], Date.now() - startTime);
|
|
35
|
+
}
|
|
36
|
+
return this.fromViolations(violations ?? [], Date.now() - startTime);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (this.isNotInstalledError(error)) {
|
|
40
|
+
return this.skipNotInstalled(Date.now() - startTime);
|
|
41
|
+
}
|
|
42
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
43
|
+
return this.fail([this.createErrorViolation(`ESLint error: ${message}`)], Date.now() - startTime);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
parseOutput(stdout, projectRoot) {
|
|
47
|
+
try {
|
|
48
|
+
const results = JSON.parse(stdout);
|
|
49
|
+
const violations = [];
|
|
50
|
+
for (const fileResult of results) {
|
|
51
|
+
for (const msg of fileResult.messages) {
|
|
52
|
+
violations.push({
|
|
53
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
54
|
+
tool: this.toolId,
|
|
55
|
+
file: path.relative(projectRoot, fileResult.filePath),
|
|
56
|
+
line: msg.line,
|
|
57
|
+
column: msg.column,
|
|
58
|
+
message: msg.message,
|
|
59
|
+
code: msg.ruleId ?? undefined,
|
|
60
|
+
severity: msg.severity === 2 ? "error" : "warning",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return violations;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
createErrorViolation(message) {
|
|
71
|
+
return {
|
|
72
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
73
|
+
tool: this.toolId,
|
|
74
|
+
message,
|
|
75
|
+
severity: "error",
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=eslint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../../src/code/tools/eslint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/code/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type CheckResult } from "../../types/index.js";
|
|
2
|
+
import { BaseToolRunner } from "./base.js";
|
|
3
|
+
/**
|
|
4
|
+
* Ruff (Python linter) tool runner
|
|
5
|
+
*/
|
|
6
|
+
export declare class RuffRunner extends BaseToolRunner {
|
|
7
|
+
readonly name = "Ruff";
|
|
8
|
+
readonly rule = "code.linting";
|
|
9
|
+
readonly toolId = "ruff";
|
|
10
|
+
readonly configFiles: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Override hasConfig to also check for [tool.ruff] in pyproject.toml
|
|
13
|
+
*/
|
|
14
|
+
protected hasConfig(projectRoot: string): boolean;
|
|
15
|
+
private hasPyprojectConfig;
|
|
16
|
+
private hasPythonFiles;
|
|
17
|
+
run(projectRoot: string): Promise<CheckResult>;
|
|
18
|
+
private skip;
|
|
19
|
+
private parseOutput;
|
|
20
|
+
private createErrorViolation;
|
|
21
|
+
/**
|
|
22
|
+
* Override audit to include pyproject.toml check
|
|
23
|
+
*/
|
|
24
|
+
audit(projectRoot: string): Promise<CheckResult>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ruff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruff.d.ts","sourceRoot":"","sources":["../../../src/code/tools/ruff.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAa3C;;GAEG;AACH,qBAAa,UAAW,SAAQ,cAAc;IAC5C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,MAAM,UAAU;IACzB,QAAQ,CAAC,WAAW,WAA+B;IAEnD;;OAEG;cACgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAU1D,OAAO,CAAC,kBAAkB;YAcZ,cAAc;IAYtB,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAuCpD,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACY,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CA+BhE"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { execa } from "execa";
|
|
4
|
+
import { BaseToolRunner } from "./base.js";
|
|
5
|
+
/**
|
|
6
|
+
* Ruff (Python linter) tool runner
|
|
7
|
+
*/
|
|
8
|
+
export class RuffRunner extends BaseToolRunner {
|
|
9
|
+
name = "Ruff";
|
|
10
|
+
rule = "code.linting";
|
|
11
|
+
toolId = "ruff";
|
|
12
|
+
configFiles = ["ruff.toml", ".ruff.toml"];
|
|
13
|
+
/**
|
|
14
|
+
* Override hasConfig to also check for [tool.ruff] in pyproject.toml
|
|
15
|
+
*/
|
|
16
|
+
hasConfig(projectRoot) {
|
|
17
|
+
// Check dedicated config files
|
|
18
|
+
if (super.hasConfig(projectRoot)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
// Check pyproject.toml for [tool.ruff] section
|
|
22
|
+
return this.hasPyprojectConfig(projectRoot);
|
|
23
|
+
}
|
|
24
|
+
hasPyprojectConfig(projectRoot) {
|
|
25
|
+
const pyprojectPath = path.join(projectRoot, "pyproject.toml");
|
|
26
|
+
if (!fs.existsSync(pyprojectPath)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const content = fs.readFileSync(pyprojectPath, "utf-8");
|
|
31
|
+
return content.includes("[tool.ruff]");
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async hasPythonFiles(projectRoot) {
|
|
38
|
+
try {
|
|
39
|
+
const result = await execa("find", [".", "-name", "*.py", "-type", "f"], {
|
|
40
|
+
cwd: projectRoot,
|
|
41
|
+
reject: false,
|
|
42
|
+
});
|
|
43
|
+
return Boolean(result.stdout.trim());
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async run(projectRoot) {
|
|
50
|
+
const startTime = Date.now();
|
|
51
|
+
// Skip if no Python files
|
|
52
|
+
if (!(await this.hasPythonFiles(projectRoot))) {
|
|
53
|
+
return this.skip("No Python files found", Date.now() - startTime);
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const result = await execa("ruff", ["check", ".", "--output-format", "json"], {
|
|
57
|
+
cwd: projectRoot,
|
|
58
|
+
reject: false,
|
|
59
|
+
timeout: 5 * 60 * 1000,
|
|
60
|
+
});
|
|
61
|
+
const violations = this.parseOutput(result.stdout, projectRoot);
|
|
62
|
+
// Handle parse failure with non-zero exit
|
|
63
|
+
if (violations === null && result.exitCode !== 0 && result.stderr) {
|
|
64
|
+
return this.fail([this.createErrorViolation(`Ruff error: ${result.stderr}`)], Date.now() - startTime);
|
|
65
|
+
}
|
|
66
|
+
return this.fromViolations(violations ?? [], Date.now() - startTime);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (this.isNotInstalledError(error)) {
|
|
70
|
+
return this.skipNotInstalled(Date.now() - startTime);
|
|
71
|
+
}
|
|
72
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
73
|
+
return this.fail([this.createErrorViolation(`Ruff error: ${message}`)], Date.now() - startTime);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
skip(reason, duration) {
|
|
77
|
+
return {
|
|
78
|
+
name: this.name,
|
|
79
|
+
rule: this.rule,
|
|
80
|
+
passed: true,
|
|
81
|
+
violations: [],
|
|
82
|
+
skipped: true,
|
|
83
|
+
skipReason: reason,
|
|
84
|
+
duration,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
parseOutput(stdout, projectRoot) {
|
|
88
|
+
if (!stdout.trim()) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const results = JSON.parse(stdout);
|
|
93
|
+
return results.map((msg) => ({
|
|
94
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
95
|
+
tool: this.toolId,
|
|
96
|
+
file: path.relative(projectRoot, msg.filename),
|
|
97
|
+
line: msg.location.row,
|
|
98
|
+
column: msg.location.column,
|
|
99
|
+
message: msg.message,
|
|
100
|
+
code: msg.code,
|
|
101
|
+
severity: "error",
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
createErrorViolation(message) {
|
|
109
|
+
return {
|
|
110
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
111
|
+
tool: this.toolId,
|
|
112
|
+
message,
|
|
113
|
+
severity: "error",
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Override audit to include pyproject.toml check
|
|
118
|
+
*/
|
|
119
|
+
async audit(projectRoot) {
|
|
120
|
+
const startTime = Date.now();
|
|
121
|
+
if (this.hasConfig(projectRoot)) {
|
|
122
|
+
return {
|
|
123
|
+
name: `${this.name} Config`,
|
|
124
|
+
rule: this.rule,
|
|
125
|
+
passed: true,
|
|
126
|
+
violations: [],
|
|
127
|
+
skipped: false,
|
|
128
|
+
duration: Date.now() - startTime,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const allConfigs = [...this.configFiles, "pyproject.toml [tool.ruff]"];
|
|
132
|
+
return {
|
|
133
|
+
name: `${this.name} Config`,
|
|
134
|
+
rule: this.rule,
|
|
135
|
+
passed: false,
|
|
136
|
+
violations: [
|
|
137
|
+
{
|
|
138
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
139
|
+
tool: "audit",
|
|
140
|
+
message: `Ruff config not found. Expected one of: ${allConfigs.join(", ")}`,
|
|
141
|
+
severity: "error",
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
skipped: false,
|
|
145
|
+
duration: Date.now() - startTime,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=ruff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruff.js","sourceRoot":"","sources":["../../../src/code/tools/ruff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type CheckResult } from "../../types/index.js";
|
|
2
|
+
import { BaseToolRunner } from "./base.js";
|
|
3
|
+
/**
|
|
4
|
+
* TypeScript type checker tool runner
|
|
5
|
+
*/
|
|
6
|
+
export declare class TscRunner extends BaseToolRunner {
|
|
7
|
+
readonly name = "TypeScript";
|
|
8
|
+
readonly rule = "code.types";
|
|
9
|
+
readonly toolId = "tsc";
|
|
10
|
+
readonly configFiles: string[];
|
|
11
|
+
run(projectRoot: string): Promise<CheckResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Parse tsc output into diagnostics
|
|
14
|
+
* Format: file(line,col): error TSxxxx: message
|
|
15
|
+
*/
|
|
16
|
+
private parseOutput;
|
|
17
|
+
private parseDiagnostics;
|
|
18
|
+
private createErrorViolation;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=tsc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsc.d.ts","sourceRoot":"","sources":["../../../src/code/tools/tsc.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAW3C;;GAEG;AACH,qBAAa,SAAU,SAAQ,cAAc;IAC3C,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,MAAM,SAAS;IACxB,QAAQ,CAAC,WAAW,WAAqB;IAEnC,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA8CpD;;;OAGG;IACH,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,oBAAoB;CAQ7B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import { BaseToolRunner } from "./base.js";
|
|
4
|
+
/**
|
|
5
|
+
* TypeScript type checker tool runner
|
|
6
|
+
*/
|
|
7
|
+
export class TscRunner extends BaseToolRunner {
|
|
8
|
+
name = "TypeScript";
|
|
9
|
+
rule = "code.types";
|
|
10
|
+
toolId = "tsc";
|
|
11
|
+
configFiles = ["tsconfig.json"];
|
|
12
|
+
async run(projectRoot) {
|
|
13
|
+
const startTime = Date.now();
|
|
14
|
+
if (!this.hasConfig(projectRoot)) {
|
|
15
|
+
return this.skipNoConfig(Date.now() - startTime);
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const result = await execa("npx", ["tsc", "--noEmit"], {
|
|
19
|
+
cwd: projectRoot,
|
|
20
|
+
reject: false,
|
|
21
|
+
timeout: 5 * 60 * 1000,
|
|
22
|
+
});
|
|
23
|
+
// tsc exits with 0 if no errors
|
|
24
|
+
if (result.exitCode === 0) {
|
|
25
|
+
return this.pass(Date.now() - startTime);
|
|
26
|
+
}
|
|
27
|
+
const violations = this.parseOutput(result.stdout, projectRoot);
|
|
28
|
+
// If we couldn't parse any diagnostics but tsc failed, report raw output
|
|
29
|
+
if (violations.length === 0) {
|
|
30
|
+
const errorOutput = result.stdout || result.stderr;
|
|
31
|
+
if (errorOutput) {
|
|
32
|
+
return this.fail([this.createErrorViolation(`TypeScript error: ${errorOutput.slice(0, 500)}`)], Date.now() - startTime);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return this.fromViolations(violations, Date.now() - startTime);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (this.isNotInstalledError(error)) {
|
|
39
|
+
return this.skipNotInstalled(Date.now() - startTime);
|
|
40
|
+
}
|
|
41
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
42
|
+
return this.fail([this.createErrorViolation(`TypeScript error: ${message}`)], Date.now() - startTime);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse tsc output into diagnostics
|
|
47
|
+
* Format: file(line,col): error TSxxxx: message
|
|
48
|
+
*/
|
|
49
|
+
parseOutput(stdout, projectRoot) {
|
|
50
|
+
const diagnostics = this.parseDiagnostics(stdout, projectRoot);
|
|
51
|
+
return diagnostics.map((diag) => ({
|
|
52
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
53
|
+
tool: this.toolId,
|
|
54
|
+
file: diag.file,
|
|
55
|
+
line: diag.line,
|
|
56
|
+
column: diag.column,
|
|
57
|
+
message: diag.message,
|
|
58
|
+
code: `TS${diag.code}`,
|
|
59
|
+
severity: "error",
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
parseDiagnostics(output, projectRoot) {
|
|
63
|
+
const diagnostics = [];
|
|
64
|
+
const lines = output.split("\n");
|
|
65
|
+
const errorRegex = /^(.+?)\((\d+),(\d+)\):\s*error\s+TS(\d+):\s*(.+)$/;
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
const match = errorRegex.exec(line);
|
|
68
|
+
if (match) {
|
|
69
|
+
const [, filePath, lineNum, colNum, code, message] = match;
|
|
70
|
+
diagnostics.push({
|
|
71
|
+
file: path.relative(projectRoot, filePath),
|
|
72
|
+
line: parseInt(lineNum, 10),
|
|
73
|
+
column: parseInt(colNum, 10),
|
|
74
|
+
code: parseInt(code, 10),
|
|
75
|
+
message: message.trim(),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return diagnostics;
|
|
80
|
+
}
|
|
81
|
+
createErrorViolation(message) {
|
|
82
|
+
return {
|
|
83
|
+
rule: `${this.rule}.${this.toolId}`,
|
|
84
|
+
tool: this.toolId,
|
|
85
|
+
message,
|
|
86
|
+
severity: "error",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=tsc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsc.js","sourceRoot":"","sources":["../../../src/code/tools/tsc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/code/types.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAsCrE;;GAEG;AACH,wBAAsB,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA4GtE"}
|