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.
- package/README.md +1 -1
- package/dist/agents/consensus.d.ts +16 -0
- package/dist/agents/consensus.d.ts.map +1 -1
- package/dist/agents/consensus.js +57 -33
- package/dist/agents/consensus.js.map +1 -1
- package/dist/agents/diagnostic.d.ts +55 -0
- package/dist/agents/diagnostic.d.ts.map +1 -0
- package/dist/agents/diagnostic.js +143 -0
- package/dist/agents/diagnostic.js.map +1 -0
- package/dist/agents/prompts.d.ts +6 -4
- package/dist/agents/prompts.d.ts.map +1 -1
- package/dist/agents/prompts.js +110 -24
- package/dist/agents/prompts.js.map +1 -1
- package/dist/agents/simple.d.ts +7 -0
- package/dist/agents/simple.d.ts.map +1 -1
- package/dist/agents/simple.js +32 -18
- package/dist/agents/simple.js.map +1 -1
- package/dist/agents/workflow.d.ts +28 -1
- package/dist/agents/workflow.d.ts.map +1 -1
- package/dist/agents/workflow.js +112 -45
- package/dist/agents/workflow.js.map +1 -1
- package/dist/enhance/enhance.d.ts.map +1 -1
- package/dist/enhance/enhance.js +16 -4
- package/dist/enhance/enhance.js.map +1 -1
- package/dist/format.d.ts +47 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +175 -3
- package/dist/format.js.map +1 -1
- package/dist/graph/blast-radius.d.ts +57 -0
- package/dist/graph/blast-radius.d.ts.map +1 -0
- package/dist/graph/blast-radius.js +145 -0
- package/dist/graph/blast-radius.js.map +1 -0
- package/dist/graph/builder.d.ts +50 -0
- package/dist/graph/builder.d.ts.map +1 -0
- package/dist/graph/builder.js +210 -0
- package/dist/graph/builder.js.map +1 -0
- package/dist/graph/extractors/go.d.ts +9 -0
- package/dist/graph/extractors/go.d.ts.map +1 -0
- package/dist/graph/extractors/go.js +78 -0
- package/dist/graph/extractors/go.js.map +1 -0
- package/dist/graph/extractors/index.d.ts +22 -0
- package/dist/graph/extractors/index.d.ts.map +1 -0
- package/dist/graph/extractors/index.js +37 -0
- package/dist/graph/extractors/index.js.map +1 -0
- package/dist/graph/extractors/java.d.ts +9 -0
- package/dist/graph/extractors/java.d.ts.map +1 -0
- package/dist/graph/extractors/java.js +80 -0
- package/dist/graph/extractors/java.js.map +1 -0
- package/dist/graph/extractors/javascript.d.ts +9 -0
- package/dist/graph/extractors/javascript.d.ts.map +1 -0
- package/dist/graph/extractors/javascript.js +204 -0
- package/dist/graph/extractors/javascript.js.map +1 -0
- package/dist/graph/extractors/python.d.ts +9 -0
- package/dist/graph/extractors/python.d.ts.map +1 -0
- package/dist/graph/extractors/python.js +103 -0
- package/dist/graph/extractors/python.js.map +1 -0
- package/dist/graph/extractors/rust.d.ts +9 -0
- package/dist/graph/extractors/rust.d.ts.map +1 -0
- package/dist/graph/extractors/rust.js +115 -0
- package/dist/graph/extractors/rust.js.map +1 -0
- package/dist/graph/extractors/types.d.ts +31 -0
- package/dist/graph/extractors/types.d.ts.map +1 -0
- package/dist/graph/extractors/types.js +9 -0
- package/dist/graph/extractors/types.js.map +1 -0
- package/dist/graph/extractors/typescript.d.ts +9 -0
- package/dist/graph/extractors/typescript.d.ts.map +1 -0
- package/dist/graph/extractors/typescript.js +151 -0
- package/dist/graph/extractors/typescript.js.map +1 -0
- package/dist/graph/index.d.ts +15 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +14 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/loader.d.ts +43 -0
- package/dist/graph/loader.d.ts.map +1 -0
- package/dist/graph/loader.js +104 -0
- package/dist/graph/loader.js.map +1 -0
- package/dist/graph/schema.d.ts +113 -0
- package/dist/graph/schema.d.ts.map +1 -0
- package/dist/graph/schema.js +144 -0
- package/dist/graph/schema.js.map +1 -0
- package/dist/health/trends.js +1 -1
- package/dist/health/trends.js.map +1 -1
- package/dist/index.d.ts +20 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/memory/sqlite.js +4 -4
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +291 -42
- package/dist/pipeline.js.map +1 -1
- package/dist/providers/cli-bridge.d.ts +136 -0
- package/dist/providers/cli-bridge.d.ts.map +1 -0
- package/dist/providers/cli-bridge.js +457 -0
- package/dist/providers/cli-bridge.js.map +1 -0
- package/dist/providers/fallback.d.ts +8 -0
- package/dist/providers/fallback.d.ts.map +1 -1
- package/dist/providers/fallback.js +24 -8
- package/dist/providers/fallback.js.map +1 -1
- package/dist/providers/gateway.d.ts +40 -0
- package/dist/providers/gateway.d.ts.map +1 -0
- package/dist/providers/gateway.js +52 -0
- package/dist/providers/gateway.js.map +1 -0
- package/dist/providers/generate-fn.d.ts +62 -0
- package/dist/providers/generate-fn.d.ts.map +1 -0
- package/dist/providers/generate-fn.js +84 -0
- package/dist/providers/generate-fn.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +53 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/tools/plugins/index.d.ts +2 -0
- package/dist/tools/plugins/index.d.ts.map +1 -1
- package/dist/tools/plugins/index.js +7 -0
- package/dist/tools/plugins/index.js.map +1 -1
- package/dist/tools/plugins/zizmor.d.ts +22 -0
- package/dist/tools/plugins/zizmor.d.ts.map +1 -0
- package/dist/tools/plugins/zizmor.js +112 -0
- package/dist/tools/plugins/zizmor.js.map +1 -0
- package/dist/tools/resolve.js +1 -1
- package/dist/tools/resolve.js.map +1 -1
- package/dist/tools/types.d.ts +1 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/types.d.ts +54 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +21 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/concurrency.d.ts +29 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +40 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/context-levels.d.ts +113 -0
- package/dist/utils/context-levels.d.ts.map +1 -0
- package/dist/utils/context-levels.js +255 -0
- package/dist/utils/context-levels.js.map +1 -0
- package/dist/utils/diff.d.ts +25 -0
- package/dist/utils/diff.d.ts.map +1 -1
- package/dist/utils/diff.js +28 -0
- package/dist/utils/diff.js.map +1 -1
- package/dist/utils/llm-timeout.d.ts +38 -0
- package/dist/utils/llm-timeout.d.ts.map +1 -0
- package/dist/utils/llm-timeout.js +76 -0
- package/dist/utils/llm-timeout.js.map +1 -0
- package/dist/utils/path-protection.d.ts +59 -0
- package/dist/utils/path-protection.d.ts.map +1 -0
- package/dist/utils/path-protection.js +136 -0
- package/dist/utils/path-protection.js.map +1 -0
- package/dist/utils/token-budget.d.ts +34 -1
- package/dist/utils/token-budget.d.ts.map +1 -1
- package/dist/utils/token-budget.js +108 -3
- package/dist/utils/token-budget.js.map +1 -1
- package/package.json +21 -19
- package/LICENSE +0 -21
package/dist/enhance/enhance.js
CHANGED
|
@@ -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 {
|
|
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
|
|
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":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,
|
|
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
|
-
|
|
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
|
package/dist/format.d.ts.map
CHANGED
|
@@ -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,
|
|
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 =
|
|
169
|
+
let comment = `${REVIEW_COMMENT_MARKER}\n## \ud83e\udd16 GHAGGA Code Review\n\n`;
|
|
29
170
|
comment += `**Status:** ${status}\n`;
|
|
30
|
-
|
|
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
|
package/dist/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;
|
|
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"}
|