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.
Files changed (122) hide show
  1. package/README.md +2 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +116 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/code/audit.d.ts +14 -0
  7. package/dist/code/audit.d.ts.map +1 -0
  8. package/dist/code/audit.js +130 -0
  9. package/dist/code/audit.js.map +1 -0
  10. package/dist/code/index.d.ts +13 -0
  11. package/dist/code/index.d.ts.map +1 -0
  12. package/dist/code/index.js +49 -0
  13. package/dist/code/index.js.map +1 -0
  14. package/dist/code/linting.d.ts +10 -0
  15. package/dist/code/linting.d.ts.map +1 -0
  16. package/dist/code/linting.js +233 -0
  17. package/dist/code/linting.js.map +1 -0
  18. package/dist/code/tools/base.d.ts +52 -0
  19. package/dist/code/tools/base.d.ts.map +1 -0
  20. package/dist/code/tools/base.js +83 -0
  21. package/dist/code/tools/base.js.map +1 -0
  22. package/dist/code/tools/eslint.d.ts +15 -0
  23. package/dist/code/tools/eslint.d.ts.map +1 -0
  24. package/dist/code/tools/eslint.js +79 -0
  25. package/dist/code/tools/eslint.js.map +1 -0
  26. package/dist/code/tools/index.d.ts +5 -0
  27. package/dist/code/tools/index.d.ts.map +1 -0
  28. package/dist/code/tools/index.js +5 -0
  29. package/dist/code/tools/index.js.map +1 -0
  30. package/dist/code/tools/ruff.d.ts +26 -0
  31. package/dist/code/tools/ruff.d.ts.map +1 -0
  32. package/dist/code/tools/ruff.js +149 -0
  33. package/dist/code/tools/ruff.js.map +1 -0
  34. package/dist/code/tools/tsc.d.ts +20 -0
  35. package/dist/code/tools/tsc.d.ts.map +1 -0
  36. package/dist/code/tools/tsc.js +90 -0
  37. package/dist/code/tools/tsc.js.map +1 -0
  38. package/dist/code/types.d.ts +6 -0
  39. package/dist/code/types.d.ts.map +1 -0
  40. package/dist/code/types.js +132 -0
  41. package/dist/code/types.js.map +1 -0
  42. package/dist/config/index.d.ts +3 -0
  43. package/dist/config/index.d.ts.map +1 -0
  44. package/dist/config/index.js +3 -0
  45. package/dist/config/index.js.map +1 -0
  46. package/dist/config/loader.d.ts +21 -0
  47. package/dist/config/loader.d.ts.map +1 -0
  48. package/dist/config/loader.js +118 -0
  49. package/dist/config/loader.js.map +1 -0
  50. package/dist/config/schema.d.ts +1217 -0
  51. package/dist/config/schema.d.ts.map +1 -0
  52. package/dist/config/schema.js +190 -0
  53. package/dist/config/schema.js.map +1 -0
  54. package/dist/index.d.ts +8 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +16 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/output/index.d.ts +15 -0
  59. package/dist/output/index.d.ts.map +1 -0
  60. package/dist/output/index.js +98 -0
  61. package/dist/output/index.js.map +1 -0
  62. package/dist/src/cli.d.ts +3 -0
  63. package/dist/src/cli.d.ts.map +1 -0
  64. package/dist/src/cli.js +116 -0
  65. package/dist/src/cli.js.map +1 -0
  66. package/dist/src/code/index.d.ts +13 -0
  67. package/dist/src/code/index.d.ts.map +1 -0
  68. package/dist/src/code/index.js +53 -0
  69. package/dist/src/code/index.js.map +1 -0
  70. package/dist/src/code/tools/base.d.ts +52 -0
  71. package/dist/src/code/tools/base.d.ts.map +1 -0
  72. package/dist/src/code/tools/base.js +83 -0
  73. package/dist/src/code/tools/base.js.map +1 -0
  74. package/dist/src/code/tools/eslint.d.ts +15 -0
  75. package/dist/src/code/tools/eslint.d.ts.map +1 -0
  76. package/dist/src/code/tools/eslint.js +79 -0
  77. package/dist/src/code/tools/eslint.js.map +1 -0
  78. package/dist/src/code/tools/index.d.ts +5 -0
  79. package/dist/src/code/tools/index.d.ts.map +1 -0
  80. package/dist/src/code/tools/index.js +5 -0
  81. package/dist/src/code/tools/index.js.map +1 -0
  82. package/dist/src/code/tools/ruff.d.ts +26 -0
  83. package/dist/src/code/tools/ruff.d.ts.map +1 -0
  84. package/dist/src/code/tools/ruff.js +149 -0
  85. package/dist/src/code/tools/ruff.js.map +1 -0
  86. package/dist/src/code/tools/tsc.d.ts +21 -0
  87. package/dist/src/code/tools/tsc.d.ts.map +1 -0
  88. package/dist/src/code/tools/tsc.js +94 -0
  89. package/dist/src/code/tools/tsc.js.map +1 -0
  90. package/dist/src/config/index.d.ts +3 -0
  91. package/dist/src/config/index.d.ts.map +1 -0
  92. package/dist/src/config/index.js +3 -0
  93. package/dist/src/config/index.js.map +1 -0
  94. package/dist/src/config/loader.d.ts +22 -0
  95. package/dist/src/config/loader.d.ts.map +1 -0
  96. package/dist/src/config/loader.js +124 -0
  97. package/dist/src/config/loader.js.map +1 -0
  98. package/dist/src/config/schema.d.ts +503 -0
  99. package/dist/src/config/schema.d.ts.map +1 -0
  100. package/dist/src/config/schema.js +190 -0
  101. package/dist/src/config/schema.js.map +1 -0
  102. package/dist/src/index.d.ts +8 -0
  103. package/dist/src/index.d.ts.map +1 -0
  104. package/dist/src/index.js +16 -0
  105. package/dist/src/index.js.map +1 -0
  106. package/dist/src/output/index.d.ts +15 -0
  107. package/dist/src/output/index.d.ts.map +1 -0
  108. package/dist/src/output/index.js +96 -0
  109. package/dist/src/output/index.js.map +1 -0
  110. package/dist/src/types/index.d.ts +96 -0
  111. package/dist/src/types/index.d.ts.map +1 -0
  112. package/dist/src/types/index.js +89 -0
  113. package/dist/src/types/index.js.map +1 -0
  114. package/dist/tests/e2e/e2e.test.d.ts +2 -0
  115. package/dist/tests/e2e/e2e.test.d.ts.map +1 -0
  116. package/dist/tests/e2e/e2e.test.js +398 -0
  117. package/dist/tests/e2e/e2e.test.js.map +1 -0
  118. package/dist/types/index.d.ts +96 -0
  119. package/dist/types/index.d.ts.map +1 -0
  120. package/dist/types/index.js +89 -0
  121. package/dist/types/index.js.map +1 -0
  122. 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,5 @@
1
+ export { BaseToolRunner } from "./base.js";
2
+ export { ESLintRunner } from "./eslint.js";
3
+ export { RuffRunner } from "./ruff.js";
4
+ export { TscRunner } from "./tsc.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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,5 @@
1
+ export { BaseToolRunner } from "./base.js";
2
+ export { ESLintRunner } from "./eslint.js";
3
+ export { RuffRunner } from "./ruff.js";
4
+ export { TscRunner } from "./tsc.js";
5
+ //# sourceMappingURL=index.js.map
@@ -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":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAa3C;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,cAAc;IACnC,IAAI,GAAG,MAAM,CAAC;IACd,IAAI,GAAG,cAAc,CAAC;IACtB,MAAM,GAAG,MAAM,CAAC;IAChB,WAAW,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEnD;;OAEG;IACgB,SAAS,CAAC,WAAmB;QAC9C,+BAA+B;QAC/B,IAAI,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,+CAA+C;QAC/C,OAAO,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAEO,kBAAkB,CAAC,WAAmB;QAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,WAAmB;QAC9C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE;gBACvE,GAAG,EAAE,WAAW;gBAChB,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,0BAA0B;QAC1B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE;gBAC5E,GAAG,EAAE,WAAW;gBAChB,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;aACvB,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAEhE,0CAA0C;YAC1C,IAAI,UAAU,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClE,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,IAAI,CAAC,oBAAoB,CAAC,eAAe,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAC3D,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CACvB,CAAC;YACJ,CAAC;YAED,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YACvD,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACzE,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,IAAI,CAAC,oBAAoB,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC,EACrD,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CACvB,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,IAAI,CAAC,MAAc,EAAE,QAAgB;QAC3C,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,EAAE;YACd,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,MAAM;YAClB,QAAQ;SACT,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,MAAc,EAAE,WAAmB;QACrD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAkB,CAAC;YACpD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC3B,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;gBACnC,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC;gBAC9C,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG;gBACtB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM;gBAC3B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,QAAQ,EAAE,OAAgB;aAC3B,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,OAAe;QAC1C,OAAO;YACL,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;YACnC,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,OAAO;YACP,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED;;OAEG;IACM,KAAK,CAAC,KAAK,CAAC,WAAmB;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO;gBACL,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,SAAS;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI;gBACZ,UAAU,EAAE,EAAE;gBACd,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACjC,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;QACvE,OAAO;YACL,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,SAAS;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,KAAK;YACb,UAAU,EAAE;gBACV;oBACE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;oBACnC,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,2CAA2C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBAC3E,QAAQ,EAAE,OAAO;iBAClB;aACF;YACD,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACjC,CAAC;IACJ,CAAC;CACF"}
@@ -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,6 @@
1
+ import { type CheckResult } from "../types/index.js";
2
+ /**
3
+ * Run TypeScript type checking and return violations
4
+ */
5
+ export declare function runTsc(projectRoot: string): Promise<CheckResult>;
6
+ //# sourceMappingURL=types.d.ts.map
@@ -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"}