Skip to content

refactor: cleanup BoostServiceProvider #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 11, 2025
Merged
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
14 changes: 12 additions & 2 deletions config/boost.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
declare(strict_types=1);

return [
'project_purpose' => null,
'browser_logs' => true,

/*
|--------------------------------------------------------------------------
| Boost Browser Logs Watcher Switch
|--------------------------------------------------------------------------
|
| The following option may be used to enable or disable browser logs watcher
| functionality which simply provides a single and convenient way to
| enable or disable browser logs functionality in Boost.
*/

'browser_logs_watcher' => env('BOOST_BROWSER_LOGS_WATCHER', true),
];
2 changes: 1 addition & 1 deletion pint.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
"phpdoc_align": {
"align": "left",
"spacing": {
"param": 2
"param": 1
}
},
"phpdoc_indent": true,
Expand Down
89 changes: 47 additions & 42 deletions src/BoostServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Http\Request;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Compilers\BladeCompiler;
use Laravel\Boost\Mcp\Boost;
use Laravel\Boost\Middleware\InjectBoost;
use Laravel\Mcp\Server\Facades\Mcp;
Expand All @@ -21,18 +21,21 @@ class BoostServiceProvider extends ServiceProvider
public function register(): void
{
$this->mergeConfigFrom(
__DIR__.'/../config/boost.php', 'boost'
__DIR__.'/../config/boost.php',
'boost'
);

$this->app->singleton(Roster::class, function () {
$composerLockPath = base_path('composer.lock');
$packageLockPath = base_path('package-lock.json');
$lockFiles = [
base_path('composer.lock'),
base_path('package-lock.json'),
base_path('bun.lockb'),
base_path('pnpm-lock.yaml'),
base_path('yarn.lock'),
];

$cacheKey = 'boost.roster.scan';
$lastModified = max(
file_exists($composerLockPath) ? filemtime($composerLockPath) : 0,
file_exists($packageLockPath) ? filemtime($packageLockPath) : 0
);
$lastModified = max(array_map(fn ($path) => file_exists($path) ? filemtime($path) : 0, $lockFiles));

$cached = cache()->get($cacheKey);
if ($cached && isset($cached['timestamp']) && $cached['timestamp'] >= $lastModified) {
Expand Down Expand Up @@ -62,7 +65,7 @@ public function boot(Router $router): void
$this->registerCommands();
$this->registerRoutes();
$this->registerBrowserLogger();
$this->registerBladeDirectives();
$this->callAfterResolving('blade.compiler', fn (BladeCompiler $bladeCompiler) => $this->registerBladeDirectives($bladeCompiler));
$this->hookIntoResponses($router);
}

Expand Down Expand Up @@ -93,10 +96,17 @@ private function registerRoutes(): void
/** @var \Illuminate\Log\Logger $logger */
$logger = Log::channel('browser');

/** @var array{type: 'error'|'warn'|'info'|'log'|'table'|'window_error'|'uncaught_error'|'unhandled_rejection', timestamp: string, data: array<mixed>, url:string, userAgent:string} $log */
/**
* @var array{
* type: 'error'|'warn'|'info'|'log'|'table'|'window_error'|'uncaught_error'|'unhandled_rejection',
* timestamp: string,
* data: array<mixed>,
* url:string,
* userAgent:string
* } $log */
foreach ($logs as $log) {
$logger->write(
level: $this->jsTypeToPsr3($log['type']),
level: $this->mapJsTypeToPsr3Level($log['type']),
message: $this->buildLogMessageFromData($log['data']),
context: [
'url' => $log['url'],
Expand All @@ -107,58 +117,53 @@ private function registerRoutes(): void
}

return response()->json(['status' => 'logged']);
})->name('boost.browser-logs')->withoutMiddleware(VerifyCsrfToken::class);
})
->name('boost.browser-logs')
->withoutMiddleware(VerifyCsrfToken::class);
}

/**
* Build a string message for the log based on various input types. Single dimensional, and multi:
* "data":[{"message":"Unhandled Promise Rejection","reason":{"name":"TypeError","message":"NetworkError when attempting to fetch resource.","stack":""}}]
* "data":[
* {"message":"Unhandled Promise Rejection","reason":{"name":"TypeError","message":"NetworkError when attempting to fetch resource.","stack":""}}]
*
* @param array<mixed> $data
* @param array<mixed> $data
*/
protected function buildLogMessageFromData(array $data): string
{
$messages = [];

foreach ($data as $key => $value) {
if (is_array($value)) {
$nestedMessage = $this->buildLogMessageFromData($value);
if ($nestedMessage !== '') {
$messages[] = $nestedMessage;
}
} elseif (is_string($value) || is_numeric($value)) {
$messages[] = (string) $value;
} elseif (is_bool($value)) {
$messages[] = $value ? 'true' : 'false';
} elseif (is_null($value)) {
$messages[] = 'null';
} elseif (is_object($value)) {
$messages[] = json_encode($value);
}
foreach ($data as $value) {
$messages[] = match (true) {
is_array($value) => $this->buildLogMessageFromData($value),
is_string($value), is_numeric($value) => (string) $value,
is_bool($value) => $value ? 'true' : 'false',
is_null($value) => 'null',
is_object($value) => json_encode($value),
};
}

return implode(' ', $messages);
}

protected function registerBrowserLogger(): void
{
// Register a custom log channel for browser logs
config(['logging.channels.browser' => [
'driver' => 'single',
'path' => storage_path('logs/browser.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
]]);
config([
'logging.channels.browser' => [
'driver' => 'single',
'path' => storage_path('logs/browser.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
],
]);
}

protected function registerBladeDirectives(): void
protected function registerBladeDirectives(BladeCompiler $bladeCompiler): void
{
Blade::directive('boostJs', function () {
return '<?php echo \\Laravel\\Boost\\Services\\BrowserLogger::getScript(); ?>';
});
$bladeCompiler->directive('boostJs', fn () => '<?php echo \\Laravel\\Boost\\Services\\BrowserLogger::getScript(); ?>');
}

private function jsTypeToPsr3(string $type): string
private function mapJsTypeToPsr3Level(string $type): string
{
return match ($type) {
'warn' => 'warning',
Expand All @@ -173,7 +178,7 @@ private function jsTypeToPsr3(string $type): string

private function hookIntoResponses(Router $router): void
{
if (config('boost.browser_logs', true) === false) {
if (! config('boost.browser_logs_watcher', true)) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/MakesHttpRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function get(string $url): Response
}

/**
* @param array<string, mixed> $json
* @param array<string, mixed> $json
*/
public function json(string $url, array $json): Response
{
Expand Down
4 changes: 2 additions & 2 deletions src/Contracts/Ide.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ interface Ide
// Things to note: supports relative (absolute path required)? global mcp only? Prefer local file, but if global only we have to add the project name to the server name

/**
* @param array<int, string> $args
* @param array<string, string> $env
* @param array<int, string> $args
* @param array<string, string> $env
*/
public function installMcp(string $key, string $command, array $args = [], array $env = []): bool;
}
4 changes: 2 additions & 2 deletions src/Install/Agents/FileMcpIde.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public function mcpPath(): string
}

/**
* @param array<int, string> $args
* @param array<string, string> $env
* @param array<int, string> $args
* @param array<string, string> $env
*/
public function installMcp(string $key, string $command, array $args = [], array $env = []): bool
{
Expand Down
4 changes: 2 additions & 2 deletions src/Install/Agents/ShellMcpIde.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ abstract class ShellMcpIde implements Ide
protected string $shellCommand = 'echo "{command} {args} {env}"';

/**
* @param array<int, string> $args
* @param array<string, string> $env
* @param array<int, string> $args
* @param array<string, string> $env
*/
public function installMcp(string $key, string $command, array $args = [], array $env = []): bool
{
Expand Down
8 changes: 4 additions & 4 deletions src/Install/ApplicationDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public function detectInProject(string $basePath): array
/**
* Check if an application is installed based on its configuration.
*
* @param array<string, string|array<string>> $config
* @param array<string, string|array<string>> $config
*/
protected function isAppInstalled(array $config, string $platform): bool
{
Expand Down Expand Up @@ -219,7 +219,7 @@ protected function isAppInstalled(array $config, string $platform): bool
/**
* Check if an application is used in the current project.
*
* @param array<string, string|array<string>> $config
* @param array<string, string|array<string>> $config
*/
protected function isAppUsedInProject(array $config, string $basePath): bool
{
Expand Down Expand Up @@ -297,7 +297,7 @@ protected function getPlatform(): string
/**
* Add custom detection configuration for an application.
*
* @param array<string, array<string, string|array<string>>> $config
* @param array<string, array<string, string|array<string>>> $config
*/
public function addDetectionConfig(string $app, array $config, ?string $platform = null): void
{
Expand All @@ -314,7 +314,7 @@ public function addDetectionConfig(string $app, array $config, ?string $platform
/**
* Add custom project detection configuration for an application.
*
* @param array<string, string|array<string>> $config
* @param array<string, string|array<string>> $config
*/
public function addProjectDetectionConfig(string $app, array $config): void
{
Expand Down
4 changes: 2 additions & 2 deletions src/Install/Cli/DisplayHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class DisplayHelper
{
/**
* @param array<int, array<int|string, mixed>> $data
* @param array<int, array<int|string, mixed>> $data
*/
public static function datatable(array $data, int $cols = 80): void
{
Expand Down Expand Up @@ -96,7 +96,7 @@ public static function datatable(array $data, int $cols = 80): void
}

/**
* @param array<int, string> $items
* @param array<int, string> $items
*/
public static function grid(array $items, int $cols = 80): void
{
Expand Down
8 changes: 4 additions & 4 deletions src/Mcp/ToolExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct()
/**
* Execute a tool with the given arguments.
*
* @param array<string, mixed> $arguments
* @param array<string, mixed> $arguments
*/
public function execute(string $toolClass, array $arguments = []): ToolResult
{
Expand All @@ -37,7 +37,7 @@ public function execute(string $toolClass, array $arguments = []): ToolResult
/**
* Execute tool in a separate process for isolation.
*
* @param array<string, mixed> $arguments
* @param array<string, mixed> $arguments
*/
protected function executeInProcess(string $toolClass, array $arguments): ToolResult
{
Expand Down Expand Up @@ -80,7 +80,7 @@ protected function executeInProcess(string $toolClass, array $arguments): ToolRe
/**
* Execute tool inline (current process).
*
* @param array<string, mixed> $arguments
* @param array<string, mixed> $arguments
*/
protected function executeInline(string $toolClass, array $arguments): ToolResult
{
Expand Down Expand Up @@ -117,7 +117,7 @@ protected function getTimeout(): int
/**
* Reconstruct a ToolResult from JSON data.
*
* @param array<string, mixed> $data
* @param array<string, mixed> $data
*/
protected function reconstructToolResult(array $data): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/ApplicationInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/BrowserLogs.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/DatabaseConnections.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/DatabaseQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/DatabaseSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/GetAbsoluteUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/GetConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mcp/Tools/LastError.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
}

/**
* @param array<string> $arguments
* @param array<string> $arguments
*/
public function handle(array $arguments): ToolResult
{
Expand Down
Loading
Loading