@defai.digital/review-domain 13.0.3
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/LICENSE +214 -0
- package/dist/comment-builder.d.ts +34 -0
- package/dist/comment-builder.d.ts.map +1 -0
- package/dist/comment-builder.js +171 -0
- package/dist/comment-builder.js.map +1 -0
- package/dist/focus-modes.d.ts +39 -0
- package/dist/focus-modes.d.ts.map +1 -0
- package/dist/focus-modes.js +241 -0
- package/dist/focus-modes.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown-formatter.d.ts +16 -0
- package/dist/markdown-formatter.d.ts.map +1 -0
- package/dist/markdown-formatter.js +183 -0
- package/dist/markdown-formatter.js.map +1 -0
- package/dist/review-service.d.ts +68 -0
- package/dist/review-service.d.ts.map +1 -0
- package/dist/review-service.js +281 -0
- package/dist/review-service.js.map +1 -0
- package/dist/sarif-formatter.d.ts +21 -0
- package/dist/sarif-formatter.d.ts.map +1 -0
- package/dist/sarif-formatter.js +139 -0
- package/dist/sarif-formatter.js.map +1 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review Service
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the AI code review process.
|
|
5
|
+
* Implements:
|
|
6
|
+
* - INV-REV-OPS-001: Timeout Handling
|
|
7
|
+
* - INV-REV-OPS-002: Provider Fallback
|
|
8
|
+
*/
|
|
9
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { createReviewSummary, sortCommentsBySeverity, ReviewErrorCode, TIMEOUT_PROVIDER_DEFAULT, } from '@defai.digital/contracts';
|
|
13
|
+
import { buildReviewPrompt } from './focus-modes.js';
|
|
14
|
+
import { parseReviewResponse, filterCommentsByConfidence } from './comment-builder.js';
|
|
15
|
+
import { formatReviewAsMarkdown, formatCompactSummary } from './markdown-formatter.js';
|
|
16
|
+
import { formatReviewAsSarif, formatSarifAsJson } from './sarif-formatter.js';
|
|
17
|
+
/**
|
|
18
|
+
* Default configuration
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_CONFIG = {
|
|
21
|
+
defaultProvider: 'claude',
|
|
22
|
+
defaultTimeoutMs: TIMEOUT_PROVIDER_DEFAULT,
|
|
23
|
+
providerFallbackOrder: ['claude', 'gemini', 'codex'],
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Review service for orchestrating AI code review
|
|
27
|
+
*/
|
|
28
|
+
export class ReviewService {
|
|
29
|
+
config;
|
|
30
|
+
promptExecutor;
|
|
31
|
+
constructor(config, promptExecutor) {
|
|
32
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
33
|
+
this.promptExecutor = promptExecutor;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Execute a code review
|
|
37
|
+
* INV-REV-OPS-001: Reviews MUST complete or fail within configured timeout
|
|
38
|
+
*/
|
|
39
|
+
async review(request, options) {
|
|
40
|
+
const startTime = Date.now();
|
|
41
|
+
const resultId = uuidv4();
|
|
42
|
+
const timeoutMs = request.timeoutMs ?? this.config.defaultTimeoutMs;
|
|
43
|
+
// Handle dry run
|
|
44
|
+
if (request.dryRun || options?.dryRun) {
|
|
45
|
+
const dryRun = await this.dryRun(request);
|
|
46
|
+
return this.createEmptyResult(request, resultId, dryRun, startTime);
|
|
47
|
+
}
|
|
48
|
+
// Collect files to review
|
|
49
|
+
const files = await this.collectFiles(request.paths, request.maxFiles, request.maxLinesPerFile);
|
|
50
|
+
if (files.length === 0) {
|
|
51
|
+
throw new ReviewError(ReviewErrorCode.NO_FILES_FOUND, 'No files found to review');
|
|
52
|
+
}
|
|
53
|
+
// Build prompt
|
|
54
|
+
const prompt = buildReviewPrompt(request.focus, files, request.context);
|
|
55
|
+
// Execute with timeout
|
|
56
|
+
const providerId = options?.providerId ?? request.providerId ?? this.config.defaultProvider;
|
|
57
|
+
let response;
|
|
58
|
+
try {
|
|
59
|
+
response = await this.executeWithTimeout(prompt, providerId, timeoutMs);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof Error && error.message.includes('timeout')) {
|
|
63
|
+
throw new ReviewError(ReviewErrorCode.TIMEOUT, `Review timed out after ${timeoutMs}ms`);
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
// Parse response
|
|
68
|
+
const parsed = parseReviewResponse(response.content, request.focus, request.minConfidence);
|
|
69
|
+
// Filter by confidence (INV-REV-002)
|
|
70
|
+
const filteredComments = filterCommentsByConfidence(parsed.comments, request.minConfidence);
|
|
71
|
+
// Sort by severity (INV-REV-OUT-001)
|
|
72
|
+
const sortedComments = sortCommentsBySeverity(filteredComments);
|
|
73
|
+
// Build summary
|
|
74
|
+
const summary = createReviewSummary(sortedComments);
|
|
75
|
+
const result = {
|
|
76
|
+
resultId,
|
|
77
|
+
requestId: request.requestId,
|
|
78
|
+
comments: sortedComments,
|
|
79
|
+
summary,
|
|
80
|
+
filesReviewed: files.map((f) => f.path),
|
|
81
|
+
linesAnalyzed: files.reduce((sum, f) => sum + f.lineCount, 0),
|
|
82
|
+
providerId: response.providerId,
|
|
83
|
+
modelId: response.modelId,
|
|
84
|
+
durationMs: Date.now() - startTime,
|
|
85
|
+
completedAt: new Date().toISOString(),
|
|
86
|
+
};
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute dry run - show what would be analyzed
|
|
91
|
+
*/
|
|
92
|
+
async dryRun(request) {
|
|
93
|
+
const files = await this.collectFiles(request.paths, request.maxFiles, request.maxLinesPerFile);
|
|
94
|
+
return {
|
|
95
|
+
files: files.map((f) => f.path),
|
|
96
|
+
totalLines: files.reduce((sum, f) => sum + f.lineCount, 0),
|
|
97
|
+
focus: request.focus,
|
|
98
|
+
estimatedDurationMs: files.length * 5000, // Rough estimate: 5s per file
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Format result based on output format
|
|
103
|
+
*/
|
|
104
|
+
formatResult(result, format) {
|
|
105
|
+
switch (format) {
|
|
106
|
+
case 'markdown':
|
|
107
|
+
return formatReviewAsMarkdown(result);
|
|
108
|
+
case 'sarif':
|
|
109
|
+
return formatSarifAsJson(formatReviewAsSarif(result));
|
|
110
|
+
case 'json':
|
|
111
|
+
return JSON.stringify(result, null, 2);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get compact summary for CLI
|
|
116
|
+
*/
|
|
117
|
+
getCompactSummary(result) {
|
|
118
|
+
return formatCompactSummary(result);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Collect files from paths
|
|
122
|
+
*/
|
|
123
|
+
async collectFiles(paths, maxFiles, maxLinesPerFile) {
|
|
124
|
+
const files = [];
|
|
125
|
+
const seen = new Set();
|
|
126
|
+
for (const p of paths) {
|
|
127
|
+
if (files.length >= maxFiles)
|
|
128
|
+
break;
|
|
129
|
+
const resolved = path.resolve(p);
|
|
130
|
+
try {
|
|
131
|
+
const stat = fs.statSync(resolved);
|
|
132
|
+
if (stat.isDirectory()) {
|
|
133
|
+
// Recursively collect files from directory
|
|
134
|
+
await this.collectFromDirectory(resolved, files, seen, maxFiles, maxLinesPerFile);
|
|
135
|
+
}
|
|
136
|
+
else if (stat.isFile()) {
|
|
137
|
+
if (!seen.has(resolved)) {
|
|
138
|
+
const file = this.readFile(resolved, maxLinesPerFile);
|
|
139
|
+
if (file) {
|
|
140
|
+
files.push(file);
|
|
141
|
+
seen.add(resolved);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Skip inaccessible files/directories
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return files;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Recursively collect files from directory
|
|
155
|
+
*/
|
|
156
|
+
async collectFromDirectory(dir, files, seen, maxFiles, maxLinesPerFile) {
|
|
157
|
+
const CODE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs', '.java', '.kt', '.swift', '.rb', '.php', '.cs', '.cpp', '.c', '.h'];
|
|
158
|
+
const IGNORE_DIRS = ['node_modules', 'dist', 'build', '.git', '__pycache__', 'vendor', 'target'];
|
|
159
|
+
try {
|
|
160
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
161
|
+
for (const entry of entries) {
|
|
162
|
+
if (files.length >= maxFiles)
|
|
163
|
+
return;
|
|
164
|
+
const fullPath = path.join(dir, entry.name);
|
|
165
|
+
if (entry.isDirectory()) {
|
|
166
|
+
if (!IGNORE_DIRS.includes(entry.name)) {
|
|
167
|
+
await this.collectFromDirectory(fullPath, files, seen, maxFiles, maxLinesPerFile);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else if (entry.isFile()) {
|
|
171
|
+
const ext = path.extname(entry.name);
|
|
172
|
+
if (CODE_EXTENSIONS.includes(ext) && !seen.has(fullPath)) {
|
|
173
|
+
const file = this.readFile(fullPath, maxLinesPerFile);
|
|
174
|
+
if (file) {
|
|
175
|
+
files.push(file);
|
|
176
|
+
seen.add(fullPath);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Skip inaccessible directories
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Read a single file
|
|
188
|
+
*/
|
|
189
|
+
readFile(filePath, maxLines) {
|
|
190
|
+
try {
|
|
191
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
192
|
+
const lines = content.split('\n');
|
|
193
|
+
const lineCount = lines.length;
|
|
194
|
+
// Truncate if too many lines
|
|
195
|
+
const truncatedContent = lineCount > maxLines ? lines.slice(0, maxLines).join('\n') + '\n// ... truncated' : content;
|
|
196
|
+
return {
|
|
197
|
+
path: filePath,
|
|
198
|
+
content: truncatedContent,
|
|
199
|
+
lineCount: Math.min(lineCount, maxLines),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Execute prompt with timeout
|
|
208
|
+
* INV-REV-OPS-001: Timeout Handling
|
|
209
|
+
*/
|
|
210
|
+
async executeWithTimeout(prompt, providerId, timeoutMs) {
|
|
211
|
+
if (!this.promptExecutor) {
|
|
212
|
+
throw new ReviewError(ReviewErrorCode.PROVIDER_UNAVAILABLE, 'No prompt executor configured');
|
|
213
|
+
}
|
|
214
|
+
// Create cancellable timeout to prevent timer leaks
|
|
215
|
+
let timeoutId;
|
|
216
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
217
|
+
timeoutId = setTimeout(() => {
|
|
218
|
+
reject(new Error(`Review timeout after ${timeoutMs}ms`));
|
|
219
|
+
}, timeoutMs);
|
|
220
|
+
});
|
|
221
|
+
try {
|
|
222
|
+
const result = await Promise.race([
|
|
223
|
+
this.promptExecutor.execute(prompt, { providerId, timeoutMs }),
|
|
224
|
+
timeoutPromise,
|
|
225
|
+
]);
|
|
226
|
+
// Clean up timeout
|
|
227
|
+
if (timeoutId !== undefined) {
|
|
228
|
+
clearTimeout(timeoutId);
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
// Clean up timeout on error too
|
|
234
|
+
if (timeoutId !== undefined) {
|
|
235
|
+
clearTimeout(timeoutId);
|
|
236
|
+
}
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Create empty result for dry run
|
|
242
|
+
*/
|
|
243
|
+
createEmptyResult(request, resultId, dryRun, startTime) {
|
|
244
|
+
return {
|
|
245
|
+
resultId,
|
|
246
|
+
requestId: request.requestId,
|
|
247
|
+
comments: [],
|
|
248
|
+
summary: {
|
|
249
|
+
bySeverity: { critical: 0, warning: 0, suggestion: 0, note: 0 },
|
|
250
|
+
byFocus: {},
|
|
251
|
+
hotspots: [],
|
|
252
|
+
healthScore: 100,
|
|
253
|
+
verdict: `Dry run: Would analyze ${dryRun.files.length} files, ${dryRun.totalLines} lines`,
|
|
254
|
+
},
|
|
255
|
+
filesReviewed: dryRun.files,
|
|
256
|
+
linesAnalyzed: dryRun.totalLines,
|
|
257
|
+
providerId: 'dry-run',
|
|
258
|
+
modelId: 'dry-run',
|
|
259
|
+
durationMs: Date.now() - startTime,
|
|
260
|
+
completedAt: new Date().toISOString(),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Review error with error code
|
|
266
|
+
*/
|
|
267
|
+
export class ReviewError extends Error {
|
|
268
|
+
code;
|
|
269
|
+
constructor(code, message) {
|
|
270
|
+
super(message);
|
|
271
|
+
this.code = code;
|
|
272
|
+
this.name = 'ReviewError';
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Create a review service instance
|
|
277
|
+
*/
|
|
278
|
+
export function createReviewService(config, promptExecutor) {
|
|
279
|
+
return new ReviewService(config, promptExecutor);
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=review-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-service.js","sourceRoot":"","sources":["../src/review-service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAGL,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAS9E;;GAEG;AACH,MAAM,cAAc,GAAkC;IACpD,eAAe,EAAE,QAAQ;IACzB,gBAAgB,EAAE,wBAAwB;IAC1C,qBAAqB,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,aAAa;IACP,MAAM,CAAgC;IACtC,cAAc,CAAmC;IAElE,YAAY,MAA4B,EAAE,cAAqC;QAC7E,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CACV,OAAsB,EACtB,OAAgC;QAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;QAEpE,iBAAiB;QACjB,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC;QAED,0BAA0B;QAC1B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QAEhG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;QACpF,CAAC;QAED,eAAe;QACf,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAExE,uBAAuB;QACvB,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QAC5F,IAAI,QAAkE,CAAC;QAEvE,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,WAAW,CAAC,eAAe,CAAC,OAAO,EAAE,0BAA0B,SAAS,IAAI,CAAC,CAAC;YAC1F,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,iBAAiB;QACjB,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAE3F,qCAAqC;QACrC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAE5F,qCAAqC;QACrC,MAAM,cAAc,GAAG,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;QAEhE,gBAAgB;QAChB,MAAM,OAAO,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAiB;YAC3B,QAAQ;YACR,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,cAAc;YACxB,OAAO;YACP,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACvC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YAC7D,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,OAAsB;QACjC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QAEhG,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YAC1D,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,mBAAmB,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,8BAA8B;SACzE,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,MAAoB,EAAE,MAAqC;QACtE,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,UAAU;gBACb,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;YACxC,KAAK,OAAO;gBACV,OAAO,iBAAiB,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,MAAoB;QACpC,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CACxB,KAAe,EACf,QAAgB,EAChB,eAAuB;QAEvB,MAAM,KAAK,GAAkB,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;gBAAE,MAAM;YAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAEjC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAEnC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvB,2CAA2C;oBAC3C,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;gBACpF,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACxB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;wBACtD,IAAI,IAAI,EAAE,CAAC;4BACT,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACjB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACrB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,sCAAsC;gBACtC,SAAS;YACX,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAChC,GAAW,EACX,KAAoB,EACpB,IAAiB,EACjB,QAAgB,EAChB,eAAuB;QAEvB,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAChJ,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEjG,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAE7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;oBAAE,OAAO;gBAErC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAE5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBACtC,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;oBACpF,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACrC,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACzD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;wBACtD,IAAI,IAAI,EAAE,CAAC;4BACT,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACjB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACrB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,QAAgB,EAAE,QAAgB;QACjD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;YAE/B,6BAA6B;YAC7B,MAAM,gBAAgB,GACpB,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC;YAE9F,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,gBAAgB;gBACzB,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC;aACzC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,kBAAkB,CAC9B,MAAc,EACd,UAAkB,EAClB,SAAiB;QAEjB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,WAAW,CACnB,eAAe,CAAC,oBAAoB,EACpC,+BAA+B,CAChC,CAAC;QACJ,CAAC;QAED,oDAAoD;QACpD,IAAI,SAAoD,CAAC;QACzD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YACtD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,SAAS,IAAI,CAAC,CAAC,CAAC;YAC3D,CAAC,EAAE,SAAS,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAChC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;gBAC9D,cAAc;aACf,CAAC,CAAC;YAEH,mBAAmB;YACnB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gCAAgC;YAChC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,YAAY,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CACvB,OAAsB,EACtB,QAAgB,EAChB,MAAoB,EACpB,SAAiB;QAEjB,OAAO;YACL,QAAQ;YACR,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE;gBACP,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;gBAC/D,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,EAAE;gBACZ,WAAW,EAAE,GAAG;gBAChB,OAAO,EAAE,0BAA0B,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,MAAM,CAAC,UAAU,QAAQ;aAC3F;YACD,aAAa,EAAE,MAAM,CAAC,KAAK;YAC3B,aAAa,EAAE,MAAM,CAAC,UAAU;YAChC,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,SAAS;YAClB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA4B,EAC5B,cAAqC;IAErC,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats review results as SARIF 2.1.0 output.
|
|
5
|
+
* INV-REV-OUT-003: SARIF output MUST comply with SARIF 2.1.0 schema.
|
|
6
|
+
*/
|
|
7
|
+
import { type ReviewResult, type SarifOutput } from '@defai.digital/contracts';
|
|
8
|
+
/**
|
|
9
|
+
* Format review result as SARIF
|
|
10
|
+
* INV-REV-OUT-003: SARIF Compliance
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatReviewAsSarif(result: ReviewResult): SarifOutput;
|
|
13
|
+
/**
|
|
14
|
+
* Convert SARIF output to JSON string
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatSarifAsJson(sarif: SarifOutput): string;
|
|
17
|
+
/**
|
|
18
|
+
* Create an empty SARIF report (no issues found)
|
|
19
|
+
*/
|
|
20
|
+
export declare function createEmptySarifReport(): SarifOutput;
|
|
21
|
+
//# sourceMappingURL=sarif-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif-formatter.d.ts","sourceRoot":"","sources":["../src/sarif-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,WAAW,EAIjB,MAAM,0BAA0B,CAAC;AAqClC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,CA4ErE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,WAAW,CAiBpD"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats review results as SARIF 2.1.0 output.
|
|
5
|
+
* INV-REV-OUT-003: SARIF output MUST comply with SARIF 2.1.0 schema.
|
|
6
|
+
*/
|
|
7
|
+
import { sortCommentsBySeverity, } from '@defai.digital/contracts';
|
|
8
|
+
/**
|
|
9
|
+
* SARIF schema URL
|
|
10
|
+
*/
|
|
11
|
+
const SARIF_SCHEMA = 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json';
|
|
12
|
+
/**
|
|
13
|
+
* SARIF version
|
|
14
|
+
*/
|
|
15
|
+
const SARIF_VERSION = '2.1.0';
|
|
16
|
+
/**
|
|
17
|
+
* Map review severity to SARIF level
|
|
18
|
+
*/
|
|
19
|
+
function mapSeverityToLevel(severity) {
|
|
20
|
+
switch (severity) {
|
|
21
|
+
case 'critical':
|
|
22
|
+
return 'error';
|
|
23
|
+
case 'warning':
|
|
24
|
+
return 'warning';
|
|
25
|
+
case 'suggestion':
|
|
26
|
+
case 'note':
|
|
27
|
+
return 'note';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate rule ID from category
|
|
32
|
+
*/
|
|
33
|
+
function categoryToRuleId(category) {
|
|
34
|
+
return category.replace(/\//g, '-');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Format review result as SARIF
|
|
38
|
+
* INV-REV-OUT-003: SARIF Compliance
|
|
39
|
+
*/
|
|
40
|
+
export function formatReviewAsSarif(result) {
|
|
41
|
+
// Sort comments by severity (INV-REV-OUT-001)
|
|
42
|
+
const sortedComments = sortCommentsBySeverity(result.comments);
|
|
43
|
+
// Collect unique rules
|
|
44
|
+
const rulesMap = new Map();
|
|
45
|
+
for (const comment of sortedComments) {
|
|
46
|
+
const ruleId = categoryToRuleId(comment.category);
|
|
47
|
+
if (!rulesMap.has(ruleId)) {
|
|
48
|
+
rulesMap.set(ruleId, {
|
|
49
|
+
id: ruleId,
|
|
50
|
+
name: comment.category,
|
|
51
|
+
shortDescription: {
|
|
52
|
+
text: `${comment.category} issue`,
|
|
53
|
+
},
|
|
54
|
+
defaultConfiguration: {
|
|
55
|
+
level: mapSeverityToLevel(comment.severity),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Build results
|
|
61
|
+
const sarifResults = sortedComments.map((comment) => {
|
|
62
|
+
const sarifResult = {
|
|
63
|
+
ruleId: categoryToRuleId(comment.category),
|
|
64
|
+
level: mapSeverityToLevel(comment.severity),
|
|
65
|
+
message: {
|
|
66
|
+
text: `${comment.title}\n\n${comment.body}${comment.rationale ? `\n\nWhy: ${comment.rationale}` : ''}`,
|
|
67
|
+
},
|
|
68
|
+
locations: [
|
|
69
|
+
{
|
|
70
|
+
physicalLocation: {
|
|
71
|
+
artifactLocation: {
|
|
72
|
+
uri: comment.file,
|
|
73
|
+
},
|
|
74
|
+
region: {
|
|
75
|
+
startLine: comment.line,
|
|
76
|
+
endLine: comment.lineEnd,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
// Add fix suggestion if present
|
|
83
|
+
if (comment.suggestion) {
|
|
84
|
+
sarifResult.fixes = [
|
|
85
|
+
{
|
|
86
|
+
description: {
|
|
87
|
+
text: comment.suggestion,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
return sarifResult;
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
$schema: SARIF_SCHEMA,
|
|
96
|
+
version: SARIF_VERSION,
|
|
97
|
+
runs: [
|
|
98
|
+
{
|
|
99
|
+
tool: {
|
|
100
|
+
driver: {
|
|
101
|
+
name: 'ax-review',
|
|
102
|
+
version: '1.0.0',
|
|
103
|
+
informationUri: 'https://github.com/automatosx/ax',
|
|
104
|
+
rules: Array.from(rulesMap.values()),
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
results: sarifResults,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Convert SARIF output to JSON string
|
|
114
|
+
*/
|
|
115
|
+
export function formatSarifAsJson(sarif) {
|
|
116
|
+
return JSON.stringify(sarif, null, 2);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create an empty SARIF report (no issues found)
|
|
120
|
+
*/
|
|
121
|
+
export function createEmptySarifReport() {
|
|
122
|
+
return {
|
|
123
|
+
$schema: SARIF_SCHEMA,
|
|
124
|
+
version: SARIF_VERSION,
|
|
125
|
+
runs: [
|
|
126
|
+
{
|
|
127
|
+
tool: {
|
|
128
|
+
driver: {
|
|
129
|
+
name: 'ax-review',
|
|
130
|
+
version: '1.0.0',
|
|
131
|
+
informationUri: 'https://github.com/automatosx/ax',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
results: [],
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=sarif-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif-formatter.js","sourceRoot":"","sources":["../src/sarif-formatter.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review Domain Internal Types
|
|
3
|
+
*
|
|
4
|
+
* Types used internally by the review domain.
|
|
5
|
+
*/
|
|
6
|
+
import type { ReviewRequest, ReviewResult, ReviewComment, ReviewFocus, ReviewSummary, SarifOutput } from '@defai.digital/contracts';
|
|
7
|
+
export type { ReviewRequest, ReviewResult, ReviewComment, ReviewFocus, ReviewSummary, SarifOutput, };
|
|
8
|
+
/**
|
|
9
|
+
* File content for review
|
|
10
|
+
*/
|
|
11
|
+
export interface FileContent {
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
lineCount: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Review context provided to the LLM
|
|
18
|
+
*/
|
|
19
|
+
export interface ReviewContext {
|
|
20
|
+
/** Focus mode for this review */
|
|
21
|
+
focus: ReviewFocus;
|
|
22
|
+
/** Additional user-provided context */
|
|
23
|
+
userContext?: string;
|
|
24
|
+
/** Files to review */
|
|
25
|
+
files: FileContent[];
|
|
26
|
+
/** Minimum confidence threshold */
|
|
27
|
+
minConfidence: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parsed LLM response containing review comments
|
|
31
|
+
*/
|
|
32
|
+
export interface ParsedReviewResponse {
|
|
33
|
+
/** Extracted comments */
|
|
34
|
+
comments: ReviewComment[];
|
|
35
|
+
/** Whether parsing was successful */
|
|
36
|
+
success: boolean;
|
|
37
|
+
/** Any parsing errors */
|
|
38
|
+
errors?: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Review service configuration
|
|
42
|
+
*/
|
|
43
|
+
export interface ReviewServiceConfig {
|
|
44
|
+
/** Default provider to use */
|
|
45
|
+
defaultProvider?: string;
|
|
46
|
+
/** Default timeout in milliseconds */
|
|
47
|
+
defaultTimeoutMs?: number;
|
|
48
|
+
/** Provider fallback order */
|
|
49
|
+
providerFallbackOrder?: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Provider interface for executing review prompts
|
|
53
|
+
*/
|
|
54
|
+
export interface ReviewPromptExecutor {
|
|
55
|
+
/**
|
|
56
|
+
* Execute a review prompt and return the response
|
|
57
|
+
*/
|
|
58
|
+
execute(prompt: string, options?: {
|
|
59
|
+
providerId?: string;
|
|
60
|
+
timeoutMs?: number;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
content: string;
|
|
63
|
+
providerId: string;
|
|
64
|
+
modelId: string;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Review execution options
|
|
69
|
+
*/
|
|
70
|
+
export interface ReviewExecutionOptions {
|
|
71
|
+
/** Provider to use */
|
|
72
|
+
providerId?: string;
|
|
73
|
+
/** Timeout in milliseconds */
|
|
74
|
+
timeoutMs?: number;
|
|
75
|
+
/** Dry run - only analyze what would be reviewed */
|
|
76
|
+
dryRun?: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Dry run result
|
|
80
|
+
*/
|
|
81
|
+
export interface DryRunResult {
|
|
82
|
+
/** Files that would be reviewed */
|
|
83
|
+
files: string[];
|
|
84
|
+
/** Total lines that would be analyzed */
|
|
85
|
+
totalLines: number;
|
|
86
|
+
/** Focus mode */
|
|
87
|
+
focus: ReviewFocus;
|
|
88
|
+
/** Estimated duration (rough) */
|
|
89
|
+
estimatedDurationMs: number;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,aAAa,EACb,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,aAAa,EACb,WAAW,GACZ,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,KAAK,EAAE,WAAW,CAAC;IACnB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,mCAAmC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yBAAyB;IACzB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8BAA8B;IAC9B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,sBAAsB;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,iCAAiC;IACjC,mBAAmB,EAAE,MAAM,CAAC;CAC7B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@defai.digital/review-domain",
|
|
3
|
+
"version": "13.0.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Review domain for AutomatosX - AI-powered code review with focused analysis modes",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"author": "DEFAI Private Limited",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/defai-digital/automatosx.git",
|
|
11
|
+
"directory": "packages/core/review-domain"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/defai-digital/automatosx#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/defai-digital/automatosx/issues"
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20.0.0"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"uuid": "^11.0.5",
|
|
36
|
+
"@defai.digital/analysis-domain": "13.0.3",
|
|
37
|
+
"@defai.digital/contracts": "13.0.3"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/uuid": "^10.0.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc --build",
|
|
44
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
45
|
+
}
|
|
46
|
+
}
|