getAttributeClass() => $mapper]; echo "Target attribute class: " . $mapper->getAttributeClass() . PHP_EOL; echo "Testing class: " . $className->getFullyQualified() . PHP_EOL; if (! $className->exists()) { echo "❌ Class does not exist!" . PHP_EOL; exit(1); } try { $reflection = $reflectionProvider->getClass($className); echo "✅ Got reflection for class" . PHP_EOL; // Process method attributes (copied from AttributeVisitor logic) $methods = $reflection->getMethods(); echo "Found " . count($methods) . " methods" . PHP_EOL; foreach ($methods as $method) { echo " Processing method: " . $method->getName() . PHP_EOL; $attributes = $method->getAttributes(); echo " Found " . count($attributes) . " attributes" . PHP_EOL; foreach ($attributes as $attribute) { $attributeClass = $attribute->getName(); echo " Attribute: $attributeClass" . PHP_EOL; // Check if we should ignore this attribute $ignoredAttributes = [ 'Attribute', 'Override', 'AllowDynamicProperties', 'ReturnTypeWillChange', 'SensitiveParameter', ]; $shortName = substr($attributeClass, strrpos($attributeClass, '\\') + 1); if (in_array($shortName, $ignoredAttributes, true) || in_array($attributeClass, $ignoredAttributes, true)) { echo " → Ignored (built-in attribute)" . PHP_EOL; continue; } // Extract attribute arguments $arguments = $attribute->getArguments() ?? []; echo " → Arguments: " . json_encode($arguments) . PHP_EOL; // Apply mapper if available $additionalData = []; if (isset($mapperMap[$attributeClass])) { echo " → Found mapper for this attribute" . PHP_EOL; try { $mapper = $mapperMap[$attributeClass]; $attributeInstance = $attribute->newInstance(); $mapped = $mapper->map($method, $attributeInstance); $additionalData = $mapped ?? []; echo " → Mapping result: " . json_encode($additionalData) . PHP_EOL; } catch (Exception $e) { echo " → Mapping error: " . $e->getMessage() . PHP_EOL; } } else { echo " → No mapper found for: $attributeClass" . PHP_EOL; } // Create DiscoveredAttribute $filePath = FilePath::create(__DIR__ . '/../../src/Framework/Mcp/Console/McpServerCommand.php'); $discoveredAttribute = new DiscoveredAttribute( className: $className, attributeClass: $attributeClass, target: AttributeTarget::METHOD, methodName: MethodName::create($method->getName()), propertyName: null, arguments: $arguments, filePath: $filePath, additionalData: $additionalData ); echo " → Created DiscoveredAttribute" . PHP_EOL; // Add to registry $registry->add($attributeClass, $discoveredAttribute); echo " → Added to registry" . PHP_EOL; } } echo PHP_EOL . "Final registry state:" . PHP_EOL; echo "Total attributes: " . $registry->count() . PHP_EOL; echo "Available types: " . count($registry->getAllTypes()) . PHP_EOL; foreach ($registry->getAllTypes() as $type) { $count = $registry->getCount($type); echo " - $type: $count" . PHP_EOL; if ($type === 'App\\Framework\\Console\\ConsoleCommand') { $commands = $registry->get($type); foreach ($commands as $i => $command) { echo " Command $i:" . PHP_EOL; echo " Class: " . $command->className->getFullyQualified() . PHP_EOL; echo " Method: " . ($command->methodName?->toString() ?? 'unknown') . PHP_EOL; $instance = $command->createAttributeInstance(); if ($instance) { echo " Name: " . $instance->name . PHP_EOL; echo " Description: " . $instance->description . PHP_EOL; } } } } } catch (Exception $e) { echo "❌ Error: " . $e->getMessage() . PHP_EOL; echo "Stack trace: " . $e->getTraceAsString() . PHP_EOL; }