diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index a4ff129..c8327d3 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -6,7 +6,6 @@ on:
env:
REGISTRY: ghcr.io
- IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
@@ -40,7 +39,9 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ images: |
+ ${{ env.REGISTRY }}/usetrmnl/byos_laravel
+ ${{ env.REGISTRY }}/usetrmnl/larapaper
tags: |
type=semver,pattern={{version}}
diff --git a/Dockerfile b/Dockerfile
index c679db8..4dc531b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,8 +3,8 @@
########################
FROM bnussbau/serversideup-php:8.4-fpm-nginx-alpine-imagick-chromium@sha256:ed705a4060d50143ddc538c1288afff217eaf76ad5791f7556a97943854cf745 AS base
-LABEL org.opencontainers.image.source=https://github.com/usetrmnl/byos_laravel
-LABEL org.opencontainers.image.description="TRMNL BYOS Laravel"
+LABEL org.opencontainers.image.source=https://github.com/usetrmnl/larapaper
+LABEL org.opencontainers.image.description="LaraPaper"
LABEL org.opencontainers.image.licenses=MIT
ARG APP_VERSION
diff --git a/README.md b/README.md
index 442cc15..c1ebafe 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-## TRMNL BYOS (PHP/Laravel)
+## LaraPaper (PHP/Laravel)
-[](https://github.com/usetrmnl/byos_laravel/actions/workflows/test.yml)
+[](https://github.com/usetrmnl/larapaper/actions/workflows/test.yml)
-TRMNL BYOS Laravel is a self-hostable implementation of a TRMNL server, built with Laravel.
+LaraPaper is a self-hostable implementation of a TRMNL server (BYOS), built with Laravel.
It allows you to manage TRMNL devices, generate screens using **native plugins** (Screens API, Markup), **recipes** (130+ from the [OSS community catalog](https://bnussbau.github.io/trmnl-recipe-catalog/), 700+ from the [TRMNL catalog](https://trmnl.com/recipes), or your own), or the **API**, and can also act as a **proxy** for the native cloud service (Core). With over 50k downloads and 200+ stars, it’s the most popular community-driven BYOS.

@@ -26,7 +26,7 @@ It allows you to manage TRMNL devices, generate screens using **native plugins**
* Custom ESP32 with TRMNL firmware
* E-Reader Devices
* KOReader ([trmnl-koreader](https://github.com/usetrmnl/trmnl-koreader))
- * Kindle ([trmnl-kindle](https://github.com/usetrmnl/byos_laravel/pull/27))
+ * Kindle ([trmnl-kindle](https://github.com/usetrmnl/larapaper/pull/27))
* Nook ([trmnl-nook](https://github.com/usetrmnl/trmnl-nook))
* Kobo ([trmnl-kobo](https://github.com/usetrmnl/trmnl-kobo))
* Android Devices with [trmnl-android](https://github.com/usetrmnl/trmnl-android)
@@ -61,7 +61,7 @@ Docker Compose file located at: [docker/prod/docker-compose.yml](docker/prod/doc
##### Backup Database
```sh
-docker ps #find container id of byos_laravel container
+docker ps #find container id of larapaper container
docker cp {{CONTAINER_ID}}:/var/www/html/database/storage/database.sqlite database_backup.sqlite
```
@@ -73,11 +73,11 @@ docker compose up -d
```
#### VPS
-If you’re using a VPS (e.g., Hetzner) and prefer an alternative to native Docker, you can install Dokploy and deploy BYOS Laravel using the integrated [Template](https://templates.dokploy.com/?q=trmnl+byos+laravel).
+If you’re using a VPS (e.g., Hetzner) and prefer an alternative to native Docker, you can install Dokploy and deploy LaraPaper using the integrated [Template](https://templates.dokploy.com/?q=trmnl+byos+laravel).
It’s a quick way to get started without having to manually manage Docker setup.
#### PikaPods
-You can vote for TRMNL BYOS Laravel to be included as PikaPods Template here: [feedback.pikapods.com](https://feedback.pikapods.com/posts/842/add-app-trmnl-byos-laravel)
+You can vote for LaraPaper to be included as PikaPods Template here: [feedback.pikapods.com](https://feedback.pikapods.com/posts/842/add-app-trmnl-byos-laravel)
#### Umbrel
Umbrel is supported through a community store, [see](http://github.com/bnussbau/umbrel-store).
@@ -173,13 +173,13 @@ See this YouTube guide: [https://www.youtube.com/watch?v=3xehPW-PCOM](https://ww
### ☁️ Activate fresh TRMNL Device with Cloud Proxy
1) Setup the TRMNL as in the official docs with the cloud service (connect one of the plugins to later verify it works)
-2) Setup Laravel BYOS, create a user and login
-3) In Laravel BYOS in the header bar, activate the toggle "Permit Auto-Join"
+2) Setup LaraPaper, create a user and login
+3) In LaraPaper in the header bar, activate the toggle "Permit Auto-Join"
4) Press and hold the button on the back of your TRMNL for 5 seconds to reactivate the captive portal (or reflash).
-5) Go through the setup process again, in the screen where you provide the Wi-Fi credentials there is also option to set the Server URL. Use the local address of your Laravel BYOS
+5) Go through the setup process again, in the screen where you provide the Wi-Fi credentials there is also option to set the Server URL. Use the local address of LaraPaper.
6) The device should automatically appear in the device list; you can deactivate the "Permit Auto-Join" toggle again.
7) In the devices list, activate the toggle "☁️ Proxy" for your device. (Make sure that the queue worker is active. In the docker image it should be running automatically.)
-8) As long as no Laravel BYOS plugin is scheduled, the device will show your cloud plugins.
+8) As long as no LaraPaper plugin is scheduled, the device will show your cloud plugins.
###### Troubleshooting
diff --git a/app/Jobs/GenerateScreenJob.php b/app/Jobs/GenerateScreenJob.php
index b9661cc..4af43dd 100644
--- a/app/Jobs/GenerateScreenJob.php
+++ b/app/Jobs/GenerateScreenJob.php
@@ -34,8 +34,13 @@ class GenerateScreenJob implements ShouldQueue
Device::find($this->deviceId)->update(['current_screen_image' => $newImageUuid]);
if ($this->pluginId) {
- // cache current image
- Plugin::find($this->pluginId)->update(['current_image' => $newImageUuid]);
+ $plugin = Plugin::find($this->pluginId);
+ $update = ['current_image' => $newImageUuid];
+ if ($plugin->plugin_type === 'recipe') {
+ $device = Device::with(['deviceModel', 'deviceModel.palette'])->find($this->deviceId);
+ $update['current_image_metadata'] = ImageGenerationService::buildImageMetadataFromDevice($device);
+ }
+ $plugin->update($update);
}
ImageGenerationService::cleanupFolder();
diff --git a/app/Models/Plugin.php b/app/Models/Plugin.php
index 3f84bc5..0a39553 100644
--- a/app/Models/Plugin.php
+++ b/app/Models/Plugin.php
@@ -49,6 +49,7 @@ class Plugin extends Model
'preferred_renderer' => 'string',
'plugin_type' => 'string',
'alias' => 'boolean',
+ 'current_image_metadata' => 'array',
];
protected static function boot()
@@ -71,6 +72,7 @@ class Plugin extends Model
'render_markup_shared',
])) {
$model->current_image = null;
+ $model->current_image_metadata = null;
}
});
@@ -222,7 +224,7 @@ class Plugin extends Model
if ($this->data_strategy !== 'polling' || ! $this->polling_url) {
return;
}
- $headers = ['User-Agent' => 'usetrmnl/byos_laravel', 'Accept' => 'application/json'];
+ $headers = ['User-Agent' => 'usetrmnl/larapaper', 'Accept' => 'application/json'];
// resolve headers
if ($this->polling_header) {
diff --git a/app/Services/ImageGenerationService.php b/app/Services/ImageGenerationService.php
index fa6f325..75f374e 100644
--- a/app/Services/ImageGenerationService.php
+++ b/app/Services/ImageGenerationService.php
@@ -331,36 +331,88 @@ class ImageGenerationService
}
}
- public static function resetIfNotCacheable(?Plugin $plugin): void
+ /**
+ * Ensure plugin image cache is valid for the current context. No-op for image_webhook.
+ * When deviceOrModel is provided (recipe only), clears cache if stored metadata does not match.
+ */
+ public static function resetIfNotCacheable(?Plugin $plugin, Device|DeviceModel|null $deviceOrModel = null): void
{
- if ($plugin?->id) {
- // Image webhook plugins have finalized images that shouldn't be reset
- if ($plugin->plugin_type === 'image_webhook') {
- return;
- }
- // Check if any devices have custom dimensions or use non-standard DeviceModels
- $hasCustomDimensions = Device::query()
- ->where(function ($query): void {
- $query->where('width', '!=', 800)
- ->orWhere('height', '!=', 480)
- ->orWhere('rotate', '!=', 0);
- })
- ->orWhereHas('deviceModel', function ($query): void {
- // Only allow caching if all device models have standard dimensions (800x480, rotation=0)
- $query->where(function ($subQuery): void {
- $subQuery->where('width', '!=', 800)
- ->orWhere('height', '!=', 480)
- ->orWhere('rotation', '!=', 0);
- });
- })
- ->exists();
+ if (! $plugin?->id || $plugin->plugin_type === 'image_webhook') {
+ return;
+ }
+ if ($deviceOrModel === null || $plugin->plugin_type !== 'recipe') {
+ return;
+ }
+ if ($plugin->current_image === null) {
+ return;
+ }
+ if (self::imageMetadataMatches($plugin->current_image_metadata, $deviceOrModel)) {
+ return;
+ }
+ $plugin->update([
+ 'current_image' => null,
+ 'current_image_metadata' => null,
+ ]);
+ Log::debug("Plugin {$plugin->id}: cleared image cache due to metadata mismatch");
+ }
- if ($hasCustomDimensions) {
- // TODO cache image per device
- $plugin->update(['current_image' => null]);
- Log::debug('Skip cache as devices with custom dimensions or non-standard DeviceModels exist');
+ /**
+ * Build canonical image metadata from a Device for cache comparison.
+ *
+ * @return array{width: int, height: int, rotation: int, palette_id: int|null, mime_type: string}
+ */
+ public static function buildImageMetadataFromDevice(Device $device): array
+ {
+ $device->loadMissing(['deviceModel', 'deviceModel.palette']);
+ $settings = self::getImageSettings($device);
+ $paletteId = $device->palette_id ?? $device->deviceModel?->palette_id;
+
+ return [
+ 'width' => $settings['width'],
+ 'height' => $settings['height'],
+ 'rotation' => $settings['rotation'] ?? 0,
+ 'palette_id' => $paletteId,
+ 'mime_type' => $settings['mime_type'],
+ ];
+ }
+
+ /**
+ * Build canonical image metadata from a DeviceModel for cache comparison.
+ *
+ * @return array{width: int, height: int, rotation: int, palette_id: int|null, mime_type: string}
+ */
+ public static function buildImageMetadataFromDeviceModel(DeviceModel $model): array
+ {
+ return [
+ 'width' => $model->width,
+ 'height' => $model->height,
+ 'rotation' => $model->rotation ?? 0,
+ 'palette_id' => $model->palette_id,
+ 'mime_type' => $model->mime_type,
+ ];
+ }
+
+ /**
+ * Check if stored metadata matches the current device or device model.
+ * Returns false if stored is null or empty so cache is regenerated and metadata is stored.
+ */
+ public static function imageMetadataMatches(?array $stored, Device|DeviceModel $deviceOrModel): bool
+ {
+ if ($stored === null || $stored === []) {
+ return false;
+ }
+
+ $current = $deviceOrModel instanceof Device
+ ? self::buildImageMetadataFromDevice($deviceOrModel)
+ : self::buildImageMetadataFromDeviceModel($deviceOrModel);
+
+ foreach (['width', 'height', 'rotation', 'palette_id', 'mime_type'] as $key) {
+ if (($stored[$key] ?? null) !== ($current[$key] ?? null)) {
+ return false;
}
}
+
+ return true;
}
/**
diff --git a/composer.lock b/composer.lock
index 03ceff2..82d7b7a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -62,16 +62,16 @@
},
{
"name": "aws/aws-sdk-php",
- "version": "3.370.1",
+ "version": "3.372.1",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "273a9bbed9e73016be390b8428f7925f15ea053e"
+ "reference": "a48ff951eaad7f038eca3e0e89f168048b99082b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/273a9bbed9e73016be390b8428f7925f15ea053e",
- "reference": "273a9bbed9e73016be390b8428f7925f15ea053e",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a48ff951eaad7f038eca3e0e89f168048b99082b",
+ "reference": "a48ff951eaad7f038eca3e0e89f168048b99082b",
"shasum": ""
},
"require": {
@@ -135,11 +135,11 @@
"authors": [
{
"name": "Amazon Web Services",
- "homepage": "http://aws.amazon.com"
+ "homepage": "https://aws.amazon.com"
}
],
"description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
- "homepage": "http://aws.amazon.com/sdkforphp",
+ "homepage": "https://aws.amazon.com/sdk-for-php",
"keywords": [
"amazon",
"aws",
@@ -153,9 +153,9 @@
"support": {
"forum": "https://github.com/aws/aws-sdk-php/discussions",
"issues": "https://github.com/aws/aws-sdk-php/issues",
- "source": "https://github.com/aws/aws-sdk-php/tree/3.370.1"
+ "source": "https://github.com/aws/aws-sdk-php/tree/3.372.1"
},
- "time": "2026-02-23T19:05:30+00:00"
+ "time": "2026-03-06T21:27:21+00:00"
},
{
"name": "bacon/bacon-qr-code",
@@ -214,16 +214,16 @@
},
{
"name": "bnussbau/laravel-trmnl-blade",
- "version": "2.3.1",
+ "version": "2.3.3",
"source": {
"type": "git",
"url": "https://github.com/bnussbau/laravel-trmnl-blade.git",
- "reference": "95b781733a6943acd9d908c3366a3d71e47df4a4"
+ "reference": "777af3e26a6bee154efd87caf06131cc18c84452"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bnussbau/laravel-trmnl-blade/zipball/95b781733a6943acd9d908c3366a3d71e47df4a4",
- "reference": "95b781733a6943acd9d908c3366a3d71e47df4a4",
+ "url": "https://api.github.com/repos/bnussbau/laravel-trmnl-blade/zipball/777af3e26a6bee154efd87caf06131cc18c84452",
+ "reference": "777af3e26a6bee154efd87caf06131cc18c84452",
"shasum": ""
},
"require": {
@@ -278,7 +278,7 @@
],
"support": {
"issues": "https://github.com/bnussbau/laravel-trmnl-blade/issues",
- "source": "https://github.com/bnussbau/laravel-trmnl-blade/tree/2.3.1"
+ "source": "https://github.com/bnussbau/laravel-trmnl-blade/tree/2.3.3"
},
"funding": [
{
@@ -294,7 +294,7 @@
"type": "github"
}
],
- "time": "2026-02-10T16:12:33+00:00"
+ "time": "2026-03-03T06:47:48+00:00"
},
{
"name": "bnussbau/trmnl-pipeline-php",
@@ -1030,16 +1030,16 @@
},
{
"name": "firebase/php-jwt",
- "version": "v7.0.2",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
- "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65"
+ "reference": "28aa0694bcfdfa5e2959c394d5a1ee7a5083629e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5645b43af647b6947daac1d0f659dd1fbe8d3b65",
- "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65",
+ "url": "https://api.github.com/repos/firebase/php-jwt/zipball/28aa0694bcfdfa5e2959c394d5a1ee7a5083629e",
+ "reference": "28aa0694bcfdfa5e2959c394d5a1ee7a5083629e",
"shasum": ""
},
"require": {
@@ -1087,9 +1087,9 @@
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
- "source": "https://github.com/firebase/php-jwt/tree/v7.0.2"
+ "source": "https://github.com/firebase/php-jwt/tree/v7.0.3"
},
- "time": "2025-12-16T22:17:28+00:00"
+ "time": "2026-02-25T22:16:40+00:00"
},
{
"name": "fruitcake/php-cors",
@@ -1695,16 +1695,16 @@
},
{
"name": "keepsuit/laravel-liquid",
- "version": "v0.5.4",
+ "version": "v0.5.5",
"source": {
"type": "git",
"url": "https://github.com/keepsuit/laravel-liquid.git",
- "reference": "ba426f44798042e3635a29ea91bbf2a4b2874a04"
+ "reference": "7f9996cc2eac16489d33d76e265939c2d556bded"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/keepsuit/laravel-liquid/zipball/ba426f44798042e3635a29ea91bbf2a4b2874a04",
- "reference": "ba426f44798042e3635a29ea91bbf2a4b2874a04",
+ "url": "https://api.github.com/repos/keepsuit/laravel-liquid/zipball/7f9996cc2eac16489d33d76e265939c2d556bded",
+ "reference": "7f9996cc2eac16489d33d76e265939c2d556bded",
"shasum": ""
},
"require": {
@@ -1712,7 +1712,7 @@
"keepsuit/liquid": "^0.7 || ^0.8 || ^0.9",
"php": "^8.1",
"spatie/laravel-package-tools": "^1.16",
- "symfony/var-exporter": "^6.3 || ^7.0"
+ "symfony/var-exporter": "^6.3 || ^7.0 || ^8.0"
},
"require-dev": {
"itsgoingd/clockwork": "^5.3",
@@ -1764,9 +1764,9 @@
],
"support": {
"issues": "https://github.com/keepsuit/laravel-liquid/issues",
- "source": "https://github.com/keepsuit/laravel-liquid/tree/v0.5.4"
+ "source": "https://github.com/keepsuit/laravel-liquid/tree/v0.5.5"
},
- "time": "2025-06-15T12:06:40+00:00"
+ "time": "2026-03-04T16:46:40+00:00"
},
{
"name": "keepsuit/liquid",
@@ -2437,16 +2437,16 @@
},
{
"name": "league/commonmark",
- "version": "2.8.0",
+ "version": "2.8.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb"
+ "reference": "84b1ca48347efdbe775426f108622a42735a6579"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
- "reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84b1ca48347efdbe775426f108622a42735a6579",
+ "reference": "84b1ca48347efdbe775426f108622a42735a6579",
"shasum": ""
},
"require": {
@@ -2471,9 +2471,9 @@
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
"scrutinizer/ocular": "^1.8.1",
- "symfony/finder": "^5.3 | ^6.0 | ^7.0",
- "symfony/process": "^5.4 | ^6.0 | ^7.0",
- "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0",
+ "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0",
+ "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0",
+ "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0"
},
@@ -2540,7 +2540,7 @@
"type": "tidelift"
}
],
- "time": "2025-11-26T21:48:24+00:00"
+ "time": "2026-03-05T21:37:03+00:00"
},
{
"name": "league/config",
@@ -2626,16 +2626,16 @@
},
{
"name": "league/flysystem",
- "version": "3.31.0",
+ "version": "3.32.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff"
+ "reference": "254b1595b16b22dbddaaef9ed6ca9fdac4956725"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1717e0b3642b0df65ecb0cc89cdd99fa840672ff",
- "reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/254b1595b16b22dbddaaef9ed6ca9fdac4956725",
+ "reference": "254b1595b16b22dbddaaef9ed6ca9fdac4956725",
"shasum": ""
},
"require": {
@@ -2703,9 +2703,9 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
- "source": "https://github.com/thephpleague/flysystem/tree/3.31.0"
+ "source": "https://github.com/thephpleague/flysystem/tree/3.32.0"
},
- "time": "2026-01-23T15:38:47+00:00"
+ "time": "2026-02-25T17:01:41+00:00"
},
{
"name": "league/flysystem-local",
@@ -3128,26 +3128,26 @@
},
{
"name": "livewire/flux",
- "version": "v2.12.1",
+ "version": "v2.13.0",
"source": {
"type": "git",
"url": "https://github.com/livewire/flux.git",
- "reference": "24c139b97b6df1e67c0235637f0e08c206bf4486"
+ "reference": "741be2d4526e90b97c7a59e079a2f27ecdce2461"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/livewire/flux/zipball/24c139b97b6df1e67c0235637f0e08c206bf4486",
- "reference": "24c139b97b6df1e67c0235637f0e08c206bf4486",
+ "url": "https://api.github.com/repos/livewire/flux/zipball/741be2d4526e90b97c7a59e079a2f27ecdce2461",
+ "reference": "741be2d4526e90b97c7a59e079a2f27ecdce2461",
"shasum": ""
},
"require": {
- "illuminate/console": "^10.0|^11.0|^12.0",
- "illuminate/support": "^10.0|^11.0|^12.0",
- "illuminate/view": "^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",
+ "illuminate/view": "^10.0|^11.0|^12.0|^13.0",
"laravel/prompts": "^0.1|^0.2|^0.3",
"livewire/livewire": "^3.7.4|^4.0",
"php": "^8.1",
- "symfony/console": "^6.0|^7.0"
+ "symfony/console": "^6.0|^7.0|^8.0"
},
"conflict": {
"livewire/blaze": "<1.0.0-beta.2"
@@ -3188,42 +3188,42 @@
],
"support": {
"issues": "https://github.com/livewire/flux/issues",
- "source": "https://github.com/livewire/flux/tree/v2.12.1"
+ "source": "https://github.com/livewire/flux/tree/v2.13.0"
},
- "time": "2026-02-17T21:12:27+00:00"
+ "time": "2026-03-03T03:32:35+00:00"
},
{
"name": "livewire/livewire",
- "version": "v4.1.4",
+ "version": "v4.2.1",
"source": {
"type": "git",
"url": "https://github.com/livewire/livewire.git",
- "reference": "4697085e02a1f5f11410a1b5962400e3539f8843"
+ "reference": "93e972fa42c1b34fff1550093ab94f778d81ea5a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/livewire/livewire/zipball/4697085e02a1f5f11410a1b5962400e3539f8843",
- "reference": "4697085e02a1f5f11410a1b5962400e3539f8843",
+ "url": "https://api.github.com/repos/livewire/livewire/zipball/93e972fa42c1b34fff1550093ab94f778d81ea5a",
+ "reference": "93e972fa42c1b34fff1550093ab94f778d81ea5a",
"shasum": ""
},
"require": {
- "illuminate/database": "^10.0|^11.0|^12.0",
- "illuminate/routing": "^10.0|^11.0|^12.0",
- "illuminate/support": "^10.0|^11.0|^12.0",
- "illuminate/validation": "^10.0|^11.0|^12.0",
+ "illuminate/database": "^10.0|^11.0|^12.0|^13.0",
+ "illuminate/routing": "^10.0|^11.0|^12.0|^13.0",
+ "illuminate/support": "^10.0|^11.0|^12.0|^13.0",
+ "illuminate/validation": "^10.0|^11.0|^12.0|^13.0",
"laravel/prompts": "^0.1.24|^0.2|^0.3",
"league/mime-type-detection": "^1.9",
"php": "^8.1",
- "symfony/console": "^6.0|^7.0",
- "symfony/http-kernel": "^6.2|^7.0"
+ "symfony/console": "^6.0|^7.0|^8.0",
+ "symfony/http-kernel": "^6.2|^7.0|^8.0"
},
"require-dev": {
"calebporzio/sushi": "^2.1",
- "laravel/framework": "^10.15.0|^11.0|^12.0",
+ "laravel/framework": "^10.15.0|^11.0|^12.0|^13.0",
"mockery/mockery": "^1.3.1",
- "orchestra/testbench": "^8.21.0|^9.0|^10.0",
- "orchestra/testbench-dusk": "^8.24|^9.1|^10.0",
- "phpunit/phpunit": "^10.4|^11.5",
+ "orchestra/testbench": "^8.21.0|^9.0|^10.0|^11.0",
+ "orchestra/testbench-dusk": "^8.24|^9.1|^10.0|^11.0",
+ "phpunit/phpunit": "^10.4|^11.5|^12.5",
"psy/psysh": "^0.11.22|^0.12"
},
"type": "library",
@@ -3258,7 +3258,7 @@
"description": "A front-end framework for Laravel.",
"support": {
"issues": "https://github.com/livewire/livewire/issues",
- "source": "https://github.com/livewire/livewire/tree/v4.1.4"
+ "source": "https://github.com/livewire/livewire/tree/v4.2.1"
},
"funding": [
{
@@ -3266,7 +3266,7 @@
"type": "github"
}
],
- "time": "2026-02-09T22:59:54+00:00"
+ "time": "2026-02-28T00:01:19+00:00"
},
{
"name": "maennchen/zipstream-php",
@@ -4902,16 +4902,16 @@
},
{
"name": "psy/psysh",
- "version": "v0.12.20",
+ "version": "v0.12.21",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
- "reference": "19678eb6b952a03b8a1d96ecee9edba518bb0373"
+ "reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bobthecow/psysh/zipball/19678eb6b952a03b8a1d96ecee9edba518bb0373",
- "reference": "19678eb6b952a03b8a1d96ecee9edba518bb0373",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4821fab5b7cd8c49a673a9fd5754dc9162bb9e97",
+ "reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97",
"shasum": ""
},
"require": {
@@ -4975,9 +4975,9 @@
],
"support": {
"issues": "https://github.com/bobthecow/psysh/issues",
- "source": "https://github.com/bobthecow/psysh/tree/v0.12.20"
+ "source": "https://github.com/bobthecow/psysh/tree/v0.12.21"
},
- "time": "2026-02-11T15:05:28+00:00"
+ "time": "2026-03-06T21:21:28+00:00"
},
{
"name": "ralouphie/getallheaders",
@@ -5597,16 +5597,16 @@
},
{
"name": "symfony/console",
- "version": "v7.4.4",
+ "version": "v7.4.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894"
+ "reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/41e38717ac1dd7a46b6bda7d6a82af2d98a78894",
- "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894",
+ "url": "https://api.github.com/repos/symfony/console/zipball/e1e6770440fb9c9b0cf725f81d1361ad1835329d",
+ "reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d",
"shasum": ""
},
"require": {
@@ -5671,7 +5671,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v7.4.4"
+ "source": "https://github.com/symfony/console/tree/v7.4.7"
},
"funding": [
{
@@ -5691,20 +5691,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-13T11:36:38+00:00"
+ "time": "2026-03-06T14:06:20+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v8.0.0",
+ "version": "v8.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b"
+ "reference": "2a178bf80f05dbbe469a337730eba79d61315262"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/6225bd458c53ecdee056214cb4a2ffaf58bd592b",
- "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/2a178bf80f05dbbe469a337730eba79d61315262",
+ "reference": "2a178bf80f05dbbe469a337730eba79d61315262",
"shasum": ""
},
"require": {
@@ -5740,7 +5740,7 @@
"description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/css-selector/tree/v8.0.0"
+ "source": "https://github.com/symfony/css-selector/tree/v8.0.6"
},
"funding": [
{
@@ -5760,7 +5760,7 @@
"type": "tidelift"
}
],
- "time": "2025-10-30T14:17:19+00:00"
+ "time": "2026-02-17T13:07:04+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -6074,16 +6074,16 @@
},
{
"name": "symfony/filesystem",
- "version": "v8.0.1",
+ "version": "v8.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "d937d400b980523dc9ee946bb69972b5e619058d"
+ "reference": "7bf9162d7a0dff98d079b72948508fa48018a770"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/d937d400b980523dc9ee946bb69972b5e619058d",
- "reference": "d937d400b980523dc9ee946bb69972b5e619058d",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/7bf9162d7a0dff98d079b72948508fa48018a770",
+ "reference": "7bf9162d7a0dff98d079b72948508fa48018a770",
"shasum": ""
},
"require": {
@@ -6120,7 +6120,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v8.0.1"
+ "source": "https://github.com/symfony/filesystem/tree/v8.0.6"
},
"funding": [
{
@@ -6140,20 +6140,20 @@
"type": "tidelift"
}
],
- "time": "2025-12-01T09:13:36+00:00"
+ "time": "2026-02-25T16:59:43+00:00"
},
{
"name": "symfony/finder",
- "version": "v7.4.5",
+ "version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb"
+ "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/ad4daa7c38668dcb031e63bc99ea9bd42196a2cb",
- "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/8655bf1076b7a3a346cb11413ffdabff50c7ffcf",
+ "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf",
"shasum": ""
},
"require": {
@@ -6188,7 +6188,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.5"
+ "source": "https://github.com/symfony/finder/tree/v7.4.6"
},
"funding": [
{
@@ -6208,20 +6208,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-26T15:07:59+00:00"
+ "time": "2026-01-29T09:40:50+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v7.4.5",
+ "version": "v7.4.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "446d0db2b1f21575f1284b74533e425096abdfb6"
+ "reference": "f94b3e7b7dafd40e666f0c9ff2084133bae41e81"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/446d0db2b1f21575f1284b74533e425096abdfb6",
- "reference": "446d0db2b1f21575f1284b74533e425096abdfb6",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f94b3e7b7dafd40e666f0c9ff2084133bae41e81",
+ "reference": "f94b3e7b7dafd40e666f0c9ff2084133bae41e81",
"shasum": ""
},
"require": {
@@ -6270,7 +6270,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v7.4.5"
+ "source": "https://github.com/symfony/http-foundation/tree/v7.4.7"
},
"funding": [
{
@@ -6290,20 +6290,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-27T16:16:02+00:00"
+ "time": "2026-03-06T13:15:18+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v7.4.5",
+ "version": "v7.4.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "229eda477017f92bd2ce7615d06222ec0c19e82a"
+ "reference": "3b3fcf386c809be990c922e10e4c620d6367cab1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/229eda477017f92bd2ce7615d06222ec0c19e82a",
- "reference": "229eda477017f92bd2ce7615d06222ec0c19e82a",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3b3fcf386c809be990c922e10e4c620d6367cab1",
+ "reference": "3b3fcf386c809be990c922e10e4c620d6367cab1",
"shasum": ""
},
"require": {
@@ -6345,7 +6345,7 @@
"symfony/config": "^6.4|^7.0|^8.0",
"symfony/console": "^6.4|^7.0|^8.0",
"symfony/css-selector": "^6.4|^7.0|^8.0",
- "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4.1|^7.0.1|^8.0",
"symfony/dom-crawler": "^6.4|^7.0|^8.0",
"symfony/expression-language": "^6.4|^7.0|^8.0",
"symfony/finder": "^6.4|^7.0|^8.0",
@@ -6389,7 +6389,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v7.4.5"
+ "source": "https://github.com/symfony/http-kernel/tree/v7.4.7"
},
"funding": [
{
@@ -6409,20 +6409,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-28T10:33:42+00:00"
+ "time": "2026-03-06T16:33:18+00:00"
},
{
"name": "symfony/mailer",
- "version": "v7.4.4",
+ "version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
- "reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6"
+ "reference": "b02726f39a20bc65e30364f5c750c4ddbf1f58e9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/7b750074c40c694ceb34cb926d6dffee231c5cd6",
- "reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/b02726f39a20bc65e30364f5c750c4ddbf1f58e9",
+ "reference": "b02726f39a20bc65e30364f5c750c4ddbf1f58e9",
"shasum": ""
},
"require": {
@@ -6473,7 +6473,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailer/tree/v7.4.4"
+ "source": "https://github.com/symfony/mailer/tree/v7.4.6"
},
"funding": [
{
@@ -6493,20 +6493,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-08T08:25:11+00:00"
+ "time": "2026-02-25T16:50:00+00:00"
},
{
"name": "symfony/mime",
- "version": "v7.4.5",
+ "version": "v7.4.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
- "reference": "b18c7e6e9eee1e19958138df10412f3c4c316148"
+ "reference": "da5ab4fde3f6c88ab06e96185b9922f48b677cd1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/b18c7e6e9eee1e19958138df10412f3c4c316148",
- "reference": "b18c7e6e9eee1e19958138df10412f3c4c316148",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/da5ab4fde3f6c88ab06e96185b9922f48b677cd1",
+ "reference": "da5ab4fde3f6c88ab06e96185b9922f48b677cd1",
"shasum": ""
},
"require": {
@@ -6517,7 +6517,7 @@
},
"conflict": {
"egulias/email-validator": "~3.0.0",
- "phpdocumentor/reflection-docblock": "<5.2|>=6",
+ "phpdocumentor/reflection-docblock": "<5.2|>=7",
"phpdocumentor/type-resolver": "<1.5.1",
"symfony/mailer": "<6.4",
"symfony/serializer": "<6.4.3|>7.0,<7.0.3"
@@ -6525,7 +6525,7 @@
"require-dev": {
"egulias/email-validator": "^2.1.10|^3.1|^4",
"league/html-to-markdown": "^5.0",
- "phpdocumentor/reflection-docblock": "^5.2",
+ "phpdocumentor/reflection-docblock": "^5.2|^6.0",
"symfony/dependency-injection": "^6.4|^7.0|^8.0",
"symfony/process": "^6.4|^7.0|^8.0",
"symfony/property-access": "^6.4|^7.0|^8.0",
@@ -6562,7 +6562,7 @@
"mime-type"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v7.4.5"
+ "source": "https://github.com/symfony/mime/tree/v7.4.7"
},
"funding": [
{
@@ -6582,7 +6582,7 @@
"type": "tidelift"
}
],
- "time": "2026-01-27T08:59:58+00:00"
+ "time": "2026-03-05T15:24:09+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -7480,16 +7480,16 @@
},
{
"name": "symfony/routing",
- "version": "v7.4.4",
+ "version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "0798827fe2c79caeed41d70b680c2c3507d10147"
+ "reference": "238d749c56b804b31a9bf3e26519d93b65a60938"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/0798827fe2c79caeed41d70b680c2c3507d10147",
- "reference": "0798827fe2c79caeed41d70b680c2c3507d10147",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/238d749c56b804b31a9bf3e26519d93b65a60938",
+ "reference": "238d749c56b804b31a9bf3e26519d93b65a60938",
"shasum": ""
},
"require": {
@@ -7541,7 +7541,7 @@
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v7.4.4"
+ "source": "https://github.com/symfony/routing/tree/v7.4.6"
},
"funding": [
{
@@ -7561,7 +7561,7 @@
"type": "tidelift"
}
],
- "time": "2026-01-12T12:19:02+00:00"
+ "time": "2026-02-25T16:50:00+00:00"
},
{
"name": "symfony/service-contracts",
@@ -7652,16 +7652,16 @@
},
{
"name": "symfony/string",
- "version": "v8.0.4",
+ "version": "v8.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "758b372d6882506821ed666032e43020c4f57194"
+ "reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194",
- "reference": "758b372d6882506821ed666032e43020c4f57194",
+ "url": "https://api.github.com/repos/symfony/string/zipball/6c9e1108041b5dce21a9a4984b531c4923aa9ec4",
+ "reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4",
"shasum": ""
},
"require": {
@@ -7718,7 +7718,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v8.0.4"
+ "source": "https://github.com/symfony/string/tree/v8.0.6"
},
"funding": [
{
@@ -7738,20 +7738,20 @@
"type": "tidelift"
}
],
- "time": "2026-01-12T12:37:40+00:00"
+ "time": "2026-02-09T10:14:57+00:00"
},
{
"name": "symfony/translation",
- "version": "v8.0.4",
+ "version": "v8.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10"
+ "reference": "13ff19bcf2bea492d3c2fbeaa194dd6f4599ce1b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/db70c8ce7db74fd2da7b1d268db46b2a8ce32c10",
- "reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/13ff19bcf2bea492d3c2fbeaa194dd6f4599ce1b",
+ "reference": "13ff19bcf2bea492d3c2fbeaa194dd6f4599ce1b",
"shasum": ""
},
"require": {
@@ -7811,7 +7811,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/translation/tree/v8.0.4"
+ "source": "https://github.com/symfony/translation/tree/v8.0.6"
},
"funding": [
{
@@ -7831,7 +7831,7 @@
"type": "tidelift"
}
],
- "time": "2026-01-13T13:06:50+00:00"
+ "time": "2026-02-17T13:07:04+00:00"
},
{
"name": "symfony/translation-contracts",
@@ -7995,16 +7995,16 @@
},
{
"name": "symfony/var-dumper",
- "version": "v7.4.4",
+ "version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "0e4769b46a0c3c62390d124635ce59f66874b282"
+ "reference": "045321c440ac18347b136c63d2e9bf28a2dc0291"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e4769b46a0c3c62390d124635ce59f66874b282",
- "reference": "0e4769b46a0c3c62390d124635ce59f66874b282",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/045321c440ac18347b136c63d2e9bf28a2dc0291",
+ "reference": "045321c440ac18347b136c63d2e9bf28a2dc0291",
"shasum": ""
},
"require": {
@@ -8058,7 +8058,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v7.4.4"
+ "source": "https://github.com/symfony/var-dumper/tree/v7.4.6"
},
"funding": [
{
@@ -8078,30 +8078,29 @@
"type": "tidelift"
}
],
- "time": "2026-01-01T22:13:48+00:00"
+ "time": "2026-02-15T10:53:20+00:00"
},
{
"name": "symfony/var-exporter",
- "version": "v7.4.0",
+ "version": "v8.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
- "reference": "03a60f169c79a28513a78c967316fbc8bf17816f"
+ "reference": "7345f46c251f2eb27c7b3ebdb5bb076b3ffcae04"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-exporter/zipball/03a60f169c79a28513a78c967316fbc8bf17816f",
- "reference": "03a60f169c79a28513a78c967316fbc8bf17816f",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/7345f46c251f2eb27c7b3ebdb5bb076b3ffcae04",
+ "reference": "7345f46c251f2eb27c7b3ebdb5bb076b3ffcae04",
"shasum": ""
},
"require": {
- "php": ">=8.2",
- "symfony/deprecation-contracts": "^2.5|^3"
+ "php": ">=8.4"
},
"require-dev": {
- "symfony/property-access": "^6.4|^7.0|^8.0",
- "symfony/serializer": "^6.4|^7.0|^8.0",
- "symfony/var-dumper": "^6.4|^7.0|^8.0"
+ "symfony/property-access": "^7.4|^8.0",
+ "symfony/serializer": "^7.4|^8.0",
+ "symfony/var-dumper": "^7.4|^8.0"
},
"type": "library",
"autoload": {
@@ -8139,7 +8138,7 @@
"serialize"
],
"support": {
- "source": "https://github.com/symfony/var-exporter/tree/v7.4.0"
+ "source": "https://github.com/symfony/var-exporter/tree/v8.0.0"
},
"funding": [
{
@@ -8159,20 +8158,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:15:23+00:00"
+ "time": "2025-11-05T18:53:00+00:00"
},
{
"name": "symfony/yaml",
- "version": "v7.4.1",
+ "version": "v7.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "24dd4de28d2e3988b311751ac49e684d783e2345"
+ "reference": "58751048de17bae71c5aa0d13cb19d79bca26391"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345",
- "reference": "24dd4de28d2e3988b311751ac49e684d783e2345",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/58751048de17bae71c5aa0d13cb19d79bca26391",
+ "reference": "58751048de17bae71c5aa0d13cb19d79bca26391",
"shasum": ""
},
"require": {
@@ -8215,7 +8214,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v7.4.1"
+ "source": "https://github.com/symfony/yaml/tree/v7.4.6"
},
"funding": [
{
@@ -8235,7 +8234,7 @@
"type": "tidelift"
}
],
- "time": "2025-12-04T18:11:45+00:00"
+ "time": "2026-02-09T09:33:46+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -8452,23 +8451,23 @@
},
{
"name": "wnx/sidecar-browsershot",
- "version": "v2.7.0",
+ "version": "v2.8.0",
"source": {
"type": "git",
"url": "https://github.com/stefanzweifel/sidecar-browsershot.git",
- "reference": "e42a996c6fab4357919cd5e3f3fab33f019cdd80"
+ "reference": "1d2a20a6723b74c139f98f7a020fe5c0f57d05a5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/stefanzweifel/sidecar-browsershot/zipball/e42a996c6fab4357919cd5e3f3fab33f019cdd80",
- "reference": "e42a996c6fab4357919cd5e3f3fab33f019cdd80",
+ "url": "https://api.github.com/repos/stefanzweifel/sidecar-browsershot/zipball/1d2a20a6723b74c139f98f7a020fe5c0f57d05a5",
+ "reference": "1d2a20a6723b74c139f98f7a020fe5c0f57d05a5",
"shasum": ""
},
"require": {
- "hammerstone/sidecar": "^0.7",
+ "hammerstone/sidecar": "^0.7.1",
"illuminate/contracts": "^12.0",
"php": "^8.4",
- "spatie/browsershot": "^4.0 || ^5.0",
+ "spatie/browsershot": "^5.0",
"spatie/laravel-package-tools": "^1.9.2"
},
"require-dev": {
@@ -8484,7 +8483,7 @@
"phpstan/phpstan-phpunit": "^1.0|^2.0",
"phpunit/phpunit": "^11.0 | ^12.0",
"spatie/image": "^3.3",
- "spatie/pixelmatch-php": "^1.0"
+ "spatie/pixelmatch-php": "^1.2"
},
"type": "library",
"extra": {
@@ -8526,7 +8525,7 @@
],
"support": {
"issues": "https://github.com/stefanzweifel/sidecar-browsershot/issues",
- "source": "https://github.com/stefanzweifel/sidecar-browsershot/tree/v2.7.0"
+ "source": "https://github.com/stefanzweifel/sidecar-browsershot/tree/v2.8.0"
},
"funding": [
{
@@ -8534,7 +8533,7 @@
"type": "github"
}
],
- "time": "2025-11-22T08:49:08+00:00"
+ "time": "2026-03-07T18:24:28+00:00"
}
],
"packages-dev": [
@@ -8980,40 +8979,40 @@
},
{
"name": "larastan/larastan",
- "version": "v3.9.2",
+ "version": "v3.9.3",
"source": {
"type": "git",
"url": "https://github.com/larastan/larastan.git",
- "reference": "2e9ed291bdc1969e7f270fb33c9cdf3c912daeb2"
+ "reference": "64a52bcc5347c89fdf131cb59f96ebfbc8d1ad65"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/larastan/larastan/zipball/2e9ed291bdc1969e7f270fb33c9cdf3c912daeb2",
- "reference": "2e9ed291bdc1969e7f270fb33c9cdf3c912daeb2",
+ "url": "https://api.github.com/repos/larastan/larastan/zipball/64a52bcc5347c89fdf131cb59f96ebfbc8d1ad65",
+ "reference": "64a52bcc5347c89fdf131cb59f96ebfbc8d1ad65",
"shasum": ""
},
"require": {
"ext-json": "*",
"iamcal/sql-parser": "^0.7.0",
- "illuminate/console": "^11.44.2 || ^12.4.1",
- "illuminate/container": "^11.44.2 || ^12.4.1",
- "illuminate/contracts": "^11.44.2 || ^12.4.1",
- "illuminate/database": "^11.44.2 || ^12.4.1",
- "illuminate/http": "^11.44.2 || ^12.4.1",
- "illuminate/pipeline": "^11.44.2 || ^12.4.1",
- "illuminate/support": "^11.44.2 || ^12.4.1",
+ "illuminate/console": "^11.44.2 || ^12.4.1 || ^13",
+ "illuminate/container": "^11.44.2 || ^12.4.1 || ^13",
+ "illuminate/contracts": "^11.44.2 || ^12.4.1 || ^13",
+ "illuminate/database": "^11.44.2 || ^12.4.1 || ^13",
+ "illuminate/http": "^11.44.2 || ^12.4.1 || ^13",
+ "illuminate/pipeline": "^11.44.2 || ^12.4.1 || ^13",
+ "illuminate/support": "^11.44.2 || ^12.4.1 || ^13",
"php": "^8.2",
"phpstan/phpstan": "^2.1.32"
},
"require-dev": {
"doctrine/coding-standard": "^13",
- "laravel/framework": "^11.44.2 || ^12.7.2",
+ "laravel/framework": "^11.44.2 || ^12.7.2 || ^13",
"mockery/mockery": "^1.6.12",
"nikic/php-parser": "^5.4",
- "orchestra/canvas": "^v9.2.2 || ^10.0.1",
- "orchestra/testbench-core": "^9.12.0 || ^10.1",
+ "orchestra/canvas": "^v9.2.2 || ^10.0.1 || ^11",
+ "orchestra/testbench-core": "^9.12.0 || ^10.1 || ^11",
"phpstan/phpstan-deprecation-rules": "^2.0.1",
- "phpunit/phpunit": "^10.5.35 || ^11.5.15"
+ "phpunit/phpunit": "^10.5.35 || ^11.5.15 || ^12.5.8"
},
"suggest": {
"orchestra/testbench": "Using Larastan for analysing a package needs Testbench",
@@ -9058,7 +9057,7 @@
],
"support": {
"issues": "https://github.com/larastan/larastan/issues",
- "source": "https://github.com/larastan/larastan/tree/v3.9.2"
+ "source": "https://github.com/larastan/larastan/tree/v3.9.3"
},
"funding": [
{
@@ -9066,29 +9065,29 @@
"type": "github"
}
],
- "time": "2026-01-30T15:16:32+00:00"
+ "time": "2026-02-20T12:07:12+00:00"
},
{
"name": "laravel/boost",
- "version": "v2.2.0",
+ "version": "v2.2.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/boost.git",
- "reference": "b4c5bed7b45e9cd9f705ef3ab1157d437376323c"
+ "reference": "44ab65a5455c2d6fceb71d6145f8d5d89c02d889"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/boost/zipball/b4c5bed7b45e9cd9f705ef3ab1157d437376323c",
- "reference": "b4c5bed7b45e9cd9f705ef3ab1157d437376323c",
+ "url": "https://api.github.com/repos/laravel/boost/zipball/44ab65a5455c2d6fceb71d6145f8d5d89c02d889",
+ "reference": "44ab65a5455c2d6fceb71d6145f8d5d89c02d889",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^7.9",
- "illuminate/console": "^11.45.3|^12.41.1",
- "illuminate/contracts": "^11.45.3|^12.41.1",
- "illuminate/routing": "^11.45.3|^12.41.1",
- "illuminate/support": "^11.45.3|^12.41.1",
- "laravel/mcp": "^0.5.1",
+ "illuminate/console": "^11.45.3|^12.41.1|^13.0",
+ "illuminate/contracts": "^11.45.3|^12.41.1|^13.0",
+ "illuminate/routing": "^11.45.3|^12.41.1|^13.0",
+ "illuminate/support": "^11.45.3|^12.41.1|^13.0",
+ "laravel/mcp": "^0.5.1|^0.6.0",
"laravel/prompts": "^0.3.10",
"laravel/roster": "^0.5.0",
"php": "^8.2"
@@ -9096,7 +9095,7 @@
"require-dev": {
"laravel/pint": "^1.27.0",
"mockery/mockery": "^1.6.12",
- "orchestra/testbench": "^9.15.0|^10.6",
+ "orchestra/testbench": "^9.15.0|^10.6|^11.0",
"pestphp/pest": "^2.36.0|^3.8.4|^4.1.5",
"phpstan/phpstan": "^2.1.27",
"rector/rector": "^2.1"
@@ -9132,20 +9131,20 @@
"issues": "https://github.com/laravel/boost/issues",
"source": "https://github.com/laravel/boost"
},
- "time": "2026-02-20T14:45:22+00:00"
+ "time": "2026-03-06T20:20:28+00:00"
},
{
"name": "laravel/mcp",
- "version": "v0.5.9",
+ "version": "v0.6.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/mcp.git",
- "reference": "39e8da60eb7bce4737c5d868d35a3fe78938c129"
+ "reference": "28860a10ca0cc5433e25d897ba7af844e6c7b6a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/mcp/zipball/39e8da60eb7bce4737c5d868d35a3fe78938c129",
- "reference": "39e8da60eb7bce4737c5d868d35a3fe78938c129",
+ "url": "https://api.github.com/repos/laravel/mcp/zipball/28860a10ca0cc5433e25d897ba7af844e6c7b6a2",
+ "reference": "28860a10ca0cc5433e25d897ba7af844e6c7b6a2",
"shasum": ""
},
"require": {
@@ -9205,7 +9204,7 @@
"issues": "https://github.com/laravel/mcp/issues",
"source": "https://github.com/laravel/mcp"
},
- "time": "2026-02-17T19:05:53+00:00"
+ "time": "2026-02-24T08:43:06+00:00"
},
{
"name": "laravel/pail",
@@ -9356,16 +9355,16 @@
},
{
"name": "laravel/roster",
- "version": "v0.5.0",
+ "version": "v0.5.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/roster.git",
- "reference": "56904a78f4d7360c1c490ced7deeebf9aecb8c0e"
+ "reference": "5089de7615f72f78e831590ff9d0435fed0102bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/roster/zipball/56904a78f4d7360c1c490ced7deeebf9aecb8c0e",
- "reference": "56904a78f4d7360c1c490ced7deeebf9aecb8c0e",
+ "url": "https://api.github.com/repos/laravel/roster/zipball/5089de7615f72f78e831590ff9d0435fed0102bb",
+ "reference": "5089de7615f72f78e831590ff9d0435fed0102bb",
"shasum": ""
},
"require": {
@@ -9413,7 +9412,7 @@
"issues": "https://github.com/laravel/roster/issues",
"source": "https://github.com/laravel/roster"
},
- "time": "2026-02-17T17:33:35+00:00"
+ "time": "2026-03-05T07:58:43+00:00"
},
{
"name": "laravel/sail",
@@ -12055,16 +12054,16 @@
},
{
"name": "webmozart/assert",
- "version": "2.1.5",
+ "version": "2.1.6",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
- "reference": "79155f94852fa27e2f73b459f6503f5e87e2c188"
+ "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/79155f94852fa27e2f73b459f6503f5e87e2c188",
- "reference": "79155f94852fa27e2f73b459f6503f5e87e2c188",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/ff31ad6efc62e66e518fbab1cde3453d389bcdc8",
+ "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8",
"shasum": ""
},
"require": {
@@ -12111,9 +12110,9 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/2.1.5"
+ "source": "https://github.com/webmozarts/assert/tree/2.1.6"
},
- "time": "2026-02-18T14:09:36+00:00"
+ "time": "2026-02-27T10:28:38+00:00"
}
],
"aliases": [],
diff --git a/config/app.php b/config/app.php
index fe8499c..176342e 100644
--- a/config/app.php
+++ b/config/app.php
@@ -13,7 +13,7 @@ return [
|
*/
- 'name' => env('APP_NAME', 'Laravel'),
+ 'name' => env('APP_NAME', 'LaraPaper'),
/*
|--------------------------------------------------------------------------
@@ -127,6 +127,8 @@ return [
'enabled' => env('REGISTRATION_ENABLED', true),
],
+ 'pixel_logo_enabled' => env('PIXELLOGO_ENABLED', true),
+
'force_https' => env('FORCE_HTTPS', false),
'puppeteer_docker' => env('PUPPETEER_DOCKER', false),
'puppeteer_mode' => env('PUPPETEER_MODE', 'local'),
@@ -154,5 +156,5 @@ return [
'catalog_url' => env('CATALOG_URL', 'https://raw.githubusercontent.com/bnussbau/trmnl-recipe-catalog/refs/heads/main/catalog.yaml'),
- 'github_repo' => env('GITHUB_REPO', 'usetrmnl/byos_laravel'),
+ 'github_repo' => env('GITHUB_REPO', 'usetrmnl/larapaper'),
];
diff --git a/database/migrations/2026_02_27_153837_add_current_image_metadata_to_plugins_table.php b/database/migrations/2026_02_27_153837_add_current_image_metadata_to_plugins_table.php
new file mode 100644
index 0000000..d212fe7
--- /dev/null
+++ b/database/migrations/2026_02_27_153837_add_current_image_metadata_to_plugins_table.php
@@ -0,0 +1,28 @@
+json('current_image_metadata')->nullable()->after('current_image');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('plugins', function (Blueprint $table) {
+ $table->dropColumn('current_image_metadata');
+ });
+ }
+};
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index c7125c5..5811f4c 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\Device;
+use App\Models\Playlist;
use App\Models\Plugin;
use App\Models\User;
use Illuminate\Database\Seeder;
@@ -23,9 +24,19 @@ class DatabaseSeeder extends Seeder
'password' => bcrypt('admin@example.com'),
]);
- Device::factory(1)->create([
+ $device = Device::factory()->create([
'mac_address' => '00:00:00:00:00:00',
'api_key' => 'test-api-key',
+ 'proxy_cloud' => false,
+ ]);
+
+ Playlist::factory()->create([
+ 'device_id' => $device->id,
+ 'name' => 'Default',
+ 'is_active' => true,
+ 'active_from' => null,
+ 'active_until' => null,
+ 'weekdays' => null
]);
// Device::factory(5)->create();
diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml
index 38cac0e..eaa48fb 100644
--- a/docker/prod/docker-compose.yml
+++ b/docker/prod/docker-compose.yml
@@ -1,9 +1,10 @@
services:
app:
- image: ghcr.io/usetrmnl/byos_laravel:latest
+ image: ghcr.io/usetrmnl/larapaper:latest
ports:
- "4567:8080"
environment:
+ # Generate the APP_KEY with `echo "base64:$(openssl rand -base64 32)"`
#- APP_KEY=
- PHP_OPCACHE_ENABLE=1
- TRMNL_PROXY_REFRESH_MINUTES=15
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
index 40bcbd3..e2246bc 100644
--- a/docs/DEVELOPMENT.md
+++ b/docs/DEVELOPMENT.md
@@ -9,7 +9,7 @@
#### Clone the repository
```bash
-git clone git@github.com:usetrmnl/byos_laravel.git
+git clone git@github.com:usetrmnl/larapaper.git
```
#### Copy environment file
diff --git a/resources/views/components/app-logo.blade.php b/resources/views/components/app-logo.blade.php
index 842020e..f50634a 100644
--- a/resources/views/components/app-logo.blade.php
+++ b/resources/views/components/app-logo.blade.php
@@ -2,5 +2,9 @@
date: "%N" is unsupported. Use date: "u" instead