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 @@
1
+ {"version":3,"file":"gitleaks.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/gitleaks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAanF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAiBxF;AAED,eAAO,MAAM,cAAc,EAAE,cAgE5B,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Gitleaks plugin — secret detection (always-on).
3
+ *
4
+ * Scans the repository for hardcoded secrets, API keys, and credentials.
5
+ * All secret findings are reported as critical severity.
6
+ *
7
+ * Uses ExecutionContext for DI instead of direct child_process.
8
+ */
9
+ const GITLEAKS_VERSION = '8.21.2';
10
+ const GITLEAKS_BIN = '/usr/local/bin/gitleaks';
11
+ /**
12
+ * Parse Gitleaks JSON output into ReviewFinding[].
13
+ * Gitleaks writes results to a report file; we read from stdout or the report.
14
+ * Exported for direct testing with fixture data.
15
+ */
16
+ export function parseGitleaksOutput(raw, repoDir) {
17
+ if (raw.timedOut)
18
+ return [];
19
+ try {
20
+ const findings = JSON.parse(raw.stdout);
21
+ return findings.map((f) => ({
22
+ severity: 'critical',
23
+ category: 'secrets',
24
+ file: f.File.replace(`${repoDir}/`, ''),
25
+ line: f.StartLine,
26
+ message: `${f.Description} (rule: ${f.RuleID})`,
27
+ source: 'gitleaks',
28
+ }));
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ }
34
+ export const gitleaksPlugin = {
35
+ name: 'gitleaks',
36
+ displayName: 'Gitleaks',
37
+ category: 'secrets',
38
+ tier: 'always-on',
39
+ version: GITLEAKS_VERSION,
40
+ outputFormat: 'json',
41
+ cachePaths: [GITLEAKS_BIN],
42
+ async install(ctx) {
43
+ const cached = await ctx.cacheRestore('gitleaks', [GITLEAKS_BIN]);
44
+ if (cached) {
45
+ try {
46
+ await ctx.exec('gitleaks', ['version'], { timeoutMs: 10_000 });
47
+ return;
48
+ }
49
+ catch {
50
+ ctx.log('warn', 'Gitleaks cache restored but binary not functional, reinstalling');
51
+ }
52
+ }
53
+ // Download Gitleaks binary from GitHub Releases
54
+ await ctx.exec('bash', [
55
+ '-c',
56
+ `curl -sL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" | tar xz -C /usr/local/bin gitleaks`,
57
+ ], { timeoutMs: 120_000 });
58
+ await ctx.exec('gitleaks', ['version'], { timeoutMs: 10_000 });
59
+ await ctx.cacheSave('gitleaks', [GITLEAKS_BIN]);
60
+ },
61
+ async run(ctx, repoDir, _files, timeout) {
62
+ const reportPath = '/tmp/gitleaks-result.json';
63
+ await ctx.exec('gitleaks', [
64
+ 'detect',
65
+ `--source=${repoDir}`,
66
+ '--report-format=json',
67
+ `--report-path=${reportPath}`,
68
+ '--no-git',
69
+ '--exit-code=0',
70
+ ], {
71
+ timeoutMs: timeout,
72
+ });
73
+ // Read the report file and return it as stdout
74
+ return ctx.exec('cat', [reportPath], {
75
+ timeoutMs: 10_000,
76
+ allowExitCodes: [1], // cat may fail if no findings file
77
+ });
78
+ },
79
+ parse: parseGitleaksOutput,
80
+ };
81
+ //# sourceMappingURL=gitleaks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitleaks.js","sourceRoot":"","sources":["../../../src/tools/plugins/gitleaks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAClC,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAU/C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAkB,EAAE,OAAe;IACrE,IAAI,GAAG,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAsB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE3D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1B,QAAQ,EAAE,UAAmB;YAC7B,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC;YACvC,IAAI,EAAE,CAAC,CAAC,SAAS;YACjB,OAAO,EAAE,GAAG,CAAC,CAAC,WAAW,WAAW,CAAC,CAAC,MAAM,GAAG;YAC/C,MAAM,EAAE,UAAmB;SAC5B,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,UAAU;IACvB,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,gBAAgB;IACzB,YAAY,EAAE,MAAM;IACpB,UAAU,EAAE,CAAC,YAAY,CAAC;IAE1B,KAAK,CAAC,OAAO,CAAC,GAAqB;QACjC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;QAClE,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC/D,OAAO;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,iEAAiE,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QAED,gDAAgD;QAChD,MAAM,GAAG,CAAC,IAAI,CACZ,MAAM,EACN;YACE,IAAI;YACJ,qEAAqE,gBAAgB,aAAa,gBAAgB,wDAAwD;SAC3K,EACD,EAAE,SAAS,EAAE,OAAO,EAAE,CACvB,CAAC;QACF,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/D,MAAM,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAqB,EACrB,OAAe,EACf,MAAgB,EAChB,OAAe;QAEf,MAAM,UAAU,GAAG,2BAA2B,CAAC;QAE/C,MAAM,GAAG,CAAC,IAAI,CACZ,UAAU,EACV;YACE,QAAQ;YACR,YAAY,OAAO,EAAE;YACrB,sBAAsB;YACtB,iBAAiB,UAAU,EAAE;YAC7B,UAAU;YACV,eAAe;SAChB,EACD;YACE,SAAS,EAAE,OAAO;SACnB,CACF,CAAC;QAEF,+CAA+C;QAC/C,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE;YACnC,SAAS,EAAE,MAAM;YACjB,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,mCAAmC;SACzD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,EAAE,mBAAmB;CAC3B,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * golangci-lint plugin — Go code analysis (auto-detect).
3
+ *
4
+ * Runs multiple Go linters in a single pass.
5
+ * Activates when Go files or go.mod is detected.
6
+ * Maps gosec linter findings to security/high, others to quality/medium.
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 golangci-lint issue to GHAGGA FindingSeverity and category.
14
+ * gosec linter → security category with high severity.
15
+ * Other linters → quality category with medium severity.
16
+ */
17
+ export declare function mapGolangciLintFinding(fromLinter: string): {
18
+ severity: FindingSeverity;
19
+ category: string;
20
+ };
21
+ /**
22
+ * Parse golangci-lint JSON output into ReviewFinding[].
23
+ * Exported for direct testing with fixture data.
24
+ */
25
+ export declare function parseGolangciLintOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
26
+ export declare const golangciLintPlugin: ToolDefinition;
27
+ //# sourceMappingURL=golangci-lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"golangci-lint.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/golangci-lint.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;AAKnF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG;IAC1D,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAKA;AAgBD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAqB5F;AAED,eAAO,MAAM,kBAAkB,EAAE,cAwDhC,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * golangci-lint plugin — Go code analysis (auto-detect).
3
+ *
4
+ * Runs multiple Go linters in a single pass.
5
+ * Activates when Go files or go.mod is detected.
6
+ * Maps gosec linter findings to security/high, others to quality/medium.
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ const GOLANGCI_LINT_VERSION = '1.63.4';
11
+ const GOLANGCI_LINT_BIN = '/usr/local/bin/golangci-lint';
12
+ /**
13
+ * Map golangci-lint issue to GHAGGA FindingSeverity and category.
14
+ * gosec linter → security category with high severity.
15
+ * Other linters → quality category with medium severity.
16
+ */
17
+ export function mapGolangciLintFinding(fromLinter) {
18
+ if (fromLinter === 'gosec') {
19
+ return { severity: 'high', category: 'security' };
20
+ }
21
+ return { severity: 'medium', category: 'quality' };
22
+ }
23
+ /**
24
+ * Parse golangci-lint JSON output into ReviewFinding[].
25
+ * Exported for direct testing with fixture data.
26
+ */
27
+ export function parseGolangciLintOutput(raw, repoDir) {
28
+ if (raw.timedOut)
29
+ return [];
30
+ try {
31
+ const result = JSON.parse(raw.stdout);
32
+ return (result.Issues ?? []).map((issue) => {
33
+ const { severity, category } = mapGolangciLintFinding(issue.FromLinter);
34
+ return {
35
+ severity,
36
+ category,
37
+ file: issue.Pos.Filename.replace(`${repoDir}/`, ''),
38
+ line: issue.Pos.Line,
39
+ message: `[${issue.FromLinter}] ${issue.Text}`,
40
+ source: 'golangci-lint',
41
+ };
42
+ });
43
+ }
44
+ catch {
45
+ return [];
46
+ }
47
+ }
48
+ export const golangciLintPlugin = {
49
+ name: 'golangci-lint',
50
+ displayName: 'golangci-lint',
51
+ category: 'quality',
52
+ tier: 'auto-detect',
53
+ version: GOLANGCI_LINT_VERSION,
54
+ outputFormat: 'json',
55
+ cachePaths: [GOLANGCI_LINT_BIN],
56
+ detect(files) {
57
+ return files.some((f) => f === 'go.mod' || f.endsWith('.go'));
58
+ },
59
+ async install(ctx) {
60
+ const cached = await ctx.cacheRestore('golangci-lint', [GOLANGCI_LINT_BIN]);
61
+ if (cached) {
62
+ try {
63
+ await ctx.exec('golangci-lint', ['--version'], { timeoutMs: 10_000 });
64
+ return;
65
+ }
66
+ catch {
67
+ ctx.log('warn', 'golangci-lint cache restored but binary not functional, reinstalling');
68
+ }
69
+ }
70
+ await ctx.exec('bash', [
71
+ '-c',
72
+ `curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v${GOLANGCI_LINT_VERSION}`,
73
+ ], { timeoutMs: 120_000 });
74
+ await ctx.exec('golangci-lint', ['--version'], { timeoutMs: 10_000 });
75
+ await ctx.cacheSave('golangci-lint', [GOLANGCI_LINT_BIN]);
76
+ },
77
+ async run(ctx, repoDir, _files, timeout) {
78
+ const timeoutSec = Math.max(60, Math.floor(timeout / 1000));
79
+ return ctx.exec('golangci-lint', ['run', '--out-format', 'json', '--timeout', `${timeoutSec}s`], {
80
+ timeoutMs: timeout,
81
+ cwd: repoDir,
82
+ allowExitCodes: [1], // returns 1 when findings are present
83
+ });
84
+ },
85
+ parse: parseGolangciLintOutput,
86
+ };
87
+ //# sourceMappingURL=golangci-lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"golangci-lint.js","sourceRoot":"","sources":["../../../src/tools/plugins/golangci-lint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Hadolint plugin — Dockerfile linting (auto-detect).
3
+ *
4
+ * Lints Dockerfiles for best practices and common issues.
5
+ * Activates when Dockerfile-named files are detected.
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 Hadolint level to GHAGGA FindingSeverity.
13
+ * error→high, warning→medium, info→info, style→low
14
+ */
15
+ export declare function mapHadolintSeverity(level: string): FindingSeverity;
16
+ /**
17
+ * Parse Hadolint JSON output into ReviewFinding[].
18
+ * Exported for direct testing with fixture data.
19
+ */
20
+ export declare function parseHadolintOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
21
+ export declare const hadolintPlugin: ToolDefinition;
22
+ //# sourceMappingURL=hadolint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hadolint.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/hadolint.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;AAKnF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAalE;AAYD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAiBxF;AAED,eAAO,MAAM,cAAc,EAAE,cA8D5B,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Hadolint plugin — Dockerfile linting (auto-detect).
3
+ *
4
+ * Lints Dockerfiles for best practices and common issues.
5
+ * Activates when Dockerfile-named files are detected.
6
+ *
7
+ * Uses ExecutionContext for DI instead of direct child_process.
8
+ */
9
+ const HADOLINT_VERSION = '2.12.0';
10
+ const HADOLINT_BIN = '/usr/local/bin/hadolint';
11
+ /**
12
+ * Map Hadolint level to GHAGGA FindingSeverity.
13
+ * error→high, warning→medium, info→info, style→low
14
+ */
15
+ export function mapHadolintSeverity(level) {
16
+ switch (level.toLowerCase()) {
17
+ case 'error':
18
+ return 'high';
19
+ case 'warning':
20
+ return 'medium';
21
+ case 'info':
22
+ return 'info';
23
+ case 'style':
24
+ return 'low';
25
+ default:
26
+ return 'low';
27
+ }
28
+ }
29
+ /**
30
+ * Parse Hadolint JSON output into ReviewFinding[].
31
+ * Exported for direct testing with fixture data.
32
+ */
33
+ export function parseHadolintOutput(raw, repoDir) {
34
+ if (raw.timedOut)
35
+ return [];
36
+ try {
37
+ const findings = JSON.parse(raw.stdout);
38
+ return findings.map((f) => ({
39
+ severity: mapHadolintSeverity(f.level),
40
+ category: 'quality',
41
+ file: f.file.replace(`${repoDir}/`, ''),
42
+ line: f.line,
43
+ message: `${f.code}: ${f.message}`,
44
+ source: 'hadolint',
45
+ }));
46
+ }
47
+ catch {
48
+ return [];
49
+ }
50
+ }
51
+ export const hadolintPlugin = {
52
+ name: 'hadolint',
53
+ displayName: 'Hadolint',
54
+ category: 'quality',
55
+ tier: 'auto-detect',
56
+ version: HADOLINT_VERSION,
57
+ outputFormat: 'json',
58
+ cachePaths: [HADOLINT_BIN],
59
+ detect(files) {
60
+ return files.some((f) => {
61
+ const basename = f.split('/').pop() ?? '';
62
+ return /Dockerfile/.test(basename);
63
+ });
64
+ },
65
+ async install(ctx) {
66
+ const cached = await ctx.cacheRestore('hadolint', [HADOLINT_BIN]);
67
+ if (cached) {
68
+ try {
69
+ await ctx.exec('hadolint', ['--version'], { timeoutMs: 10_000 });
70
+ return;
71
+ }
72
+ catch {
73
+ ctx.log('warn', 'Hadolint cache restored but binary not functional, reinstalling');
74
+ }
75
+ }
76
+ await ctx.exec('bash', [
77
+ '-c',
78
+ `curl -sL "https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-Linux-x86_64" -o ${HADOLINT_BIN} && chmod +x ${HADOLINT_BIN}`,
79
+ ], { timeoutMs: 120_000 });
80
+ await ctx.exec('hadolint', ['--version'], { timeoutMs: 10_000 });
81
+ await ctx.cacheSave('hadolint', [HADOLINT_BIN]);
82
+ },
83
+ async run(ctx, _repoDir, files, timeout) {
84
+ // Filter to only Dockerfile-matching files
85
+ const dockerfiles = files.filter((f) => {
86
+ const basename = f.split('/').pop() ?? '';
87
+ return /Dockerfile/.test(basename);
88
+ });
89
+ if (dockerfiles.length === 0) {
90
+ return { stdout: '[]', stderr: '', exitCode: 0, timedOut: false };
91
+ }
92
+ return ctx.exec('hadolint', ['--format', 'json', ...dockerfiles], {
93
+ timeoutMs: timeout,
94
+ allowExitCodes: [1], // hadolint returns 1 when findings are present
95
+ });
96
+ },
97
+ parse: parseHadolintOutput,
98
+ };
99
+ //# sourceMappingURL=hadolint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hadolint.js","sourceRoot":"","sources":["../../../src/tools/plugins/hadolint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Plugin registry initialization.
3
+ *
4
+ * Imports all tool plugins and registers them with the singleton toolRegistry.
5
+ * Call `initializeDefaultTools()` to populate the registry.
6
+ *
7
+ * Phase 2: semgrep, trivy, cpd (always-on)
8
+ * Phase 3: gitleaks, shellcheck, markdownlint, lizard (always-on)
9
+ * Phase 4: ruff, bandit, golangci-lint (auto-detect)
10
+ * Phase 5: biome, pmd, psalm, clippy, hadolint (auto-detect)
11
+ */
12
+ /**
13
+ * Register all default tool plugins with the registry.
14
+ * Safe to call multiple times — only registers once.
15
+ */
16
+ export declare function initializeDefaultTools(): void;
17
+ /**
18
+ * Reset the initialization flag (for tests).
19
+ * @internal
20
+ */
21
+ export declare function resetInitialization(): void;
22
+ export { banditPlugin } from './bandit.js';
23
+ export { biomePlugin } from './biome.js';
24
+ export { clippyPlugin } from './clippy.js';
25
+ export { cpdPlugin } from './cpd.js';
26
+ export { gitleaksPlugin } from './gitleaks.js';
27
+ export { golangciLintPlugin } from './golangci-lint.js';
28
+ export { hadolintPlugin } from './hadolint.js';
29
+ export { lizardPlugin } from './lizard.js';
30
+ export { markdownlintPlugin } from './markdownlint.js';
31
+ export { pmdPlugin } from './pmd.js';
32
+ export { psalmPlugin } from './psalm.js';
33
+ export { ruffPlugin } from './ruff.js';
34
+ export { semgrepPlugin } from './semgrep.js';
35
+ export { shellcheckPlugin } from './shellcheck.js';
36
+ export { trivyPlugin } from './trivy.js';
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgDH;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAQ7C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Plugin registry initialization.
3
+ *
4
+ * Imports all tool plugins and registers them with the singleton toolRegistry.
5
+ * Call `initializeDefaultTools()` to populate the registry.
6
+ *
7
+ * Phase 2: semgrep, trivy, cpd (always-on)
8
+ * Phase 3: gitleaks, shellcheck, markdownlint, lizard (always-on)
9
+ * Phase 4: ruff, bandit, golangci-lint (auto-detect)
10
+ * Phase 5: biome, pmd, psalm, clippy, hadolint (auto-detect)
11
+ */
12
+ import { toolRegistry } from '../registry.js';
13
+ // Phase 4: auto-detect (Python + Go)
14
+ import { banditPlugin } from './bandit.js';
15
+ // Phase 5: auto-detect (remaining)
16
+ import { biomePlugin } from './biome.js';
17
+ import { clippyPlugin } from './clippy.js';
18
+ // Phase 2: always-on (adapted)
19
+ import { cpdPlugin } from './cpd.js';
20
+ // Phase 3: always-on (new)
21
+ import { gitleaksPlugin } from './gitleaks.js';
22
+ import { golangciLintPlugin } from './golangci-lint.js';
23
+ import { hadolintPlugin } from './hadolint.js';
24
+ import { lizardPlugin } from './lizard.js';
25
+ import { markdownlintPlugin } from './markdownlint.js';
26
+ import { pmdPlugin } from './pmd.js';
27
+ import { psalmPlugin } from './psalm.js';
28
+ import { ruffPlugin } from './ruff.js';
29
+ import { semgrepPlugin } from './semgrep.js';
30
+ import { shellcheckPlugin } from './shellcheck.js';
31
+ import { trivyPlugin } from './trivy.js';
32
+ /** All built-in plugins. Grows as more phases are implemented. */
33
+ const DEFAULT_PLUGINS = [
34
+ // Phase 2: always-on (adapted)
35
+ semgrepPlugin,
36
+ trivyPlugin,
37
+ cpdPlugin,
38
+ // Phase 3: always-on (new)
39
+ gitleaksPlugin,
40
+ shellcheckPlugin,
41
+ markdownlintPlugin,
42
+ lizardPlugin,
43
+ // Phase 4: auto-detect (Python + Go)
44
+ ruffPlugin,
45
+ banditPlugin,
46
+ golangciLintPlugin,
47
+ // Phase 5: auto-detect (remaining)
48
+ biomePlugin,
49
+ pmdPlugin,
50
+ psalmPlugin,
51
+ clippyPlugin,
52
+ hadolintPlugin,
53
+ ];
54
+ let initialized = false;
55
+ /**
56
+ * Register all default tool plugins with the registry.
57
+ * Safe to call multiple times — only registers once.
58
+ */
59
+ export function initializeDefaultTools() {
60
+ if (initialized)
61
+ return;
62
+ for (const plugin of DEFAULT_PLUGINS) {
63
+ toolRegistry.register(plugin);
64
+ }
65
+ initialized = true;
66
+ }
67
+ /**
68
+ * Reset the initialization flag (for tests).
69
+ * @internal
70
+ */
71
+ export function resetInitialization() {
72
+ initialized = false;
73
+ }
74
+ export { banditPlugin } from './bandit.js';
75
+ // Phase 5
76
+ export { biomePlugin } from './biome.js';
77
+ export { clippyPlugin } from './clippy.js';
78
+ // Re-export plugins for direct access
79
+ export { cpdPlugin } from './cpd.js';
80
+ // Phase 3
81
+ export { gitleaksPlugin } from './gitleaks.js';
82
+ export { golangciLintPlugin } from './golangci-lint.js';
83
+ export { hadolintPlugin } from './hadolint.js';
84
+ export { lizardPlugin } from './lizard.js';
85
+ export { markdownlintPlugin } from './markdownlint.js';
86
+ export { pmdPlugin } from './pmd.js';
87
+ export { psalmPlugin } from './psalm.js';
88
+ // Phase 4
89
+ export { ruffPlugin } from './ruff.js';
90
+ export { semgrepPlugin } from './semgrep.js';
91
+ export { shellcheckPlugin } from './shellcheck.js';
92
+ export { trivyPlugin } from './trivy.js';
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,mCAAmC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,+BAA+B;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,2BAA2B;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,kEAAkE;AAClE,MAAM,eAAe,GAAG;IACtB,+BAA+B;IAC/B,aAAa;IACb,WAAW;IACX,SAAS;IACT,2BAA2B;IAC3B,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,YAAY;IACZ,qCAAqC;IACrC,UAAU;IACV,YAAY;IACZ,kBAAkB;IAClB,mCAAmC;IACnC,WAAW;IACX,SAAS;IACT,WAAW;IACX,YAAY;IACZ,cAAc;CACf,CAAC;AAEF,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,IAAI,WAAW;QAAE,OAAO;IAExB,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,WAAW,GAAG,KAAK,CAAC;AACtB,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,UAAU;AACV,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,sCAAsC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,UAAU;AACV,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,UAAU;AACV,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Lizard plugin — cyclomatic complexity analysis (always-on).
3
+ *
4
+ * Analyzes function-level cyclomatic complexity across all languages.
5
+ * Flags functions exceeding complexity thresholds:
6
+ * CCN > 20 → high, CCN > 15 → medium, CCN > 10 → low, CCN ≤ 10 → skip
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 cyclomatic complexity to GHAGGA FindingSeverity.
14
+ * Returns null for functions below threshold (CCN ≤ 10).
15
+ */
16
+ export declare function mapComplexitySeverity(ccn: number): FindingSeverity | null;
17
+ /**
18
+ * Parse Lizard JSON output into ReviewFinding[].
19
+ * Only includes functions with CCN > 10.
20
+ * Exported for direct testing with fixture data.
21
+ */
22
+ export declare function parseLizardOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
23
+ export declare const lizardPlugin: ToolDefinition;
24
+ //# sourceMappingURL=lizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lizard.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/lizard.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,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAKzE;AAgBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CA2BtF;AAED,eAAO,MAAM,YAAY,EAAE,cAkC1B,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Lizard plugin — cyclomatic complexity analysis (always-on).
3
+ *
4
+ * Analyzes function-level cyclomatic complexity across all languages.
5
+ * Flags functions exceeding complexity thresholds:
6
+ * CCN > 20 → high, CCN > 15 → medium, CCN > 10 → low, CCN ≤ 10 → skip
7
+ *
8
+ * Uses ExecutionContext for DI instead of direct child_process.
9
+ */
10
+ const LIZARD_VERSION = '1.17.13';
11
+ /**
12
+ * Map cyclomatic complexity to GHAGGA FindingSeverity.
13
+ * Returns null for functions below threshold (CCN ≤ 10).
14
+ */
15
+ export function mapComplexitySeverity(ccn) {
16
+ if (ccn > 20)
17
+ return 'high';
18
+ if (ccn > 15)
19
+ return 'medium';
20
+ if (ccn > 10)
21
+ return 'low';
22
+ return null;
23
+ }
24
+ /**
25
+ * Parse Lizard JSON output into ReviewFinding[].
26
+ * Only includes functions with CCN > 10.
27
+ * Exported for direct testing with fixture data.
28
+ */
29
+ export function parseLizardOutput(raw, repoDir) {
30
+ if (raw.timedOut)
31
+ return [];
32
+ try {
33
+ const files = JSON.parse(raw.stdout);
34
+ const findings = [];
35
+ for (const file of files) {
36
+ for (const func of file.function_list) {
37
+ const severity = mapComplexitySeverity(func.cyclomatic_complexity);
38
+ if (severity === null)
39
+ continue;
40
+ findings.push({
41
+ severity,
42
+ category: 'complexity',
43
+ file: file.filename.replace(`${repoDir}/`, ''),
44
+ line: func.start_line,
45
+ message: `Function '${func.name}' has cyclomatic complexity of ${func.cyclomatic_complexity} (threshold: 10)`,
46
+ source: 'lizard',
47
+ });
48
+ }
49
+ }
50
+ return findings;
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ }
56
+ export const lizardPlugin = {
57
+ name: 'lizard',
58
+ displayName: 'Lizard',
59
+ category: 'complexity',
60
+ tier: 'always-on',
61
+ version: LIZARD_VERSION,
62
+ outputFormat: 'json',
63
+ async install(ctx) {
64
+ try {
65
+ await ctx.exec('lizard', ['--version'], { timeoutMs: 10_000 });
66
+ return;
67
+ }
68
+ catch {
69
+ ctx.log('info', 'Lizard not found, installing...');
70
+ }
71
+ await ctx.exec('pip', ['install', '--quiet', `lizard==${LIZARD_VERSION}`], {
72
+ timeoutMs: 120_000,
73
+ });
74
+ await ctx.exec('lizard', ['--version'], { timeoutMs: 10_000 });
75
+ },
76
+ async run(ctx, repoDir, _files, timeout) {
77
+ return ctx.exec('lizard', ['--json', repoDir], {
78
+ timeoutMs: timeout,
79
+ });
80
+ },
81
+ parse: parseLizardOutput,
82
+ };
83
+ //# sourceMappingURL=lizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lizard.js","sourceRoot":"","sources":["../../../src/tools/plugins/lizard.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,cAAc,GAAG,SAAS,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,MAAM,CAAC;IAC5B,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAkB,EAAE,OAAe;IACnE,IAAI,GAAG,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,KAAK,GAAiB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAoB,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;gBACnE,IAAI,QAAQ,KAAK,IAAI;oBAAE,SAAS;gBAEhC,QAAQ,CAAC,IAAI,CAAC;oBACZ,QAAQ;oBACR,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC;oBAC9C,IAAI,EAAE,IAAI,CAAC,UAAU;oBACrB,OAAO,EAAE,aAAa,IAAI,CAAC,IAAI,kCAAkC,IAAI,CAAC,qBAAqB,kBAAkB;oBAC7G,MAAM,EAAE,QAAiB;iBAC1B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE,YAAY;IACtB,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,cAAc;IACvB,YAAY,EAAE,MAAM;IAEpB,KAAK,CAAC,OAAO,CAAC,GAAqB;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,cAAc,EAAE,CAAC,EAAE;YACzE,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAqB,EACrB,OAAe,EACf,MAAgB,EAChB,OAAe;QAEf,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;YAC7C,SAAS,EAAE,OAAO;SACnB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,EAAE,iBAAiB;CACzB,CAAC"}
@@ -0,0 +1,17 @@
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
+ import type { ReviewFinding } from '../../types.js';
10
+ import type { RawToolOutput, ToolDefinition } from '../types.js';
11
+ /**
12
+ * Parse markdownlint-cli2 JSON output into ReviewFinding[].
13
+ * Exported for direct testing with fixture data.
14
+ */
15
+ export declare function parseMarkdownlintOutput(raw: RawToolOutput, repoDir: string): ReviewFinding[];
16
+ export declare const markdownlintPlugin: ToolDefinition;
17
+ //# sourceMappingURL=markdownlint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownlint.d.ts","sourceRoot":"","sources":["../../../src/tools/plugins/markdownlint.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAoB,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAanF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAsB5F;AAED,eAAO,MAAM,kBAAkB,EAAE,cA2ChC,CAAC"}