diff --git a/src/Console/InstallCommand.php b/src/Console/InstallCommand.php index 135f758..081213f 100644 --- a/src/Console/InstallCommand.php +++ b/src/Console/InstallCommand.php @@ -462,17 +462,18 @@ private function installMcpServerConfig(): void )->toArray() ); - /** @var CodeEnvironment $mcpClient */ + /** @var McpClient $mcpClient */ foreach ($this->selectedTargetMcpClient as $mcpClient) { $ideName = $mcpClient->mcpClientName(); $ideDisplay = str_pad($ideName, $longestIdeName); $this->output->write(" {$ideDisplay}... "); $results = []; + $php = $mcpClient->getPhpPath(); if ($this->shouldInstallMcp()) { try { - $artisan = $mcpClient->useAbsolutePathForMcp ? base_path('artisan') : './artisan'; - $result = $mcpClient->installMcp('laravel-boost', 'php', [$artisan, 'boost:mcp']); + $artisan = $mcpClient->getArtisanPath(); + $result = $mcpClient->installMcp('laravel-boost', $php, [$artisan, 'boost:mcp']); if ($result) { $results[] = $this->greenTick.' Boost'; @@ -491,7 +492,7 @@ private function installMcpServerConfig(): void try { $result = $mcpClient->installMcp( key: 'herd', - command: 'php', + command: $php, args: [$this->herd->mcpPath()], env: ['SITE_PATH' => base_path()] ); diff --git a/src/Contracts/McpClient.php b/src/Contracts/McpClient.php index 74629d3..68c106b 100644 --- a/src/Contracts/McpClient.php +++ b/src/Contracts/McpClient.php @@ -16,6 +16,21 @@ interface McpClient */ public function mcpClientName(): ?string; + /** + * Whether to use absolute paths for MCP commands. + */ + public function useAbsolutePathForMcp(): bool; + + /** + * Get the PHP executable path for this MCP client. + */ + public function getPhpPath(): string; + + /** + * Get the artisan path for this MCP client. + */ + public function getArtisanPath(): string; + /** * Install an MCP server configuration in this IDE. * diff --git a/src/Install/CodeEnvironment/CodeEnvironment.php b/src/Install/CodeEnvironment/CodeEnvironment.php index fe4a4b5..8887619 100644 --- a/src/Install/CodeEnvironment/CodeEnvironment.php +++ b/src/Install/CodeEnvironment/CodeEnvironment.php @@ -35,6 +35,22 @@ public function mcpClientName(): ?string return $this->displayName(); } + public function useAbsolutePathForMcp(): bool + { + return $this->useAbsolutePathForMcp; + } + + public function getPhpPath(): string + { + return $this->useAbsolutePathForMcp() ? PHP_BINARY : 'php'; + } + + public function getArtisanPath(): string + { + return $this->useAbsolutePathForMcp() ? base_path('artisan') : './artisan'; + + } + /** * Get the detection configuration for system-wide installation detection. * diff --git a/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php b/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php new file mode 100644 index 0000000..415f7f7 --- /dev/null +++ b/tests/Feature/Install/CodeEnvironment/CodeEnvironmentPathResolutionTest.php @@ -0,0 +1,39 @@ +getPhpPath())->toBe(PHP_BINARY); +}); + +test('PhpStorm returns absolute artisan path', function () { + $strategyFactory = Mockery::mock(DetectionStrategyFactory::class); + $phpStorm = new PhpStorm($strategyFactory); + + $artisanPath = $phpStorm->getArtisanPath(); + + // Should be an absolute path ending with 'artisan' + expect($artisanPath)->toEndWith('artisan') + ->and($artisanPath)->not()->toBe('./artisan'); +}); + +test('Cursor returns relative php string', function () { + $strategyFactory = Mockery::mock(DetectionStrategyFactory::class); + $cursor = new Cursor($strategyFactory); + + expect($cursor->getPhpPath())->toBe('php'); +}); + +test('Cursor returns relative artisan path', function () { + $strategyFactory = Mockery::mock(DetectionStrategyFactory::class); + $cursor = new Cursor($strategyFactory); + + expect($cursor->getArtisanPath())->toBe('./artisan'); +});