diff --git a/.cursor/mcp.json b/.cursor/mcp.json index 8c6715a151..21682bbfb0 100644 --- a/.cursor/mcp.json +++ b/.cursor/mcp.json @@ -1,11 +1,8 @@ { - "mcpServers": { - "laravel-boost": { - "command": "php", - "args": [ - "artisan", - "boost:mcp" - ] - } + "mcpServers": { + "laravel-boost": { + "command": "php", + "args": ["artisan", "boost:mcp"] } -} \ No newline at end of file + } +} diff --git a/.github/ISSUE_TEMPLATE/1-bug-report.yml b/.github/ISSUE_TEMPLATE/1-bug-report.yml index 15cce4409b..1727fc5a8d 100644 --- a/.github/ISSUE_TEMPLATE/1-bug-report.yml +++ b/.github/ISSUE_TEMPLATE/1-bug-report.yml @@ -1,6 +1,6 @@ name: πŸ› Bug Report description: File a bug report. -title: "[Bug]: " +title: '[Bug]: ' assignees: - phanan body: diff --git a/.github/ISSUE_TEMPLATE/2-feature-request.yml b/.github/ISSUE_TEMPLATE/2-feature-request.yml index 93052b603a..587cfd8b95 100644 --- a/.github/ISSUE_TEMPLATE/2-feature-request.yml +++ b/.github/ISSUE_TEMPLATE/2-feature-request.yml @@ -1,6 +1,6 @@ name: πŸ’‘Feature request description: Request a new feature or improvement. -title: "[FR]: " +title: '[FR]: ' assignees: - phanan body: diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 4435733435..d608b6f66f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -6,6 +6,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications. ## Foundational Context + This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. - php - 8.4.20 @@ -23,46 +24,58 @@ This application is a Laravel application and its main Laravel ecosystems packag - tailwindcss (TAILWINDCSS) - v4 ## Conventions + - You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming. - Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`. - Check for existing components to reuse before writing a new one. ## Verification Scripts + - Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. ## Application Structure & Architecture + - Stick to existing directory structure; don't create new base folders without approval. - Do not change the application's dependencies without approval. ## Frontend Bundling + - If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `pnpm run build`, `pnpm run dev`, or `composer run dev`. Ask them. ## Replies + - Be concise in your explanations - focus on what's important rather than explaining obvious details. ## Documentation Files + - You must only create documentation files if explicitly requested by the user. === boost rules === ## Laravel Boost + - Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. ## Artisan + - Use the `list-artisan-commands` tool when you need to call an Artisan command to double-check the available parameters. ## URLs + - Whenever you share a project URL with the user, you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain/IP, and port. ## Tinker / Debugging + - You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly. - Use the `database-query` tool when you only need to read from the database. ## Reading Browser Logs With the `browser-logs` Tool + - You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost. - Only recent browser logs will be useful - ignore old logs. ## Searching Documentation (Critically Important) + - Boost comes with a powerful `search-docs` tool you should use before any other approaches when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. - The `search-docs` tool is perfect for all Laravel-related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. - You must use this tool to search for Laravel ecosystem documentation before falling back to other approaches. @@ -71,6 +84,7 @@ This application is a Laravel application and its main Laravel ecosystems packag - Do not add package names to queries; package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. ### Available Search Syntax + - You can and should pass multiple queries at once. The most relevant results will be returned first. 1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'. @@ -86,11 +100,13 @@ This application is a Laravel application and its main Laravel ecosystems packag - Always use curly braces for control structures, even if it has one line. ### Constructors + - Use PHP 8 constructor property promotion in `__construct()`. - - public function __construct(public GitHub $github) { } + - public function __construct(public GitHub $github) { } - Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. ### Type Declarations + - Always use explicit return type declarations for methods and functions. - Use appropriate PHP type hints for method parameters. @@ -102,12 +118,15 @@ protected function isAccessible(User $user, ?string $path = null): bool ## Comments + - Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless there is something very complex going on. ## PHPDoc Blocks + - Add useful array shape type definitions for arrays when appropriate. ## Enums + - Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. === tests rules === @@ -126,6 +145,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior. ### Database + - Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. - Use Eloquent models and relationships before suggesting raw database queries. - Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them. @@ -133,33 +153,42 @@ protected function isAccessible(User $user, ?string $path = null): bool - Use Laravel's query builder for very complex database operations. ### Model Creation + - When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. ### APIs & Eloquent Resources + - For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention. ### Controllers & Validation + - Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. - Check sibling Form Requests to see if the application uses array or string based validation rules. ### Queues + - Use queued jobs for time-consuming operations with the `ShouldQueue` interface. ### Authentication & Authorization + - Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). ### URL Generation + - When generating links to other pages, prefer named routes and the `route()` function. ### Configuration + - Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`. ### Testing + - When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model. - Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`. - When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. ### Vite Error + - If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `pnpm run build` or ask the user to run `pnpm run dev` or `composer run dev`. === laravel/v12 rules === @@ -170,6 +199,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - Since Laravel 11, Laravel has a new streamlined file structure which this project uses. ### Laravel 12 Structure + - In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`. - Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`. - `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. @@ -178,10 +208,12 @@ protected function isAccessible(User $user, ?string $path = null): bool - Console commands in `app/Console/Commands/` are automatically available and do not require manual registration. ### Database + - When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. - Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. ### Models + - Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. === phpunit/core rules === @@ -196,6 +228,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files; these are core to the application. ### Running Tests + - Run the minimal number of tests, using an appropriate filter, before finalizing. - To run all tests: `php artisan test --compact`. - To run all tests in a file: `php artisan test --compact tests/Feature/ExampleTest.php`. @@ -211,6 +244,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - You can use the `search-docs` tool to get exact examples from the official documentation when needed. ### Spacing + - When listing items, use gap utilities for spacing; don't use margins. @@ -222,6 +256,7 @@ protected function isAccessible(User $user, ?string $path = null): bool ### Dark Mode + - If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. === tailwindcss/v4 rules === @@ -248,10 +283,11 @@ protected function isAccessible(User $user, ?string $path = null): bool ### Replaced Utilities + - Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. - Opacity values are still numeric. -| Deprecated | Replacement | +| Deprecated | Replacement | |------------+--------------| | bg-opacity-* | bg-black/* | | text-opacity-* | text-black/* | diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 74cf425789..ae8d93090c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,14 +3,17 @@ Thank you for contributing to Koel! Please provide a clear description of your c --> ## Description + ## Motivation + ## Screenshots (if applicable) ## Checklist + - [ ] I've tested my changes thoroughly and added tests where applicable - [ ] I've updated relevant documentation (if any) - [ ] My code follows the project's conventions diff --git a/.github/workflows/lint-backend.yml b/.github/workflows/lint-backend.yml index 5b9981cdbf..0dccc69633 100644 --- a/.github/workflows/lint-backend.yml +++ b/.github/workflows/lint-backend.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: [ 8.3 ] + php-version: [8.3] steps: - uses: actions/checkout@v6 - name: Set up PHP diff --git a/.github/workflows/lint-frontend.yml b/.github/workflows/lint-frontend.yml index b59d684540..17d40aa981 100644 --- a/.github/workflows/lint-frontend.yml +++ b/.github/workflows/lint-frontend.yml @@ -26,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [ 22 ] + node-version: [22] steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 81ebb6f91a..d3c59f2fc1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: - name: Install PHP dependencies uses: ramsey/composer-install@v2 with: - composer-options: "--prefer-dist --no-dev --optimize-autoloader" + composer-options: '--prefer-dist --no-dev --optimize-autoloader' - name: Set up Node uses: actions/setup-node@v6 with: diff --git a/.github/workflows/test-backend-mariadb.yml b/.github/workflows/test-backend-mariadb.yml index bbf815f748..cb3a3fc33c 100644 --- a/.github/workflows/test-backend-mariadb.yml +++ b/.github/workflows/test-backend-mariadb.yml @@ -20,8 +20,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: [ 8.3 ] - mariadb-version: [ 11.7 ] + php-version: [8.3] + mariadb-version: [11.7] fail-fast: false services: mariadb: diff --git a/.github/workflows/test-backend-pgsql.yml b/.github/workflows/test-backend-pgsql.yml index bbfc8e350f..d8ba14d360 100644 --- a/.github/workflows/test-backend-pgsql.yml +++ b/.github/workflows/test-backend-pgsql.yml @@ -20,8 +20,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: [ 8.3 ] - postgres-version: [ 15 ] + php-version: [8.3] + postgres-version: [15] fail-fast: false services: postgres: diff --git a/.github/workflows/test-backend-sqlite.yml b/.github/workflows/test-backend-sqlite.yml index 357f1887a1..9974b0fefd 100644 --- a/.github/workflows/test-backend-sqlite.yml +++ b/.github/workflows/test-backend-sqlite.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: [ 8.3 ] + php-version: [8.3] fail-fast: false steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/unit-frontend.yml b/.github/workflows/unit-frontend.yml index d159d6635a..8a3e28299e 100644 --- a/.github/workflows/unit-frontend.yml +++ b/.github/workflows/unit-frontend.yml @@ -26,8 +26,8 @@ jobs: strategy: fail-fast: false matrix: - node-version: [ 22 ] - shard: [ 1/3, 2/3, 3/3 ] + node-version: [22] + shard: [1/3, 2/3, 3/3] steps: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v6 diff --git a/.junie/guidelines.md b/.junie/guidelines.md index 4435733435..d608b6f66f 100644 --- a/.junie/guidelines.md +++ b/.junie/guidelines.md @@ -6,6 +6,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications. ## Foundational Context + This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. - php - 8.4.20 @@ -23,46 +24,58 @@ This application is a Laravel application and its main Laravel ecosystems packag - tailwindcss (TAILWINDCSS) - v4 ## Conventions + - You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming. - Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`. - Check for existing components to reuse before writing a new one. ## Verification Scripts + - Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. ## Application Structure & Architecture + - Stick to existing directory structure; don't create new base folders without approval. - Do not change the application's dependencies without approval. ## Frontend Bundling + - If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `pnpm run build`, `pnpm run dev`, or `composer run dev`. Ask them. ## Replies + - Be concise in your explanations - focus on what's important rather than explaining obvious details. ## Documentation Files + - You must only create documentation files if explicitly requested by the user. === boost rules === ## Laravel Boost + - Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. ## Artisan + - Use the `list-artisan-commands` tool when you need to call an Artisan command to double-check the available parameters. ## URLs + - Whenever you share a project URL with the user, you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain/IP, and port. ## Tinker / Debugging + - You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly. - Use the `database-query` tool when you only need to read from the database. ## Reading Browser Logs With the `browser-logs` Tool + - You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost. - Only recent browser logs will be useful - ignore old logs. ## Searching Documentation (Critically Important) + - Boost comes with a powerful `search-docs` tool you should use before any other approaches when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. - The `search-docs` tool is perfect for all Laravel-related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. - You must use this tool to search for Laravel ecosystem documentation before falling back to other approaches. @@ -71,6 +84,7 @@ This application is a Laravel application and its main Laravel ecosystems packag - Do not add package names to queries; package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. ### Available Search Syntax + - You can and should pass multiple queries at once. The most relevant results will be returned first. 1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'. @@ -86,11 +100,13 @@ This application is a Laravel application and its main Laravel ecosystems packag - Always use curly braces for control structures, even if it has one line. ### Constructors + - Use PHP 8 constructor property promotion in `__construct()`. - - public function __construct(public GitHub $github) { } + - public function __construct(public GitHub $github) { } - Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. ### Type Declarations + - Always use explicit return type declarations for methods and functions. - Use appropriate PHP type hints for method parameters. @@ -102,12 +118,15 @@ protected function isAccessible(User $user, ?string $path = null): bool ## Comments + - Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless there is something very complex going on. ## PHPDoc Blocks + - Add useful array shape type definitions for arrays when appropriate. ## Enums + - Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. === tests rules === @@ -126,6 +145,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior. ### Database + - Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. - Use Eloquent models and relationships before suggesting raw database queries. - Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them. @@ -133,33 +153,42 @@ protected function isAccessible(User $user, ?string $path = null): bool - Use Laravel's query builder for very complex database operations. ### Model Creation + - When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. ### APIs & Eloquent Resources + - For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention. ### Controllers & Validation + - Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. - Check sibling Form Requests to see if the application uses array or string based validation rules. ### Queues + - Use queued jobs for time-consuming operations with the `ShouldQueue` interface. ### Authentication & Authorization + - Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). ### URL Generation + - When generating links to other pages, prefer named routes and the `route()` function. ### Configuration + - Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`. ### Testing + - When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model. - Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`. - When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. ### Vite Error + - If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `pnpm run build` or ask the user to run `pnpm run dev` or `composer run dev`. === laravel/v12 rules === @@ -170,6 +199,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - Since Laravel 11, Laravel has a new streamlined file structure which this project uses. ### Laravel 12 Structure + - In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`. - Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`. - `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. @@ -178,10 +208,12 @@ protected function isAccessible(User $user, ?string $path = null): bool - Console commands in `app/Console/Commands/` are automatically available and do not require manual registration. ### Database + - When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. - Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. ### Models + - Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. === phpunit/core rules === @@ -196,6 +228,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files; these are core to the application. ### Running Tests + - Run the minimal number of tests, using an appropriate filter, before finalizing. - To run all tests: `php artisan test --compact`. - To run all tests in a file: `php artisan test --compact tests/Feature/ExampleTest.php`. @@ -211,6 +244,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - You can use the `search-docs` tool to get exact examples from the official documentation when needed. ### Spacing + - When listing items, use gap utilities for spacing; don't use margins. @@ -222,6 +256,7 @@ protected function isAccessible(User $user, ?string $path = null): bool ### Dark Mode + - If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. === tailwindcss/v4 rules === @@ -248,10 +283,11 @@ protected function isAccessible(User $user, ?string $path = null): bool ### Replaced Utilities + - Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. - Opacity values are still numeric. -| Deprecated | Replacement | +| Deprecated | Replacement | |------------+--------------| | bg-opacity-* | bg-black/* | | text-opacity-* | text-black/* | diff --git a/.junie/mcp/mcp.json b/.junie/mcp/mcp.json index 334edc6fd5..3242e7b13c 100644 --- a/.junie/mcp/mcp.json +++ b/.junie/mcp/mcp.json @@ -1,11 +1,8 @@ { - "mcpServers": { - "laravel-boost": { - "command": "/Users/an/Library/Application Support/Herd/bin/php83", - "args": [ - "/Users/an/OSS/koel/koel/artisan", - "boost:mcp" - ] - } + "mcpServers": { + "laravel-boost": { + "command": "/Users/an/Library/Application Support/Herd/bin/php83", + "args": ["/Users/an/OSS/koel/koel/artisan", "boost:mcp"] } -} \ No newline at end of file + } +} diff --git a/.mcp.json b/.mcp.json index 8c6715a151..21682bbfb0 100644 --- a/.mcp.json +++ b/.mcp.json @@ -1,11 +1,8 @@ { - "mcpServers": { - "laravel-boost": { - "command": "php", - "args": [ - "artisan", - "boost:mcp" - ] - } + "mcpServers": { + "laravel-boost": { + "command": "php", + "args": ["artisan", "boost:mcp"] } -} \ No newline at end of file + } +} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..5a801366e4 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +# vite-plus preview build registry bridge (auto-added by vp) +registry=https://registry-bridge.viteplus.dev/ diff --git a/.vscode/mcp.json b/.vscode/mcp.json index 5d3724c4ba..2189c2496b 100644 --- a/.vscode/mcp.json +++ b/.vscode/mcp.json @@ -1,11 +1,8 @@ { - "servers": { - "laravel-boost": { - "command": "php", - "args": [ - "artisan", - "boost:mcp" - ] - } + "servers": { + "laravel-boost": { + "command": "php", + "args": ["artisan", "boost:mcp"] } -} \ No newline at end of file + } +} diff --git a/AGENTS.md b/AGENTS.md index 1b09c09e6c..bd96e9ecd8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,6 +6,7 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications. ## Foundational Context + This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. - php - 8.4.20 @@ -23,46 +24,58 @@ This application is a Laravel application and its main Laravel ecosystems packag - tailwindcss (TAILWINDCSS) - v4 ## Conventions + - You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming. - Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`. - Check for existing components to reuse before writing a new one. ## Verification Scripts + - Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. ## Application Structure & Architecture + - Stick to existing directory structure; don't create new base folders without approval. - Do not change the application's dependencies without approval. ## Frontend Bundling + - If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `pnpm run build`, `pnpm run dev`, or `composer run dev`. Ask them. ## Replies + - Be concise in your explanations - focus on what's important rather than explaining obvious details. ## Documentation Files + - You must only create documentation files if explicitly requested by the user. === boost rules === ## Laravel Boost + - Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. ## Artisan + - Use the `list-artisan-commands` tool when you need to call an Artisan command to double-check the available parameters. ## URLs + - Whenever you share a project URL with the user, you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain/IP, and port. ## Tinker / Debugging + - You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly. - Use the `database-query` tool when you only need to read from the database. ## Reading Browser Logs With the `browser-logs` Tool + - You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost. - Only recent browser logs will be useful - ignore old logs. ## Searching Documentation (Critically Important) + - Boost comes with a powerful `search-docs` tool you should use before any other approaches when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. - The `search-docs` tool is perfect for all Laravel-related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. - You must use this tool to search for Laravel ecosystem documentation before falling back to other approaches. @@ -71,6 +84,7 @@ This application is a Laravel application and its main Laravel ecosystems packag - Do not add package names to queries; package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. ### Available Search Syntax + - You can and should pass multiple queries at once. The most relevant results will be returned first. 1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'. @@ -86,11 +100,13 @@ This application is a Laravel application and its main Laravel ecosystems packag - Always use curly braces for control structures, even if it has one line. ### Constructors + - Use PHP 8 constructor property promotion in `__construct()`. - - public function __construct(public GitHub $github) { } + - public function __construct(public GitHub $github) { } - Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. ### Type Declarations + - Always use explicit return type declarations for methods and functions. - Use appropriate PHP type hints for method parameters. @@ -102,12 +118,15 @@ protected function isAccessible(User $user, ?string $path = null): bool ## Comments + - Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless there is something very complex going on. ## PHPDoc Blocks + - Add useful array shape type definitions for arrays when appropriate. ## Enums + - Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. === tests rules === @@ -126,6 +145,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior. ### Database + - Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. - Use Eloquent models and relationships before suggesting raw database queries. - Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them. @@ -133,33 +153,42 @@ protected function isAccessible(User $user, ?string $path = null): bool - Use Laravel's query builder for very complex database operations. ### Model Creation + - When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. ### APIs & Eloquent Resources + - For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention. ### Controllers & Validation + - Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. - Check sibling Form Requests to see if the application uses array or string based validation rules. ### Queues + - Use queued jobs for time-consuming operations with the `ShouldQueue` interface. ### Authentication & Authorization + - Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). ### URL Generation + - When generating links to other pages, prefer named routes and the `route()` function. ### Configuration + - Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`. ### Testing + - When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model. - Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`. - When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. ### Vite Error + - If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `pnpm run build` or ask the user to run `pnpm run dev` or `composer run dev`. === laravel/v12 rules === @@ -170,6 +199,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - Since Laravel 11, Laravel has a new streamlined file structure which this project uses. ### Laravel 12 Structure + - In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`. - Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`. - `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. @@ -178,10 +208,12 @@ protected function isAccessible(User $user, ?string $path = null): bool - Console commands in `app/Console/Commands/` are automatically available and do not require manual registration. ### Database + - When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. - Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. ### Models + - Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. === phpunit/core rules === @@ -196,6 +228,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files; these are core to the application. ### Running Tests + - Run the minimal number of tests, using an appropriate filter, before finalizing. - To run all tests: `php artisan test --compact`. - To run all tests in a file: `php artisan test --compact tests/Feature/ExampleTest.php`. @@ -211,6 +244,7 @@ protected function isAccessible(User $user, ?string $path = null): bool - You can use the `search-docs` tool to get exact examples from the official documentation when needed. ### Spacing + - When listing items, use gap utilities for spacing; don't use margins. @@ -222,6 +256,7 @@ protected function isAccessible(User $user, ?string $path = null): bool ### Dark Mode + - If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. === tailwindcss/v4 rules === @@ -248,10 +283,11 @@ protected function isAccessible(User $user, ?string $path = null): bool ### Replaced Utilities + - Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. - Opacity values are still numeric. -| Deprecated | Replacement | +| Deprecated | Replacement | |------------+--------------| | bg-opacity-* | bg-black/* | | text-opacity-* | text-black/* | @@ -267,21 +303,26 @@ protected function isAccessible(User $user, ?string $path = null): bool ## Architecture + - Koel loads data progressively β€” there is no method to fetch all songs at once. Songs are loaded lazily per screen/context. This is by design for large libraries. Never assume the playable store vault contains all songs. ## Code Organization + - Traits must be placed in a `Concerns` subfolder (namespace) relative to their consumers (e.g. `App\Ai\Tools\Concerns\PlaysMusic`). - Interfaces must be placed in a `Contracts` subfolder (namespace) relative to their consumers (e.g. `App\Ai\Tools\Contracts\SomeInterface`). ## Spelling + - Use US English spelling for all identifiers (PHP method/class/property names, TS/Vue variables and components), comments, docstrings, doc pages, and user-visible strings: `serialize` / `serializer` (not `serialise`), `color` (not `colour`), `initialize` (not `initialise`), `behavior` (not `behaviour`), `organize` / `organization`, `favorite`, `analyze`. Koel's codebase β€” and PHP's SPL (`JsonSerializable`) β€” is uniformly American; don't drift British by reflex. ## Self-Explanatory Code + - Code should read on its own. If a piece of code needs a comment to be understood, that's a signal the code is wrong, not that the comment is needed β€” refactor it: extract a named helper, rename a variable to encode intent, lift a condition into a named flag, pull a block into a small function. Use a comment only when refactoring genuinely can't carry the intent (a hidden invariant, a workaround tied to a specific external bug, behaviour a reader would otherwise misjudge). Never write comments that narrate the next line, summarise the surrounding block, or restate what well-named identifiers already say. - Don't use single-letter variable names. The only allowed ones are `i` / `j` for loop counters, `h` for the test harness, and `$e` for the exception variable in `catch (Throwable|Exception|Error $e)` blocks (PHP's universal idiom β€” analogous to `e` for events in JS/TS event handlers). For everything else (callback params, destructured fields, lambda args, etc.) pick a name that says what it is. - Never combine assignment with return. Always `$x = expr;` then `return $x;` on a separate line β€” `return $x = expr;` cramming two effects into one statement is forbidden in PHP, TS, and JS. ## PHP Conventions + - Always prefer Laravel's built-in helpers over custom implementations (e.g. `str()->plural()`, `Str::slug()`, `Arr::flatten()`, etc.). Do not reimplement what Laravel already provides. - For guard clauses that throw on a condition, always reach for `throw_if($condition, ExceptionClass::class, ...$args)` / `throw_unless($condition, ExceptionClass::class, ...$args)` before writing `if (…) { throw new …; }`. The Laravel helpers read as a single declarative line, and the extra args are forwarded to the exception constructor. Plain `if`/`throw` is only correct when the throw branch has to do additional work (logging, side effects) before throwing. - All methods must have explicit visibility (`public`, `protected`, or `private`). Never omit the visibility keyword, even on interface methods or static methods. @@ -300,80 +341,96 @@ protected function isAccessible(User $user, ?string $path = null): bool - Value objects in `app/Values/` must use a `final readonly class` with a `private __construct(...)` and a `public static function make(...): self` factory. Call sites construct them via `Foo::make(...)`, never `new Foo(...)`. The reference shape is `App\Values\Radio\RadioStationCreateData`. ## Environment Variables Documentation + - When adding, removing, or modifying environment variables in `.env.example`, always update `docs/environment-variables.md` to stay in sync. ## Documentation Pages + - Every doc page under `docs/` must have a `description` in its YAML frontmatter. When creating or editing a doc page, ensure the description accurately summarizes the page content. - The docs use `vitepress-plugin-llms` to generate `llms.txt` and `llms-full.txt` on build; descriptions are surfaced there. - Run `bash docs/.vitepress/check-frontmatter.sh` to verify all pages have descriptions. -- **Write docs for users, not engineers.** Be concise, use simple words, be friendly. Lead with the action ("To upgrade: 1. Download. 2. Extract. 3. Restart."), not the rationale. Don't explain how launcher scripts or commands work internally β€” users want to know *what to do*, not *how the script reasons about it*. Cut corporate-speak ("turnkey path", "conceptually immutable", "provisions with the conventional layout"), nerdy parentheticals ("(`migrate` is idempotent β€” Laravel skips already-applied ones)"), and redundant warnings already covered elsewhere on the page. -- **Don't inject your own judgment into docs.** No "isn't straightforward", "is usually easier", "you'd need to", "this is the recommended path", "for most users", "if you really want to". Don't editorialize difficulty, opinion-rate alternatives, or steer the reader toward what *you* think they should do. Users decided to read this section; just give them the steps. +- **Write docs for users, not engineers.** Be concise, use simple words, be friendly. Lead with the action ("To upgrade: 1. Download. 2. Extract. 3. Restart."), not the rationale. Don't explain how launcher scripts or commands work internally β€” users want to know _what to do_, not _how the script reasons about it_. Cut corporate-speak ("turnkey path", "conceptually immutable", "provisions with the conventional layout"), nerdy parentheticals ("(`migrate` is idempotent β€” Laravel skips already-applied ones)"), and redundant warnings already covered elsewhere on the page. +- **Don't inject your own judgment into docs.** No "isn't straightforward", "is usually easier", "you'd need to", "this is the recommended path", "for most users", "if you really want to". Don't editorialize difficulty, opinion-rate alternatives, or steer the reader toward what _you_ think they should do. Users decided to read this section; just give them the steps. - **No clever bash one-liners for trivial tasks.** Don't reach for `diff <(grep -oE … | sort -u) <(…)` when the instruction is "compare two files" β€” users can eyeball them. Process substitution, awk, sed pipelines, and similar are nerd-bait. If the task is "look at the difference between A and B", say that in English. Reserve shell snippets for things the user actually needs the exact incantation for. ## Git Commits + - Use [Conventional Commits](https://www.conventionalcommits.org/) for all commit messages (e.g. `fix:`, `feat:`, `chore:`, `test:`, `refactor:`, `docs:`, `ci:`, etc.). - Focus on the feature/purpose, not implementation details. For example, prefer "feat: show current playing song during radio stream" over "feat: radio station ICY metadata now-playing". Same applies to PR titles. - Never attribute work to AI in any artifact: no "Generated with Claude Code", "Assisted by AI", "Co-Authored-By: Claude/ChatGPT/Copilot/AI" lines, no AI-tool mentions in commits, PR titles, PR descriptions, issue comments, code comments, or doc pages. The author is the human running the tool. - When the implementation of a PR changes (e.g. during code review), always update the PR title and description to reflect the current state of the changes. ## Releasing + - To release a new version, run `php artisan koel:release` (interactive) or `php artisan koel:release {patch|minor|major|vX.Y.Z}`. The command handles the version bump, commit, tag, `latest` tag move, and `release` branch sync. - Do not bump `.version`, create release tags, or move the `latest` tag manually β€” always use `php artisan koel:release`. - After the command finishes, the draft release is **not** immediately available on https://github.com/koel/koel/releases. The tag push triggers the `Upload Release Assets` GitHub Action (`.github/workflows/release.yml`), which sets up PHP/Node, builds assets, packages the zip/tarball, and only then creates the draft release. This typically takes several minutes. - Wait for the workflow to finish before opening the releases page. Poll with `gh run list --workflow=release.yml --limit 1` or block on it with `gh run watch` (pick the most recent run). Once it's `completed/success`, the draft release exists and can be edited/published on GitHub. - For minor/patch releases, you may be asked to write the release notes. Follow the convention of prior releases (e.g. v9.1.1, v9.1.0, v8.3.1): - - Title: `vX.Y.Z` (no codename β€” codenames are reserved for major versions like "Beethoven" in v9.0.0, "Tchaikovsky" in v8.0.0). - - Body matches GitHub's auto-generated format. Easiest way: `gh api repos/koel/koel/releases/generate-notes -F tag_name=vX.Y.Z -F previous_tag_name=vPREV --jq .body` to fetch the auto-generated body, then apply it with `gh release edit vX.Y.Z --repo koel/koel --notes-file -`. - - Required structure: a `## What's Changed` section with bullets in the form `* by @ in `, optionally a `## New Contributors` section, and a trailing `**Full Changelog**: https://github.com/koel/koel/compare/vPREV...vX.Y.Z` line. - - Do not rewrite or summarize commit subjects β€” keep them verbatim. Direct-to-master commits without PRs link to the commit SHA URL instead of a PR URL. - - **Publish (un-draft) the release before tagging koel/franken or koel/docker.** Both downstream build scripts `curl https://github.com/koel/koel/releases/download/vX.Y.Z/koel-vX.Y.Z.tar.gz`, and that URL returns 404 for draft releases β€” the build fails. Apply notes and publish in one shot: `gh release edit vX.Y.Z --repo koel/koel --notes-file /tmp/notes.md --draft=false`. Only leave it as a draft if you're releasing koel/koel in isolation (no franken/docker companion). + - Title: `vX.Y.Z` (no codename β€” codenames are reserved for major versions like "Beethoven" in v9.0.0, "Tchaikovsky" in v8.0.0). + - Body matches GitHub's auto-generated format. Easiest way: `gh api repos/koel/koel/releases/generate-notes -F tag_name=vX.Y.Z -F previous_tag_name=vPREV --jq .body` to fetch the auto-generated body, then apply it with `gh release edit vX.Y.Z --repo koel/koel --notes-file -`. + - Required structure: a `## What's Changed` section with bullets in the form `* by @ in `, optionally a `## New Contributors` section, and a trailing `**Full Changelog**: https://github.com/koel/koel/compare/vPREV...vX.Y.Z` line. + - Do not rewrite or summarize commit subjects β€” keep them verbatim. Direct-to-master commits without PRs link to the commit SHA URL instead of a PR URL. + - **Publish (un-draft) the release before tagging koel/franken or koel/docker.** Both downstream build scripts `curl https://github.com/koel/koel/releases/download/vX.Y.Z/koel-vX.Y.Z.tar.gz`, and that URL returns 404 for draft releases β€” the build fails. Apply notes and publish in one shot: `gh release edit vX.Y.Z --repo koel/koel --notes-file /tmp/notes.md --draft=false`. Only leave it as a draft if you're releasing koel/koel in isolation (no franken/docker companion). - If a downstream build fails because koel/koel was still a draft at the time, recover with `gh workflow run release.yml --repo koel/franken -f koel_version=vX.Y.Z` for franken. koel/docker has no such input β€” koel/docker#226 removed `workflow_dispatch` so a tag push is the only way to release β€” so recover there with `gh run rerun --repo koel/docker`, which replays the build against the tag that already exists. ## AI Assistant Tools + - When AI assistant tool capabilities change (added, removed, or updated), always update the sample prompts in `AiSamplePrompts.vue` to reflect the current abilities. ## Lucide Icons + - When importing icons from `lucide-vue-next`, always use the `Icon` suffix (e.g. `SparklesIcon`, not `Sparkles`; `SearchIcon`, not `Search`). ## TypeScript Conventions + - Always prefer generics over type casting when the API supports it (e.g. `container.querySelector('.foo')` instead of `container.querySelector('.foo') as HTMLElement`). - Do not add explicit return types when they can be inferred by the compiler. Only annotate return types when inference is insufficient or ambiguous. - When using `setTimeout`, `setInterval`, or `requestAnimationFrame`, always ensure they are cleaned up: on component unmount (`onBeforeUnmount`), on state transitions that invalidate them (e.g. drop cancels a pending expand), and when the operation completes. Treat every timer/rAF as a resource that must be explicitly released. ## Vue Template Conventions + - Always use Vue's same-name shorthand for bindings: `:foo` instead of `:foo="foo"`. This applies to props, components, and any v-bind where the attribute name matches the variable name. ## Vue Forms + - Any Vue surface that takes user input and commits it on submit must use the `useForm` composable from `@/composables/useForm` β€” including inline composers, popovers, and mini name-prompts that aren't named `*Form.vue`. Don't roll your own `ref('')` + manual submit handling. - Pair it with the canonical wiring: `
`, inputs use `v-koel-focus` (not manual `onMounted` focus) and `required` (not manual `:disabled`), Save is ``, Cancel is ``, and `maybeClose` does `if (isPristine() || (await showConfirmDialog(...))) emit('cancel')`. - For purely-local submits (no server call), pass `useOverlay: false` and have `onSubmit` just emit. Use the optional `validator` callback for non-HTML5 rules (e.g. trim/whitespace). - Read `resources/assets/js/components/playlist/CreatePlaylistFolderForm.vue` before writing a new form β€” that's the reference shape. ## Vue Component Decomposition + - Always try to break Vue components into smaller, self-managed-state subcomponents. A component that hosts multiple stages, multiple modes, or multiple distinct UI shapes should split each into its own focused child. The parent becomes a thin orchestrator (state machine + API calls + composition); each child owns one shape with clear props in and events out, no service dependencies of its own, and is testable in isolation with minimal mocks. Reference shape: `TwoFactorAuthSettings.vue` (orchestrator) β†’ `TwoFactorEnrollment.vue` / `TwoFactorRecoveryCodes.vue` / `TwoFactorManageActions.vue` (focused children). ## Vue Component Styling + - Put shared/base Tailwind classes directly on the HTML element via the `class` attribute. - For variant-specific styles (e.g. modes, states), use custom CSS classes (`.initial`, `.chat`, `.user`, `.error`, etc.) with `@apply` in a scoped ` diff --git a/docs/.vitepress/components/SponsorLogo.vue b/docs/.vitepress/components/SponsorLogo.vue index aeb5c3beec..0117d9bb60 100644 --- a/docs/.vitepress/components/SponsorLogo.vue +++ b/docs/.vitepress/components/SponsorLogo.vue @@ -1,6 +1,6 @@ @@ -22,18 +22,18 @@ defineOptions({