From 9be69f1622aec9e0bfbd283c2bc027ccf7c560b4 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Tue, 25 Nov 2025 20:52:07 +0530 Subject: [PATCH 01/11] Add PHP 8.5 to ci Signed-off-by: Pushpak Chhajed --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 135c793a..f1c03ced 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,7 +23,7 @@ jobs: fail-fast: true matrix: os: [ ubuntu-22.04, windows-latest ] - php: [ 8.2, 8.3, 8.4 ] + php: [ 8.2, 8.3, 8.4, 8.5 ] laravel: [ 11, 12 ] name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.os }} From 57578a9e78f057a299c2e524d5e1d78d626202d6 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 13:17:24 +0530 Subject: [PATCH 02/11] Add PHP 8.5 Guidelines Signed-off-by: Pushpak Chhajed --- .ai/php/8.5/core.blade.php | 27 +++++++++++++++++++ composer.json | 6 ++--- src/Mcp/Tools/BrowserLogs.php | 5 ++-- src/Mcp/Tools/DatabaseQuery.php | 5 ++-- src/Mcp/Tools/DatabaseSchema.php | 5 ++-- src/Mcp/Tools/GetAbsoluteUrl.php | 5 ++-- src/Mcp/Tools/GetConfig.php | 5 ++-- src/Mcp/Tools/ListAvailableEnvVars.php | 5 ++-- src/Mcp/Tools/ListRoutes.php | 5 ++-- src/Mcp/Tools/ReadLogEntries.php | 5 ++-- src/Mcp/Tools/ReportFeedback.php | 5 ++-- src/Mcp/Tools/SearchDocs.php | 5 ++-- src/Mcp/Tools/Tinker.php | 5 ++-- .../Console/InstallCommandMultiselectTest.php | 18 +++++-------- tests/Feature/Middleware/InjectBoostTest.php | 2 +- tests/Pest.php | 4 +-- .../CodeEnvironment/CodeEnvironmentTest.php | 4 +-- tests/Unit/Install/GuidelineWriterTest.php | 4 +-- tests/Unit/Install/Mcp/FileWriterTest.php | 20 +++++++------- 19 files changed, 87 insertions(+), 53 deletions(-) create mode 100644 .ai/php/8.5/core.blade.php diff --git a/.ai/php/8.5/core.blade.php b/.ai/php/8.5/core.blade.php new file mode 100644 index 00000000..bb9ee482 --- /dev/null +++ b/.ai/php/8.5/core.blade.php @@ -0,0 +1,27 @@ +## PHP 8.5 + +- PHP 8.5 introduces new array functions for cleaner code: + - `array_first(array $array): mixed` - Get first value (or `null` if empty) + - `array_last(array $array): mixed` - Get last value (or `null` if empty) + +- The `#[\NoDiscard]` attribute warns when a function's return value is ignored. Use `(void)` cast to suppress intentionally. + +### Pipe Operator +- The pipe operator (`|>`) chains function calls left-to-right, replacing nested calls: + +// Before PHP 8.5 +$slug = strtolower(str_replace(' ', '-', trim($title))); + +// After PHP 8.5 +$slug = $title |> trim(...) |> (fn($s) => str_replace(' ', '-', $s)) |> strtolower(...); + + +### Clone With +- Properties can be modified during cloning using `clone($object, ['property' => $value])`: + +// Before PHP 8.5 (readonly classes required manual reconstruction) +$new = new User(...get_object_vars($user), role: 'admin'); + +// After PHP 8.5 +$new = clone($user, ['role' => 'admin']); + diff --git a/composer.json b/composer.json index f0a5961d..183e97e6 100644 --- a/composer.json +++ b/composer.json @@ -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": "^v1.26.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" }, diff --git a/src/Mcp/Tools/BrowserLogs.php b/src/Mcp/Tools/BrowserLogs.php index 4b316130..f3ef3d32 100644 --- a/src/Mcp/Tools/BrowserLogs.php +++ b/src/Mcp/Tools/BrowserLogs.php @@ -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; @@ -24,7 +25,7 @@ class BrowserLogs extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/DatabaseQuery.php b/src/Mcp/Tools/DatabaseQuery.php index 1f954037..45c8d663 100644 --- a/src/Mcp/Tools/DatabaseQuery.php +++ b/src/Mcp/Tools/DatabaseQuery.php @@ -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; @@ -23,7 +24,7 @@ class DatabaseQuery extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/DatabaseSchema.php b/src/Mcp/Tools/DatabaseSchema.php index 2069f93b..524fcab3 100644 --- a/src/Mcp/Tools/DatabaseSchema.php +++ b/src/Mcp/Tools/DatabaseSchema.php @@ -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; @@ -28,7 +29,7 @@ class DatabaseSchema extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/GetAbsoluteUrl.php b/src/Mcp/Tools/GetAbsoluteUrl.php index 300da97d..a22ea282 100644 --- a/src/Mcp/Tools/GetAbsoluteUrl.php +++ b/src/Mcp/Tools/GetAbsoluteUrl.php @@ -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; @@ -21,7 +22,7 @@ class GetAbsoluteUrl extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/GetConfig.php b/src/Mcp/Tools/GetConfig.php index 1d3d9c9b..31c97700 100644 --- a/src/Mcp/Tools/GetConfig.php +++ b/src/Mcp/Tools/GetConfig.php @@ -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; @@ -19,7 +20,7 @@ class GetConfig extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/ListAvailableEnvVars.php b/src/Mcp/Tools/ListAvailableEnvVars.php index 0615eecd..31f86283 100644 --- a/src/Mcp/Tools/ListAvailableEnvVars.php +++ b/src/Mcp/Tools/ListAvailableEnvVars.php @@ -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; @@ -21,7 +22,7 @@ class ListAvailableEnvVars extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/ListRoutes.php b/src/Mcp/Tools/ListRoutes.php index 77513a8b..08cf0a81 100644 --- a/src/Mcp/Tools/ListRoutes.php +++ b/src/Mcp/Tools/ListRoutes.php @@ -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; @@ -24,7 +25,7 @@ class ListRoutes extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/ReadLogEntries.php b/src/Mcp/Tools/ReadLogEntries.php index 38e6b946..3c2e234a 100644 --- a/src/Mcp/Tools/ReadLogEntries.php +++ b/src/Mcp/Tools/ReadLogEntries.php @@ -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; @@ -24,7 +25,7 @@ class ReadLogEntries extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/ReportFeedback.php b/src/Mcp/Tools/ReportFeedback.php index 6a238e9a..b3c83c9f 100644 --- a/src/Mcp/Tools/ReportFeedback.php +++ b/src/Mcp/Tools/ReportFeedback.php @@ -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; @@ -20,7 +21,7 @@ class ReportFeedback extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/SearchDocs.php b/src/Mcp/Tools/SearchDocs.php index 0ca065a9..23b34407 100644 --- a/src/Mcp/Tools/SearchDocs.php +++ b/src/Mcp/Tools/SearchDocs.php @@ -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; @@ -28,7 +29,7 @@ public function __construct(protected Roster $roster) {} /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/src/Mcp/Tools/Tinker.php b/src/Mcp/Tools/Tinker.php index f90237a7..67b5a024 100644 --- a/src/Mcp/Tools/Tinker.php +++ b/src/Mcp/Tools/Tinker.php @@ -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; @@ -21,7 +22,7 @@ class Tinker extends Tool /** * Get the tool's input schema. * - * @return array + * @return array */ public function schema(JsonSchema $schema): array { diff --git a/tests/Feature/Console/InstallCommandMultiselectTest.php b/tests/Feature/Console/InstallCommandMultiselectTest.php index ce6630a7..1d9729d3 100644 --- a/tests/Feature/Console/InstallCommandMultiselectTest.php +++ b/tests/Feature/Console/InstallCommandMultiselectTest.php @@ -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(); diff --git a/tests/Feature/Middleware/InjectBoostTest.php b/tests/Feature/Middleware/InjectBoostTest.php index 797efd14..1623a305 100644 --- a/tests/Feature/Middleware/InjectBoostTest.php +++ b/tests/Feature/Middleware/InjectBoostTest.php @@ -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 diff --git a/tests/Pest.php b/tests/Pest.php index 79ba034a..c15add9a 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -63,7 +63,7 @@ return $this; }); -function fixture(string $name): string +function fixtureContent(string $name): string { - return file_get_contents(\Pest\testDirectory('fixtures/'.$name)); + return file_get_contents(fixture($name)); } diff --git a/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php b/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php index 2f8d1fc5..b4a0a5f5 100644 --- a/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php +++ b/tests/Unit/Install/CodeEnvironment/CodeEnvironmentTest.php @@ -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); @@ -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 { diff --git a/tests/Unit/Install/GuidelineWriterTest.php b/tests/Unit/Install/GuidelineWriterTest.php index 7bbb5d87..7c879849 100644 --- a/tests/Unit/Install/GuidelineWriterTest.php +++ b/tests/Unit/Install/GuidelineWriterTest.php @@ -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); diff --git a/tests/Unit/Install/Mcp/FileWriterTest.php b/tests/Unit/Install/Mcp/FileWriterTest.php index 17405ef2..f83424de 100644 --- a/tests/Unit/Install/Mcp/FileWriterTest.php +++ b/tests/Unit/Install/Mcp/FileWriterTest.php @@ -69,7 +69,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp-plain.json'), + content: fixtureContent('mcp-plain.json'), capturedPath: $writtenPath, capturedContent: $writtenContent ); @@ -101,7 +101,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp-with-servers.json'), + content: fixtureContent('mcp-with-servers.json'), capturedPath: $writtenPath, capturedContent: $writtenContent ); @@ -129,7 +129,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp.json5'), + content: fixtureContent('mcp.json5'), capturedContent: $writtenContent ); @@ -153,7 +153,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp-comments-in-strings.json'), + content: fixtureContent('mcp-comments-in-strings.json'), capturedContent: $writtenContent ); @@ -220,7 +220,7 @@ }); test('fixture mcp-no-configkey.json5 is detected as JSON5 and will use injectNewConfigKey', function (): void { - $content = fixture('mcp-no-configkey.json5'); + $content = fixtureContent('mcp-no-configkey.json5'); $writer = new FileWriter('/tmp/test.json'); $reflection = new ReflectionClass($writer); @@ -241,7 +241,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp-no-configkey.json5'), + content: fixtureContent('mcp-no-configkey.json5'), capturedContent: $writtenContent ); @@ -266,7 +266,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp.json5'), + content: fixtureContent('mcp.json5'), capturedContent: $writtenContent ); @@ -296,7 +296,7 @@ File::shouldReceive('ensureDirectoryExists')->once(); File::shouldReceive('exists')->andReturn(true); File::shouldReceive('size')->andReturn(1000); - File::shouldReceive('get')->andReturn(fixture('mcp.json5')); + File::shouldReceive('get')->andReturn(fixtureContent('mcp.json5')); File::shouldReceive('put') ->with( Mockery::capture($capturedPath), @@ -351,7 +351,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp-empty-configkey.json5'), + content: fixtureContent('mcp-empty-configkey.json5'), capturedContent: $writtenContent ); @@ -375,7 +375,7 @@ mockFileOperations( fileExists: true, - content: fixture('mcp-trailing-comma.json5'), + content: fixtureContent('mcp-trailing-comma.json5'), capturedContent: $writtenContent ); From 7da7a93bc077a01453ffb73235d714102ea5aecf Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 14:06:42 +0530 Subject: [PATCH 03/11] Refine PHP 8.5 guidelines Signed-off-by: Pushpak Chhajed --- .ai/php/8.5/core.blade.php | 12 +----------- composer.json | 2 +- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.ai/php/8.5/core.blade.php b/.ai/php/8.5/core.blade.php index bb9ee482..6e4eae4a 100644 --- a/.ai/php/8.5/core.blade.php +++ b/.ai/php/8.5/core.blade.php @@ -4,7 +4,7 @@ - `array_first(array $array): mixed` - Get first value (or `null` if empty) - `array_last(array $array): mixed` - Get last value (or `null` if empty) -- The `#[\NoDiscard]` attribute warns when a function's return value is ignored. Use `(void)` cast to suppress intentionally. +- 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: @@ -15,13 +15,3 @@ // After PHP 8.5 $slug = $title |> trim(...) |> (fn($s) => str_replace(' ', '-', $s)) |> strtolower(...); - -### Clone With -- Properties can be modified during cloning using `clone($object, ['property' => $value])`: - -// Before PHP 8.5 (readonly classes required manual reconstruction) -$new = new User(...get_object_vars($user), role: 'admin'); - -// After PHP 8.5 -$new = clone($user, ['role' => 'admin']); - diff --git a/composer.json b/composer.json index 183e97e6..e78f970c 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "laravel/roster": "^0.2.9" }, "require-dev": { - "laravel/pint": "^v1.26.0", + "laravel/pint": "^v1.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|^4.1.5", From 291da56b869fea777ec223679f4a1bfb6571bbdd Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 17:31:06 +0530 Subject: [PATCH 04/11] Update matrix to include PHP 8.5 compatibility Signed-off-by: Pushpak Chhajed --- .github/workflows/tests.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f1c03ced..856497f8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,8 +23,15 @@ jobs: fail-fast: true matrix: os: [ ubuntu-22.04, windows-latest ] - php: [ 8.2, 8.3, 8.4, 8.5 ] + 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 }} From b9a88a89c5590ee27e8a3914f0ec5cdbf5353a32 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 17:38:12 +0530 Subject: [PATCH 05/11] Move fixtures to Fixtures Signed-off-by: Pushpak Chhajed --- tests/{fixtures => Fixtures}/.ai/guidelines/custom-rule.blade.php | 0 .../.ai/guidelines/laravel/11/core.blade.php | 0 .../.ai/guidelines/project-specific.blade.php | 0 .../.ai/guidelines/test-blade-with-assist.blade.php | 0 .../.ai/guidelines/test-blade-with-backticks.blade.php | 0 .../.ai/guidelines/test-blade-with-php-tags.blade.php | 0 tests/{fixtures => Fixtures}/.ai/guidelines/test-markdown.md | 0 tests/{fixtures => Fixtures}/injection-test.blade.php | 0 tests/{fixtures => Fixtures}/mcp-comments-in-strings.json | 0 tests/{fixtures => Fixtures}/mcp-empty-configkey.json5 | 0 tests/{fixtures => Fixtures}/mcp-empty.json | 0 tests/{fixtures => Fixtures}/mcp-expected.json5 | 0 tests/{fixtures => Fixtures}/mcp-no-configkey.json5 | 0 tests/{fixtures => Fixtures}/mcp-plain.json | 0 tests/{fixtures => Fixtures}/mcp-trailing-comma.json5 | 0 tests/{fixtures => Fixtures}/mcp-with-servers.json | 0 tests/{fixtures => Fixtures}/mcp.json5 | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename tests/{fixtures => Fixtures}/.ai/guidelines/custom-rule.blade.php (100%) rename tests/{fixtures => Fixtures}/.ai/guidelines/laravel/11/core.blade.php (100%) rename tests/{fixtures => Fixtures}/.ai/guidelines/project-specific.blade.php (100%) rename tests/{fixtures => Fixtures}/.ai/guidelines/test-blade-with-assist.blade.php (100%) rename tests/{fixtures => Fixtures}/.ai/guidelines/test-blade-with-backticks.blade.php (100%) rename tests/{fixtures => Fixtures}/.ai/guidelines/test-blade-with-php-tags.blade.php (100%) rename tests/{fixtures => Fixtures}/.ai/guidelines/test-markdown.md (100%) rename tests/{fixtures => Fixtures}/injection-test.blade.php (100%) rename tests/{fixtures => Fixtures}/mcp-comments-in-strings.json (100%) rename tests/{fixtures => Fixtures}/mcp-empty-configkey.json5 (100%) rename tests/{fixtures => Fixtures}/mcp-empty.json (100%) rename tests/{fixtures => Fixtures}/mcp-expected.json5 (100%) rename tests/{fixtures => Fixtures}/mcp-no-configkey.json5 (100%) rename tests/{fixtures => Fixtures}/mcp-plain.json (100%) rename tests/{fixtures => Fixtures}/mcp-trailing-comma.json5 (100%) rename tests/{fixtures => Fixtures}/mcp-with-servers.json (100%) rename tests/{fixtures => Fixtures}/mcp.json5 (100%) diff --git a/tests/fixtures/.ai/guidelines/custom-rule.blade.php b/tests/Fixtures/.ai/guidelines/custom-rule.blade.php similarity index 100% rename from tests/fixtures/.ai/guidelines/custom-rule.blade.php rename to tests/Fixtures/.ai/guidelines/custom-rule.blade.php diff --git a/tests/fixtures/.ai/guidelines/laravel/11/core.blade.php b/tests/Fixtures/.ai/guidelines/laravel/11/core.blade.php similarity index 100% rename from tests/fixtures/.ai/guidelines/laravel/11/core.blade.php rename to tests/Fixtures/.ai/guidelines/laravel/11/core.blade.php diff --git a/tests/fixtures/.ai/guidelines/project-specific.blade.php b/tests/Fixtures/.ai/guidelines/project-specific.blade.php similarity index 100% rename from tests/fixtures/.ai/guidelines/project-specific.blade.php rename to tests/Fixtures/.ai/guidelines/project-specific.blade.php diff --git a/tests/fixtures/.ai/guidelines/test-blade-with-assist.blade.php b/tests/Fixtures/.ai/guidelines/test-blade-with-assist.blade.php similarity index 100% rename from tests/fixtures/.ai/guidelines/test-blade-with-assist.blade.php rename to tests/Fixtures/.ai/guidelines/test-blade-with-assist.blade.php diff --git a/tests/fixtures/.ai/guidelines/test-blade-with-backticks.blade.php b/tests/Fixtures/.ai/guidelines/test-blade-with-backticks.blade.php similarity index 100% rename from tests/fixtures/.ai/guidelines/test-blade-with-backticks.blade.php rename to tests/Fixtures/.ai/guidelines/test-blade-with-backticks.blade.php diff --git a/tests/fixtures/.ai/guidelines/test-blade-with-php-tags.blade.php b/tests/Fixtures/.ai/guidelines/test-blade-with-php-tags.blade.php similarity index 100% rename from tests/fixtures/.ai/guidelines/test-blade-with-php-tags.blade.php rename to tests/Fixtures/.ai/guidelines/test-blade-with-php-tags.blade.php diff --git a/tests/fixtures/.ai/guidelines/test-markdown.md b/tests/Fixtures/.ai/guidelines/test-markdown.md similarity index 100% rename from tests/fixtures/.ai/guidelines/test-markdown.md rename to tests/Fixtures/.ai/guidelines/test-markdown.md diff --git a/tests/fixtures/injection-test.blade.php b/tests/Fixtures/injection-test.blade.php similarity index 100% rename from tests/fixtures/injection-test.blade.php rename to tests/Fixtures/injection-test.blade.php diff --git a/tests/fixtures/mcp-comments-in-strings.json b/tests/Fixtures/mcp-comments-in-strings.json similarity index 100% rename from tests/fixtures/mcp-comments-in-strings.json rename to tests/Fixtures/mcp-comments-in-strings.json diff --git a/tests/fixtures/mcp-empty-configkey.json5 b/tests/Fixtures/mcp-empty-configkey.json5 similarity index 100% rename from tests/fixtures/mcp-empty-configkey.json5 rename to tests/Fixtures/mcp-empty-configkey.json5 diff --git a/tests/fixtures/mcp-empty.json b/tests/Fixtures/mcp-empty.json similarity index 100% rename from tests/fixtures/mcp-empty.json rename to tests/Fixtures/mcp-empty.json diff --git a/tests/fixtures/mcp-expected.json5 b/tests/Fixtures/mcp-expected.json5 similarity index 100% rename from tests/fixtures/mcp-expected.json5 rename to tests/Fixtures/mcp-expected.json5 diff --git a/tests/fixtures/mcp-no-configkey.json5 b/tests/Fixtures/mcp-no-configkey.json5 similarity index 100% rename from tests/fixtures/mcp-no-configkey.json5 rename to tests/Fixtures/mcp-no-configkey.json5 diff --git a/tests/fixtures/mcp-plain.json b/tests/Fixtures/mcp-plain.json similarity index 100% rename from tests/fixtures/mcp-plain.json rename to tests/Fixtures/mcp-plain.json diff --git a/tests/fixtures/mcp-trailing-comma.json5 b/tests/Fixtures/mcp-trailing-comma.json5 similarity index 100% rename from tests/fixtures/mcp-trailing-comma.json5 rename to tests/Fixtures/mcp-trailing-comma.json5 diff --git a/tests/fixtures/mcp-with-servers.json b/tests/Fixtures/mcp-with-servers.json similarity index 100% rename from tests/fixtures/mcp-with-servers.json rename to tests/Fixtures/mcp-with-servers.json diff --git a/tests/fixtures/mcp.json5 b/tests/Fixtures/mcp.json5 similarity index 100% rename from tests/fixtures/mcp.json5 rename to tests/Fixtures/mcp.json5 From 9dd4e423f71a950248a007ce779e3fcf6d3ad57e Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 18:13:16 +0530 Subject: [PATCH 06/11] fix Test Signed-off-by: Pushpak Chhajed --- tests/Pest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Pest.php b/tests/Pest.php index c15add9a..e9463e77 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -14,6 +14,7 @@ */ use Laravel\Mcp\Response; +use function Pest\testDirectory; uses(Tests\TestCase::class)->in('Unit', 'Feature'); @@ -63,6 +64,13 @@ return $this; }); +if (! function_exists('fixture')) { + function fixture(string $name): string + { + return testDirectory('Fixtures/'.$name); + } +} + function fixtureContent(string $name): string { return file_get_contents(fixture($name)); From 799b9a36506e8171f4c54b2efd49f28f02d3761b Mon Sep 17 00:00:00 2001 From: pushpak1300 <31663512+pushpak1300@users.noreply.github.com> Date: Thu, 4 Dec 2025 12:43:50 +0000 Subject: [PATCH 07/11] Fix code styling --- tests/Pest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Pest.php b/tests/Pest.php index e9463e77..fc393e45 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -14,6 +14,7 @@ */ use Laravel\Mcp\Response; + use function Pest\testDirectory; uses(Tests\TestCase::class)->in('Unit', 'Feature'); From c1de9e70e5f3f2f89ad8c38b3964ed579d63afd6 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 18:36:12 +0530 Subject: [PATCH 08/11] Fix Test Signed-off-by: Pushpak Chhajed --- src/Install/GuidelineComposer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Install/GuidelineComposer.php b/src/Install/GuidelineComposer.php index 3056466d..6f4fa392 100644 --- a/src/Install/GuidelineComposer.php +++ b/src/Install/GuidelineComposer.php @@ -249,7 +249,8 @@ protected function guidelinesDir(string $dirPath, bool $thirdParty = false): arr ->files() ->in($dirPath) ->name('*.blade.php') - ->name('*.md'); + ->name('*.md') + ->ignoreUnreadableDirs(); } catch (DirectoryNotFoundException) { return []; } From c5c087e2794c37d5fc2a9dca1365e860ce294374 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 18:49:20 +0530 Subject: [PATCH 09/11] Fix Test Signed-off-by: Pushpak Chhajed --- src/Install/GuidelineComposer.php | 3 +-- tests/Feature/Install/GuidelineComposerTest.php | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Install/GuidelineComposer.php b/src/Install/GuidelineComposer.php index 6f4fa392..3056466d 100644 --- a/src/Install/GuidelineComposer.php +++ b/src/Install/GuidelineComposer.php @@ -249,8 +249,7 @@ protected function guidelinesDir(string $dirPath, bool $thirdParty = false): arr ->files() ->in($dirPath) ->name('*.blade.php') - ->name('*.md') - ->ignoreUnreadableDirs(); + ->name('*.md'); } catch (DirectoryNotFoundException) { return []; } diff --git a/tests/Feature/Install/GuidelineComposerTest.php b/tests/Feature/Install/GuidelineComposerTest.php index 6648682f..22b8132f 100644 --- a/tests/Feature/Install/GuidelineComposerTest.php +++ b/tests/Feature/Install/GuidelineComposerTest.php @@ -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 ===') @@ -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'); @@ -440,7 +440,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(); From b77e4a25dc7cc4f3db16d49b9bbe0fd176c1cba0 Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 18:55:52 +0530 Subject: [PATCH 10/11] Fix Test Signed-off-by: Pushpak Chhajed --- tests/Feature/Install/GuidelineComposerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Install/GuidelineComposerTest.php b/tests/Feature/Install/GuidelineComposerTest.php index 6e14fb61..51d1e046 100644 --- a/tests/Feature/Install/GuidelineComposerTest.php +++ b/tests/Feature/Install/GuidelineComposerTest.php @@ -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'), From e7359eda7b30a64f48a8cbfe21e12c3baeef756a Mon Sep 17 00:00:00 2001 From: Pushpak Chhajed Date: Thu, 4 Dec 2025 19:09:26 +0530 Subject: [PATCH 11/11] Formatting Signed-off-by: Pushpak Chhajed --- .ai/php/8.5/core.blade.php | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ai/php/8.5/core.blade.php b/.ai/php/8.5/core.blade.php index 6e4eae4a..312da05f 100644 --- a/.ai/php/8.5/core.blade.php +++ b/.ai/php/8.5/core.blade.php @@ -1,6 +1,6 @@ ## PHP 8.5 -- PHP 8.5 introduces new array functions for cleaner code: +- 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) diff --git a/composer.json b/composer.json index e78f970c..1df295a1 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "laravel/roster": "^0.2.9" }, "require-dev": { - "laravel/pint": "^v1.20.0", + "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|^4.1.5",