@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.
Files changed (49) hide show
  1. package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
  2. package/dist/cli/setup/ProjectSetup.js +13 -1
  3. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  4. package/dist/tools/dispatch/deterministicSignals.d.ts.map +1 -1
  5. package/dist/tools/dispatch/deterministicSignals.js +15 -10
  6. package/dist/tools/dispatch/deterministicSignals.js.map +1 -1
  7. package/dist/tools/dispatch/vibePaths.d.ts +7 -0
  8. package/dist/tools/dispatch/vibePaths.d.ts.map +1 -0
  9. package/dist/tools/dispatch/vibePaths.js +35 -0
  10. package/dist/tools/dispatch/vibePaths.js.map +1 -0
  11. package/dist/tools/spec/validateSpecDocument.d.ts.map +1 -1
  12. package/dist/tools/spec/validateSpecDocument.js +33 -6
  13. package/dist/tools/spec/validateSpecDocument.js.map +1 -1
  14. package/hooks/scripts/code-check.js +90 -16
  15. package/hooks/scripts/lib/anchor.js +15 -4
  16. package/hooks/scripts/lib/inbox.js +10 -2
  17. package/package.json +1 -1
  18. package/dist/infra/lib/DeepInit.d.ts +0 -60
  19. package/dist/infra/lib/DeepInit.d.ts.map +0 -1
  20. package/dist/infra/lib/DeepInit.js +0 -245
  21. package/dist/infra/lib/DeepInit.js.map +0 -1
  22. package/dist/infra/lib/FrameworkDetector.d.ts +0 -56
  23. package/dist/infra/lib/FrameworkDetector.d.ts.map +0 -1
  24. package/dist/infra/lib/FrameworkDetector.js +0 -287
  25. package/dist/infra/lib/FrameworkDetector.js.map +0 -1
  26. package/dist/infra/lib/ModelRouter.d.ts +0 -48
  27. package/dist/infra/lib/ModelRouter.d.ts.map +0 -1
  28. package/dist/infra/lib/ModelRouter.js +0 -216
  29. package/dist/infra/lib/ModelRouter.js.map +0 -1
  30. package/dist/infra/lib/ReviewRace.d.ts +0 -86
  31. package/dist/infra/lib/ReviewRace.d.ts.map +0 -1
  32. package/dist/infra/lib/ReviewRace.js +0 -454
  33. package/dist/infra/lib/ReviewRace.js.map +0 -1
  34. package/dist/infra/lib/RuleBuildSystem.d.ts +0 -157
  35. package/dist/infra/lib/RuleBuildSystem.d.ts.map +0 -1
  36. package/dist/infra/lib/RuleBuildSystem.js +0 -550
  37. package/dist/infra/lib/RuleBuildSystem.js.map +0 -1
  38. package/dist/infra/lib/SkillQualityGate.d.ts +0 -42
  39. package/dist/infra/lib/SkillQualityGate.d.ts.map +0 -1
  40. package/dist/infra/lib/SkillQualityGate.js +0 -220
  41. package/dist/infra/lib/SkillQualityGate.js.map +0 -1
  42. package/dist/infra/lib/SkillRepository.d.ts +0 -134
  43. package/dist/infra/lib/SkillRepository.d.ts.map +0 -1
  44. package/dist/infra/lib/SkillRepository.js +0 -500
  45. package/dist/infra/lib/SkillRepository.js.map +0 -1
  46. package/dist/infra/lib/UltraQA.d.ts +0 -89
  47. package/dist/infra/lib/UltraQA.d.ts.map +0 -1
  48. package/dist/infra/lib/UltraQA.js +0 -301
  49. 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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"}