From 9f3f37360cd7d3582b1fb0bbe8b06bce3f8d9962 Mon Sep 17 00:00:00 2001 From: Jordan Partridge Date: Fri, 10 Apr 2026 13:28:49 -0700 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20full=20quality=20gate=20=E2=80=94?= =?UTF-8?q?=20PHPStan,=20Pint,=20Rector,=20Publish=20Guard=20in=20certify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire 4 new checks into CertifyCommand alongside existing Tests, Security, and Syntax: - PhpStanAnalyzer: configurable level (--phpstan-level, default 5), JSON output parsing, graceful skip if not installed - PintFormatter: --test mode, JSON output, reports files needing formatting - RectorAnalyzer: --dry-run mode, graceful skip if no rector.php config - PublishGuard: scans for .env files (excludes .testing/.example), .map files, large binaries (>1MB) All checks follow existing CheckInterface pattern with pass/fail/skip semantics. New action.yml input: phpstan-level (default 5, set -1 to skip). Certify now runs 7 checks: Tests → Pint → PHPStan → Rector → Security → Syntax → Publish --- action.yml | 5 +++ app/Checks/PhpStanAnalyzer.php | 72 ++++++++++++++++++++++++++++++++ app/Checks/PintFormatter.php | 65 +++++++++++++++++++++++++++++ app/Checks/PublishGuard.php | 74 +++++++++++++++++++++++++++++++++ app/Checks/RectorAnalyzer.php | 63 ++++++++++++++++++++++++++++ app/Commands/CertifyCommand.php | 13 ++++++ 6 files changed, 292 insertions(+) create mode 100644 app/Checks/PhpStanAnalyzer.php create mode 100644 app/Checks/PintFormatter.php create mode 100644 app/Checks/PublishGuard.php create mode 100644 app/Checks/RectorAnalyzer.php diff --git a/action.yml b/action.yml index e751d04..808d529 100644 --- a/action.yml +++ b/action.yml @@ -39,6 +39,10 @@ inputs: description: 'Directory to scan for coverage (auto-detects app/ or src/ if not specified)' required: false default: '' + phpstan-level: + description: 'PHPStan analysis level (0-9). Set to -1 to skip.' + required: false + default: '5' compact: description: 'Use compact single-line output instead of verbose' required: false @@ -122,6 +126,7 @@ runs: certify|*) php ${{ github.action_path }}/gate certify \ --coverage=${{ inputs.coverage-threshold }} \ + --phpstan-level=${{ inputs.phpstan-level }} \ --token=${{ inputs.github-token }} \ ${{ inputs.compact == 'true' && '--compact' || '' }} ;; diff --git a/app/Checks/PhpStanAnalyzer.php b/app/Checks/PhpStanAnalyzer.php new file mode 100644 index 0000000..3202df8 --- /dev/null +++ b/app/Checks/PhpStanAnalyzer.php @@ -0,0 +1,72 @@ +processRunner->run( + [$binary, 'analyse', '--no-progress', '--error-format=json', "--level={$this->level}", '--memory-limit=512M'], + $workingDirectory, + timeout: 300, + ); + + $data = json_decode($result->output, true); + + if ($data === null) { + // Fall back to exit code if JSON parsing fails + if ($result->exitCode === 0) { + return CheckResult::pass('PHPStan passed (level '.$this->level.')'); + } + + return CheckResult::fail( + 'PHPStan failed', + [substr($result->output, 0, 500)], + $result->output, + ); + } + + $errorCount = $data['totals']['errors'] ?? 0; + $fileErrors = $data['totals']['file_errors'] ?? 0; + $totalErrors = $errorCount + $fileErrors; + + if ($totalErrors === 0) { + return CheckResult::pass('PHPStan passed (level '.$this->level.', 0 errors)'); + } + + $details = []; + foreach ($data['files'] ?? [] as $file => $fileData) { + foreach ($fileData['messages'] ?? [] as $msg) { + $details[] = basename($file).':'.$msg['line'].' — '.$msg['message']; + } + } + + return CheckResult::fail( + "PHPStan found {$totalErrors} error(s) at level {$this->level}", + array_slice($details, 0, 20), + $result->output, + ); + } +} diff --git a/app/Checks/PintFormatter.php b/app/Checks/PintFormatter.php new file mode 100644 index 0000000..8074ae6 --- /dev/null +++ b/app/Checks/PintFormatter.php @@ -0,0 +1,65 @@ +processRunner->run( + [$binary, '--test', '--format=json'], + $workingDirectory, + timeout: 120, + ); + + $data = json_decode($result->output, true); + + if ($data === null) { + if ($result->exitCode === 0) { + return CheckResult::pass('Code style is clean'); + } + + return CheckResult::fail( + 'Pint check failed', + [substr($result->output, 0, 500)], + $result->output, + ); + } + + if (($data['result'] ?? '') === 'pass') { + return CheckResult::pass('Code style is clean'); + } + + $files = $data['files'] ?? []; + $details = array_map( + fn (array $f): string => $f['path'].' ('.implode(', ', $f['fixers'] ?? []).')', + array_slice($files, 0, 20), + ); + + return CheckResult::fail( + count($files).' file(s) need formatting', + $details, + $result->output, + ); + } +} diff --git a/app/Checks/PublishGuard.php b/app/Checks/PublishGuard.php new file mode 100644 index 0000000..24dd5b2 --- /dev/null +++ b/app/Checks/PublishGuard.php @@ -0,0 +1,74 @@ +processRunner->run( + ['git', 'ls-files', '*.env', '.env*'], + $workingDirectory, + timeout: 10, + ); + + foreach (array_filter(explode("\n", trim($envResult->output))) as $file) { + if (! str_ends_with($file, '.env.testing') && ! str_ends_with($file, '.env.example')) { + $violations[] = "Tracked .env file: {$file}"; + } + } + + // Check for source map files + $mapResult = $this->processRunner->run( + ['git', 'ls-files', '*.map'], + $workingDirectory, + timeout: 10, + ); + + foreach (array_filter(explode("\n", trim($mapResult->output))) as $file) { + $violations[] = "Tracked .map file: {$file}"; + } + + // Check for large files (> 1MB) + $lsResult = $this->processRunner->run( + ['git', 'ls-files'], + $workingDirectory, + timeout: 10, + ); + + foreach (array_filter(explode("\n", trim($lsResult->output))) as $file) { + $path = $workingDirectory.'/'.$file; + if (file_exists($path) && filesize($path) > 1_048_576) { + $size = round(filesize($path) / 1_048_576, 1); + $violations[] = "Large file ({$size}MB): {$file}"; + } + } + + if ($violations === []) { + return CheckResult::pass('No disallowed artifacts found'); + } + + return CheckResult::fail( + count($violations).' publish violation(s) found', + $violations, + implode("\n", $violations), + ); + } +} diff --git a/app/Checks/RectorAnalyzer.php b/app/Checks/RectorAnalyzer.php new file mode 100644 index 0000000..e758df9 --- /dev/null +++ b/app/Checks/RectorAnalyzer.php @@ -0,0 +1,63 @@ +processRunner->run( + [$binary, 'process', '--dry-run', '--no-progress-bar'], + $workingDirectory, + timeout: 300, + ); + + if ($result->exitCode === 0) { + return CheckResult::pass('Rector found no issues'); + } + + // Count suggested changes from output + $lines = explode("\n", trim($result->output)); + $changeCount = 0; + $details = []; + + foreach ($lines as $line) { + if (str_contains($line, 'diff')) { + $changeCount++; + } + if (str_starts_with(trim($line), '---') || str_starts_with(trim($line), '+++')) { + $details[] = trim($line); + } + } + + return CheckResult::fail( + 'Rector found '.max($changeCount, 1).' file(s) needing refactoring', + array_slice($details, 0, 20), + $result->output, + ); + } +} diff --git a/app/Commands/CertifyCommand.php b/app/Commands/CertifyCommand.php index f50d6bb..424015e 100644 --- a/app/Commands/CertifyCommand.php +++ b/app/Commands/CertifyCommand.php @@ -8,6 +8,10 @@ use App\Checks\CheckInterface; use App\Checks\CheckResult; use App\Checks\PestSyntaxValidator; +use App\Checks\PhpStanAnalyzer; +use App\Checks\PintFormatter; +use App\Checks\PublishGuard; +use App\Checks\RectorAnalyzer; use App\Checks\SecurityScanner; use App\Checks\TestRunner; use App\GitHub\ChecksClient; @@ -24,6 +28,7 @@ final class CertifyCommand extends Command { protected $signature = 'certify {--coverage=80 : Minimum coverage threshold percentage} + {--phpstan-level=5 : PHPStan analysis level (0-9)} {--token= : GitHub token for Checks API} {--stop-on-failure : Stop at first failing check} {--compact : Show single-line output instead of verbose}'; @@ -61,10 +66,16 @@ public function handle(): int $checksClient = $this->checksClient ?? new ChecksClient($token); $workingDirectory = getcwd(); + $phpstanLevel = (int) $this->option('phpstan-level'); + $checks = $this->checks ?? [ new TestRunner($coverageThreshold), + new PintFormatter, + new PhpStanAnalyzer($phpstanLevel), + new RectorAnalyzer, new SecurityScanner, new PestSyntaxValidator, + new PublishGuard, ]; $stopOnFailure = $this->option('stop-on-failure'); @@ -210,6 +221,8 @@ private function shortName(string $name): string 'Tests & Coverage' => 'Tests', 'Security Audit' => 'Security', 'Pest Syntax' => 'Syntax', + 'Pint Style' => 'Pint', + 'Publish Guard' => 'Publish', default => $name, }; } From b3116c8d9ad6c71e0720e714855a0e981f128be8 Mon Sep 17 00:00:00 2001 From: Jordan Partridge Date: Fri, 10 Apr 2026 13:33:40 -0700 Subject: [PATCH 2/5] fix: pint formatting on all files + guard PintFormatter against varied JSON structures Fix pre-existing pint style issues across gate codebase (4 files). Guard PintFormatter::run() against missing 'path' key in JSON output since different pint versions may structure the files array differently. --- app/Checks/PintFormatter.php | 13 +++++++++---- app/Commands/CertifyCommand.php | 3 +-- app/GitHub/ChecksClient.php | 5 +++++ app/Services/PromptAssembler.php | 8 ++++---- app/Transformers/PhpStanPromptTransformer.php | 2 +- app/Transformers/TestFailurePromptTransformer.php | 3 +-- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/Checks/PintFormatter.php b/app/Checks/PintFormatter.php index 8074ae6..05a98c6 100644 --- a/app/Checks/PintFormatter.php +++ b/app/Checks/PintFormatter.php @@ -51,10 +51,15 @@ public function run(string $workingDirectory): CheckResult } $files = $data['files'] ?? []; - $details = array_map( - fn (array $f): string => $f['path'].' ('.implode(', ', $f['fixers'] ?? []).')', - array_slice($files, 0, 20), - ); + $details = []; + + foreach (array_slice($files, 0, 20) as $f) { + if (is_array($f) && isset($f['path'])) { + $details[] = $f['path'].' ('.implode(', ', $f['fixers'] ?? []).')'; + } elseif (is_string($f)) { + $details[] = $f; + } + } return CheckResult::fail( count($files).' file(s) need formatting', diff --git a/app/Commands/CertifyCommand.php b/app/Commands/CertifyCommand.php index 424015e..3eae9ee 100644 --- a/app/Commands/CertifyCommand.php +++ b/app/Commands/CertifyCommand.php @@ -6,7 +6,6 @@ use App\Branding; use App\Checks\CheckInterface; -use App\Checks\CheckResult; use App\Checks\PestSyntaxValidator; use App\Checks\PhpStanAnalyzer; use App\Checks\PintFormatter; @@ -134,7 +133,7 @@ public function handle(): int $checksClient->postCertificationComment($checkResults); } else { // Post actionable prompt with fix directions on failure - $assembler = new PromptAssembler(); + $assembler = new PromptAssembler; $assembled = $assembler->assemble($rawOutputs); if ($assembled['prompt'] !== '') { diff --git a/app/GitHub/ChecksClient.php b/app/GitHub/ChecksClient.php index 92e2e71..17c5a33 100644 --- a/app/GitHub/ChecksClient.php +++ b/app/GitHub/ChecksClient.php @@ -89,6 +89,7 @@ public function createCheck(string $name, string $status = 'in_progress'): ?int return $data['id'] ?? null; } catch (GuzzleException $e) { $this->logError('createCheck', $e); + return null; } } @@ -119,6 +120,7 @@ public function completeCheck( return true; } catch (GuzzleException $e) { $this->logError('completeCheck', $e); + return false; } } @@ -155,6 +157,7 @@ public function reportCheck( return true; } catch (GuzzleException $e) { $this->logError('reportCheck', $e); + return false; } } @@ -199,6 +202,7 @@ public function postCertificationComment(array $checkResults): bool return true; } catch (GuzzleException $e) { $this->logError('postCertificationComment', $e); + return false; } } @@ -234,6 +238,7 @@ public function postActionablePrompt(string $prompt): bool return true; } catch (GuzzleException $e) { $this->logError('postActionablePrompt', $e); + return false; } } diff --git a/app/Services/PromptAssembler.php b/app/Services/PromptAssembler.php index 58efb7a..bd27ea9 100644 --- a/app/Services/PromptAssembler.php +++ b/app/Services/PromptAssembler.php @@ -22,8 +22,8 @@ final class PromptAssembler public function __construct() { $this->transformers = [ - new PhpStanPromptTransformer(), - new TestFailurePromptTransformer(), + new PhpStanPromptTransformer, + new TestFailurePromptTransformer, ]; } @@ -94,7 +94,7 @@ public function transform(string $checkName, string $output): array private function buildCombinedPrompt(array $failedChecks): string { $count = count($failedChecks); - $prompt = "# 🔧 Synapse Sentinel: {$count} check" . ($count === 1 ? '' : 's') . " need attention\n\n"; + $prompt = "# 🔧 Synapse Sentinel: {$count} check".($count === 1 ? '' : 's')." need attention\n\n"; $prompt .= "The following issues must be resolved before this PR can be merged:\n\n"; foreach ($failedChecks as $checkName => $section) { @@ -117,6 +117,6 @@ private function truncate(string $text, int $maxLength = 2000): string return $text; } - return substr($text, 0, $maxLength) . "\n... (truncated)"; + return substr($text, 0, $maxLength)."\n... (truncated)"; } } diff --git a/app/Transformers/PhpStanPromptTransformer.php b/app/Transformers/PhpStanPromptTransformer.php index 2d3ebf5..69fa343 100644 --- a/app/Transformers/PhpStanPromptTransformer.php +++ b/app/Transformers/PhpStanPromptTransformer.php @@ -115,7 +115,7 @@ private function buildPrompt(array $data): array $relativePath = $this->relativePath($filePath); $errorCount = $fileData['errors'] ?? 0; - $prompt .= "### {$relativePath} ({$errorCount} error" . ($errorCount === 1 ? '' : 's') . ")\n\n"; + $prompt .= "### {$relativePath} ({$errorCount} error".($errorCount === 1 ? '' : 's').")\n\n"; foreach ($fileData['messages'] ?? [] as $index => $message) { $prompt .= $this->formatError($index + 1, $message); diff --git a/app/Transformers/TestFailurePromptTransformer.php b/app/Transformers/TestFailurePromptTransformer.php index 379402b..450e847 100644 --- a/app/Transformers/TestFailurePromptTransformer.php +++ b/app/Transformers/TestFailurePromptTransformer.php @@ -95,7 +95,6 @@ private function parseJunitXml(string $xml): array /** * Extract test cases from a test suite. * - * @param \SimpleXMLElement $suite * @param array> $failures * @param array> $errors */ @@ -246,7 +245,7 @@ private function cleanMessage(string $message): string // Truncate if too long if (strlen($clean) > 500) { - $clean = substr($clean, 0, 500) . '... (truncated)'; + $clean = substr($clean, 0, 500).'... (truncated)'; } return trim($clean); From cc9a6de91b4da2c008dac7d01c8e967d17a96d6c Mon Sep 17 00:00:00 2001 From: Jordan Partridge Date: Fri, 10 Apr 2026 13:42:36 -0700 Subject: [PATCH 3/5] chore: composer update to fix CVE-2026-24765 and CVE-2026-24739 --- composer.lock | 682 ++++++++++++++++++++++++++------------------------ 1 file changed, 349 insertions(+), 333 deletions(-) diff --git a/composer.lock b/composer.lock index fefa126..937878e 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "brick/math", - "version": "0.14.1", + "version": "0.14.8", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "f05858549e5f9d7bb45875a75583240a38a281d0" + "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0", - "reference": "f05858549e5f9d7bb45875a75583240a38a281d0", + "url": "https://api.github.com/repos/brick/math/zipball/63422359a44b7f06cae63c3b429b59e8efcc0629", + "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629", "shasum": "" }, "require": { @@ -56,7 +56,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.1" + "source": "https://github.com/brick/math/tree/0.14.8" }, "funding": [ { @@ -64,7 +64,7 @@ "type": "github" } ], - "time": "2025-11-24T14:40:29+00:00" + "time": "2026-02-10T14:33:43+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -362,24 +362,24 @@ }, { "name": "graham-campbell/result-type", - "version": "v1.1.3", + "version": "v1.1.4", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3" + "phpoption/phpoption": "^1.9.5" }, "require-dev": { - "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" }, "type": "library", "autoload": { @@ -408,7 +408,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" }, "funding": [ { @@ -420,7 +420,7 @@ "type": "tidelift" } ], - "time": "2024-07-20T21:45:45+00:00" + "time": "2025-12-27T19:43:20+00:00" }, { "name": "guzzlehttp/guzzle", @@ -633,16 +633,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.8.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "21dc724a0583619cd1652f673303492272778051" + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", - "reference": "21dc724a0583619cd1652f673303492272778051", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884", + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884", "shasum": "" }, "require": { @@ -658,6 +658,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", + "jshttp/mime-db": "1.54.0.1", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { @@ -729,7 +730,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.8.0" + "source": "https://github.com/guzzle/psr7/tree/2.9.0" }, "funding": [ { @@ -745,11 +746,11 @@ "type": "tidelift" } ], - "time": "2025-08-23T21:21:41+00:00" + "time": "2026-03-10T16:41:02+00:00" }, { "name": "illuminate/bus", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/bus.git", @@ -802,7 +803,7 @@ }, { "name": "illuminate/cache", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/cache.git", @@ -864,7 +865,7 @@ }, { "name": "illuminate/collections", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -920,7 +921,7 @@ }, { "name": "illuminate/conditionable", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -966,7 +967,7 @@ }, { "name": "illuminate/config", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/config.git", @@ -1014,16 +1015,16 @@ }, { "name": "illuminate/console", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/console.git", - "reference": "a41fbfc99bac948ee27fc8d99bb0e5b4175dec00" + "reference": "c48cf3587c7f8c0f3b34b05de88e2a14830f8641" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/console/zipball/a41fbfc99bac948ee27fc8d99bb0e5b4175dec00", - "reference": "a41fbfc99bac948ee27fc8d99bb0e5b4175dec00", + "url": "https://api.github.com/repos/illuminate/console/zipball/c48cf3587c7f8c0f3b34b05de88e2a14830f8641", + "reference": "c48cf3587c7f8c0f3b34b05de88e2a14830f8641", "shasum": "" }, "require": { @@ -1076,11 +1077,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-11T13:49:37+00:00" + "time": "2026-03-24T14:05:16+00:00" }, { "name": "illuminate/container", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", @@ -1131,7 +1132,7 @@ }, { "name": "illuminate/contracts", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1179,7 +1180,7 @@ }, { "name": "illuminate/events", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/events.git", @@ -1234,7 +1235,7 @@ }, { "name": "illuminate/filesystem", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", @@ -1301,7 +1302,7 @@ }, { "name": "illuminate/macroable", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1347,7 +1348,7 @@ }, { "name": "illuminate/pipeline", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/pipeline.git", @@ -1395,7 +1396,7 @@ }, { "name": "illuminate/process", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/process.git", @@ -1446,16 +1447,16 @@ }, { "name": "illuminate/support", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "20fbd9f9f502a55de0cbba3f3f81444b7c44af4b" + "reference": "11cc8bd46991e277f6af19eb9dee5d4c1f65c7d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/20fbd9f9f502a55de0cbba3f3f81444b7c44af4b", - "reference": "20fbd9f9f502a55de0cbba3f3f81444b7c44af4b", + "url": "https://api.github.com/repos/illuminate/support/zipball/11cc8bd46991e277f6af19eb9dee5d4c1f65c7d2", + "reference": "11cc8bd46991e277f6af19eb9dee5d4c1f65c7d2", "shasum": "" }, "require": { @@ -1519,11 +1520,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-11-27T16:16:32+00:00" + "time": "2026-01-20T15:25:35+00:00" }, { "name": "illuminate/testing", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/testing.git", @@ -1582,16 +1583,16 @@ }, { "name": "illuminate/view", - "version": "v11.47.0", + "version": "v11.51.0", "source": { "type": "git", "url": "https://github.com/illuminate/view.git", - "reference": "9da5543dccb4e406f98016bac8678c97b7dc6915" + "reference": "64f466393edcd99cc076c65a9ab6ffa3ce11dd10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/view/zipball/9da5543dccb4e406f98016bac8678c97b7dc6915", - "reference": "9da5543dccb4e406f98016bac8678c97b7dc6915", + "url": "https://api.github.com/repos/illuminate/view/zipball/64f466393edcd99cc076c65a9ab6ffa3ce11dd10", + "reference": "64f466393edcd99cc076c65a9ab6ffa3ce11dd10", "shasum": "" }, "require": { @@ -1632,7 +1633,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-03-24T11:54:20+00:00" + "time": "2026-03-17T14:00:57+00:00" }, { "name": "jolicode/jolinotif", @@ -1927,30 +1928,30 @@ }, { "name": "laravel/prompts", - "version": "v0.3.8", + "version": "v0.3.16", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "096748cdfb81988f60090bbb839ce3205ace0d35" + "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/096748cdfb81988f60090bbb839ce3205ace0d35", - "reference": "096748cdfb81988f60090bbb839ce3205ace0d35", + "url": "https://api.github.com/repos/laravel/prompts/zipball/11e7d5f93803a2190b00e145142cb00a33d17ad2", + "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "ext-mbstring": "*", "php": "^8.1", - "symfony/console": "^6.2|^7.0" + "symfony/console": "^6.2|^7.0|^8.0" }, "conflict": { "illuminate/console": ">=10.17.0 <10.25.0", "laravel/framework": ">=10.17.0 <10.25.0" }, "require-dev": { - "illuminate/collections": "^10.0|^11.0|^12.0", + "illuminate/collections": "^10.0|^11.0|^12.0|^13.0", "mockery/mockery": "^1.5", "pestphp/pest": "^2.3|^3.4|^4.0", "phpstan/phpstan": "^1.12.28", @@ -1980,22 +1981,22 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.8" + "source": "https://github.com/laravel/prompts/tree/v0.3.16" }, - "time": "2025-11-21T20:52:52+00:00" + "time": "2026-03-23T14:35:33+00:00" }, { "name": "league/flysystem", - "version": "3.30.2", + "version": "3.33.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277" + "reference": "570b8871e0ce693764434b29154c54b434905350" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277", - "reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/570b8871e0ce693764434b29154c54b434905350", + "reference": "570b8871e0ce693764434b29154c54b434905350", "shasum": "" }, "require": { @@ -2063,22 +2064,22 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.30.2" + "source": "https://github.com/thephpleague/flysystem/tree/3.33.0" }, - "time": "2025-11-10T17:13:11+00:00" + "time": "2026-03-25T07:59:30+00:00" }, { "name": "league/flysystem-local", - "version": "3.30.2", + "version": "3.31.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "ab4f9d0d672f601b102936aa728801dd1a11968d" + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ab4f9d0d672f601b102936aa728801dd1a11968d", - "reference": "ab4f9d0d672f601b102936aa728801dd1a11968d", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", "shasum": "" }, "require": { @@ -2112,9 +2113,9 @@ "local" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.2" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" }, - "time": "2025-11-10T11:23:37+00:00" + "time": "2026-01-23T15:30:45+00:00" }, { "name": "league/mime-type-detection", @@ -2174,16 +2175,16 @@ }, { "name": "nesbot/carbon", - "version": "3.11.0", + "version": "3.11.4", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "bdb375400dcd162624531666db4799b36b64e4a1" + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1", - "reference": "bdb375400dcd162624531666db4799b36b64e4a1", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", "shasum": "" }, "require": { @@ -2207,7 +2208,7 @@ "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan": "^2.1.22", "phpunit/phpunit": "^10.5.53", - "squizlabs/php_codesniffer": "^3.13.4" + "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" }, "bin": [ "bin/carbon" @@ -2250,14 +2251,14 @@ } ], "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbon.nesbot.com", + "homepage": "https://carbonphp.github.io/carbon/", "keywords": [ "date", "datetime", "time" ], "support": { - "docs": "https://carbon.nesbot.com/docs", + "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", "issues": "https://github.com/CarbonPHP/carbon/issues", "source": "https://github.com/CarbonPHP/carbon" }, @@ -2275,43 +2276,40 @@ "type": "tidelift" } ], - "time": "2025-12-02T21:04:28+00:00" + "time": "2026-04-07T09:57:54+00:00" }, { "name": "nunomaduro/collision", - "version": "v8.8.3", + "version": "v8.9.3", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4" + "reference": "b0d8ab95b29c3189aeeb902d81215231df4c1b64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/1dc9e88d105699d0fee8bb18890f41b274f6b4c4", - "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/b0d8ab95b29c3189aeeb902d81215231df4c1b64", + "reference": "b0d8ab95b29c3189aeeb902d81215231df4c1b64", "shasum": "" }, "require": { - "filp/whoops": "^2.18.1", - "nunomaduro/termwind": "^2.3.1", + "filp/whoops": "^2.18.4", + "nunomaduro/termwind": "^2.4.0", "php": "^8.2.0", - "symfony/console": "^7.3.0" + "symfony/console": "^7.4.8 || ^8.0.4" }, "conflict": { - "laravel/framework": "<11.44.2 || >=13.0.0", - "phpunit/phpunit": "<11.5.15 || >=13.0.0" + "laravel/framework": "<11.48.0 || >=14.0.0", + "phpunit/phpunit": "<11.5.50 || >=14.0.0" }, "require-dev": { - "brianium/paratest": "^7.8.3", - "larastan/larastan": "^3.4.2", - "laravel/framework": "^11.44.2 || ^12.18", - "laravel/pint": "^1.22.1", - "laravel/sail": "^1.43.1", - "laravel/sanctum": "^4.1.1", - "laravel/tinker": "^2.10.1", - "orchestra/testbench-core": "^9.12.0 || ^10.4", - "pestphp/pest": "^3.8.2 || ^4.0.0", - "sebastian/environment": "^7.2.1 || ^8.0" + "brianium/paratest": "^7.8.5", + "larastan/larastan": "^3.9.3", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.2.0", + "laravel/pint": "^1.29.0", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.0.0", + "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.0.0" }, "type": "library", "extra": { @@ -2374,25 +2372,25 @@ "type": "patreon" } ], - "time": "2025-11-20T02:55:25+00:00" + "time": "2026-04-06T19:25:53+00:00" }, { "name": "nunomaduro/laravel-console-summary", - "version": "v1.13.0", + "version": "v1.14.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/laravel-console-summary.git", - "reference": "8fe07f5ecbedca8544edc54f397538dc0b49d7f9" + "reference": "21c4c5c432bd0db55d747647a7b3a75be71bf67b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/laravel-console-summary/zipball/8fe07f5ecbedca8544edc54f397538dc0b49d7f9", - "reference": "8fe07f5ecbedca8544edc54f397538dc0b49d7f9", + "url": "https://api.github.com/repos/nunomaduro/laravel-console-summary/zipball/21c4c5c432bd0db55d747647a7b3a75be71bf67b", + "reference": "21c4c5c432bd0db55d747647a7b3a75be71bf67b", "shasum": "" }, "require": { - "illuminate/console": "^11.4|^12.0", - "illuminate/support": "^11.4|^12.0", + "illuminate/console": "^11.4|^12.0|^13.0", + "illuminate/support": "^11.4|^12.0|^13.0", "php": "^8.2" }, "require-dev": { @@ -2436,29 +2434,29 @@ "issues": "https://github.com/nunomaduro/laravel-console-summary/issues", "source": "https://github.com/nunomaduro/laravel-console-summary" }, - "time": "2025-02-19T11:10:44+00:00" + "time": "2026-02-23T09:40:19+00:00" }, { "name": "nunomaduro/laravel-console-task", - "version": "v1.10.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/laravel-console-task.git", - "reference": "9d11073ad8b0215c63a962250e2bf071611f975d" + "reference": "bb90369a55908d14055de33ee4bf70ba638f4ee1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/laravel-console-task/zipball/9d11073ad8b0215c63a962250e2bf071611f975d", - "reference": "9d11073ad8b0215c63a962250e2bf071611f975d", + "url": "https://api.github.com/repos/nunomaduro/laravel-console-task/zipball/bb90369a55908d14055de33ee4bf70ba638f4ee1", + "reference": "bb90369a55908d14055de33ee4bf70ba638f4ee1", "shasum": "" }, "require": { - "illuminate/console": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", "php": "^8.2" }, "require-dev": { - "pestphp/pest": "^3.7" + "pestphp/pest": "^3.7|^4.4" }, "type": "library", "extra": { @@ -2498,31 +2496,31 @@ "issues": "https://github.com/nunomaduro/laravel-console-task/issues", "source": "https://github.com/nunomaduro/laravel-console-task" }, - "time": "2025-02-19T11:02:37+00:00" + "time": "2026-02-24T09:37:53+00:00" }, { "name": "nunomaduro/laravel-desktop-notifier", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/laravel-desktop-notifier.git", - "reference": "4871ee90fff38fbe25a2b8f81b5daeedf98a3ed7" + "reference": "0454df17906c4d29ed87f563b121e3224c9655b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/laravel-desktop-notifier/zipball/4871ee90fff38fbe25a2b8f81b5daeedf98a3ed7", - "reference": "4871ee90fff38fbe25a2b8f81b5daeedf98a3ed7", + "url": "https://api.github.com/repos/nunomaduro/laravel-desktop-notifier/zipball/0454df17906c4d29ed87f563b121e3224c9655b1", + "reference": "0454df17906c4d29ed87f563b121e3224c9655b1", "shasum": "" }, "require": { - "illuminate/console": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", + "illuminate/console": "^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", "jolicode/jolinotif": "^2.5", "php": "^8.2" }, "require-dev": { "graham-campbell/testbench": "^5.7|^6.2", - "pestphp/pest": "^3.7" + "pestphp/pest": "^3.7|^4.4" }, "type": "library", "extra": { @@ -2566,37 +2564,37 @@ ], "support": { "issues": "https://github.com/nunomaduro/laravel-desktop-notifier/issues", - "source": "https://github.com/nunomaduro/laravel-desktop-notifier/tree/v2.9.0" + "source": "https://github.com/nunomaduro/laravel-desktop-notifier/tree/v2.10.0" }, - "time": "2025-02-19T11:22:09+00:00" + "time": "2026-02-24T09:42:50+00:00" }, { "name": "nunomaduro/termwind", - "version": "v2.3.3", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017" + "reference": "712a31b768f5daea284c2169a7d227031001b9a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/6fb2a640ff502caace8e05fd7be3b503a7e1c017", - "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/712a31b768f5daea284c2169a7d227031001b9a8", + "reference": "712a31b768f5daea284c2169a7d227031001b9a8", "shasum": "" }, "require": { "ext-mbstring": "*", "php": "^8.2", - "symfony/console": "^7.3.6" + "symfony/console": "^7.4.4 || ^8.0.4" }, "require-dev": { - "illuminate/console": "^11.46.1", - "laravel/pint": "^1.25.1", + "illuminate/console": "^11.47.0", + "laravel/pint": "^1.27.1", "mockery/mockery": "^1.6.12", - "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.1.3", + "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.3.2", "phpstan/phpstan": "^1.12.32", "phpstan/phpstan-strict-rules": "^1.6.2", - "symfony/var-dumper": "^7.3.5", + "symfony/var-dumper": "^7.3.5 || ^8.0.4", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -2628,7 +2626,7 @@ "email": "enunomaduro@gmail.com" } ], - "description": "Its like Tailwind CSS, but for the console.", + "description": "It's like Tailwind CSS, but for the console.", "keywords": [ "cli", "console", @@ -2639,7 +2637,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.3.3" + "source": "https://github.com/nunomaduro/termwind/tree/v2.4.0" }, "funding": [ { @@ -2655,20 +2653,20 @@ "type": "github" } ], - "time": "2025-11-20T02:34:59+00:00" + "time": "2026-02-16T23:10:27+00:00" }, { "name": "phpoption/phpoption", - "version": "1.9.4", + "version": "1.9.5", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d" + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d", - "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", "shasum": "" }, "require": { @@ -2718,7 +2716,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.4" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" }, "funding": [ { @@ -2730,7 +2728,7 @@ "type": "tidelift" } ], - "time": "2025-08-21T11:53:16+00:00" + "time": "2025-12-27T19:41:33+00:00" }, { "name": "psr/clock", @@ -3344,16 +3342,16 @@ }, { "name": "symfony/clock", - "version": "v8.0.0", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f" + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/832119f9b8dbc6c8e6f65f30c5969eca1e88764f", - "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f", + "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", "shasum": "" }, "require": { @@ -3397,7 +3395,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v8.0.0" + "source": "https://github.com/symfony/clock/tree/v8.0.8" }, "funding": [ { @@ -3417,20 +3415,20 @@ "type": "tidelift" } ], - "time": "2025-11-12T15:46:48+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/console", - "version": "v7.4.1", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e" + "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", - "reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e", + "url": "https://api.github.com/repos/symfony/console/zipball/1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", + "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", "shasum": "" }, "require": { @@ -3495,7 +3493,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.1" + "source": "https://github.com/symfony/console/tree/v7.4.8" }, "funding": [ { @@ -3515,7 +3513,7 @@ "type": "tidelift" } ], - "time": "2025-12-05T15:23:39+00:00" + "time": "2026-03-30T13:54:39+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3586,16 +3584,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2" + "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/48be2b0653594eea32dcef130cca1c811dcf25c2", - "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", + "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", "shasum": "" }, "require": { @@ -3644,7 +3642,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.4.0" + "source": "https://github.com/symfony/error-handler/tree/v7.4.8" }, "funding": [ { @@ -3664,20 +3662,20 @@ "type": "tidelift" } ], - "time": "2025-11-05T14:29:59+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d" + "reference": "f57b899fa736fd71121168ef268f23c206083f0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9dddcddff1ef974ad87b3708e4b442dc38b2261d", - "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f57b899fa736fd71121168ef268f23c206083f0a", + "reference": "f57b899fa736fd71121168ef268f23c206083f0a", "shasum": "" }, "require": { @@ -3729,7 +3727,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.8" }, "funding": [ { @@ -3749,7 +3747,7 @@ "type": "tidelift" } ], - "time": "2025-10-28T09:38:46+00:00" + "time": "2026-03-30T13:54:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3829,16 +3827,16 @@ }, { "name": "symfony/finder", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "340b9ed7320570f319028a2cbec46d40535e94bd" + "reference": "e0be088d22278583a82da281886e8c3592fbf149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/340b9ed7320570f319028a2cbec46d40535e94bd", - "reference": "340b9ed7320570f319028a2cbec46d40535e94bd", + "url": "https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149", + "reference": "e0be088d22278583a82da281886e8c3592fbf149", "shasum": "" }, "require": { @@ -3873,7 +3871,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.4.0" + "source": "https://github.com/symfony/finder/tree/v7.4.8" }, "funding": [ { @@ -3893,7 +3891,7 @@ "type": "tidelift" } ], - "time": "2025-11-05T05:42:40+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4476,16 +4474,16 @@ }, { "name": "symfony/process", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8" + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7ca8dc2d0dcf4882658313aba8be5d9fd01026c8", - "reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8", + "url": "https://api.github.com/repos/symfony/process/zipball/60f19cd3badc8de688421e21e4305eba50f8089a", + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a", "shasum": "" }, "require": { @@ -4517,7 +4515,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.4.0" + "source": "https://github.com/symfony/process/tree/v7.4.8" }, "funding": [ { @@ -4537,7 +4535,7 @@ "type": "tidelift" } ], - "time": "2025-10-16T11:21:06+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/service-contracts", @@ -4628,16 +4626,16 @@ }, { "name": "symfony/string", - "version": "v8.0.1", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc" + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc", - "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc", + "url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963", + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963", "shasum": "" }, "require": { @@ -4694,7 +4692,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.1" + "source": "https://github.com/symfony/string/tree/v8.0.8" }, "funding": [ { @@ -4714,20 +4712,20 @@ "type": "tidelift" } ], - "time": "2025-12-01T09:13:36+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/translation", - "version": "v8.0.1", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "770e3b8b0ba8360958abedcabacd4203467333ca" + "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/770e3b8b0ba8360958abedcabacd4203467333ca", - "reference": "770e3b8b0ba8360958abedcabacd4203467333ca", + "url": "https://api.github.com/repos/symfony/translation/zipball/27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", + "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", "shasum": "" }, "require": { @@ -4787,7 +4785,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.1" + "source": "https://github.com/symfony/translation/tree/v8.0.8" }, "funding": [ { @@ -4807,7 +4805,7 @@ "type": "tidelift" } ], - "time": "2025-12-01T09:13:36+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/translation-contracts", @@ -4893,16 +4891,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece" + "reference": "9510c3966f749a1d1ff0059e1eabef6cc621e7fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41fd6c4ae28c38b294b42af6db61446594a0dece", - "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9510c3966f749a1d1ff0059e1eabef6cc621e7fd", + "reference": "9510c3966f749a1d1ff0059e1eabef6cc621e7fd", "shasum": "" }, "require": { @@ -4956,7 +4954,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.4.0" + "source": "https://github.com/symfony/var-dumper/tree/v7.4.8" }, "funding": [ { @@ -4976,30 +4974,30 @@ "type": "tidelift" } ], - "time": "2025-10-27T20:36:44+00:00" + "time": "2026-03-30T13:44:50+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v5.6.2", + "version": "v5.6.3", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af" + "reference": "955e7815d677a3eaa7075231212f2110983adecc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af", - "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", + "reference": "955e7815d677a3eaa7075231212f2110983adecc", "shasum": "" }, "require": { "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.3", + "graham-campbell/result-type": "^1.1.4", "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" + "phpoption/phpoption": "^1.9.5", + "symfony/polyfill-ctype": "^1.26", + "symfony/polyfill-mbstring": "^1.26", + "symfony/polyfill-php80": "^1.26" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", @@ -5048,7 +5046,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2" + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3" }, "funding": [ { @@ -5060,7 +5058,7 @@ "type": "tidelift" } ], - "time": "2025-04-30T23:37:27+00:00" + "time": "2025-12-27T19:49:13+00:00" }, { "name": "voku/portable-ascii", @@ -5140,16 +5138,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v7.8.4", + "version": "v7.8.5", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "130a9bf0e269ee5f5b320108f794ad03e275cad4" + "reference": "9b324c8fc319cf9728b581c7a90e1c8f6361c5e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/130a9bf0e269ee5f5b320108f794ad03e275cad4", - "reference": "130a9bf0e269ee5f5b320108f794ad03e275cad4", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/9b324c8fc319cf9728b581c7a90e1c8f6361c5e5", + "reference": "9b324c8fc319cf9728b581c7a90e1c8f6361c5e5", "shasum": "" }, "require": { @@ -5157,27 +5155,27 @@ "ext-pcre": "*", "ext-reflection": "*", "ext-simplexml": "*", - "fidry/cpu-core-counter": "^1.2.0", + "fidry/cpu-core-counter": "^1.3.0", "jean85/pretty-package-versions": "^2.1.1", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "phpunit/php-code-coverage": "^11.0.10", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "phpunit/php-code-coverage": "^11.0.12", "phpunit/php-file-iterator": "^5.1.0", "phpunit/php-timer": "^7.0.1", - "phpunit/phpunit": "^11.5.24", + "phpunit/phpunit": "^11.5.46", "sebastian/environment": "^7.2.1", - "symfony/console": "^6.4.22 || ^7.3.0", - "symfony/process": "^6.4.20 || ^7.3.0" + "symfony/console": "^6.4.22 || ^7.3.4 || ^8.0.3", + "symfony/process": "^6.4.20 || ^7.3.4 || ^8.0.3" }, "require-dev": { "doctrine/coding-standard": "^12.0.0", "ext-pcov": "*", "ext-posix": "*", - "phpstan/phpstan": "^2.1.17", + "phpstan/phpstan": "^2.1.33", "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.6", - "phpstan/phpstan-strict-rules": "^2.0.4", - "squizlabs/php_codesniffer": "^3.13.2", - "symfony/filesystem": "^6.4.13 || ^7.3.0" + "phpstan/phpstan-phpunit": "^2.0.11", + "phpstan/phpstan-strict-rules": "^2.0.7", + "squizlabs/php_codesniffer": "^3.13.5", + "symfony/filesystem": "^6.4.13 || ^7.3.2 || ^8.0.1" }, "bin": [ "bin/paratest", @@ -5217,7 +5215,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.8.4" + "source": "https://github.com/paratestphp/paratest/tree/v7.8.5" }, "funding": [ { @@ -5229,33 +5227,33 @@ "type": "paypal" } ], - "time": "2025-06-23T06:07:21+00:00" + "time": "2026-01-08T08:02:38+00:00" }, { "name": "doctrine/deprecations", - "version": "1.1.5", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "conflict": { - "phpunit/phpunit": "<=7.5 || >=13" + "phpunit/phpunit": "<=7.5 || >=14" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^13", - "phpstan/phpstan": "1.4.10 || 2.1.11", + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", "psr/log": "^1 || ^2 || ^3" }, "suggest": { @@ -5275,9 +5273,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" }, - "time": "2025-04-07T20:06:18+00:00" + "time": "2026-02-07T07:09:04+00:00" }, { "name": "fidry/cpu-core-counter", @@ -5453,16 +5451,16 @@ }, { "name": "laravel/pint", - "version": "v1.26.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "69dcca060ecb15e4b564af63d1f642c81a241d6f" + "reference": "bdec963f53172c5e36330f3a400604c69bf02d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/69dcca060ecb15e4b564af63d1f642c81a241d6f", - "reference": "69dcca060ecb15e4b564af63d1f642c81a241d6f", + "url": "https://api.github.com/repos/laravel/pint/zipball/bdec963f53172c5e36330f3a400604c69bf02d39", + "reference": "bdec963f53172c5e36330f3a400604c69bf02d39", "shasum": "" }, "require": { @@ -5473,13 +5471,14 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.90.0", - "illuminate/view": "^12.40.1", - "larastan/larastan": "^3.8.0", - "laravel-zero/framework": "^12.0.4", + "friendsofphp/php-cs-fixer": "^3.94.2", + "illuminate/view": "^12.54.1", + "larastan/larastan": "^3.9.3", + "laravel-zero/framework": "^12.0.5", "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^2.3.3", - "pestphp/pest": "^3.8.4" + "nunomaduro/termwind": "^2.4.0", + "pestphp/pest": "^3.8.6", + "shipfastlabs/agent-detector": "^1.1.0" }, "bin": [ "builds/pint" @@ -5516,7 +5515,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2025-11-25T21:15:52+00:00" + "time": "2026-03-12T15:51:39+00:00" }, { "name": "mockery/mockery", @@ -5721,38 +5720,38 @@ }, { "name": "pestphp/pest", - "version": "v3.8.4", + "version": "v3.8.6", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "72cf695554420e21858cda831d5db193db102574" + "reference": "8871a6f5ef1de8e7c8dee2a270991449a7b6af73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/72cf695554420e21858cda831d5db193db102574", - "reference": "72cf695554420e21858cda831d5db193db102574", + "url": "https://api.github.com/repos/pestphp/pest/zipball/8871a6f5ef1de8e7c8dee2a270991449a7b6af73", + "reference": "8871a6f5ef1de8e7c8dee2a270991449a7b6af73", "shasum": "" }, "require": { - "brianium/paratest": "^7.8.4", - "nunomaduro/collision": "^8.8.2", - "nunomaduro/termwind": "^2.3.1", + "brianium/paratest": "^7.8.5", + "nunomaduro/collision": "^8.9.1", + "nunomaduro/termwind": "^2.4.0", "pestphp/pest-plugin": "^3.0.0", "pestphp/pest-plugin-arch": "^3.1.1", "pestphp/pest-plugin-mutate": "^3.0.5", "php": "^8.2.0", - "phpunit/phpunit": "^11.5.33" + "phpunit/phpunit": "^11.5.50" }, "conflict": { "filp/whoops": "<2.16.0", - "phpunit/phpunit": ">11.5.33", + "phpunit/phpunit": ">11.5.50", "sebastian/exporter": "<6.0.0", "webmozart/assert": "<1.11.0" }, "require-dev": { "pestphp/pest-dev-tools": "^3.4.0", "pestphp/pest-plugin-type-coverage": "^3.6.1", - "symfony/process": "^7.3.0" + "symfony/process": "^7.4.5" }, "bin": [ "bin/pest" @@ -5817,7 +5816,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v3.8.4" + "source": "https://github.com/pestphp/pest/tree/v3.8.6" }, "funding": [ { @@ -5829,7 +5828,7 @@ "type": "github" } ], - "time": "2025-08-20T19:12:42+00:00" + "time": "2026-03-10T21:04:33+00:00" }, { "name": "pestphp/pest-plugin", @@ -6216,16 +6215,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.5", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/90614c73d3800e187615e2dd236ad0e2a01bf761", - "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -6233,9 +6232,9 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1" + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", + "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { "mockery/mockery": "~1.3.5 || ~1.6.0", @@ -6244,7 +6243,8 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { @@ -6274,44 +6274,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.5" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "time": "2025-11-27T19:50:05+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -6332,22 +6332,22 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.0", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", "shasum": "" }, "require": { @@ -6379,41 +6379,41 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" }, - "time": "2025-08-30T15:50:23+00:00" + "time": "2026-01-25T14:56:51+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "11.0.11", + "version": "11.0.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4" + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", - "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.4.0", + "nikic/php-parser": "^5.7.0", "php": ">=8.2", "phpunit/php-file-iterator": "^5.1.0", "phpunit/php-text-template": "^4.0.1", "sebastian/code-unit-reverse-lookup": "^4.0.1", "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", + "sebastian/environment": "^7.2.1", "sebastian/lines-of-code": "^3.0.1", "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.2.3" + "theseer/tokenizer": "^1.3.1" }, "require-dev": { - "phpunit/phpunit": "^11.5.2" + "phpunit/phpunit": "^11.5.46" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -6451,7 +6451,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.11" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" }, "funding": [ { @@ -6471,32 +6471,32 @@ "type": "tidelift" } ], - "time": "2025-08-27T14:37:49+00:00" + "time": "2025-12-24T07:01:01+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "5.1.0", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -6524,15 +6524,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" } ], - "time": "2024-08-27T05:02:59+00:00" + "time": "2026-02-02T13:52:54+00:00" }, { "name": "phpunit/php-invoker", @@ -6720,16 +6732,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.33", + "version": "11.5.50", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6" + "reference": "fdfc727f0fcacfeb8fcb30c7e5da173125b58be3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", - "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fdfc727f0fcacfeb8fcb30c7e5da173125b58be3", + "reference": "fdfc727f0fcacfeb8fcb30c7e5da173125b58be3", "shasum": "" }, "require": { @@ -6743,17 +6755,17 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.10", + "phpunit/php-code-coverage": "^11.0.12", "phpunit/php-file-iterator": "^5.1.0", "phpunit/php-invoker": "^5.0.1", "phpunit/php-text-template": "^4.0.1", "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", "sebastian/code-unit": "^3.0.3", - "sebastian/comparator": "^6.3.2", + "sebastian/comparator": "^6.3.3", "sebastian/diff": "^6.0.2", "sebastian/environment": "^7.2.1", - "sebastian/exporter": "^6.3.0", + "sebastian/exporter": "^6.3.2", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", "sebastian/type": "^5.1.3", @@ -6801,7 +6813,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.33" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.50" }, "funding": [ { @@ -6825,7 +6837,7 @@ "type": "tidelift" } ], - "time": "2025-08-16T05:19:02+00:00" + "time": "2026-01-27T05:59:18+00:00" }, { "name": "sebastian/cli-parser", @@ -6999,16 +7011,16 @@ }, { "name": "sebastian/comparator", - "version": "6.3.2", + "version": "6.3.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8" + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85c77556683e6eee4323e4c5468641ca0237e2e8", - "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", "shasum": "" }, "require": { @@ -7067,7 +7079,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.2" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" }, "funding": [ { @@ -7087,7 +7099,7 @@ "type": "tidelift" } ], - "time": "2025-08-10T08:07:46+00:00" + "time": "2026-01-24T09:26:40+00:00" }, { "name": "sebastian/complexity", @@ -7867,24 +7879,24 @@ }, { "name": "ta-tikoma/phpunit-architecture-test", - "version": "0.8.5", + "version": "0.8.7", "source": { "type": "git", "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", - "reference": "cf6fb197b676ba716837c886baca842e4db29005" + "reference": "1248f3f506ca9641d4f68cebcd538fa489754db8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/cf6fb197b676ba716837c886baca842e4db29005", - "reference": "cf6fb197b676ba716837c886baca842e4db29005", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/1248f3f506ca9641d4f68cebcd538fa489754db8", + "reference": "1248f3f506ca9641d4f68cebcd538fa489754db8", "shasum": "" }, "require": { "nikic/php-parser": "^4.18.0 || ^5.0.0", "php": "^8.1.0", - "phpdocumentor/reflection-docblock": "^5.3.0", - "phpunit/phpunit": "^10.5.5 || ^11.0.0 || ^12.0.0", - "symfony/finder": "^6.4.0 || ^7.0.0" + "phpdocumentor/reflection-docblock": "^5.3.0 || ^6.0.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0 || ^12.0.0 || ^13.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0 || ^8.0.0" }, "require-dev": { "laravel/pint": "^1.13.7", @@ -7920,9 +7932,9 @@ ], "support": { "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", - "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.5" + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.7" }, - "time": "2025-04-20T20:23:40+00:00" + "time": "2026-02-17T17:25:14+00:00" }, { "name": "theseer/tokenizer", @@ -7976,23 +7988,23 @@ }, { "name": "webmozart/assert", - "version": "1.12.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/1b99650e7ffcad232624a260bc7fbdec2ffc407c", + "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c", "shasum": "" }, "require": { "ext-ctype": "*", "ext-date": "*", "ext-filter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.2" }, "suggest": { "ext-intl": "", @@ -8002,7 +8014,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10-dev" + "dev-feature/2-0": "2.0-dev" } }, "autoload": { @@ -8018,6 +8030,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", @@ -8028,9 +8044,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.12.1" + "source": "https://github.com/webmozarts/assert/tree/2.2.0" }, - "time": "2025-10-29T15:56:20+00:00" + "time": "2026-04-09T16:54:47+00:00" } ], "aliases": [], From 832006ecb399de7d0a2bb093368179bc320e8540 Mon Sep 17 00:00:00 2001 From: Jordan Partridge Date: Fri, 10 Apr 2026 13:48:21 -0700 Subject: [PATCH 4/5] fix: add mock responses for actionable prompt in failure-path tests --- tests/Unit/Commands/CertifyCommandTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/Unit/Commands/CertifyCommandTest.php b/tests/Unit/Commands/CertifyCommandTest.php index 10f2818..f007820 100644 --- a/tests/Unit/Commands/CertifyCommandTest.php +++ b/tests/Unit/Commands/CertifyCommandTest.php @@ -60,6 +60,7 @@ new Response(201), // First check new Response(201), // Second check new Response(201), // Certification check + new Response(201), // Actionable prompt comment ]); $httpClient = new Client(['handler' => HandlerStack::create($mock)]); $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); @@ -80,6 +81,7 @@ $mock = new MockHandler([ new Response(201), new Response(201), + new Response(201), // Actionable prompt ]); $httpClient = new Client(['handler' => HandlerStack::create($mock)]); $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); @@ -165,6 +167,7 @@ new Response(201), new Response(201), new Response(201), + new Response(201), // Actionable prompt ]); $httpClient = new Client(['handler' => HandlerStack::create($mock)]); $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); @@ -223,6 +226,7 @@ $mock = new MockHandler([ new Response(201), // First check new Response(201), // Certification + new Response(201), // Actionable prompt ]); $httpClient = new Client(['handler' => HandlerStack::create($mock)]); $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); @@ -250,6 +254,7 @@ new Response(201), // First check new Response(201), // Second check new Response(201), // Certification + new Response(201), // Actionable prompt ]); $httpClient = new Client(['handler' => HandlerStack::create($mock)]); $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); @@ -312,6 +317,7 @@ new Response(201), new Response(201), new Response(201), + new Response(201), // Actionable prompt ]); $httpClient = new Client(['handler' => HandlerStack::create($mock)]); $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); From 507ef2be71ec316aae6b17a72e91d90d4f323f25 Mon Sep 17 00:00:00 2001 From: Jordan Partridge Date: Fri, 10 Apr 2026 16:27:08 -0700 Subject: [PATCH 5/5] fix: pint formatting on all remaining files --- app/Checks/TestRunner.php | 18 ++++++++++-------- app/Commands/CertifyCommand.php | 3 ++- bootstrap/app.php | 3 ++- config/app.php | 3 ++- config/commands.php | 18 ++++++++++++------ tests/Unit/Checks/PestSyntaxValidatorTest.php | 3 ++- tests/Unit/Checks/SecurityScannerTest.php | 3 ++- tests/Unit/Checks/TestRunnerTest.php | 19 +++++++++++-------- 8 files changed, 43 insertions(+), 27 deletions(-) diff --git a/app/Checks/TestRunner.php b/app/Checks/TestRunner.php index 0d6cc04..424254b 100644 --- a/app/Checks/TestRunner.php +++ b/app/Checks/TestRunner.php @@ -5,16 +5,18 @@ namespace App\Checks; use App\Contracts\ProcessRunner; +use App\GitHub\CommentsClient; +use App\Services\CoverageReporter; use App\Services\PestOutputParser; use App\Services\SymfonyProcessRunner; final class TestRunner implements CheckInterface { - /** @var \App\GitHub\CommentsClient|null For testing */ - private ?\App\GitHub\CommentsClient $commentsClient = null; + /** @var CommentsClient|null For testing */ + private ?CommentsClient $commentsClient = null; - /** @var \App\Services\CoverageReporter|null For testing */ - private ?\App\Services\CoverageReporter $coverageReporter = null; + /** @var CoverageReporter|null For testing */ + private ?CoverageReporter $coverageReporter = null; public function __construct( private readonly int $coverageThreshold = 100, @@ -24,8 +26,8 @@ public function __construct( /** @internal For testing only */ public function withCommentDependencies( - \App\GitHub\CommentsClient $commentsClient, - \App\Services\CoverageReporter $coverageReporter, + CommentsClient $commentsClient, + CoverageReporter $coverageReporter, ): self { $this->commentsClient = $commentsClient; $this->coverageReporter = $coverageReporter; @@ -75,8 +77,8 @@ private function postCoverageComment(string $cloverPath): void return; } - $commentsClient = $this->commentsClient ?? new \App\GitHub\CommentsClient($token); - $reporter = $this->coverageReporter ?? new \App\Services\CoverageReporter($this->coverageThreshold); + $commentsClient = $this->commentsClient ?? new CommentsClient($token); + $reporter = $this->coverageReporter ?? new CoverageReporter($this->coverageThreshold); if ($commentsClient->isAvailable()) { try { diff --git a/app/Commands/CertifyCommand.php b/app/Commands/CertifyCommand.php index 3eae9ee..b9b408a 100644 --- a/app/Commands/CertifyCommand.php +++ b/app/Commands/CertifyCommand.php @@ -6,6 +6,7 @@ use App\Branding; use App\Checks\CheckInterface; +use App\Checks\CheckResult; use App\Checks\PestSyntaxValidator; use App\Checks\PhpStanAnalyzer; use App\Checks\PintFormatter; @@ -184,7 +185,7 @@ private function runCheck( string $workingDirectory, ChecksClient $checksClient, bool $compact = false, - ): \App\Checks\CheckResult { + ): CheckResult { if ($compact) { $result = $check->run($workingDirectory); } else { diff --git a/bootstrap/app.php b/bootstrap/app.php index c97c23d..b4bad74 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,5 +1,6 @@ create(); +return Application::configure(basePath: dirname(__DIR__))->create(); diff --git a/config/app.php b/config/app.php index 2342b22..a9461b8 100644 --- a/config/app.php +++ b/config/app.php @@ -1,12 +1,13 @@ 'Synapse Sentinel Gate', 'version' => app('git.version'), 'env' => 'development', 'providers' => [ - App\Providers\AppServiceProvider::class, + AppServiceProvider::class, ], ]; diff --git a/config/commands.php b/config/commands.php index 1326995..eb09f46 100644 --- a/config/commands.php +++ b/config/commands.php @@ -1,17 +1,23 @@ [app_path('Commands')], 'add' => [], 'hidden' => [ - NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, - Symfony\Component\Console\Command\DumpCompletionCommand::class, - Symfony\Component\Console\Command\HelpCommand::class, - Illuminate\Console\Scheduling\ScheduleRunCommand::class, - Illuminate\Console\Scheduling\ScheduleListCommand::class, - Illuminate\Console\Scheduling\ScheduleFinishCommand::class, + SummaryCommand::class, + DumpCompletionCommand::class, + HelpCommand::class, + ScheduleRunCommand::class, + ScheduleListCommand::class, + ScheduleFinishCommand::class, ], 'remove' => [], ]; diff --git a/tests/Unit/Checks/PestSyntaxValidatorTest.php b/tests/Unit/Checks/PestSyntaxValidatorTest.php index 0184dc2..2b5054b 100644 --- a/tests/Unit/Checks/PestSyntaxValidatorTest.php +++ b/tests/Unit/Checks/PestSyntaxValidatorTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Checks\CheckInterface; use App\Checks\PestSyntaxValidator; describe('PestSyntaxValidator', function () { @@ -12,7 +13,7 @@ it('implements CheckInterface', function () { $validator = new PestSyntaxValidator; - expect($validator)->toBeInstanceOf(\App\Checks\CheckInterface::class); + expect($validator)->toBeInstanceOf(CheckInterface::class); }); it('passes when test files use describe/it blocks', function () { diff --git a/tests/Unit/Checks/SecurityScannerTest.php b/tests/Unit/Checks/SecurityScannerTest.php index 4788e86..6fe5460 100644 --- a/tests/Unit/Checks/SecurityScannerTest.php +++ b/tests/Unit/Checks/SecurityScannerTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use App\Checks\CheckInterface; use App\Checks\SecurityScanner; use App\Contracts\ProcessResult; use App\Contracts\ProcessRunner; @@ -14,7 +15,7 @@ it('implements CheckInterface', function () { $scanner = new SecurityScanner; - expect($scanner)->toBeInstanceOf(\App\Checks\CheckInterface::class); + expect($scanner)->toBeInstanceOf(CheckInterface::class); }); it('returns pass when no vulnerabilities found', function () { diff --git a/tests/Unit/Checks/TestRunnerTest.php b/tests/Unit/Checks/TestRunnerTest.php index 6774236..aba7c59 100644 --- a/tests/Unit/Checks/TestRunnerTest.php +++ b/tests/Unit/Checks/TestRunnerTest.php @@ -2,9 +2,12 @@ declare(strict_types=1); +use App\Checks\CheckInterface; use App\Checks\TestRunner; use App\Contracts\ProcessResult; use App\Contracts\ProcessRunner; +use App\GitHub\CommentsClient; +use App\Services\CoverageReporter; use App\Services\PestOutputParser; describe('TestRunner', function () { @@ -15,7 +18,7 @@ it('implements CheckInterface', function () { $runner = new TestRunner(coverageThreshold: 80); - expect($runner)->toBeInstanceOf(\App\Checks\CheckInterface::class); + expect($runner)->toBeInstanceOf(CheckInterface::class); }); it('returns pass when tests pass and coverage meets threshold', function () { @@ -292,12 +295,12 @@ )); // Mock CommentsClient - $mockCommentsClient = mock(\App\GitHub\CommentsClient::class); + $mockCommentsClient = mock(CommentsClient::class); $mockCommentsClient->shouldReceive('isAvailable')->andReturn(true); $mockCommentsClient->shouldReceive('postOrUpdateComment')->once()->andReturn(true); // Mock CoverageReporter - $mockReporter = mock(\App\Services\CoverageReporter::class); + $mockReporter = mock(CoverageReporter::class); $mockReporter->shouldReceive('generatePRComment') ->with($tempDir.'/coverage.xml') ->once() @@ -337,11 +340,11 @@ )); // Mock CommentsClient - not available - $mockCommentsClient = mock(\App\GitHub\CommentsClient::class); + $mockCommentsClient = mock(CommentsClient::class); $mockCommentsClient->shouldReceive('isAvailable')->andReturn(false); $mockCommentsClient->shouldNotReceive('postOrUpdateComment'); - $mockReporter = mock(\App\Services\CoverageReporter::class); + $mockReporter = mock(CoverageReporter::class); $runner = new TestRunner( coverageThreshold: 100, @@ -377,13 +380,13 @@ )); // Mock CommentsClient - $mockCommentsClient = mock(\App\GitHub\CommentsClient::class); + $mockCommentsClient = mock(CommentsClient::class); $mockCommentsClient->shouldReceive('isAvailable')->andReturn(true); // Mock CoverageReporter - throws exception - $mockReporter = mock(\App\Services\CoverageReporter::class); + $mockReporter = mock(CoverageReporter::class); $mockReporter->shouldReceive('generatePRComment') - ->andThrow(new \Exception('Test error')); + ->andThrow(new Exception('Test error')); $runner = new TestRunner( coverageThreshold: 100,