From 8f39da8923be832a5fb47c0a5c5ab7d42c0ef2de Mon Sep 17 00:00:00 2001 From: Illia Vasylevskyi Date: Sat, 4 Oct 2025 22:34:55 -0400 Subject: [PATCH] Fixed Discoverer file processing for PHAR --- src/Capability/Discovery/Discoverer.php | 51 +++++++++++-------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/src/Capability/Discovery/Discoverer.php b/src/Capability/Discovery/Discoverer.php index 83dafa0..1520a8e 100644 --- a/src/Capability/Discovery/Discoverer.php +++ b/src/Capability/Discovery/Discoverer.php @@ -143,16 +143,9 @@ public function discover(string $basePath, array $directories, array $excludeDir */ private function processFile(SplFileInfo $file, array &$discoveredCount, array &$tools, array &$resources, array &$prompts, array &$resourceTemplates): void { - $filePath = $file->getRealPath(); - if (false === $filePath) { - $this->logger->warning('Could not get real path for file', ['path' => $file->getPathname()]); - - return; - } - - $className = $this->getClassFromFile($filePath); + $className = $this->getClassFromFile($file); if (!$className) { - $this->logger->warning('No valid class found in file', ['file' => $filePath]); + $this->logger->warning('No valid class found in file', ['file' => $file->getPathname()]); return; } @@ -199,10 +192,10 @@ private function processFile(SplFileInfo $file, array &$discoveredCount, array & } } } catch (\ReflectionException $e) { - $this->logger->error('Reflection error processing file for MCP discovery', ['file' => $filePath, 'class' => $className, 'exception' => $e->getMessage()]); + $this->logger->error('Reflection error processing file for MCP discovery', ['file' => $file->getPathname(), 'class' => $className, 'exception' => $e->getMessage()]); } catch (\Throwable $e) { $this->logger->error('Unexpected error processing file for MCP discovery', [ - 'file' => $filePath, + 'file' => $file->getPathname(), 'class' => $className, 'exception' => $e->getMessage(), 'trace' => $e->getTraceAsString(), @@ -329,34 +322,34 @@ private function getCompletionProviders(\ReflectionMethod $reflectionMethod): ar * Attempt to determine the FQCN from a PHP file path. * Uses tokenization to extract namespace and class name. * - * @param string $filePath absolute path to the PHP file - * * @return class-string|null the FQCN or null if not found/determinable */ - private function getClassFromFile(string $filePath): ?string + private function getClassFromFile(SplFileInfo $file): ?string { - if (!file_exists($filePath) || !is_readable($filePath)) { - $this->logger->warning('File does not exist or is not readable.', ['file' => $filePath]); + $this->logger->debug('Processing file', ['path' => $file->getPathname()]); + + try { + $content = $file->getContents(); + } catch (\Throwable $e) { + $this->logger->warning("Failed to read file content during class discovery: {$file->getPathname()}", [ + 'exception' => $e->getMessage(), + ]); return null; } - try { - $content = file_get_contents($filePath); - if (false === $content) { - $this->logger->warning('Failed to read file content.', ['file' => $filePath]); - - return null; - } - if (\strlen($content) > 500 * 1024) { - $this->logger->debug('Skipping large file during class discovery.', ['file' => $filePath]); + if (\strlen($content) > 500 * 1024) { + $this->logger->warning('Skipping large file during class discovery.', ['file' => $file->getPathname()]); - return null; - } + return null; + } + try { $tokens = token_get_all($content); } catch (\Throwable $e) { - $this->logger->warning("Failed to read or tokenize file during class discovery: {$filePath}", ['exception' => $e->getMessage()]); + $this->logger->warning("Failed to tokenize file during class discovery: {$file->getPathname()}", [ + 'exception' => $e->getMessage(), + ]); return null; } @@ -427,7 +420,7 @@ private function getClassFromFile(string $filePath): ?string if (!empty($potentialClasses)) { if (!class_exists($potentialClasses[0], false)) { - $this->logger->debug('getClassFromFile returning potential non-class type. Are you sure this class has been autoloaded?', ['file' => $filePath, 'type' => $potentialClasses[0]]); + $this->logger->debug('getClassFromFile returning potential non-class type. Are you sure this class has been autoloaded?', ['file' => $file->getPathname(), 'type' => $potentialClasses[0]]); } return $potentialClasses[0];