ghagga-core 2.5.0 → 2.6.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 (153) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/consensus.d.ts +16 -0
  3. package/dist/agents/consensus.d.ts.map +1 -1
  4. package/dist/agents/consensus.js +57 -33
  5. package/dist/agents/consensus.js.map +1 -1
  6. package/dist/agents/diagnostic.d.ts +55 -0
  7. package/dist/agents/diagnostic.d.ts.map +1 -0
  8. package/dist/agents/diagnostic.js +143 -0
  9. package/dist/agents/diagnostic.js.map +1 -0
  10. package/dist/agents/prompts.d.ts +6 -4
  11. package/dist/agents/prompts.d.ts.map +1 -1
  12. package/dist/agents/prompts.js +110 -24
  13. package/dist/agents/prompts.js.map +1 -1
  14. package/dist/agents/simple.d.ts +7 -0
  15. package/dist/agents/simple.d.ts.map +1 -1
  16. package/dist/agents/simple.js +32 -18
  17. package/dist/agents/simple.js.map +1 -1
  18. package/dist/agents/workflow.d.ts +28 -1
  19. package/dist/agents/workflow.d.ts.map +1 -1
  20. package/dist/agents/workflow.js +112 -45
  21. package/dist/agents/workflow.js.map +1 -1
  22. package/dist/enhance/enhance.d.ts.map +1 -1
  23. package/dist/enhance/enhance.js +16 -4
  24. package/dist/enhance/enhance.js.map +1 -1
  25. package/dist/format.d.ts +47 -1
  26. package/dist/format.d.ts.map +1 -1
  27. package/dist/format.js +175 -3
  28. package/dist/format.js.map +1 -1
  29. package/dist/graph/blast-radius.d.ts +57 -0
  30. package/dist/graph/blast-radius.d.ts.map +1 -0
  31. package/dist/graph/blast-radius.js +145 -0
  32. package/dist/graph/blast-radius.js.map +1 -0
  33. package/dist/graph/builder.d.ts +50 -0
  34. package/dist/graph/builder.d.ts.map +1 -0
  35. package/dist/graph/builder.js +210 -0
  36. package/dist/graph/builder.js.map +1 -0
  37. package/dist/graph/extractors/go.d.ts +9 -0
  38. package/dist/graph/extractors/go.d.ts.map +1 -0
  39. package/dist/graph/extractors/go.js +78 -0
  40. package/dist/graph/extractors/go.js.map +1 -0
  41. package/dist/graph/extractors/index.d.ts +22 -0
  42. package/dist/graph/extractors/index.d.ts.map +1 -0
  43. package/dist/graph/extractors/index.js +37 -0
  44. package/dist/graph/extractors/index.js.map +1 -0
  45. package/dist/graph/extractors/java.d.ts +9 -0
  46. package/dist/graph/extractors/java.d.ts.map +1 -0
  47. package/dist/graph/extractors/java.js +80 -0
  48. package/dist/graph/extractors/java.js.map +1 -0
  49. package/dist/graph/extractors/javascript.d.ts +9 -0
  50. package/dist/graph/extractors/javascript.d.ts.map +1 -0
  51. package/dist/graph/extractors/javascript.js +204 -0
  52. package/dist/graph/extractors/javascript.js.map +1 -0
  53. package/dist/graph/extractors/python.d.ts +9 -0
  54. package/dist/graph/extractors/python.d.ts.map +1 -0
  55. package/dist/graph/extractors/python.js +103 -0
  56. package/dist/graph/extractors/python.js.map +1 -0
  57. package/dist/graph/extractors/rust.d.ts +9 -0
  58. package/dist/graph/extractors/rust.d.ts.map +1 -0
  59. package/dist/graph/extractors/rust.js +115 -0
  60. package/dist/graph/extractors/rust.js.map +1 -0
  61. package/dist/graph/extractors/types.d.ts +31 -0
  62. package/dist/graph/extractors/types.d.ts.map +1 -0
  63. package/dist/graph/extractors/types.js +9 -0
  64. package/dist/graph/extractors/types.js.map +1 -0
  65. package/dist/graph/extractors/typescript.d.ts +9 -0
  66. package/dist/graph/extractors/typescript.d.ts.map +1 -0
  67. package/dist/graph/extractors/typescript.js +151 -0
  68. package/dist/graph/extractors/typescript.js.map +1 -0
  69. package/dist/graph/index.d.ts +15 -0
  70. package/dist/graph/index.d.ts.map +1 -0
  71. package/dist/graph/index.js +14 -0
  72. package/dist/graph/index.js.map +1 -0
  73. package/dist/graph/loader.d.ts +43 -0
  74. package/dist/graph/loader.d.ts.map +1 -0
  75. package/dist/graph/loader.js +104 -0
  76. package/dist/graph/loader.js.map +1 -0
  77. package/dist/graph/schema.d.ts +113 -0
  78. package/dist/graph/schema.d.ts.map +1 -0
  79. package/dist/graph/schema.js +144 -0
  80. package/dist/graph/schema.js.map +1 -0
  81. package/dist/health/trends.js +1 -1
  82. package/dist/health/trends.js.map +1 -1
  83. package/dist/index.d.ts +20 -5
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +10 -4
  86. package/dist/index.js.map +1 -1
  87. package/dist/memory/sqlite.js +4 -4
  88. package/dist/memory/sqlite.js.map +1 -1
  89. package/dist/pipeline.d.ts.map +1 -1
  90. package/dist/pipeline.js +291 -42
  91. package/dist/pipeline.js.map +1 -1
  92. package/dist/providers/cli-bridge.d.ts +136 -0
  93. package/dist/providers/cli-bridge.d.ts.map +1 -0
  94. package/dist/providers/cli-bridge.js +457 -0
  95. package/dist/providers/cli-bridge.js.map +1 -0
  96. package/dist/providers/fallback.d.ts +8 -0
  97. package/dist/providers/fallback.d.ts.map +1 -1
  98. package/dist/providers/fallback.js +24 -8
  99. package/dist/providers/fallback.js.map +1 -1
  100. package/dist/providers/gateway.d.ts +40 -0
  101. package/dist/providers/gateway.d.ts.map +1 -0
  102. package/dist/providers/gateway.js +52 -0
  103. package/dist/providers/gateway.js.map +1 -0
  104. package/dist/providers/generate-fn.d.ts +62 -0
  105. package/dist/providers/generate-fn.d.ts.map +1 -0
  106. package/dist/providers/generate-fn.js +84 -0
  107. package/dist/providers/generate-fn.js.map +1 -0
  108. package/dist/providers/index.d.ts +5 -0
  109. package/dist/providers/index.d.ts.map +1 -1
  110. package/dist/providers/index.js +53 -0
  111. package/dist/providers/index.js.map +1 -1
  112. package/dist/tools/plugins/index.d.ts +2 -0
  113. package/dist/tools/plugins/index.d.ts.map +1 -1
  114. package/dist/tools/plugins/index.js +7 -0
  115. package/dist/tools/plugins/index.js.map +1 -1
  116. package/dist/tools/plugins/zizmor.d.ts +22 -0
  117. package/dist/tools/plugins/zizmor.d.ts.map +1 -0
  118. package/dist/tools/plugins/zizmor.js +112 -0
  119. package/dist/tools/plugins/zizmor.js.map +1 -0
  120. package/dist/tools/resolve.js +1 -1
  121. package/dist/tools/resolve.js.map +1 -1
  122. package/dist/tools/types.d.ts +1 -1
  123. package/dist/tools/types.d.ts.map +1 -1
  124. package/dist/types.d.ts +54 -3
  125. package/dist/types.d.ts.map +1 -1
  126. package/dist/types.js +21 -1
  127. package/dist/types.js.map +1 -1
  128. package/dist/utils/concurrency.d.ts +29 -0
  129. package/dist/utils/concurrency.d.ts.map +1 -0
  130. package/dist/utils/concurrency.js +40 -0
  131. package/dist/utils/concurrency.js.map +1 -0
  132. package/dist/utils/context-levels.d.ts +113 -0
  133. package/dist/utils/context-levels.d.ts.map +1 -0
  134. package/dist/utils/context-levels.js +255 -0
  135. package/dist/utils/context-levels.js.map +1 -0
  136. package/dist/utils/diff.d.ts +25 -0
  137. package/dist/utils/diff.d.ts.map +1 -1
  138. package/dist/utils/diff.js +28 -0
  139. package/dist/utils/diff.js.map +1 -1
  140. package/dist/utils/llm-timeout.d.ts +38 -0
  141. package/dist/utils/llm-timeout.d.ts.map +1 -0
  142. package/dist/utils/llm-timeout.js +76 -0
  143. package/dist/utils/llm-timeout.js.map +1 -0
  144. package/dist/utils/path-protection.d.ts +59 -0
  145. package/dist/utils/path-protection.d.ts.map +1 -0
  146. package/dist/utils/path-protection.js +136 -0
  147. package/dist/utils/path-protection.js.map +1 -0
  148. package/dist/utils/token-budget.d.ts +34 -1
  149. package/dist/utils/token-budget.d.ts.map +1 -1
  150. package/dist/utils/token-budget.js +108 -3
  151. package/dist/utils/token-budget.js.map +1 -1
  152. package/package.json +21 -19
  153. package/LICENSE +0 -21
@@ -4,9 +4,9 @@
4
4
  * Calls an LLM to group, prioritize, and filter static analysis findings.
5
5
  * Failures are non-blocking — returns empty result on any error.
6
6
  */
7
- import { generateText } from 'ai';
8
7
  import { createModel } from '../providers/index.js';
9
- import { buildEnhancePrompt, ENHANCE_SYSTEM_PROMPT, truncateByTokenBudget, } from './prompt.js';
8
+ import { generateTextWithTimeout } from '../utils/llm-timeout.js';
9
+ import { buildEnhancePrompt, ENHANCE_SYSTEM_PROMPT, truncateByTokenBudget } from './prompt.js';
10
10
  /** Default token budget for the enhance prompt (4K tokens). */
11
11
  const DEFAULT_TOKEN_BUDGET = 4000;
12
12
  /** Empty result returned on failure or zero findings. */
@@ -41,12 +41,24 @@ export async function enhanceFindings(input) {
41
41
  const prompt = buildEnhancePrompt(truncated);
42
42
  // Call LLM
43
43
  const model = createModel(input.provider, input.model, input.apiKey);
44
- const response = await generateText({
44
+ const response = await generateTextWithTimeout({
45
45
  model,
46
46
  system: ENHANCE_SYSTEM_PROMPT,
47
47
  prompt,
48
48
  maxOutputTokens: 2000,
49
- });
49
+ }, { provider: input.provider, model: input.model });
50
+ // Timeout: return empty result (enhance is already non-blocking)
51
+ if (response === null) {
52
+ return {
53
+ result: EMPTY_RESULT,
54
+ metadata: {
55
+ model: input.model,
56
+ tokenUsage: { input: 0, output: 0 },
57
+ groupCount: 0,
58
+ filteredCount: 0,
59
+ },
60
+ };
61
+ }
50
62
  // Parse response
51
63
  const parsed = parseEnhanceResponse(response.text);
52
64
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"enhance.js","sourceRoot":"","sources":["../../src/enhance/enhance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"enhance.js","sourceRoot":"","sources":["../../src/enhance/enhance.ts"],"names":[],"mappings":"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"}
package/dist/format.d.ts CHANGED
@@ -5,7 +5,53 @@
5
5
  * suitable for posting to a PR via the GitHub API.
6
6
  */
7
7
  import type { ReviewResult, ReviewStatus } from './types.js';
8
+ export interface FileStats {
9
+ additions: number;
10
+ deletions: number;
11
+ }
12
+ interface FileCategory {
13
+ key: string;
14
+ name: string;
15
+ emoji: string;
16
+ patterns: RegExp[];
17
+ }
18
+ export declare const FILE_CATEGORIES: FileCategory[];
8
19
  export declare const STATUS_EMOJI: Record<ReviewStatus, string>;
9
20
  export declare const SEVERITY_EMOJI: Record<string, string>;
10
- export declare function formatReviewComment(result: ReviewResult): string;
21
+ /** Idempotent comment marker used to find and update existing comments. */
22
+ export declare const REVIEW_COMMENT_MARKER = "<!-- ghagga-review -->";
23
+ /**
24
+ * Build a visual emoji stats bar showing additions vs deletions.
25
+ *
26
+ * Format: `🟩🟩🟩🟩🟩🟩🟩🟩🟩🟥🟥 +120 / -15 (net +105)`
27
+ * Uses 20 emoji blocks proportional to the add/delete ratio.
28
+ */
29
+ export declare function buildStatsBar(stats: FileStats): string;
30
+ /**
31
+ * Categorize a list of file paths into groups.
32
+ * Returns categories with at least one file, in definition order.
33
+ */
34
+ export declare function categorizeFiles(fileList: string[]): Array<{
35
+ name: string;
36
+ emoji: string;
37
+ files: string[];
38
+ }>;
39
+ /**
40
+ * Format a file category summary section.
41
+ * Max 3 files shown per category, then "+N more".
42
+ */
43
+ export declare function formatFileCategorySummary(fileList: string[]): string;
44
+ export interface FormatReviewCommentOptions {
45
+ /** File-level additions/deletions stats. When provided, renders the emoji stats bar. */
46
+ fileStats?: FileStats;
47
+ /** List of changed file paths. When provided, renders the categorized file summary. */
48
+ fileList?: string[];
49
+ /**
50
+ * GitHub username of the PR author. When provided, a @mention is appended
51
+ * so GitHub sends a notification to the author when the review is posted.
52
+ */
53
+ prAuthor?: string;
54
+ }
55
+ export declare function formatReviewComment(result: ReviewResult, options?: FormatReviewCommentOptions): string;
56
+ export {};
11
57
  //# sourceMappingURL=format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI7D,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAKrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMjD,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAyFhE"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI7D,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,eAAe,EAAE,YAAY,EAqEzC,CAAC;AAIF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAKrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMjD,CAAC;AAIF,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAI9D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAYtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAAE,GACjB,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAwBzD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAoBpE;AAID,MAAM,WAAW,0BAA0B;IACzC,wFAAwF;IACxF,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,0BAA0B,GACnC,MAAM,CA2HR"}
package/dist/format.js CHANGED
@@ -7,6 +7,76 @@
7
7
  import { initializeDefaultTools } from './tools/plugins/index.js';
8
8
  import { toolRegistry } from './tools/registry.js';
9
9
  import { isToolRegistryEnabled } from './tools/runner.js';
10
+ export const FILE_CATEGORIES = [
11
+ {
12
+ key: 'test',
13
+ name: 'Tests',
14
+ emoji: '\ud83e\uddea',
15
+ patterns: [/\.test\./, /\.spec\./, /__tests__/, /test[s]?\//],
16
+ },
17
+ {
18
+ key: 'docs',
19
+ name: 'Docs',
20
+ emoji: '\ud83d\udcdd',
21
+ patterns: [/\.md$/, /docs?\//, /README/, /CHANGELOG/],
22
+ },
23
+ {
24
+ key: 'ci',
25
+ name: 'CI/CD',
26
+ emoji: '\ud83d\udd04',
27
+ patterns: [/\.github\/workflows/, /\.gitlab-ci/, /Jenkinsfile/],
28
+ },
29
+ {
30
+ key: 'config',
31
+ name: 'Config',
32
+ emoji: '\u2699\ufe0f',
33
+ patterns: [
34
+ /\.config\.[jt]s$/,
35
+ /tsconfig/,
36
+ /\.eslint/,
37
+ /\.prettier/,
38
+ /Dockerfile/,
39
+ /docker-compose/,
40
+ ],
41
+ },
42
+ {
43
+ key: 'deps',
44
+ name: 'Dependencies',
45
+ emoji: '\ud83d\udce6',
46
+ patterns: [
47
+ /package(-lock)?\.json$/,
48
+ /yarn\.lock/,
49
+ /pnpm-lock/,
50
+ /go\.(mod|sum)$/,
51
+ /requirements.*\.txt$/,
52
+ ],
53
+ },
54
+ {
55
+ key: 'style',
56
+ name: 'Styling',
57
+ emoji: '\ud83c\udfa8',
58
+ patterns: [/\.css$/, /\.scss$/, /\.sass$/, /\.less$/],
59
+ },
60
+ {
61
+ key: 'migration',
62
+ name: 'Database',
63
+ emoji: '\ud83d\uddc4\ufe0f',
64
+ patterns: [/migrat/, /schema\./, /seed\./],
65
+ },
66
+ {
67
+ key: 'api',
68
+ name: 'API',
69
+ emoji: '\ud83d\udd0c',
70
+ patterns: [/routes?\//, /api\//, /controllers?\//, /handlers?\//],
71
+ },
72
+ {
73
+ key: 'ui',
74
+ name: 'UI',
75
+ emoji: '\ud83d\uddbc\ufe0f',
76
+ patterns: [/components?\//, /pages?\//, /views?\//, /\.tsx$/],
77
+ },
78
+ { key: 'core', name: 'Core', emoji: '\ud83d\udd27', patterns: [/src\//, /lib\//, /\.[jt]sx?$/] },
79
+ ];
10
80
  // ─── Constants ──────────────────────────────────────────────────
11
81
  export const STATUS_EMOJI = {
12
82
  PASSED: '\u2705 PASSED',
@@ -21,13 +91,106 @@ export const SEVERITY_EMOJI = {
21
91
  low: '\ud83d\udfe2',
22
92
  info: '\ud83d\udfe3',
23
93
  };
94
+ // ─── Formatting Helpers ─────────────────────────────────────────
95
+ /** Idempotent comment marker — used to find and update existing comments. */
96
+ export const REVIEW_COMMENT_MARKER = '<!-- ghagga-review -->';
97
+ const STATS_BAR_BLOCKS = 20;
98
+ /**
99
+ * Build a visual emoji stats bar showing additions vs deletions.
100
+ *
101
+ * Format: `🟩🟩🟩🟩🟩🟩🟩🟩🟩🟥🟥 +120 / -15 (net +105)`
102
+ * Uses 20 emoji blocks proportional to the add/delete ratio.
103
+ */
104
+ export function buildStatsBar(stats) {
105
+ const total = stats.additions + stats.deletions;
106
+ if (total === 0)
107
+ return '';
108
+ const greenCount = Math.round((stats.additions / total) * STATS_BAR_BLOCKS);
109
+ const redCount = STATS_BAR_BLOCKS - greenCount;
110
+ const bar = '\ud83d\udfe9'.repeat(greenCount) + '\ud83d\udfe5'.repeat(redCount);
111
+ const net = stats.additions - stats.deletions;
112
+ const netStr = net >= 0 ? `+${net}` : `${net}`;
113
+ return `${bar} +${stats.additions} / -${stats.deletions} (net ${netStr})`;
114
+ }
115
+ /**
116
+ * Categorize a list of file paths into groups.
117
+ * Returns categories with at least one file, in definition order.
118
+ */
119
+ export function categorizeFiles(fileList) {
120
+ const categorized = new Map();
121
+ const assigned = new Set();
122
+ for (const cat of FILE_CATEGORIES) {
123
+ const matched = [];
124
+ for (const filePath of fileList) {
125
+ if (assigned.has(filePath))
126
+ continue;
127
+ if (cat.patterns.some((p) => p.test(filePath))) {
128
+ matched.push(filePath);
129
+ assigned.add(filePath);
130
+ }
131
+ }
132
+ if (matched.length > 0) {
133
+ categorized.set(cat.key, matched);
134
+ }
135
+ }
136
+ // Return in definition order, only non-empty categories
137
+ return FILE_CATEGORIES.filter((cat) => categorized.has(cat.key)).map((cat) => ({
138
+ name: cat.name,
139
+ emoji: cat.emoji,
140
+ files: categorized.get(cat.key),
141
+ }));
142
+ }
143
+ /**
144
+ * Format a file category summary section.
145
+ * Max 3 files shown per category, then "+N more".
146
+ */
147
+ export function formatFileCategorySummary(fileList) {
148
+ const categories = categorizeFiles(fileList);
149
+ if (categories.length === 0)
150
+ return '';
151
+ let section = `### Files Changed (${fileList.length})\n`;
152
+ for (const cat of categories) {
153
+ const basenames = cat.files.map((f) => f.split('/').pop() ?? f);
154
+ const MAX_SHOWN = 3;
155
+ const shown = basenames.slice(0, MAX_SHOWN);
156
+ const remaining = basenames.length - MAX_SHOWN;
157
+ section += `${cat.emoji} **${cat.name}**: ${shown.join(', ')}`;
158
+ if (remaining > 0) {
159
+ section += ` (+${remaining} more)`;
160
+ }
161
+ section += '\n';
162
+ }
163
+ return section + '\n';
164
+ }
24
165
  // ─── Formatting ─────────────────────────────────────────────────
25
- export function formatReviewComment(result) {
166
+ export function formatReviewComment(result, options) {
26
167
  const status = STATUS_EMOJI[result.status] ?? result.status;
27
168
  const timeSeconds = (result.metadata.executionTimeMs / 1000).toFixed(1);
28
- let comment = `## \ud83e\udd16 GHAGGA Code Review\n\n`;
169
+ let comment = `${REVIEW_COMMENT_MARKER}\n## \ud83e\udd16 GHAGGA Code Review\n\n`;
29
170
  comment += `**Status:** ${status}\n`;
30
- comment += `**Mode:** ${result.metadata.mode} | **Model:** ${result.metadata.model} | **Time:** ${timeSeconds}s\n\n`;
171
+ const modelsUsed = result.metadata.modelsUsed;
172
+ if (modelsUsed && modelsUsed.length > 1) {
173
+ // Multi-model: show primary model + details per specialist/stance
174
+ comment += `**Mode:** ${result.metadata.mode} | **Model:** ${result.metadata.model} | **Time:** ${timeSeconds}s\n`;
175
+ comment += `<details><summary>\ud83e\udde0 Models used (${modelsUsed.length})</summary>\n\n`;
176
+ comment += '| Role | Model |\n|------|-------|\n';
177
+ for (const entry of modelsUsed) {
178
+ const [role, model] = entry.includes(':') ? entry.split(':', 2) : ['—', entry];
179
+ comment += `| ${role} | \`${model}\` |\n`;
180
+ }
181
+ comment += '\n</details>\n';
182
+ }
183
+ else {
184
+ comment += `**Mode:** ${result.metadata.mode} | **Model:** ${result.metadata.model} | **Time:** ${timeSeconds}s\n`;
185
+ }
186
+ // Emoji stats bar (Enhancement 1)
187
+ if (options?.fileStats) {
188
+ const statsBar = buildStatsBar(options.fileStats);
189
+ if (statsBar) {
190
+ comment += `${statsBar}\n`;
191
+ }
192
+ }
193
+ comment += '\n';
31
194
  // Summary
32
195
  comment += `### Summary\n${result.summary}\n\n`;
33
196
  // Findings grouped by source
@@ -98,7 +261,16 @@ export function formatReviewComment(result) {
98
261
  }
99
262
  comment += '\n';
100
263
  }
264
+ // File category summary (Enhancement 3)
265
+ if (options?.fileList && options.fileList.length > 0) {
266
+ comment += formatFileCategorySummary(options.fileList);
267
+ }
101
268
  comment += `---\n*Powered by [GHAGGA](https://github.com/JNZader/ghagga) \u2014 AI Code Review*`;
269
+ // @mention the PR author so GitHub sends them a notification.
270
+ // Rendered as small text to keep the footer clean.
271
+ if (options?.prAuthor) {
272
+ comment += ` — @${options.prAuthor}`;
273
+ }
102
274
  return comment;
103
275
  }
104
276
  //# sourceMappingURL=format.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Blast-Radius Computation
3
+ *
4
+ * Given a dependency graph and a set of changed files, computes the
5
+ * "blast radius" — the set of files transitively affected by the changes.
6
+ *
7
+ * Uses BFS reverse traversal: for each changed file, find all files that
8
+ * import/call it, up to a configurable depth limit. Test files that depend
9
+ * on any impacted file are automatically included.
10
+ */
11
+ import { type DependencyGraph } from './schema.js';
12
+ export interface BlastRadiusOptions {
13
+ /** Maximum BFS traversal depth. Default: DEFAULT_TRAVERSAL_DEPTH (3) */
14
+ maxDepth?: number;
15
+ /** Maximum files before declaring "exceeded cap". Default: MAX_BLAST_RADIUS_FILES (50) */
16
+ maxFiles?: number;
17
+ /** Whether to include test files in the result. Default: true */
18
+ includeTests?: boolean;
19
+ }
20
+ export interface BlastRadiusResult {
21
+ /** All files in the blast radius (changed + dependents + tests) */
22
+ files: Set<string>;
23
+ /** Only the changed files from the input that exist in the graph */
24
+ changedFiles: string[];
25
+ /** Files that depend on changed files (not including the changed files themselves) */
26
+ dependents: string[];
27
+ /** Test files added to the blast radius */
28
+ testFiles: string[];
29
+ /** Max depth actually reached during BFS */
30
+ depth: number;
31
+ /** Whether the blast radius exceeded the file cap */
32
+ exceededCap: boolean;
33
+ }
34
+ /**
35
+ * Build a reverse adjacency map from the dependency graph.
36
+ *
37
+ * For each edge A → B (A imports B), creates a reverse edge B → A.
38
+ * This allows efficient lookup of "who depends on this file?"
39
+ * Also includes reverse edges for `calls[].target`.
40
+ */
41
+ export declare function buildReverseIndex(graph: DependencyGraph): Map<string, Set<string>>;
42
+ /**
43
+ * Compute the blast radius for a set of changed files.
44
+ *
45
+ * Algorithm:
46
+ * 1. Build reverse index (who depends on whom)
47
+ * 2. BFS from changed files through reverse dependencies, up to maxDepth
48
+ * 3. Collect test files that import any file in the blast radius
49
+ * 4. If total exceeds maxFiles, set exceededCap flag
50
+ *
51
+ * @param graph - The dependency graph
52
+ * @param changedFiles - File paths that were modified in the PR
53
+ * @param options - Traversal limits
54
+ * @returns BlastRadiusResult with all impacted files
55
+ */
56
+ export declare function computeBlastRadius(graph: DependencyGraph, changedFiles: string[], options?: BlastRadiusOptions): BlastRadiusResult;
57
+ //# sourceMappingURL=blast-radius.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blast-radius.d.ts","sourceRoot":"","sources":["../../src/graph/blast-radius.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAA2B,KAAK,eAAe,EAA0B,MAAM,aAAa,CAAC;AAIpG,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,iEAAiE;IACjE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAEnB,oEAAoE;IACpE,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,sFAAsF;IACtF,UAAU,EAAE,MAAM,EAAE,CAAC;IAErB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IAEd,qDAAqD;IACrD,WAAW,EAAE,OAAO,CAAC;CACtB;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAsBlF;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,iBAAiB,CAoGnB"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Blast-Radius Computation
3
+ *
4
+ * Given a dependency graph and a set of changed files, computes the
5
+ * "blast radius" — the set of files transitively affected by the changes.
6
+ *
7
+ * Uses BFS reverse traversal: for each changed file, find all files that
8
+ * import/call it, up to a configurable depth limit. Test files that depend
9
+ * on any impacted file are automatically included.
10
+ */
11
+ import { DEFAULT_TRAVERSAL_DEPTH, MAX_BLAST_RADIUS_FILES } from './schema.js';
12
+ // ─── Reverse Index ──────────────────────────────────────────────
13
+ /**
14
+ * Build a reverse adjacency map from the dependency graph.
15
+ *
16
+ * For each edge A → B (A imports B), creates a reverse edge B → A.
17
+ * This allows efficient lookup of "who depends on this file?"
18
+ * Also includes reverse edges for `calls[].target`.
19
+ */
20
+ export function buildReverseIndex(graph) {
21
+ const reverseIndex = new Map();
22
+ for (const [filePath, node] of Object.entries(graph.nodes)) {
23
+ // Reverse edges for imports: if filePath imports target, then target → filePath
24
+ for (const importPath of node.imports) {
25
+ if (!reverseIndex.has(importPath)) {
26
+ reverseIndex.set(importPath, new Set());
27
+ }
28
+ reverseIndex.get(importPath).add(filePath);
29
+ }
30
+ // Reverse edges for calls: if filePath calls target, then target → filePath
31
+ for (const call of node.calls) {
32
+ if (!reverseIndex.has(call.target)) {
33
+ reverseIndex.set(call.target, new Set());
34
+ }
35
+ reverseIndex.get(call.target).add(filePath);
36
+ }
37
+ }
38
+ return reverseIndex;
39
+ }
40
+ // ─── BFS Computation ────────────────────────────────────────────
41
+ /**
42
+ * Compute the blast radius for a set of changed files.
43
+ *
44
+ * Algorithm:
45
+ * 1. Build reverse index (who depends on whom)
46
+ * 2. BFS from changed files through reverse dependencies, up to maxDepth
47
+ * 3. Collect test files that import any file in the blast radius
48
+ * 4. If total exceeds maxFiles, set exceededCap flag
49
+ *
50
+ * @param graph - The dependency graph
51
+ * @param changedFiles - File paths that were modified in the PR
52
+ * @param options - Traversal limits
53
+ * @returns BlastRadiusResult with all impacted files
54
+ */
55
+ export function computeBlastRadius(graph, changedFiles, options) {
56
+ const maxDepth = options?.maxDepth ?? DEFAULT_TRAVERSAL_DEPTH;
57
+ const maxFiles = options?.maxFiles ?? MAX_BLAST_RADIUS_FILES;
58
+ const includeTests = options?.includeTests ?? true;
59
+ // Handle empty input
60
+ if (changedFiles.length === 0) {
61
+ return {
62
+ files: new Set(),
63
+ changedFiles: [],
64
+ dependents: [],
65
+ testFiles: [],
66
+ depth: 0,
67
+ exceededCap: false,
68
+ };
69
+ }
70
+ const reverseIndex = buildReverseIndex(graph);
71
+ // Track all visited non-test nodes (for cycle detection and BFS)
72
+ const visited = new Set();
73
+ const dependentsSet = new Set();
74
+ const testFilesSet = new Set();
75
+ // Include changed files in visited (but not in dependents)
76
+ for (const file of changedFiles) {
77
+ visited.add(file);
78
+ }
79
+ // BFS traversal — only follows non-test files
80
+ // Test files are collected separately after BFS
81
+ let queue = [...changedFiles];
82
+ let actualDepth = 0;
83
+ for (let depth = 0; depth < maxDepth && queue.length > 0; depth++) {
84
+ const nextQueue = [];
85
+ for (const file of queue) {
86
+ const reverseDeps = reverseIndex.get(file);
87
+ if (!reverseDeps)
88
+ continue;
89
+ for (const dependent of reverseDeps) {
90
+ if (visited.has(dependent) || testFilesSet.has(dependent))
91
+ continue;
92
+ const node = graph.nodes[dependent];
93
+ if (node?.isTest) {
94
+ // Test files are collected but not traversed further
95
+ if (includeTests) {
96
+ testFilesSet.add(dependent);
97
+ }
98
+ }
99
+ else {
100
+ visited.add(dependent);
101
+ dependentsSet.add(dependent);
102
+ nextQueue.push(dependent);
103
+ }
104
+ }
105
+ }
106
+ if (nextQueue.length > 0) {
107
+ actualDepth = depth + 1;
108
+ }
109
+ queue = nextQueue;
110
+ }
111
+ // Post-BFS: find additional test files that import any file in the blast radius
112
+ // This catches tests that weren't direct reverse deps during BFS
113
+ if (includeTests) {
114
+ for (const file of visited) {
115
+ const reverseDeps = reverseIndex.get(file);
116
+ if (!reverseDeps)
117
+ continue;
118
+ for (const dependent of reverseDeps) {
119
+ if (visited.has(dependent) || testFilesSet.has(dependent))
120
+ continue;
121
+ const node = graph.nodes[dependent];
122
+ if (node?.isTest) {
123
+ testFilesSet.add(dependent);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ // Build the full file set
129
+ const allFiles = new Set(visited);
130
+ for (const testFile of testFilesSet) {
131
+ allFiles.add(testFile);
132
+ }
133
+ const dependents = [...dependentsSet];
134
+ // Check cap
135
+ const exceededCap = allFiles.size > maxFiles;
136
+ return {
137
+ files: allFiles,
138
+ changedFiles: changedFiles.filter((f) => visited.has(f)),
139
+ dependents,
140
+ testFiles: [...testFilesSet],
141
+ depth: actualDepth,
142
+ exceededCap,
143
+ };
144
+ }
145
+ //# sourceMappingURL=blast-radius.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blast-radius.js","sourceRoot":"","sources":["../../src/graph/blast-radius.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Graph Builder
3
+ *
4
+ * Builds a DependencyGraph from a map of file paths → file content.
5
+ * Pure function: no filesystem access — the caller provides content.
6
+ *
7
+ * Two modes:
8
+ * - `buildGraph()` — full build from scratch
9
+ * - `buildGraphIncremental()` — updates only changed/deleted nodes
10
+ */
11
+ import { type DependencyGraph, type SupportedLanguage } from './schema.js';
12
+ /**
13
+ * Detect the language of a file based on its extension.
14
+ * Returns undefined for unsupported extensions.
15
+ */
16
+ export declare function detectLanguage(filePath: string): SupportedLanguage | undefined;
17
+ /**
18
+ * Check if a file path traverses any excluded directory.
19
+ */
20
+ export declare function isExcludedPath(filePath: string): boolean;
21
+ /**
22
+ * Resolve a relative import path to an absolute path within the project.
23
+ *
24
+ * Given the file doing the import and the import specifier, resolves
25
+ * to a project-relative path. Only resolves relative imports (starting
26
+ * with `.` or `..`). Non-relative imports (e.g., 'lodash') are returned
27
+ * as-is since they refer to external packages.
28
+ */
29
+ export declare function resolveImportPath(importerPath: string, importSpecifier: string, availableFiles: Set<string>): string;
30
+ /**
31
+ * Build a complete dependency graph from a map of file paths → file content.
32
+ *
33
+ * @param rootDir - Base directory for all paths (used in the graph metadata)
34
+ * @param files - Map of relative file paths to their content
35
+ * @returns Complete DependencyGraph
36
+ */
37
+ export declare function buildGraph(rootDir: string, files: Map<string, string>): DependencyGraph;
38
+ /**
39
+ * Update a dependency graph incrementally.
40
+ *
41
+ * Only re-processes changed files and removes deleted files.
42
+ * Unchanged files keep their existing nodes.
43
+ *
44
+ * @param existing - The existing dependency graph
45
+ * @param changedFiles - Map of changed file paths → new content
46
+ * @param deletedFiles - Array of file paths that were deleted
47
+ * @returns Updated DependencyGraph
48
+ */
49
+ export declare function buildGraphIncremental(existing: DependencyGraph, changedFiles: Map<string, string>, deletedFiles: string[]): DependencyGraph;
50
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/graph/builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EACL,KAAK,eAAe,EAMpB,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAIrB;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAG9E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGxD;AASD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,MAAM,CAmDR;AAID;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,eAAe,CAkDvF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,YAAY,EAAE,MAAM,EAAE,GACrB,eAAe,CAuDjB"}