ghagga-core 2.3.0 → 2.4.1

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 (111) hide show
  1. package/dist/format.d.ts.map +1 -1
  2. package/dist/format.js +23 -1
  3. package/dist/format.js.map +1 -1
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/pipeline.d.ts.map +1 -1
  9. package/dist/pipeline.js +36 -19
  10. package/dist/pipeline.js.map +1 -1
  11. package/dist/tools/budget.d.ts +26 -0
  12. package/dist/tools/budget.d.ts.map +1 -0
  13. package/dist/tools/budget.js +78 -0
  14. package/dist/tools/budget.js.map +1 -0
  15. package/dist/tools/execution.d.ts +18 -0
  16. package/dist/tools/execution.d.ts.map +1 -0
  17. package/dist/tools/execution.js +82 -0
  18. package/dist/tools/execution.js.map +1 -0
  19. package/dist/tools/index.d.ts +16 -0
  20. package/dist/tools/index.d.ts.map +1 -0
  21. package/dist/tools/index.js +20 -0
  22. package/dist/tools/index.js.map +1 -0
  23. package/dist/tools/orchestrator.d.ts +24 -0
  24. package/dist/tools/orchestrator.d.ts.map +1 -0
  25. package/dist/tools/orchestrator.js +127 -0
  26. package/dist/tools/orchestrator.js.map +1 -0
  27. package/dist/tools/plugins/bandit.d.ts +22 -0
  28. package/dist/tools/plugins/bandit.d.ts.map +1 -0
  29. package/dist/tools/plugins/bandit.js +79 -0
  30. package/dist/tools/plugins/bandit.js.map +1 -0
  31. package/dist/tools/plugins/biome.d.ts +22 -0
  32. package/dist/tools/plugins/biome.d.ts.map +1 -0
  33. package/dist/tools/plugins/biome.js +80 -0
  34. package/dist/tools/plugins/biome.js.map +1 -0
  35. package/dist/tools/plugins/clippy.d.ts +25 -0
  36. package/dist/tools/plugins/clippy.d.ts.map +1 -0
  37. package/dist/tools/plugins/clippy.js +95 -0
  38. package/dist/tools/plugins/clippy.js.map +1 -0
  39. package/dist/tools/plugins/cpd.d.ts +20 -0
  40. package/dist/tools/plugins/cpd.d.ts.map +1 -0
  41. package/dist/tools/plugins/cpd.js +111 -0
  42. package/dist/tools/plugins/cpd.js.map +1 -0
  43. package/dist/tools/plugins/gitleaks.d.ts +18 -0
  44. package/dist/tools/plugins/gitleaks.d.ts.map +1 -0
  45. package/dist/tools/plugins/gitleaks.js +81 -0
  46. package/dist/tools/plugins/gitleaks.js.map +1 -0
  47. package/dist/tools/plugins/golangci-lint.d.ts +27 -0
  48. package/dist/tools/plugins/golangci-lint.d.ts.map +1 -0
  49. package/dist/tools/plugins/golangci-lint.js +87 -0
  50. package/dist/tools/plugins/golangci-lint.js.map +1 -0
  51. package/dist/tools/plugins/hadolint.d.ts +22 -0
  52. package/dist/tools/plugins/hadolint.d.ts.map +1 -0
  53. package/dist/tools/plugins/hadolint.js +99 -0
  54. package/dist/tools/plugins/hadolint.js.map +1 -0
  55. package/dist/tools/plugins/index.d.ts +37 -0
  56. package/dist/tools/plugins/index.d.ts.map +1 -0
  57. package/dist/tools/plugins/index.js +93 -0
  58. package/dist/tools/plugins/index.js.map +1 -0
  59. package/dist/tools/plugins/lizard.d.ts +24 -0
  60. package/dist/tools/plugins/lizard.d.ts.map +1 -0
  61. package/dist/tools/plugins/lizard.js +83 -0
  62. package/dist/tools/plugins/lizard.js.map +1 -0
  63. package/dist/tools/plugins/markdownlint.d.ts +17 -0
  64. package/dist/tools/plugins/markdownlint.d.ts.map +1 -0
  65. package/dist/tools/plugins/markdownlint.js +70 -0
  66. package/dist/tools/plugins/markdownlint.js.map +1 -0
  67. package/dist/tools/plugins/pmd.d.ts +23 -0
  68. package/dist/tools/plugins/pmd.d.ts.map +1 -0
  69. package/dist/tools/plugins/pmd.js +108 -0
  70. package/dist/tools/plugins/pmd.js.map +1 -0
  71. package/dist/tools/plugins/psalm.d.ts +24 -0
  72. package/dist/tools/plugins/psalm.d.ts.map +1 -0
  73. package/dist/tools/plugins/psalm.js +85 -0
  74. package/dist/tools/plugins/psalm.js.map +1 -0
  75. package/dist/tools/plugins/ruff.d.ts +22 -0
  76. package/dist/tools/plugins/ruff.d.ts.map +1 -0
  77. package/dist/tools/plugins/ruff.js +80 -0
  78. package/dist/tools/plugins/ruff.js.map +1 -0
  79. package/dist/tools/plugins/semgrep.d.ts +23 -0
  80. package/dist/tools/plugins/semgrep.d.ts.map +1 -0
  81. package/dist/tools/plugins/semgrep.js +82 -0
  82. package/dist/tools/plugins/semgrep.js.map +1 -0
  83. package/dist/tools/plugins/shellcheck.d.ts +23 -0
  84. package/dist/tools/plugins/shellcheck.d.ts.map +1 -0
  85. package/dist/tools/plugins/shellcheck.js +87 -0
  86. package/dist/tools/plugins/shellcheck.js.map +1 -0
  87. package/dist/tools/plugins/trivy.d.ts +25 -0
  88. package/dist/tools/plugins/trivy.d.ts.map +1 -0
  89. package/dist/tools/plugins/trivy.js +108 -0
  90. package/dist/tools/plugins/trivy.js.map +1 -0
  91. package/dist/tools/registry.d.ts +37 -0
  92. package/dist/tools/registry.d.ts.map +1 -0
  93. package/dist/tools/registry.js +61 -0
  94. package/dist/tools/registry.js.map +1 -0
  95. package/dist/tools/resolve.d.ts +37 -0
  96. package/dist/tools/resolve.d.ts.map +1 -0
  97. package/dist/tools/resolve.js +67 -0
  98. package/dist/tools/resolve.js.map +1 -0
  99. package/dist/tools/runner.d.ts +15 -1
  100. package/dist/tools/runner.d.ts.map +1 -1
  101. package/dist/tools/runner.js +76 -6
  102. package/dist/tools/runner.js.map +1 -1
  103. package/dist/tools/types.d.ts +83 -0
  104. package/dist/tools/types.d.ts.map +1 -0
  105. package/dist/tools/types.js +11 -0
  106. package/dist/tools/types.js.map +1 -0
  107. package/dist/types.d.ts +15 -3
  108. package/dist/types.d.ts.map +1 -1
  109. package/dist/types.js +2 -0
  110. package/dist/types.js.map +1 -1
  111. package/package.json +1 -1
@@ -0,0 +1,70 @@
1
+ /**
2
+ * markdownlint-cli2 plugin — Markdown documentation linting (always-on).
3
+ *
4
+ * Lints Markdown files for style and formatting issues.
5
+ * Only runs on *.md files; returns empty findings if none found.
6
+ *
7
+ * Uses ExecutionContext for DI instead of direct child_process.
8
+ */
9
+ const MARKDOWNLINT_VERSION = '0.17.1';
10
+ /**
11
+ * Parse markdownlint-cli2 JSON output into ReviewFinding[].
12
+ * Exported for direct testing with fixture data.
13
+ */
14
+ export function parseMarkdownlintOutput(raw, repoDir) {
15
+ if (raw.timedOut)
16
+ return [];
17
+ try {
18
+ const findings = JSON.parse(raw.stdout);
19
+ return findings.map((f) => {
20
+ const ruleName = f.ruleNames[0] ?? 'unknown';
21
+ const detail = f.errorDetail ? ` (${f.errorDetail})` : '';
22
+ return {
23
+ severity: 'info',
24
+ category: 'docs',
25
+ file: f.fileName.replace(`${repoDir}/`, ''),
26
+ line: f.lineNumber,
27
+ message: `${ruleName}: ${f.ruleDescription}${detail}`,
28
+ source: 'markdownlint',
29
+ };
30
+ });
31
+ }
32
+ catch {
33
+ return [];
34
+ }
35
+ }
36
+ export const markdownlintPlugin = {
37
+ name: 'markdownlint',
38
+ displayName: 'markdownlint-cli2',
39
+ category: 'docs',
40
+ tier: 'always-on',
41
+ version: MARKDOWNLINT_VERSION,
42
+ outputFormat: 'json',
43
+ async install(ctx) {
44
+ try {
45
+ await ctx.exec('markdownlint-cli2', ['--help'], { timeoutMs: 10_000 });
46
+ return;
47
+ }
48
+ catch {
49
+ ctx.log('info', 'markdownlint-cli2 not found, installing...');
50
+ }
51
+ await ctx.exec('npm', ['install', '-g', `markdownlint-cli2@${MARKDOWNLINT_VERSION}`], {
52
+ timeoutMs: 120_000,
53
+ });
54
+ await ctx.exec('markdownlint-cli2', ['--help'], { timeoutMs: 10_000 });
55
+ },
56
+ async run(ctx, _repoDir, files, timeout) {
57
+ // Filter to only Markdown files
58
+ const mdFiles = files.filter((f) => f.endsWith('.md'));
59
+ if (mdFiles.length === 0) {
60
+ // No Markdown files — return empty output
61
+ return { stdout: '[]', stderr: '', exitCode: 0, timedOut: false };
62
+ }
63
+ return ctx.exec('markdownlint-cli2', ['--config', '{}', ...mdFiles], {
64
+ timeoutMs: timeout,
65
+ allowExitCodes: [1], // markdownlint returns 1 when findings are present
66
+ });
67
+ },
68
+ parse: parseMarkdownlintOutput,
69
+ };
70
+ //# sourceMappingURL=markdownlint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownlint.js","sourceRoot":"","sources":["../../../src/tools/plugins/markdownlint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * PMD plugin — Java code quality analysis (auto-detect).
3
+ *
4
+ * Runs PMD static analysis with the quickstart ruleset.
5
+ * Shares installation with CPD (both use the PMD binary at /opt/pmd).
6
+ * Activates when Java or Kotlin files are detected.
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ import type { FindingSeverity, ReviewFinding } from '../../types.js';
11
+ import type { RawToolOutput, ToolDefinition } from '../types.js';
12
+ /**
13
+ * Map PMD violation priority to GHAGGA FindingSeverity.
14
+ * 1→critical, 2→high, 3→medium, 4→low, 5→info
15
+ */
16
+ export declare function mapPmdPriority(priority: number): FindingSeverity;
17
+ /**
18
+ * Parse PMD JSON output into ReviewFinding[].
19
+ * Exported for direct testing with fixture data.
20
+ */
21
+ export declare function parsePmdOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
22
+ export declare const pmdPlugin: ToolDefinition;
23
+ //# sourceMappingURL=pmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pmd.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/pmd.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAMnF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAehE;AAgBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAwBnF;AAED,eAAO,MAAM,SAAS,EAAE,cA+DvB,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * PMD plugin — Java code quality analysis (auto-detect).
3
+ *
4
+ * Runs PMD static analysis with the quickstart ruleset.
5
+ * Shares installation with CPD (both use the PMD binary at /opt/pmd).
6
+ * Activates when Java or Kotlin files are detected.
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ const PMD_VERSION = '7.8.0';
11
+ const PMD_HOME = '/opt/pmd';
12
+ const PMD_BIN = `${PMD_HOME}/bin/pmd`;
13
+ /**
14
+ * Map PMD violation priority to GHAGGA FindingSeverity.
15
+ * 1→critical, 2→high, 3→medium, 4→low, 5→info
16
+ */
17
+ export function mapPmdPriority(priority) {
18
+ switch (priority) {
19
+ case 1:
20
+ return 'critical';
21
+ case 2:
22
+ return 'high';
23
+ case 3:
24
+ return 'medium';
25
+ case 4:
26
+ return 'low';
27
+ case 5:
28
+ return 'info';
29
+ default:
30
+ return 'low';
31
+ }
32
+ }
33
+ /**
34
+ * Parse PMD JSON output into ReviewFinding[].
35
+ * Exported for direct testing with fixture data.
36
+ */
37
+ export function parsePmdOutput(raw, repoDir) {
38
+ if (raw.timedOut)
39
+ return [];
40
+ try {
41
+ const result = JSON.parse(raw.stdout);
42
+ const findings = [];
43
+ for (const file of result.files ?? []) {
44
+ for (const violation of file.violations) {
45
+ findings.push({
46
+ severity: mapPmdPriority(violation.priority),
47
+ category: 'quality',
48
+ file: file.filename.replace(`${repoDir}/`, ''),
49
+ line: violation.beginline,
50
+ message: `[${violation.rule}] ${violation.description}`,
51
+ source: 'pmd',
52
+ });
53
+ }
54
+ }
55
+ return findings;
56
+ }
57
+ catch {
58
+ return [];
59
+ }
60
+ }
61
+ export const pmdPlugin = {
62
+ name: 'pmd',
63
+ displayName: 'PMD',
64
+ category: 'quality',
65
+ tier: 'auto-detect',
66
+ version: PMD_VERSION,
67
+ outputFormat: 'json',
68
+ detect(files) {
69
+ return files.some((f) => /\.(java|kt)$/.test(f));
70
+ },
71
+ async install(ctx) {
72
+ // PMD may already be installed via CPD plugin (shared binary)
73
+ try {
74
+ await ctx.exec(PMD_BIN, ['--version'], { timeoutMs: 10_000 });
75
+ return;
76
+ }
77
+ catch {
78
+ ctx.log('info', 'PMD not found, installing (shared with CPD)...');
79
+ }
80
+ const cached = await ctx.cacheRestore('cpd', [PMD_HOME]);
81
+ if (cached) {
82
+ try {
83
+ await ctx.exec(PMD_BIN, ['--version'], { timeoutMs: 10_000 });
84
+ return;
85
+ }
86
+ catch {
87
+ ctx.log('warn', 'PMD cache restored but binary not functional, reinstalling');
88
+ }
89
+ }
90
+ await ctx.exec('bash', [
91
+ '-c',
92
+ `curl -sL "https://github.com/pmd/pmd/releases/download/pmd_releases%2F${PMD_VERSION}/pmd-dist-${PMD_VERSION}-bin.zip" -o /tmp/pmd.zip && ` +
93
+ `unzip -q /tmp/pmd.zip -d /opt && ` +
94
+ `mv /opt/pmd-bin-${PMD_VERSION} ${PMD_HOME} && ` +
95
+ `rm -f /tmp/pmd.zip`,
96
+ ], { timeoutMs: 120_000 });
97
+ await ctx.exec(PMD_BIN, ['--version'], { timeoutMs: 10_000 });
98
+ await ctx.cacheSave('cpd', [PMD_HOME]);
99
+ },
100
+ async run(ctx, repoDir, _files, timeout) {
101
+ return ctx.exec(PMD_BIN, ['check', '--format', 'json', '--dir', repoDir, '--rulesets', 'rulesets/java/quickstart.xml'], {
102
+ timeoutMs: timeout,
103
+ allowExitCodes: [4], // PMD returns 4 when violations are found
104
+ });
105
+ },
106
+ parse: parsePmdOutput,
107
+ };
108
+ //# sourceMappingURL=pmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pmd.js","sourceRoot":"","sources":["../../../src/tools/plugins/pmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Psalm plugin — PHP static analysis (auto-detect).
3
+ *
4
+ * Runs Psalm for type checking and security analysis on PHP codebases.
5
+ * Activates when PHP files or composer.json is detected.
6
+ * Maps taint-related findings to critical severity.
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ import type { FindingSeverity, ReviewFinding } from '../../types.js';
11
+ import type { RawToolOutput, ToolDefinition } from '../types.js';
12
+ /**
13
+ * Map Psalm finding to GHAGGA FindingSeverity.
14
+ * Taint findings (e.g., TaintedHtml, TaintedSql) → critical.
15
+ * error → high, info → low, default → medium
16
+ */
17
+ export declare function mapPsalmSeverity(severity: string, type: string): FindingSeverity;
18
+ /**
19
+ * Parse Psalm JSON output into ReviewFinding[].
20
+ * Exported for direct testing with fixture data.
21
+ */
22
+ export declare function parsePsalmOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
23
+ export declare const psalmPlugin: ToolDefinition;
24
+ //# sourceMappingURL=psalm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"psalm.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/psalm.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAInF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAYhF;AAYD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAiBrF;AAED,eAAO,MAAM,WAAW,EAAE,cA0CzB,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Psalm plugin — PHP static analysis (auto-detect).
3
+ *
4
+ * Runs Psalm for type checking and security analysis on PHP codebases.
5
+ * Activates when PHP files or composer.json is detected.
6
+ * Maps taint-related findings to critical severity.
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ const PSALM_VERSION = '6.5.1';
11
+ /**
12
+ * Map Psalm finding to GHAGGA FindingSeverity.
13
+ * Taint findings (e.g., TaintedHtml, TaintedSql) → critical.
14
+ * error → high, info → low, default → medium
15
+ */
16
+ export function mapPsalmSeverity(severity, type) {
17
+ // Taint findings are always critical regardless of severity
18
+ if (type.toLowerCase().startsWith('tainted'))
19
+ return 'critical';
20
+ switch (severity.toLowerCase()) {
21
+ case 'error':
22
+ return 'high';
23
+ case 'info':
24
+ return 'low';
25
+ default:
26
+ return 'medium';
27
+ }
28
+ }
29
+ /**
30
+ * Parse Psalm JSON output into ReviewFinding[].
31
+ * Exported for direct testing with fixture data.
32
+ */
33
+ export function parsePsalmOutput(raw, repoDir) {
34
+ if (raw.timedOut)
35
+ return [];
36
+ try {
37
+ const findings = JSON.parse(raw.stdout);
38
+ return findings.map((f) => ({
39
+ severity: mapPsalmSeverity(f.severity, f.type),
40
+ category: 'quality',
41
+ file: f.file_path.replace(`${repoDir}/`, ''),
42
+ line: f.line_from,
43
+ message: `[${f.type}] ${f.message}`,
44
+ source: 'psalm',
45
+ }));
46
+ }
47
+ catch {
48
+ return [];
49
+ }
50
+ }
51
+ export const psalmPlugin = {
52
+ name: 'psalm',
53
+ displayName: 'Psalm',
54
+ category: 'quality',
55
+ tier: 'auto-detect',
56
+ version: PSALM_VERSION,
57
+ outputFormat: 'json',
58
+ detect(files) {
59
+ return files.some((f) => f.endsWith('.php') || f === 'composer.json');
60
+ },
61
+ async install(ctx) {
62
+ // Check if Psalm PHAR is already available
63
+ try {
64
+ await ctx.exec('psalm', ['--version'], { timeoutMs: 10_000 });
65
+ return;
66
+ }
67
+ catch {
68
+ ctx.log('info', 'Psalm not found, installing...');
69
+ }
70
+ // Install via Composer global
71
+ await ctx.exec('composer', ['global', 'require', `vimeo/psalm:${PSALM_VERSION}`], {
72
+ timeoutMs: 120_000,
73
+ });
74
+ await ctx.exec('psalm', ['--version'], { timeoutMs: 10_000 });
75
+ },
76
+ async run(ctx, repoDir, _files, timeout) {
77
+ return ctx.exec('psalm', ['--output-format=json', '--no-cache'], {
78
+ timeoutMs: timeout,
79
+ cwd: repoDir,
80
+ allowExitCodes: [1, 2], // psalm returns 1 for info, 2 for errors
81
+ });
82
+ },
83
+ parse: parsePsalmOutput,
84
+ };
85
+ //# sourceMappingURL=psalm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"psalm.js","sourceRoot":"","sources":["../../../src/tools/plugins/psalm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Ruff plugin — Python linting (auto-detect).
3
+ *
4
+ * Fast Python linter. Activates when Python files are detected.
5
+ * Maps ruff rule code prefixes to severity levels.
6
+ *
7
+ * Uses ExecutionContext for DI instead of direct child_process.
8
+ */
9
+ import type { FindingSeverity, ReviewFinding } from '../../types.js';
10
+ import type { RawToolOutput, ToolDefinition } from '../types.js';
11
+ /**
12
+ * Map Ruff code prefix to GHAGGA FindingSeverity.
13
+ * F (Pyflakes) → high, E (errors) → medium, W (warnings) → low, others → low
14
+ */
15
+ export declare function mapRuffSeverity(code: string): FindingSeverity;
16
+ /**
17
+ * Parse Ruff JSON output into ReviewFinding[].
18
+ * Exported for direct testing with fixture data.
19
+ */
20
+ export declare function parseRuffOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
21
+ export declare const ruffPlugin: ToolDefinition;
22
+ //# sourceMappingURL=ruff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ruff.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/ruff.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAInF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAY7D;AAWD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAiBpF;AAED,eAAO,MAAM,UAAU,EAAE,cAuCxB,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Ruff plugin — Python linting (auto-detect).
3
+ *
4
+ * Fast Python linter. Activates when Python files are detected.
5
+ * Maps ruff rule code prefixes to severity levels.
6
+ *
7
+ * Uses ExecutionContext for DI instead of direct child_process.
8
+ */
9
+ const RUFF_VERSION = '0.9.7';
10
+ /**
11
+ * Map Ruff code prefix to GHAGGA FindingSeverity.
12
+ * F (Pyflakes) → high, E (errors) → medium, W (warnings) → low, others → low
13
+ */
14
+ export function mapRuffSeverity(code) {
15
+ const prefix = code.charAt(0).toUpperCase();
16
+ switch (prefix) {
17
+ case 'F':
18
+ return 'high';
19
+ case 'E':
20
+ return 'medium';
21
+ case 'W':
22
+ return 'low';
23
+ default:
24
+ return 'low';
25
+ }
26
+ }
27
+ /**
28
+ * Parse Ruff JSON output into ReviewFinding[].
29
+ * Exported for direct testing with fixture data.
30
+ */
31
+ export function parseRuffOutput(raw, repoDir) {
32
+ if (raw.timedOut)
33
+ return [];
34
+ try {
35
+ const findings = JSON.parse(raw.stdout);
36
+ return findings.map((f) => ({
37
+ severity: mapRuffSeverity(f.code),
38
+ category: 'quality',
39
+ file: f.filename.replace(`${repoDir}/`, ''),
40
+ line: f.location.row,
41
+ message: `${f.code}: ${f.message}`,
42
+ source: 'ruff',
43
+ }));
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ }
49
+ export const ruffPlugin = {
50
+ name: 'ruff',
51
+ displayName: 'Ruff',
52
+ category: 'quality',
53
+ tier: 'auto-detect',
54
+ version: RUFF_VERSION,
55
+ outputFormat: 'json',
56
+ detect(files) {
57
+ return files.some((f) => f.endsWith('.py') || f.endsWith('.pyi'));
58
+ },
59
+ async install(ctx) {
60
+ try {
61
+ await ctx.exec('ruff', ['--version'], { timeoutMs: 10_000 });
62
+ return;
63
+ }
64
+ catch {
65
+ ctx.log('info', 'Ruff not found, installing...');
66
+ }
67
+ await ctx.exec('pip', ['install', '--quiet', `ruff==${RUFF_VERSION}`], {
68
+ timeoutMs: 120_000,
69
+ });
70
+ await ctx.exec('ruff', ['--version'], { timeoutMs: 10_000 });
71
+ },
72
+ async run(ctx, repoDir, _files, timeout) {
73
+ return ctx.exec('ruff', ['check', '--output-format', 'json', repoDir], {
74
+ timeoutMs: timeout,
75
+ allowExitCodes: [1], // ruff returns 1 when findings are present
76
+ });
77
+ },
78
+ parse: parseRuffOutput,
79
+ };
80
+ //# sourceMappingURL=ruff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ruff.js","sourceRoot":"","sources":["../../../src/tools/plugins/ruff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Semgrep plugin — security analysis (always-on).
3
+ *
4
+ * Adapted from:
5
+ * - packages/core/src/tools/semgrep.ts (parsing logic)
6
+ * - apps/action/src/tools/semgrep.ts (install/run flow)
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ import type { FindingSeverity, ReviewFinding } from '../../types.js';
11
+ import type { RawToolOutput, ToolDefinition } from '../types.js';
12
+ /**
13
+ * Map Semgrep severity to GHAGGA FindingSeverity.
14
+ * ERROR -> high, WARNING -> medium, INFO -> info, default -> low
15
+ */
16
+ export declare function mapSemgrepSeverity(semgrepSeverity: string): FindingSeverity;
17
+ /**
18
+ * Parse Semgrep JSON output into ReviewFinding[].
19
+ * Exported for direct testing with fixture data.
20
+ */
21
+ export declare function parseSemgrepOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
22
+ export declare const semgrepPlugin: ToolDefinition;
23
+ //# sourceMappingURL=semgrep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semgrep.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/semgrep.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAInF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAW3E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAuBvF;AAED,eAAO,MAAM,aAAa,EAAE,cAwC3B,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Semgrep plugin — security analysis (always-on).
3
+ *
4
+ * Adapted from:
5
+ * - packages/core/src/tools/semgrep.ts (parsing logic)
6
+ * - apps/action/src/tools/semgrep.ts (install/run flow)
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ const SEMGREP_VERSION = '1.90.0';
11
+ /**
12
+ * Map Semgrep severity to GHAGGA FindingSeverity.
13
+ * ERROR -> high, WARNING -> medium, INFO -> info, default -> low
14
+ */
15
+ export function mapSemgrepSeverity(semgrepSeverity) {
16
+ switch (semgrepSeverity.toUpperCase()) {
17
+ case 'ERROR':
18
+ return 'high';
19
+ case 'WARNING':
20
+ return 'medium';
21
+ case 'INFO':
22
+ return 'info';
23
+ default:
24
+ return 'low';
25
+ }
26
+ }
27
+ /**
28
+ * Parse Semgrep JSON output into ReviewFinding[].
29
+ * Exported for direct testing with fixture data.
30
+ */
31
+ export function parseSemgrepOutput(raw, repoDir) {
32
+ if (raw.timedOut)
33
+ return [];
34
+ try {
35
+ const result = JSON.parse(raw.stdout);
36
+ return (result.results ?? []).map((r) => ({
37
+ severity: mapSemgrepSeverity(r.extra.severity),
38
+ category: 'security',
39
+ file: r.path.replace(`${repoDir}/`, ''),
40
+ line: r.start.line,
41
+ message: r.extra.message,
42
+ source: 'semgrep',
43
+ }));
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ }
49
+ export const semgrepPlugin = {
50
+ name: 'semgrep',
51
+ displayName: 'Semgrep',
52
+ category: 'security',
53
+ tier: 'always-on',
54
+ version: SEMGREP_VERSION,
55
+ outputFormat: 'json',
56
+ cachePaths: ['/usr/local/bin/semgrep'],
57
+ async install(ctx) {
58
+ const cached = await ctx.cacheRestore('semgrep', ['/usr/local/bin/semgrep']);
59
+ if (cached) {
60
+ try {
61
+ await ctx.exec('semgrep', ['--version'], { timeoutMs: 10_000 });
62
+ return;
63
+ }
64
+ catch {
65
+ ctx.log('warn', 'Semgrep cache restored but binary not functional, reinstalling');
66
+ }
67
+ }
68
+ await ctx.exec('pip', ['install', '--quiet', `semgrep==${SEMGREP_VERSION}`], {
69
+ timeoutMs: 120_000,
70
+ });
71
+ await ctx.exec('semgrep', ['--version'], { timeoutMs: 10_000 });
72
+ await ctx.cacheSave('semgrep', ['/usr/local/bin/semgrep']);
73
+ },
74
+ async run(ctx, repoDir, _files, timeout) {
75
+ return ctx.exec('semgrep', ['--json', '--config', 'auto', '--quiet', repoDir], {
76
+ timeoutMs: timeout,
77
+ allowExitCodes: [1], // semgrep returns 1 when findings are present
78
+ });
79
+ },
80
+ parse: parseSemgrepOutput,
81
+ };
82
+ //# sourceMappingURL=semgrep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semgrep.js","sourceRoot":"","sources":["../../../src/tools/plugins/semgrep.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,eAAuB;IACxD,QAAQ,eAAe,CAAC,WAAW,EAAE,EAAE,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,MAAM,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,QAAQ,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAkB,EAAE,OAAe;IACpE,IAAI,GAAG,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAMnC,CAAC;QAEF,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC9C,QAAQ,EAAE,UAAU;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC;YACvC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;YAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO;YACxB,MAAM,EAAE,SAAkB;SAC3B,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,SAAS;IACtB,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,eAAe;IACxB,YAAY,EAAE,MAAM;IACpB,UAAU,EAAE,CAAC,wBAAwB,CAAC;IAEtC,KAAK,CAAC,OAAO,CAAC,GAAqB;QACjC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAC7E,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;gBAChE,OAAO;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,gEAAgE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QAED,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,YAAY,eAAe,EAAE,CAAC,EAAE;YAC3E,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAChE,MAAM,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAqB,EACrB,OAAe,EACf,MAAgB,EAChB,OAAe;QAEf,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;YAC7E,SAAS,EAAE,OAAO;YAClB,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,8CAA8C;SACpE,CAAC,CAAC;IACL,CAAC;IAED,KAAK,EAAE,kBAAkB;CAC1B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * ShellCheck plugin — shell script linting (always-on).
3
+ *
4
+ * Lints shell scripts for common issues and portability problems.
5
+ * Only runs on *.sh and *.bash files; returns empty findings if none found.
6
+ *
7
+ * Pre-installed on GitHub Actions runners — install is a verification step.
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ import type { FindingSeverity, ReviewFinding } from '../../types.js';
11
+ import type { RawToolOutput, ToolDefinition } from '../types.js';
12
+ /**
13
+ * Map ShellCheck level to GHAGGA FindingSeverity.
14
+ * error→high, warning→medium, info→info, style→low
15
+ */
16
+ export declare function mapShellCheckSeverity(level: string): FindingSeverity;
17
+ /**
18
+ * Parse ShellCheck JSON output into ReviewFinding[].
19
+ * Exported for direct testing with fixture data.
20
+ */
21
+ export declare function parseShellCheckOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
22
+ export declare const shellcheckPlugin: ToolDefinition;
23
+ //# sourceMappingURL=shellcheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellcheck.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/shellcheck.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAInF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAapE;AAYD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAiB1F;AAED,eAAO,MAAM,gBAAgB,EAAE,cAiD9B,CAAC"}