codereview-aia 0.1.0 → 0.1.2
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/analysis/FindingsExtractor.d.ts +105 -0
- package/dist/analysis/FindingsExtractor.js +363 -0
- package/dist/analysis/FindingsExtractor.js.map +1 -0
- package/dist/analysis/ai-detection/analyzers/BaseAnalyzer.d.ts +111 -0
- package/dist/analysis/ai-detection/analyzers/BaseAnalyzer.js +215 -0
- package/dist/analysis/ai-detection/analyzers/BaseAnalyzer.js.map +1 -0
- package/dist/analysis/ai-detection/analyzers/DocumentationAnalyzer.d.ts +142 -0
- package/dist/analysis/ai-detection/analyzers/DocumentationAnalyzer.js +503 -0
- package/dist/analysis/ai-detection/analyzers/DocumentationAnalyzer.js.map +1 -0
- package/dist/analysis/ai-detection/analyzers/GitHistoryAnalyzer.d.ts +88 -0
- package/dist/analysis/ai-detection/analyzers/GitHistoryAnalyzer.js +343 -0
- package/dist/analysis/ai-detection/analyzers/GitHistoryAnalyzer.js.map +1 -0
- package/dist/analysis/ai-detection/core/AIDetectionEngine.d.ts +104 -0
- package/dist/analysis/ai-detection/core/AIDetectionEngine.js +369 -0
- package/dist/analysis/ai-detection/core/AIDetectionEngine.js.map +1 -0
- package/dist/analysis/ai-detection/types/DetectionTypes.d.ts +364 -0
- package/dist/analysis/ai-detection/types/DetectionTypes.js +32 -0
- package/dist/analysis/ai-detection/types/DetectionTypes.js.map +1 -0
- package/dist/analysis/ai-detection/utils/SubmissionConverter.d.ts +97 -0
- package/dist/analysis/ai-detection/utils/SubmissionConverter.js +339 -0
- package/dist/analysis/ai-detection/utils/SubmissionConverter.js.map +1 -0
- package/dist/analysis/context/ReviewContext.d.ts +184 -0
- package/dist/analysis/context/ReviewContext.js +294 -0
- package/dist/analysis/context/ReviewContext.js.map +1 -0
- package/dist/analysis/context/index.d.ts +6 -0
- package/dist/analysis/context/index.js +23 -0
- package/dist/analysis/context/index.js.map +1 -0
- package/dist/analysis/index.d.ts +7 -0
- package/dist/analysis/index.js +24 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/tokens/TokenAnalysisFormatter.d.ts +27 -0
- package/dist/analysis/tokens/TokenAnalysisFormatter.js +143 -0
- package/dist/analysis/tokens/TokenAnalysisFormatter.js.map +1 -0
- package/dist/analysis/tokens/TokenAnalyzer.d.ts +155 -0
- package/dist/analysis/tokens/TokenAnalyzer.js +502 -0
- package/dist/analysis/tokens/TokenAnalyzer.js.map +1 -0
- package/dist/analysis/tokens/index.d.ts +7 -0
- package/dist/analysis/tokens/index.js +24 -0
- package/dist/analysis/tokens/index.js.map +1 -0
- package/dist/clients/base/abstractClient.d.ts +99 -0
- package/dist/clients/base/abstractClient.js +98 -0
- package/dist/clients/base/abstractClient.js.map +1 -0
- package/dist/clients/base/httpClient.d.ts +24 -0
- package/dist/clients/base/httpClient.js +147 -0
- package/dist/clients/base/httpClient.js.map +1 -0
- package/dist/clients/base/index.d.ts +11 -0
- package/dist/clients/base/index.js +28 -0
- package/dist/clients/base/index.js.map +1 -0
- package/dist/clients/base/modelDetection.d.ts +41 -0
- package/dist/clients/base/modelDetection.js +88 -0
- package/dist/clients/base/modelDetection.js.map +1 -0
- package/dist/clients/base/responseProcessor.d.ts +45 -0
- package/dist/clients/base/responseProcessor.js +495 -0
- package/dist/clients/base/responseProcessor.js.map +1 -0
- package/dist/clients/factory/clientFactory.d.ts +23 -0
- package/dist/clients/factory/clientFactory.js +50 -0
- package/dist/clients/factory/clientFactory.js.map +1 -0
- package/dist/clients/factory/index.d.ts +7 -0
- package/dist/clients/factory/index.js +24 -0
- package/dist/clients/factory/index.js.map +1 -0
- package/dist/clients/implementations/index.d.ts +7 -0
- package/dist/clients/implementations/index.js +24 -0
- package/dist/clients/implementations/index.js.map +1 -0
- package/dist/clients/implementations/openRouterClient.d.ts +69 -0
- package/dist/clients/implementations/openRouterClient.js +294 -0
- package/dist/clients/implementations/openRouterClient.js.map +1 -0
- package/dist/clients/openRouterClient.d.ts +42 -0
- package/dist/clients/openRouterClient.js +738 -0
- package/dist/clients/openRouterClient.js.map +1 -0
- package/dist/clients/openRouterClientWrapper.d.ts +22 -0
- package/dist/clients/openRouterClientWrapper.js +64 -0
- package/dist/clients/openRouterClientWrapper.js.map +1 -0
- package/dist/clients/utils/directoryStructure.d.ts +14 -0
- package/dist/clients/utils/directoryStructure.js +48 -0
- package/dist/clients/utils/directoryStructure.js.map +1 -0
- package/dist/clients/utils/index.d.ts +10 -0
- package/dist/clients/utils/index.js +31 -0
- package/dist/clients/utils/index.js.map +1 -0
- package/dist/clients/utils/languageDetection.d.ts +13 -0
- package/dist/clients/utils/languageDetection.js +46 -0
- package/dist/clients/utils/languageDetection.js.map +1 -0
- package/dist/clients/utils/promptFormatter.d.ts +36 -0
- package/dist/clients/utils/promptFormatter.js +92 -0
- package/dist/clients/utils/promptFormatter.js.map +1 -0
- package/dist/clients/utils/promptLoader.d.ts +27 -0
- package/dist/clients/utils/promptLoader.js +49 -0
- package/dist/clients/utils/promptLoader.js.map +1 -0
- package/dist/clients/utils/tokenCounter.d.ts +81 -0
- package/dist/clients/utils/tokenCounter.js +209 -0
- package/dist/clients/utils/tokenCounter.js.map +1 -0
- package/dist/core/ApiClientSelector.d.ts +8 -0
- package/dist/core/ApiClientSelector.js +29 -0
- package/dist/core/ApiClientSelector.js.map +1 -0
- package/dist/core/ConfigurationService.d.ts +286 -0
- package/dist/core/ConfigurationService.js +477 -0
- package/dist/core/ConfigurationService.js.map +1 -0
- package/dist/core/ConsolidationService.d.ts +99 -0
- package/dist/core/ConsolidationService.js +341 -0
- package/dist/core/ConsolidationService.js.map +1 -0
- package/dist/core/InteractiveDisplayManager.d.ts +22 -0
- package/dist/core/InteractiveDisplayManager.js +70 -0
- package/dist/core/InteractiveDisplayManager.js.map +1 -0
- package/dist/core/OutputManager.d.ts +26 -0
- package/dist/core/OutputManager.js +217 -0
- package/dist/core/OutputManager.js.map +1 -0
- package/dist/core/ReviewGenerator.d.ts +13 -0
- package/dist/core/ReviewGenerator.js +102 -0
- package/dist/core/ReviewGenerator.js.map +1 -0
- package/dist/core/fileDiscovery.d.ts +35 -0
- package/dist/core/fileDiscovery.js +202 -0
- package/dist/core/fileDiscovery.js.map +1 -0
- package/dist/core/handlers/EstimationHandler.d.ts +18 -0
- package/dist/core/handlers/EstimationHandler.js +110 -0
- package/dist/core/handlers/EstimationHandler.js.map +1 -0
- package/dist/core/handlers/FileProcessingHandler.d.ts +31 -0
- package/dist/core/handlers/FileProcessingHandler.js +159 -0
- package/dist/core/handlers/FileProcessingHandler.js.map +1 -0
- package/dist/core/handlers/OutputHandler.d.ts +27 -0
- package/dist/core/handlers/OutputHandler.js +127 -0
- package/dist/core/handlers/OutputHandler.js.map +1 -0
- package/dist/core/handlers/ReviewExecutor.d.ts +32 -0
- package/dist/core/handlers/ReviewExecutor.js +111 -0
- package/dist/core/handlers/ReviewExecutor.js.map +1 -0
- package/dist/core/reviewOrchestrator.d.ts +24 -0
- package/dist/core/reviewOrchestrator.js +294 -0
- package/dist/core/reviewOrchestrator.js.map +1 -0
- package/dist/core/utils/ModelInfoUtils.d.ts +16 -0
- package/dist/core/utils/ModelInfoUtils.js +54 -0
- package/dist/core/utils/ModelInfoUtils.js.map +1 -0
- package/dist/formatters/outputFormatter.d.ts +31 -0
- package/dist/formatters/outputFormatter.js +65 -0
- package/dist/formatters/outputFormatter.js.map +1 -0
- package/dist/formatters/utils/IssueFormatters.d.ts +20 -0
- package/dist/formatters/utils/IssueFormatters.js +67 -0
- package/dist/formatters/utils/IssueFormatters.js.map +1 -0
- package/dist/formatters/utils/JsonFormatter.d.ts +13 -0
- package/dist/formatters/utils/JsonFormatter.js +57 -0
- package/dist/formatters/utils/JsonFormatter.js.map +1 -0
- package/dist/formatters/utils/MarkdownFormatters.d.ts +51 -0
- package/dist/formatters/utils/MarkdownFormatters.js +456 -0
- package/dist/formatters/utils/MarkdownFormatters.js.map +1 -0
- package/dist/formatters/utils/MetadataFormatter.d.ts +65 -0
- package/dist/formatters/utils/MetadataFormatter.js +219 -0
- package/dist/formatters/utils/MetadataFormatter.js.map +1 -0
- package/dist/formatters/utils/ModelInfoExtractor.d.ts +33 -0
- package/dist/formatters/utils/ModelInfoExtractor.js +111 -0
- package/dist/formatters/utils/ModelInfoExtractor.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/PluginInterface.d.ts +44 -0
- package/dist/plugins/PluginInterface.js +9 -0
- package/dist/plugins/PluginInterface.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +51 -0
- package/dist/plugins/PluginManager.js +151 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/prompts/PromptManager.d.ts +30 -0
- package/dist/prompts/PromptManager.js +62 -0
- package/dist/prompts/PromptManager.js.map +1 -0
- package/dist/prompts/cache/PromptCache.d.ts +32 -0
- package/dist/prompts/cache/PromptCache.js +48 -0
- package/dist/prompts/cache/PromptCache.js.map +1 -0
- package/dist/runtime/auth/service.d.ts +2 -0
- package/dist/runtime/auth/service.js +41 -0
- package/dist/runtime/auth/service.js.map +1 -0
- package/dist/runtime/auth/session.d.ts +5 -0
- package/dist/runtime/auth/session.js +87 -0
- package/dist/runtime/auth/session.js.map +1 -0
- package/dist/runtime/auth/types.d.ts +9 -0
- package/dist/runtime/auth/types.js +3 -0
- package/dist/runtime/auth/types.js.map +1 -0
- package/dist/runtime/cliEntry.d.ts +1 -0
- package/dist/runtime/cliEntry.js +213 -0
- package/dist/runtime/cliEntry.js.map +1 -0
- package/dist/runtime/debug/logManager.d.ts +5 -0
- package/dist/runtime/debug/logManager.js +31 -0
- package/dist/runtime/debug/logManager.js.map +1 -0
- package/dist/runtime/errors.d.ts +5 -0
- package/dist/runtime/errors.js +15 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/fileCollector.d.ts +5 -0
- package/dist/runtime/fileCollector.js +167 -0
- package/dist/runtime/fileCollector.js.map +1 -0
- package/dist/runtime/manifest.d.ts +1 -0
- package/dist/runtime/manifest.js +65 -0
- package/dist/runtime/manifest.js.map +1 -0
- package/dist/runtime/openrouterProxy.d.ts +4 -0
- package/dist/runtime/openrouterProxy.js +43 -0
- package/dist/runtime/openrouterProxy.js.map +1 -0
- package/dist/runtime/preprod/webCheck.d.ts +1 -0
- package/dist/runtime/preprod/webCheck.js +98 -0
- package/dist/runtime/preprod/webCheck.js.map +1 -0
- package/dist/runtime/proxyConfig.d.ts +6 -0
- package/dist/runtime/proxyConfig.js +86 -0
- package/dist/runtime/proxyConfig.js.map +1 -0
- package/dist/runtime/proxyEnvironment.d.ts +3 -0
- package/dist/runtime/proxyEnvironment.js +63 -0
- package/dist/runtime/proxyEnvironment.js.map +1 -0
- package/dist/runtime/reportMerge.d.ts +30 -0
- package/dist/runtime/reportMerge.js +70 -0
- package/dist/runtime/reportMerge.js.map +1 -0
- package/dist/runtime/reporting/markdownReportBuilder.d.ts +15 -0
- package/dist/runtime/reporting/markdownReportBuilder.js +97 -0
- package/dist/runtime/reporting/markdownReportBuilder.js.map +1 -0
- package/dist/runtime/reporting/reportDataCollector.d.ts +31 -0
- package/dist/runtime/reporting/reportDataCollector.js +170 -0
- package/dist/runtime/reporting/reportDataCollector.js.map +1 -0
- package/dist/runtime/reporting/summaryGenerator.d.ts +10 -0
- package/dist/runtime/reporting/summaryGenerator.js +67 -0
- package/dist/runtime/reporting/summaryGenerator.js.map +1 -0
- package/dist/runtime/reviewPipeline.d.ts +28 -0
- package/dist/runtime/reviewPipeline.js +122 -0
- package/dist/runtime/reviewPipeline.js.map +1 -0
- package/dist/runtime/runAiCodeReview.d.ts +10 -0
- package/dist/runtime/runAiCodeReview.js +138 -0
- package/dist/runtime/runAiCodeReview.js.map +1 -0
- package/dist/runtime/runtimeConfig.d.ts +4 -0
- package/dist/runtime/runtimeConfig.js +7 -0
- package/dist/runtime/runtimeConfig.js.map +1 -0
- package/dist/runtime/ui/Layout.d.ts +11 -0
- package/dist/runtime/ui/Layout.js +47 -0
- package/dist/runtime/ui/Layout.js.map +1 -0
- package/dist/runtime/ui/RuntimeApp.d.ts +6 -0
- package/dist/runtime/ui/RuntimeApp.js +161 -0
- package/dist/runtime/ui/RuntimeApp.js.map +1 -0
- package/dist/runtime/ui/inkModules.d.ts +10 -0
- package/dist/runtime/ui/inkModules.js +63 -0
- package/dist/runtime/ui/inkModules.js.map +1 -0
- package/dist/runtime/ui/screens/AuthScreen.d.ts +6 -0
- package/dist/runtime/ui/screens/AuthScreen.js +67 -0
- package/dist/runtime/ui/screens/AuthScreen.js.map +1 -0
- package/dist/runtime/ui/screens/ModeSelection.d.ts +10 -0
- package/dist/runtime/ui/screens/ModeSelection.js +100 -0
- package/dist/runtime/ui/screens/ModeSelection.js.map +1 -0
- package/dist/runtime/ui/screens/ProgressScreen.d.ts +7 -0
- package/dist/runtime/ui/screens/ProgressScreen.js +38 -0
- package/dist/runtime/ui/screens/ProgressScreen.js.map +1 -0
- package/dist/runtime/ui/screens/ResultsScreen.d.ts +7 -0
- package/dist/runtime/ui/screens/ResultsScreen.js +22 -0
- package/dist/runtime/ui/screens/ResultsScreen.js.map +1 -0
- package/dist/strategies/ArchitecturalReviewStrategy.d.ts +29 -0
- package/dist/strategies/ArchitecturalReviewStrategy.js +42 -0
- package/dist/strategies/ArchitecturalReviewStrategy.js.map +1 -0
- package/dist/strategies/CodingTestReviewStrategy.d.ts +194 -0
- package/dist/strategies/CodingTestReviewStrategy.js +681 -0
- package/dist/strategies/CodingTestReviewStrategy.js.map +1 -0
- package/dist/strategies/ConsolidatedReviewStrategy.d.ts +25 -0
- package/dist/strategies/ConsolidatedReviewStrategy.js +45 -0
- package/dist/strategies/ConsolidatedReviewStrategy.js.map +1 -0
- package/dist/strategies/ExtractPatternsReviewStrategy.d.ts +30 -0
- package/dist/strategies/ExtractPatternsReviewStrategy.js +51 -0
- package/dist/strategies/ExtractPatternsReviewStrategy.js.map +1 -0
- package/dist/strategies/MultiPassReviewStrategy.d.ts +86 -0
- package/dist/strategies/MultiPassReviewStrategy.js +590 -0
- package/dist/strategies/MultiPassReviewStrategy.js.map +1 -0
- package/dist/strategies/ReviewStrategy.d.ts +45 -0
- package/dist/strategies/ReviewStrategy.js +24 -0
- package/dist/strategies/ReviewStrategy.js.map +1 -0
- package/dist/strategies/StrategyFactory.d.ts +19 -0
- package/dist/strategies/StrategyFactory.js +72 -0
- package/dist/strategies/StrategyFactory.js.map +1 -0
- package/dist/strategies/index.d.ts +13 -0
- package/dist/strategies/index.js +30 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/tokenizers/baseTokenizer.d.ts +25 -0
- package/dist/tokenizers/baseTokenizer.js +48 -0
- package/dist/tokenizers/baseTokenizer.js.map +1 -0
- package/dist/tokenizers/gptTokenizer.d.ts +7 -0
- package/dist/tokenizers/gptTokenizer.js +28 -0
- package/dist/tokenizers/gptTokenizer.js.map +1 -0
- package/dist/tokenizers/index.d.ts +7 -0
- package/dist/tokenizers/index.js +24 -0
- package/dist/tokenizers/index.js.map +1 -0
- package/dist/types/apiResponses.d.ts +39 -0
- package/dist/types/apiResponses.js +9 -0
- package/dist/types/apiResponses.js.map +1 -0
- package/dist/types/cli.d.ts +22 -0
- package/dist/types/cli.js +3 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/common.d.ts +22 -0
- package/dist/types/common.js +14 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/configuration.d.ts +682 -0
- package/dist/types/configuration.js +65 -0
- package/dist/types/configuration.js.map +1 -0
- package/dist/types/review.d.ts +258 -0
- package/dist/types/review.js +8 -0
- package/dist/types/review.js.map +1 -0
- package/dist/types/reviewSchema.d.ts +543 -0
- package/dist/types/reviewSchema.js +121 -0
- package/dist/types/reviewSchema.js.map +1 -0
- package/dist/types/structuredReview.d.ts +119 -0
- package/dist/types/structuredReview.js +6 -0
- package/dist/types/structuredReview.js.map +1 -0
- package/dist/types/tokenAnalysis.d.ts +44 -0
- package/dist/types/tokenAnalysis.js +4 -0
- package/dist/types/tokenAnalysis.js.map +1 -0
- package/dist/utils/FileReader.d.ts +33 -0
- package/dist/utils/FileReader.js +88 -0
- package/dist/utils/FileReader.js.map +1 -0
- package/dist/utils/FileWriter.d.ts +26 -0
- package/dist/utils/FileWriter.js +76 -0
- package/dist/utils/FileWriter.js.map +1 -0
- package/dist/utils/PathGenerator.d.ts +30 -0
- package/dist/utils/PathGenerator.js +82 -0
- package/dist/utils/PathGenerator.js.map +1 -0
- package/dist/utils/api/apiUtils.d.ts +3 -0
- package/dist/utils/api/apiUtils.js +20 -0
- package/dist/utils/api/apiUtils.js.map +1 -0
- package/dist/utils/api/index.d.ts +1 -0
- package/dist/utils/api/index.js +18 -0
- package/dist/utils/api/index.js.map +1 -0
- package/dist/utils/apiErrorHandler.d.ts +130 -0
- package/dist/utils/apiErrorHandler.js +256 -0
- package/dist/utils/apiErrorHandler.js.map +1 -0
- package/dist/utils/ciDataCollector.d.ts +51 -0
- package/dist/utils/ciDataCollector.js +197 -0
- package/dist/utils/ciDataCollector.js.map +1 -0
- package/dist/utils/codingTestConfigLoader.d.ts +66 -0
- package/dist/utils/codingTestConfigLoader.js +420 -0
- package/dist/utils/codingTestConfigLoader.js.map +1 -0
- package/dist/utils/dependencies/aiDependencyAnalyzer.d.ts +30 -0
- package/dist/utils/dependencies/aiDependencyAnalyzer.js +343 -0
- package/dist/utils/dependencies/aiDependencyAnalyzer.js.map +1 -0
- package/dist/utils/detection/frameworkDetector.d.ts +43 -0
- package/dist/utils/detection/frameworkDetector.js +795 -0
- package/dist/utils/detection/frameworkDetector.js.map +1 -0
- package/dist/utils/detection/index.d.ts +9 -0
- package/dist/utils/detection/index.js +28 -0
- package/dist/utils/detection/index.js.map +1 -0
- package/dist/utils/detection/projectTypeDetector.d.ts +27 -0
- package/dist/utils/detection/projectTypeDetector.js +469 -0
- package/dist/utils/detection/projectTypeDetector.js.map +1 -0
- package/dist/utils/diagramGenerator.d.ts +49 -0
- package/dist/utils/diagramGenerator.js +218 -0
- package/dist/utils/diagramGenerator.js.map +1 -0
- package/dist/utils/errorLogger.d.ts +24 -0
- package/dist/utils/errorLogger.js +59 -0
- package/dist/utils/errorLogger.js.map +1 -0
- package/dist/utils/estimationUtils.d.ts +139 -0
- package/dist/utils/estimationUtils.js +329 -0
- package/dist/utils/estimationUtils.js.map +1 -0
- package/dist/utils/fileFilters.d.ts +72 -0
- package/dist/utils/fileFilters.js +338 -0
- package/dist/utils/fileFilters.js.map +1 -0
- package/dist/utils/fileSystem.d.ts +22 -0
- package/dist/utils/fileSystem.js +45 -0
- package/dist/utils/fileSystem.js.map +1 -0
- package/dist/utils/index.d.ts +22 -0
- package/dist/utils/index.js +52 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +77 -0
- package/dist/utils/logger.js +271 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pathValidator.d.ts +40 -0
- package/dist/utils/pathValidator.js +98 -0
- package/dist/utils/pathValidator.js.map +1 -0
- package/dist/utils/priorityFilter.d.ts +34 -0
- package/dist/utils/priorityFilter.js +54 -0
- package/dist/utils/priorityFilter.js.map +1 -0
- package/dist/utils/projectDocs.d.ts +47 -0
- package/dist/utils/projectDocs.js +158 -0
- package/dist/utils/projectDocs.js.map +1 -0
- package/dist/utils/promptPaths.d.ts +6 -0
- package/dist/utils/promptPaths.js +33 -0
- package/dist/utils/promptPaths.js.map +1 -0
- package/dist/utils/promptTemplateManager.d.ts +34 -0
- package/dist/utils/promptTemplateManager.js +140 -0
- package/dist/utils/promptTemplateManager.js.map +1 -0
- package/dist/utils/review/consolidateReview.d.ts +15 -0
- package/dist/utils/review/consolidateReview.js +481 -0
- package/dist/utils/review/consolidateReview.js.map +1 -0
- package/dist/utils/review/fixDisplay.d.ts +20 -0
- package/dist/utils/review/fixDisplay.js +84 -0
- package/dist/utils/review/fixDisplay.js.map +1 -0
- package/dist/utils/review/fixImplementation.d.ts +28 -0
- package/dist/utils/review/fixImplementation.js +60 -0
- package/dist/utils/review/fixImplementation.js.map +1 -0
- package/dist/utils/review/index.d.ts +13 -0
- package/dist/utils/review/index.js +50 -0
- package/dist/utils/review/index.js.map +1 -0
- package/dist/utils/review/interactiveProcessing.d.ts +25 -0
- package/dist/utils/review/interactiveProcessing.js +251 -0
- package/dist/utils/review/interactiveProcessing.js.map +1 -0
- package/dist/utils/review/progressTracker.d.ts +106 -0
- package/dist/utils/review/progressTracker.js +227 -0
- package/dist/utils/review/progressTracker.js.map +1 -0
- package/dist/utils/review/reviewExtraction.d.ts +31 -0
- package/dist/utils/review/reviewExtraction.js +324 -0
- package/dist/utils/review/reviewExtraction.js.map +1 -0
- package/dist/utils/review/types.d.ts +45 -0
- package/dist/utils/review/types.js +18 -0
- package/dist/utils/review/types.js.map +1 -0
- package/dist/utils/reviewActionHandler.d.ts +16 -0
- package/dist/utils/reviewActionHandler.js +34 -0
- package/dist/utils/reviewActionHandler.js.map +1 -0
- package/dist/utils/reviewParser.d.ts +34 -0
- package/dist/utils/reviewParser.js +218 -0
- package/dist/utils/reviewParser.js.map +1 -0
- package/dist/utils/sanitizer.d.ts +82 -0
- package/dist/utils/sanitizer.js +239 -0
- package/dist/utils/sanitizer.js.map +1 -0
- package/dist/utils/smartFileSelector.d.ts +50 -0
- package/dist/utils/smartFileSelector.js +261 -0
- package/dist/utils/smartFileSelector.js.map +1 -0
- package/dist/utils/templateLoader.d.ts +44 -0
- package/dist/utils/templateLoader.js +431 -0
- package/dist/utils/templateLoader.js.map +1 -0
- package/dist/utils/treeGenerator.d.ts +12 -0
- package/dist/utils/treeGenerator.js +133 -0
- package/dist/utils/treeGenerator.js.map +1 -0
- package/package.json +11 -12
- package/src/index.ts +1 -0
- package/src/runtime/debug/logManager.ts +37 -0
- package/src/runtime/fileCollector.ts +58 -24
- package/src/runtime/preprod/webCheck.ts +104 -0
- package/src/runtime/reviewPipeline.ts +10 -4
- package/src/runtime/ui/RuntimeApp.tsx +96 -13
- package/src/runtime/ui/screens/ModeSelection.tsx +148 -15
- package/src/runtime/ui/screens/ProgressScreen.tsx +10 -3
- package/src/runtime/ui/screens/ResultsScreen.tsx +8 -1
- package/src/utils/logger.ts +64 -14
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { disableFileLogging, enableFileLogging } from '../../utils/logger';
|
|
4
|
+
|
|
5
|
+
export interface DebugLogSession {
|
|
6
|
+
filePath: string;
|
|
7
|
+
stop: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function formatTimestamp(date: Date): string {
|
|
11
|
+
const pad = (value: number) => value.toString().padStart(2, '0');
|
|
12
|
+
const year = date.getFullYear();
|
|
13
|
+
const month = pad(date.getMonth() + 1);
|
|
14
|
+
const day = pad(date.getDate());
|
|
15
|
+
const hours = pad(date.getHours());
|
|
16
|
+
const minutes = pad(date.getMinutes());
|
|
17
|
+
const seconds = pad(date.getSeconds());
|
|
18
|
+
return `${year}${month}${day}-${hours}${minutes}${seconds}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function startDebugLogSession(workspaceRoot: string): DebugLogSession {
|
|
22
|
+
const logsDir = resolve(workspaceRoot, 'logs');
|
|
23
|
+
mkdirSync(logsDir, { recursive: true });
|
|
24
|
+
|
|
25
|
+
const timestamp = formatTimestamp(new Date());
|
|
26
|
+
const fileName = `cr-debug-${timestamp}.log`;
|
|
27
|
+
const filePath = join(logsDir, fileName);
|
|
28
|
+
|
|
29
|
+
enableFileLogging(filePath);
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
filePath,
|
|
33
|
+
stop: () => {
|
|
34
|
+
disableFileLogging();
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -3,7 +3,13 @@ import { relative as relativePath, resolve as resolvePath, isAbsolute as isAbsol
|
|
|
3
3
|
import { execa } from 'execa';
|
|
4
4
|
import { MissingCrIgnoreError } from './errors';
|
|
5
5
|
|
|
6
|
-
export
|
|
6
|
+
export type FileCollectionMode = 'uncommitted' | 'preprod';
|
|
7
|
+
|
|
8
|
+
export interface CollectFilesOptions {
|
|
9
|
+
mode?: FileCollectionMode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function collectFiles(options: CollectFilesOptions = {}): Promise<string[]> {
|
|
7
13
|
try {
|
|
8
14
|
const { stdout: rootOut } = await execa('git', ['rev-parse', '--show-toplevel']);
|
|
9
15
|
const repoRoot = resolvePath(rootOut.trim());
|
|
@@ -58,40 +64,54 @@ export async function collectFiles(): Promise<string[]> {
|
|
|
58
64
|
return absolutePath;
|
|
59
65
|
};
|
|
60
66
|
|
|
61
|
-
const
|
|
62
|
-
const gitPathSpec = ['--', '.'] as const;
|
|
67
|
+
const mode: FileCollectionMode = options.mode ?? 'uncommitted';
|
|
63
68
|
|
|
64
|
-
const
|
|
65
|
-
|
|
69
|
+
const collectUncommittedFiles = async (): Promise<string[]> => {
|
|
70
|
+
const gitWorkspaceOptions = { cwd: workspaceRoot } as const;
|
|
71
|
+
const gitPathSpec = ['--', '.'] as const;
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
const { stdout: statusOut } = await execa('git', ['status', '--porcelain=1', '-z', ...gitPathSpec], gitWorkspaceOptions);
|
|
74
|
+
const { stdout: diffOut } = await execa('git', ['diff', '--name-only', '-z', ...gitPathSpec], gitWorkspaceOptions);
|
|
69
75
|
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
const statusPrefix = entry.slice(0, 3);
|
|
73
|
-
const pathPart = entry.slice(3).trim();
|
|
76
|
+
const statusEntries = statusOut.split('\0').filter(Boolean);
|
|
77
|
+
const statusFiles: string[] = [];
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
for (let i = 0; i < statusEntries.length; i += 1) {
|
|
80
|
+
const entry = statusEntries[i];
|
|
81
|
+
const statusPrefix = entry.slice(0, 3);
|
|
82
|
+
const pathPart = entry.slice(3).trim();
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
const renamedTarget = statusEntries[i + 1];
|
|
81
|
-
if (renamedTarget) {
|
|
82
|
-
statusFiles.push(renamedTarget);
|
|
83
|
-
i += 1;
|
|
84
|
+
if (!pathPart) {
|
|
84
85
|
continue;
|
|
85
86
|
}
|
|
87
|
+
|
|
88
|
+
if (statusPrefix.trim().startsWith('R')) {
|
|
89
|
+
const renamedTarget = statusEntries[i + 1];
|
|
90
|
+
if (renamedTarget) {
|
|
91
|
+
statusFiles.push(renamedTarget);
|
|
92
|
+
i += 1;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
statusFiles.push(pathPart);
|
|
86
98
|
}
|
|
87
99
|
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
const diffFiles = diffOut.split('\0').filter(Boolean);
|
|
101
|
+
const unique = new Set([...statusFiles, ...diffFiles]);
|
|
102
|
+
return Array.from(unique);
|
|
103
|
+
};
|
|
90
104
|
|
|
91
|
-
const
|
|
92
|
-
|
|
105
|
+
const collectWorkspaceFiles = async (): Promise<string[]> => {
|
|
106
|
+
const pathSpec = workspaceRelative === '' ? '.' : workspaceRelative;
|
|
107
|
+
const tracked = await listTrackedFiles(repoRoot, pathSpec || '.');
|
|
108
|
+
const untracked = await listUntrackedFiles(repoRoot, pathSpec || '.');
|
|
109
|
+
return Array.from(new Set([...tracked, ...untracked]));
|
|
110
|
+
};
|
|
93
111
|
|
|
94
|
-
const
|
|
112
|
+
const pendingFiles = mode === 'preprod' ? await collectWorkspaceFiles() : await collectUncommittedFiles();
|
|
113
|
+
|
|
114
|
+
const resolved = pendingFiles
|
|
95
115
|
.map((file) => normalize(file))
|
|
96
116
|
.filter((file): file is string => Boolean(file));
|
|
97
117
|
|
|
@@ -105,6 +125,20 @@ export async function collectFiles(): Promise<string[]> {
|
|
|
105
125
|
}
|
|
106
126
|
}
|
|
107
127
|
|
|
128
|
+
async function listTrackedFiles(repoRoot: string, pathSpec: string): Promise<string[]> {
|
|
129
|
+
const { stdout } = await execa('git', ['ls-files', '-z', '--', pathSpec], {
|
|
130
|
+
cwd: repoRoot,
|
|
131
|
+
});
|
|
132
|
+
return stdout.split('\0').filter(Boolean);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function listUntrackedFiles(repoRoot: string, pathSpec: string): Promise<string[]> {
|
|
136
|
+
const { stdout } = await execa('git', ['ls-files', '-z', '--others', '--exclude-standard', '--', pathSpec], {
|
|
137
|
+
cwd: repoRoot,
|
|
138
|
+
});
|
|
139
|
+
return stdout.split('\0').filter(Boolean);
|
|
140
|
+
}
|
|
141
|
+
|
|
108
142
|
async function excludeIgnored(repoRoot: string, files: string[]): Promise<string[]> {
|
|
109
143
|
if (files.length === 0) {
|
|
110
144
|
return [];
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const DEFAULT_AIA_BASE_URL = 'https://ai.enki.si';
|
|
2
|
+
|
|
3
|
+
function resolveAiaBaseUrl(): string {
|
|
4
|
+
const configured = process.env.AIA_BASE_URL || process.env.CR_AIA_AIA_BASE_URL;
|
|
5
|
+
const base = (configured || DEFAULT_AIA_BASE_URL).trim();
|
|
6
|
+
return base.replace(/\/$/, '');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function summarizeErrorBody(body: string): string {
|
|
10
|
+
if (!body.trim()) {
|
|
11
|
+
return 'No response body';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (/<html/i.test(body)) {
|
|
15
|
+
const sanitized = body
|
|
16
|
+
.replace(/<script[\s\S]*?<\/script>/gi, ' ')
|
|
17
|
+
.replace(/<style[\s\S]*?<\/style>/gi, ' ')
|
|
18
|
+
.replace(/<[^>]+>/g, ' ')
|
|
19
|
+
.replace(/\s+/g, ' ')
|
|
20
|
+
.trim();
|
|
21
|
+
return sanitized ? `${sanitized.slice(0, 200)}${sanitized.length > 200 ? '…' : ''}` : 'HTML error response';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const normalized = body.replace(/\s+/g, ' ').trim();
|
|
25
|
+
if (!normalized) {
|
|
26
|
+
return 'Empty error body';
|
|
27
|
+
}
|
|
28
|
+
return normalized.length > 200 ? `${normalized.slice(0, 200)}…` : normalized;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class WebCheckRequestError extends Error {
|
|
32
|
+
status?: number;
|
|
33
|
+
detail?: string;
|
|
34
|
+
|
|
35
|
+
constructor(message: string, options?: { status?: number; detail?: string; cause?: unknown }) {
|
|
36
|
+
super(message, options?.cause ? { cause: options.cause } : undefined);
|
|
37
|
+
this.name = 'WebCheckRequestError';
|
|
38
|
+
this.status = options?.status;
|
|
39
|
+
this.detail = options?.detail;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function extractErrorDetail(response: Response): Promise<string | undefined> {
|
|
44
|
+
const contentType = response.headers.get('content-type') || '';
|
|
45
|
+
if (contentType.includes('application/json')) {
|
|
46
|
+
try {
|
|
47
|
+
const payload = (await response.json()) as { error?: { message?: string }; message?: string };
|
|
48
|
+
return payload?.error?.message || payload?.message || JSON.stringify(payload);
|
|
49
|
+
} catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const textBody = await response.text();
|
|
56
|
+
return summarizeErrorBody(textBody);
|
|
57
|
+
} catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function sendWebCheckRequest(endpoint: string, payload: Record<string, unknown>): Promise<void> {
|
|
63
|
+
let response: Response;
|
|
64
|
+
try {
|
|
65
|
+
response = await fetch(endpoint, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify(payload),
|
|
71
|
+
});
|
|
72
|
+
} catch (networkError) {
|
|
73
|
+
const message =
|
|
74
|
+
networkError instanceof Error ? networkError.message : 'Website check request failed due to an unknown error';
|
|
75
|
+
throw new WebCheckRequestError(`Website check request failed: ${message}`, { cause: networkError });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
const detail = await extractErrorDetail(response);
|
|
80
|
+
const suffix = detail ? ` ${detail}` : '';
|
|
81
|
+
throw new WebCheckRequestError(`Website check failed (${response.status}).${suffix}`, {
|
|
82
|
+
status: response.status,
|
|
83
|
+
detail,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function triggerManualWebCheck(targetUrl: string): Promise<void> {
|
|
89
|
+
const baseUrl = resolveAiaBaseUrl();
|
|
90
|
+
const manualEndpoint = `${baseUrl}/api/manual/check`;
|
|
91
|
+
const legacyEndpoint = `${baseUrl}/api/check-website`;
|
|
92
|
+
const missingEndpointStatuses = new Set([404, 405, 501]);
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
await sendWebCheckRequest(manualEndpoint, { url: targetUrl });
|
|
96
|
+
return;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (!(error instanceof WebCheckRequestError) || !error.status || !missingEndpointStatuses.has(error.status)) {
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
await sendWebCheckRequest(legacyEndpoint, { url: targetUrl, options: {} });
|
|
104
|
+
}
|
|
@@ -2,7 +2,7 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { basename, isAbsolute, join, resolve } from 'node:path';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { execa } from 'execa';
|
|
5
|
-
import { collectFiles } from './fileCollector';
|
|
5
|
+
import { collectFiles, type FileCollectionMode } from './fileCollector';
|
|
6
6
|
import { loadManifest } from './manifest';
|
|
7
7
|
import { runAiCodeReview } from './runAiCodeReview';
|
|
8
8
|
import { ensureProxyEnvironmentInitialized } from './proxyEnvironment';
|
|
@@ -10,13 +10,17 @@ import { mergeReports } from './reportMerge';
|
|
|
10
10
|
import { collectReportData } from './reporting/reportDataCollector';
|
|
11
11
|
import { buildMarkdownReport, injectSummary } from './reporting/markdownReportBuilder';
|
|
12
12
|
import { generateReportSummary } from './reporting/summaryGenerator';
|
|
13
|
+
import logger from '../utils/logger';
|
|
13
14
|
|
|
14
|
-
export type ReviewStage = 'collecting' | 'reviewing' | 'merging';
|
|
15
|
+
export type ReviewStage = 'preparing' | 'collecting' | 'reviewing' | 'merging';
|
|
16
|
+
export type ReviewMode = FileCollectionMode;
|
|
15
17
|
|
|
16
18
|
export interface ReviewOptions {
|
|
17
19
|
model: string;
|
|
18
20
|
outDir: string;
|
|
19
21
|
debug?: boolean;
|
|
22
|
+
mode?: ReviewMode;
|
|
23
|
+
preprodTargetUrl?: string;
|
|
20
24
|
onStage?: (stage: ReviewStage, info?: { filesFound?: number }) => void;
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -37,10 +41,11 @@ export interface ReviewResult {
|
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
export async function executeReview(options: ReviewOptions): Promise<ReviewResult> {
|
|
40
|
-
const { model, outDir, debug = false, onStage } = options;
|
|
44
|
+
const { model, outDir, debug = false, onStage, mode = 'uncommitted' } = options;
|
|
41
45
|
|
|
42
46
|
onStage?.('collecting');
|
|
43
|
-
|
|
47
|
+
logger.info('Collecting files for review', { mode, workspace: process.cwd() });
|
|
48
|
+
const files = await collectFiles({ mode });
|
|
44
49
|
const fileCount = files.length;
|
|
45
50
|
|
|
46
51
|
if (fileCount === 0) {
|
|
@@ -48,6 +53,7 @@ export async function executeReview(options: ReviewOptions): Promise<ReviewResul
|
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
onStage?.('collecting', { filesFound: fileCount });
|
|
56
|
+
logger.info('File collection complete', { fileCount });
|
|
51
57
|
|
|
52
58
|
const workspaceRoot = process.cwd();
|
|
53
59
|
const repoRoot = await resolveRepoRoot();
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { LayoutProvider, useLayout } from './Layout';
|
|
3
3
|
import { AuthScreen } from './screens/AuthScreen';
|
|
4
4
|
import { ModeSelection } from './screens/ModeSelection';
|
|
5
5
|
import { ProgressScreen } from './screens/ProgressScreen';
|
|
6
6
|
import { ResultsScreen } from './screens/ResultsScreen';
|
|
7
7
|
import { getInk, getInkSpinner } from './inkModules';
|
|
8
|
-
import type { ReviewResult, ReviewStage } from '../reviewPipeline';
|
|
8
|
+
import type { ReviewMode, ReviewResult, ReviewStage } from '../reviewPipeline';
|
|
9
9
|
import { executeReview } from '../reviewPipeline';
|
|
10
10
|
import { loadSession, getSessionToken } from '../auth/session';
|
|
11
11
|
import type { SessionUser } from '../auth/types';
|
|
12
12
|
import { RUNTIME_CONFIG } from '../runtimeConfig';
|
|
13
13
|
import { MissingCrIgnoreError } from '../errors';
|
|
14
|
+
import { triggerManualWebCheck } from '../preprod/webCheck';
|
|
15
|
+
import { startDebugLogSession, type DebugLogSession } from '../debug/logManager';
|
|
16
|
+
import logger from '../../utils/logger';
|
|
14
17
|
|
|
15
18
|
type ScreenState = 'auth' | 'mode' | 'progress' | 'results';
|
|
16
19
|
|
|
@@ -24,6 +27,10 @@ interface ProgressState {
|
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
const defaultProgress: ProgressState = { stage: 'collecting' };
|
|
30
|
+
const GENERIC_ERROR_MESSAGE =
|
|
31
|
+
'Something went wrong. Press D to enable debug mode and rerun to capture logs.';
|
|
32
|
+
const PREPROD_ERROR_MESSAGE =
|
|
33
|
+
'Could not start the website check. Double-check the URL or try again later.';
|
|
27
34
|
|
|
28
35
|
function AppBody({ debug = false }: RuntimeAppProps) {
|
|
29
36
|
const { Box, Text, useApp, useInput } = getInk();
|
|
@@ -33,8 +40,11 @@ function AppBody({ debug = false }: RuntimeAppProps) {
|
|
|
33
40
|
const [user, setUser] = useState<SessionUser | null>(null);
|
|
34
41
|
const [progress, setProgress] = useState<ProgressState>(defaultProgress);
|
|
35
42
|
const [results, setResults] = useState<ReviewResult | null>(null);
|
|
43
|
+
const [debugEnabled, setDebugEnabled] = useState(false);
|
|
44
|
+
const [lastDebugLogPath, setLastDebugLogPath] = useState<string | null>(null);
|
|
36
45
|
type ErrorInfo = { type: 'generic' | 'crignore'; message: string; hint?: string };
|
|
37
46
|
const [error, setError] = useState<ErrorInfo | null>(null);
|
|
47
|
+
const combinedDebugFlag = useMemo(() => debug || debugEnabled, [debug, debugEnabled]);
|
|
38
48
|
|
|
39
49
|
useEffect(() => {
|
|
40
50
|
const sessionUser = loadSession();
|
|
@@ -68,23 +78,85 @@ function AppBody({ debug = false }: RuntimeAppProps) {
|
|
|
68
78
|
setScreen('mode');
|
|
69
79
|
}, []);
|
|
70
80
|
|
|
71
|
-
const
|
|
81
|
+
const handleToggleDebug = useCallback(() => {
|
|
82
|
+
setDebugEnabled((prev) => {
|
|
83
|
+
if (prev) {
|
|
84
|
+
setLastDebugLogPath(null);
|
|
85
|
+
}
|
|
86
|
+
return !prev;
|
|
87
|
+
});
|
|
88
|
+
}, []);
|
|
89
|
+
|
|
90
|
+
const handleRunReview = useCallback(async (mode: ReviewMode, extras?: { targetUrl?: string }) => {
|
|
91
|
+
const trimmedUrl = extras?.targetUrl?.trim();
|
|
92
|
+
|
|
93
|
+
if (mode === 'preprod' && !trimmedUrl) {
|
|
94
|
+
setError({ type: 'generic', message: 'Pre-production mode requires a website URL.' });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
72
98
|
setScreen('progress');
|
|
73
99
|
setResults(null);
|
|
74
100
|
setError(null);
|
|
75
|
-
setProgress(defaultProgress);
|
|
101
|
+
setProgress(mode === 'preprod' ? { stage: 'preparing' } : defaultProgress);
|
|
102
|
+
setLastDebugLogPath(null);
|
|
103
|
+
|
|
104
|
+
let debugSession: DebugLogSession | null = null;
|
|
105
|
+
const finalizeDebugLogging = () => {
|
|
106
|
+
if (debugSession) {
|
|
107
|
+
debugSession.stop();
|
|
108
|
+
setLastDebugLogPath(debugSession.filePath);
|
|
109
|
+
} else {
|
|
110
|
+
setLastDebugLogPath(null);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
if (debugEnabled) {
|
|
115
|
+
try {
|
|
116
|
+
debugSession = startDebugLogSession(process.cwd());
|
|
117
|
+
} catch (logInitError) {
|
|
118
|
+
const message =
|
|
119
|
+
logInitError instanceof Error
|
|
120
|
+
? logInitError.message
|
|
121
|
+
: 'Unable to initialize debug logging.';
|
|
122
|
+
setError({ type: 'generic', message: `Debug logging disabled: ${message}` });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (mode === 'preprod' && trimmedUrl) {
|
|
127
|
+
try {
|
|
128
|
+
logger.info('Triggering manual website check', { url: trimmedUrl });
|
|
129
|
+
await triggerManualWebCheck(trimmedUrl);
|
|
130
|
+
} catch (webError) {
|
|
131
|
+
logger.error('Pre-production web check failed', webError);
|
|
132
|
+
setError({ type: 'generic', message: PREPROD_ERROR_MESSAGE });
|
|
133
|
+
setScreen('mode');
|
|
134
|
+
finalizeDebugLogging();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
76
138
|
|
|
77
139
|
try {
|
|
140
|
+
logger.info('Starting code review run', { mode, workspace: process.cwd(), preprodTarget: trimmedUrl });
|
|
141
|
+
setProgress({ stage: 'collecting' });
|
|
78
142
|
const reviewResult = await executeReview({
|
|
79
143
|
model: process.env.AI_CODE_REVIEW_MODEL || RUNTIME_CONFIG.DEFAULT_MODEL,
|
|
80
144
|
outDir: './reports',
|
|
81
|
-
debug,
|
|
145
|
+
debug: combinedDebugFlag,
|
|
146
|
+
mode,
|
|
147
|
+
preprodTargetUrl: trimmedUrl,
|
|
82
148
|
onStage: (stage, info) => setProgress({ stage, filesFound: info?.filesFound }),
|
|
83
149
|
});
|
|
84
150
|
|
|
151
|
+
logger.info('Code review run complete', {
|
|
152
|
+
mode,
|
|
153
|
+
durationSeconds: reviewResult.duration,
|
|
154
|
+
filesReviewed: reviewResult.filesReviewed,
|
|
155
|
+
});
|
|
85
156
|
setResults(reviewResult);
|
|
86
157
|
setScreen('results');
|
|
87
158
|
} catch (reviewError) {
|
|
159
|
+
logger.error('Code review run failed', reviewError);
|
|
88
160
|
if (reviewError instanceof MissingCrIgnoreError) {
|
|
89
161
|
setError({
|
|
90
162
|
type: 'crignore',
|
|
@@ -92,22 +164,28 @@ function AppBody({ debug = false }: RuntimeAppProps) {
|
|
|
92
164
|
hint: `Create ${reviewError.crIgnorePath} (can be empty, gitignore syntax) and rerun.`,
|
|
93
165
|
});
|
|
94
166
|
} else {
|
|
95
|
-
|
|
96
|
-
reviewError instanceof Error
|
|
97
|
-
? reviewError.message
|
|
98
|
-
: 'Failed to run review. Check proxy/auth configuration.';
|
|
99
|
-
setError({ type: 'generic', message });
|
|
167
|
+
setError({ type: 'generic', message: GENERIC_ERROR_MESSAGE });
|
|
100
168
|
}
|
|
101
169
|
setScreen('mode');
|
|
170
|
+
} finally {
|
|
171
|
+
finalizeDebugLogging();
|
|
102
172
|
}
|
|
103
|
-
}, [
|
|
173
|
+
}, [combinedDebugFlag, debugEnabled]);
|
|
104
174
|
|
|
105
175
|
return (
|
|
106
176
|
<Box width={layout.frameWidth} flexDirection="column" gap={1}>
|
|
107
177
|
{screen === 'auth' && <AuthScreen onAuth={handleAuth} />}
|
|
108
|
-
{screen === 'mode' && user &&
|
|
178
|
+
{screen === 'mode' && user && (
|
|
179
|
+
<ModeSelection
|
|
180
|
+
onSelect={(mode, payload) => handleRunReview(mode, payload)}
|
|
181
|
+
debugEnabled={debugEnabled}
|
|
182
|
+
onToggleDebug={handleToggleDebug}
|
|
183
|
+
/>
|
|
184
|
+
)}
|
|
109
185
|
{screen === 'progress' && <ProgressScreen stage={progress.stage} filesFound={progress.filesFound} />}
|
|
110
|
-
{screen === 'results' && results &&
|
|
186
|
+
{screen === 'results' && results && (
|
|
187
|
+
<ResultsScreen result={results} debugLogPath={lastDebugLogPath} />
|
|
188
|
+
)}
|
|
111
189
|
{error && (
|
|
112
190
|
<Box
|
|
113
191
|
borderStyle="round"
|
|
@@ -121,6 +199,11 @@ function AppBody({ debug = false }: RuntimeAppProps) {
|
|
|
121
199
|
</Text>
|
|
122
200
|
</Box>
|
|
123
201
|
)}
|
|
202
|
+
{lastDebugLogPath && screen !== 'results' && (
|
|
203
|
+
<Box>
|
|
204
|
+
<Text dimColor>Debug logs saved to: {lastDebugLogPath}</Text>
|
|
205
|
+
</Box>
|
|
206
|
+
)}
|
|
124
207
|
<Box justifyContent="space-between">
|
|
125
208
|
<Text dimColor>{user ? `Logged in as ${user.username}` : 'Authenticate to start reviewing'}</Text>
|
|
126
209
|
<Text dimColor>Ctrl+C to exit</Text>
|
|
@@ -1,23 +1,154 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { getInk, getInkSelectInput } from '../inkModules';
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
import { getInk, getInkSelectInput, getInkTextInput } from '../inkModules';
|
|
3
3
|
import { useLayout } from '../Layout';
|
|
4
|
+
import type { ReviewMode } from '../../reviewPipeline';
|
|
4
5
|
|
|
5
6
|
interface ModeSelectionProps {
|
|
6
|
-
onSelect: (mode: string) => void;
|
|
7
|
+
onSelect: (mode: ReviewMode, extras?: { targetUrl?: string }) => void;
|
|
8
|
+
debugEnabled: boolean;
|
|
9
|
+
onToggleDebug: () => void;
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
interface ModeOption {
|
|
13
|
+
label: string;
|
|
14
|
+
value: ReviewMode;
|
|
15
|
+
description: string;
|
|
16
|
+
requiresUrl?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const OPTIONS: ModeOption[] = [
|
|
10
20
|
{
|
|
11
21
|
label: 'Review uncommitted changes',
|
|
12
22
|
value: 'uncommitted',
|
|
13
23
|
description: 'Scan staged and unstaged changes only',
|
|
14
24
|
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Pre-production review',
|
|
27
|
+
value: 'preprod',
|
|
28
|
+
description: 'Scan the entire workspace and trigger website checks',
|
|
29
|
+
requiresUrl: true,
|
|
30
|
+
},
|
|
15
31
|
];
|
|
16
32
|
|
|
17
|
-
export function ModeSelection({ onSelect }: ModeSelectionProps) {
|
|
18
|
-
const { Box, Text } = getInk();
|
|
33
|
+
export function ModeSelection({ onSelect, debugEnabled, onToggleDebug }: ModeSelectionProps) {
|
|
34
|
+
const { Box, Text, useInput } = getInk();
|
|
19
35
|
const SelectInput = getInkSelectInput();
|
|
36
|
+
const TextInput = getInkTextInput();
|
|
20
37
|
const { frameWidth } = useLayout();
|
|
38
|
+
const [phase, setPhase] = useState<'list' | 'preprodUrl'>('list');
|
|
39
|
+
const [pendingMode, setPendingMode] = useState<ReviewMode>('preprod');
|
|
40
|
+
const [highlighted, setHighlighted] = useState<ReviewMode>('uncommitted');
|
|
41
|
+
const [urlValue, setUrlValue] = useState('');
|
|
42
|
+
const [urlError, setUrlError] = useState<string | null>(null);
|
|
43
|
+
|
|
44
|
+
const resetUrlState = useCallback(() => {
|
|
45
|
+
setUrlValue('');
|
|
46
|
+
setUrlError(null);
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
const handleModeSelect = useCallback(
|
|
50
|
+
(mode: ReviewMode) => {
|
|
51
|
+
const option = OPTIONS.find((opt) => opt.value === mode);
|
|
52
|
+
if (!option) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (option.requiresUrl) {
|
|
57
|
+
setPendingMode(option.value);
|
|
58
|
+
resetUrlState();
|
|
59
|
+
setPhase('preprodUrl');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
onSelect(option.value);
|
|
64
|
+
},
|
|
65
|
+
[onSelect, resetUrlState],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const submitUrl = useCallback(() => {
|
|
69
|
+
if (phase !== 'preprodUrl') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const trimmed = urlValue.trim();
|
|
74
|
+
if (!trimmed) {
|
|
75
|
+
setUrlError('URL is required');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const parsed = new URL(trimmed);
|
|
81
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
82
|
+
throw new Error('invalid');
|
|
83
|
+
}
|
|
84
|
+
setUrlError(null);
|
|
85
|
+
onSelect(pendingMode, { targetUrl: parsed.toString() });
|
|
86
|
+
} catch {
|
|
87
|
+
setUrlError('Enter a valid URL starting with http:// or https://');
|
|
88
|
+
}
|
|
89
|
+
}, [onSelect, pendingMode, phase, urlValue]);
|
|
90
|
+
|
|
91
|
+
useInput((input, key) => {
|
|
92
|
+
const normalizedInput = input.toLowerCase();
|
|
93
|
+
if (normalizedInput === 'd' && !key.ctrl && !key.meta) {
|
|
94
|
+
onToggleDebug();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (phase !== 'preprodUrl') {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (key.escape) {
|
|
103
|
+
setPhase('list');
|
|
104
|
+
resetUrlState();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (key.return) {
|
|
109
|
+
submitUrl();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (phase === 'preprodUrl') {
|
|
114
|
+
return (
|
|
115
|
+
<Box
|
|
116
|
+
width={frameWidth}
|
|
117
|
+
flexDirection="column"
|
|
118
|
+
borderStyle="round"
|
|
119
|
+
borderColor="cyan"
|
|
120
|
+
paddingX={2}
|
|
121
|
+
paddingY={1}
|
|
122
|
+
gap={1}
|
|
123
|
+
>
|
|
124
|
+
<Text color="cyan" bold>
|
|
125
|
+
Pre-production review
|
|
126
|
+
</Text>
|
|
127
|
+
<Text dimColor>Enter the full website URL. We will trigger ai.enki.si and scan every file here.</Text>
|
|
128
|
+
<Box flexDirection="column">
|
|
129
|
+
<Text dimColor>Target URL</Text>
|
|
130
|
+
<TextInput
|
|
131
|
+
value={urlValue}
|
|
132
|
+
onChange={(value) => {
|
|
133
|
+
setUrlValue(value);
|
|
134
|
+
if (urlError) {
|
|
135
|
+
setUrlError(null);
|
|
136
|
+
}
|
|
137
|
+
}}
|
|
138
|
+
placeholder="https://example.com"
|
|
139
|
+
focus
|
|
140
|
+
/>
|
|
141
|
+
</Box>
|
|
142
|
+
{urlError && (
|
|
143
|
+
<Text color="red">{urlError}</Text>
|
|
144
|
+
)}
|
|
145
|
+
<Box justifyContent="space-between">
|
|
146
|
+
<Text dimColor>Press Enter to start · Esc to go back</Text>
|
|
147
|
+
<Text dimColor>Debug: {debugEnabled ? 'On' : 'Off'} (press D)</Text>
|
|
148
|
+
</Box>
|
|
149
|
+
</Box>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
21
152
|
|
|
22
153
|
return (
|
|
23
154
|
<Box
|
|
@@ -29,23 +160,25 @@ export function ModeSelection({ onSelect }: ModeSelectionProps) {
|
|
|
29
160
|
paddingY={1}
|
|
30
161
|
gap={1}
|
|
31
162
|
>
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
163
|
+
<Box justifyContent="space-between" alignItems="center">
|
|
164
|
+
<Text color="green" bold>
|
|
165
|
+
Choose review mode
|
|
166
|
+
</Text>
|
|
167
|
+
<Text dimColor>Debug: {debugEnabled ? 'On' : 'Off'} (press D)</Text>
|
|
168
|
+
</Box>
|
|
35
169
|
<Text dimColor>Use arrow keys, press Enter to start.</Text>
|
|
36
170
|
<SelectInput
|
|
37
171
|
items={OPTIONS.map((option) => ({
|
|
38
172
|
label: option.label,
|
|
39
173
|
value: option.value,
|
|
40
174
|
}))}
|
|
41
|
-
|
|
175
|
+
onHighlight={(item) => setHighlighted(item.value as ReviewMode)}
|
|
176
|
+
onSelect={(item) => handleModeSelect(item.value as ReviewMode)}
|
|
42
177
|
/>
|
|
43
178
|
<Box flexDirection="column" marginTop={1}>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</Text>
|
|
48
|
-
))}
|
|
179
|
+
<Text dimColor>
|
|
180
|
+
· {OPTIONS.find((option) => option.value === highlighted)?.description}
|
|
181
|
+
</Text>
|
|
49
182
|
</Box>
|
|
50
183
|
</Box>
|
|
51
184
|
);
|