Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .ai/php/8.5/core.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## PHP 8.5

- PHP 8.5 has new array functions that will make code simpler whenever we don't use Laravel's collections.
- `array_first(array $array): mixed` - Get first value (or `null` if empty)
- `array_last(array $array): mixed` - Get last value (or `null` if empty)

- Use `clone($object, ['property' => $value])` to modify properties during cloning—ideal for readonly classes.

### Pipe Operator
- The pipe operator (`|>`) chains function calls left-to-right, replacing nested calls:
<code-snippet name="Pipe Operator Example" lang="php">
// Before PHP 8.5
$slug = strtolower(str_replace(' ', '-', trim($title)));

// After PHP 8.5
$slug = $title |> trim(...) |> (fn($s) => str_replace(' ', '-', $s)) |> strtolower(...);
</code-snippet>
7 changes: 7 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ jobs:
os: [ ubuntu-22.04, windows-latest ]
php: [ 8.2, 8.3, 8.4 ]
laravel: [ 11, 12 ]
include:
- php: 8.5
laravel: 12
os: ubuntu-22.04
- php: 8.5
laravel: 12
os: windows-latest

name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.os }}

Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
"illuminate/contracts": "^10.49.0|^11.45.3|^12.28.1",
"illuminate/routing": "^10.49.0|^11.45.3|^12.28.1",
"illuminate/support": "^10.49.0|^11.45.3|^12.28.1",
"laravel/mcp": "^0.3.4",
"laravel/mcp": "^0.4.0",
"laravel/prompts": "0.1.25|^0.3.6",
"laravel/roster": "^0.2.9"
},
"require-dev": {
"laravel/pint": "1.20",
"laravel/pint": "^1.20.0",
"mockery/mockery": "^1.6.12",
"orchestra/testbench": "^8.36.0|^9.15.0|^10.6",
"pestphp/pest": "^2.36.0|^3.8.4",
"pestphp/pest": "^2.36.0|^3.8.4|^4.1.5",
"phpstan/phpstan": "^2.1.27",
"rector/rector": "^2.1"
},
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/BrowserLogs.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Boost\Concerns\ReadsLogs;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -24,7 +25,7 @@ class BrowserLogs extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/DatabaseQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Illuminate\Support\Facades\DB;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -23,7 +24,7 @@ class DatabaseQuery extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/DatabaseSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
namespace Laravel\Boost\Mcp\Tools;

use Exception;
use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
Expand All @@ -28,7 +29,7 @@ class DatabaseSchema extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/GetAbsoluteUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
Expand All @@ -21,7 +22,7 @@ class GetAbsoluteUrl extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/GetConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Illuminate\Support\Facades\Config;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -19,7 +20,7 @@ class GetConfig extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/ListAvailableEnvVars.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
Expand All @@ -21,7 +22,7 @@ class ListAvailableEnvVars extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/ListRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Illuminate\Support\Facades\Artisan;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -24,7 +25,7 @@ class ListRoutes extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/ReadLogEntries.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Laravel\Boost\Mcp\Tools;

use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Boost\Concerns\ReadsLogs;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -24,7 +25,7 @@ class ReadLogEntries extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/ReportFeedback.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
namespace Laravel\Boost\Mcp\Tools;

use Generator;
use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Boost\Concerns\MakesHttpRequests;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -20,7 +21,7 @@ class ReportFeedback extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/SearchDocs.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
namespace Laravel\Boost\Mcp\Tools;

use Generator;
use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Boost\Concerns\MakesHttpRequests;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
Expand All @@ -28,7 +29,7 @@ public function __construct(protected Roster $roster) {}
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
5 changes: 3 additions & 2 deletions src/Mcp/Tools/Tinker.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
namespace Laravel\Boost\Mcp\Tools;

use Exception;
use Illuminate\JsonSchema\JsonSchema;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\JsonSchema\Types\Type;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
Expand All @@ -21,7 +22,7 @@ class Tinker extends Tool
/**
* Get the tool's input schema.
*
* @return array<string, JsonSchema>
* @return array<string, Type>
*/
public function schema(JsonSchema $schema): array
{
Expand Down
18 changes: 7 additions & 11 deletions tests/Feature/Console/InstallCommandMultiselectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,11 @@
);

// Verify we get keys that can be used with in_array checks
expect($result)->toBeArray();
expect($result)->toHaveCount(3); // All 3 selected (2 default + 1 added)

// These are the exact checks used in InstallCommand
expect(in_array('mcp_server', $result, true))->toBeTrue();
expect(in_array('ai_guidelines', $result, true))->toBeTrue();
expect(in_array('style_guidelines', $result, true))->toBeTrue();

// Verify it doesn't contain the display values
expect(in_array('Boost MCP Server', $result, true))->toBeFalse();
expect(in_array('Package AI Guidelines (i.e. Framework, Inertia, Pest)', $result, true))->toBeFalse();
expect($result)->toBeArray()
->and($result)->toHaveCount(3)
->and($result)->toContain('mcp_server')
->and($result)->toContain('ai_guidelines')
->and($result)->toContain('style_guidelines')
->and($result)->not->toContain('Boost MCP Server')
->and($result)->not->toContain('Package AI Guidelines (i.e. Framework, Inertia, Pest)');
})->skipOnWindows();
8 changes: 4 additions & 4 deletions tests/Feature/Install/GuidelineComposerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@
$composer = Mockery::mock(GuidelineComposer::class, [$this->roster, $this->herd])->makePartial();
$composer
->shouldReceive('customGuidelinePath')
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('Fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));

expect($composer->compose())
->toContain('=== .ai/custom-rule rules ===')
Expand All @@ -336,7 +336,7 @@
$composer = Mockery::mock(GuidelineComposer::class, [$this->roster, $this->herd])->makePartial();
$composer
->shouldReceive('customGuidelinePath')
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('Fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));

$guidelines = $composer->compose();
$overrideStringCount = substr_count((string) $guidelines, 'Thanks though, appreciate you');
Expand Down Expand Up @@ -442,7 +442,7 @@
$composer = Mockery::mock(GuidelineComposer::class, [$this->roster, $this->herd])->makePartial();
$composer
->shouldReceive('customGuidelinePath')
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('Fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));

$guidelines = $composer->compose();

Expand Down Expand Up @@ -640,7 +640,7 @@
$composer = Mockery::mock(GuidelineComposer::class, [$this->roster, $this->herd])->makePartial();
$composer
->shouldReceive('customGuidelinePath')
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));
->andReturnUsing(fn ($path = ''): string => realpath(testDirectory('Fixtures/.ai/guidelines')).'/'.ltrim((string) $path, '/'));

$packages = new PackageCollection([
new Package(Packages::LARAVEL, 'laravel/framework', '11.0.0'),
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/Middleware/InjectBoostTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Symfony\Component\HttpFoundation\StreamedResponse;

beforeEach(function (): void {
$this->app['view']->addNamespace('test', __DIR__.'/../../fixtures');
$this->app['view']->addNamespace('test', __DIR__.'/../../Fixtures');
});

function createMiddlewareResponse($response): SymfonyResponse
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 11 additions & 2 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

use Laravel\Mcp\Response;

use function Pest\testDirectory;

uses(Tests\TestCase::class)->in('Unit', 'Feature');

expect()->extend('isToolResult', fn () => $this->toBeInstanceOf(Response::class));
Expand Down Expand Up @@ -63,7 +65,14 @@
return $this;
});

function fixture(string $name): string
if (! function_exists('fixture')) {
function fixture(string $name): string
{
return testDirectory('Fixtures/'.$name);
}
}

function fixtureContent(string $name): string
{
return file_get_contents(\Pest\testDirectory('fixtures/'.$name));
return file_get_contents(fixture($name));
}
4 changes: 2 additions & 2 deletions tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ public function mcpConfigPath(): string
$vscode = new VSCode($this->strategyFactory);
$capturedPath = '';
$capturedContent = '';
$json5 = fixture('mcp.json5');
$json5 = fixtureContent('mcp.json5');

File::shouldReceive('exists')->once()->andReturn(true);
File::shouldReceive('size')->once()->andReturn(10);
Expand All @@ -403,7 +403,7 @@ public function mcpConfigPath(): string

expect($wasWritten)->toBeTrue()
->and($capturedPath)->toBe($vscode->mcpConfigPath())
->and($capturedContent)->toBe(fixture('mcp-expected.json5'));
->and($capturedContent)->toBe(fixtureContent('mcp-expected.json5'));
});

test('getPhpPath uses absolute paths when forceAbsolutePath is true', function (): void {
Expand Down
4 changes: 2 additions & 2 deletions tests/Unit/Install/GuidelineWriterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
$writer = new GuidelineWriter($agent);
$writer->write('test guidelines');

expect(is_dir(dirname($filePath)))->toBeTrue()
->and(file_exists($filePath))->toBeTrue();
expect(dirname($filePath))->toBeDirectory()
->and($filePath)->toBeFile();

// Cleanup
unlink($filePath);
Expand Down
Loading