codereview-aia 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/.cr-aia.yml +23 -0
  2. package/.crignore +0 -0
  3. package/dist/index.js +27 -0
  4. package/package.json +85 -0
  5. package/src/analysis/FindingsExtractor.ts +431 -0
  6. package/src/analysis/ai-detection/analyzers/BaseAnalyzer.ts +267 -0
  7. package/src/analysis/ai-detection/analyzers/DocumentationAnalyzer.ts +622 -0
  8. package/src/analysis/ai-detection/analyzers/GitHistoryAnalyzer.ts +430 -0
  9. package/src/analysis/ai-detection/core/AIDetectionEngine.ts +467 -0
  10. package/src/analysis/ai-detection/types/DetectionTypes.ts +406 -0
  11. package/src/analysis/ai-detection/utils/SubmissionConverter.ts +390 -0
  12. package/src/analysis/context/ReviewContext.ts +378 -0
  13. package/src/analysis/context/index.ts +7 -0
  14. package/src/analysis/index.ts +8 -0
  15. package/src/analysis/tokens/TokenAnalysisFormatter.ts +154 -0
  16. package/src/analysis/tokens/TokenAnalyzer.ts +747 -0
  17. package/src/analysis/tokens/index.ts +8 -0
  18. package/src/clients/base/abstractClient.ts +190 -0
  19. package/src/clients/base/httpClient.ts +160 -0
  20. package/src/clients/base/index.ts +12 -0
  21. package/src/clients/base/modelDetection.ts +107 -0
  22. package/src/clients/base/responseProcessor.ts +586 -0
  23. package/src/clients/factory/clientFactory.ts +55 -0
  24. package/src/clients/factory/index.ts +8 -0
  25. package/src/clients/implementations/index.ts +8 -0
  26. package/src/clients/implementations/openRouterClient.ts +411 -0
  27. package/src/clients/openRouterClient.ts +863 -0
  28. package/src/clients/openRouterClientWrapper.ts +44 -0
  29. package/src/clients/utils/directoryStructure.ts +52 -0
  30. package/src/clients/utils/index.ts +11 -0
  31. package/src/clients/utils/languageDetection.ts +44 -0
  32. package/src/clients/utils/promptFormatter.ts +105 -0
  33. package/src/clients/utils/promptLoader.ts +53 -0
  34. package/src/clients/utils/tokenCounter.ts +297 -0
  35. package/src/core/ApiClientSelector.ts +37 -0
  36. package/src/core/ConfigurationService.ts +591 -0
  37. package/src/core/ConsolidationService.ts +423 -0
  38. package/src/core/InteractiveDisplayManager.ts +81 -0
  39. package/src/core/OutputManager.ts +275 -0
  40. package/src/core/ReviewGenerator.ts +140 -0
  41. package/src/core/fileDiscovery.ts +237 -0
  42. package/src/core/handlers/EstimationHandler.ts +104 -0
  43. package/src/core/handlers/FileProcessingHandler.ts +204 -0
  44. package/src/core/handlers/OutputHandler.ts +125 -0
  45. package/src/core/handlers/ReviewExecutor.ts +104 -0
  46. package/src/core/reviewOrchestrator.ts +333 -0
  47. package/src/core/utils/ModelInfoUtils.ts +56 -0
  48. package/src/formatters/outputFormatter.ts +62 -0
  49. package/src/formatters/utils/IssueFormatters.ts +83 -0
  50. package/src/formatters/utils/JsonFormatter.ts +77 -0
  51. package/src/formatters/utils/MarkdownFormatters.ts +609 -0
  52. package/src/formatters/utils/MetadataFormatter.ts +269 -0
  53. package/src/formatters/utils/ModelInfoExtractor.ts +115 -0
  54. package/src/index.ts +27 -0
  55. package/src/plugins/PluginInterface.ts +50 -0
  56. package/src/plugins/PluginManager.ts +126 -0
  57. package/src/prompts/PromptManager.ts +69 -0
  58. package/src/prompts/cache/PromptCache.ts +50 -0
  59. package/src/prompts/promptText/common/variables/css-frameworks.json +33 -0
  60. package/src/prompts/promptText/common/variables/framework-versions.json +45 -0
  61. package/src/prompts/promptText/frameworks/react/comprehensive.hbs +19 -0
  62. package/src/prompts/promptText/languages/css/comprehensive.hbs +18 -0
  63. package/src/prompts/promptText/languages/generic/comprehensive.hbs +20 -0
  64. package/src/prompts/promptText/languages/html/comprehensive.hbs +18 -0
  65. package/src/prompts/promptText/languages/javascript/comprehensive.hbs +18 -0
  66. package/src/prompts/promptText/languages/python/comprehensive.hbs +18 -0
  67. package/src/prompts/promptText/languages/typescript/comprehensive.hbs +18 -0
  68. package/src/runtime/auth/service.ts +58 -0
  69. package/src/runtime/auth/session.ts +103 -0
  70. package/src/runtime/auth/types.ts +11 -0
  71. package/src/runtime/cliEntry.ts +196 -0
  72. package/src/runtime/errors.ts +13 -0
  73. package/src/runtime/fileCollector.ts +188 -0
  74. package/src/runtime/manifest.ts +64 -0
  75. package/src/runtime/openrouterProxy.ts +45 -0
  76. package/src/runtime/proxyConfig.ts +94 -0
  77. package/src/runtime/proxyEnvironment.ts +71 -0
  78. package/src/runtime/reportMerge.ts +102 -0
  79. package/src/runtime/reporting/markdownReportBuilder.ts +138 -0
  80. package/src/runtime/reporting/reportDataCollector.ts +234 -0
  81. package/src/runtime/reporting/summaryGenerator.ts +86 -0
  82. package/src/runtime/reviewPipeline.ts +155 -0
  83. package/src/runtime/runAiCodeReview.ts +153 -0
  84. package/src/runtime/runtimeConfig.ts +5 -0
  85. package/src/runtime/ui/Layout.tsx +57 -0
  86. package/src/runtime/ui/RuntimeApp.tsx +150 -0
  87. package/src/runtime/ui/inkModules.ts +73 -0
  88. package/src/runtime/ui/screens/AuthScreen.tsx +128 -0
  89. package/src/runtime/ui/screens/ModeSelection.tsx +52 -0
  90. package/src/runtime/ui/screens/ProgressScreen.tsx +55 -0
  91. package/src/runtime/ui/screens/ResultsScreen.tsx +76 -0
  92. package/src/strategies/ArchitecturalReviewStrategy.ts +54 -0
  93. package/src/strategies/CodingTestReviewStrategy.ts +920 -0
  94. package/src/strategies/ConsolidatedReviewStrategy.ts +59 -0
  95. package/src/strategies/ExtractPatternsReviewStrategy.ts +64 -0
  96. package/src/strategies/MultiPassReviewStrategy.ts +785 -0
  97. package/src/strategies/ReviewStrategy.ts +64 -0
  98. package/src/strategies/StrategyFactory.ts +79 -0
  99. package/src/strategies/index.ts +14 -0
  100. package/src/tokenizers/baseTokenizer.ts +61 -0
  101. package/src/tokenizers/gptTokenizer.ts +27 -0
  102. package/src/tokenizers/index.ts +8 -0
  103. package/src/types/apiResponses.ts +40 -0
  104. package/src/types/cli.ts +24 -0
  105. package/src/types/common.ts +39 -0
  106. package/src/types/configuration.ts +201 -0
  107. package/src/types/handlebars.d.ts +5 -0
  108. package/src/types/patch.d.ts +25 -0
  109. package/src/types/review.ts +294 -0
  110. package/src/types/reviewContext.d.ts +65 -0
  111. package/src/types/reviewSchema.ts +181 -0
  112. package/src/types/structuredReview.ts +167 -0
  113. package/src/types/tokenAnalysis.ts +56 -0
  114. package/src/utils/FileReader.ts +93 -0
  115. package/src/utils/FileWriter.ts +76 -0
  116. package/src/utils/PathGenerator.ts +97 -0
  117. package/src/utils/api/apiUtils.ts +14 -0
  118. package/src/utils/api/index.ts +1 -0
  119. package/src/utils/apiErrorHandler.ts +287 -0
  120. package/src/utils/ciDataCollector.ts +252 -0
  121. package/src/utils/codingTestConfigLoader.ts +466 -0
  122. package/src/utils/dependencies/aiDependencyAnalyzer.ts +454 -0
  123. package/src/utils/detection/frameworkDetector.ts +879 -0
  124. package/src/utils/detection/index.ts +10 -0
  125. package/src/utils/detection/projectTypeDetector.ts +518 -0
  126. package/src/utils/diagramGenerator.ts +206 -0
  127. package/src/utils/errorLogger.ts +60 -0
  128. package/src/utils/estimationUtils.ts +407 -0
  129. package/src/utils/fileFilters.ts +373 -0
  130. package/src/utils/fileSystem.ts +57 -0
  131. package/src/utils/index.ts +36 -0
  132. package/src/utils/logger.ts +240 -0
  133. package/src/utils/pathValidator.ts +98 -0
  134. package/src/utils/priorityFilter.ts +59 -0
  135. package/src/utils/projectDocs.ts +189 -0
  136. package/src/utils/promptPaths.ts +29 -0
  137. package/src/utils/promptTemplateManager.ts +157 -0
  138. package/src/utils/review/consolidateReview.ts +553 -0
  139. package/src/utils/review/fixDisplay.ts +100 -0
  140. package/src/utils/review/fixImplementation.ts +61 -0
  141. package/src/utils/review/index.ts +36 -0
  142. package/src/utils/review/interactiveProcessing.ts +294 -0
  143. package/src/utils/review/progressTracker.ts +296 -0
  144. package/src/utils/review/reviewExtraction.ts +382 -0
  145. package/src/utils/review/types.ts +46 -0
  146. package/src/utils/reviewActionHandler.ts +18 -0
  147. package/src/utils/reviewParser.ts +253 -0
  148. package/src/utils/sanitizer.ts +238 -0
  149. package/src/utils/smartFileSelector.ts +255 -0
  150. package/src/utils/templateLoader.ts +514 -0
  151. package/src/utils/treeGenerator.ts +153 -0
  152. package/tsconfig.build.json +14 -0
  153. package/tsconfig.json +59 -0
@@ -0,0 +1,411 @@
1
+ /**
2
+ * @fileoverview OpenRouter client implementation using the abstract client interface.
3
+ *
4
+ * This module implements the OpenRouter client using the abstract client base class.
5
+ * It provides functionality for interacting with OpenRouter's API, which gives access
6
+ * to a variety of AI models from different providers.
7
+ */
8
+
9
+ import type { FileInfo, ReviewOptions, ReviewResult, ReviewType } from '../../types/review';
10
+ import logger from '../../utils/logger';
11
+ import type { ProjectDocs } from '../../utils/projectDocs';
12
+ import {
13
+ AbstractClient,
14
+ createStandardReviewResult,
15
+ detectModelProvider,
16
+ fetchWithRetry,
17
+ handleApiError,
18
+ validateApiKey,
19
+ } from '../base';
20
+ import {
21
+ formatConsolidatedReviewPrompt,
22
+ formatSingleFileReviewPrompt,
23
+ } from '../utils/promptFormatter';
24
+ import { loadPromptTemplate } from '../utils/promptLoader';
25
+
26
+ // import { getLanguageFromExtension } from '../utils/languageDetection'; // Not used in this implementation
27
+
28
+ const MAX_TOKENS_PER_REQUEST = 4000;
29
+
30
+ /**
31
+ * OpenRouter client implementation
32
+ */
33
+ export class OpenRouterClient extends AbstractClient {
34
+ protected apiKey: string | undefined;
35
+
36
+ /**
37
+ * Initialize with default values
38
+ */
39
+ constructor() {
40
+ super();
41
+ this.modelName = '';
42
+ this.isInitialized = false;
43
+ this.apiKey = process.env.AI_CODE_REVIEW_OPENROUTER_API_KEY;
44
+ }
45
+
46
+ /**
47
+ * Check if the provided model name is supported by this client
48
+ * @param modelName The full model name (potentially with provider prefix)
49
+ * @returns Object indicating if this is the correct client for the model
50
+ */
51
+ public isModelSupported(modelName: string): {
52
+ isCorrect: boolean;
53
+ adapter: string;
54
+ modelName: string;
55
+ } {
56
+ return detectModelProvider('openrouter', modelName);
57
+ }
58
+
59
+ /**
60
+ * Get the provider name for this client
61
+ * @returns The provider name
62
+ */
63
+ protected getProviderName(): string {
64
+ return 'openrouter';
65
+ }
66
+
67
+ /**
68
+ * Initialize the OpenRouter client
69
+ * @returns Promise resolving to a boolean indicating success
70
+ */
71
+ public async initialize(): Promise<boolean> {
72
+ // If already initialized, return true
73
+ if (this.isInitialized) {
74
+ return true;
75
+ }
76
+
77
+ // Get model information - clean the model name to handle malformed input
78
+ const rawModel = process.env.AI_CODE_REVIEW_MODEL || '';
79
+ const cleanedModel = rawModel.replace(/['"``]/g, '').trim();
80
+ const { isCorrect, modelName } = this.isModelSupported(cleanedModel);
81
+
82
+ // If this is not an OpenRouter model, just return true without initializing
83
+ if (!isCorrect) {
84
+ return true;
85
+ }
86
+
87
+ // Set the model name
88
+ this.modelName = modelName;
89
+
90
+ // Validate the API key
91
+ if (!validateApiKey('openrouter', 'AI_CODE_REVIEW_OPENROUTER_API_KEY')) {
92
+ process.exit(1);
93
+ }
94
+
95
+ try {
96
+ logger.info(`Initializing OpenRouter model: ${this.modelName}...`);
97
+
98
+ // Mark as initialized
99
+ this.isInitialized = true;
100
+ logger.info(`Successfully initialized OpenRouter model: ${this.modelName}`);
101
+ return true;
102
+ } catch (error) {
103
+ logger.error(
104
+ `Error initializing OpenRouter model ${this.modelName}: ${
105
+ error instanceof Error ? error.message : String(error)
106
+ }`,
107
+ );
108
+ return false;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Generate a review for a single file
114
+ * @param fileContent Content of the file to review
115
+ * @param filePath Path to the file
116
+ * @param reviewType Type of review to perform
117
+ * @param projectDocs Optional project documentation
118
+ * @param options Review options
119
+ * @returns Promise resolving to the review result
120
+ */
121
+ public async generateReview(
122
+ fileContent: string,
123
+ filePath: string,
124
+ reviewType: ReviewType,
125
+ projectDocs?: ProjectDocs | null,
126
+ options?: ReviewOptions,
127
+ ): Promise<ReviewResult> {
128
+ // During consolidation, the model may have been overridden.
129
+ // If we're already initialized with a valid model, trust that initialization was correct.
130
+ // Only check the environment if we're not initialized.
131
+ if (!this.isInitialized) {
132
+ // If not initialized, check against the current environment variable
133
+ const rawModel = process.env.AI_CODE_REVIEW_MODEL || '';
134
+ // Clean the model name to handle malformed input (quotes, backticks, whitespace)
135
+ const currentModel = rawModel.replace(/['"``]/g, '').trim();
136
+ const { isCorrect } = this.isModelSupported(currentModel);
137
+
138
+ // Make sure this is the correct client
139
+ if (!isCorrect) {
140
+ logger.error(
141
+ `[OpenRouter] Invalid model for OpenRouter client: ${currentModel} (original: ${rawModel})`,
142
+ );
143
+ throw new Error(
144
+ `OpenRouter client was called with an invalid model: ${currentModel}. This is likely a bug in the client selection logic.`,
145
+ );
146
+ }
147
+
148
+ // Initialize if this is the correct client
149
+ await this.initialize();
150
+ }
151
+
152
+ // At this point we should be initialized with a valid model
153
+ if (!this.modelName) {
154
+ logger.error(`[OpenRouter] Client is initialized but has no model name`);
155
+ throw new Error(`OpenRouter client is in an invalid state: initialized but no model name`);
156
+ }
157
+
158
+ try {
159
+ // Get the language from file extension
160
+ // const language = getLanguageFromExtension(filePath); // Currently unused
161
+
162
+ // Load the appropriate prompt template
163
+ const promptTemplate = await loadPromptTemplate(reviewType, options);
164
+
165
+ // Format the prompt
166
+ const prompt = formatSingleFileReviewPrompt(
167
+ promptTemplate,
168
+ fileContent,
169
+ filePath,
170
+ projectDocs,
171
+ );
172
+
173
+ try {
174
+ logger.info(`Generating review with OpenRouter ${this.modelName}...`);
175
+
176
+ // Make the API request
177
+ const response = await fetchWithRetry('https://openrouter.ai/api/v1/chat/completions', {
178
+ method: 'POST',
179
+ headers: {
180
+ 'Content-Type': 'application/json',
181
+ Authorization: `Bearer ${this.apiKey}`,
182
+ 'HTTP-Referer': 'https://cr-aia.app', // Required by OpenRouter
183
+ 'X-Title': 'cr-aia', // Optional for OpenRouter stats
184
+ },
185
+ body: JSON.stringify({
186
+ model: this.modelName,
187
+ messages: [
188
+ {
189
+ role: 'user',
190
+ content: prompt,
191
+ },
192
+ ],
193
+ temperature: 0.2,
194
+ // For consolidation, don't limit tokens to avoid truncation
195
+ ...(options?.isConsolidation ? {} : { max_tokens: MAX_TOKENS_PER_REQUEST }),
196
+ }),
197
+ });
198
+
199
+ const data = await response.json();
200
+ if (!Array.isArray(data.choices) || !data.choices[0]?.message?.content) {
201
+ throw new Error(`Invalid response format from OpenRouter ${this.modelName}`);
202
+ }
203
+
204
+ const content = data.choices[0].message.content;
205
+
206
+ // Check for truncated response
207
+ const usage = data.usage;
208
+ if (usage && usage.completion_tokens < 50) {
209
+ logger.warn(
210
+ `Response appears truncated - only ${usage.completion_tokens} output tokens generated. ` +
211
+ `This may indicate an API issue with model ${this.modelName}.`,
212
+ );
213
+
214
+ // If response is truncated and appears to be incomplete JSON
215
+ if (content.trim().startsWith('{') && !content.includes('}')) {
216
+ const errorMessage =
217
+ `The AI model response was truncated and incomplete. ` +
218
+ `Only ${usage.completion_tokens} tokens were generated instead of the expected response. ` +
219
+ `This is likely an issue with the OpenRouter API or the ${this.modelName} model. ` +
220
+ `Please try again or use a different model.`;
221
+
222
+ logger.error(`Truncated response detected: ${content.substring(0, 100)}...`);
223
+ throw new Error(errorMessage);
224
+ }
225
+ }
226
+
227
+ // Log response details for debugging
228
+ if (usage) {
229
+ logger.debug(
230
+ `OpenRouter response stats - Input tokens: ${usage.prompt_tokens}, ` +
231
+ `Output tokens: ${usage.completion_tokens}, Total: ${usage.total_tokens}`,
232
+ );
233
+ }
234
+
235
+ logger.info(`Successfully generated review with OpenRouter ${this.modelName}`);
236
+
237
+ // Create and return the review result
238
+ return createStandardReviewResult(
239
+ content,
240
+ prompt,
241
+ this.getFullModelName(),
242
+ filePath,
243
+ reviewType,
244
+ options,
245
+ );
246
+ } catch (error) {
247
+ throw handleApiError(error, 'generate review', this.getFullModelName());
248
+ }
249
+ } catch (error) {
250
+ this.handleApiError(error, 'generating review', filePath);
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Generate a consolidated review for multiple files
256
+ * @param files Array of file information objects
257
+ * @param projectName Name of the project
258
+ * @param reviewType Type of review to perform
259
+ * @param projectDocs Optional project documentation
260
+ * @param options Review options
261
+ * @returns Promise resolving to the review result
262
+ */
263
+ public async generateConsolidatedReview(
264
+ files: FileInfo[],
265
+ projectName: string,
266
+ reviewType: ReviewType,
267
+ projectDocs?: ProjectDocs | null,
268
+ options?: ReviewOptions,
269
+ ): Promise<ReviewResult> {
270
+ // During consolidation, the model may have been overridden. We should check if we're already initialized
271
+ // with a valid model rather than checking the current environment variable.
272
+ if (!this.isInitialized || !this.modelName) {
273
+ // If not initialized, check against the current environment variable
274
+ const { isCorrect } = this.isModelSupported(process.env.AI_CODE_REVIEW_MODEL || '');
275
+
276
+ // Make sure this is the correct client
277
+ if (!isCorrect) {
278
+ throw new Error(
279
+ `OpenRouter client was called with an invalid model. This is likely a bug in the client selection logic.`,
280
+ );
281
+ }
282
+ }
283
+ // If we're already initialized with a model, trust that initialization was correct
284
+
285
+ try {
286
+ // Initialize if needed
287
+ if (!this.isInitialized) {
288
+ await this.initialize();
289
+ }
290
+
291
+ // Load the appropriate prompt template
292
+ const promptTemplate = await loadPromptTemplate(reviewType, options);
293
+
294
+ // Format the prompt
295
+ const prompt = formatConsolidatedReviewPrompt(
296
+ promptTemplate,
297
+ projectName,
298
+ files.map((file) => ({
299
+ relativePath: file.relativePath || '',
300
+ content: file.content,
301
+ sizeInBytes: file.content.length,
302
+ })),
303
+ projectDocs,
304
+ );
305
+
306
+ try {
307
+ logger.info(`Generating consolidated review with OpenRouter ${this.modelName}...`);
308
+
309
+ // Make the API request
310
+ const response = await fetchWithRetry('https://openrouter.ai/api/v1/chat/completions', {
311
+ method: 'POST',
312
+ headers: {
313
+ 'Content-Type': 'application/json',
314
+ Authorization: `Bearer ${this.apiKey}`,
315
+ 'HTTP-Referer': 'https://cr-aia.app', // Required by OpenRouter
316
+ 'X-Title': 'cr-aia', // Optional for OpenRouter stats
317
+ },
318
+ body: JSON.stringify({
319
+ model: this.modelName,
320
+ messages: [
321
+ {
322
+ role: 'user',
323
+ content: prompt,
324
+ },
325
+ ],
326
+ temperature: 0.2,
327
+ // For consolidated reviews, don't limit tokens to avoid truncation
328
+ // max_tokens is omitted to allow unlimited output
329
+ }),
330
+ });
331
+
332
+ const data = await response.json();
333
+ if (!Array.isArray(data.choices) || !data.choices[0]?.message?.content) {
334
+ throw new Error(`Invalid response format from OpenRouter ${this.modelName}`);
335
+ }
336
+
337
+ const content = data.choices[0].message.content;
338
+
339
+ // Check for truncated response
340
+ const usage = data.usage;
341
+ if (usage && usage.completion_tokens < 50) {
342
+ logger.warn(
343
+ `Response appears truncated - only ${usage.completion_tokens} output tokens generated. ` +
344
+ `This may indicate an API issue with model ${this.modelName}.`,
345
+ );
346
+
347
+ // If response is truncated and appears to be incomplete JSON
348
+ if (content.trim().startsWith('{') && !content.includes('}')) {
349
+ const errorMessage =
350
+ `The AI model response was truncated and incomplete. ` +
351
+ `Only ${usage.completion_tokens} tokens were generated instead of the expected response. ` +
352
+ `This is likely an issue with the OpenRouter API or the ${this.modelName} model. ` +
353
+ `Please try again or use a different model.`;
354
+
355
+ logger.error(`Truncated response detected: ${content.substring(0, 100)}...`);
356
+ throw new Error(errorMessage);
357
+ }
358
+ }
359
+
360
+ // Log response details for debugging
361
+ if (usage) {
362
+ logger.debug(
363
+ `OpenRouter response stats - Input tokens: ${usage.prompt_tokens}, ` +
364
+ `Output tokens: ${usage.completion_tokens}, Total: ${usage.total_tokens}`,
365
+ );
366
+ }
367
+
368
+ logger.info(`Successfully generated consolidated review with OpenRouter ${this.modelName}`);
369
+
370
+ // Create and return the review result
371
+ return createStandardReviewResult(
372
+ content,
373
+ prompt,
374
+ this.getFullModelName(),
375
+ 'consolidated',
376
+ reviewType,
377
+ options,
378
+ );
379
+ } catch (error) {
380
+ throw handleApiError(error, 'generate consolidated review', this.getFullModelName());
381
+ }
382
+ } catch (error) {
383
+ this.handleApiError(error, 'generating consolidated review', projectName);
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Generate an architectural review for a project
389
+ * @param files Array of file information objects
390
+ * @param projectName Name of the project
391
+ * @param projectDocs Optional project documentation
392
+ * @param options Review options
393
+ * @returns Promise resolving to the review result
394
+ */
395
+ public async generateArchitecturalReview(
396
+ files: FileInfo[],
397
+ projectName: string,
398
+ projectDocs?: ProjectDocs | null,
399
+ options?: ReviewOptions,
400
+ ): Promise<ReviewResult> {
401
+ // For OpenRouter, architectural reviews are handled by the consolidated review function
402
+ // with the review type set to 'architectural'
403
+ return this.generateConsolidatedReview(
404
+ files,
405
+ projectName,
406
+ 'architectural',
407
+ projectDocs,
408
+ options,
409
+ );
410
+ }
411
+ }