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,64 @@
1
+ /**
2
+ * @fileoverview Review strategy interface and base class.
3
+ *
4
+ * This module defines the interface and base class for review strategies,
5
+ * which encapsulate the logic for different types of code reviews.
6
+ */
7
+
8
+ import type { ApiClientConfig } from '../core/ApiClientSelector';
9
+ import type { FileInfo, ReviewOptions, ReviewResult, ReviewType } from '../types/review';
10
+ import type { ProjectDocs } from '../utils/projectDocs';
11
+
12
+ /**
13
+ * Interface for review strategies
14
+ */
15
+ export interface IReviewStrategy {
16
+ /**
17
+ * Execute the review strategy
18
+ * @param files Files to review
19
+ * @param projectName Project name
20
+ * @param projectDocs Project documentation
21
+ * @param options Review options
22
+ * @param apiClientConfig API client configuration
23
+ * @returns Promise resolving to the review result
24
+ */
25
+ execute(
26
+ files: FileInfo[],
27
+ projectName: string,
28
+ projectDocs: ProjectDocs | null,
29
+ options: ReviewOptions,
30
+ apiClientConfig: ApiClientConfig,
31
+ ): Promise<ReviewResult>;
32
+ }
33
+
34
+ /**
35
+ * Base class for review strategies
36
+ */
37
+ export abstract class BaseReviewStrategy implements IReviewStrategy {
38
+ protected reviewType: ReviewType;
39
+
40
+ /**
41
+ * Create a new review strategy
42
+ * @param reviewType Type of review to perform
43
+ */
44
+ constructor(reviewType: ReviewType) {
45
+ this.reviewType = reviewType;
46
+ }
47
+
48
+ /**
49
+ * Execute the review strategy
50
+ * @param files Files to review
51
+ * @param projectName Project name
52
+ * @param projectDocs Project documentation
53
+ * @param options Review options
54
+ * @param apiClientConfig API client configuration
55
+ * @returns Promise resolving to the review result
56
+ */
57
+ abstract execute(
58
+ files: FileInfo[],
59
+ projectName: string,
60
+ projectDocs: ProjectDocs | null,
61
+ options: ReviewOptions,
62
+ apiClientConfig: ApiClientConfig,
63
+ ): Promise<ReviewResult>;
64
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @fileoverview Strategy factory for creating review strategies.
3
+ *
4
+ * This module provides a factory for creating the appropriate review strategy
5
+ * based on the review options.
6
+ */
7
+
8
+ import { PluginManager } from '../plugins/PluginManager';
9
+ import type { ReviewOptions, ReviewType } from '../types/review';
10
+ import logger from '../utils/logger';
11
+ import { ArchitecturalReviewStrategy } from './ArchitecturalReviewStrategy';
12
+ import { CodingTestReviewStrategy } from './CodingTestReviewStrategy';
13
+ import { ConsolidatedReviewStrategy } from './ConsolidatedReviewStrategy';
14
+ import { ExtractPatternsReviewStrategy } from './ExtractPatternsReviewStrategy';
15
+ import { MultiPassReviewStrategy } from './MultiPassReviewStrategy';
16
+ import type { IReviewStrategy } from './ReviewStrategy';
17
+
18
+ /**
19
+ * Factory for creating review strategies
20
+ */
21
+ export class StrategyFactory {
22
+ /**
23
+ * Create a review strategy based on options
24
+ * @param options Review options
25
+ * @returns The appropriate review strategy
26
+ */
27
+ static createStrategy(options: ReviewOptions): IReviewStrategy {
28
+ // Check if a custom strategy is specified
29
+ if (options.strategy) {
30
+ const pluginManager = PluginManager.getInstance();
31
+ const customStrategy = pluginManager.getPlugin(options.strategy);
32
+
33
+ if (customStrategy) {
34
+ logger.info(`Using custom strategy: ${options.strategy}`);
35
+ return customStrategy;
36
+ }
37
+ logger.warn(
38
+ `Custom strategy "${options.strategy}" not found. Falling back to default strategy.`,
39
+ );
40
+ }
41
+
42
+ // Use default strategies if no custom strategy is specified or if the custom strategy is not found
43
+ const reviewType = options.type as ReviewType;
44
+
45
+ // Debug logging for strategy selection
46
+ logger.debug(`StrategyFactory.createStrategy: reviewType = "${reviewType}"`);
47
+
48
+ // Check if multi-pass mode is explicitly requested
49
+ if (options.multiPass) {
50
+ logger.info('Using Multi-Pass Review Strategy');
51
+ return new MultiPassReviewStrategy(reviewType);
52
+ }
53
+
54
+ if (reviewType === 'architectural') {
55
+ logger.debug('Creating ArchitecturalReviewStrategy');
56
+ return new ArchitecturalReviewStrategy();
57
+ }
58
+ if (reviewType === 'extract-patterns') {
59
+ logger.debug('Creating ExtractPatternsReviewStrategy');
60
+ return new ExtractPatternsReviewStrategy();
61
+ }
62
+ if (reviewType === 'coding-test') {
63
+ logger.debug('Creating CodingTestReviewStrategy');
64
+ return new CodingTestReviewStrategy();
65
+ }
66
+ if (
67
+ reviewType === 'unused-code' ||
68
+ reviewType === 'focused-unused-code' ||
69
+ reviewType === 'code-tracing-unused-code' ||
70
+ reviewType === 'quick-fixes'
71
+ ) {
72
+ logger.warn(
73
+ `Review type "${reviewType}" is not supported in this runtime. Falling back to consolidated review.`,
74
+ );
75
+ }
76
+ logger.debug(`Creating ConsolidatedReviewStrategy for reviewType: "${reviewType}"`);
77
+ return new ConsolidatedReviewStrategy(reviewType);
78
+ }
79
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Review strategies module.
3
+ *
4
+ * This module provides a collection of strategies for performing different types
5
+ * of code reviews, along with a factory for creating strategy instances.
6
+ */
7
+
8
+ export * from './ReviewStrategy';
9
+ export * from './StrategyFactory';
10
+ export * from './ArchitecturalReviewStrategy';
11
+ export * from './ConsolidatedReviewStrategy';
12
+ export * from './ExtractPatternsReviewStrategy';
13
+ export * from './CodingTestReviewStrategy';
14
+ export * from './MultiPassReviewStrategy';
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared tokenizer contract for the cr-aia.
3
+ * Tokenizers just need to report how many tokens a given model would consume.
4
+ */
5
+ export interface Tokenizer {
6
+ countTokens(text: string): number;
7
+ getModelName(): string;
8
+ supportsModel(modelName: string): boolean;
9
+ }
10
+
11
+ export class TokenizerRegistry {
12
+ private static tokenizers: Tokenizer[] = [];
13
+
14
+ static register(tokenizer: Tokenizer): void {
15
+ TokenizerRegistry.tokenizers.push(tokenizer);
16
+ }
17
+
18
+ static find(modelName: string): Tokenizer | undefined {
19
+ return TokenizerRegistry.tokenizers.find((tokenizer) => tokenizer.supportsModel(modelName));
20
+ }
21
+
22
+ static list(): Tokenizer[] {
23
+ return [...TokenizerRegistry.tokenizers];
24
+ }
25
+ }
26
+
27
+ export class FallbackTokenizer implements Tokenizer {
28
+ countTokens(text: string): number {
29
+ // Rule of thumb for GPT-style models: ~4 characters per token.
30
+ return Math.ceil(text.length / 4);
31
+ }
32
+
33
+ getModelName(): string {
34
+ return 'fallback';
35
+ }
36
+
37
+ supportsModel(_modelName: string): boolean {
38
+ return true;
39
+ }
40
+ }
41
+
42
+ const fallbackTokenizer = new FallbackTokenizer();
43
+
44
+ export function getTokenizer(modelName: string): Tokenizer {
45
+ return TokenizerRegistry.find(modelName) ?? fallbackTokenizer;
46
+ }
47
+
48
+ /**
49
+ * Count tokens using whichever tokenizer matches the supplied model.
50
+ */
51
+ export function countTokens(text: string, modelName: string): number {
52
+ const tokenizer = getTokenizer(modelName);
53
+ const count = tokenizer.countTokens(text);
54
+
55
+ if (modelName === 'test-small-context') {
56
+ // Tests rely on this inflated value to stress chunking.
57
+ return text.length;
58
+ }
59
+
60
+ return count;
61
+ }
@@ -0,0 +1,27 @@
1
+ import { encode } from 'gpt-tokenizer';
2
+ import { type Tokenizer, TokenizerRegistry } from './baseTokenizer';
3
+
4
+ export class GPTTokenizer implements Tokenizer {
5
+ private modelPatterns: RegExp[] = [/gpt/i];
6
+
7
+ countTokens(text: string): number {
8
+ try {
9
+ const tokens = encode(text);
10
+ return tokens.length;
11
+ } catch (error) {
12
+ console.warn(`Error counting tokens with GPT tokenizer: ${error}`);
13
+ return Math.ceil(text.length / 4);
14
+ }
15
+ }
16
+
17
+ getModelName(): string {
18
+ return 'gpt';
19
+ }
20
+
21
+ supportsModel(modelName: string): boolean {
22
+ const lowerModelName = modelName.toLowerCase();
23
+ return this.modelPatterns.some((pattern) => pattern.test(lowerModelName));
24
+ }
25
+ }
26
+
27
+ TokenizerRegistry.register(new GPTTokenizer());
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Tokenizer exports.
3
+ *
4
+ * This module exports all tokenizer implementations and utilities.
5
+ */
6
+
7
+ export * from './baseTokenizer';
8
+ export * from './gptTokenizer';
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Type definitions for cr-aia responses.
3
+ *
4
+ * We only keep the pieces of the responses that are actually consumed in this fork.
5
+ * Additional provider-specific interfaces were removed because they were never used.
6
+ */
7
+
8
+ /**
9
+ * Minimal JSON payload we expect when a provider returns structured output.
10
+ */
11
+ export interface AIJsonResponse {
12
+ review?: {
13
+ version?: string;
14
+ timestamp?: string;
15
+ files?: Array<{
16
+ filePath?: string;
17
+ issues?: Array<{
18
+ id?: string;
19
+ priority?: string;
20
+ description?: string;
21
+ location?: {
22
+ startLine?: number;
23
+ endLine?: number;
24
+ };
25
+ currentCode?: string;
26
+ suggestedCode?: string;
27
+ explanation?: string;
28
+ }>;
29
+ }>;
30
+ summary?: {
31
+ grade?: string;
32
+ highPriorityIssues?: number;
33
+ mediumPriorityIssues?: number;
34
+ lowPriorityIssues?: number;
35
+ totalIssues?: number;
36
+ };
37
+ positiveAspects?: string[];
38
+ recommendations?: string[];
39
+ };
40
+ }
@@ -0,0 +1,24 @@
1
+ import type { ReviewOptions } from './review';
2
+
3
+ /**
4
+ * Minimal CLI options interface consumed by legacy config utilities.
5
+ * The actual argument parser is gone, but these modules still expect
6
+ * a typed shape for overrides coming from the UI runtime.
7
+ */
8
+ export interface CliOptions extends ReviewOptions {
9
+ /** Target file or directory */
10
+ target: string;
11
+ /** Output directory for generated files */
12
+ outputDir?: string;
13
+ /** Writer model for consolidation */
14
+ writerModel?: string;
15
+ /** API keys map (legacy singular naming) */
16
+ apiKey?: Record<string, string>;
17
+ /** API keys map (preferred naming) */
18
+ apiKeys?: Record<string, string>;
19
+ /** Log level override */
20
+ logLevel?: string;
21
+ /** Path to configuration file */
22
+ config?: string;
23
+ }
24
+
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Common type definitions used throughout cr-aia.
3
+ *
4
+ * The previous fork duplicated a lot of unused helper constants and validation tables.
5
+ * We trimmed those so only the pieces referenced elsewhere remain here.
6
+ */
7
+
8
+ /**
9
+ * Output format options for persisted review artifacts.
10
+ */
11
+ export type OutputFormat = 'markdown' | 'json';
12
+
13
+ /**
14
+ * Supported programming languages that the project detector can report.
15
+ */
16
+ export type ProgrammingLanguage =
17
+ | 'typescript'
18
+ | 'javascript'
19
+ | 'python'
20
+ | 'java'
21
+ | 'go'
22
+ | 'rust'
23
+ | 'c'
24
+ | 'cpp'
25
+ | 'csharp'
26
+ | 'php'
27
+ | 'ruby'
28
+ | 'swift'
29
+ | 'kotlin';
30
+
31
+ /**
32
+ * Default programming language when detection fails.
33
+ */
34
+ export const DEFAULT_LANGUAGE: ProgrammingLanguage = 'typescript';
35
+
36
+ /**
37
+ * Priority filter options for interactive mode.
38
+ */
39
+ export type PriorityFilter = 'h' | 'm' | 'l' | 'a';
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Centralized configuration type definitions for cr-aia.
3
+ *
4
+ * The previous upstream project exposed dozens of knobs we do not use, so this fork
5
+ * focuses on the configuration surfaces that actually exist in our runtime.
6
+ */
7
+
8
+ import { z } from 'zod';
9
+
10
+ /**
11
+ * Environment source for a configuration value
12
+ */
13
+ export type EnvSource =
14
+ // Primary environment variables
15
+ | 'AI_CODE_REVIEW_GOOGLE_API_KEY'
16
+ | 'AI_CODE_REVIEW_OPENROUTER_API_KEY'
17
+ | 'AI_CODE_REVIEW_ANTHROPIC_API_KEY'
18
+ | 'AI_CODE_REVIEW_OPENAI_API_KEY'
19
+ | 'AI_CODE_REVIEW_MODEL'
20
+ | 'AI_CODE_REVIEW_WRITER_MODEL'
21
+ | 'AI_CODE_REVIEW_LOG_LEVEL'
22
+ | 'AI_CODE_REVIEW_OUTPUT_DIR'
23
+ | 'AI_CODE_REVIEW_CONTEXT'
24
+ | 'AI_CODE_REVIEW_DIR'
25
+ | 'AI_CODE_REVIEW_DEBUG'
26
+ // Legacy environment variables
27
+ | 'CODE_REVIEW_GOOGLE_API_KEY'
28
+ | 'CODE_REVIEW_OPENROUTER_API_KEY'
29
+ | 'CODE_REVIEW_ANTHROPIC_API_KEY'
30
+ | 'CODE_REVIEW_OPENAI_API_KEY'
31
+ // Generic environment variables
32
+ | 'GOOGLE_GENERATIVE_AI_KEY'
33
+ | 'GOOGLE_AI_STUDIO_KEY'
34
+ | 'OPENROUTER_API_KEY'
35
+ | 'ANTHROPIC_API_KEY'
36
+ | 'OPENAI_API_KEY'
37
+ // CLI option
38
+ | 'cli_option'
39
+ // Default value
40
+ | 'default_value'
41
+ // None (not set)
42
+ | 'none';
43
+
44
+ /**
45
+ * Configuration value record with its source
46
+ */
47
+ export interface ConfigValue<T> {
48
+ value: T;
49
+ source: EnvSource;
50
+ }
51
+
52
+ /**
53
+ * API keys configuration
54
+ */
55
+ export interface ApiKeysConfig {
56
+ openRouter?: ConfigValue<string>;
57
+ }
58
+
59
+ /**
60
+ * API provider types
61
+ */
62
+ export type ApiProvider = 'openrouter';
63
+
64
+ /**
65
+ * API endpoint configuration
66
+ */
67
+ export interface ApiEndpointsConfig {
68
+ openRouter: ConfigValue<string>;
69
+ }
70
+
71
+ /**
72
+ * API version configuration
73
+ */
74
+ export interface ApiVersionsConfig {
75
+ openRouter: ConfigValue<string>;
76
+ }
77
+
78
+ /**
79
+ * Log level type
80
+ */
81
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
82
+
83
+ /**
84
+ * Paths configuration
85
+ */
86
+ export interface PathsConfig {
87
+ outputDir: ConfigValue<string>;
88
+ promptsDir: ConfigValue<string>;
89
+ templatesDir: ConfigValue<string>;
90
+ contextPaths?: ConfigValue<string[]>;
91
+ }
92
+
93
+ /**
94
+ * Rate limiting configuration
95
+ */
96
+ export interface RateLimitConfig {
97
+ tokensPerSecond: ConfigValue<number>;
98
+ maxConcurrentRequests: ConfigValue<number>;
99
+ retryDelayMs: ConfigValue<number>;
100
+ maxRetries: ConfigValue<number>;
101
+ }
102
+
103
+ /**
104
+ * Token configuration
105
+ */
106
+ export interface TokenConfig {
107
+ maxTokensPerRequest: ConfigValue<number>;
108
+ contextWindowSize: Record<ApiProvider, ConfigValue<number>>;
109
+ costPerInputToken: Record<ApiProvider, ConfigValue<number>>;
110
+ costPerOutputToken: Record<ApiProvider, ConfigValue<number>>;
111
+ }
112
+
113
+ /**
114
+ * Complete application configuration interface
115
+ */
116
+ export interface ApplicationConfig {
117
+ // API connections
118
+ apiKeys: ApiKeysConfig;
119
+ apiEndpoints: ApiEndpointsConfig;
120
+ apiVersions: ApiVersionsConfig;
121
+
122
+ // Model configuration
123
+ selectedModel: ConfigValue<string>;
124
+ writerModel?: ConfigValue<string>;
125
+ modelProvider: ConfigValue<ApiProvider>;
126
+
127
+ // Logging and debugging
128
+ debug: ConfigValue<boolean>;
129
+ logLevel: ConfigValue<LogLevel>;
130
+
131
+ // File system
132
+ paths: PathsConfig;
133
+
134
+ // Rate limiting and performance
135
+ rateLimit: RateLimitConfig;
136
+
137
+ // Token management
138
+ tokens: TokenConfig;
139
+ }
140
+
141
+ /**
142
+ * Zod schema for application configuration validation
143
+ */
144
+ export const applicationConfigSchema = z.object({
145
+ apiKeys: z.object({
146
+ openRouter: z.object({ value: z.string().optional(), source: z.string() }).optional(),
147
+ }),
148
+
149
+ apiEndpoints: z.object({
150
+ openRouter: z.object({ value: z.string(), source: z.string() }),
151
+ }),
152
+
153
+ apiVersions: z.object({
154
+ openRouter: z.object({ value: z.string(), source: z.string() }),
155
+ }),
156
+
157
+ selectedModel: z.object({ value: z.string(), source: z.string() }),
158
+ writerModel: z.object({ value: z.string(), source: z.string() }).optional(),
159
+ modelProvider: z.object({
160
+ value: z.enum(['openrouter']),
161
+ source: z.string(),
162
+ }),
163
+
164
+ debug: z.object({ value: z.boolean(), source: z.string() }),
165
+ logLevel: z.object({
166
+ value: z.enum(['debug', 'info', 'warn', 'error', 'none']),
167
+ source: z.string(),
168
+ }),
169
+
170
+ paths: z.object({
171
+ outputDir: z.object({ value: z.string(), source: z.string() }),
172
+ promptsDir: z.object({ value: z.string(), source: z.string() }),
173
+ templatesDir: z.object({ value: z.string(), source: z.string() }),
174
+ contextPaths: z
175
+ .object({
176
+ value: z.array(z.string()),
177
+ source: z.string(),
178
+ })
179
+ .optional(),
180
+ }),
181
+
182
+ rateLimit: z.object({
183
+ tokensPerSecond: z.object({ value: z.number(), source: z.string() }),
184
+ maxConcurrentRequests: z.object({ value: z.number(), source: z.string() }),
185
+ retryDelayMs: z.object({ value: z.number(), source: z.string() }),
186
+ maxRetries: z.object({ value: z.number(), source: z.string() }),
187
+ }),
188
+
189
+ tokens: z.object({
190
+ maxTokensPerRequest: z.object({ value: z.number(), source: z.string() }),
191
+ contextWindowSize: z.object({
192
+ openrouter: z.object({ value: z.number(), source: z.string() }),
193
+ }),
194
+ costPerInputToken: z.object({
195
+ openrouter: z.object({ value: z.number(), source: z.string() }),
196
+ }),
197
+ costPerOutputToken: z.object({
198
+ openrouter: z.object({ value: z.number(), source: z.string() }),
199
+ }),
200
+ }),
201
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Minimal declaration so we can compile isolated Handlebars helpers
3
+ * without pulling the entire upstream type package into runtime builds.
4
+ */
5
+ declare type HandlebarsTemplateDelegate<T = any> = (context: T, options?: any) => string;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Local module patches so cr-aia can use optional file paths without rewriting the formatter.
3
+ */
4
+
5
+ // Allow optional filePath in formatSimpleMarkdown and formatStructuredReviewAsMarkdown
6
+ declare module '../formatters/outputFormatter' {
7
+ function formatSimpleMarkdown(
8
+ content: string,
9
+ filePath: string | undefined,
10
+ reviewType: string,
11
+ timestamp: string,
12
+ costInfo: string,
13
+ modelInfo: string,
14
+ metadataSection?: string,
15
+ ): string;
16
+
17
+ function formatStructuredReviewAsMarkdown(
18
+ structuredReview: import('./structuredReview').StructuredReview,
19
+ filePath: string | undefined,
20
+ reviewType: string,
21
+ timestamp: string,
22
+ costInfo: string,
23
+ modelInfo: string,
24
+ ): string;
25
+ }