@su-record/vibe 3.2.19 → 3.2.21
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/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
- package/dist/cli/setup/ProjectSetup.js +13 -1
- package/dist/cli/setup/ProjectSetup.js.map +1 -1
- package/dist/tools/dispatch/deterministicSignals.d.ts.map +1 -1
- package/dist/tools/dispatch/deterministicSignals.js +15 -10
- package/dist/tools/dispatch/deterministicSignals.js.map +1 -1
- package/dist/tools/dispatch/vibePaths.d.ts +7 -0
- package/dist/tools/dispatch/vibePaths.d.ts.map +1 -0
- package/dist/tools/dispatch/vibePaths.js +35 -0
- package/dist/tools/dispatch/vibePaths.js.map +1 -0
- package/dist/tools/spec/validateSpecDocument.d.ts.map +1 -1
- package/dist/tools/spec/validateSpecDocument.js +33 -6
- package/dist/tools/spec/validateSpecDocument.js.map +1 -1
- package/hooks/scripts/code-check.js +90 -16
- package/hooks/scripts/lib/anchor.js +15 -4
- package/hooks/scripts/lib/inbox.js +10 -2
- package/package.json +1 -1
- package/dist/infra/lib/DeepInit.d.ts +0 -60
- package/dist/infra/lib/DeepInit.d.ts.map +0 -1
- package/dist/infra/lib/DeepInit.js +0 -245
- package/dist/infra/lib/DeepInit.js.map +0 -1
- package/dist/infra/lib/FrameworkDetector.d.ts +0 -56
- package/dist/infra/lib/FrameworkDetector.d.ts.map +0 -1
- package/dist/infra/lib/FrameworkDetector.js +0 -287
- package/dist/infra/lib/FrameworkDetector.js.map +0 -1
- package/dist/infra/lib/ModelRouter.d.ts +0 -48
- package/dist/infra/lib/ModelRouter.d.ts.map +0 -1
- package/dist/infra/lib/ModelRouter.js +0 -216
- package/dist/infra/lib/ModelRouter.js.map +0 -1
- package/dist/infra/lib/ReviewRace.d.ts +0 -86
- package/dist/infra/lib/ReviewRace.d.ts.map +0 -1
- package/dist/infra/lib/ReviewRace.js +0 -454
- package/dist/infra/lib/ReviewRace.js.map +0 -1
- package/dist/infra/lib/RuleBuildSystem.d.ts +0 -157
- package/dist/infra/lib/RuleBuildSystem.d.ts.map +0 -1
- package/dist/infra/lib/RuleBuildSystem.js +0 -550
- package/dist/infra/lib/RuleBuildSystem.js.map +0 -1
- package/dist/infra/lib/SkillQualityGate.d.ts +0 -42
- package/dist/infra/lib/SkillQualityGate.d.ts.map +0 -1
- package/dist/infra/lib/SkillQualityGate.js +0 -220
- package/dist/infra/lib/SkillQualityGate.js.map +0 -1
- package/dist/infra/lib/SkillRepository.d.ts +0 -134
- package/dist/infra/lib/SkillRepository.d.ts.map +0 -1
- package/dist/infra/lib/SkillRepository.js +0 -500
- package/dist/infra/lib/SkillRepository.js.map +0 -1
- package/dist/infra/lib/UltraQA.d.ts +0 -89
- package/dist/infra/lib/UltraQA.d.ts.map +0 -1
- package/dist/infra/lib/UltraQA.js +0 -301
- package/dist/infra/lib/UltraQA.js.map +0 -1
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Multi-LLM Race Review
|
|
3
|
-
*
|
|
4
|
-
* 같은 리뷰 작업을 Claude + GPT + Antigravity가 병렬로 수행하고
|
|
5
|
-
* 교차 검증하여 신뢰도 기반 우선순위를 부여합니다.
|
|
6
|
-
*
|
|
7
|
-
* @deprecated Not wired into the vibe runtime (no hook/skill/CLI consumer).
|
|
8
|
-
* No consumer in the shipped pipeline.
|
|
9
|
-
* Retained for API compatibility; may be removed in a future major.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* import { raceReview, formatRaceResult } from '@su-record/vibe/lib/ReviewRace';
|
|
14
|
-
*
|
|
15
|
-
* const result = await raceReview({
|
|
16
|
-
* reviewType: 'security',
|
|
17
|
-
* code: diffContent,
|
|
18
|
-
* context: 'Authentication module changes',
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* console.log(formatRaceResult(result));
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export type LLMProvider = 'claude' | 'gpt' | 'antigravity';
|
|
25
|
-
export type Priority = 'P1' | 'P2' | 'P3';
|
|
26
|
-
export type ReviewType = 'security' | 'performance' | 'architecture' | 'complexity' | 'data-integrity' | 'test-coverage' | 'general';
|
|
27
|
-
export interface ReviewIssue {
|
|
28
|
-
id: string;
|
|
29
|
-
title: string;
|
|
30
|
-
description: string;
|
|
31
|
-
location?: string;
|
|
32
|
-
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
33
|
-
suggestion?: string;
|
|
34
|
-
}
|
|
35
|
-
export interface LLMReviewResult {
|
|
36
|
-
provider: LLMProvider;
|
|
37
|
-
issues: ReviewIssue[];
|
|
38
|
-
duration: number;
|
|
39
|
-
error?: string;
|
|
40
|
-
}
|
|
41
|
-
export interface CrossValidatedIssue {
|
|
42
|
-
issue: ReviewIssue;
|
|
43
|
-
foundBy: LLMProvider[];
|
|
44
|
-
confidence: number;
|
|
45
|
-
priority: Priority;
|
|
46
|
-
consensusTitle: string;
|
|
47
|
-
}
|
|
48
|
-
export interface RaceReviewResult {
|
|
49
|
-
reviewType: ReviewType;
|
|
50
|
-
llmResults: LLMReviewResult[];
|
|
51
|
-
crossValidated: CrossValidatedIssue[];
|
|
52
|
-
summary: {
|
|
53
|
-
totalIssues: number;
|
|
54
|
-
p1Count: number;
|
|
55
|
-
p2Count: number;
|
|
56
|
-
p3Count: number;
|
|
57
|
-
consensusRate: number;
|
|
58
|
-
};
|
|
59
|
-
duration: number;
|
|
60
|
-
}
|
|
61
|
-
export interface RaceReviewOptions {
|
|
62
|
-
reviewType: ReviewType;
|
|
63
|
-
code: string;
|
|
64
|
-
context?: string;
|
|
65
|
-
includeClaudeSubagent?: boolean;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Multi-LLM Race Review 수행
|
|
69
|
-
*
|
|
70
|
-
* GPT + Antigravity를 병렬로 실행하고 결과를 교차 검증합니다.
|
|
71
|
-
* Claude는 현재 세션에서 실행 중이므로 별도의 서브에이전트로 호출됩니다.
|
|
72
|
-
*/
|
|
73
|
-
export declare function raceReview(options: RaceReviewOptions): Promise<RaceReviewResult>;
|
|
74
|
-
/**
|
|
75
|
-
* Race Review 결과를 마크다운으로 포맷
|
|
76
|
-
*/
|
|
77
|
-
export declare function formatRaceResult(result: RaceReviewResult): string;
|
|
78
|
-
/**
|
|
79
|
-
* LLM 가용성 확인
|
|
80
|
-
*/
|
|
81
|
-
export declare function checkLLMAvailability(): Promise<{
|
|
82
|
-
gpt: boolean;
|
|
83
|
-
antigravity: boolean;
|
|
84
|
-
}>;
|
|
85
|
-
export type { ReviewIssue as RaceReviewIssue, LLMReviewResult as RaceLLMResult, CrossValidatedIssue as RaceCrossValidatedIssue, };
|
|
86
|
-
//# sourceMappingURL=ReviewRace.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewRace.d.ts","sourceRoot":"","sources":["../../../src/infra/lib/ReviewRace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAUH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,GAAG,aAAa,CAAC;AAC3D,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC1C,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,aAAa,GACb,cAAc,GACd,YAAY,GACZ,gBAAgB,GAChB,eAAe,GACf,SAAS,CAAC;AAEd,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,cAAc,EAAE,mBAAmB,EAAE,CAAC;IACtC,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AA6XD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsCtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAkDjE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC;IACpD,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC,CAUD;AAGD,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,aAAa,EAChC,mBAAmB,IAAI,uBAAuB,GAC/C,CAAC"}
|
|
@@ -1,454 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Multi-LLM Race Review
|
|
3
|
-
*
|
|
4
|
-
* 같은 리뷰 작업을 Claude + GPT + Antigravity가 병렬로 수행하고
|
|
5
|
-
* 교차 검증하여 신뢰도 기반 우선순위를 부여합니다.
|
|
6
|
-
*
|
|
7
|
-
* @deprecated Not wired into the vibe runtime (no hook/skill/CLI consumer).
|
|
8
|
-
* No consumer in the shipped pipeline.
|
|
9
|
-
* Retained for API compatibility; may be removed in a future major.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* import { raceReview, formatRaceResult } from '@su-record/vibe/lib/ReviewRace';
|
|
14
|
-
*
|
|
15
|
-
* const result = await raceReview({
|
|
16
|
-
* reviewType: 'security',
|
|
17
|
-
* code: diffContent,
|
|
18
|
-
* context: 'Authentication module changes',
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* console.log(formatRaceResult(result));
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
import * as gptApi from './gpt/index.js';
|
|
25
|
-
import * as antigravityApi from './antigravity/index.js';
|
|
26
|
-
import { isAntigravityAvailable, isCodexAvailable } from './llm-availability.js';
|
|
27
|
-
// ============================================================================
|
|
28
|
-
// Constants
|
|
29
|
-
// ============================================================================
|
|
30
|
-
const REVIEW_PROMPTS = {
|
|
31
|
-
security: `You are a security expert reviewing code changes.
|
|
32
|
-
Identify security vulnerabilities including:
|
|
33
|
-
- SQL injection, XSS, CSRF
|
|
34
|
-
- Authentication/authorization flaws
|
|
35
|
-
- Sensitive data exposure
|
|
36
|
-
- Insecure dependencies
|
|
37
|
-
- OWASP Top 10 issues
|
|
38
|
-
|
|
39
|
-
For each issue found, respond in this exact JSON format:
|
|
40
|
-
{
|
|
41
|
-
"issues": [
|
|
42
|
-
{
|
|
43
|
-
"id": "SEC-001",
|
|
44
|
-
"title": "Brief title",
|
|
45
|
-
"description": "Detailed description",
|
|
46
|
-
"location": "file.ts:42",
|
|
47
|
-
"severity": "critical|high|medium|low",
|
|
48
|
-
"suggestion": "How to fix"
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
If no issues found, respond: {"issues": []}`,
|
|
54
|
-
performance: `You are a performance expert reviewing code changes.
|
|
55
|
-
Identify performance issues including:
|
|
56
|
-
- N+1 queries
|
|
57
|
-
- Memory leaks
|
|
58
|
-
- Unnecessary re-renders
|
|
59
|
-
- Blocking operations
|
|
60
|
-
- Large bundle size impacts
|
|
61
|
-
- Missing caching opportunities
|
|
62
|
-
|
|
63
|
-
Respond in JSON format:
|
|
64
|
-
{
|
|
65
|
-
"issues": [
|
|
66
|
-
{
|
|
67
|
-
"id": "PERF-001",
|
|
68
|
-
"title": "Brief title",
|
|
69
|
-
"description": "Detailed description",
|
|
70
|
-
"location": "file.ts:42",
|
|
71
|
-
"severity": "critical|high|medium|low",
|
|
72
|
-
"suggestion": "How to fix"
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
}`,
|
|
76
|
-
architecture: `You are an architecture expert reviewing code changes.
|
|
77
|
-
Identify architecture issues including:
|
|
78
|
-
- Circular dependencies
|
|
79
|
-
- Layer violations (e.g., UI calling DB directly)
|
|
80
|
-
- Missing abstractions
|
|
81
|
-
- Tight coupling
|
|
82
|
-
- Single Responsibility violations
|
|
83
|
-
- DRY violations
|
|
84
|
-
|
|
85
|
-
Respond in JSON format with issues array.`,
|
|
86
|
-
complexity: `You are a code quality expert reviewing complexity.
|
|
87
|
-
Identify complexity issues including:
|
|
88
|
-
- Functions > 30 lines
|
|
89
|
-
- Nesting depth > 3 levels
|
|
90
|
-
- Cyclomatic complexity > 10
|
|
91
|
-
- Too many parameters (> 5)
|
|
92
|
-
- Long files (> 300 lines)
|
|
93
|
-
|
|
94
|
-
Respond in JSON format with issues array.`,
|
|
95
|
-
'data-integrity': `You are a data integrity expert reviewing code changes.
|
|
96
|
-
Identify data integrity issues including:
|
|
97
|
-
- Missing validations
|
|
98
|
-
- Race conditions
|
|
99
|
-
- Inconsistent state handling
|
|
100
|
-
- Missing error handling
|
|
101
|
-
- Data loss scenarios
|
|
102
|
-
|
|
103
|
-
Respond in JSON format with issues array.`,
|
|
104
|
-
'test-coverage': `You are a testing expert reviewing code changes.
|
|
105
|
-
Identify missing test coverage including:
|
|
106
|
-
- Untested edge cases
|
|
107
|
-
- Missing error case tests
|
|
108
|
-
- Missing integration tests
|
|
109
|
-
- Untested business logic
|
|
110
|
-
|
|
111
|
-
Respond in JSON format with issues array.`,
|
|
112
|
-
general: `You are a senior code reviewer.
|
|
113
|
-
Review this code for any issues including security, performance, maintainability, and best practices.
|
|
114
|
-
|
|
115
|
-
Respond in JSON format with issues array.`,
|
|
116
|
-
};
|
|
117
|
-
// ============================================================================
|
|
118
|
-
// Helper Functions
|
|
119
|
-
// ============================================================================
|
|
120
|
-
/**
|
|
121
|
-
* 이슈 ID에서 숫자 추출
|
|
122
|
-
*/
|
|
123
|
-
function extractIssueNumber(id) {
|
|
124
|
-
const match = id.match(/\d+/);
|
|
125
|
-
return match ? parseInt(match[0], 10) : 0;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* 두 이슈가 유사한지 판단 (제목/설명 기반)
|
|
129
|
-
*/
|
|
130
|
-
function areIssuesSimilar(a, b) {
|
|
131
|
-
// 1. 위치가 같으면 유사
|
|
132
|
-
if (a.location && b.location && a.location === b.location) {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
// 2. 제목 유사도 (Jaccard similarity)
|
|
136
|
-
const aWords = new Set(a.title.toLowerCase().split(/\s+/));
|
|
137
|
-
const bWords = new Set(b.title.toLowerCase().split(/\s+/));
|
|
138
|
-
const intersection = new Set([...aWords].filter(x => bWords.has(x)));
|
|
139
|
-
const union = new Set([...aWords, ...bWords]);
|
|
140
|
-
const similarity = intersection.size / union.size;
|
|
141
|
-
if (similarity > 0.5)
|
|
142
|
-
return true;
|
|
143
|
-
// 3. 설명에서 키워드 매칭
|
|
144
|
-
const aDesc = a.description.toLowerCase();
|
|
145
|
-
const bDesc = b.description.toLowerCase();
|
|
146
|
-
// 공통 보안 키워드
|
|
147
|
-
const keywords = ['injection', 'xss', 'csrf', 'auth', 'leak', 'overflow', 'validation', 'null', 'undefined'];
|
|
148
|
-
const aKeywords = keywords.filter(k => aDesc.includes(k));
|
|
149
|
-
const bKeywords = keywords.filter(k => bDesc.includes(k));
|
|
150
|
-
if (aKeywords.length > 0 && bKeywords.length > 0) {
|
|
151
|
-
const commonKeywords = aKeywords.filter(k => bKeywords.includes(k));
|
|
152
|
-
if (commonKeywords.length > 0)
|
|
153
|
-
return true;
|
|
154
|
-
}
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* JSON 파싱 (LLM 응답에서)
|
|
159
|
-
*/
|
|
160
|
-
function parseIssuesFromResponse(response) {
|
|
161
|
-
try {
|
|
162
|
-
// JSON 블록 추출
|
|
163
|
-
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
164
|
-
if (!jsonMatch)
|
|
165
|
-
return [];
|
|
166
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
167
|
-
return parsed.issues || [];
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
// JSON 파싱 실패 시 빈 배열
|
|
171
|
-
return [];
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* 신뢰도에서 우선순위 계산
|
|
176
|
-
*/
|
|
177
|
-
function calculatePriority(confidence, severity) {
|
|
178
|
-
// 3/3 동의 (100%) + critical/high → P1
|
|
179
|
-
// 2/3 동의 (67%) 또는 medium → P2
|
|
180
|
-
// 1/3 동의 (33%) 또는 low → P3
|
|
181
|
-
if (confidence >= 0.9 && (severity === 'critical' || severity === 'high')) {
|
|
182
|
-
return 'P1';
|
|
183
|
-
}
|
|
184
|
-
if (confidence >= 0.6 || severity === 'medium') {
|
|
185
|
-
return 'P2';
|
|
186
|
-
}
|
|
187
|
-
return 'P3';
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* 가장 상세한 제목 선택
|
|
191
|
-
*/
|
|
192
|
-
function selectBestTitle(issues) {
|
|
193
|
-
return issues.reduce((best, issue) => issue.title.length > best.length ? issue.title : best, issues[0]?.title || 'Unknown Issue');
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* 가장 상세한 설명 선택
|
|
197
|
-
*/
|
|
198
|
-
function selectBestDescription(issues) {
|
|
199
|
-
return issues.reduce((best, issue) => issue.description.length > best.length ? issue.description : best, issues[0]?.description || '');
|
|
200
|
-
}
|
|
201
|
-
// ============================================================================
|
|
202
|
-
// Core Functions
|
|
203
|
-
// ============================================================================
|
|
204
|
-
/**
|
|
205
|
-
* GPT로 리뷰 수행
|
|
206
|
-
*/
|
|
207
|
-
async function reviewWithGPT(reviewType, code, context) {
|
|
208
|
-
const startTime = Date.now();
|
|
209
|
-
try {
|
|
210
|
-
const prompt = `${REVIEW_PROMPTS[reviewType]}
|
|
211
|
-
|
|
212
|
-
Context: ${context || 'Code review'}
|
|
213
|
-
|
|
214
|
-
Code to review:
|
|
215
|
-
\`\`\`
|
|
216
|
-
${code}
|
|
217
|
-
\`\`\`
|
|
218
|
-
|
|
219
|
-
Respond with JSON only.`;
|
|
220
|
-
const response = await gptApi.ask(prompt, {
|
|
221
|
-
model: isCodexAvailable() ? 'gpt-5.3-codex-spark' : 'gpt-5.3-codex',
|
|
222
|
-
temperature: 0.3,
|
|
223
|
-
});
|
|
224
|
-
const issues = parseIssuesFromResponse(response);
|
|
225
|
-
return {
|
|
226
|
-
provider: 'gpt',
|
|
227
|
-
issues,
|
|
228
|
-
duration: Date.now() - startTime,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
catch (error) {
|
|
232
|
-
return {
|
|
233
|
-
provider: 'gpt',
|
|
234
|
-
issues: [],
|
|
235
|
-
duration: Date.now() - startTime,
|
|
236
|
-
error: error.message,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Antigravity로 리뷰 수행
|
|
242
|
-
*/
|
|
243
|
-
async function reviewWithAntigravity(reviewType, code, context) {
|
|
244
|
-
const startTime = Date.now();
|
|
245
|
-
try {
|
|
246
|
-
const prompt = `${REVIEW_PROMPTS[reviewType]}
|
|
247
|
-
|
|
248
|
-
Context: ${context || 'Code review'}
|
|
249
|
-
|
|
250
|
-
Code to review:
|
|
251
|
-
\`\`\`
|
|
252
|
-
${code}
|
|
253
|
-
\`\`\`
|
|
254
|
-
|
|
255
|
-
Respond with JSON only.`;
|
|
256
|
-
const response = await antigravityApi.ask(prompt, {
|
|
257
|
-
model: 'antigravity-fast',
|
|
258
|
-
temperature: 0.3,
|
|
259
|
-
});
|
|
260
|
-
const issues = parseIssuesFromResponse(response);
|
|
261
|
-
return {
|
|
262
|
-
provider: 'antigravity',
|
|
263
|
-
issues,
|
|
264
|
-
duration: Date.now() - startTime,
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
catch (error) {
|
|
268
|
-
return {
|
|
269
|
-
provider: 'antigravity',
|
|
270
|
-
issues: [],
|
|
271
|
-
duration: Date.now() - startTime,
|
|
272
|
-
error: error.message,
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* 이슈 교차 검증 (클러스터링)
|
|
278
|
-
*/
|
|
279
|
-
function crossValidateIssues(llmResults) {
|
|
280
|
-
const validResults = llmResults.filter(r => !r.error);
|
|
281
|
-
const totalProviders = validResults.length;
|
|
282
|
-
if (totalProviders === 0)
|
|
283
|
-
return [];
|
|
284
|
-
// 모든 이슈를 플랫하게 펼침
|
|
285
|
-
const allIssues = [];
|
|
286
|
-
for (const result of validResults) {
|
|
287
|
-
for (const issue of result.issues) {
|
|
288
|
-
allIssues.push({ issue, provider: result.provider });
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// 클러스터링 (유사한 이슈 그룹화)
|
|
292
|
-
const clusters = [];
|
|
293
|
-
const used = new Set();
|
|
294
|
-
for (let i = 0; i < allIssues.length; i++) {
|
|
295
|
-
if (used.has(i))
|
|
296
|
-
continue;
|
|
297
|
-
const cluster = [allIssues[i]];
|
|
298
|
-
used.add(i);
|
|
299
|
-
for (let j = i + 1; j < allIssues.length; j++) {
|
|
300
|
-
if (used.has(j))
|
|
301
|
-
continue;
|
|
302
|
-
// 같은 provider의 이슈는 클러스터에 추가하지 않음
|
|
303
|
-
if (allIssues[j].provider === allIssues[i].provider)
|
|
304
|
-
continue;
|
|
305
|
-
if (areIssuesSimilar(allIssues[i].issue, allIssues[j].issue)) {
|
|
306
|
-
cluster.push(allIssues[j]);
|
|
307
|
-
used.add(j);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
clusters.push(cluster);
|
|
311
|
-
}
|
|
312
|
-
// 클러스터를 CrossValidatedIssue로 변환
|
|
313
|
-
const crossValidated = clusters.map(cluster => {
|
|
314
|
-
const issues = cluster.map(c => c.issue);
|
|
315
|
-
const foundBy = [...new Set(cluster.map(c => c.provider))];
|
|
316
|
-
const confidence = foundBy.length / totalProviders;
|
|
317
|
-
// 가장 높은 severity 선택
|
|
318
|
-
const severityOrder = ['critical', 'high', 'medium', 'low'];
|
|
319
|
-
const highestSeverity = issues.reduce((highest, issue) => {
|
|
320
|
-
const currentIndex = severityOrder.indexOf(issue.severity);
|
|
321
|
-
const highestIndex = severityOrder.indexOf(highest);
|
|
322
|
-
return currentIndex < highestIndex ? issue.severity : highest;
|
|
323
|
-
}, 'low');
|
|
324
|
-
const priority = calculatePriority(confidence, highestSeverity);
|
|
325
|
-
return {
|
|
326
|
-
issue: {
|
|
327
|
-
id: issues[0].id,
|
|
328
|
-
title: selectBestTitle(issues),
|
|
329
|
-
description: selectBestDescription(issues),
|
|
330
|
-
location: issues.find(i => i.location)?.location,
|
|
331
|
-
severity: highestSeverity,
|
|
332
|
-
suggestion: issues.find(i => i.suggestion)?.suggestion,
|
|
333
|
-
},
|
|
334
|
-
foundBy,
|
|
335
|
-
confidence,
|
|
336
|
-
priority,
|
|
337
|
-
consensusTitle: selectBestTitle(issues),
|
|
338
|
-
};
|
|
339
|
-
});
|
|
340
|
-
// 우선순위 순으로 정렬 (P1 > P2 > P3, 같은 우선순위 내에서는 confidence 높은 순)
|
|
341
|
-
return crossValidated.sort((a, b) => {
|
|
342
|
-
const priorityOrder = { P1: 0, P2: 1, P3: 2 };
|
|
343
|
-
if (priorityOrder[a.priority] !== priorityOrder[b.priority]) {
|
|
344
|
-
return priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
345
|
-
}
|
|
346
|
-
return b.confidence - a.confidence;
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
// ============================================================================
|
|
350
|
-
// Main Export
|
|
351
|
-
// ============================================================================
|
|
352
|
-
/**
|
|
353
|
-
* Multi-LLM Race Review 수행
|
|
354
|
-
*
|
|
355
|
-
* GPT + Antigravity를 병렬로 실행하고 결과를 교차 검증합니다.
|
|
356
|
-
* Claude는 현재 세션에서 실행 중이므로 별도의 서브에이전트로 호출됩니다.
|
|
357
|
-
*/
|
|
358
|
-
export async function raceReview(options) {
|
|
359
|
-
const { reviewType, code, context } = options;
|
|
360
|
-
const startTime = Date.now();
|
|
361
|
-
// GPT + Antigravity 병렬 실행 (가용성 체크)
|
|
362
|
-
const reviewPromises = [];
|
|
363
|
-
if (isCodexAvailable()) {
|
|
364
|
-
reviewPromises.push(reviewWithGPT(reviewType, code, context));
|
|
365
|
-
}
|
|
366
|
-
if (isAntigravityAvailable()) {
|
|
367
|
-
reviewPromises.push(reviewWithAntigravity(reviewType, code, context));
|
|
368
|
-
}
|
|
369
|
-
const llmResults = await Promise.all(reviewPromises);
|
|
370
|
-
// 교차 검증
|
|
371
|
-
const crossValidated = crossValidateIssues(llmResults);
|
|
372
|
-
// 요약 생성
|
|
373
|
-
const p1Count = crossValidated.filter(i => i.priority === 'P1').length;
|
|
374
|
-
const p2Count = crossValidated.filter(i => i.priority === 'P2').length;
|
|
375
|
-
const p3Count = crossValidated.filter(i => i.priority === 'P3').length;
|
|
376
|
-
return {
|
|
377
|
-
reviewType,
|
|
378
|
-
llmResults,
|
|
379
|
-
crossValidated,
|
|
380
|
-
summary: {
|
|
381
|
-
totalIssues: crossValidated.length,
|
|
382
|
-
p1Count,
|
|
383
|
-
p2Count,
|
|
384
|
-
p3Count,
|
|
385
|
-
consensusRate: crossValidated.length > 0
|
|
386
|
-
? (p1Count + p2Count) / crossValidated.length
|
|
387
|
-
: 1,
|
|
388
|
-
},
|
|
389
|
-
duration: Date.now() - startTime,
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Race Review 결과를 마크다운으로 포맷
|
|
394
|
-
*/
|
|
395
|
-
export function formatRaceResult(result) {
|
|
396
|
-
const lines = [];
|
|
397
|
-
lines.push(`## ${result.reviewType.toUpperCase()} Review (Race Mode)`);
|
|
398
|
-
lines.push('');
|
|
399
|
-
lines.push(`**Duration**: ${result.duration}ms`);
|
|
400
|
-
lines.push(`**Models**: GPT-5.3-Codex, Antigravity`);
|
|
401
|
-
lines.push('');
|
|
402
|
-
// LLM별 결과 요약
|
|
403
|
-
lines.push('### Model Results');
|
|
404
|
-
lines.push('');
|
|
405
|
-
lines.push('| Model | Issues Found | Duration | Status |');
|
|
406
|
-
lines.push('|-------|--------------|----------|--------|');
|
|
407
|
-
for (const llm of result.llmResults) {
|
|
408
|
-
const status = llm.error ? `Error: ${llm.error}` : 'OK';
|
|
409
|
-
lines.push(`| ${llm.provider} | ${llm.issues.length} | ${llm.duration}ms | ${status} |`);
|
|
410
|
-
}
|
|
411
|
-
lines.push('');
|
|
412
|
-
// 교차 검증 결과
|
|
413
|
-
lines.push('### Cross-Validated Issues');
|
|
414
|
-
lines.push('');
|
|
415
|
-
lines.push(`**Summary**: ${result.summary.totalIssues} issues (P1: ${result.summary.p1Count}, P2: ${result.summary.p2Count}, P3: ${result.summary.p3Count})`);
|
|
416
|
-
lines.push(`**Consensus Rate**: ${(result.summary.consensusRate * 100).toFixed(0)}%`);
|
|
417
|
-
lines.push('');
|
|
418
|
-
if (result.crossValidated.length === 0) {
|
|
419
|
-
lines.push('No issues found.');
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
for (const item of result.crossValidated) {
|
|
423
|
-
const priorityEmoji = item.priority === 'P1' ? '🔴' : item.priority === 'P2' ? '🟡' : '🔵';
|
|
424
|
-
const confidencePct = (item.confidence * 100).toFixed(0);
|
|
425
|
-
lines.push(`#### ${priorityEmoji} ${item.priority} - ${item.consensusTitle}`);
|
|
426
|
-
lines.push('');
|
|
427
|
-
lines.push(`- **Confidence**: ${confidencePct}% (${item.foundBy.join(', ')})`);
|
|
428
|
-
lines.push(`- **Severity**: ${item.issue.severity}`);
|
|
429
|
-
if (item.issue.location) {
|
|
430
|
-
lines.push(`- **Location**: \`${item.issue.location}\``);
|
|
431
|
-
}
|
|
432
|
-
lines.push(`- **Description**: ${item.issue.description}`);
|
|
433
|
-
if (item.issue.suggestion) {
|
|
434
|
-
lines.push(`- **Suggestion**: ${item.issue.suggestion}`);
|
|
435
|
-
}
|
|
436
|
-
lines.push('');
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
return lines.join('\n');
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* LLM 가용성 확인
|
|
443
|
-
*/
|
|
444
|
-
export async function checkLLMAvailability() {
|
|
445
|
-
const results = await Promise.allSettled([
|
|
446
|
-
gptApi.ask('ping', { maxTokens: 10 }),
|
|
447
|
-
antigravityApi.ask('ping', { maxTokens: 10 }),
|
|
448
|
-
]);
|
|
449
|
-
return {
|
|
450
|
-
gpt: results[0].status === 'fulfilled',
|
|
451
|
-
antigravity: results[1].status === 'fulfilled',
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
//# sourceMappingURL=ReviewRace.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewRace.js","sourceRoot":"","sources":["../../../src/infra/lib/ReviewRace.ts"],"names":[],"mappings":"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"}
|