Skip to content

Commit cf2414d

Browse files
authored
[1.x] Sail Support for Boost (#303)
1 parent bf54529 commit cf2414d

File tree

8 files changed

+91
-27
lines changed

8 files changed

+91
-27
lines changed

src/Console/InstallCommand.php

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -235,26 +235,37 @@ protected function determineTestEnforcement(): bool
235235
*/
236236
protected function selectBoostFeatures(): Collection
237237
{
238-
$features = collect([
239-
'mcp_server',
240-
'ai_guidelines',
241-
]);
238+
$features = collect(['mcp_server', 'ai_guidelines']);
242239

243-
if ($this->herd->isMcpAvailable() === false) {
244-
return $features;
240+
if ($this->herd->isMcpAvailable() && $this->shouldConfigureHerdMcp()) {
241+
$features->push('herd_mcp');
245242
}
246243

247-
if (confirm(
248-
label: 'Would you like to install Herd MCP alongside Boost MCP?',
249-
default: $this->config->getHerdMcp(),
250-
hint: 'The Herd MCP provides additional tools like browser logs, which can help AI understand issues better',
251-
)) {
252-
$features->push('herd_mcp');
244+
if ($this->isSailInstalled() && ($this->isRunningInsideSail() || $this->shouldConfigureSail())) {
245+
$features->push('sail');
253246
}
254247

255248
return $features;
256249
}
257250

251+
protected function shouldConfigureSail(): bool
252+
{
253+
return confirm(
254+
label: 'Laravel Sail detected. Configure Boost MCP to use Sail?',
255+
default: $this->config->getSail(),
256+
hint: 'This will configure the MCP server to run through Sail. Note: Sail must be running to use Boost MCP',
257+
);
258+
}
259+
260+
protected function shouldConfigureHerdMcp(): bool
261+
{
262+
return confirm(
263+
label: 'Would you like to install Herd MCP alongside Boost MCP?',
264+
default: $this->config->getHerdMcp(),
265+
hint: 'The Herd MCP provides additional tools like browser logs, which can help AI understand issues better',
266+
);
267+
}
268+
258269
/**
259270
* @return Collection<int, string>
260271
*/
@@ -442,6 +453,10 @@ protected function installGuidelines(): void
442453
}
443454
}
444455

456+
$this->config->setSail(
457+
$this->shouldUseSail()
458+
);
459+
445460
$this->config->setHerdMcp(
446461
$this->shouldInstallHerdMcp()
447462
);
@@ -469,6 +484,39 @@ protected function shouldInstallHerdMcp(): bool
469484
return $this->selectedBoostFeatures->contains('herd_mcp');
470485
}
471486

487+
protected function shouldUseSail(): bool
488+
{
489+
return $this->selectedBoostFeatures->contains('sail');
490+
}
491+
492+
protected function isSailInstalled(): bool
493+
{
494+
return file_exists(base_path('vendor/bin/sail')) &&
495+
(file_exists(base_path('docker-compose.yml')) || file_exists(base_path('compose.yaml')));
496+
}
497+
498+
protected function isRunningInsideSail(): bool
499+
{
500+
return get_current_user() === 'sail' || getenv('LARAVEL_SAIL') === '1';
501+
}
502+
503+
protected function buildMcpCommand(McpClient $mcpClient): array
504+
{
505+
if ($this->shouldUseSail()) {
506+
return ['laravel-boost', './vendor/bin/sail', 'artisan', 'boost:mcp'];
507+
}
508+
509+
$inWsl = $this->isRunningInWsl();
510+
511+
return array_filter([
512+
'laravel-boost',
513+
$inWsl ? 'wsl' : false,
514+
$mcpClient->getPhpPath($inWsl),
515+
$mcpClient->getArtisanPath($inWsl),
516+
'boost:mcp',
517+
]);
518+
}
519+
472520
protected function installMcpServerConfig(): void
473521
{
474522
if ($this->selectedTargetMcpClient->isEmpty()) {
@@ -498,14 +546,8 @@ protected function installMcpServerConfig(): void
498546
$this->output->write(" {$ideDisplay}... ");
499547
$results = [];
500548

501-
$inWsl = $this->isRunningInWsl();
502-
$mcp = array_filter([
503-
'laravel-boost',
504-
$inWsl ? 'wsl' : false,
505-
$mcpClient->getPhpPath($inWsl),
506-
$mcpClient->getArtisanPath($inWsl),
507-
'boost:mcp',
508-
]);
549+
$mcp = $this->buildMcpCommand($mcpClient);
550+
509551
try {
510552
$result = $mcpClient->installMcp(
511553
array_shift($mcp),
@@ -527,6 +569,7 @@ protected function installMcpServerConfig(): void
527569
// Install Herd MCP if enabled
528570
if ($this->shouldInstallHerdMcp()) {
529571
$php = $mcpClient->getPhpPath();
572+
530573
try {
531574
$result = $mcpClient->installMcp(
532575
key: 'herd',
@@ -554,6 +597,7 @@ protected function installMcpServerConfig(): void
554597

555598
if ($failed !== []) {
556599
$this->error(sprintf('%s Some MCP servers failed to install:', $this->redCross));
600+
557601
foreach ($failed as $ideName => $errors) {
558602
foreach ($errors as $server => $error) {
559603
$this->line(" - {$ideName} ({$server}): {$error}");

src/Support/Composer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static function packagesDirectories(): array
1313
base_path('vendor'),
1414
str_replace('/', DIRECTORY_SEPARATOR, $package),
1515
])])
16-
->filter(is_dir(...))
16+
->filter(fn (string $path): bool => is_dir($path))
1717
->toArray();
1818
}
1919

@@ -45,7 +45,7 @@ public static function packagesDirectoriesWithBoostGuidelines(): array
4545
'resources',
4646
'boost',
4747
'guidelines',
48-
]))->filter(is_dir(...))
48+
]))->filter(fn (string $path): bool => is_dir($path))
4949
->toArray();
5050
}
5151
}

src/Support/Config.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ public function getHerdMcp(): bool
6262
return $this->get('herd_mcp', false);
6363
}
6464

65+
public function setSail(bool $useSail): void
66+
{
67+
$this->set('sail', $useSail);
68+
}
69+
70+
public function getSail(): bool
71+
{
72+
return $this->get('sail', false);
73+
}
74+
6575
public function flush(): void
6676
{
6777
$path = base_path(self::FILE);

tests/Feature/BoostServiceProviderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
beforeEach(function (): void {
1111
$this->refreshApplication();
12-
Config::set('logging.channels.browser', null);
12+
Config::set('logging.channels.browser');
1313
});
1414

1515
describe('boost.enabled configuration', function (): void {

tests/Feature/Install/GuidelineComposerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,8 @@
407407
->toContain('`artisan make:model`')
408408
->toContain('`php artisan migrate`')
409409
->toContain('`Model::query()`')
410-
->toContain('`route(\'home\')`')
411-
->toContain('`config(\'app.name\')`')
410+
->toContain("`route('home')`")
411+
->toContain("`config('app.name')`")
412412
// Preserves PHP tags in blade templates
413413
->toContain('=== .ai/test-blade-with-php-tags rules ===')
414414
->not->toContain('=== .ai/test-blade-with-backticks.blade.php rules ===')

tests/Feature/Mcp/Tools/ListAvailableConfigKeysTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
test('it handles empty config gracefully', function (): void {
4141
// Clear all config
42-
config()->set('test', null);
42+
config()->set('test');
4343

4444
$tool = new ListAvailableConfigKeys;
4545
$response = $tool->handle(new Request([]));

tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,13 @@ public function mcpConfigPath(): string
415415
$environment = new TestCodeEnvironment($this->strategyFactory);
416416
expect($environment->getPhpPath(false))->toBe('php');
417417
});
418+
419+
test('getArtisanPath uses absolute path when forceAbsolutePath is true', function (): void {
420+
$environment = new TestCodeEnvironment($this->strategyFactory);
421+
expect($environment->getArtisanPath(true))->toBe(base_path('artisan'));
422+
});
423+
424+
test('getArtisanPath maintains default behavior when forceAbsolutePath is false', function (): void {
425+
$environment = new TestCodeEnvironment($this->strategyFactory);
426+
expect($environment->getArtisanPath(false))->toBe('artisan');
427+
});

tests/Unit/Install/Detection/CompositeDetectionStrategyTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@
170170
$this->firstStrategy,
171171
]);
172172

173-
$result = $composite->detect(['config' => 'test'], null);
173+
$result = $composite->detect(['config' => 'test']);
174174

175175
expect($result)->toBeTrue();
176176
});

0 commit comments

Comments
 (0)