codereview-aia 0.1.2 → 0.1.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/dist/index.js +0 -2
- package/docs/opt-in-full-context.md +27 -0
- package/package.json +11 -11
- package/reports/cr-cr-aia-17-11-2025-20-13.md +354 -0
- package/src/clients/implementations/openRouterClient.ts +2 -0
- package/src/clients/openRouterClient.ts +8 -1
- package/src/clients/utils/promptFormatter.ts +97 -20
- package/src/core/handlers/FileProcessingHandler.ts +6 -0
- package/src/index.ts +0 -3
- package/src/runtime/cliEntry.ts +21 -3
- package/src/runtime/fileCollector.ts +278 -5
- package/src/runtime/reviewPipeline.ts +46 -7
- package/src/runtime/runAiCodeReview.ts +161 -6
- package/src/runtime/ui/RuntimeApp.tsx +34 -5
- package/src/runtime/ui/screens/ProgressScreen.tsx +49 -1
- package/src/runtime/ui/screens/ResultsScreen.tsx +29 -9
- package/src/types/review.ts +18 -0
- package/dist/analysis/FindingsExtractor.d.ts +0 -105
- package/dist/analysis/FindingsExtractor.js +0 -363
- package/dist/analysis/FindingsExtractor.js.map +0 -1
- package/dist/analysis/ai-detection/analyzers/BaseAnalyzer.d.ts +0 -111
- package/dist/analysis/ai-detection/analyzers/BaseAnalyzer.js +0 -215
- package/dist/analysis/ai-detection/analyzers/BaseAnalyzer.js.map +0 -1
- package/dist/analysis/ai-detection/analyzers/DocumentationAnalyzer.d.ts +0 -142
- package/dist/analysis/ai-detection/analyzers/DocumentationAnalyzer.js +0 -503
- package/dist/analysis/ai-detection/analyzers/DocumentationAnalyzer.js.map +0 -1
- package/dist/analysis/ai-detection/analyzers/GitHistoryAnalyzer.d.ts +0 -88
- package/dist/analysis/ai-detection/analyzers/GitHistoryAnalyzer.js +0 -343
- package/dist/analysis/ai-detection/analyzers/GitHistoryAnalyzer.js.map +0 -1
- package/dist/analysis/ai-detection/core/AIDetectionEngine.d.ts +0 -104
- package/dist/analysis/ai-detection/core/AIDetectionEngine.js +0 -369
- package/dist/analysis/ai-detection/core/AIDetectionEngine.js.map +0 -1
- package/dist/analysis/ai-detection/types/DetectionTypes.d.ts +0 -364
- package/dist/analysis/ai-detection/types/DetectionTypes.js +0 -32
- package/dist/analysis/ai-detection/types/DetectionTypes.js.map +0 -1
- package/dist/analysis/ai-detection/utils/SubmissionConverter.d.ts +0 -97
- package/dist/analysis/ai-detection/utils/SubmissionConverter.js +0 -339
- package/dist/analysis/ai-detection/utils/SubmissionConverter.js.map +0 -1
- package/dist/analysis/context/ReviewContext.d.ts +0 -184
- package/dist/analysis/context/ReviewContext.js +0 -294
- package/dist/analysis/context/ReviewContext.js.map +0 -1
- package/dist/analysis/context/index.d.ts +0 -6
- package/dist/analysis/context/index.js +0 -23
- package/dist/analysis/context/index.js.map +0 -1
- package/dist/analysis/index.d.ts +0 -7
- package/dist/analysis/index.js +0 -24
- package/dist/analysis/index.js.map +0 -1
- package/dist/analysis/tokens/TokenAnalysisFormatter.d.ts +0 -27
- package/dist/analysis/tokens/TokenAnalysisFormatter.js +0 -143
- package/dist/analysis/tokens/TokenAnalysisFormatter.js.map +0 -1
- package/dist/analysis/tokens/TokenAnalyzer.d.ts +0 -155
- package/dist/analysis/tokens/TokenAnalyzer.js +0 -502
- package/dist/analysis/tokens/TokenAnalyzer.js.map +0 -1
- package/dist/analysis/tokens/index.d.ts +0 -7
- package/dist/analysis/tokens/index.js +0 -24
- package/dist/analysis/tokens/index.js.map +0 -1
- package/dist/clients/base/abstractClient.d.ts +0 -99
- package/dist/clients/base/abstractClient.js +0 -98
- package/dist/clients/base/abstractClient.js.map +0 -1
- package/dist/clients/base/httpClient.d.ts +0 -24
- package/dist/clients/base/httpClient.js +0 -147
- package/dist/clients/base/httpClient.js.map +0 -1
- package/dist/clients/base/index.d.ts +0 -11
- package/dist/clients/base/index.js +0 -28
- package/dist/clients/base/index.js.map +0 -1
- package/dist/clients/base/modelDetection.d.ts +0 -41
- package/dist/clients/base/modelDetection.js +0 -88
- package/dist/clients/base/modelDetection.js.map +0 -1
- package/dist/clients/base/responseProcessor.d.ts +0 -45
- package/dist/clients/base/responseProcessor.js +0 -495
- package/dist/clients/base/responseProcessor.js.map +0 -1
- package/dist/clients/factory/clientFactory.d.ts +0 -23
- package/dist/clients/factory/clientFactory.js +0 -50
- package/dist/clients/factory/clientFactory.js.map +0 -1
- package/dist/clients/factory/index.d.ts +0 -7
- package/dist/clients/factory/index.js +0 -24
- package/dist/clients/factory/index.js.map +0 -1
- package/dist/clients/implementations/index.d.ts +0 -7
- package/dist/clients/implementations/index.js +0 -24
- package/dist/clients/implementations/index.js.map +0 -1
- package/dist/clients/implementations/openRouterClient.d.ts +0 -69
- package/dist/clients/implementations/openRouterClient.js +0 -294
- package/dist/clients/implementations/openRouterClient.js.map +0 -1
- package/dist/clients/openRouterClient.d.ts +0 -42
- package/dist/clients/openRouterClient.js +0 -738
- package/dist/clients/openRouterClient.js.map +0 -1
- package/dist/clients/openRouterClientWrapper.d.ts +0 -22
- package/dist/clients/openRouterClientWrapper.js +0 -64
- package/dist/clients/openRouterClientWrapper.js.map +0 -1
- package/dist/clients/utils/directoryStructure.d.ts +0 -14
- package/dist/clients/utils/directoryStructure.js +0 -48
- package/dist/clients/utils/directoryStructure.js.map +0 -1
- package/dist/clients/utils/index.d.ts +0 -10
- package/dist/clients/utils/index.js +0 -31
- package/dist/clients/utils/index.js.map +0 -1
- package/dist/clients/utils/languageDetection.d.ts +0 -13
- package/dist/clients/utils/languageDetection.js +0 -46
- package/dist/clients/utils/languageDetection.js.map +0 -1
- package/dist/clients/utils/promptFormatter.d.ts +0 -36
- package/dist/clients/utils/promptFormatter.js +0 -92
- package/dist/clients/utils/promptFormatter.js.map +0 -1
- package/dist/clients/utils/promptLoader.d.ts +0 -27
- package/dist/clients/utils/promptLoader.js +0 -49
- package/dist/clients/utils/promptLoader.js.map +0 -1
- package/dist/clients/utils/tokenCounter.d.ts +0 -81
- package/dist/clients/utils/tokenCounter.js +0 -209
- package/dist/clients/utils/tokenCounter.js.map +0 -1
- package/dist/core/ApiClientSelector.d.ts +0 -8
- package/dist/core/ApiClientSelector.js +0 -29
- package/dist/core/ApiClientSelector.js.map +0 -1
- package/dist/core/ConfigurationService.d.ts +0 -286
- package/dist/core/ConfigurationService.js +0 -477
- package/dist/core/ConfigurationService.js.map +0 -1
- package/dist/core/ConsolidationService.d.ts +0 -99
- package/dist/core/ConsolidationService.js +0 -341
- package/dist/core/ConsolidationService.js.map +0 -1
- package/dist/core/InteractiveDisplayManager.d.ts +0 -22
- package/dist/core/InteractiveDisplayManager.js +0 -70
- package/dist/core/InteractiveDisplayManager.js.map +0 -1
- package/dist/core/OutputManager.d.ts +0 -26
- package/dist/core/OutputManager.js +0 -217
- package/dist/core/OutputManager.js.map +0 -1
- package/dist/core/ReviewGenerator.d.ts +0 -13
- package/dist/core/ReviewGenerator.js +0 -102
- package/dist/core/ReviewGenerator.js.map +0 -1
- package/dist/core/fileDiscovery.d.ts +0 -35
- package/dist/core/fileDiscovery.js +0 -202
- package/dist/core/fileDiscovery.js.map +0 -1
- package/dist/core/handlers/EstimationHandler.d.ts +0 -18
- package/dist/core/handlers/EstimationHandler.js +0 -110
- package/dist/core/handlers/EstimationHandler.js.map +0 -1
- package/dist/core/handlers/FileProcessingHandler.d.ts +0 -31
- package/dist/core/handlers/FileProcessingHandler.js +0 -159
- package/dist/core/handlers/FileProcessingHandler.js.map +0 -1
- package/dist/core/handlers/OutputHandler.d.ts +0 -27
- package/dist/core/handlers/OutputHandler.js +0 -127
- package/dist/core/handlers/OutputHandler.js.map +0 -1
- package/dist/core/handlers/ReviewExecutor.d.ts +0 -32
- package/dist/core/handlers/ReviewExecutor.js +0 -111
- package/dist/core/handlers/ReviewExecutor.js.map +0 -1
- package/dist/core/reviewOrchestrator.d.ts +0 -24
- package/dist/core/reviewOrchestrator.js +0 -294
- package/dist/core/reviewOrchestrator.js.map +0 -1
- package/dist/core/utils/ModelInfoUtils.d.ts +0 -16
- package/dist/core/utils/ModelInfoUtils.js +0 -54
- package/dist/core/utils/ModelInfoUtils.js.map +0 -1
- package/dist/formatters/outputFormatter.d.ts +0 -31
- package/dist/formatters/outputFormatter.js +0 -65
- package/dist/formatters/outputFormatter.js.map +0 -1
- package/dist/formatters/utils/IssueFormatters.d.ts +0 -20
- package/dist/formatters/utils/IssueFormatters.js +0 -67
- package/dist/formatters/utils/IssueFormatters.js.map +0 -1
- package/dist/formatters/utils/JsonFormatter.d.ts +0 -13
- package/dist/formatters/utils/JsonFormatter.js +0 -57
- package/dist/formatters/utils/JsonFormatter.js.map +0 -1
- package/dist/formatters/utils/MarkdownFormatters.d.ts +0 -51
- package/dist/formatters/utils/MarkdownFormatters.js +0 -456
- package/dist/formatters/utils/MarkdownFormatters.js.map +0 -1
- package/dist/formatters/utils/MetadataFormatter.d.ts +0 -65
- package/dist/formatters/utils/MetadataFormatter.js +0 -219
- package/dist/formatters/utils/MetadataFormatter.js.map +0 -1
- package/dist/formatters/utils/ModelInfoExtractor.d.ts +0 -33
- package/dist/formatters/utils/ModelInfoExtractor.js +0 -111
- package/dist/formatters/utils/ModelInfoExtractor.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/plugins/PluginInterface.d.ts +0 -44
- package/dist/plugins/PluginInterface.js +0 -9
- package/dist/plugins/PluginInterface.js.map +0 -1
- package/dist/plugins/PluginManager.d.ts +0 -51
- package/dist/plugins/PluginManager.js +0 -151
- package/dist/plugins/PluginManager.js.map +0 -1
- package/dist/prompts/PromptManager.d.ts +0 -30
- package/dist/prompts/PromptManager.js +0 -62
- package/dist/prompts/PromptManager.js.map +0 -1
- package/dist/prompts/cache/PromptCache.d.ts +0 -32
- package/dist/prompts/cache/PromptCache.js +0 -48
- package/dist/prompts/cache/PromptCache.js.map +0 -1
- package/dist/runtime/auth/service.d.ts +0 -2
- package/dist/runtime/auth/service.js +0 -41
- package/dist/runtime/auth/service.js.map +0 -1
- package/dist/runtime/auth/session.d.ts +0 -5
- package/dist/runtime/auth/session.js +0 -87
- package/dist/runtime/auth/session.js.map +0 -1
- package/dist/runtime/auth/types.d.ts +0 -9
- package/dist/runtime/auth/types.js +0 -3
- package/dist/runtime/auth/types.js.map +0 -1
- package/dist/runtime/cliEntry.d.ts +0 -1
- package/dist/runtime/cliEntry.js +0 -213
- package/dist/runtime/cliEntry.js.map +0 -1
- package/dist/runtime/debug/logManager.d.ts +0 -5
- package/dist/runtime/debug/logManager.js +0 -31
- package/dist/runtime/debug/logManager.js.map +0 -1
- package/dist/runtime/errors.d.ts +0 -5
- package/dist/runtime/errors.js +0 -15
- package/dist/runtime/errors.js.map +0 -1
- package/dist/runtime/fileCollector.d.ts +0 -5
- package/dist/runtime/fileCollector.js +0 -167
- package/dist/runtime/fileCollector.js.map +0 -1
- package/dist/runtime/manifest.d.ts +0 -1
- package/dist/runtime/manifest.js +0 -65
- package/dist/runtime/manifest.js.map +0 -1
- package/dist/runtime/openrouterProxy.d.ts +0 -4
- package/dist/runtime/openrouterProxy.js +0 -43
- package/dist/runtime/openrouterProxy.js.map +0 -1
- package/dist/runtime/preprod/webCheck.d.ts +0 -1
- package/dist/runtime/preprod/webCheck.js +0 -98
- package/dist/runtime/preprod/webCheck.js.map +0 -1
- package/dist/runtime/proxyConfig.d.ts +0 -6
- package/dist/runtime/proxyConfig.js +0 -86
- package/dist/runtime/proxyConfig.js.map +0 -1
- package/dist/runtime/proxyEnvironment.d.ts +0 -3
- package/dist/runtime/proxyEnvironment.js +0 -63
- package/dist/runtime/proxyEnvironment.js.map +0 -1
- package/dist/runtime/reportMerge.d.ts +0 -30
- package/dist/runtime/reportMerge.js +0 -70
- package/dist/runtime/reportMerge.js.map +0 -1
- package/dist/runtime/reporting/markdownReportBuilder.d.ts +0 -15
- package/dist/runtime/reporting/markdownReportBuilder.js +0 -97
- package/dist/runtime/reporting/markdownReportBuilder.js.map +0 -1
- package/dist/runtime/reporting/reportDataCollector.d.ts +0 -31
- package/dist/runtime/reporting/reportDataCollector.js +0 -170
- package/dist/runtime/reporting/reportDataCollector.js.map +0 -1
- package/dist/runtime/reporting/summaryGenerator.d.ts +0 -10
- package/dist/runtime/reporting/summaryGenerator.js +0 -67
- package/dist/runtime/reporting/summaryGenerator.js.map +0 -1
- package/dist/runtime/reviewPipeline.d.ts +0 -28
- package/dist/runtime/reviewPipeline.js +0 -122
- package/dist/runtime/reviewPipeline.js.map +0 -1
- package/dist/runtime/runAiCodeReview.d.ts +0 -10
- package/dist/runtime/runAiCodeReview.js +0 -138
- package/dist/runtime/runAiCodeReview.js.map +0 -1
- package/dist/runtime/runtimeConfig.d.ts +0 -4
- package/dist/runtime/runtimeConfig.js +0 -7
- package/dist/runtime/runtimeConfig.js.map +0 -1
- package/dist/runtime/ui/Layout.d.ts +0 -11
- package/dist/runtime/ui/Layout.js +0 -47
- package/dist/runtime/ui/Layout.js.map +0 -1
- package/dist/runtime/ui/RuntimeApp.d.ts +0 -6
- package/dist/runtime/ui/RuntimeApp.js +0 -161
- package/dist/runtime/ui/RuntimeApp.js.map +0 -1
- package/dist/runtime/ui/inkModules.d.ts +0 -10
- package/dist/runtime/ui/inkModules.js +0 -63
- package/dist/runtime/ui/inkModules.js.map +0 -1
- package/dist/runtime/ui/screens/AuthScreen.d.ts +0 -6
- package/dist/runtime/ui/screens/AuthScreen.js +0 -67
- package/dist/runtime/ui/screens/AuthScreen.js.map +0 -1
- package/dist/runtime/ui/screens/ModeSelection.d.ts +0 -10
- package/dist/runtime/ui/screens/ModeSelection.js +0 -100
- package/dist/runtime/ui/screens/ModeSelection.js.map +0 -1
- package/dist/runtime/ui/screens/ProgressScreen.d.ts +0 -7
- package/dist/runtime/ui/screens/ProgressScreen.js +0 -38
- package/dist/runtime/ui/screens/ProgressScreen.js.map +0 -1
- package/dist/runtime/ui/screens/ResultsScreen.d.ts +0 -7
- package/dist/runtime/ui/screens/ResultsScreen.js +0 -22
- package/dist/runtime/ui/screens/ResultsScreen.js.map +0 -1
- package/dist/strategies/ArchitecturalReviewStrategy.d.ts +0 -29
- package/dist/strategies/ArchitecturalReviewStrategy.js +0 -42
- package/dist/strategies/ArchitecturalReviewStrategy.js.map +0 -1
- package/dist/strategies/CodingTestReviewStrategy.d.ts +0 -194
- package/dist/strategies/CodingTestReviewStrategy.js +0 -681
- package/dist/strategies/CodingTestReviewStrategy.js.map +0 -1
- package/dist/strategies/ConsolidatedReviewStrategy.d.ts +0 -25
- package/dist/strategies/ConsolidatedReviewStrategy.js +0 -45
- package/dist/strategies/ConsolidatedReviewStrategy.js.map +0 -1
- package/dist/strategies/ExtractPatternsReviewStrategy.d.ts +0 -30
- package/dist/strategies/ExtractPatternsReviewStrategy.js +0 -51
- package/dist/strategies/ExtractPatternsReviewStrategy.js.map +0 -1
- package/dist/strategies/MultiPassReviewStrategy.d.ts +0 -86
- package/dist/strategies/MultiPassReviewStrategy.js +0 -590
- package/dist/strategies/MultiPassReviewStrategy.js.map +0 -1
- package/dist/strategies/ReviewStrategy.d.ts +0 -45
- package/dist/strategies/ReviewStrategy.js +0 -24
- package/dist/strategies/ReviewStrategy.js.map +0 -1
- package/dist/strategies/StrategyFactory.d.ts +0 -19
- package/dist/strategies/StrategyFactory.js +0 -72
- package/dist/strategies/StrategyFactory.js.map +0 -1
- package/dist/strategies/index.d.ts +0 -13
- package/dist/strategies/index.js +0 -30
- package/dist/strategies/index.js.map +0 -1
- package/dist/tokenizers/baseTokenizer.d.ts +0 -25
- package/dist/tokenizers/baseTokenizer.js +0 -48
- package/dist/tokenizers/baseTokenizer.js.map +0 -1
- package/dist/tokenizers/gptTokenizer.d.ts +0 -7
- package/dist/tokenizers/gptTokenizer.js +0 -28
- package/dist/tokenizers/gptTokenizer.js.map +0 -1
- package/dist/tokenizers/index.d.ts +0 -7
- package/dist/tokenizers/index.js +0 -24
- package/dist/tokenizers/index.js.map +0 -1
- package/dist/types/apiResponses.d.ts +0 -39
- package/dist/types/apiResponses.js +0 -9
- package/dist/types/apiResponses.js.map +0 -1
- package/dist/types/cli.d.ts +0 -22
- package/dist/types/cli.js +0 -3
- package/dist/types/cli.js.map +0 -1
- package/dist/types/common.d.ts +0 -22
- package/dist/types/common.js +0 -14
- package/dist/types/common.js.map +0 -1
- package/dist/types/configuration.d.ts +0 -682
- package/dist/types/configuration.js +0 -65
- package/dist/types/configuration.js.map +0 -1
- package/dist/types/review.d.ts +0 -258
- package/dist/types/review.js +0 -8
- package/dist/types/review.js.map +0 -1
- package/dist/types/reviewSchema.d.ts +0 -543
- package/dist/types/reviewSchema.js +0 -121
- package/dist/types/reviewSchema.js.map +0 -1
- package/dist/types/structuredReview.d.ts +0 -119
- package/dist/types/structuredReview.js +0 -6
- package/dist/types/structuredReview.js.map +0 -1
- package/dist/types/tokenAnalysis.d.ts +0 -44
- package/dist/types/tokenAnalysis.js +0 -4
- package/dist/types/tokenAnalysis.js.map +0 -1
- package/dist/utils/FileReader.d.ts +0 -33
- package/dist/utils/FileReader.js +0 -88
- package/dist/utils/FileReader.js.map +0 -1
- package/dist/utils/FileWriter.d.ts +0 -26
- package/dist/utils/FileWriter.js +0 -76
- package/dist/utils/FileWriter.js.map +0 -1
- package/dist/utils/PathGenerator.d.ts +0 -30
- package/dist/utils/PathGenerator.js +0 -82
- package/dist/utils/PathGenerator.js.map +0 -1
- package/dist/utils/api/apiUtils.d.ts +0 -3
- package/dist/utils/api/apiUtils.js +0 -20
- package/dist/utils/api/apiUtils.js.map +0 -1
- package/dist/utils/api/index.d.ts +0 -1
- package/dist/utils/api/index.js +0 -18
- package/dist/utils/api/index.js.map +0 -1
- package/dist/utils/apiErrorHandler.d.ts +0 -130
- package/dist/utils/apiErrorHandler.js +0 -256
- package/dist/utils/apiErrorHandler.js.map +0 -1
- package/dist/utils/ciDataCollector.d.ts +0 -51
- package/dist/utils/ciDataCollector.js +0 -197
- package/dist/utils/ciDataCollector.js.map +0 -1
- package/dist/utils/codingTestConfigLoader.d.ts +0 -66
- package/dist/utils/codingTestConfigLoader.js +0 -420
- package/dist/utils/codingTestConfigLoader.js.map +0 -1
- package/dist/utils/dependencies/aiDependencyAnalyzer.d.ts +0 -30
- package/dist/utils/dependencies/aiDependencyAnalyzer.js +0 -343
- package/dist/utils/dependencies/aiDependencyAnalyzer.js.map +0 -1
- package/dist/utils/detection/frameworkDetector.d.ts +0 -43
- package/dist/utils/detection/frameworkDetector.js +0 -795
- package/dist/utils/detection/frameworkDetector.js.map +0 -1
- package/dist/utils/detection/index.d.ts +0 -9
- package/dist/utils/detection/index.js +0 -28
- package/dist/utils/detection/index.js.map +0 -1
- package/dist/utils/detection/projectTypeDetector.d.ts +0 -27
- package/dist/utils/detection/projectTypeDetector.js +0 -469
- package/dist/utils/detection/projectTypeDetector.js.map +0 -1
- package/dist/utils/diagramGenerator.d.ts +0 -49
- package/dist/utils/diagramGenerator.js +0 -218
- package/dist/utils/diagramGenerator.js.map +0 -1
- package/dist/utils/errorLogger.d.ts +0 -24
- package/dist/utils/errorLogger.js +0 -59
- package/dist/utils/errorLogger.js.map +0 -1
- package/dist/utils/estimationUtils.d.ts +0 -139
- package/dist/utils/estimationUtils.js +0 -329
- package/dist/utils/estimationUtils.js.map +0 -1
- package/dist/utils/fileFilters.d.ts +0 -72
- package/dist/utils/fileFilters.js +0 -338
- package/dist/utils/fileFilters.js.map +0 -1
- package/dist/utils/fileSystem.d.ts +0 -22
- package/dist/utils/fileSystem.js +0 -45
- package/dist/utils/fileSystem.js.map +0 -1
- package/dist/utils/index.d.ts +0 -22
- package/dist/utils/index.js +0 -52
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -77
- package/dist/utils/logger.js +0 -271
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/pathValidator.d.ts +0 -40
- package/dist/utils/pathValidator.js +0 -98
- package/dist/utils/pathValidator.js.map +0 -1
- package/dist/utils/priorityFilter.d.ts +0 -34
- package/dist/utils/priorityFilter.js +0 -54
- package/dist/utils/priorityFilter.js.map +0 -1
- package/dist/utils/projectDocs.d.ts +0 -47
- package/dist/utils/projectDocs.js +0 -158
- package/dist/utils/projectDocs.js.map +0 -1
- package/dist/utils/promptPaths.d.ts +0 -6
- package/dist/utils/promptPaths.js +0 -33
- package/dist/utils/promptPaths.js.map +0 -1
- package/dist/utils/promptTemplateManager.d.ts +0 -34
- package/dist/utils/promptTemplateManager.js +0 -140
- package/dist/utils/promptTemplateManager.js.map +0 -1
- package/dist/utils/review/consolidateReview.d.ts +0 -15
- package/dist/utils/review/consolidateReview.js +0 -481
- package/dist/utils/review/consolidateReview.js.map +0 -1
- package/dist/utils/review/fixDisplay.d.ts +0 -20
- package/dist/utils/review/fixDisplay.js +0 -84
- package/dist/utils/review/fixDisplay.js.map +0 -1
- package/dist/utils/review/fixImplementation.d.ts +0 -28
- package/dist/utils/review/fixImplementation.js +0 -60
- package/dist/utils/review/fixImplementation.js.map +0 -1
- package/dist/utils/review/index.d.ts +0 -13
- package/dist/utils/review/index.js +0 -50
- package/dist/utils/review/index.js.map +0 -1
- package/dist/utils/review/interactiveProcessing.d.ts +0 -25
- package/dist/utils/review/interactiveProcessing.js +0 -251
- package/dist/utils/review/interactiveProcessing.js.map +0 -1
- package/dist/utils/review/progressTracker.d.ts +0 -106
- package/dist/utils/review/progressTracker.js +0 -227
- package/dist/utils/review/progressTracker.js.map +0 -1
- package/dist/utils/review/reviewExtraction.d.ts +0 -31
- package/dist/utils/review/reviewExtraction.js +0 -324
- package/dist/utils/review/reviewExtraction.js.map +0 -1
- package/dist/utils/review/types.d.ts +0 -45
- package/dist/utils/review/types.js +0 -18
- package/dist/utils/review/types.js.map +0 -1
- package/dist/utils/reviewActionHandler.d.ts +0 -16
- package/dist/utils/reviewActionHandler.js +0 -34
- package/dist/utils/reviewActionHandler.js.map +0 -1
- package/dist/utils/reviewParser.d.ts +0 -34
- package/dist/utils/reviewParser.js +0 -218
- package/dist/utils/reviewParser.js.map +0 -1
- package/dist/utils/sanitizer.d.ts +0 -82
- package/dist/utils/sanitizer.js +0 -239
- package/dist/utils/sanitizer.js.map +0 -1
- package/dist/utils/smartFileSelector.d.ts +0 -50
- package/dist/utils/smartFileSelector.js +0 -261
- package/dist/utils/smartFileSelector.js.map +0 -1
- package/dist/utils/templateLoader.d.ts +0 -44
- package/dist/utils/templateLoader.js +0 -431
- package/dist/utils/templateLoader.js.map +0 -1
- package/dist/utils/treeGenerator.d.ts +0 -12
- package/dist/utils/treeGenerator.js +0 -133
- package/dist/utils/treeGenerator.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import logger from './utils/logger';
|
|
3
2
|
import { ensureProxyEnvironmentInitialized } from './runtime/proxyEnvironment';
|
|
4
3
|
import { handleRuntimeCliEntry } from './runtime/cliEntry';
|
|
5
4
|
|
|
6
|
-
// Minimal bootstrap that wires the runtime CLI into the proxy-enabled environment.
|
|
7
|
-
|
|
8
5
|
async function bootstrap(): Promise<void> {
|
|
9
6
|
try {
|
|
10
7
|
ensureProxyEnvironmentInitialized(process.cwd());
|
package/src/runtime/cliEntry.ts
CHANGED
|
@@ -164,12 +164,30 @@ async function runDirect(options: DirectOptions): Promise<void> {
|
|
|
164
164
|
switch (stage) {
|
|
165
165
|
case 'collecting':
|
|
166
166
|
if (info?.filesFound !== undefined) {
|
|
167
|
-
|
|
167
|
+
const uncommitted = info.uncommittedFiles ?? info.filesFound;
|
|
168
|
+
const context = info.contextFiles ?? 0;
|
|
169
|
+
const breakdown = context ? ` (${uncommitted} uncommitted + ${context} context)` : '';
|
|
170
|
+
console.log(pc.green(`✓ Found ${info.filesFound} files${breakdown}`));
|
|
168
171
|
}
|
|
169
172
|
break;
|
|
170
|
-
case 'reviewing':
|
|
171
|
-
|
|
173
|
+
case 'reviewing': {
|
|
174
|
+
const context = info?.contextFiles ?? 0;
|
|
175
|
+
const base = info?.uncommittedFiles ?? info?.filesFound;
|
|
176
|
+
const suffix =
|
|
177
|
+
base || context
|
|
178
|
+
? ` (scope: ${base ?? '?'} uncommitted${context ? ` + ${context} context` : ''})`
|
|
179
|
+
: '';
|
|
180
|
+
const defaultLine = `Running AI review${suffix ? suffix : ''}...`;
|
|
181
|
+
const detailLine =
|
|
182
|
+
typeof info?.fileIndex === 'number' &&
|
|
183
|
+
typeof info.totalFiles === 'number' &&
|
|
184
|
+
info.totalFiles > 0 &&
|
|
185
|
+
info.currentFile
|
|
186
|
+
? `Running AI review ▸ ${info.fileIndex}/${info.totalFiles} ${info.currentFile}${suffix}`
|
|
187
|
+
: defaultLine;
|
|
188
|
+
console.log(pc.blue(detailLine));
|
|
172
189
|
break;
|
|
190
|
+
}
|
|
173
191
|
case 'merging':
|
|
174
192
|
console.log(pc.blue('Merging reports...'));
|
|
175
193
|
break;
|
|
@@ -1,15 +1,32 @@
|
|
|
1
|
-
import { existsSync, statSync } from 'node:fs';
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import {
|
|
3
|
+
relative as relativePath,
|
|
4
|
+
resolve as resolvePath,
|
|
5
|
+
isAbsolute as isAbsolutePath,
|
|
6
|
+
join as joinPath,
|
|
7
|
+
dirname as dirnamePath,
|
|
8
|
+
} from 'node:path';
|
|
3
9
|
import { execa } from 'execa';
|
|
4
10
|
import { MissingCrIgnoreError } from './errors';
|
|
5
11
|
|
|
12
|
+
export interface FileCollectionStats {
|
|
13
|
+
uncommitted: number;
|
|
14
|
+
context: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface FileCollectionResult {
|
|
18
|
+
targets: string[];
|
|
19
|
+
context: string[];
|
|
20
|
+
stats: FileCollectionStats;
|
|
21
|
+
}
|
|
22
|
+
|
|
6
23
|
export type FileCollectionMode = 'uncommitted' | 'preprod';
|
|
7
24
|
|
|
8
25
|
export interface CollectFilesOptions {
|
|
9
26
|
mode?: FileCollectionMode;
|
|
10
27
|
}
|
|
11
28
|
|
|
12
|
-
export async function collectFiles(options: CollectFilesOptions = {}): Promise<
|
|
29
|
+
export async function collectFiles(options: CollectFilesOptions = {}): Promise<FileCollectionResult> {
|
|
13
30
|
try {
|
|
14
31
|
const { stdout: rootOut } = await execa('git', ['rev-parse', '--show-toplevel']);
|
|
15
32
|
const repoRoot = resolvePath(rootOut.trim());
|
|
@@ -115,8 +132,22 @@ export async function collectFiles(options: CollectFilesOptions = {}): Promise<s
|
|
|
115
132
|
.map((file) => normalize(file))
|
|
116
133
|
.filter((file): file is string => Boolean(file));
|
|
117
134
|
|
|
118
|
-
const
|
|
119
|
-
|
|
135
|
+
const baseSet = new Set(resolved);
|
|
136
|
+
const { combinedFiles, extras } = await augmentWithContext(resolved, workspaceRoot);
|
|
137
|
+
const extraSet = new Set(extras);
|
|
138
|
+
|
|
139
|
+
const gitFiltered = await excludeIgnored(repoRoot, combinedFiles);
|
|
140
|
+
const finalFiles = await excludeCrIgnored(workspaceRoot, crIgnorePath, gitFiltered);
|
|
141
|
+
|
|
142
|
+
const targets = finalFiles.filter((file) => baseSet.has(file));
|
|
143
|
+
const contextFiles = finalFiles.filter((file) => extraSet.has(file) && !baseSet.has(file));
|
|
144
|
+
|
|
145
|
+
const stats: FileCollectionStats = {
|
|
146
|
+
uncommitted: targets.length,
|
|
147
|
+
context: contextFiles.length,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return { targets, context: contextFiles, stats };
|
|
120
151
|
} catch (error: any) {
|
|
121
152
|
if (error.message?.includes('not a git repository')) {
|
|
122
153
|
throw new Error('Not a git repository. Please run this command from a git repository root.');
|
|
@@ -125,6 +156,248 @@ export async function collectFiles(options: CollectFilesOptions = {}): Promise<s
|
|
|
125
156
|
}
|
|
126
157
|
}
|
|
127
158
|
|
|
159
|
+
const CONTEXT_FILENAMES = [
|
|
160
|
+
'README.md',
|
|
161
|
+
'readme.md',
|
|
162
|
+
'README',
|
|
163
|
+
'README.mdx',
|
|
164
|
+
'CHANGELOG.md',
|
|
165
|
+
'changelog.md',
|
|
166
|
+
'HISTORY.md',
|
|
167
|
+
'history.md',
|
|
168
|
+
'package.json',
|
|
169
|
+
'.env.example',
|
|
170
|
+
'.env.sample',
|
|
171
|
+
'.env.template',
|
|
172
|
+
'.env.local.example',
|
|
173
|
+
'.env.production.example',
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
const DEPENDENCY_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts'];
|
|
177
|
+
const MAX_CONTEXT_FILE_BYTES = 200 * 1024; // 200KB guardrail
|
|
178
|
+
|
|
179
|
+
async function augmentWithContext(
|
|
180
|
+
files: string[],
|
|
181
|
+
workspaceRoot: string,
|
|
182
|
+
): Promise<{ combinedFiles: string[]; extras: string[] }> {
|
|
183
|
+
if (files.length === 0) {
|
|
184
|
+
return { combinedFiles: files, extras: [] };
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const baseSet = new Set(files);
|
|
188
|
+
const contextFiles = collectContextFiles(files, workspaceRoot);
|
|
189
|
+
const dependencyFiles = collectDependencyFiles(files, workspaceRoot);
|
|
190
|
+
const localMarkdownFiles = collectLocalMarkdownFiles(files);
|
|
191
|
+
const globalNamedFiles = await collectGlobalNamedContext(workspaceRoot);
|
|
192
|
+
|
|
193
|
+
const extras = Array.from(
|
|
194
|
+
new Set(
|
|
195
|
+
[...contextFiles, ...dependencyFiles, ...localMarkdownFiles, ...globalNamedFiles].filter(
|
|
196
|
+
(file) => !baseSet.has(file),
|
|
197
|
+
),
|
|
198
|
+
),
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const combinedFiles = Array.from(new Set([...files, ...extras]));
|
|
202
|
+
return { combinedFiles, extras };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function collectContextFiles(files: string[], workspaceRoot: string): string[] {
|
|
206
|
+
const extras = new Set<string>();
|
|
207
|
+
const candidateDirs = new Set<string>();
|
|
208
|
+
files.forEach((file) => candidateDirs.add(dirnamePath(file)));
|
|
209
|
+
candidateDirs.add(workspaceRoot);
|
|
210
|
+
|
|
211
|
+
for (const dir of candidateDirs) {
|
|
212
|
+
for (const filename of CONTEXT_FILENAMES) {
|
|
213
|
+
const candidate = joinPath(dir, filename);
|
|
214
|
+
if (!candidate.startsWith(workspaceRoot)) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
const stats = statSync(candidate);
|
|
219
|
+
if (stats.isFile() && stats.size <= MAX_CONTEXT_FILE_BYTES && isTextFile(candidate)) {
|
|
220
|
+
extras.add(candidate);
|
|
221
|
+
}
|
|
222
|
+
} catch {
|
|
223
|
+
// ignored
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return Array.from(extras);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function collectDependencyFiles(files: string[], workspaceRoot: string): string[] {
|
|
232
|
+
const extras = new Set<string>();
|
|
233
|
+
|
|
234
|
+
for (const file of files) {
|
|
235
|
+
if (!isDependencyCandidate(file)) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let content: string;
|
|
240
|
+
try {
|
|
241
|
+
content = readFileSync(file, 'utf-8');
|
|
242
|
+
} catch {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const specifiers = extractImportSpecifiers(content);
|
|
247
|
+
if (specifiers.length === 0) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const baseDir = dirnamePath(file);
|
|
252
|
+
for (const specifier of specifiers) {
|
|
253
|
+
const resolved = resolveImportSpecifier(specifier, baseDir, workspaceRoot);
|
|
254
|
+
if (resolved) {
|
|
255
|
+
extras.add(resolved);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return Array.from(extras);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function isDependencyCandidate(filePath: string): boolean {
|
|
264
|
+
const lower = filePath.toLowerCase();
|
|
265
|
+
return DEPENDENCY_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function extractImportSpecifiers(content: string): string[] {
|
|
269
|
+
const specifiers = new Set<string>();
|
|
270
|
+
const patterns = [
|
|
271
|
+
/import\s+[^;]*?from\s+['"]([^'"\n]+)['"]/g,
|
|
272
|
+
/import\s+['"]([^'"\n]+)['"]/g,
|
|
273
|
+
/export\s+[^;]*?from\s+['"]([^'"\n]+)['"]/g,
|
|
274
|
+
/require\(\s*['"]([^'"\n]+)['"]\s*\)/g,
|
|
275
|
+
/import\(\s*['"]([^'"\n]+)['"]\s*\)/g,
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
for (const pattern of patterns) {
|
|
279
|
+
let match: RegExpExecArray | null;
|
|
280
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
281
|
+
const spec = match[1];
|
|
282
|
+
if (spec && spec.startsWith('.')) {
|
|
283
|
+
specifiers.add(spec);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return Array.from(specifiers);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function resolveImportSpecifier(
|
|
292
|
+
specifier: string,
|
|
293
|
+
baseDir: string,
|
|
294
|
+
workspaceRoot: string,
|
|
295
|
+
): string | null {
|
|
296
|
+
const cleaned = specifier.replace(/[#?].*$/, '');
|
|
297
|
+
const resolvedBase = resolvePath(baseDir, cleaned);
|
|
298
|
+
const candidates = new Set<string>([resolvedBase]);
|
|
299
|
+
|
|
300
|
+
const hasExtension = DEPENDENCY_EXTENSIONS.some((ext) => resolvedBase.endsWith(ext));
|
|
301
|
+
if (!hasExtension) {
|
|
302
|
+
for (const ext of DEPENDENCY_EXTENSIONS) {
|
|
303
|
+
candidates.add(`${resolvedBase}${ext}`);
|
|
304
|
+
candidates.add(joinPath(resolvedBase, `index${ext}`));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
for (const candidate of candidates) {
|
|
309
|
+
if (!candidate.startsWith(workspaceRoot)) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
const stats = statSync(candidate);
|
|
314
|
+
if (stats.isFile()) {
|
|
315
|
+
return candidate;
|
|
316
|
+
}
|
|
317
|
+
} catch {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function collectLocalMarkdownFiles(files: string[]): string[] {
|
|
326
|
+
const extras = new Set<string>();
|
|
327
|
+
const dirs = new Set<string>();
|
|
328
|
+
files.forEach((file) => dirs.add(dirnamePath(file)));
|
|
329
|
+
|
|
330
|
+
for (const dir of dirs) {
|
|
331
|
+
let entries;
|
|
332
|
+
try {
|
|
333
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
334
|
+
} catch {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
for (const entry of entries) {
|
|
339
|
+
if (!entry.isFile()) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const lower = entry.name.toLowerCase();
|
|
344
|
+
if (!lower.endsWith('.md') && !lower.endsWith('.mdx')) {
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const fullPath = joinPath(dir, entry.name);
|
|
349
|
+
try {
|
|
350
|
+
const stats = statSync(fullPath);
|
|
351
|
+
if (stats.isFile() && stats.size <= MAX_CONTEXT_FILE_BYTES && isTextFile(fullPath)) {
|
|
352
|
+
extras.add(fullPath);
|
|
353
|
+
}
|
|
354
|
+
} catch {
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return Array.from(extras);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
async function collectGlobalNamedContext(workspaceRoot: string): Promise<string[]> {
|
|
364
|
+
try {
|
|
365
|
+
const pathspecs = CONTEXT_FILENAMES.map((name) => `:(glob)**/${name}`);
|
|
366
|
+
const { stdout } = await execa('git', ['ls-files', '-z', '--', ...pathspecs], {
|
|
367
|
+
cwd: workspaceRoot,
|
|
368
|
+
reject: false,
|
|
369
|
+
});
|
|
370
|
+
if (!stdout) {
|
|
371
|
+
return [];
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return stdout
|
|
375
|
+
.split('\0')
|
|
376
|
+
.filter(Boolean)
|
|
377
|
+
.map((rel) => resolvePath(workspaceRoot, rel))
|
|
378
|
+
.filter((abs) => {
|
|
379
|
+
try {
|
|
380
|
+
const stats = statSync(abs);
|
|
381
|
+
return stats.isFile() && stats.size <= MAX_CONTEXT_FILE_BYTES && isTextFile(abs);
|
|
382
|
+
} catch {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
} catch {
|
|
387
|
+
return [];
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function isTextFile(filePath: string): boolean {
|
|
392
|
+
try {
|
|
393
|
+
const buffer = readFileSync(filePath);
|
|
394
|
+
const sample = buffer.subarray(0, 4096);
|
|
395
|
+
return !sample.includes(0);
|
|
396
|
+
} catch {
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
128
401
|
async function listTrackedFiles(repoRoot: string, pathSpec: string): Promise<string[]> {
|
|
129
402
|
const { stdout } = await execa('git', ['ls-files', '-z', '--', pathSpec], {
|
|
130
403
|
cwd: repoRoot,
|
|
@@ -15,13 +15,22 @@ import logger from '../utils/logger';
|
|
|
15
15
|
export type ReviewStage = 'preparing' | 'collecting' | 'reviewing' | 'merging';
|
|
16
16
|
export type ReviewMode = FileCollectionMode;
|
|
17
17
|
|
|
18
|
+
export interface StageUpdate {
|
|
19
|
+
filesFound?: number;
|
|
20
|
+
currentFile?: string;
|
|
21
|
+
fileIndex?: number;
|
|
22
|
+
totalFiles?: number;
|
|
23
|
+
uncommittedFiles?: number;
|
|
24
|
+
contextFiles?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
export interface ReviewOptions {
|
|
19
28
|
model: string;
|
|
20
29
|
outDir: string;
|
|
21
30
|
debug?: boolean;
|
|
22
31
|
mode?: ReviewMode;
|
|
23
32
|
preprodTargetUrl?: string;
|
|
24
|
-
onStage?: (stage: ReviewStage, info?:
|
|
33
|
+
onStage?: (stage: ReviewStage, info?: StageUpdate) => void;
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
export interface ReviewTotals {
|
|
@@ -37,6 +46,8 @@ export interface ReviewResult {
|
|
|
37
46
|
duration: number;
|
|
38
47
|
repo: string;
|
|
39
48
|
filesReviewed: number;
|
|
49
|
+
fileBreakdown?: { uncommitted: number; context: number };
|
|
50
|
+
reportSummary?: string;
|
|
40
51
|
reportPath?: string;
|
|
41
52
|
}
|
|
42
53
|
|
|
@@ -45,14 +56,18 @@ export async function executeReview(options: ReviewOptions): Promise<ReviewResul
|
|
|
45
56
|
|
|
46
57
|
onStage?.('collecting');
|
|
47
58
|
logger.info('Collecting files for review', { mode, workspace: process.cwd() });
|
|
48
|
-
const
|
|
49
|
-
const fileCount =
|
|
59
|
+
const { targets, context, stats } = await collectFiles({ mode });
|
|
60
|
+
const fileCount = targets.length;
|
|
50
61
|
|
|
51
62
|
if (fileCount === 0) {
|
|
52
63
|
throw new Error('No files to review');
|
|
53
64
|
}
|
|
54
65
|
|
|
55
|
-
onStage?.('collecting', {
|
|
66
|
+
onStage?.('collecting', {
|
|
67
|
+
filesFound: fileCount,
|
|
68
|
+
uncommittedFiles: stats.uncommitted,
|
|
69
|
+
contextFiles: stats.context,
|
|
70
|
+
});
|
|
56
71
|
logger.info('File collection complete', { fileCount });
|
|
57
72
|
|
|
58
73
|
const workspaceRoot = process.cwd();
|
|
@@ -70,9 +85,15 @@ export async function executeReview(options: ReviewOptions): Promise<ReviewResul
|
|
|
70
85
|
|
|
71
86
|
const start = Date.now();
|
|
72
87
|
|
|
88
|
+
const repoName = basename(workspaceRoot) || 'workspace';
|
|
73
89
|
try {
|
|
74
|
-
onStage?.('reviewing', {
|
|
75
|
-
|
|
90
|
+
onStage?.('reviewing', {
|
|
91
|
+
filesFound: fileCount,
|
|
92
|
+
totalFiles: fileCount,
|
|
93
|
+
uncommittedFiles: stats.uncommitted,
|
|
94
|
+
contextFiles: stats.context,
|
|
95
|
+
});
|
|
96
|
+
const reports = await runAiCodeReview(targets, context, {
|
|
76
97
|
provider: 'openrouter',
|
|
77
98
|
type: 'comprehensive',
|
|
78
99
|
outDir: rawOutDir,
|
|
@@ -80,6 +101,22 @@ export async function executeReview(options: ReviewOptions): Promise<ReviewResul
|
|
|
80
101
|
model,
|
|
81
102
|
configPath: manifestPath,
|
|
82
103
|
debug,
|
|
104
|
+
runContext: {
|
|
105
|
+
repoName,
|
|
106
|
+
reviewMode: mode,
|
|
107
|
+
totalFiles: fileCount,
|
|
108
|
+
uncommittedFiles: stats.uncommitted,
|
|
109
|
+
contextFiles: stats.context,
|
|
110
|
+
},
|
|
111
|
+
onFileProgress: ({ file, index, total }) =>
|
|
112
|
+
onStage?.('reviewing', {
|
|
113
|
+
filesFound: fileCount,
|
|
114
|
+
currentFile: file,
|
|
115
|
+
fileIndex: index,
|
|
116
|
+
totalFiles: total,
|
|
117
|
+
uncommittedFiles: stats.uncommitted,
|
|
118
|
+
contextFiles: stats.context,
|
|
119
|
+
}),
|
|
83
120
|
});
|
|
84
121
|
|
|
85
122
|
onStage?.('merging');
|
|
@@ -88,7 +125,7 @@ export async function executeReview(options: ReviewOptions): Promise<ReviewResul
|
|
|
88
125
|
(merged?.totals as ReviewTotals) || ({ critical: 0, high: 0, medium: 0, low: 0 } as ReviewTotals);
|
|
89
126
|
const findings = (merged?.findings as any[]) || [];
|
|
90
127
|
|
|
91
|
-
const repo =
|
|
128
|
+
const repo = repoName;
|
|
92
129
|
const duration = Math.round((Date.now() - start) / 1000);
|
|
93
130
|
const reportTimestamp = new Date();
|
|
94
131
|
|
|
@@ -125,6 +162,8 @@ export async function executeReview(options: ReviewOptions): Promise<ReviewResul
|
|
|
125
162
|
duration,
|
|
126
163
|
repo,
|
|
127
164
|
filesReviewed: fileCount,
|
|
165
|
+
fileBreakdown: { uncommitted: stats.uncommitted, context: stats.context },
|
|
166
|
+
reportSummary: summary,
|
|
128
167
|
reportPath,
|
|
129
168
|
};
|
|
130
169
|
} finally {
|
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
import { join, relative, resolve } from 'node:path';
|
|
3
4
|
import { execa } from 'execa';
|
|
4
5
|
import type { OutputFormat } from '../types/common';
|
|
5
|
-
import type { ReviewOptions, ReviewType } from '../types/review';
|
|
6
|
+
import type { ReviewOptions, ReviewType, RunContext } from '../types/review';
|
|
6
7
|
import { orchestrateReview } from '../core/reviewOrchestrator';
|
|
7
8
|
import { RUNTIME_CONFIG } from './runtimeConfig';
|
|
8
9
|
|
|
10
|
+
interface FileProgressPayload {
|
|
11
|
+
file: string;
|
|
12
|
+
index: number;
|
|
13
|
+
total: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ReviewGroup {
|
|
17
|
+
label: string;
|
|
18
|
+
files: string[];
|
|
19
|
+
absoluteFiles: string[];
|
|
20
|
+
targetPath: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const MAX_FILES_PER_GROUP = 5;
|
|
24
|
+
const MAX_CONTEXT_DOCS_PER_GROUP = 5;
|
|
25
|
+
const MAX_CONTEXT_DOC_CHARS = 2000;
|
|
26
|
+
|
|
27
|
+
interface ContextDocEntry {
|
|
28
|
+
path: string;
|
|
29
|
+
relativePath: string;
|
|
30
|
+
snippet: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
9
33
|
export interface AiReviewOptions {
|
|
10
34
|
provider: 'openrouter';
|
|
11
35
|
type: string;
|
|
@@ -14,10 +38,16 @@ export interface AiReviewOptions {
|
|
|
14
38
|
model?: string;
|
|
15
39
|
configPath?: string;
|
|
16
40
|
debug?: boolean;
|
|
41
|
+
onFileProgress?: (payload: FileProgressPayload) => void;
|
|
42
|
+
runContext?: RunContext;
|
|
17
43
|
}
|
|
18
44
|
|
|
19
|
-
export async function runAiCodeReview(
|
|
20
|
-
|
|
45
|
+
export async function runAiCodeReview(
|
|
46
|
+
targetFiles: string[],
|
|
47
|
+
contextFiles: string[],
|
|
48
|
+
opts: AiReviewOptions,
|
|
49
|
+
): Promise<any[]> {
|
|
50
|
+
if (targetFiles.length === 0) return [];
|
|
21
51
|
|
|
22
52
|
const workspaceRoot = process.cwd();
|
|
23
53
|
let repoRoot: string;
|
|
@@ -68,7 +98,7 @@ export async function runAiCodeReview(files: string[], opts: AiReviewOptions): P
|
|
|
68
98
|
}
|
|
69
99
|
|
|
70
100
|
const expandedFiles: string[] = [];
|
|
71
|
-
for (const file of
|
|
101
|
+
for (const file of targetFiles) {
|
|
72
102
|
const absPath = resolve(file);
|
|
73
103
|
try {
|
|
74
104
|
const stats = statSync(absPath);
|
|
@@ -144,10 +174,135 @@ export async function runAiCodeReview(files: string[], opts: AiReviewOptions): P
|
|
|
144
174
|
baseOptions.config = opts.configPath;
|
|
145
175
|
}
|
|
146
176
|
|
|
147
|
-
|
|
148
|
-
|
|
177
|
+
const groups = createReviewGroups(targets, workspaceRoot);
|
|
178
|
+
const contextDocEntries = prepareContextDocs(contextFiles, workspaceRoot);
|
|
179
|
+
const totalFiles = targets.length;
|
|
180
|
+
let processedCount = 0;
|
|
181
|
+
|
|
182
|
+
const groupCount = groups.length;
|
|
183
|
+
for (let groupIdx = 0; groupIdx < groups.length; groupIdx += 1) {
|
|
184
|
+
const group = groups[groupIdx];
|
|
185
|
+
const progressIndex = Math.min(processedCount + 1, totalFiles);
|
|
186
|
+
const displayName = formatGroupDisplay(group.files);
|
|
187
|
+
opts.onFileProgress?.({ file: displayName, index: progressIndex, total: totalFiles });
|
|
188
|
+
|
|
189
|
+
const selectedContextDocs = selectContextDocs(group.files, contextDocEntries);
|
|
190
|
+
const inheritedContext = opts.runContext;
|
|
191
|
+
const runContext = inheritedContext
|
|
192
|
+
? {
|
|
193
|
+
...inheritedContext,
|
|
194
|
+
groupIndex: groupIdx + 1,
|
|
195
|
+
groupCount,
|
|
196
|
+
groupLabel: group.label,
|
|
197
|
+
groupFiles: group.files,
|
|
198
|
+
docFiles: selectedContextDocs.map((doc) => doc.relativePath),
|
|
199
|
+
contextDocs: selectedContextDocs.map((doc) => ({
|
|
200
|
+
path: doc.relativePath,
|
|
201
|
+
snippet: doc.snippet,
|
|
202
|
+
})),
|
|
203
|
+
}
|
|
204
|
+
: undefined;
|
|
205
|
+
|
|
206
|
+
await orchestrateReview(group.targetPath, {
|
|
207
|
+
...baseOptions,
|
|
208
|
+
targetFileList: group.absoluteFiles,
|
|
209
|
+
runContext,
|
|
210
|
+
});
|
|
211
|
+
processedCount += group.files.length;
|
|
149
212
|
collectOutputs();
|
|
150
213
|
}
|
|
151
214
|
|
|
152
215
|
return outputs;
|
|
153
216
|
}
|
|
217
|
+
|
|
218
|
+
function createReviewGroups(targets: string[], workspaceRoot: string): ReviewGroup[] {
|
|
219
|
+
const directoryMap = new Map<string, string[]>();
|
|
220
|
+
for (const target of targets) {
|
|
221
|
+
const dir = path.posix.dirname(target) || '.';
|
|
222
|
+
if (!directoryMap.has(dir)) {
|
|
223
|
+
directoryMap.set(dir, []);
|
|
224
|
+
}
|
|
225
|
+
directoryMap.get(dir)!.push(target);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const groups: ReviewGroup[] = [];
|
|
229
|
+
for (const [dir, files] of directoryMap) {
|
|
230
|
+
for (let i = 0; i < files.length; i += MAX_FILES_PER_GROUP) {
|
|
231
|
+
const chunk = files.slice(i, i + MAX_FILES_PER_GROUP);
|
|
232
|
+
const absoluteFiles = chunk.map((file) => resolve(workspaceRoot, file));
|
|
233
|
+
const targetPath = dir === '.' ? chunk[0] ?? '.' : dir;
|
|
234
|
+
groups.push({
|
|
235
|
+
label: dir,
|
|
236
|
+
files: chunk,
|
|
237
|
+
absoluteFiles,
|
|
238
|
+
targetPath,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return groups;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function formatGroupDisplay(files: string[]): string {
|
|
247
|
+
if (files.length === 0) {
|
|
248
|
+
return 'pending files';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (files.length === 1) {
|
|
252
|
+
return files[0];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return `${files[0]} (+${files.length - 1} more)`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function prepareContextDocs(contextFiles: string[], workspaceRoot: string): ContextDocEntry[] {
|
|
259
|
+
const docs: ContextDocEntry[] = [];
|
|
260
|
+
const seen = new Set<string>();
|
|
261
|
+
|
|
262
|
+
for (const file of contextFiles) {
|
|
263
|
+
const absPath = resolve(file);
|
|
264
|
+
if (seen.has(absPath)) continue;
|
|
265
|
+
seen.add(absPath);
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const stats = statSync(absPath);
|
|
269
|
+
if (!stats.isFile()) continue;
|
|
270
|
+
const buffer = readFileSync(absPath);
|
|
271
|
+
if (buffer.length === 0 || buffer.includes(0)) continue;
|
|
272
|
+
const snippet = buffer.toString('utf-8').slice(0, MAX_CONTEXT_DOC_CHARS);
|
|
273
|
+
const relativePath = relative(workspaceRoot, absPath).replace(/\\/g, '/');
|
|
274
|
+
if (!relativePath || relativePath.startsWith('..')) continue;
|
|
275
|
+
docs.push({ path: absPath, relativePath, snippet });
|
|
276
|
+
} catch {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return docs;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function selectContextDocs(
|
|
285
|
+
groupFiles: string[],
|
|
286
|
+
docs: ContextDocEntry[],
|
|
287
|
+
limit = MAX_CONTEXT_DOCS_PER_GROUP,
|
|
288
|
+
): ContextDocEntry[] {
|
|
289
|
+
if (docs.length === 0 || limit <= 0) {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const groupDirs = new Set(groupFiles.map((file) => path.posix.dirname(file)));
|
|
294
|
+
const prioritized: ContextDocEntry[] = [];
|
|
295
|
+
const remaining: ContextDocEntry[] = [];
|
|
296
|
+
|
|
297
|
+
for (const doc of docs) {
|
|
298
|
+
const docDir = path.posix.dirname(doc.relativePath);
|
|
299
|
+
if (groupDirs.has(docDir)) {
|
|
300
|
+
prioritized.push(doc);
|
|
301
|
+
} else {
|
|
302
|
+
remaining.push(doc);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const ordered = [...prioritized, ...remaining];
|
|
307
|
+
return ordered.slice(0, limit);
|
|
308
|
+
}
|