From dcd325dc44f20806d983c92d4fa60fb28ad961d7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:09:49 +0200 Subject: [PATCH 001/178] feat(v5): add Inertia app shell with Flux health Adds v5 routing, middleware, home page rendering, team context sharing, project model/table support, and Flux health reporting. Installs Flux in container builds with role-aware s6 services and documents runtime roles. --- README.md | 25 + app/Http/Controllers/V5/HomeController.php | 44 + app/Http/Kernel.php | 18 + app/Http/Middleware/V5/EnsureCurrentTeam.php | 54 ++ .../Middleware/V5/HandleInertiaRequests.php | 25 + app/Models/V5/Project.php | 29 + app/Models/V5/V5Model.php | 10 + app/Providers/RouteServiceProvider.php | 5 + app/Services/Flux/FluxHealth.php | 66 ++ composer.json | 1 + composer.lock | 111 ++- config/flux.php | 6 + ..._06_04_050157_create_v5_projects_table.php | 33 + database/schema/testing-schema.sql | 11 + docker-compose.dev.yml | 2 + docker-compose.prod.yml | 4 + docker/development/Dockerfile | 27 + .../s6-rc.d/flux/dependencies.d/init-setup | 0 .../etc/s6-overlay/s6-rc.d/flux/run | 49 ++ .../etc/s6-overlay/s6-rc.d/flux/type | 1 + .../etc/s6-overlay/s6-rc.d/horizon/run | 14 + .../s6-overlay/s6-rc.d/nightwatch-agent/run | 14 + .../s6-overlay/s6-rc.d/scheduler-worker/run | 14 + .../s6-overlay/s6-rc.d/user/contents.d/flux | 0 docker/production/Dockerfile | 27 + .../s6-rc.d/flux/dependencies.d/init-script | 0 .../etc/s6-overlay/s6-rc.d/flux/run | 49 ++ .../etc/s6-overlay/s6-rc.d/flux/type | 1 + .../etc/s6-overlay/s6-rc.d/horizon/run | 14 + .../s6-overlay/s6-rc.d/nightwatch-agent/run | 14 + .../s6-overlay/s6-rc.d/scheduler-worker/run | 14 + .../s6-overlay/s6-rc.d/user/contents.d/flux | 0 package-lock.json | 793 ++++++++++++++++-- package.json | 7 +- resources/css/v5/app.css | 11 + resources/js/v5/Pages/Home.jsx | 59 ++ resources/js/v5/app.jsx | 11 + resources/views/v5/app.blade.php | 18 + routes/v5.php | 8 + tests/Feature/V5/HomeTest.php | 214 +++++ vite.config.js | 10 +- 41 files changed, 1705 insertions(+), 108 deletions(-) create mode 100644 app/Http/Controllers/V5/HomeController.php create mode 100644 app/Http/Middleware/V5/EnsureCurrentTeam.php create mode 100644 app/Http/Middleware/V5/HandleInertiaRequests.php create mode 100644 app/Models/V5/Project.php create mode 100644 app/Models/V5/V5Model.php create mode 100644 app/Services/Flux/FluxHealth.php create mode 100644 config/flux.php create mode 100644 database/migrations/2026_06_04_050157_create_v5_projects_table.php create mode 100644 docker/development/etc/s6-overlay/s6-rc.d/flux/dependencies.d/init-setup create mode 100755 docker/development/etc/s6-overlay/s6-rc.d/flux/run create mode 100644 docker/development/etc/s6-overlay/s6-rc.d/flux/type create mode 100644 docker/development/etc/s6-overlay/s6-rc.d/user/contents.d/flux create mode 100644 docker/production/etc/s6-overlay/s6-rc.d/flux/dependencies.d/init-script create mode 100755 docker/production/etc/s6-overlay/s6-rc.d/flux/run create mode 100644 docker/production/etc/s6-overlay/s6-rc.d/flux/type create mode 100644 docker/production/etc/s6-overlay/s6-rc.d/user/contents.d/flux create mode 100644 resources/css/v5/app.css create mode 100644 resources/js/v5/Pages/Home.jsx create mode 100644 resources/js/v5/app.jsx create mode 100644 resources/views/v5/app.blade.php create mode 100644 routes/v5.php create mode 100644 tests/Feature/V5/HomeTest.php diff --git a/README.md b/README.md index b387d87e8..f4e289bcd 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,31 @@ You can find the installation script source [here](./scripts/install.sh). > [!NOTE] > Please refer to the [docs](https://coolify.io/docs/installation) for more information about the installation. + +## Container roles and Flux + +The Coolify image can run different process roles with `COOLIFY_CONTAINER_ROLE`: + +- `all` (default): self-hosted mode; runs the web process, worker services, and Flux when configured. +- `web`: web/API process only; s6 worker services and Flux sleep. +- `worker`: Horizon, Laravel scheduler worker, and optional Nightwatch agent. +- `flux`: Flux only; used by Cloud/HA deployments that scale coold connection routers separately. + +Flux is installed from the coold nightly release into `/usr/local/bin/flux`. Containers running the `all` or `flux` role expose Flux on port `6443` and use these runtime variables: + +```env +COOLIFY_FLUX_GRPC_BIND=0.0.0.0:6443 +COOLIFY_FLUX_UNIX_SOCKET_PATH=/run/coolify/flux.sock +COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH=/var/www/html/storage/app/flux/jwt.priv +COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH=/var/www/html/storage/app/flux/jwt.pub +COOLIFY_FLUX_ALLOW_PUBLIC_BIND=1 +COOLIFY_FLUX_ID=flux-eu-1 +COOLIFY_FLUX_PUBLIC_URL=grpcs://flux-eu-1.example.com:6443 +COOLIFY_FLUX_INTERNAL_URL=http://coolify-flux-eu-1.internal:6443 +``` + +If `COOLIFY_FLUX_ENABLED=false` is set, the Flux s6 service sleeps even for `all` and `flux` roles. The Flux s6 service creates a persistent JWT keypair on first boot when the key files are missing. The current Coolify image only installs the nightly Flux artifact during the Docker build; the s6 service verifies the binary at runtime and sleeps with a clear error if the published artifact is not compatible with the Alpine base image. + ## Support Contact us at [coolify.io/docs/contact](https://coolify.io/docs/contact). diff --git a/app/Http/Controllers/V5/HomeController.php b/app/Http/Controllers/V5/HomeController.php new file mode 100644 index 000000000..b8f9fa6db --- /dev/null +++ b/app/Http/Controllers/V5/HomeController.php @@ -0,0 +1,44 @@ +user(); + $currentTeam = $request->attributes->get('v5.currentTeam'); + + return Inertia::render('Home', [ + 'status' => 'v5-ready', + 'flux' => $fluxHealth->check(), + 'currentTeam' => $currentTeam instanceof Team ? [ + 'id' => $currentTeam->id, + 'name' => $currentTeam->name, + 'description' => $currentTeam->description, + 'role' => $currentTeam->pivot?->role ?? $user->roleInTeam($currentTeam->id), + 'personal' => $currentTeam->personal_team, + ] : null, + 'teams' => $user->teams() + ->select('teams.id', 'teams.name', 'teams.description', 'teams.personal_team') + ->orderBy('teams.name') + ->get() + ->map(fn (Team $team) => [ + 'id' => $team->id, + 'name' => $team->name, + 'description' => $team->description, + 'role' => $team->pivot->role, + 'personal' => $team->personal_team, + ]), + ]); + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 02a49aaa8..dfd66284a 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -18,6 +18,8 @@ use App\Http\Middleware\RedirectIfAuthenticated; use App\Http\Middleware\TrimStrings; use App\Http\Middleware\TrustHosts; use App\Http\Middleware\TrustProxies; +use App\Http\Middleware\V5\EnsureCurrentTeam as V5EnsureCurrentTeam; +use App\Http\Middleware\V5\HandleInertiaRequests as V5HandleInertiaRequests; use App\Http\Middleware\ValidateSignature; use App\Http\Middleware\VerifyCsrfToken; use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; @@ -76,6 +78,22 @@ class Kernel extends HttpKernel ], + 'v5.web' => [ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + V5HandleInertiaRequests::class, + ], + + 'v5.authenticated' => [ + 'auth', + 'verified', + V5EnsureCurrentTeam::class, + ], + 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, ThrottleRequests::class.':api', diff --git a/app/Http/Middleware/V5/EnsureCurrentTeam.php b/app/Http/Middleware/V5/EnsureCurrentTeam.php new file mode 100644 index 000000000..f8aa78f92 --- /dev/null +++ b/app/Http/Middleware/V5/EnsureCurrentTeam.php @@ -0,0 +1,54 @@ +user(); + + if (! $user) { + return $next($request); + } + + $currentTeam = $this->resolveCurrentTeam($user); + + if (! $currentTeam) { + abort(403, 'No team available for this user.'); + } + + session(['currentTeam' => $currentTeam]); + $request->attributes->set('v5.currentTeam', $currentTeam); + + return $next($request); + } + + private function resolveCurrentTeam(User $user): ?Team + { + $sessionTeamId = data_get(session('currentTeam'), 'id'); + + if ($sessionTeamId) { + $sessionTeam = $user->teams() + ->select('teams.id', 'teams.name', 'teams.description', 'teams.personal_team') + ->whereKey($sessionTeamId) + ->first(); + + if ($sessionTeam) { + return $sessionTeam; + } + } + + return $user->teams() + ->select('teams.id', 'teams.name', 'teams.description', 'teams.personal_team') + ->orderBy('teams.id') + ->first(); + } +} diff --git a/app/Http/Middleware/V5/HandleInertiaRequests.php b/app/Http/Middleware/V5/HandleInertiaRequests.php new file mode 100644 index 000000000..2772c9c2e --- /dev/null +++ b/app/Http/Middleware/V5/HandleInertiaRequests.php @@ -0,0 +1,25 @@ + [ + 'user' => $request->user() ? [ + 'id' => $request->user()->id, + 'name' => $request->user()->name, + 'email' => $request->user()->email, + ] : null, + ], + ]; + } +} diff --git a/app/Models/V5/Project.php b/app/Models/V5/Project.php new file mode 100644 index 000000000..a04a381f9 --- /dev/null +++ b/app/Models/V5/Project.php @@ -0,0 +1,29 @@ +belongsTo(Team::class); + } + + public function creator(): BelongsTo + { + return $this->belongsTo(User::class, 'created_by_user_id'); + } +} diff --git a/app/Models/V5/V5Model.php b/app/Models/V5/V5Model.php new file mode 100644 index 000000000..9907e827d --- /dev/null +++ b/app/Models/V5/V5Model.php @@ -0,0 +1,10 @@ +group(base_path('routes/webhooks.php')); + Route::middleware('v5.web') + ->prefix('v5') + ->as('v5.') + ->group(base_path('routes/v5.php')); + Route::middleware('web') ->group(base_path('routes/web.php')); }); diff --git a/app/Services/Flux/FluxHealth.php b/app/Services/Flux/FluxHealth.php new file mode 100644 index 000000000..85d49d948 --- /dev/null +++ b/app/Services/Flux/FluxHealth.php @@ -0,0 +1,66 @@ +unavailable(null, 'Flux socket is not configured.'); + } + + if (! file_exists($socketPath)) { + return $this->unavailable($socketPath, 'Flux socket was not found.'); + } + + $timeout = (float) config('flux.health_timeout_seconds', 1.0); + $stream = @stream_socket_client("unix://{$socketPath}", $errorCode, $errorMessage, $timeout); + + if ($stream === false) { + return $this->unavailable($socketPath, $errorMessage ?: "Could not connect to Flux socket ({$errorCode})."); + } + + stream_set_timeout($stream, (int) ceil($timeout)); + + fwrite($stream, "GET /v1/health HTTP/1.1\r\nHost: flux\r\nAccept: application/json\r\nConnection: close\r\n\r\n"); + $response = stream_get_contents($stream) ?: ''; + fclose($stream); + + if (! str_starts_with($response, 'HTTP/1.1 200') && ! str_starts_with($response, 'HTTP/1.0 200')) { + return $this->unavailable($socketPath, 'Flux health endpoint did not return HTTP 200.'); + } + + $body = str_contains($response, "\r\n\r\n") ? substr($response, strpos($response, "\r\n\r\n") + 4) : ''; + $payload = json_decode($body, true); + + if (! is_array($payload) || ($payload['ok'] ?? false) !== true) { + return $this->unavailable($socketPath, 'Flux health endpoint returned an invalid response.'); + } + + return [ + 'available' => true, + 'label' => 'Running', + 'message' => 'Flux is running.', + 'socket' => $socketPath, + ]; + } + + /** + * @return array{available: false, label: string, message: string, socket: string|null} + */ + private function unavailable(?string $socketPath, string $message): array + { + return [ + 'available' => false, + 'label' => 'Unavailable', + 'message' => $message, + 'socket' => $socketPath, + ]; + } +} diff --git a/composer.json b/composer.json index 9415aa624..1d94dca00 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "danharrin/livewire-rate-limiting": "^2.1.0", "doctrine/dbal": "^4.4.1", "guzzlehttp/guzzle": "^7.10.0", + "inertiajs/inertia-laravel": "^3.1", "laravel/fortify": "^1.34.0", "laravel/framework": "^12.49.0", "laravel/horizon": "^5.43.0", diff --git a/composer.lock b/composer.lock index 7d958a9cc..ded6d4b6c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64b77285a7140ce68e83db2659e9a21d", + "content-hash": "d7e1f3eef5ae01d358f9482007814245", "packages": [ { "name": "aws/aws-crt-php", @@ -1643,6 +1643,79 @@ ], "time": "2025-08-22T14:27:06+00:00" }, + { + "name": "inertiajs/inertia-laravel", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/inertiajs/inertia-laravel.git", + "reference": "f588ce4a5beb25d166f4e372bac0c7f46a4f52ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/f588ce4a5beb25d166f4e372bac0c7f46a4f52ac", + "reference": "f588ce4a5beb25d166f4e372bac0c7f46a4f52ac", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^11.0|^12.0|^13.0", + "php": "^8.2.0", + "symfony/console": "^7.0|^8.0" + }, + "conflict": { + "laravel/boost": "<2.2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.2", + "larastan/larastan": "^3.0", + "laravel/pint": "^1.16", + "mockery/mockery": "^1.3.3", + "orchestra/testbench": "^9.2|^10.0|^11.0", + "phpunit/phpunit": "^11.5|^12.0", + "roave/security-advisories": "dev-master" + }, + "suggest": { + "ext-pcntl": "Recommended when running the Inertia SSR server via the `inertia:start-ssr` artisan command." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Inertia\\ServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "./helpers.php" + ], + "psr-4": { + "Inertia\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Reinink", + "email": "jonathan@reinink.ca", + "homepage": "https://reinink.ca" + } + ], + "description": "The Laravel adapter for Inertia.js.", + "keywords": [ + "inertia", + "laravel" + ], + "support": { + "issues": "https://github.com/inertiajs/inertia-laravel/issues", + "source": "https://github.com/inertiajs/inertia-laravel/tree/v3.1.0" + }, + "time": "2026-04-30T15:30:29+00:00" + }, { "name": "jean85/pretty-package-versions", "version": "2.1.1", @@ -8973,16 +9046,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9381209597ec66c25be154cbf2289076e64d1eab" + "reference": "bc354f47c62301e990b7874fa662326368508e2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9381209597ec66c25be154cbf2289076e64d1eab", - "reference": "9381209597ec66c25be154cbf2289076e64d1eab", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/bc354f47c62301e990b7874fa662326368508e2c", + "reference": "bc354f47c62301e990b7874fa662326368508e2c", "shasum": "" }, "require": { @@ -9031,7 +9104,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.8" + "source": "https://github.com/symfony/http-foundation/tree/v7.4.13" }, "funding": [ { @@ -9051,7 +9124,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-24T11:20:33+00:00" }, { "name": "symfony/http-kernel", @@ -10008,16 +10081,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" + "reference": "8339098cae28673c15cce00d80734af0453054e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", + "reference": "8339098cae28673c15cce00d80734af0453054e2", "shasum": "" }, "require": { @@ -10064,7 +10137,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" }, "funding": [ { @@ -10084,7 +10157,7 @@ "type": "tidelift" } ], - "time": "2026-04-10T17:25:58+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php84", @@ -10650,16 +10723,16 @@ }, { "name": "symfony/routing", - "version": "v7.4.12", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "3b04a5ec4887a8135a12ebf0f4cbc5b8fc8ee204" + "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/3b04a5ec4887a8135a12ebf0f4cbc5b8fc8ee204", - "reference": "3b04a5ec4887a8135a12ebf0f4cbc5b8fc8ee204", + "url": "https://api.github.com/repos/symfony/routing/zipball/3a162171bb008e5e0f15dce6581373a4c0e8390d", + "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d", "shasum": "" }, "require": { @@ -10711,7 +10784,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.4.12" + "source": "https://github.com/symfony/routing/tree/v7.4.13" }, "funding": [ { @@ -10731,7 +10804,7 @@ "type": "tidelift" } ], - "time": "2026-05-20T07:20:23+00:00" + "time": "2026-05-24T11:20:33+00:00" }, { "name": "symfony/serializer", diff --git a/config/flux.php b/config/flux.php new file mode 100644 index 000000000..e82914de0 --- /dev/null +++ b/config/flux.php @@ -0,0 +1,6 @@ + env('COOLIFY_FLUX_UNIX_SOCKET_PATH', '/run/coolify/flux.sock'), + 'health_timeout_seconds' => (float) env('COOLIFY_FLUX_HEALTH_TIMEOUT_SECONDS', 1.0), +]; diff --git a/database/migrations/2026_06_04_050157_create_v5_projects_table.php b/database/migrations/2026_06_04_050157_create_v5_projects_table.php new file mode 100644 index 000000000..8148c6cce --- /dev/null +++ b/database/migrations/2026_06_04_050157_create_v5_projects_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('team_id')->constrained('teams')->cascadeOnDelete(); + $table->foreignId('created_by_user_id')->constrained('users')->cascadeOnDelete(); + $table->string('name'); + $table->text('description')->nullable(); + $table->timestamps(); + + $table->index(['team_id', 'name']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('v5_projects'); + } +}; diff --git a/database/schema/testing-schema.sql b/database/schema/testing-schema.sql index edbc35db4..7555922ce 100644 --- a/database/schema/testing-schema.sql +++ b/database/schema/testing-schema.sql @@ -1321,6 +1321,16 @@ CREATE TABLE IF NOT EXISTS "users" ( "email_change_code_expires_at" TEXT ); +CREATE TABLE IF NOT EXISTS "v5_projects" ( + "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + "team_id" INTEGER NOT NULL, + "created_by_user_id" INTEGER NOT NULL, + "name" TEXT NOT NULL, + "description" TEXT, + "created_at" TEXT, + "updated_at" TEXT +); + CREATE TABLE IF NOT EXISTS "webhook_notification_settings" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "team_id" INTEGER NOT NULL, @@ -1752,3 +1762,4 @@ INSERT INTO "migrations" ("id", "migration", "batch") VALUES (311, '2025_12_10_1 INSERT INTO "migrations" ("id", "migration", "batch") VALUES (312, '2025_12_15_143052_trim_s3_storage_credentials', 312); INSERT INTO "migrations" ("id", "migration", "batch") VALUES (313, '2025_12_17_000001_add_is_wire_navigate_enabled_to_instance_settings_table', 313); INSERT INTO "migrations" ("id", "migration", "batch") VALUES (314, '2025_12_17_000002_add_restart_tracking_to_standalone_databases', 314); +INSERT INTO "migrations" ("id", "migration", "batch") VALUES (315, '2026_06_04_050157_create_v5_projects_table', 315); diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 9c93678af..bad72a22d 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -10,8 +10,10 @@ services: - GROUP_ID=${GROUPID:-1000} ports: - "${APP_PORT:-8000}:8080" + - "${FORWARD_FLUX_PORT:-6443}:6443" environment: AUTORUN_ENABLED: false + COOLIFY_CONTAINER_ROLE: "${COOLIFY_CONTAINER_ROLE:-all}" PUSHER_HOST: "${PUSHER_HOST}" PUSHER_PORT: "${PUSHER_PORT}" PUSHER_SCHEME: "${PUSHER_SCHEME:-http}" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 8907a30b9..fd4aabeef 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -11,6 +11,7 @@ services: - /data/coolify/databases:/var/www/html/storage/app/databases - /data/coolify/services:/var/www/html/storage/app/services - /data/coolify/backups:/var/www/html/storage/app/backups + - /data/coolify/flux:/var/www/html/storage/app/flux environment: - APP_ENV=${APP_ENV:-production} - PHP_MEMORY_LIMIT=${PHP_MEMORY_LIMIT:-256M} @@ -18,12 +19,15 @@ services: - PHP_FPM_PM_START_SERVERS=${PHP_FPM_PM_START_SERVERS:-1} - PHP_FPM_PM_MIN_SPARE_SERVERS=${PHP_FPM_PM_MIN_SPARE_SERVERS:-1} - PHP_FPM_PM_MAX_SPARE_SERVERS=${PHP_FPM_PM_MAX_SPARE_SERVERS:-10} + - COOLIFY_CONTAINER_ROLE=${COOLIFY_CONTAINER_ROLE:-all} env_file: - /data/coolify/source/.env ports: - "${APP_PORT:-8000}:8080" + - "${COOLIFY_FLUX_PORT:-6443}:6443" expose: - "${APP_PORT:-8000}" + - "${COOLIFY_FLUX_PORT:-6443}" healthcheck: test: curl --fail http://127.0.0.1:8080/api/health || exit 1 interval: 5s diff --git a/docker/development/Dockerfile b/docker/development/Dockerfile index 8fc46e32d..08450e817 100644 --- a/docker/development/Dockerfile +++ b/docker/development/Dockerfile @@ -5,6 +5,8 @@ ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine ARG MINIO_VERSION=RELEASE.2025-05-21T01-59-54Z # https://github.com/cloudflare/cloudflared/releases ARG CLOUDFLARED_VERSION=2025.7.0 +# https://github.com/coollabsio/coold/releases/tag/nightly +ARG COOLIFY_FLUX_VERSION=nightly # https://www.postgresql.org/support/versioning/ # Note: We are using version 18 of the postgres client (while still using postgres 15 for the postgres server) as version 15 has been removed from Alpine 3.23+ https://pkgs.alpinelinux.org/packages?name=postgresql*-client&branch=v3.23&repo=&arch=x86_64&origin=&flagged=&maintainer= ARG POSTGRES_VERSION=18 @@ -24,8 +26,10 @@ FROM serversideup/php:${SERVERSIDEUP_PHP_VERSION} ARG USER_ID ARG GROUP_ID ARG TARGETPLATFORM +ARG TARGETARCH ARG POSTGRES_VERSION ARG CLOUDFLARED_VERSION +ARG COOLIFY_FLUX_VERSION ARG NGINX_VERSION WORKDIR /var/www/html @@ -58,6 +62,7 @@ RUN apk upgrade --no-cache && \ RUN apk add --no-cache \ postgresql${POSTGRES_VERSION}-client \ openssh-client \ + openssl \ git \ git-lfs \ jq \ @@ -81,6 +86,28 @@ RUN mkdir -p /usr/local/bin && \ fi && \ chmod +x /usr/local/bin/cloudflared +# Install Flux from coold nightly release based on architecture +RUN set -eux; \ + mkdir -p /usr/local/bin /run/coolify /etc/coolify; \ + chown -R www-data:www-data /run/coolify /etc/coolify; \ + case "${TARGETARCH:-}" in \ + amd64|arm64) FLUX_ARCH="${TARGETARCH}" ;; \ + "") \ + case "$(uname -m)" in \ + x86_64) FLUX_ARCH="amd64" ;; \ + aarch64) FLUX_ARCH="arm64" ;; \ + *) echo "unsupported Flux arch: $(uname -m)" >&2; exit 1 ;; \ + esac ;; \ + *) echo "unsupported Flux TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \ + esac; \ + curl -fsSL --retry 3 --max-time 120 \ + -o /tmp/flux.tar.gz \ + "https://github.com/coollabsio/coold/releases/download/${COOLIFY_FLUX_VERSION}/flux-linux-musl-${FLUX_ARCH}.tar.gz"; \ + tar -xzf /tmp/flux.tar.gz -C /tmp; \ + test -f /tmp/flux; \ + install -m 0755 /tmp/flux /usr/local/bin/flux; \ + rm -f /tmp/flux /tmp/flux.tar.gz + # Configure PHP COPY docker/development/etc/php/conf.d/zzz-custom-php.ini /usr/local/etc/php/conf.d/zzz-custom-php.ini ENV PHP_OPCACHE_ENABLE=0 diff --git a/docker/development/etc/s6-overlay/s6-rc.d/flux/dependencies.d/init-setup b/docker/development/etc/s6-overlay/s6-rc.d/flux/dependencies.d/init-setup new file mode 100644 index 000000000..e69de29bb diff --git a/docker/development/etc/s6-overlay/s6-rc.d/flux/run b/docker/development/etc/s6-overlay/s6-rc.d/flux/run new file mode 100755 index 000000000..95f648f8e --- /dev/null +++ b/docker/development/etc/s6-overlay/s6-rc.d/flux/run @@ -0,0 +1,49 @@ +#!/bin/sh + +cd /var/www/html + +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|flux) ;; + *) + echo " INFO Flux is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + +if grep -qE '^COOLIFY_FLUX_ENABLED=false' .env 2>/dev/null || [ "${COOLIFY_FLUX_ENABLED:-}" = "false" ]; then + echo " INFO Flux is disabled, sleeping." + exec sleep infinity +fi + +export COOLIFY_FLUX_GRPC_BIND="${COOLIFY_FLUX_GRPC_BIND:-0.0.0.0:6443}" +export COOLIFY_FLUX_UNIX_SOCKET_PATH="${COOLIFY_FLUX_UNIX_SOCKET_PATH:-/run/coolify/flux.sock}" +export COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH="${COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH:-/var/www/html/storage/app/flux/jwt.priv}" +export COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH="${COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH:-/var/www/html/storage/app/flux/jwt.pub}" +export COOLIFY_FLUX_ALLOW_PUBLIC_BIND="${COOLIFY_FLUX_ALLOW_PUBLIC_BIND:-1}" + +if [ ! -r "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH" ]; then + echo " INFO Flux JWT public key not found at $COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH, generating keypair..." + mkdir -p "$(dirname "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH")" "$(dirname "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH")" + openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH.tmp" + chmod 0600 "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH.tmp" + mv "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH.tmp" "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH" + openssl pkey -in "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH" -pubout -out "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH.tmp" + chmod 0644 "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH.tmp" + mv "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH.tmp" "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH" +fi + +if ! /usr/local/bin/flux --version >/dev/null 2>&1; then + echo " ERROR Flux binary cannot run in this container. Check that the installed coold nightly Flux artifact is compatible with Alpine." + exec sleep infinity +fi + +mkdir -p "$(dirname "$COOLIFY_FLUX_UNIX_SOCKET_PATH")" + +echo " INFO Flux is enabled for role '$role', starting..." +exec /usr/local/bin/flux diff --git a/docker/development/etc/s6-overlay/s6-rc.d/flux/type b/docker/development/etc/s6-overlay/s6-rc.d/flux/type new file mode 100644 index 000000000..1780f9f44 --- /dev/null +++ b/docker/development/etc/s6-overlay/s6-rc.d/flux/type @@ -0,0 +1 @@ +longrun \ No newline at end of file diff --git a/docker/development/etc/s6-overlay/s6-rc.d/horizon/run b/docker/development/etc/s6-overlay/s6-rc.d/horizon/run index dbc472d06..9a8d96d2a 100644 --- a/docker/development/etc/s6-overlay/s6-rc.d/horizon/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/horizon/run @@ -2,6 +2,20 @@ cd /var/www/html +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|worker) ;; + *) + echo " INFO Horizon is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + if grep -qE '^HORIZON_ENABLED=false' .env 2>/dev/null; then echo " INFO Horizon is disabled, sleeping." exec sleep infinity diff --git a/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run b/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run index ee46dba7e..7242b3f79 100644 --- a/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run @@ -2,6 +2,20 @@ cd /var/www/html +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|worker) ;; + *) + echo " INFO Nightwatch is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + if grep -qE '^NIGHTWATCH_ENABLED=true' .env 2>/dev/null; then echo " INFO Nightwatch is enabled, starting..." exec php artisan nightwatch:agent diff --git a/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run b/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run index bfa44c7e3..0dbc2e716 100644 --- a/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run @@ -2,6 +2,20 @@ cd /var/www/html +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|worker) ;; + *) + echo " INFO Scheduler worker is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + if grep -qE '^SCHEDULER_ENABLED=false' .env 2>/dev/null; then echo " INFO Scheduler is disabled, sleeping." exec sleep infinity diff --git a/docker/development/etc/s6-overlay/s6-rc.d/user/contents.d/flux b/docker/development/etc/s6-overlay/s6-rc.d/user/contents.d/flux new file mode 100644 index 000000000..e69de29bb diff --git a/docker/production/Dockerfile b/docker/production/Dockerfile index 0f849785e..b6dd5fac0 100644 --- a/docker/production/Dockerfile +++ b/docker/production/Dockerfile @@ -5,6 +5,8 @@ ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine ARG MINIO_VERSION=RELEASE.2025-05-21T01-59-54Z # https://github.com/cloudflare/cloudflared/releases ARG CLOUDFLARED_VERSION=2025.7.0 +# https://github.com/coollabsio/coold/releases/tag/nightly +ARG COOLIFY_FLUX_VERSION=nightly # https://www.postgresql.org/support/versioning/ # Note: We are using version 18 of the postgres client (while still using postgres 15 for the postgres server) as version 15 has been removed from Alpine 3.23+ https://pkgs.alpinelinux.org/packages?name=postgresql*-client&branch=v3.23&repo=&arch=x86_64&origin=&flagged=&maintainer= ARG POSTGRES_VERSION=18 @@ -73,8 +75,10 @@ FROM serversideup/php:${SERVERSIDEUP_PHP_VERSION} ARG USER_ID ARG GROUP_ID ARG TARGETPLATFORM +ARG TARGETARCH ARG POSTGRES_VERSION ARG CLOUDFLARED_VERSION +ARG COOLIFY_FLUX_VERSION ARG NGINX_VERSION ARG CI=true @@ -108,6 +112,7 @@ RUN --mount=type=cache,target=/var/cache/apk \ apk add --no-cache \ postgresql${POSTGRES_VERSION}-client \ openssh-client \ + openssl \ git \ git-lfs \ jq \ @@ -128,6 +133,28 @@ RUN mkdir -p /usr/local/bin && \ fi && \ chmod +x /usr/local/bin/cloudflared +# Install Flux from coold nightly release based on architecture +RUN set -eux; \ + mkdir -p /usr/local/bin /run/coolify /etc/coolify; \ + chown -R www-data:www-data /run/coolify /etc/coolify; \ + case "${TARGETARCH:-}" in \ + amd64|arm64) FLUX_ARCH="${TARGETARCH}" ;; \ + "") \ + case "$(uname -m)" in \ + x86_64) FLUX_ARCH="amd64" ;; \ + aarch64) FLUX_ARCH="arm64" ;; \ + *) echo "unsupported Flux arch: $(uname -m)" >&2; exit 1 ;; \ + esac ;; \ + *) echo "unsupported Flux TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \ + esac; \ + curl -fsSL --retry 3 --max-time 120 \ + -o /tmp/flux.tar.gz \ + "https://github.com/coollabsio/coold/releases/download/${COOLIFY_FLUX_VERSION}/flux-linux-musl-${FLUX_ARCH}.tar.gz"; \ + tar -xzf /tmp/flux.tar.gz -C /tmp; \ + test -f /tmp/flux; \ + install -m 0755 /tmp/flux /usr/local/bin/flux; \ + rm -f /tmp/flux /tmp/flux.tar.gz + # Configure PHP COPY docker/production/etc/php/conf.d/zzz-custom-php.ini /usr/local/etc/php/conf.d/zzz-custom-php.ini ENV PHP_OPCACHE_ENABLE=1 diff --git a/docker/production/etc/s6-overlay/s6-rc.d/flux/dependencies.d/init-script b/docker/production/etc/s6-overlay/s6-rc.d/flux/dependencies.d/init-script new file mode 100644 index 000000000..e69de29bb diff --git a/docker/production/etc/s6-overlay/s6-rc.d/flux/run b/docker/production/etc/s6-overlay/s6-rc.d/flux/run new file mode 100755 index 000000000..95f648f8e --- /dev/null +++ b/docker/production/etc/s6-overlay/s6-rc.d/flux/run @@ -0,0 +1,49 @@ +#!/bin/sh + +cd /var/www/html + +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|flux) ;; + *) + echo " INFO Flux is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + +if grep -qE '^COOLIFY_FLUX_ENABLED=false' .env 2>/dev/null || [ "${COOLIFY_FLUX_ENABLED:-}" = "false" ]; then + echo " INFO Flux is disabled, sleeping." + exec sleep infinity +fi + +export COOLIFY_FLUX_GRPC_BIND="${COOLIFY_FLUX_GRPC_BIND:-0.0.0.0:6443}" +export COOLIFY_FLUX_UNIX_SOCKET_PATH="${COOLIFY_FLUX_UNIX_SOCKET_PATH:-/run/coolify/flux.sock}" +export COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH="${COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH:-/var/www/html/storage/app/flux/jwt.priv}" +export COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH="${COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH:-/var/www/html/storage/app/flux/jwt.pub}" +export COOLIFY_FLUX_ALLOW_PUBLIC_BIND="${COOLIFY_FLUX_ALLOW_PUBLIC_BIND:-1}" + +if [ ! -r "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH" ]; then + echo " INFO Flux JWT public key not found at $COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH, generating keypair..." + mkdir -p "$(dirname "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH")" "$(dirname "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH")" + openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH.tmp" + chmod 0600 "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH.tmp" + mv "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH.tmp" "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH" + openssl pkey -in "$COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH" -pubout -out "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH.tmp" + chmod 0644 "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH.tmp" + mv "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH.tmp" "$COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH" +fi + +if ! /usr/local/bin/flux --version >/dev/null 2>&1; then + echo " ERROR Flux binary cannot run in this container. Check that the installed coold nightly Flux artifact is compatible with Alpine." + exec sleep infinity +fi + +mkdir -p "$(dirname "$COOLIFY_FLUX_UNIX_SOCKET_PATH")" + +echo " INFO Flux is enabled for role '$role', starting..." +exec /usr/local/bin/flux diff --git a/docker/production/etc/s6-overlay/s6-rc.d/flux/type b/docker/production/etc/s6-overlay/s6-rc.d/flux/type new file mode 100644 index 000000000..1780f9f44 --- /dev/null +++ b/docker/production/etc/s6-overlay/s6-rc.d/flux/type @@ -0,0 +1 @@ +longrun \ No newline at end of file diff --git a/docker/production/etc/s6-overlay/s6-rc.d/horizon/run b/docker/production/etc/s6-overlay/s6-rc.d/horizon/run index dbc472d06..9a8d96d2a 100644 --- a/docker/production/etc/s6-overlay/s6-rc.d/horizon/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/horizon/run @@ -2,6 +2,20 @@ cd /var/www/html +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|worker) ;; + *) + echo " INFO Horizon is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + if grep -qE '^HORIZON_ENABLED=false' .env 2>/dev/null; then echo " INFO Horizon is disabled, sleeping." exec sleep infinity diff --git a/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run b/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run index ee46dba7e..7242b3f79 100644 --- a/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run @@ -2,6 +2,20 @@ cd /var/www/html +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|worker) ;; + *) + echo " INFO Nightwatch is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + if grep -qE '^NIGHTWATCH_ENABLED=true' .env 2>/dev/null; then echo " INFO Nightwatch is enabled, starting..." exec php artisan nightwatch:agent diff --git a/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run b/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run index bfa44c7e3..0dbc2e716 100644 --- a/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run @@ -2,6 +2,20 @@ cd /var/www/html +role="${COOLIFY_CONTAINER_ROLE:-}" +if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" +fi +role="${role:-all}" + +case "$role" in + all|worker) ;; + *) + echo " INFO Scheduler worker is disabled for role '$role', sleeping." + exec sleep infinity + ;; +esac + if grep -qE '^SCHEDULER_ENABLED=false' .env 2>/dev/null; then echo " INFO Scheduler is disabled, sleeping." exec sleep infinity diff --git a/docker/production/etc/s6-overlay/s6-rc.d/user/contents.d/flux b/docker/production/etc/s6-overlay/s6-rc.d/user/contents.d/flux new file mode 100644 index 000000000..e69de29bb diff --git a/package-lock.json b/package-lock.json index 9d495c412..288474a88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,14 +6,19 @@ "": { "name": "coolify", "dependencies": { + "@inertiajs/react": "^3.3.0", + "@inertiajs/vite": "^3.3.0", "@tailwindcss/forms": "0.5.10", "@tailwindcss/typography": "0.5.16", "@xterm/addon-fit": "0.10.0", "@xterm/xterm": "5.5.0", - "playwright": "^1.58.2" + "playwright": "^1.58.2", + "react": "^19.2.7", + "react-dom": "^19.2.7" }, "devDependencies": { "@tailwindcss/postcss": "4.1.18", + "@vitejs/plugin-react": "^5.2.0", "laravel-vite-plugin": "2.0.1", "postcss": "8.5.15", "tailwind-scrollbar": "4.0.2", @@ -34,6 +39,289 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -41,7 +329,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -58,7 +345,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -75,7 +361,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -92,7 +377,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -109,7 +393,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -126,7 +409,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -143,7 +425,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -160,7 +441,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -177,7 +457,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -194,7 +473,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -211,7 +489,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -228,7 +505,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -245,7 +521,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -262,7 +537,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -279,7 +553,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -296,7 +569,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -313,7 +585,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -330,7 +601,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -347,7 +617,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -364,7 +633,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -381,7 +649,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -398,7 +665,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -415,7 +681,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -432,7 +697,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -449,7 +713,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -466,7 +729,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -476,6 +738,53 @@ "node": ">=18" } }, + "node_modules/@inertiajs/core": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-3.3.0.tgz", + "integrity": "sha512-6tEe5vtjwXJj68h0nkz84WkeZ8XA0phJ8ep1l/V+im62KTzlZTw9sxlmf8uNKu4seleXVw+idw48svxUCWla/Q==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "es-toolkit": "^1.33.0", + "laravel-precognition": "^2.0.0" + }, + "peerDependencies": { + "axios": "^1.15.2" + }, + "peerDependenciesMeta": { + "axios": { + "optional": true + } + } + }, + "node_modules/@inertiajs/react": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@inertiajs/react/-/react-3.3.0.tgz", + "integrity": "sha512-8Es6i1FOyP5sHWjLlE3yFi+dOuJp3IBkl1ccoxb101Jr4/vTcNsdXvpl+U8IZmvnmyDS4dikeAa29p7xFUwgyQ==", + "license": "MIT", + "dependencies": { + "@inertiajs/core": "3.3.0", + "es-toolkit": "^1.33.0", + "laravel-precognition": "^2.0.0" + }, + "peerDependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/@inertiajs/vite": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@inertiajs/vite/-/vite-3.3.0.tgz", + "integrity": "sha512-UWm+I5OpxGnm1LBjgaPOI6/M8gurloxXRnzeNMd2UC6f6ObQo6RZvyLMMWInwS0fBief7lfkpj5sPZy+680CRA==", + "license": "MIT", + "dependencies": { + "@inertiajs/core": "3.3.0", + "tinyglobby": "^0.2.15" + }, + "peerDependencies": { + "vite": "^7.0.0 || ^8.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -502,7 +811,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -512,20 +820,25 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", @@ -533,7 +846,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -547,7 +859,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -561,7 +872,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -575,7 +885,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -589,7 +898,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -603,7 +911,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -617,7 +924,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -631,7 +937,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -645,7 +950,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -659,7 +963,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -673,7 +976,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -687,7 +989,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -701,7 +1002,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -715,7 +1015,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -729,7 +1028,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -743,7 +1041,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -757,7 +1054,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -771,7 +1067,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -785,7 +1080,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -799,7 +1093,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -813,7 +1106,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -827,7 +1119,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -841,7 +1132,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -855,7 +1145,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -869,7 +1158,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1234,11 +1522,55 @@ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/prismjs": { @@ -1248,6 +1580,27 @@ "dev": true, "license": "MIT" }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/@xterm/addon-fit": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz", @@ -1261,7 +1614,77 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT" + "license": "MIT", + "peer": true + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.33", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz", + "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, "node_modules/clsx": { "version": "2.1.1", @@ -1273,6 +1696,13 @@ "node": ">=6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1285,16 +1715,41 @@ "node": ">=4" } }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" } }, + "node_modules/electron-to-chromium": { + "version": "1.5.366", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.366.tgz", + "integrity": "sha512-OlRuhb688YTCzzU3gXPLn6nGyd+F+53INE1qaKKlu6kETErE8FYsyDh0XqXEU+uBRn0MpCzz2vfNwORhkap8qg==", + "dev": true, + "license": "ISC" + }, "node_modules/enhanced-resolve": { "version": "5.19.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", @@ -1309,11 +1764,20 @@ "node": ">=10.13.0" } }, + "node_modules/es-toolkit": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.0.tgz", + "integrity": "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -1351,11 +1815,20 @@ "@esbuild/win32-x64": "0.27.2" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -1373,7 +1846,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -1384,6 +1856,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1395,12 +1877,62 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/laravel-precognition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/laravel-precognition/-/laravel-precognition-2.0.0.tgz", + "integrity": "sha512-dmA4HGc9m+TsVNsJs9/XQBI8u6j7coilN+qKkBuhuXQzH3HypwS/c5dFQ4UqUGjBbcxIM7zdk91kM/SRZwIvWQ==", + "license": "MIT", + "dependencies": { + "es-toolkit": "^1.32.0" + }, + "peerDependencies": { + "axios": "^1.4.0" + }, + "peerDependenciesMeta": { + "axios": { + "optional": true + } + } + }, "node_modules/laravel-vite-plugin": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-2.0.1.tgz", @@ -1425,7 +1957,7 @@ "version": "1.30.2", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", - "dev": true, + "devOptional": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -1458,7 +1990,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1479,7 +2010,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1500,7 +2030,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1521,7 +2050,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1542,7 +2070,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1563,7 +2090,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1584,7 +2110,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1605,7 +2130,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1626,7 +2150,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1647,7 +2170,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1668,7 +2190,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -1700,6 +2221,16 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -1719,11 +2250,17 @@ "mini-svg-data-uri": "cli.js" } }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", - "dev": true, "funding": [ { "type": "github", @@ -1738,19 +2275,28 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -1806,7 +2352,6 @@ "version": "8.5.15", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, "funding": [ { "type": "opencollective", @@ -1859,21 +2404,42 @@ } }, "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", - "dev": true, + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", "peer": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/rollup": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -1914,11 +2480,26 @@ "fsevents": "~2.3.2" } }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -1944,7 +2525,8 @@ "version": "4.1.18", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.3.0", @@ -1964,7 +2546,6 @@ "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -1977,6 +2558,37 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1987,8 +2599,8 @@ "version": "7.3.2", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", - "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -2081,6 +2693,13 @@ "funding": { "url": "https://github.com/sponsors/jonschlinkert" } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" } } } diff --git a/package.json b/package.json index c3fb1bc5f..43c4c738a 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "4.1.18", + "@vitejs/plugin-react": "^5.2.0", "laravel-vite-plugin": "2.0.1", "postcss": "8.5.15", "tailwind-scrollbar": "4.0.2", @@ -15,10 +16,14 @@ "vite": "7.3.2" }, "dependencies": { + "@inertiajs/react": "^3.3.0", + "@inertiajs/vite": "^3.3.0", "@tailwindcss/forms": "0.5.10", "@tailwindcss/typography": "0.5.16", "@xterm/addon-fit": "0.10.0", "@xterm/xterm": "5.5.0", - "playwright": "^1.58.2" + "playwright": "^1.58.2", + "react": "^19.2.7", + "react-dom": "^19.2.7" } } diff --git a/resources/css/v5/app.css b/resources/css/v5/app.css new file mode 100644 index 000000000..a363687ee --- /dev/null +++ b/resources/css/v5/app.css @@ -0,0 +1,11 @@ +@font-face { + font-display: swap; + font-family: 'Geist Sans'; + font-style: normal; + font-weight: 100 900; + src: url('../../fonts/geist-sans-variable.woff2') format('woff2'); +} + +body { + font-family: 'Geist Sans', sans-serif; +} diff --git a/resources/js/v5/Pages/Home.jsx b/resources/js/v5/Pages/Home.jsx new file mode 100644 index 000000000..0fa9a231b --- /dev/null +++ b/resources/js/v5/Pages/Home.jsx @@ -0,0 +1,59 @@ +import { Head } from '@inertiajs/react'; + +export default function Home({ status, currentTeam, teams, flux }) { + return ( + <> + + +
+

{status}

+ +

Coolify v5

+ +

+ This page is served from Laravel through Inertia and React, with routes, + assets, and future v5 tables isolated from the current v4 Livewire app. +

+ +
+

Flux status

+ +

+ {flux.label} +

+ +

{flux.message}

+ + {flux.socket ?

Socket: {flux.socket}

: null} +
+ +

Current team

+ + {currentTeam ? ( +
+
Name
+
{currentTeam.name}
+ +
Description
+
{currentTeam.description || 'No description'}
+ +
Your role
+
{currentTeam.role}
+
+ ) : ( +

No team selected.

+ )} + +

Your teams

+ + +
+ + ); +} diff --git a/resources/js/v5/app.jsx b/resources/js/v5/app.jsx new file mode 100644 index 000000000..fa391dab8 --- /dev/null +++ b/resources/js/v5/app.jsx @@ -0,0 +1,11 @@ +import { createInertiaApp } from '@inertiajs/react'; +import '../../css/v5/app.css'; + +createInertiaApp({ + id: 'v5-app', + pages: { + path: './Pages', + extension: '.jsx', + }, + strictMode: true, +}); diff --git a/resources/views/v5/app.blade.php b/resources/views/v5/app.blade.php new file mode 100644 index 000000000..7f1a5fd70 --- /dev/null +++ b/resources/views/v5/app.blade.php @@ -0,0 +1,18 @@ + + + + + + + + {{ config('app.name') }} v5 + @viteReactRefresh + @vite('resources/js/v5/app.jsx') + + + + + + + + diff --git a/routes/v5.php b/routes/v5.php new file mode 100644 index 000000000..16525bf73 --- /dev/null +++ b/routes/v5.php @@ -0,0 +1,8 @@ +group(function () { + Route::get('/', HomeController::class)->name('home'); +}); diff --git a/tests/Feature/V5/HomeTest.php b/tests/Feature/V5/HomeTest.php new file mode 100644 index 000000000..c37b47496 --- /dev/null +++ b/tests/Feature/V5/HomeTest.php @@ -0,0 +1,214 @@ +toBeTrue(); +}); + +it('uses separated v5 middleware groups', function () { + $kernel = app(Kernel::class); + $reflection = new ReflectionClass($kernel); + $property = $reflection->getProperty('middlewareGroups'); + $property->setAccessible(true); + $groups = $property->getValue($kernel); + + expect($groups)->toHaveKey('v5.web') + ->and($groups)->toHaveKey('v5.authenticated') + ->and($groups['v5.web'])->toContain(HandleInertiaRequests::class) + ->and($groups['v5.web'])->not->toContain(CheckForcePasswordReset::class) + ->and($groups['v5.web'])->not->toContain(DecideWhatToDoWithUser::class) + ->and($groups['v5.authenticated'])->toContain('auth') + ->and($groups['v5.authenticated'])->toContain('verified') + ->and($groups['v5.authenticated'])->toContain(EnsureCurrentTeam::class); +}); + +it('creates v5 project tables in the shared database', function () { + createSharedUserAndTeamTables(); + + $migration = include database_path('migrations/2026_06_04_050157_create_v5_projects_table.php'); + $migration->up(); + + expect(Schema::hasTable('v5_projects'))->toBeTrue() + ->and(Schema::hasColumns('v5_projects', [ + 'id', + 'team_id', + 'created_by_user_id', + 'name', + 'description', + 'created_at', + 'updated_at', + ]))->toBeTrue(); +}); + +it('includes v5 project tables in the dev testing schema', function () { + $schema = file_get_contents(database_path('schema/testing-schema.sql')); + + expect($schema)->toContain('CREATE TABLE IF NOT EXISTS "v5_projects"') + ->and($schema)->toContain('"team_id" INTEGER NOT NULL') + ->and($schema)->toContain('"created_by_user_id" INTEGER NOT NULL') + ->and($schema)->toContain('2026_06_04_050157_create_v5_projects_table'); +}); + +it('redirects guests to the shared login', function () { + $this->get('/v5') + ->assertRedirect('/login'); +}); + +it('serves the v5 inertia shell', function () { + $this->withoutVite(); + fakeFluxHealth(); + createSharedUserAndTeamTables(); + + $user = User::withoutEvents(fn () => User::query()->create([ + 'name' => 'Ada Lovelace', + 'email' => 'ada@example.com', + 'email_verified_at' => now(), + 'password' => 'password', + ])); + $team = Team::withoutEvents(fn () => Team::query()->create([ + 'name' => 'V5 Shared Team', + 'description' => 'Shared team details', + 'personal_team' => true, + 'show_boarding' => false, + ])); + $user->teams()->attach($team, ['role' => 'owner']); + + $this + ->actingAs($user) + ->withSession(['currentTeam' => $team]) + ->get('/v5') + ->assertSuccessful() + ->assertSee('v5-app', false) + ->assertSee('Home', false) + ->assertSee('v5-ready', false) + ->assertSee('Running') + ->assertSee('Flux is running.') + ->assertSee('V5 Shared Team') + ->assertSee('Shared team details') + ->assertSee('owner') + ->assertSee($user->email); +}); + +it('selects a shared team when the session has no current team', function () { + $this->withoutVite(); + fakeFluxHealth(); + createSharedUserAndTeamTables(); + + $user = User::withoutEvents(fn () => User::query()->create([ + 'name' => 'Grace Hopper', + 'email' => 'grace@example.com', + 'email_verified_at' => now(), + 'password' => 'password', + ])); + $team = Team::withoutEvents(fn () => Team::query()->create([ + 'name' => 'Auto Selected Team', + 'description' => null, + 'personal_team' => false, + 'show_boarding' => false, + ])); + $user->teams()->attach($team, ['role' => 'admin']); + + $this + ->actingAs($user) + ->get('/v5') + ->assertSuccessful() + ->assertSessionHas('currentTeam') + ->assertSee('Auto Selected Team') + ->assertSee('admin'); +}); + +it('shows when flux is unavailable', function () { + $this->withoutVite(); + fakeFluxHealth(false, 'Flux socket was not found.'); + createSharedUserAndTeamTables(); + + $user = User::withoutEvents(fn () => User::query()->create([ + 'name' => 'Katherine Johnson', + 'email' => 'katherine@example.com', + 'email_verified_at' => now(), + 'password' => 'password', + ])); + $team = Team::withoutEvents(fn () => Team::query()->create([ + 'name' => 'Flux Test Team', + 'description' => null, + 'personal_team' => false, + 'show_boarding' => false, + ])); + $user->teams()->attach($team, ['role' => 'owner']); + + $this + ->actingAs($user) + ->withSession(['currentTeam' => $team]) + ->get('/v5') + ->assertSuccessful() + ->assertSee('Unavailable') + ->assertSee('Flux socket was not found.'); +}); + +function fakeFluxHealth(bool $available = true, string $message = 'Flux is running.'): void +{ + app()->instance(FluxHealth::class, Mockery::mock(FluxHealth::class, function (MockInterface $mock) use ($available, $message) { + $mock->shouldReceive('check') + ->once() + ->andReturn([ + 'available' => $available, + 'label' => $available ? 'Running' : 'Unavailable', + 'message' => $message, + 'socket' => '/run/coolify/flux.sock', + ]); + })); +} + +function createSharedUserAndTeamTables(): void +{ + Schema::create('users', function ($table) { + $table->id(); + $table->string('name')->default('Anonymous'); + $table->string('email'); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password')->nullable(); + $table->rememberToken(); + $table->timestamps(); + }); + + Schema::create('teams', function ($table) { + $table->id(); + $table->string('name'); + $table->string('description')->nullable(); + $table->boolean('personal_team')->default(false); + $table->boolean('show_boarding')->default(false); + $table->timestamps(); + }); + + Schema::create('team_user', function ($table) { + $table->id(); + $table->foreignId('team_id'); + $table->foreignId('user_id'); + $table->string('role')->default('member'); + $table->timestamps(); + + $table->unique(['team_id', 'user_id']); + }); +} diff --git a/vite.config.js b/vite.config.js index 36069fb28..3c36862f8 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,5 +1,7 @@ import { defineConfig, loadEnv } from "vite"; import laravel from "laravel-vite-plugin"; +import react from "@vitejs/plugin-react"; +import inertia from "@inertiajs/vite"; export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), '') @@ -32,9 +34,15 @@ export default defineConfig(({ mode }) => { }, plugins: [ laravel({ - input: ["resources/css/app.css", "resources/js/app.js"], + input: [ + "resources/css/app.css", + "resources/js/app.js", + "resources/js/v5/app.jsx", + ], refresh: true, }), + inertia({ ssr: false }), + react(), ], } }); From 762daf83a1af9766608cd9a43078c104659b4795 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:36:47 +0200 Subject: [PATCH 002/178] feat(container): support comma-separated roles Allow s6 services to start for specific roles like horizon, scheduler, nightwatch, and flux while keeping all as the default. --- .env.development.example | 1 + README.md | 9 +++- .../etc/s6-overlay/s6-rc.d/flux/run | 18 +++---- .../etc/s6-overlay/s6-rc.d/horizon/run | 18 +++---- .../s6-overlay/s6-rc.d/nightwatch-agent/run | 18 +++---- .../s6-overlay/s6-rc.d/scheduler-worker/run | 18 +++---- .../etc/s6-overlay/scripts/container-role | 26 +++++++++ .../etc/s6-overlay/s6-rc.d/flux/run | 18 +++---- .../etc/s6-overlay/s6-rc.d/horizon/run | 18 +++---- .../s6-overlay/s6-rc.d/nightwatch-agent/run | 18 +++---- .../s6-overlay/s6-rc.d/scheduler-worker/run | 18 +++---- .../etc/s6-overlay/scripts/container-role | 26 +++++++++ package-lock.json | 12 +---- tests/Feature/ContainerRoleScriptTest.php | 53 +++++++++++++++++++ 14 files changed, 163 insertions(+), 108 deletions(-) create mode 100755 docker/development/etc/s6-overlay/scripts/container-role create mode 100755 docker/production/etc/s6-overlay/scripts/container-role create mode 100644 tests/Feature/ContainerRoleScriptTest.php diff --git a/.env.development.example b/.env.development.example index d02b8ba59..887f62974 100644 --- a/.env.development.example +++ b/.env.development.example @@ -7,6 +7,7 @@ APP_URL=http://localhost APP_PORT=8000 APP_DEBUG=true SSH_MUX_ENABLED=true +COOLIFY_CONTAINER_ROLE=all # PostgreSQL Database Configuration DB_DATABASE=coolify diff --git a/README.md b/README.md index f4e289bcd..378e75ac7 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,18 @@ You can find the installation script source [here](./scripts/install.sh). ## Container roles and Flux -The Coolify image can run different process roles with `COOLIFY_CONTAINER_ROLE`: +The Coolify image can run different process roles with `COOLIFY_CONTAINER_ROLE`. The value can be a single role or a comma-separated list. If `all` is present anywhere in the list, every role starts. - `all` (default): self-hosted mode; runs the web process, worker services, and Flux when configured. -- `web`: web/API process only; s6 worker services and Flux sleep. +- `web`: web/API process only; s6 worker services and Flux sleep unless they are also listed. - `worker`: Horizon, Laravel scheduler worker, and optional Nightwatch agent. +- `horizon`: Horizon only. +- `scheduler` or `scheduler-worker`: Laravel scheduler worker only. +- `nightwatch` or `nightwatch-agent`: optional Nightwatch agent only. - `flux`: Flux only; used by Cloud/HA deployments that scale coold connection routers separately. +For example, `COOLIFY_CONTAINER_ROLE=web,flux` starts the web container plus Flux, while `COOLIFY_CONTAINER_ROLE=web,all` still starts all services. + Flux is installed from the coold nightly release into `/usr/local/bin/flux`. Containers running the `all` or `flux` role expose Flux on port `6443` and use these runtime variables: ```env diff --git a/docker/development/etc/s6-overlay/s6-rc.d/flux/run b/docker/development/etc/s6-overlay/s6-rc.d/flux/run index 95f648f8e..d99bdaac4 100755 --- a/docker/development/etc/s6-overlay/s6-rc.d/flux/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/flux/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|flux) ;; - *) - echo " INFO Flux is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role flux; then + echo " INFO Flux is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^COOLIFY_FLUX_ENABLED=false' .env 2>/dev/null || [ "${COOLIFY_FLUX_ENABLED:-}" = "false" ]; then echo " INFO Flux is disabled, sleeping." diff --git a/docker/development/etc/s6-overlay/s6-rc.d/horizon/run b/docker/development/etc/s6-overlay/s6-rc.d/horizon/run index 9a8d96d2a..584bd0d9d 100644 --- a/docker/development/etc/s6-overlay/s6-rc.d/horizon/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/horizon/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|worker) ;; - *) - echo " INFO Horizon is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role worker && ! coolify_container_has_role horizon; then + echo " INFO Horizon is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^HORIZON_ENABLED=false' .env 2>/dev/null; then echo " INFO Horizon is disabled, sleeping." diff --git a/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run b/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run index 7242b3f79..1f8b37079 100644 --- a/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/nightwatch-agent/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|worker) ;; - *) - echo " INFO Nightwatch is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role worker && ! coolify_container_has_role nightwatch && ! coolify_container_has_role nightwatch-agent; then + echo " INFO Nightwatch is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^NIGHTWATCH_ENABLED=true' .env 2>/dev/null; then echo " INFO Nightwatch is enabled, starting..." diff --git a/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run b/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run index 0dbc2e716..2dcd493a1 100644 --- a/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run +++ b/docker/development/etc/s6-overlay/s6-rc.d/scheduler-worker/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|worker) ;; - *) - echo " INFO Scheduler worker is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role worker && ! coolify_container_has_role scheduler && ! coolify_container_has_role scheduler-worker; then + echo " INFO Scheduler worker is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^SCHEDULER_ENABLED=false' .env 2>/dev/null; then echo " INFO Scheduler is disabled, sleeping." diff --git a/docker/development/etc/s6-overlay/scripts/container-role b/docker/development/etc/s6-overlay/scripts/container-role new file mode 100755 index 000000000..c7ee7dd3c --- /dev/null +++ b/docker/development/etc/s6-overlay/scripts/container-role @@ -0,0 +1,26 @@ +#!/bin/sh + +coolify_container_role_value() { + role="${COOLIFY_CONTAINER_ROLE:-}" + + if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" + fi + + printf '%s\n' "${role:-all}" +} + +coolify_container_has_role() { + wanted_role="$1" + roles="$(coolify_container_role_value | tr '[:upper:]' '[:lower:]' | tr ',' ' ')" + + for role in $roles; do + case "$role" in + all|"$wanted_role") + return 0 + ;; + esac + done + + return 1 +} diff --git a/docker/production/etc/s6-overlay/s6-rc.d/flux/run b/docker/production/etc/s6-overlay/s6-rc.d/flux/run index 95f648f8e..d99bdaac4 100755 --- a/docker/production/etc/s6-overlay/s6-rc.d/flux/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/flux/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|flux) ;; - *) - echo " INFO Flux is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role flux; then + echo " INFO Flux is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^COOLIFY_FLUX_ENABLED=false' .env 2>/dev/null || [ "${COOLIFY_FLUX_ENABLED:-}" = "false" ]; then echo " INFO Flux is disabled, sleeping." diff --git a/docker/production/etc/s6-overlay/s6-rc.d/horizon/run b/docker/production/etc/s6-overlay/s6-rc.d/horizon/run index 9a8d96d2a..584bd0d9d 100644 --- a/docker/production/etc/s6-overlay/s6-rc.d/horizon/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/horizon/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|worker) ;; - *) - echo " INFO Horizon is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role worker && ! coolify_container_has_role horizon; then + echo " INFO Horizon is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^HORIZON_ENABLED=false' .env 2>/dev/null; then echo " INFO Horizon is disabled, sleeping." diff --git a/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run b/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run index 7242b3f79..1f8b37079 100644 --- a/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/nightwatch-agent/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|worker) ;; - *) - echo " INFO Nightwatch is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role worker && ! coolify_container_has_role nightwatch && ! coolify_container_has_role nightwatch-agent; then + echo " INFO Nightwatch is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^NIGHTWATCH_ENABLED=true' .env 2>/dev/null; then echo " INFO Nightwatch is enabled, starting..." diff --git a/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run b/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run index 0dbc2e716..2dcd493a1 100644 --- a/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run +++ b/docker/production/etc/s6-overlay/s6-rc.d/scheduler-worker/run @@ -2,19 +2,13 @@ cd /var/www/html -role="${COOLIFY_CONTAINER_ROLE:-}" -if [ -z "$role" ]; then - role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" -fi -role="${role:-all}" +. /etc/s6-overlay/scripts/container-role +role="$(coolify_container_role_value)" -case "$role" in - all|worker) ;; - *) - echo " INFO Scheduler worker is disabled for role '$role', sleeping." - exec sleep infinity - ;; -esac +if ! coolify_container_has_role worker && ! coolify_container_has_role scheduler && ! coolify_container_has_role scheduler-worker; then + echo " INFO Scheduler worker is disabled for role '$role', sleeping." + exec sleep infinity +fi if grep -qE '^SCHEDULER_ENABLED=false' .env 2>/dev/null; then echo " INFO Scheduler is disabled, sleeping." diff --git a/docker/production/etc/s6-overlay/scripts/container-role b/docker/production/etc/s6-overlay/scripts/container-role new file mode 100755 index 000000000..c7ee7dd3c --- /dev/null +++ b/docker/production/etc/s6-overlay/scripts/container-role @@ -0,0 +1,26 @@ +#!/bin/sh + +coolify_container_role_value() { + role="${COOLIFY_CONTAINER_ROLE:-}" + + if [ -z "$role" ]; then + role="$(grep -E '^COOLIFY_CONTAINER_ROLE=' .env 2>/dev/null | tail -n1 | cut -d= -f2- | tr -d '"' | tr -d "'")" + fi + + printf '%s\n' "${role:-all}" +} + +coolify_container_has_role() { + wanted_role="$1" + roles="$(coolify_container_role_value | tr '[:upper:]' '[:lower:]' | tr ',' ' ')" + + for role in $roles; do + case "$role" in + all|"$wanted_role") + return 0 + ;; + esac + done + + return 1 +} diff --git a/package-lock.json b/package-lock.json index 288474a88..04a133240 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,6 @@ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -1614,8 +1613,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/baseline-browser-mapping": { "version": "2.10.33", @@ -1650,7 +1648,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -2296,7 +2293,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2408,7 +2404,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2418,7 +2413,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -2525,8 +2519,7 @@ "version": "4.1.18", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/tapable": { "version": "2.3.0", @@ -2600,7 +2593,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", diff --git a/tests/Feature/ContainerRoleScriptTest.php b/tests/Feature/ContainerRoleScriptTest.php new file mode 100644 index 000000000..5d55a3877 --- /dev/null +++ b/tests/Feature/ContainerRoleScriptTest.php @@ -0,0 +1,53 @@ +successful())->toBeTrue(); +})->with([ + ['worker,flux', 'worker'], + ['worker,flux', 'flux'], + ['web, all', 'flux'], + ['flux,all,worker', 'worker'], + ['horizon,scheduler,nightwatch,flux', 'horizon'], + ['horizon,scheduler,nightwatch,flux', 'scheduler'], + ['horizon,scheduler,nightwatch,flux', 'nightwatch'], +]); + +it('rejects services missing from the comma separated container roles', function () { + $result = runContainerRoleHelper('web,flux', 'worker'); + + expect($result->failed())->toBeTrue(); +}); + +it('falls back to the container role from the local env file', function () { + $directory = sys_get_temp_dir().'/coolify-container-role-'.bin2hex(random_bytes(4)); + mkdir($directory); + file_put_contents($directory.'/.env', 'COOLIFY_CONTAINER_ROLE=worker,flux'.PHP_EOL); + + $result = runContainerRoleHelper('', 'flux', $directory); + + expect($result->successful())->toBeTrue(); +}); + +it('keeps production and development role helpers in sync', function () { + expect(file_get_contents(base_path('docker/production/etc/s6-overlay/scripts/container-role'))) + ->toBe(file_get_contents(base_path('docker/development/etc/s6-overlay/scripts/container-role'))); +}); + +function runContainerRoleHelper(string $roles, string $serviceRole, ?string $workingDirectory = null): ProcessResult +{ + $script = base_path('docker/development/etc/s6-overlay/scripts/container-role'); + $command = sprintf( + '. %s && coolify_container_has_role %s', + escapeshellarg($script), + escapeshellarg($serviceRole), + ); + + return Process::path($workingDirectory ?? base_path()) + ->env(['COOLIFY_CONTAINER_ROLE' => $roles]) + ->run($command); +} From ed89d83d6838485ca87aab88d35b48125223c8cd Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 10:57:43 +0200 Subject: [PATCH 003/178] chore(scripts): remove conductor setup script --- scripts/conductor-setup.sh | 97 -------------------------------------- 1 file changed, 97 deletions(-) delete mode 100755 scripts/conductor-setup.sh diff --git a/scripts/conductor-setup.sh b/scripts/conductor-setup.sh deleted file mode 100755 index a88b457fb..000000000 --- a/scripts/conductor-setup.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash -set -e - -# Validate CONDUCTOR_ROOT_PATH is set and valid before any operations -if [ -z "$CONDUCTOR_ROOT_PATH" ]; then - echo "ERROR: CONDUCTOR_ROOT_PATH environment variable is not set" - echo "This script must be run by Conductor with CONDUCTOR_ROOT_PATH set to the main repository path" - exit 1 -fi - -if [ ! -d "$CONDUCTOR_ROOT_PATH" ]; then - echo "ERROR: CONDUCTOR_ROOT_PATH ($CONDUCTOR_ROOT_PATH) is not a valid directory" - exit 1 -fi - -# Copy .env file -cp "$CONDUCTOR_ROOT_PATH/.env" .env - -# Setup shared dependencies via symlinks to main repo -echo "Setting up shared node_modules and vendor directories..." - -# Ensure main repo has the directories -mkdir -p "$CONDUCTOR_ROOT_PATH/node_modules" -mkdir -p "$CONDUCTOR_ROOT_PATH/vendor" - -# Get current worktree path -WORKTREE_PATH=$(pwd) - -# Safety check 1: ensure WORKTREE_PATH is valid -if [ -z "$WORKTREE_PATH" ]; then - echo "ERROR: WORKTREE_PATH is empty" - exit 1 -fi - -# Safety check 2: CRITICAL FIRST - blacklist system directories -# This check runs BEFORE the positive check to prevent dangerous operations -# even if someone misconfigures CONDUCTOR_ROOT_PATH -case "$WORKTREE_PATH" in - /|/bin|/sbin|/usr|/usr/*|/etc|/etc/*|/var|/var/*|/System|/System/*|/Library|/Library/*|/Applications|/Applications/*|"$HOME") - echo "ERROR: WORKTREE_PATH ($WORKTREE_PATH) is in a dangerous system location" - exit 1 - ;; -esac - -# Safety check 3: positive check - verify we're under CONDUCTOR_ROOT_PATH -case "$WORKTREE_PATH" in - "$CONDUCTOR_ROOT_PATH"|"$CONDUCTOR_ROOT_PATH"/.conductor/*) - # Valid: either main repo or under .conductor/ - ;; - *) - echo "ERROR: WORKTREE_PATH ($WORKTREE_PATH) is not under CONDUCTOR_ROOT_PATH ($CONDUCTOR_ROOT_PATH)" - exit 1 - ;; -esac - -# Safety check 4: verify we're in a git repository -if [ ! -f ".git" ] && [ ! -d ".git" ]; then - echo "ERROR: Not in a git repository" - exit 1 -fi - -# Remove existing directories/symlinks if they exist -# For symlinks: use 'rm' without -r to remove the symlink itself (not following it) -# For directories: use 'rm -rf' to remove the directory and contents -if [ -L "node_modules" ]; then - # It's a symlink - remove it without following (no -r flag) - rm "$WORKTREE_PATH/node_modules" -elif [ -e "node_modules" ]; then - # It's a regular directory or file - safe to use -rf - rm -rf "$WORKTREE_PATH/node_modules" -fi - -if [ -L "vendor" ]; then - # It's a symlink - remove it without following (no -r flag) - rm "$WORKTREE_PATH/vendor" -elif [ -e "vendor" ]; then - # It's a regular directory or file - safe to use -rf - rm -rf "$WORKTREE_PATH/vendor" -fi - -# Calculate relative path from worktree to main repo -# Use bash-native approach: try realpath first (GNU coreutils), fallback to perl -if command -v realpath &> /dev/null && realpath --relative-to / / &> /dev/null 2>&1; then - # GNU coreutils realpath with --relative-to support - RELATIVE_PATH=$(realpath --relative-to="$WORKTREE_PATH" "$CONDUCTOR_ROOT_PATH") -else - # Fallback: use perl which is standard on macOS and most Unix systems - RELATIVE_PATH=$(perl -e 'use File::Spec; print File::Spec->abs2rel($ARGV[0], $ARGV[1])' "$CONDUCTOR_ROOT_PATH" "$WORKTREE_PATH") -fi - -# Create symlinks to main repo's node_modules and vendor -ln -sf "$RELATIVE_PATH/node_modules" node_modules -ln -sf "$RELATIVE_PATH/vendor" vendor - -echo "✓ Shared dependencies linked successfully" -echo " node_modules -> $RELATIVE_PATH/node_modules" -echo " vendor -> $RELATIVE_PATH/vendor" \ No newline at end of file From 1b1b0726a21038140ef33a41e985033fbfc4aaaf Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 11:39:36 +0200 Subject: [PATCH 004/178] feat(dev): add coold VM dev workflow Add scripts and Lima config for managing local coold endpoint VMs, mint Flux dev host JWTs, expose coold host details on the V5 home page, and document the local development workflow. --- .gitignore | 3 + README.md | 19 + app/Console/Commands/FluxDev.php | 75 +++ app/Http/Controllers/V5/HomeController.php | 26 + config/coold.php | 11 + config/flux.php | 2 + dev/lima/coold.yaml | 125 ++++ docker-compose-maxio.dev.yml | 4 +- docker-compose.dev.yml | 8 +- resources/js/v5/Pages/Home.jsx | 20 +- scripts/coold-vm.sh | 591 +++++++++++++++++ scripts/dev.sh | 680 ++++++++++++++++++++ tests/Feature/DevEnvironmentExampleTest.php | 31 + tests/Feature/FluxDevCommandTest.php | 65 ++ tests/Feature/V5/HomeTest.php | 6 + 15 files changed, 1661 insertions(+), 5 deletions(-) create mode 100644 app/Console/Commands/FluxDev.php create mode 100644 config/coold.php create mode 100644 dev/lima/coold.yaml create mode 100755 scripts/coold-vm.sh create mode 100755 scripts/dev.sh create mode 100644 tests/Feature/DevEnvironmentExampleTest.php create mode 100644 tests/Feature/FluxDevCommandTest.php diff --git a/.gitignore b/.gitignore index 403028761..b09e074f7 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ CHANGELOG.md /.workspaces tests/Browser/Screenshots tests/v4/Browser/Screenshots + +# Local generated Lima configs +.dev/lima/*.generated.yaml diff --git a/README.md b/README.md index 378e75ac7..46204ea5e 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,25 @@ You can find the installation script source [here](./scripts/install.sh). > Please refer to the [docs](https://coolify.io/docs/installation) for more information about the installation. +## Local dev with coold VM + +For v5 development that needs a packaged `coold` endpoint VM with Corrosion, use: + +```bash +scripts/dev.sh up +``` + +This starts two Lima endpoint VMs by default, configures a WireGuard mesh between them, starts the Docker stack in the background, mints dev host JWTs with `php artisan flux:dev --caps=coold,builder`, installs them into the VMs, starts each VM `coold` agent service with builder capacity, and follows Coolify + VM agent logs by default. Flux runs with the Coolify container, not inside the VM. Set `COOLIFY_COOLD_VM_COUNT=1` for a single endpoint, `COOLIFY_COOLD_VM_ENABLED=false` to skip the VMs, `COOLIFY_COOLD_VM_BUILDER_CAPACITY=0` to disable builder capability, or `COOLIFY_DEV_FOLLOW_LOGS=false` to leave `up` detached. Use `scripts/dev.sh down` to stop the stack and VM agent; set `COOLIFY_COOLD_VM_STOP_ON_DOWN=true` if you also want the VM stopped. The dev entrypoints are intentionally kept to `scripts/dev.sh` for the full stack and `scripts/coold-vm.sh` for VM-only operations. + +Useful Corrosion checks: + +```bash +scripts/dev.sh corrosion check +scripts/dev.sh corrosion containers +scripts/dev.sh corrosion config +scripts/dev.sh corrosion sql 'select count(*) from service_endpoints;' +``` + ## Container roles and Flux The Coolify image can run different process roles with `COOLIFY_CONTAINER_ROLE`. The value can be a single role or a comma-separated list. If `all` is present anywhere in the list, every role starts. diff --git a/app/Console/Commands/FluxDev.php b/app/Console/Commands/FluxDev.php new file mode 100644 index 000000000..2c6cfc84e --- /dev/null +++ b/app/Console/Commands/FluxDev.php @@ -0,0 +1,75 @@ +environment(['local', 'development', 'testing']) && ! $this->option('force')) { + $this->error('This command is intended for development only. Use --force to override.'); + + return self::FAILURE; + } + + $privateKeyPath = config('flux.jwt_private_key_path'); + + if (! is_string($privateKeyPath) || $privateKeyPath === '' || ! File::isReadable($privateKeyPath)) { + $this->error("Flux JWT private key not found at {$privateKeyPath}."); + + return self::FAILURE; + } + + $hostId = (string) $this->argument('host_id'); + $ttl = max(60, (int) $this->option('ttl')); + $now = time(); + $caps = collect(explode(',', (string) $this->option('caps'))) + ->map(fn (string $cap) => trim($cap)) + ->filter() + ->unique() + ->values() + ->all(); + + if ($caps === []) { + $caps = ['coold']; + } + + $token = JWT::encode([ + 'sub' => $hostId, + 'aud' => 'coold', + 'caps' => $caps, + 'iat' => $now, + 'exp' => $now + $ttl, + ], File::get($privateKeyPath), 'ES256'); + + $output = $this->option('output'); + + if (is_string($output) && $output !== '') { + $outputPath = Str::startsWith($output, '/') ? $output : base_path($output); + File::ensureDirectoryExists(dirname($outputPath)); + File::put($outputPath, $token.PHP_EOL); + chmod($outputPath, 0600); + $this->info("Host JWT written to {$outputPath}."); + + return self::SUCCESS; + } + + $this->line($token); + + return self::SUCCESS; + } +} diff --git a/app/Http/Controllers/V5/HomeController.php b/app/Http/Controllers/V5/HomeController.php index b8f9fa6db..116952153 100644 --- a/app/Http/Controllers/V5/HomeController.php +++ b/app/Http/Controllers/V5/HomeController.php @@ -21,6 +21,7 @@ class HomeController extends Controller return Inertia::render('Home', [ 'status' => 'v5-ready', 'flux' => $fluxHealth->check(), + 'cooldHosts' => $this->cooldHosts(), 'currentTeam' => $currentTeam instanceof Team ? [ 'id' => $currentTeam->id, 'name' => $currentTeam->name, @@ -41,4 +42,29 @@ class HomeController extends Controller ]), ]); } + + /** + * @return array, builderEnabled: bool, builderCapacity: int}> + */ + private function cooldHosts(): array + { + $baseId = (string) config('coold.dev_host_id'); + $count = max(0, (int) config('coold.dev_host_count')); + $builderCapacity = (int) config('coold.dev_builder_capacity'); + $builderEnabled = $builderCapacity > 0; + + if ($count === 0 || $baseId === '') { + return []; + } + + return collect(range(1, $count)) + ->map(fn (int $index) => [ + 'id' => $index === 1 ? $baseId : (string) config("coold.dev_host_id_{$index}", "{$baseId}-{$index}"), + 'wireguardIp' => (string) config("coold.dev_wireguard_ip_{$index}") ?: null, + 'capabilities' => $builderEnabled ? ['coold', 'builder'] : ['coold'], + 'builderEnabled' => $builderEnabled, + 'builderCapacity' => $builderCapacity, + ]) + ->all(); + } } diff --git a/config/coold.php b/config/coold.php new file mode 100644 index 000000000..20dac4445 --- /dev/null +++ b/config/coold.php @@ -0,0 +1,11 @@ + (int) env('COOLIFY_COOLD_VM_COUNT', 2), + 'dev_host_id' => env('COOLIFY_COOLD_DEV_HOST_ID', 'coolify-coold-dev'), + 'dev_host_id_2' => env('COOLIFY_COOLD_LIMA_INSTANCE_2', env('COOLIFY_COOLD_DEV_HOST_ID', 'coolify-coold-dev').'-2'), + 'dev_wireguard_ip_1' => env('COOLIFY_COOLD_VM_WG_IP_1', '100.64.0.10'), + 'dev_wireguard_ip_2' => env('COOLIFY_COOLD_VM_WG_IP_2', '100.64.0.11'), + 'dev_builder_capacity' => (int) env('COOLIFY_COOLD_VM_BUILDER_CAPACITY', 2), + 'dev_builder_enabled' => (int) env('COOLIFY_COOLD_VM_BUILDER_CAPACITY', 2) > 0, +]; diff --git a/config/flux.php b/config/flux.php index e82914de0..dea770e47 100644 --- a/config/flux.php +++ b/config/flux.php @@ -2,5 +2,7 @@ return [ 'unix_socket_path' => env('COOLIFY_FLUX_UNIX_SOCKET_PATH', '/run/coolify/flux.sock'), + 'jwt_private_key_path' => env('COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH', storage_path('app/flux/jwt.priv')), + 'jwt_public_key_path' => env('COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH', storage_path('app/flux/jwt.pub')), 'health_timeout_seconds' => (float) env('COOLIFY_FLUX_HEALTH_TIMEOUT_SECONDS', 1.0), ]; diff --git a/dev/lima/coold.yaml b/dev/lima/coold.yaml new file mode 100644 index 000000000..d0354b215 --- /dev/null +++ b/dev/lima/coold.yaml @@ -0,0 +1,125 @@ +# Lima VM for testing Coolify v5 against a packaged coold endpoint. +# Start with: scripts/coold-vm.sh up +# Run endpoint: scripts/coold-vm.sh dev +# +# This file is copied into .dev/lima/coold.generated.yaml by the wrapper script, +# with {{COOLIFY_REPO}}, {{COOLIFY_COOLD_VERSION}}, and {{COOLIFY_CORROSION_VERSION}} replaced before Lima sees it. + +vmType: "vz" +arch: "default" +cpus: 4 +memory: "8GiB" +disk: "100GiB" +containerd: + system: false + user: false + +images: + - location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img" + arch: "x86_64" + - location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img" + arch: "aarch64" + +mountType: "virtiofs" +mounts: + - location: "{{COOLIFY_REPO}}" + mountPoint: "/workspace/coolify" + writable: true + +portForwards: + - guestPort: 5173 + hostPort: 5173 + hostIP: "127.0.0.1" + - guestPort: 3000 + hostPort: 3000 + hostIP: "127.0.0.1" +provision: + - mode: system + script: | + #!/usr/bin/env bash + set -euxo pipefail + export DEBIAN_FRONTEND=noninteractive + echo "[coold-vm] Updating Ubuntu package index..." + apt-get update + echo "[coold-vm] Installing VM dependencies..." + apt-get install -y --no-install-recommends \ + bash \ + buildah \ + ca-certificates \ + clang \ + curl \ + git \ + iproute2 \ + iptables \ + jq \ + libssl-dev \ + mold \ + nftables \ + openssl \ + perl \ + pkg-config \ + podman \ + protobuf-compiler \ + sqlite3 \ + sudo \ + wireguard-tools + echo "[coold-vm] Enabling Podman socket..." + systemctl enable --now podman.socket + cat >/usr/local/bin/rtk <<'SH' + #!/usr/bin/env bash + exec "$@" + SH + chmod +x /usr/local/bin/rtk + mkdir -p /etc/coolify /var/lib/corrosion /run/corrosion /var/lib/coolify-dev /var/lib/coolify-builder/work + chmod 755 /etc/coolify + chmod 777 /var/lib/corrosion /run/corrosion + + install_coolify_binary() { + name="$1" + version="{{COOLIFY_COOLD_VERSION}}" + arch_raw="$(uname -m)" + case "$arch_raw" in + x86_64) arch=amd64 ;; + aarch64) arch=arm64 ;; + *) echo "unsupported arch: $arch_raw" >&2; exit 1 ;; + esac + + url="https://github.com/coollabsio/coold/releases/download/${version}/${name}-linux-${arch}.tar.gz" + echo "[coold-vm] Installing ${name} from ${url}..." + tmpdir="$(mktemp -d)" + trap 'rm -rf "$tmpdir"' RETURN + curl -fsSL --retry 3 --max-time 120 -o "$tmpdir/${name}.tar.gz" "$url" + tar -xzf "$tmpdir/${name}.tar.gz" -C "$tmpdir" + test -f "$tmpdir/$name" + install -m 0755 "$tmpdir/$name" "/usr/local/bin/${name}.tmp" + mv "/usr/local/bin/${name}.tmp" "/usr/local/bin/${name}" + echo "$version" > "/usr/local/bin/${name}.version" + } + + install_corrosion_binary() { + version="{{COOLIFY_CORROSION_VERSION}}" + arch_raw="$(uname -m)" + case "$arch_raw" in + x86_64) arch=x86_64-unknown-linux-gnu ;; + aarch64) arch=aarch64-unknown-linux-gnu ;; + *) echo "unsupported arch: $arch_raw" >&2; exit 1 ;; + esac + + url="https://github.com/superfly/corrosion/releases/download/${version}/corrosion-${arch}.tar.gz" + echo "[coold-vm] Installing corrosion from ${url}..." + tmpdir="$(mktemp -d)" + trap 'rm -rf "$tmpdir"' RETURN + curl -fsSL --retry 3 --max-time 180 -o "$tmpdir/corrosion.tar.gz" "$url" + tar -xzf "$tmpdir/corrosion.tar.gz" -C "$tmpdir" + test -f "$tmpdir/corrosion" + install -m 0755 "$tmpdir/corrosion" /usr/local/bin/corrosion.tmp + mv /usr/local/bin/corrosion.tmp /usr/local/bin/corrosion + echo "$version" > /usr/local/bin/corrosion.version + } + + install_coolify_binary coold + install_coolify_binary builder + install_corrosion_binary + echo "[coold-vm] Endpoint binaries installed." + + echo "[coold-vm] Provisioning complete." diff --git a/docker-compose-maxio.dev.yml b/docker-compose-maxio.dev.yml index bbb483d7a..164b1b338 100644 --- a/docker-compose-maxio.dev.yml +++ b/docker-compose-maxio.dev.yml @@ -12,8 +12,8 @@ services: - "${APP_PORT:-8000}:8080" environment: AUTORUN_ENABLED: false - PUSHER_HOST: "${PUSHER_HOST}" - PUSHER_PORT: "${PUSHER_PORT}" + PUSHER_HOST: "${PUSHER_HOST:-}" + PUSHER_PORT: "${PUSHER_PORT:-}" PUSHER_SCHEME: "${PUSHER_SCHEME:-http}" PUSHER_APP_ID: "${PUSHER_APP_ID:-coolify}" PUSHER_APP_KEY: "${PUSHER_APP_KEY:-coolify}" diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index bad72a22d..ea095f17f 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -8,14 +8,18 @@ services: args: - USER_ID=${USERID:-1000} - GROUP_ID=${GROUPID:-1000} + - COOLIFY_FLUX_VERSION=${COOLIFY_FLUX_VERSION:-nightly} ports: - "${APP_PORT:-8000}:8080" - "${FORWARD_FLUX_PORT:-6443}:6443" environment: AUTORUN_ENABLED: false COOLIFY_CONTAINER_ROLE: "${COOLIFY_CONTAINER_ROLE:-all}" - PUSHER_HOST: "${PUSHER_HOST}" - PUSHER_PORT: "${PUSHER_PORT}" + COOLIFY_COOLD_VERSION: "${COOLIFY_COOLD_VERSION:-nightly}" + COOLIFY_FLUX_VERSION: "${COOLIFY_FLUX_VERSION:-nightly}" + COOLIFY_CORROSION_VERSION: "${COOLIFY_CORROSION_VERSION:-v1.0.0}" + PUSHER_HOST: "${PUSHER_HOST:-}" + PUSHER_PORT: "${PUSHER_PORT:-}" PUSHER_SCHEME: "${PUSHER_SCHEME:-http}" PUSHER_APP_ID: "${PUSHER_APP_ID:-coolify}" PUSHER_APP_KEY: "${PUSHER_APP_KEY:-coolify}" diff --git a/resources/js/v5/Pages/Home.jsx b/resources/js/v5/Pages/Home.jsx index 0fa9a231b..4ed49d968 100644 --- a/resources/js/v5/Pages/Home.jsx +++ b/resources/js/v5/Pages/Home.jsx @@ -1,6 +1,6 @@ import { Head } from '@inertiajs/react'; -export default function Home({ status, currentTeam, teams, flux }) { +export default function Home({ status, currentTeam, teams, flux, cooldHosts }) { return ( <> @@ -27,6 +27,24 @@ export default function Home({ status, currentTeam, teams, flux }) { {flux.socket ?

Socket: {flux.socket}

: null} +
+

coold host

+ +
    + {cooldHosts.map((host) => ( +
  • + {host.id} + {host.wireguardIp ? ` (${host.wireguardIp})` : ''}: + {' '} + {host.capabilities.join(', ')}; builder{' '} + {host.builderEnabled + ? `enabled, capacity ${host.builderCapacity}` + : 'disabled'} +
  • + ))} +
+
+

Current team

{currentTeam ? ( diff --git a/scripts/coold-vm.sh b/scripts/coold-vm.sh new file mode 100755 index 000000000..627717181 --- /dev/null +++ b/scripts/coold-vm.sh @@ -0,0 +1,591 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +read_coolify_env() { + key="$1" + default_value="$2" + current_value="${!key:-}" + + if [ -n "$current_value" ]; then + printf '%s\n' "$current_value" + return + fi + + if [ -f "$ROOT/.env" ]; then + env_value="$(grep -E "^${key}=" "$ROOT/.env" 2>/dev/null | tail -n1 | cut -d= -f2- | sed "s/^['\"]//; s/['\"]$//")" + if [ -n "$env_value" ]; then + printf '%s\n' "$env_value" + return + fi + fi + + printf '%s\n' "$default_value" +} + +INSTANCE="$(read_coolify_env COOLIFY_COOLD_LIMA_INSTANCE coold-dev)" +VERSION="$(read_coolify_env COOLIFY_COOLD_VERSION nightly)" +CORROSION_VERSION="$(read_coolify_env COOLIFY_CORROSION_VERSION v1.0.0)" +FLUX_URL="$(read_coolify_env COOLIFY_COOLD_VM_FLUX_URL http://host.lima.internal:6443)" +BUILDER_CAPACITY="$(read_coolify_env COOLIFY_COOLD_VM_BUILDER_CAPACITY 2)" +WG_IP="$(read_coolify_env COOLIFY_COOLD_VM_WG_IP "")" +WG_PEER_IP="$(read_coolify_env COOLIFY_COOLD_VM_WG_PEER_IP "")" +WG_PEER_ENDPOINT="$(read_coolify_env COOLIFY_COOLD_VM_WG_PEER_ENDPOINT "")" +WG_PEER_PUBLIC_KEY="$(read_coolify_env COOLIFY_COOLD_VM_WG_PEER_PUBLIC_KEY "")" +CONTAINER_SUBNET="$(read_coolify_env COOLIFY_COOLD_VM_CONTAINER_SUBNET 10.210.0.0/24)" +CONTAINER_GATEWAY="$(read_coolify_env COOLIFY_COOLD_VM_CONTAINER_GATEWAY 10.210.0.1)" +BUILDER_ENABLED="true" +if [ "$BUILDER_CAPACITY" = "0" ]; then + BUILDER_ENABLED="false" +fi +TEMPLATE="$ROOT/dev/lima/coold.yaml" +GENERATED="$ROOT/.dev/lima/coold.generated.yaml" +GUEST_COOLIFY_ROOT="/workspace/coolify" + +usage() { + cat < + +Commands: + up Create/start the Lima VM and install packaged coold endpoint binaries + dev Start packaged coold + Corrosion inside the VM + start-agent + Start production-like coold.service + corrosion.service inside the VM + stop-agent + Stop the VM coold.service + corrosion.service + logs-agent + Follow the VM coold.service + corrosion.service logs + install-host-jwt [token] + Install a Flux host JWT into the VM at /etc/coolify/host-jwt + shell Open a shell inside the VM + status Show Lima instance status + stop Stop the VM + delete Delete the VM and all VM-local runtime state + +Environment: + COOLIFY_COOLD_LIMA_INSTANCE Override Lima instance name (default: coold-dev) + COOLIFY_COOLD_VERSION coold release tag to install (default: nightly) + COOLIFY_CORROSION_VERSION corrosion release tag to install (default: v1.0.0) + COOLIFY_COOLD_VM_FLUX_URL Flux gRPC URL visible from the VM (default: http://host.lima.internal:6443) + COOLIFY_COOLD_VM_BUILDER_CAPACITY VM builder capacity to advertise (default: 2; set 0 to disable) + COOLIFY_COOLD_VM_WG_IP Optional WireGuard mgmt IP for this host + COOLIFY_COOLD_VM_CONTAINER_SUBNET Podman mesh subnet for this host + COOLIFY_COOLD_VM_CONTAINER_GATEWAY Podman mesh gateway for this host + +Guest mounts: + $ROOT -> $GUEST_COOLIFY_ROOT + +Installed from: + https://github.com/coollabsio/coold/releases/tag/$VERSION + https://github.com/superfly/corrosion/releases/tag/$CORROSION_VERSION +USAGE +} + +require_lima() { + command -v limactl >/dev/null 2>&1 || { + echo "limactl is required. Install Lima first: brew install lima" >&2 + exit 1 + } +} + +instance_exists() { + limactl list 2>/dev/null | awk 'NR > 1 {print $1}' | grep -qx "$INSTANCE" +} + +instance_running() { + limactl list 2>/dev/null | awk -v name="$INSTANCE" 'NR > 1 && $1 == name {print $2}' | grep -qx Running +} + +lima_shell() { + (cd /tmp && limactl shell "$INSTANCE" -- "$@") +} + +vm_primary_ip() { + lima_shell sh -lc "ip -4 route get 1.1.1.1 | awk '{print \$7; exit}'" +} + +wireguard_public_key() { + lima_shell sudo sh -lc 'install -d -m 0700 /etc/wireguard; if [ ! -s /etc/wireguard/privatekey ]; then wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey; chmod 600 /etc/wireguard/privatekey; fi; cat /etc/wireguard/publickey' +} + +setup_wireguard() { + local ip="${1:-$WG_IP}" + local peer_ip="${2:-$WG_PEER_IP}" + local peer_endpoint="${3:-$WG_PEER_ENDPOINT}" + local peer_public_key="${4:-$WG_PEER_PUBLIC_KEY}" + local listen_port="${5:-51820}" + local peer_port="${6:-51820}" + local peer_subnet="${7:-}" + + if [ -z "$ip" ]; then + echo "ERROR: WireGuard IP is required." >&2 + exit 1 + fi + + wireguard_public_key >/dev/null + + if [ -n "$peer_ip" ] && [ -n "$peer_endpoint" ] && [ -n "$peer_public_key" ]; then + lima_shell sudo sh -lc "cat >/etc/wireguard/wg0.conf.tmp </dev/null 2>&1 || true; wg-quick up wg0" + else + lima_shell sudo sh -lc "cat >/etc/wireguard/wg0.conf.tmp </dev/null 2>&1 || true; wg-quick up wg0" + fi +} + +install_host_jwt() { + token="${1:-}" + + if [ -z "$token" ]; then + token="$(cat)" + fi + + if [ -z "$token" ]; then + echo "ERROR: host JWT is empty." >&2 + exit 1 + fi + + printf '%s\n' "$token" | lima_shell sudo sh -c 'install -d -m 0755 /etc/coolify && cat > /tmp/coolify-host-jwt && install -m 0600 /tmp/coolify-host-jwt /etc/coolify/host-jwt && rm -f /tmp/coolify-host-jwt' +} + + +stop_agent_processes() { + lima_shell sudo systemctl stop coold.service corrosion.service coold-dev-agent.service >/dev/null 2>&1 || true + lima_shell sudo pkill -x coold >/dev/null 2>&1 || true + lima_shell sudo pkill -x corrosion >/dev/null 2>&1 || true +} + +ensure_podman_networks() { + local current_subnet + current_subnet="$(lima_shell sudo podman network inspect coolify-default-mesh --format '{{range .Subnets}}{{.Subnet}}{{end}}' 2>/dev/null || true)" + + if [ -n "$current_subnet" ] && [ "$current_subnet" != "$CONTAINER_SUBNET" ]; then + lima_shell sudo podman network rm coolify-default-mesh >/dev/null + current_subnet="" + fi + + if [ -z "$current_subnet" ]; then + lima_shell sudo podman network create --subnet "$CONTAINER_SUBNET" --gateway "$CONTAINER_GATEWAY" coolify-default-mesh >/dev/null + fi +} + +write_runtime_config() { + local gossip_addr="127.0.0.1:8787" + local bootstrap="" + + if [ -n "$WG_IP" ]; then + gossip_addr="$WG_IP:8787" + fi + + if [ -n "$WG_PEER_IP" ]; then + bootstrap="\"$WG_PEER_IP:8787\"" + fi + + lima_shell sudo install -d -m 0755 /etc/corrosion/schemas /etc/coolify /run/coolify /var/lib/corrosion /var/run/corrosion /var/lib/coolify-dev /var/lib/coolify-builder/work + + lima_shell sudo tee /etc/corrosion/schemas/coolify.sql >/dev/null <<'SQL' +CREATE TABLE service_endpoints ( + container_id TEXT NOT NULL DEFAULT '' PRIMARY KEY, + container_name TEXT NOT NULL DEFAULT '', + namespace TEXT NOT NULL DEFAULT '', + host_mgmt_ip TEXT NOT NULL DEFAULT '', + container_ip TEXT NOT NULL DEFAULT '', + state TEXT NOT NULL DEFAULT '', + health TEXT NOT NULL DEFAULT 'unknown', + updated_at INTEGER NOT NULL DEFAULT 0 +); +SQL + + lima_shell sudo tee /etc/corrosion/config.toml >/dev/null </dev/null || cat /usr/local/bin/corrosion.version)" +echo "starting packaged coold endpoint with corrosion in local mode" + +cleanup() { + jobs -pr | xargs -r kill || true +} +trap cleanup EXIT INT TERM + +/usr/local/bin/corrosion agent --config /etc/corrosion/config.toml & + +COOLIFY_COOLD_HOST_MGMT_IP="${COOLIFY_COOLD_HOST_MGMT_IP:-127.0.0.1}" \ +COOLIFY_COOLD_PODMAN_SOCKET="${COOLIFY_COOLD_PODMAN_SOCKET:-/run/podman/podman.sock}" \ +COOLIFY_COOLD_CORROSION_URL="${COOLIFY_COOLD_CORROSION_URL:-http://127.0.0.1:8080}" \ +COOLIFY_COOLD_NAMESPACES="${COOLIFY_COOLD_NAMESPACES:-default:coolify-default-mesh:$CONTAINER_GATEWAY}" \ +COOLIFY_COOLD_DNS_ZONE="${COOLIFY_COOLD_DNS_ZONE:-coolify.internal}" \ +COOLIFY_COOLD_API_BIND="${COOLIFY_COOLD_API_BIND:-${WG_IP:-127.0.0.1}:8443}" \ +COOLIFY_COOLD_API_TOKEN_FILE="${COOLIFY_COOLD_API_TOKEN_FILE:-/etc/coolify/api-token}" \ +COOLIFY_COOLD_FLUX_URL="${COOLIFY_COOLD_FLUX_URL:-http://host.lima.internal:6443}" \ +COOLIFY_COOLD_HOST_JWT_PATH="${COOLIFY_COOLD_HOST_JWT_PATH:-/etc/coolify/host-jwt}" \ +COOLIFY_COOLD_BUILDER_ENABLED="${COOLIFY_COOLD_BUILDER_ENABLED:-true}" \ +COOLIFY_COOLD_BUILDER_CAPACITY="${COOLIFY_COOLD_BUILDER_CAPACITY:-2}" \ +COOLIFY_COOLD_BUILDER_BIN="${COOLIFY_COOLD_BUILDER_BIN:-/usr/local/bin/builder}" \ +COOLIFY_COOLD_BUILDER_WORK_DIR="${COOLIFY_COOLD_BUILDER_WORK_DIR:-/var/lib/coolify-builder/work}" \ +/usr/local/bin/coold & + +wait +RUNNER +} + +install_mesh_firewall() { + lima_shell sudo install -d -m 0755 /etc/coolify + lima_shell sudo touch /etc/coolify/allow.rules /etc/coolify/allow.nft + + lima_shell sudo tee /etc/coolify/bridge-fw.nft >/dev/null </dev/null </dev/null || /usr/sbin/iptables -t nat -I POSTROUTING -s $CONTAINER_SUBNET -o wg0 -j RETURN" +ExecStart=/bin/sh -c "/usr/sbin/iptables -D FORWARD -s $CONTAINER_SUBNET -j ACCEPT 2>/dev/null || true" +ExecStart=/bin/sh -c "/usr/sbin/iptables -D FORWARD -d $CONTAINER_SUBNET -j ACCEPT 2>/dev/null || true" +ExecStart=/bin/sh -c "/usr/sbin/iptables -N COOLIFY-ALLOW 2>/dev/null || true" +ExecStart=/bin/sh -c "/usr/sbin/iptables -N COOLIFY-INTRA 2>/dev/null || true" +ExecStart=/usr/sbin/iptables -F COOLIFY-ALLOW +ExecStart=/usr/sbin/iptables -F COOLIFY-INTRA +ExecStart=/usr/sbin/iptables -A COOLIFY-INTRA -j COOLIFY-ALLOW +ExecStart=/usr/sbin/iptables -A COOLIFY-INTRA -j DROP +ExecStart=/bin/sh -c "/usr/sbin/iptables -C FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 2>/dev/null || /usr/sbin/iptables -I FORWARD 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT" +ExecStart=/bin/sh -c "/usr/sbin/iptables -C FORWARD -d $CONTAINER_SUBNET -j COOLIFY-INTRA 2>/dev/null || /usr/sbin/iptables -A FORWARD -d $CONTAINER_SUBNET -j COOLIFY-INTRA" +ExecStart=/bin/sh -c "/usr/sbin/iptables -C FORWARD -s $CONTAINER_SUBNET -j COOLIFY-INTRA 2>/dev/null || /usr/sbin/iptables -A FORWARD -s $CONTAINER_SUBNET -j COOLIFY-INTRA" +ExecStart=/bin/sh -c "nft delete table bridge coolify_bridge 2>/dev/null || true" +ExecStart=/bin/sh -c "nft -f /etc/coolify/bridge-fw.nft" +ExecStart=/bin/sh -c "[ -s /etc/coolify/allow.nft ] && nft -f /etc/coolify/allow.nft || true" + +[Install] +WantedBy=multi-user.target +UNIT + + lima_shell sudo systemctl daemon-reload + lima_shell sudo systemctl enable --now coolify-mesh-fw.service + lima_shell sudo systemctl restart coolify-mesh-fw.service +} + +start_agent() { + stop_agent_processes + write_runtime_config + ensure_podman_networks + install_mesh_firewall + lima_shell sudo sh -c 'if [ ! -s /etc/coolify/api-token ]; then openssl rand -hex 32 > /etc/coolify/api-token.tmp && chmod 600 /etc/coolify/api-token.tmp && mv /etc/coolify/api-token.tmp /etc/coolify/api-token; fi' + + lima_shell sudo tee /etc/systemd/system/corrosion.service >/dev/null <<'UNIT' +[Unit] +Description=Corrosion local state store +After=network-online.target +Wants=network-online.target + +[Service] +ExecStart=/usr/local/bin/corrosion agent --config /etc/corrosion/config.toml +Restart=on-failure +RestartSec=2s + +[Install] +WantedBy=multi-user.target +UNIT + + lima_shell sudo tee /etc/systemd/system/coold.service >/dev/null < "$GENERATED" +} + +start_vm() { + generate_yaml + + if instance_running; then + return + fi + + if instance_exists; then + limactl start --tty=false "$INSTANCE" + else + limactl start --tty=false --name="$INSTANCE" "$GENERATED" + fi +} + +latest_lima_message() { + log_file="$HOME/.lima/$INSTANCE/ha.stderr.log" + + if [ ! -f "$log_file" ]; then + echo "creating Lima instance directory" + return 0 + fi + + grep -E '"msg":"(Starting VZ|Waiting for|The essential requirement|Executing /mnt/lima|SSH Local Port|Port is available|Attempting|Downloaded|Using the existing instance|The instance)' "$log_file" | tail -n 1 | sed -E 's/^.*"msg":"(.*)","time":.*$/\1/' | sed 's/\\"/"/g' || true +} + +wait_for_lima_start() { + start_vm & + start_pid=$! + elapsed=0 + + while kill -0 "$start_pid" 2>/dev/null; do + if instance_exists && lima_shell true >/dev/null 2>&1; then + status="$(lima_shell cloud-init status 2>/dev/null || true)" + printf '==> [%3ss] Lima start: guest SSH ready, cloud-init %s +' "$elapsed" "${status:-unknown}" + lima_shell sudo sh -c 'test -f /var/log/cloud-init-output.log && tail -n 12 /var/log/cloud-init-output.log || true' 2>/dev/null | awk '{ print "[guest] " $0; fflush(); }' || true + + if ! printf '%s' "$status" | grep -q running; then + kill "$start_pid" >/dev/null 2>&1 || true + break + fi + else + message="$(latest_lima_message)" + printf '==> [%3ss] Lima start: %s +' "$elapsed" "${message:-booting}" + fi + + sleep 5 + elapsed=$((elapsed + 5)) + done + + wait "$start_pid" 2>/dev/null || true +} + +wait_for_guest_provisioning() { + echo "==> Waiting for guest SSH..." + until instance_exists && lima_shell true >/dev/null 2>&1; do + message="$(latest_lima_message)" + printf '==> Waiting for guest SSH: %s +' "${message:-booting}" + sleep 5 + done + + status="$(lima_shell cloud-init status 2>/dev/null || true)" + + if printf '%s' "$status" | grep -q running; then + echo "==> Guest SSH is ready; streaming cloud-init output until provisioning completes..." + ( + lima_shell sudo sh -c 'touch /var/log/cloud-init-output.log; tail -n 40 -F /var/log/cloud-init-output.log' 2>/dev/null | awk '{ print "[guest] " $0; fflush(); }' + ) & + tail_pid=$! + + while true; do + status="$(lima_shell cloud-init status 2>/dev/null || true)" + printf '==> Guest cloud-init: %s +' "${status:-unknown}" + + if ! printf '%s' "$status" | grep -q running; then + break + fi + + sleep 5 + done + + kill "$tail_pid" >/dev/null 2>&1 || true + wait "$tail_pid" 2>/dev/null || true + else + printf '==> Guest cloud-init: %s +' "${status:-unknown}" + fi + + echo "==> Final guest provisioning status:" + lima_shell bash -lc 'cloud-init status 2>/dev/null || true; if command -v coold >/dev/null; then coold --version; else echo "coold not installed yet"; fi; if command -v corrosion >/dev/null; then echo "corrosion installed"; else echo "corrosion not installed yet"; fi; if command -v builder >/dev/null; then echo "builder installed"; else echo "builder not installed yet"; fi; true' | awk '{ print "[guest] " $0; fflush(); }' || true + + if ! lima_shell bash -lc 'command -v coold >/dev/null && command -v corrosion >/dev/null && command -v builder >/dev/null' >/dev/null 2>&1; then + echo "ERROR: VM provisioning finished but coold, corrosion, or builder is missing." >&2 + echo "Check with: scripts/coold-vm.sh shell" >&2 + exit 1 + fi +} + +up_with_logs() { + echo "==> Coolify coold VM: $INSTANCE" + echo "==> coold package tag: $VERSION" + echo "==> corrosion package tag: $CORROSION_VERSION" + echo "==> Lima config: $GENERATED" + + wait_for_lima_start + wait_for_guest_provisioning + + echo "==> VM is ready. Run: scripts/coold-vm.sh dev" +} + +cmd="${1:-}" +case "$cmd" in + up) + require_lima + up_with_logs + ;; + dev) + require_lima + start_vm >/dev/null + run_foreground + ;; + start-agent) + require_lima + start_vm >/dev/null + start_agent + ;; + stop-agent) + require_lima + if instance_running; then + stop_agent_processes + fi + ;; + logs-agent) + require_lima + start_vm >/dev/null + exec bash -lc "cd /tmp && limactl shell '$INSTANCE' -- sudo journalctl -u coold.service -u corrosion.service -f -n 100" + ;; + install-host-jwt) + require_lima + start_vm >/dev/null + install_host_jwt "${2:-}" + ;; + wg-public-key) + require_lima + start_vm >/dev/null + wireguard_public_key + ;; + vm-ip) + require_lima + start_vm >/dev/null + vm_primary_ip + ;; + setup-wireguard) + require_lima + start_vm >/dev/null + setup_wireguard "${2:-}" "${3:-}" "${4:-}" "${5:-}" "${6:-}" "${7:-}" "${8:-}" + ;; + shell) + require_lima + start_vm >/dev/null + exec bash -lc "cd /tmp && limactl shell '$INSTANCE' -- env TERM=xterm-256color SYSTEMD_PAGER=cat SYSTEMD_LESS=FRXMK bash -l" + ;; + status) + require_lima + if instance_exists; then + exec limactl list "$INSTANCE" + fi + + echo "No Lima instance named '$INSTANCE' exists yet." + echo "Run: scripts/coold-vm.sh up" + ;; + stop) + require_lima + exec limactl stop "$INSTANCE" + ;; + delete|destroy) + require_lima + exec limactl delete --force --tty=false "$INSTANCE" + ;; + -h|--help|help|"") + usage + ;; + *) + echo "unknown command: $cmd" >&2 + usage >&2 + exit 1 + ;; +esac diff --git a/scripts/dev.sh b/scripts/dev.sh new file mode 100755 index 000000000..f361a0fac --- /dev/null +++ b/scripts/dev.sh @@ -0,0 +1,680 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT" + +read_coolify_env() { + key="$1" + default_value="$2" + current_value="${!key:-}" + + if [ -n "$current_value" ]; then + printf '%s\n' "$current_value" + return + fi + + if [ -f .env ]; then + env_value="$(grep -E "^${key}=" .env 2>/dev/null | tail -n1 | cut -d= -f2- | sed "s/^['\"]//; s/['\"]$//")" + if [ -n "$env_value" ]; then + printf '%s\n' "$env_value" + return + fi + fi + + printf '%s\n' "$default_value" +} + +coold_vm_count() { + local count + count="$(read_coolify_env COOLIFY_COOLD_VM_COUNT 2)" + + if [ "$count" != "1" ] && [ "$count" != "2" ]; then + echo "ERROR: COOLIFY_COOLD_VM_COUNT supports 1 or 2 for now." >&2 + exit 1 + fi + + printf '%s\n' "$count" +} + +coold_vm_instance() { + local index="$1" + local base + base="$(read_coolify_env COOLIFY_COOLD_LIMA_INSTANCE coold-dev)" + + if [ "$index" = "1" ]; then + printf '%s\n' "$base" + return + fi + + read_coolify_env "COOLIFY_COOLD_LIMA_INSTANCE_${index}" "${base}-${index}" +} + +coold_vm_wg_ip() { + local index="$1" + read_coolify_env "COOLIFY_COOLD_VM_WG_IP_${index}" "100.64.0.$((9 + index))" +} + +coold_vm_wg_port() { + local index="$1" + read_coolify_env "COOLIFY_COOLD_VM_WG_PORT_${index}" "$((51820 + index))" +} + +coold_vm_container_subnet() { + local index="$1" + read_coolify_env "COOLIFY_COOLD_VM_CONTAINER_SUBNET_${index}" "10.210.$((index - 1)).0/24" +} + +coold_vm_container_gateway() { + local index="$1" + read_coolify_env "COOLIFY_COOLD_VM_CONTAINER_GATEWAY_${index}" "10.210.$((index - 1)).1" +} + +coold_vm() { + local index="$1" + shift + COOLIFY_COOLD_LIMA_INSTANCE="$(coold_vm_instance "$index")" \ + COOLIFY_COOLD_VM_WG_IP="$(coold_vm_wg_ip "$index")" \ + COOLIFY_COOLD_VM_CONTAINER_SUBNET="$(coold_vm_container_subnet "$index")" \ + COOLIFY_COOLD_VM_CONTAINER_GATEWAY="$(coold_vm_container_gateway "$index")" \ + scripts/coold-vm.sh "$@" +} + +mint_host_jwt_for_host() { + local host_id="$1" + local attempts=60 + local output + local caps + local builder_capacity + + builder_capacity="$(read_coolify_env COOLIFY_COOLD_VM_BUILDER_CAPACITY 2)" + caps="coold" + if [ "$builder_capacity" != "0" ]; then + caps="coold,builder" + fi + + for attempt in $(seq 1 "$attempts"); do + if output="$(spin exec -T coolify php artisan flux:dev "$host_id" --caps="$caps" 2>&1)"; then + printf '%s\n' "$output" | tail -n 1 + return 0 + fi + + echo "==> Waiting for Flux dev JWT key for ${host_id} (${attempt}/${attempts})..." >&2 + printf '%s\n' "$output" | tail -n 3 | sed 's/^/[coolify] /' >&2 + sleep 2 + done + + echo "ERROR: Could not mint Flux dev host JWT for ${host_id}." >&2 + return 1 +} + +setup_wireguard_mesh() { + local count="$1" + + if [ "$count" -lt 2 ]; then + return + fi + + echo "==> Configuring WireGuard mesh for ${count} coold VMs..." + + local pub1 pub2 ip1 ip2 port1 port2 subnet1 subnet2 + pub1="$(coold_vm 1 wg-public-key)" + pub2="$(coold_vm 2 wg-public-key)" + ip1="$(coold_vm_wg_ip 1)" + ip2="$(coold_vm_wg_ip 2)" + port1="$(coold_vm_wg_port 1)" + port2="$(coold_vm_wg_port 2)" + subnet1="$(coold_vm_container_subnet 1)" + subnet2="$(coold_vm_container_subnet 2)" + + coold_vm 1 setup-wireguard "$ip1" "$ip2" "host.lima.internal" "$pub2" "$port1" "$port2" "$subnet2" + coold_vm 2 setup-wireguard "$ip2" "$ip1" "host.lima.internal" "$pub1" "$port2" "$port1" "$subnet1" +} + +follow_logs() { + local coold_vm_enabled="$1" + local count + local vm_logs_pids="" + count="$(coold_vm_count)" + + echo "==> Following dev logs. Press Ctrl-C to stop the dev environment." + + cleanup_logs() { + for pid in $vm_logs_pids; do + kill "$pid" >/dev/null 2>&1 || true + done + } + + stop_from_signal() { + trap - INT TERM EXIT + cleanup_logs + echo + echo "==> Ctrl-C received; stopping dev environment..." + down + exit 130 + } + + trap cleanup_logs EXIT + trap stop_from_signal INT TERM + + if [ "$coold_vm_enabled" != "false" ]; then + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + coold_vm "$index" logs-agent | sed "s/^/[${instance}] /" & + vm_logs_pids="$vm_logs_pids $!" + done + fi + + spin logs -f +} + +up() { + local coold_vm_enabled + local follow_dev_logs + local count + coold_vm_enabled="$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)" + follow_dev_logs="$(read_coolify_env COOLIFY_DEV_FOLLOW_LOGS true)" + count="$(coold_vm_count)" + + if [ "$coold_vm_enabled" != "false" ]; then + echo "==> Starting ${count} Coolify coold VM(s) before Spin..." + for index in $(seq 1 "$count"); do + coold_vm "$index" up + done + setup_wireguard_mesh "$count" + else + echo "==> COOLIFY_COOLD_VM_ENABLED=false; skipping coold VM." + fi + + echo "==> Starting Coolify Docker stack with Spin..." + spin up -d "$@" + + if [ "$coold_vm_enabled" != "false" ]; then + for index in $(seq 1 "$count"); do + host_id="$(coold_vm_instance "$index")" + echo "==> Minting Flux dev host JWT for ${host_id}..." + host_jwt="$(mint_host_jwt_for_host "$host_id")" + echo "==> Installing host JWT into ${host_id}..." + coold_vm "$index" install-host-jwt "$host_jwt" + done + + for index in $(seq 1 "$count"); do + echo "==> Starting coold VM agent service on $(coold_vm_instance "$index")..." + if [ "$count" -ge 2 ]; then + peer_index=1 + if [ "$index" = "1" ]; then + peer_index=2 + fi + COOLIFY_COOLD_VM_WG_PEER_IP="$(coold_vm_wg_ip "$peer_index")" coold_vm "$index" start-agent + else + coold_vm "$index" start-agent + fi + done + fi + + if [ "$follow_dev_logs" = "false" ]; then + echo "==> Dev environment is ready. Use 'spin logs -f' or 'scripts/coold-vm.sh logs-agent' to follow logs." + return + fi + + follow_logs "$coold_vm_enabled" +} + +down() { + local coold_vm_enabled + local stop_coold_vm + coold_vm_enabled="$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)" + stop_coold_vm="$(read_coolify_env COOLIFY_COOLD_VM_STOP_ON_DOWN false)" + + if [ "$coold_vm_enabled" != "false" ]; then + for index in $(seq 1 "$(coold_vm_count)"); do + echo "==> Stopping coold VM agent service on $(coold_vm_instance "$index")..." + coold_vm "$index" stop-agent || true + done + fi + + echo "==> Stopping Coolify Docker stack with Spin..." + spin down "$@" + + if [ "$stop_coold_vm" = "true" ]; then + echo "==> Stopping Coolify coold VM..." + for index in $(seq 1 "$(coold_vm_count)"); do + coold_vm "$index" stop + done + fi +} + +corrosion_for_each_vm() { + local label="$1" + shift + local count + local script + count="$(coold_vm_count)" + script="$(cat)" + + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + echo "--- ${instance}: ${label} ---" + printf '%s\n' "$script" | COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell "$@" + done +} + +corrosion_check() { + local count + count="$(coold_vm_count)" + + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + peer_index=1 + if [ "$index" = "1" ]; then + peer_index=2 + fi + peer_ip="$(coold_vm_wg_ip "$peer_index")" + + echo "--- ${instance}: check ---" + COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell </dev/null 2>&1 && echo active || echo unavailable +printf 'peer ping (${peer_ip}): ' +ping -c 1 -W 2 ${peer_ip} >/dev/null 2>&1 && echo ok || echo failed +printf 'gossip: ' +awk '/^\[gossip\]/{section=1; next} /^\[/{section=0} section && /^addr =|^bootstrap =/ {printf "%s ", \$0} END {print ""}' /etc/corrosion/config.toml +printf 'registered containers: ' +sudo sqlite3 /var/lib/corrosion/corrosion.db 'select count(*) from service_endpoints;' 2>/dev/null || echo unavailable +SH + done +} + +corrosion_containers() { + corrosion_for_each_vm containers <<'SH' +echo '[corrosion service_endpoints]' +sudo sqlite3 -header -column /var/lib/corrosion/corrosion.db \ + 'select container_id, container_name, namespace, host_mgmt_ip, container_ip, state, health, updated_at from service_endpoints order by updated_at desc;' 2>/dev/null \ + || echo 'service_endpoints table unavailable' + +echo +echo '[rootful podman]' +sudo podman ps --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}' 2>/dev/null \ + || echo 'rootful podman unavailable' + +echo +echo '[rootless podman]' +podman ps --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}' 2>/dev/null \ + || echo 'rootless podman unavailable' +SH +} + +corrosion_config() { + corrosion_for_each_vm config <<'SH' +sudo cat /etc/corrosion/config.toml +SH +} + +corrosion_logs() { + local index="${1:-1}" + coold_vm "$index" logs-agent +} + +corrosion_sql() { + local query="$*" + + if [ -z "$query" ]; then + echo "Usage: scripts/dev.sh corrosion sql " >&2 + exit 1 + fi + + corrosion_for_each_vm sql < + +Commands: + check Show Corrosion service, WireGuard, gossip, and row-count state + containers List registered service_endpoints rows on each VM + config Print /etc/corrosion/config.toml from each VM + logs [n] Follow coold/corrosion logs for VM n (default: 1) + sql Run a read-only sqlite query against each Corrosion DB +USAGE + ;; + *) + echo "unknown corrosion command: $command" >&2 + echo "Run: scripts/dev.sh corrosion help" >&2 + exit 1 + ;; + esac +} + +example_nginx_name() { + local index="$1" + + if [ "$index" = "1" ]; then + printf '%s\n' coolify-example-nginx + return + fi + + printf 'coolify-example-nginx-%s\n' "$index" +} + +example_nginx_up() { + local count + count="$(coold_vm_count)" + + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + name="$(example_nginx_name "$index")" + gateway="$(coold_vm_container_gateway "$index")" + + echo "--- ${instance}: starting ${name} with coold DNS (${gateway}) ---" + COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell </dev/null 2>&1 || true +sudo podman run -d \\ + --name ${name} \\ + --network coolify-default-mesh \\ + --dns ${gateway} \\ + --dns-search default.coolify.internal \\ + docker.io/library/nginx:alpine +SH + done +} + +example_nginx_down() { + local count + count="$(coold_vm_count)" + + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + name="$(example_nginx_name "$index")" + + echo "--- ${instance}: removing ${name} ---" + COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell </dev/null 2>&1 || true +SH + done +} + +example_nginx_check_dns() { + COOLIFY_COOLD_LIMA_INSTANCE="$(coold_vm_instance 1)" scripts/coold-vm.sh shell <<'SH' +set -e +echo '--- resolv.conf ---' +sudo podman exec coolify-example-nginx cat /etc/resolv.conf +echo +echo '--- coold DNS lookup through search domain ---' +sudo podman exec coolify-example-nginx nslookup coolify-example-nginx-2 +echo +echo '--- coold DNS lookup by full name ---' +sudo podman exec coolify-example-nginx nslookup coolify-example-nginx-2.default.coolify.internal +SH +} + +example_nginx_help() { + cat <<'USAGE' +Usage: scripts/dev.sh example-nginx + +Commands: + up Start one nginx container on each coold VM with coold DNS configured + down Remove the example nginx containers + check-dns Verify host 1 nginx can resolve host 2 nginx through coold DNS +USAGE +} + +example_nginx() { + local command="${1:-help}" + if [ $# -gt 0 ]; then + shift + fi + + case "$command" in + up) + example_nginx_up + ;; + down) + example_nginx_down + ;; + check-dns) + example_nginx_check_dns + ;; + -h|--help|help) + example_nginx_help + ;; + *) + echo "unknown example-nginx command: $command" >&2 + echo "Run: scripts/dev.sh example-nginx help" >&2 + exit 1 + ;; + esac +} + +firewall_help() { + cat <<'USAGE' +Usage: scripts/dev.sh firewall + +Commands: + allow [proto] [port] Allow traffic on every coold VM (proto/port optional) + revoke [id|src] [dst] [proto] [port] + Remove an allow rule from every coold VM + list List allow rules on every coold VM + reconcile Re-apply firewall snapshot on every coold VM + +Examples: + scripts/dev.sh firewall allow 10.210.0.2 10.210.1.2 tcp 80 + scripts/dev.sh firewall revoke + scripts/dev.sh firewall revoke 10.210.0.2 10.210.1.2 tcp 80 + scripts/dev.sh firewall revoke 3ba6e0c235a6 + scripts/dev.sh firewall list +USAGE +} + +firewall_api_for_each_vm() { + local label="$1" + local method="$2" + local path="$3" + local body="${4:-}" + local count + count="$(coold_vm_count)" + + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + api_ip="$(coold_vm_wg_ip "$index")" + echo "--- ${instance}: ${label} ---" + COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell <&2 + exit 1 + fi + + if [ -n "$port" ] && [ -z "$proto" ]; then + echo "ERROR: port requires proto (tcp or udp)." >&2 + exit 1 + fi + + body="$(printf '{"namespace":"default","src":"%s","dst":"%s"' "$src" "$dst")" + if [ -n "$proto" ]; then + body="${body}$(printf ',"proto":"%s"' "$proto")" + fi + if [ -n "$port" ]; then + body="${body}$(printf ',"port":%s' "$port")" + fi + body="${body}}" + + firewall_api_for_each_vm "allow ${src} -> ${dst}" POST /api/v1/firewall/allow "$body" +} + +firewall_rule_id() { + local src="$1" + local dst="$2" + local proto="${3:-}" + local port="${4:-0}" + + if [ -z "$proto" ]; then + port=0 + fi + + printf 'default|%s|%s|%s|%s' "$src" "$dst" "$proto" "$port" \ + | shasum -a 256 \ + | awk '{print substr($1, 1, 12)}' +} + +firewall_revoke() { + local id_or_src="${1:-}" + local dst="${2:-}" + local proto="${3:-}" + local port="${4:-}" + local id + + if [ -z "$id_or_src" ]; then + echo "Current firewall allow rule IDs:" + firewall_list + echo + echo "Revoke one with: scripts/dev.sh firewall revoke " + return + fi + + if [ -z "$dst" ]; then + id="$id_or_src" + else + id="$(firewall_rule_id "$id_or_src" "$dst" "$proto" "$port")" + fi + + firewall_api_for_each_vm "revoke ${id}" DELETE "/api/v1/firewall/allow/${id}" +} + +firewall_list() { + firewall_api_for_each_vm list GET '/api/v1/firewall/allow?namespace=default' +} + +firewall_reconcile() { + firewall_api_for_each_vm reconcile POST /api/v1/firewall/reconcile +} + +firewall() { + local command="${1:-help}" + if [ $# -gt 0 ]; then + shift + fi + + case "$command" in + allow) + firewall_allow "$@" + ;; + revoke|remove|delete|deny) + firewall_revoke "$@" + ;; + list) + firewall_list + ;; + reconcile) + firewall_reconcile + ;; + -h|--help|help) + firewall_help + ;; + *) + echo "unknown firewall command: $command" >&2 + echo "Run: scripts/dev.sh firewall help" >&2 + exit 1 + ;; + esac +} + +usage() { + cat <<'USAGE' +Usage: scripts/dev.sh [spin args] + +Commands: + up Start the coold VM, Spin stack, and dev coold agent + down Stop the dev coold agent and Spin stack + shell [n] Open a shell inside coold VM n (default: 1) + list Show Lima instances + corrosion Inspect Corrosion state, config, logs, and registered containers + firewall Manage dev coold firewall allow rules + example-nginx Start/check example nginx containers with coold DNS +USAGE +} + +cmd="${1:-}" +if [ $# -gt 0 ]; then + shift +fi + +case "$cmd" in + up) + up "$@" + ;; + down) + down "$@" + ;; + shell) + coold_vm "${1:-1}" shell + ;; + list) + limactl list + ;; + corrosion) + corrosion "$@" + ;; + firewall) + firewall "$@" + ;; + example-nginx) + example_nginx "$@" + ;; + -h|--help|help|"") + usage + ;; + *) + echo "unknown command: $cmd" >&2 + usage >&2 + exit 1 + ;; +esac diff --git a/tests/Feature/DevEnvironmentExampleTest.php b/tests/Feature/DevEnvironmentExampleTest.php new file mode 100644 index 000000000..d5f2320cd --- /dev/null +++ b/tests/Feature/DevEnvironmentExampleTest.php @@ -0,0 +1,31 @@ +not->toContain($variable.'='); +})->with([ + 'coold package version default' => 'COOLIFY_COOLD_VERSION', + 'flux package version default' => 'COOLIFY_FLUX_VERSION', + 'corrosion package version default' => 'COOLIFY_CORROSION_VERSION', + 'coold VM count default' => 'COOLIFY_COOLD_VM_COUNT', + 'coold VM flux URL default' => 'COOLIFY_COOLD_VM_FLUX_URL', + 'coold VM WireGuard IP 1 default' => 'COOLIFY_COOLD_VM_WG_IP_1', + 'coold VM WireGuard IP 2 default' => 'COOLIFY_COOLD_VM_WG_IP_2', + 'coold VM WireGuard port 1 default' => 'COOLIFY_COOLD_VM_WG_PORT_1', + 'coold VM WireGuard port 2 default' => 'COOLIFY_COOLD_VM_WG_PORT_2', + 'coold VM builder capacity default' => 'COOLIFY_COOLD_VM_BUILDER_CAPACITY', + 'coold VM enabled default' => 'COOLIFY_COOLD_VM_ENABLED', + 'coold VM stop on down default' => 'COOLIFY_COOLD_VM_STOP_ON_DOWN', + 'dev follow logs default' => 'COOLIFY_DEV_FOLLOW_LOGS', +]); + +it('defaults coold dev VM settings in Laravel config', function () { + expect(config('coold.dev_host_count'))->toBe(2) + ->and(config('coold.dev_host_id'))->toBe('coolify-coold-dev') + ->and(config('coold.dev_host_id_2'))->toBe('coolify-coold-dev-2') + ->and(config('coold.dev_wireguard_ip_1'))->toBe('100.64.0.10') + ->and(config('coold.dev_wireguard_ip_2'))->toBe('100.64.0.11') + ->and(config('coold.dev_builder_capacity'))->toBe(2) + ->and(config('coold.dev_builder_enabled'))->toBeTrue(); +}); diff --git a/tests/Feature/FluxDevCommandTest.php b/tests/Feature/FluxDevCommandTest.php new file mode 100644 index 000000000..6c9a3c810 --- /dev/null +++ b/tests/Feature/FluxDevCommandTest.php @@ -0,0 +1,65 @@ + 'coold-dev', + '--caps' => 'coold,builder', + '--ttl' => '600', + ]); + + expect($exitCode)->toBe(0); + + $token = trim(Artisan::output()); + $claims = JWT::decode($token, new Key(file_get_contents($publicKeyPath), 'ES256')); + + expect($claims->sub)->toBe('coold-dev') + ->and($claims->aud)->toBe('coold') + ->and($claims->caps)->toBe(['coold', 'builder']) + ->and($claims->exp)->toBeGreaterThan(time()); +}); + +it('writes the host jwt to an output path with owner-only permissions', function () { + [$privateKeyPath] = createFluxJwtKeypair(); + $outputPath = storage_path('framework/testing/host-jwt'); + + Config::set('flux.jwt_private_key_path', $privateKeyPath); + + $exitCode = Artisan::call('flux:dev', [ + 'host_id' => 'coold-dev', + '--output' => $outputPath, + ]); + + expect($exitCode)->toBe(0); + + expect($outputPath)->toBeFile() + ->and(substr(sprintf('%o', fileperms($outputPath)), -4))->toBe('0600'); +}); + +/** + * @return array{0: string, 1: string} + */ +function createFluxJwtKeypair(): array +{ + $directory = storage_path('framework/testing/flux-keys-'.bin2hex(random_bytes(4))); + mkdir($directory, 0777, true); + + $privateKeyPath = $directory.'/jwt.priv'; + $publicKeyPath = $directory.'/jwt.pub'; + + exec('openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out '.escapeshellarg($privateKeyPath), $output, $exitCode); + expect($exitCode)->toBe(0); + + exec('openssl pkey -in '.escapeshellarg($privateKeyPath).' -pubout -out '.escapeshellarg($publicKeyPath), $output, $exitCode); + expect($exitCode)->toBe(0); + + return [$privateKeyPath, $publicKeyPath]; +} diff --git a/tests/Feature/V5/HomeTest.php b/tests/Feature/V5/HomeTest.php index c37b47496..d4b4b96dc 100644 --- a/tests/Feature/V5/HomeTest.php +++ b/tests/Feature/V5/HomeTest.php @@ -105,6 +105,12 @@ it('serves the v5 inertia shell', function () { ->assertSee('v5-ready', false) ->assertSee('Running') ->assertSee('Flux is running.') + ->assertSee('coolify-coold-dev') + ->assertSee('coolify-coold-dev-2') + ->assertSee('100.64.0.10') + ->assertSee('100.64.0.11') + ->assertSee('builder') + ->assertSee('builderCapacity') ->assertSee('V5 Shared Team') ->assertSee('Shared team details') ->assertSee('owner') From d92c6a8dabf85f25996f7ab0f0fd4257e23b3526 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:33:26 +0200 Subject: [PATCH 005/178] feat(dev): bootstrap coold VMs via cooldctl --- .dev/bin/cooldctl | Bin 0 -> 16026008 bytes dev/coold-dev.md | 182 ++++++++++++++++++++++ dev/lima/coold.yaml | 74 +-------- scripts/coold-vm.sh | 15 +- scripts/dev.sh | 367 ++++++++++++++++++++++++++++++++++++++------ 5 files changed, 515 insertions(+), 123 deletions(-) create mode 100755 .dev/bin/cooldctl create mode 100644 dev/coold-dev.md diff --git a/.dev/bin/cooldctl b/.dev/bin/cooldctl new file mode 100755 index 0000000000000000000000000000000000000000..57a106667956481b345b857cbf21e4e50ce0ee1a GIT binary patch literal 16026008 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 nDzXJ{J$5u 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

`P&eraIdACOJe2YG{#F|#pWHe)bQbPa5& z-hqdnfNyNxEuD>=%RD@fK)?70Y~1&MFKK<_+e_u}6AY&M3-0TWzRCNHjc_A*YrF8q zd@S52_Jj6CE)vCluWyHTtuv~Bg5Na$%SN`MecE4;H@>}*v&ln~^hxAsnb6OAPRRo_ z)Uux-ZyuL}1IxjIBBx#)m@8wP)_?;yGr#Qg)UVE}P~UE_Aaz!x5BBG!4=&70kNEP+ z!GfoP1kie{l)7J|n=+>Ptc4ok zL0b>~JrmHw6V3Wp+ebo0+!0C*HI5Fs*4lJXFdxqlX`E zXj%`y6uTQo4>wC$haUa~zO_gX9XtsNzimBCLl5VpgV*yD)OvWcM-K}JSb8{aK;ESH z;_IPWH?}|zZ~RY#9&Raf>tWu;pGOZ5f4^ki+qVfF z{9MX9bnsoUax5KG^)eTxms4-K)T{j-_FU-T$^F7>(ZR>Sn`^+DPxJGv#+&QCc=KS5 zHxJJH;GH=72mf!9HK$Ym((@CV2OoH`LH}x3y7h0$hF0hwG$lF@ZpW^~od=Pt=scL3 z-{d@4A@nz;f7Ioj2mdJJ>(IZ6jBm60HSs46%H`#7x|g*x|jid|FM&;YkWKZj`(Z3ONCFd z{31hAo5Ym;}`kxL1@1H~-WJez{!c`f)EvgQf6`t&9Qmm5%c&nWj+_f(Mh@f*llmRB ze#_r7_mxPwX6CTdg||(t=Vr=UA`XrmEoB{Z*e77&SaXB=BPV-sWMx0Sp6i$Q^|m2zO=CQLG<7Vfvq}Ov@TsrvBdP@g$ zXv?0*zC8#$GWJspecvFm0)9=l*1skG^XlYn z650P)C+{duvcA_&lC^b8mAv0po+ZE8|B*c))~_;$yWXIm$R5rdD<;fx^4?E5i3!8G z<|Qji+MBb3J&RRL6zG+hTyq4!OlXJ;Q$0c2IT zO^O!->z4kVvAbFC$K9M?5w_1kN}e(JB^+l7)m~SyPu*GY2cHi94r6b)_kI2NeWE%` zNK70%o(N|Nmy9*i%oQ?D&~v5m1OJLXOSr@!Z5e6RBe`cpUFv+~9ac;%sayOk(l+!w zDZ1rtPsOpx@w7KH&AgR5RbDxFFv5TrgX*Gfl75Y(kDz`qh^v0SIs0=EZC2xdaP?!Im*oRVQ$YuQeKI5EdJLH=w`G$!s^r@5BO`M-xV(|SLzW<$dhr|Oa51wCF z3npn4vxhV%E#8JJw`m|PLFGPL&=bu~tHe68+t_R0RpTe9vH zc_3{YX(jBfZ=}y+mliR{3x1fx_hjwY?Aj#km%d}X>w(zzYbNi59tit&&JAw+brP62 z5&LzW*x4BN>oSp%18BdlQsZ-8-2mZ-$9`Qxn$v!rS=@U2HHA8rEXui8v0qME#D1M7 z>8-F|1-kxp&b~HfzmAc7!y4PKzwo`S?AIV^1HBDMU&VeoZFOeA>>}x{uwU(U{mOpL zi*LWa`In|60sFO=yixmw4vGB=fSIE90{c}>96#iO%NG5fcEQTH9qIneaoASUi+0pn$vy-mbTu04W&-Y zesM1)hW+X%>8-F|-E{rw+)Zi9ei@Q4hW)yL?`>tjK7Wojl>MTwG3?hzlHLmYwN2Nr z>{s9T_UlEPjs)!2M)Ee;uRh9t{Rjqd+ONmSBlhb7lD$~Hnd+m>94FG$1iZ(uQ$bSkbwPKAIE<65*axF_DhYOk!JQ%<8xkJio<@Xu_G;w zG^hQ#+HAS~Qtg4SBF}1B^l>l4VZT(Hr0qk{*C}5i8joL4CNbuJZWK-;ys*gMi$s_jbcefu{`=w|CU;S3- z7yDJs*?WimQuL5MP10Lozs{k2)P7x;qSlY9ZtT}7q>24HR`dk>RZF~O!Cy7cByYc- z+?kC1>aOrt;qut_>vP^{JP`Klu0Of$*Bx&qX1}J0osEIN_G2>+r2X2-IEepimGDEa zAJy0yY3AFcIqlcXC9St#FH@(IMIW*l!+t#@>8-F|kL&u=xeL;i{VI`sG3?j(d~YlJ z^*3ol*)RGU!+u>a>8-F|f7JCW`!y@R{kk|xNAvb;7I_=&S9fK<%8*T`{W^<0V!zH4 z**t*$FWY{N68e?>A}(qS`*oD0x59oMO8Kb$n&!4&2a_iD%O`dW`!)P;mi<~&k-YtS zfjbz9`|qu{f4;ddw*7iT-ugQL`0L--x$W2NHxsj8`$}TluZ`G@18KjWWE{kP{Z07c zv0p1mbK0-6+gfkG?xap7i*iphhW+}Bq_@I;E!6d=b62w|`}O}MUkv;83g6qxeodD) z#C}O%W7w~WlHLmYb&9TE*{^cmKaGRGPO#}{V*P02uVcv@wO_u@%6=UR25{Q1!Q>J9 z)lX#eXRu$LgnqGKgW+Qg`?Y@^>8-F|UsFD6zgGBM`0EqW#C}ylgV?X78h-`(p6vQ@ z9QR)mwqH6HVaGW3>tWupJP`J)>$PtC^^2{E*{?nSjBUTJ$7UQL`?W>(A8%6Qb6(x0 z!jA^~wMF(H=aS~MU&s8dRrYJk*qLeOWz?x;QQ|1L?HBJyrddut=?@FhcXX*OW z&HQ-wYm4kN=1V@e{ZilW;(Hs|uPtLU1Lo1vhS)FZtJ{8UF-Xsl^p@E#;sONBgLVDN zewpl(Hnv~H0SK6>HXTjdFXAo)Odolp_6r@7_2V(jt=fKZ_dj6necG~L?;sBc*nSbO zA>DkR_LR)bf{$+dwZ$O)bxCiT{oRQ< z|Ch2~=c@5Judb``!(+e3k><2t;lH-te&tc8l0_eJj$+uaBP6{Q_G_@NKb=@daqyS2 zQ(Yxr4EyyPzPFYA`spd!5c?&4jbXpOkn~pAuTOOS%6<)wiNBQndMiptlj}!izpBU^ zwO{Cv*srgVO{e|ZNFKpo8y5dO_UmDxU#%aBsTjk4-7D#>uwTWLkJ_(+QT(Os*Plrf z`}KR|LhRSodi|KicUO!A`yN51^$tRLko#jl*v=A~nns+_rOtYLDlk`)tq1W!E ziB7zSyvUk5(}HZt+hAqfHoQ{|zahq3>mt`l=T5F06I; z-`x*YZwB@HeAHQxmpvNZaqdpWUfsQO@aWINBN=;Wk+W{Kb2+D}@BOIrPjdGsIHj&O zN8i26;?B=#?%oX)OJ;uSLf<0-S7F7 z_@~xwLFPh1pLv&-!5g0R$Y8LmI!kZM-1<5Fa>Jz^8e}fhk~y)#QJEtyMJU)1f8aPR zb8GiFWRCRmzxax;^z>Wqw}{M@+)ZBB+4sa`?sh5XlvU0XTJaqkWbR~<8P4~LoGL!b zJ8nh9Z73pc17{RFiGKs!Ch684$Od^kQOdGD6ul`y-ZrB**4bdUyoEXY6^#W^Bs@db zIRB+&&B2>J!hgdV5ZTf)SIxH& z^0h_FmXxgzc6FU`6`2~TWopSH%P;oXT8~WGcCFBQ!zs31%WIIa_beGJq28#B4dD)P zWy2lfJEcwf^U-dHjFF!9*Z6j=mseI2v}+FLpDTpwYscS??(77vh4oz@xHd>S(+jS> zEPd+%*DQVO!?g*F2Rn>wKHfYe-gvk+hqFW{^J82vxTcszeq3uWba3sB!m5Awfolgs z=Z@gocY44zbDlo~*Zy{fqgw{oGGd-fr}A8#8UUt9r+)Q72CfCCbu(6uOX<{|j!u1( za*{Y!$@$M<>ip-Ku1;<3@ZlKg#aH$`Rz7jt&goQ(zUxD$zWvMIb?R-+MSIYxv-Pb{ zr@pj&XLKsXn^M0{-NzYF_bjNt?Kc zOy^=Vbn2cootn1YSa}|}B%G?a%F(I)GIgqT{PsFkJ}RYCUvqToFO-wiDbA!vYf|SN zpHm&+)Uke@B7Nl5J?qqjoz$t(S?JX3YkJqIg}va^3;NclQ{TL1Cv?ikn`^}z52s!P zqujHPMyGWC(XUhGoO_f`jU80=&pveOBk0@_oqDgcd!0J18=dMr-G@`HQDzde&SagUHFaL{Zq)~7{p$^%evw{CfA49XV&6CFzrO@)*evc&I0(DhvRF^x?4)yk za71ThIkIri3^s8du_-dFGlY*{MZkJcK76IRC;lsk+ZDNWC&h?i#Xd6k%@4GHL7mDU z^6l9u_I_jJi@bC0Q!sh0Lc89}%Q?3u;#Zox4uYduGjr-{O8FD6vBTx%`OEe+XYVL)lQC z)28#D*Xj)PLMvg;qPgF^qi;yx8$Po>$C^RDNg)SOW}*@6aVeK3A9Ixz>D{pb65=jZDn+8&#ucRs$ZFSL(@KAl$$9Zd|> znJUw%^HkM2+c~Rg+E3oks4e(`IP2w{lbgoc%HN^6#-S}%!+OTFa3Y7cOvY{z9_Xhw z9HsK6xNYFPr)h)MVO$JRtPbrpq_u%}{x%qYP}Ww`+ECix9td4g_!Xzz63*7WdNumE z&}wnl!`E2k*|vsuF7%xrRQ?H0eH+o8Lg>_b`4H*y9IIsl&vEkj>o;dG>3?bU*Y&sG zQrXI@vxAJs-Wg28H`4#6bk+^EzmV2G-ucTnX9rmiPAfm!-~K;+4{aUPp|gW8&|gj2 zq&=ZDV(8L_O7YsP!TZic>Kw4v$fn7T1d~U4d3=4&@Rjn@>J1ODe?{3b@rg8xbDEOt zqhNcIujILhJgV2L=K$5i{6*(o6^mAUsR&q!PH5KJpA|qyShsVqV^rsbk`?x+q1}JJ zlkq;zoWSLmIp5j9S?O&{Pvv~)+-9)KIp0Y>KM#$Jz;It%IDa|7zCwIbUhqR_IJI`} zwu3X61MG{Go==^@WS!2LW8V48H!=!lly42R&(Zg_$cQ>BI47&~oydqY&I9c;NVE89 zk75?OnhnnW4nAk%>`d{hcbr|3fwSCCKF~gey0gGp&T1FhM|gShM@r%>IMWTz(zZf- ztn&Abv(Qm!mwRR7chv*Vt`N=+A)g;-&(Pe!hqF)Vyn6~~%{Mpe8*t`9?B$+u*75gC z{IGkReMse|;ViyH24_c`eVCoZ*%dR^7uv7ghkgiW?>1Q37lOqBii3ys_(%%gR`{H#n}}W zY2Q#<7C8HY#_;TMcEt=ZbOB|jaCV@<*%K%ysT1V+0(ty6`@gDZ2XJ<>`28v1?0E6X z;4FG4oMn7Zwga3Usq|gI*&+Jg!&&?p{WzOT+E0Js;Osy6KO3CA5I$z&?A9xH4rl*O z-Pz)7G?}*`E1dnK@@I*&zxT?<)XI3(A?Ga~P zzn&-RyT{ott6V?M>K?}3gtOnLO$KMVhtZF-N4qfwlDY`aUZVDU_AE3DXDeUp9%t{o zIUQ#YRe64#RU38_&d!6bB+laNFh}~BvS$s>9;0? z1)MF@_a4sDK0nSDD=iD0y$X5kD9#2cJBhQ%TlVaMl#|p6aCYm@({c73)w2UQ``Q(s z4$eLcod##+x6}>JZczFz;Ots`@8K+dOMaYPP1{ZFU#aZF(1d^o!xC-Grqdz^inJlWuEp>%l%arRY}ZE%)0b%V3dDt#Al z_6dFO;VkX*<7|u4vcTEBG*{X|d$yUfQ#d=s;Oslt0)CvmjXZvP_Mfs9b^vErNLHVq zJ^QGM8!*8BAMweoG2qMK!`byFcEAApOr`Gx&YJSIHlXi4oaKC>aMqMf+6kn+cdvu9 zN6?3|!P$G@VHEC{hiSjcYPL`g|p|zy2shS zGG_R3cCpIy%G!Xw_i&c>31>~&q%Blh7C76YF+5A0HT7bv&Y|oi z&LVHwvtOf}q)w1$8hQLUyHfS+0L~5(zdr?>9VI>qXEz|DZg6&>(su!8bM?K4v%~@O z{H=d;#3!MG3zTH8bouIOXvuaZ}I6F$|yMVLB`rgA?+ULjF zJf&rUvlnO#-$9)HSF;aik+*Pmf67Vf1UUOTdHgs#Pxb5o&i=OU)4|zCq0`{(GGx>Z z&OV^@UBKDZ`rgA?+c{@wbPs#>PSTF#C!D{pdPOPpQol}-G*-f;E=^7(OgeQP?-UMnB044nOwz5!>0-|GcumpO40r{CB; z&R(Q){W#l5Ot#&Gv-?4x!P#Ny_Ux&u(_J?(`U1`lR$Dxrg=XRGV}I)&XOBZq{5X4* z%Jbu_+OV5&_T45Q&Js)R<;%Cn*%*1U!P&i}%R7j(Z7SQ?v$UxjoPAX3yMVJT`rgA? z+ULjFdzF?2&JIEzJBqV+P|5T_a4p?7t*z7pOwGC4ANe^$HCdp(1)_Y*&oBl zOnbIOyy_iipUqe|ApXHXdouNBfwQ!OwZUZGp?%>jZ7a0=3po3}zV~pJ_?3Q~jg$6$ zezIqugO09<)wXSEfO|$PTmHHh{<50S=3U=)%ik``so%DAI`K z%p0WKhqKK4Eal#oW!`r3)@PabcjWzfmU(03y&}uJx0CnE%)G7QZ%*?zc-VnISO+}T z9VZ?53F^5yQqp<;#;#koEuGQKxnGCRS$y;8vpfDx#qW0fn|06a_&1TKcl?`$f7tPF zj(Bp%zv+4`T)?mFgDc78Fj4^J>C)oJc=C8bcId=$Y%+bAhv5`7s zFotsnV>(&y#va(q{`O}m1K;6Tv6TptuZ#ape(*n5jJ}yWe{<4k?rIHy8U4Tv;sv0W zMn9paaqF1L1+kHKX<+@-Xe;~~R5vwrC38~7`FO2mkG|>STSB4*U*fmo!FmF43~dOO zxUoD+oLC<4FeYE)R~^3ofw7>2cNLTyjclm40(Dc>zKSb@+)ML$FezaA!?vGj%vjiY zH2J|Pr*F_E#R*Y-E6akWVBOSMaQ)O${hwdQZ~fHrQH{r!C>F zmQlcYj*xzViFRr1=tLmT*VidW^~B)uCghVG@APeu_#S*WZu;Ja@8VCg{+e9Qo($sb z$zaZ&AlZxQ@ge2-1YP-Ux*hG3vgIyR3qPY*YtUk84bXJlmb4PD!|^aT9S z=irB)Yh>EgK5udpbEO>W-^Tur&Nu(@?xFP`^M6{uiA*s4QgSx>FT8vzn20?SOsKDX zGuJY9R}{N)8#Z`+tojE(E3{=5=TTI@`i9cu+y^-84%x``L42r zG8HGIqATCzQ5gZw7eveVa{9k}epdVq`S@$>WcV75jIj+L#b3AI?(;5f$e>|~<zptac119U2eE=VTvErCSrZDK^VTK4rpR}VN3@>S^p@(yL{0dz%4kJoTN)i&{P zde3@5nMUsD!OOHY#<%8KdQcv)=b;-N(zWjNAmcsXIeNhRq#jU)(F5+-Q$G)ty8R3+ zxQh12g7mX|>J+``Ml>=A%(W7ilO~Lfp$nfQK4T^gJ?a5%j@A%6Vz5)sHz>#G0X*nd z4>IyECcn`G-hX)sdH{b0q6e=$?9&7KdEBoDJjZGVI(l$#AmP=0JY^X@Xf00H1Cu{R z<5A?>P7l0sG&p>FTsS*F5j!{E;KB?~AJBt`{@NEVRNALYAG$u@vp%5ro<7t{A2M*E zL;8@>C%rzE`97%+-QmKjQ4TJ+F=vDeIq<>5-4rfNF}Uy{W21))Go=q1H1wzs?Um?V zRT39EDCYp-0zBweA2Ra4LjDm37b@*Pp5@@eNhjpgFY@by`ix&63@#ku=)=tXBrZHj zSwx91X(YcPi?{9|<&Ux~*F@k%|W7G1CF7)^5!mPe@q4q%geqwfXJabf5 zy6|_}o2d);q92)Z*eP9TFLrdnJr6HkxSaNHrwhUHMi(w2&C`Yb-`N3Opv}?9*rYCe zjdBb&z=LjeAtV23B!hYgI_&Dh3o^`=DKK!2c zW@5sK-8DY64|OoXjpZXu_%=M)4ijn)Hkfb$X&xs0OS+Kl_&}SZHRJ8jAV(J#Q;r!Q z;6b;#kdgn3^fIsVwa%!9Fmd{4!Neb_5qAMWj!h~3xEj1lMh^x?sm`p}2=L+vZ157V-=7rN1h%fX9GS?tspv1){) z4{l5g>BIYXb)yfF!;L<#t1JSt90Ug_^=&DL?#=Z_&RBx zPSg=gE|Z3yZOFsW3D!p3`Q53MV{`%@bgvWX`Hv&NqZ5bO)vivQj86Refxa-J($R@G zQaVvZSxKFU4CzKEQgj|nUg?C^k~FSr?L_P0iNm@3Ok;&0yB}ftHCSv2E!r*4=X4y@eg8snw+^00w$AZEE<>()1ITrWvgD zcr^XyKTOjFE=}{WCq0^O{SVW0h)dI-eSEs$KTOkTm!>0q`gHt%n5OrB>GZol_+&Tk zKTOkKT$)b$b4s6bcPCB3Ao$e3d0Q*^1TJY`%B<&Wt{HOd{#xpbf-~CV(K=*ZlV$t^ zG{4OIOo084+09+Spo1-0ls6}%Jj++!>l1doyeS#wZM-K%UtlNb8=FzyIll6WcA~uE zjPeHf+WYQKw6|+zx;#pK^tJ3nd0R5dTkk9Hww);N#f-9xzxdnottbFwS<@E*!NriXIv zCE1l*(nGnEdMG#V?Ci=d=%L)vJ(PQXmgR2!arb(b-$S``vy|H_J(TKdz3m zuGxf*-&7lDyY@7E2f>Tn_pwR9l7`4j#y6rlGQYEcIj4nPA1GoCcoV-`7WxO^Aea7>nMIQbK3Ls_lUhV{GHhM&#NP7eEh0&O_%%T62a-MVYK z^gTVcgZ#e!X;7BMhWq)jRF-!Oo3h*nmD!-_G zUY-l4TXr*XSqlcTmN3U+eN`AV+=<;cC!E+Aw49iZwcCF%f2g^luS ziWc)XuWsrKTHBy*uf90-Rp1j0ekK%0Rr3_Zd6gfy<|8JqEoV=i__m`uL$SlnJvWM1 zxt!Ro!egxq>OLqvE1vFMCRW8D`=R?B-+W~uxzsBC6W{ES`Hsq5=Vw`;%|_;v`;z(f(!Eb!=6^qTkIZ+epEo-9S!E;h zM}E;qKR^7_k@;DBWWHslJu=_Le$JX$-*!9k z0S4K}_9gStpSa99Pe0i1JZDco{}lSUk@+9*{g3x^BlD$uWWHPcGT*g+K0PZN&h+yy^(FJ>PiH*O z-6Qi|llczx^S?Czcl7hCzrF|CKP_xO{l7%!g?nVaYyEr&u>IAhKKl8mgzeX#wWpu& zQa|62)xO#q&CkEwm&|Yb#K-eBnx7B$%e*G#>#lPi&ffW$&d^}(g*)*Q;`rHwhM8yM zub12}*ZZPyVwQJypXY)N?3d%CV~q$W0<1SQwOVaA9glw(X$`?wjL%PV@Qluma`vV1 z_wju3JIdK#X3uvV``C)TB)=ca_1U-Z*?(R8%Bs&tM~Ho8-80$6ez)0IW{=wM$8YjC zdV9*84IrP+L9(a3##%JketL;d_anNemOE;fjv&@nKVz30UdV?4|ABS*0IXvlziYl5 zOQpDOs+GHbs`l`s6QR}O?V{x_b$p_H2ZnXVBNq4I{;Aqx zufLhQV>?Rl3BYeb`JyBFUhxd3APf8eXrtkI1#KN7p9J>bO9D=Nw=JE=9{Q=o|LSM< z&~;B_bR;y5rHm<*aWZ@yi%)@K#+*!C1^l8WstnTP!=U?7)Dd~2+SGx+f$G@XEw7m}nkl1+ zGUT72JA73Jd^NGKb-$-%;`t>wd;j<+Xg>oTkY9rFPr%neF;ISo>@s{5OuxGB9v4f| z55>yajGuzeA>E6A!fMVLkJFw8?Uav#+Wi>iz_UH_{;!cYbD|xP_u#(d-3X5Ek@tUZ z|JHnH2jpG<(?0sQ);{*g`~Nrc-e-@z|KA?JH4oZ>{(a}&ef00N|9kN~=A3iP);|BqPx|QJ+LzuV@BdzTYmFnj{=Gu$92I@ZTk9NqZ5<}vCsdz*IVQ#z61UHkiO(CU-3Qt`@gq;%hzNFZkQge{5{Uhq?SlCvI|D?Cx&p+Ps_TvN=!J8(s6Vq$^D9 z)!oUjoBN<^QkHbxyqoFz-4}c3*T5|4$|d&P?&McPAN+dbhV1m~wB1bC(|z!3LzZ+^ z6PImw^6UTl;MW~l(sg@c_tG`D4}M*gC0(cNX1#y;l-~7zPL^~XNbL6ADaV0*$Z=ej zbX~EV`DOPZ$Dl`7MB`8%dwRaR8rWwv=Vez~RmXh5*>A=|@hrYFT-C%_v@icRuy3Th z6Nopk_TSojWKT)HdKz=QF^Rv-`#Y6+>uV_>|W@+FH1VV`>)+k=hh5jK9=!MQ}vZV98PoTg5F{2-S`2C*y`@$^gJnR$bM<-_JXIn3H9-gGrjXQ>~ zhPgusKMi7NRB7Hgj=vp@g}N8T+y}&bOz~a)chYd*NgH=3nb^Tywd1xlc6FW772MZ6 zcNB;1abFx{ci>ACU+Bctn^tC3O&iT`1ivDF!}ty4SHLg8FVCvdm|a0W-3t?%=fvK- z0(#>$qwMwL!Q7#h_F3eK5s&umQ91R68q?=9UYCWdLSd`&jes?@gXiehGSjAtLj!9& zHMX~M{|jZv_oysj4LN^Hz{JT_UQ;J@net03?Tx1V(CQ0|hSW##uZhhi)~#31=y27N zYOAuHGP|qClrg!|ZgR`0RT;A>V~*p`BU(G=;J-2(|CPDn#GCl+y!l8lv1MH_vAH#v z=y)QSD1nyfs~e_rHjGj-@E+%(Z@w8{*DM&%{t7gys;<# znlgxk&tI!`VALb%)&VhS&w9Nj_&i6-d=R44s^4 zRsO99o{I;jOms?RP9=77QeH*js^te+mCy9_t?2&Ifi^xx_PDaKcKnS2#8%;5V65HI zK0v-k_PE%AcKlWM{RZ;BJOJM{+S$PS7Y8JMdx}pM&=8Lt>9!|i-`>yhKQnSNX~cde zUH3b-Swjp@ViDdUYb!k1j^b+-I>FKV$HBxX{#J&b=~En@y7CcES0Ep)gCupBzEnDm zd%B`S>}$WmSdH&ik`DvJRU7xWDzEQ>578RxVXY)SyF78h0=~sJEr$P>%HKr%n%ET5 z;j_6naZY(+)5+zD66$kkBPP1|5uRe-;BRj-eXN^)XtMv^|D@CZ3}2*|d|wtOpZL%~ zU#(2>;R^T=!;dXq!yQoQ?u@fi?G~08-3CKqO7GA2`2BgRcS)uF)KoKGEi`CcCU|pxx%)Rc6|l%tx$t$*%4Idphzd^!f(x z%IZinda=J9otV;#j~U~l6VVINyI~(kCa!!Xla0t%`s<`~&zNXlzfV#Ji+sE+k^YFj z_2e^kac{(gR9)@V6`Md^k_WyIo}R5-;?_amFlC6|FzKcY;>v4Gb;q$yC00V?GJVCR zc|Ws8`x^1}bsyj+d_uX$0UE(*#@@%3mpP}QKTu`I@gJ4UJ0@B!!pPit=oN98Iwqno z;z8^nTWh6C`@&Yr9O)~Qm}Jp%EAdN}Sx%YI7b;_oc&wE$SpA)pE`NVHzPt;eWo+0< zTfvyiJ&)q)FX($+(8xG%>t5QA&V95=c7Y?iiS`SR71e(Ry?bss^%!|p*=@WV%e&~- z#fiODzuwbFzw<;_j$}TW5vI2fat3J z$UG&>g-$ypo5Ulmdr(#yKho+6mN@kwf5|{Nt9U(z@2-~)!>Dafj3oe~vD|Q?0PAF!y>{r>b9{xwm z2PDU#=cy}RGhAa3_rO=#*SKTQZ_g~M*Ij{e_)a{vs*Ocf}AWs}Dx|fm5lnR;w(@ zY1L$V@Qojv``Sg9#+MlH%r_P`9{t6u|3`eIJNTGCfG-2=&(C(pLB31c^YA35blC`C zoA>Pv;tB6UvArC=gj4r zn^-e(arjxQdUA3u67{};=iWCT!wb>7ZRtsjLnm@iu5+hq8ur#ynf}^bp3|ndjB#vQ zr`@{iHOKzne-5T!a;C+12WUKbt|JGXUO%-Xm}@iUf-A&woXvQ9Eq3u@_9x+Ebdr?_ z4RrA2CCO%D*qrHT3XT$nJzLf=#O_cW+jFg!VrUIBu7JhQmYp)$u5j;^ePi*Edc}w= z&Eq@-G6N42H;`B5Z+x<-ei{EaFkU!o)uWxY>T|;_U|XfyAB8?sSGd@IT6N8}S`K%= z7ZxejV-9#*zICwXvn@u(Cx=^ReVlK;kCzWMZ7KHpeEC4yJ=7ksPtfqU;~p2Ui!$&U znxpq7@%q^^<{ke#Fjzl~x?`pc>^875Dd$d|M9wFdkkfzEM`J+)`Lu&A9&jBx8>uQ zS07|w!x$_6bd2SWv;OIK<0i)`wR^(R-dJeb{axCvGchrhQ~Oy5BM)%LDf-&UYBzmk zlkl}1yN~{6m09)|ytdQlmLsb;cl3Gu`aEgtXt(aNm5e{UxL^HesUuStl=e^3M0ZzB zRT^gK9FR3|{nWz)qKSU;izi&3=v&>- z61=&(DRL@jf}C?iVd!j(eIxP9^gZxy!XnYD9|4dtEU&Wm% zk<&YG0=G)Wcoxx;tgIO)l6FArB)*Z|)BL}}O%47KTelbLhVFXI0u zItv2$QUr@T3-aVs!QTSXz>((QP$w-iw6o((>K(}YO1&S}86uC)i|Kro%8Mc!-6N~M z{XN}tURP}Y`KzuEhtgt~K9B8Z>fXfM*{magO=?T1;P9=GU~d(Enh#SuQ}K>M|6zt)Y-Ns>_RYr=P{jMf(N1@#<$`_ z)Z;_6*uL52Lx-Cdx~$+1^|vO@`5C%3zPT}Q4e!E3?S5Z%*KkOa?cYpH;U>-mnmV8{ z1mBW%Gz_&b^XhQZOdaTL6K4ob9mN@SSi|hMzT(vJI%(}L4X;7>PdIaUH)rmmujaUS z>yC8gGO}}1Fn4u`{?-p2ZvPwhd4KxGAcy~P@I>)?I~Kz4TKK+@I%QYWR}`n6@!afP z>W+K0SM;yHVrYFCe2bH}qgK2eMciV>7WD0IEK% zr`_?h)AgmJ2Knc+u6cGiF(F_j#^!Xy&Juq?~R?p8jBfMIN!Qtq|P&Pru1`8Ka(7Cki$gi7S;)W zv_4+(an~v0iT@spu2!A7Eu=lz5Nj=V!7Z}er2pRYDi;%_3(|4X;bFNqK00&mrSE0BHPWToO;>z(Ic)j^utJYM?re=GNuURfuuJZ;<3W8w4m_h@M>(7j%gnQ14q z8rs!P%54WXge5WB?6s|twp3WbEp}&T|vnrpV;B(3p7d|r558FI;VTbN;%_e?jBfW**6}Q<6su`ui8*#?tS&&IcEF> zYOwvt+q~HA8|1an#i##RRNo)kr591oHkS^=e~rFZaj2EhT7|zH+399of%ciaL*2ZG zSjqL@&(qFrOJ@>4+u`+P^xX#h+#W;!`f5`}NPQbUfzCU9ZTe;(ZMra{O}FjlHWg*G zX_nij6>1YU%C@Eb=rfKVhpOwdgwcU@#sgd&+UnRx9?o!(eL)1+dcYsQ{Ne4 z=>I%phvOS{j7z@_{b_c2WPrJ!ILeq2HMRibht^EpadF+&k&`PJmzwxH7@B2|#u!&* zlQ(UhKe;L2syu@K8yG*$*cWl;%&~I%H8$%3`o^^bj4cC3D;`1z<5HZlShkJk8@jhD z6m)GU#=;KXcQAIyHr5__Gx#cdNc2Q&S>Ix8@%HXsq)kzpoh?*BYPd@ycIE`R48f?$(*Ey2$gvx*}Yz zyM}N59{Lc`m{)*L95y913ro$I7jf>{X$l6~{%5}9M`+f__!fI;d;e@ORd?Y{AL`o2 zuC5%n((S*}73lB3(e1yUt}Jk|a|8V9ZtPP&;g@jsbT{w%6#uTKP1}|pgCCtU_WhPN zY3%FA`*d5;TAkDp$wu}SZIz9T4ZCK>`eF7-v@^{%q&?e~2C)a6HGlC&Wi+&oS^IPW z`}HHO7U`1sau4{sd7HJbd}nPTX>;X=TPiNhY4POrMbnNN#&AdHuXEe+ zCv-neM$oHyZ?Y{$-$!Eyj_w@x0`*|q#pn-)F7)*~(4{yZT90>he2kfQdb%>pp)EPT zm%S{zL~%%T7n9Z>JsscZ?k8+kKj6LYWm0?>*}mb%Tsu}Cu)V&~RU4@Kzaw1TCBH@b z2Rv(U)7YN8)1H;r{$Uw%lrP3?!-F$AZxRn$ePh0Bo2Bz$3_Nh`n4{hqoV3lVY5)G+ z$VK-{$u>Kc_M5&FtWCG{cwbg8b*##$BLIeG)^U4JbwniNbpKpS>q;&bS$VR*S5`}Qe}{Ih_sAwz z?3^g~`C7}CRXcR2{A#yb&!&H9yogD^)pwXjt-HV-C-|#9GBZA0Fn{vKfmY?&Mt9sb z)yODkO%)8)+N9PS^lg-JN_{ev=gd35EFLHiI!>RnzjVHfiM*5FFl#hFh-kJWz z+=RcME22KLM()nT4K|hTZNIq;xtP4{VIj*|0e1}^*@akxkGk_ytu5jsxyIs~KfB*Z zu1;G=ch1sy7#Y6y1ZdLyMr*KUZ1M7d6Ixqmop?PyLk50_bYtUxbBV?%jP z+cVPx^@>BJd8mUeE`N|qLwlgDiM5g1quez@zHf-UXzpcGf1~f(*B%q7*BtId=+yJo zJl|!;fQ<6=ZSW=HCf&yGFQ$xl$d|dE-w-^#b2WB1r;0W-#RwJNp`ah#U!%Y309 z_cyV=uX(a;2G<_wQxEpCDlh1+ozxQp1Cx5NiaEUWpueLBQI{5@2jv0#f%9BF5O!wj z0q?TWgRe`bCU5q7@Fn*fzaGT%r{Ax2y+1=!QV%FMnMZoCDy0YOS>Gv#2b$~0S?@*< z5@x)EpQp|an6>-8*FvtG~!Z?=(GyFa_5zkwwU{iQ{a!i(b^0{90qy=6JZ+g>{*;(qzSXWPGxO!6l z3F*m&uAaOLHpynzU9;*hX51Ez$c`LKpSPU;2(CY9>s(wm@!G(}5IC##efa~J zzp}Bwj4tqC0KCzdmdv9uiZsn(gcrG_3%~Wh!BEC&VT*Ss?jG7)-tH*hf<8On*wZDQ zS81QYogbJrWX9MHzBN>{-isatkx6>Y!ITY;EuWe{xaG1(_lcCdYrDxA6@% zzGwgZjMi+>ap}IN18qamvx0Pxf9z@KrPB%PwQ>eTDUAwH?CNa`&`W%&6Pje&F(S zJDWS!;eG0^cGDK>R^OTBwFUVm+v3?#{V%Z1ZN08jrP@Kwr{u1jpWZV2>Wj^_Z8#Mf=+8MTj$1wt&P~IdZ#t;x9LOX|Hzom zt7vy}o*`9>};eMX5d8jCR3(A}VQb=4-l z)@m_&$edWdf_m34MWIZ_KeOeX`BeD$nWVsb=-4$5|PTx6MF89fDzfVw>r@FFyN;(TBWh2WaJ0Q!jPnM6; z4$1OVSC$ucBg@0Gk)_W@P=DM+{}N7W{qZg^RQ=k+treU5nRPhz@g}gwSu0?l+~A0F zmRf#J>Vx_&`iNy;zBj%?=zpfak$(+M>$^A59&>hb2k1FxC+K-(Xm<2`-J_>QHdHQ{ z6|l`X1ApX)WO%~g*&Yq-KQD(TW-SFA+apot`VCZ|*vi~MIy7sf7TR01LbOqCWRkiPJ z6@(M}ihj!d$%26K_5TC(cSYRwQOYU6_GC|`1saBo8)1E`gY~iw@ikx_Zm@^-^w4FY z;?QXPxCfC>V`qP>MeS+kJWmrp`Av-b<*b%a9%YfHeEJr;TF}83>N95-ll7`?vUyqO z2b1|3zrypi-?P!XC!BZqX|ymFwV1g8e+@msRNfGKL{aEXmXB>i?CO(}>%GV%<eiz`%5$mpa8FAkVYn z@$Rm>VYt1)t2+=*1oFD6n>@eV#kw_D-mcx&KK5N+-BZJ?U#I+hOq)r+X*bvVW!;Uw zXdn9uuiokD^)Ax+f6^~fy~v&Y#FnJoBa(Z7y*I{u>>KHr_B5oo^1b<|I~FqDw}h_tk!%r$^hCt^;Q*d*i`5>@jRG=WEjTN4>KM!D`31IX}?WF&4a@K>wczc282j zcJ@n?=Mi+ysx@FA{woIyoIOsks=%r|2A=zEMV&X$9%l$SZ*+a3W3q9upE`Iyp0$q6 z;Eaj89%F9KI3b_+=qk=VVxxJuakIuE`o8w0bhasRwBt*t^~UYWqfeN-=2aej!<1K! zJ;hk$mG?cBhwe*1Hi0|slfsE(7O>6hCpB?ZhUg@r{kZ%O} zwC&j+Juc{c16fDm!}+IsYev3%6`*+&w92>4;XQi@ zJ`9#0%L@-X%HLI>r3;{J=J$v(cyW6J67etm>M=ukuJ| zOyyY^AD{N!s?Z>-@*?v;_>L}hJd@8El|g3Al5WIb%ukqc!Sxx9p{FX(yraD6s(|h3 z&?egOj_8zLPGBGPh<^1GDBJrcT0Sk67kR!;UfD4o4mV%o=$r64`YLp&U$+iw(RW+s z2kPZJR}4Smug)}k5%JbJEu1-MX@l2M>7e>0^U#>D9*v0_FXJ!gCq}ECmEWz3V?%7v zH)^ZupuN)LP0*})jrbI!UH^7%OfxnifBF0>&5VEOs?q1xDQWsFeyoSqX3C3yoAyzr zsUO@hJVOrRm;6N!gFn)l_>}KfRY237z0t&Xu}R^?5t_rGmxdJmtKYL)92Xl14EGo>8l?u za`&y$?Jm~7TRPBd-5C*Ot)`Uyi7n{SgaUk22h!#;?TM!L7FWR&*#c>C##WMd6@HNSkndhA z@%Q^ke*oUxF|5kduTX=tW-v&4M%%To9)*9Vu3E+sWcSqP96h@fI)z6Ypi_KF>K1ua zj@Aec7k}L}`L-<9Il=Y&*j=r|(saV_uZsO-d=b3zGE^qnr2n#o3`)$Dnj7Av3-~27LyZYt5yUJ>@qi z@H|ZV^>TG7_s{%{GYOw5vl0{9tV@r@&v$%tph|v%y3?j~*%j4I+-XyBkOlUo{9pHR zb!Ab8u5?W5CN@UoFrz;m6FED$;UK#MePBGb#~pou-GN?gE)UzsPCwG#jDEz?5AF9) zTfmvZdHlY}??irI;CD2?WB5(ySH*8Czr*<*#P3jkl-HQokwL?fv) z^G(99Rb%W1otGbaqjH#earu?Ihw3~R=I@zt9`HtQ~yYF!07O0+i;i`(Cx$!o- zsmGLY>XCNbE#qpHaU*5iDT(w>r&|#EB$iPBTl+0|3YZY zalSuS=@*l})R(^TNPCG}{+UWYm-GvK>HkcnFI4)Oq@V4i$7xf?+34z-_|0EHERb`< ziMN)96aTn4oOnADPP}t@IPvba;MUdHJU3zU+!#*0c1Jkz`YmDhs7vkF^K%og_0LVT z56T6Ha`6+(O}slYH}OtMZsP6o+{8b|<|f{nkehgOVs2u~q};^j%G^Z9l-xuK{Ewo0 zmUSTKm9Pu;a`0jtvX9l$e^zmJ3mLwG%ngo1r@kpcSK_stZ%1EZP~MvD0keCN?EIe*6C$- z#{@S9NLd-@vAx(Jyf61+gOInxiw#nWE$qbx;r(#;eOamf7=D;ZK0=czzYP1CPNR{y69leX%DvS`_9Mr?mjnm zhxGFp^yf-9b_dUyxEH&Rbp!E*G921D4`}M0WIx#A`pl3nTr2>`mG6!zKK(oz{r{dD zyQ7=(O`ML=x>FdwYzU!mZj6pb-VOI+aqzy_eZN?F-S^XZ-`|bhQOf&#_kCl&eYjsg zq06DY#HD?l6T71!-`+&*s-zw#^9^(JmDq}FGt$#h+FjN_+63t-=hjb7>BS)F>B;DY ziCYnJWO7bQCVxS`$$F$8|ije$k8{(jRJSRS_CeUqLTJ(!9f@H4z9o9cd-pNxfcAbMkB$B;iX75zBRjfK>Wek9ARa>|Sy z;nS_Ea8>*pZY-p3zGY1i>>J7c89bOi%I>(fJYn9Ijk4ocmurr|ILiBo`#whA%iZ@I zM%o=q%dxH0$9R9S`@U?Xebo#f_Cc4^PWq$xUpm#s*8%JsY0viSRx%&`$K;!2bnA+L zIC^39p_DYE55<ozjO(kfY9D8hRHW=k1|?C>C(;=v8Cr}~%CLF~p7 zeoo!QJTTwwpVYxC*ZOquQ1t(_EOZciRArvx*TI9(-&1?hLFyehl{0vvKUQUTOqR6*&gKA!DK$pshfO*jSjZEW2o~DX+|H)i7%JZhZiqF2W!xWkMCRdBe75vB`u}XJ^1L2wpXd~9(Us7{yrUvuCC)#V?R z%jmDuda)abZD8yM%5dt%#x?csZU6LF8Fs^HcuBrq*KEV50_kC=<-LY`0&dxCQQpSAu{q*s6iN9Y# zmqR;tt@4JkYx!Fi9&i7Nn5@b1T=}He)3ISqz8n+tYoOP!NGl7IW^{zVV^ca3P`?_B zj__S**#t)>e@)5cDdd~1M>?YV>#%btNk^coJXO{|E=J$VDND2j_Dkx~>My3`s(G}L z?Fh;eT^9M6r&|qH60`qGIjkdNk4;OEqht!BO(m&ELS(3_sK-#F}qB@VZzjtE^^0x=NrHLn5X>xgD-7!KYRLyI48i}Dit4a;+4FVeP9j6D}&{ZOx6@Q}S zQCsn+Gy5s-T=8J({~*dYed%zASLpTTQ+)bQ8AksLyuL&}Q{RxJ{*RLWW8;Sc{T%&g zy~ET0>pFaRON>SKs4MSa-0K!^#q&V5GhbkgGj{XoDg9sEp6c7iX33+C{EVyu#9R?w zR&`SUPkq>@|BAWDK7#fBD-Q<(u_`&GG9vRfAjyK|NYSkwPX57 zM+VDNGPnSFntDunkt3_Ho9{vL(a+RRuJiXt>5k|Oli$=ip7n%Oo!3!k{9bfDpLH&^ z3%mFjR|n0Q$oE}**F~IE|Gu2ZgO*w)BdRQdb!+%V2QpY(@6^qwc#-{ARv@0oe>zT|&c z`SVr&0Q;+?k5)SCHN~Xer!>|AAAXQnRR89G*8T?aUi(LB`y(}bwRNoO$C{aC_Iwok z#@R!_cQS&HCbp!pgMI5!wZyKe4Ue$fu~Yv<3>NeQ>?bca=lh-P@yO=HE{(Sa?O*?s zXW7fO`O?d0%iQ%K>6UIMc^3@1v7cTHv+wfGb0HH;1)pDhJh6wJdmyk+qc7uE$Q~YhDQn82BkiUSbLy8< zkD+Y>`o9L7|41i}qeuTG(0`Pleg@R&O6Vc@vdL}f!(x$^_mvu=q>Tu zLObfUqn!VF&U4!lFFyKG?LoTpkre-DJ2A&R`e#A^``RayZVW&AQqB>!G}Vl}1RYsZ z=C0jqFU-)neqa0CuR!O_6paT!V~5$lO4k!&CbcxJ3bq~kwsY3GsXf@%z;ig?;d4{u zgvoxrXb7H&@Av4WUhD^5EiPS6H=QtHA-S5yZ2JsEHgRnV<%>Wj#znSji#+qKD1B`8s3?a5rG3NnK z>P)BqxZ(C^Xx40M0B z8@iiXbK2yySOwjpx2YVy@@`3?!`J4>$(_CRzlPu`CPt1&=SJu}Sai}i<3ZXuG2F5l zAMGvl#YJC`Z~m>-_eM_XycZwt=(P1yjh}8gd%zL)Tv#`Xp2>b--LmQ}&nqT7&sU@G z6GXuq;*XIM5jzex8_XevJBdj6#=jzfr?FY{5jI-C{?VY^D_@nl8)$El%P9ekV z;Dz{-iA7P;u5{C)^!dauih9V`&wkHMi-Lulz+d@CY*!v>FO&8v*!=Fdw2ysSXO+f9 z>N(q2&#S%E^JiZ@8z~F_dG=~E`UdrEAnh@Y4U~O~uk4Mzl)b@M_AmKf@!+~Edo^jl zaLbLK4nq+Lo{S55l4ZZk&WuhWQsk760hKXBcT9A5`>1_1l4_yPGlgcD!C!7}H#pZ=GH zZ`g78ViVWg#P>}38p@v29{pYK2I{ZicfsbIdg3cp8r`I9or5>)BJ0^xclR}?e;lZ{ zK8GD<{8NaxMLy-nCSboi9+eUE zLOw|N7q`eq-_S5L#|{xcQ~STA(D1!`itFDMFZu3s@V`6XV%CpaI^e}-`g$}Ae~yW! zA1v&=_=0r5NW~SiN(1(liE?2#3KQF25Y|ytLeW!KH*bk>>BYy`X`>qzg**RBfROr z_Qek-5tnU)yqn>biR*P|puP@&EaNBa+5tM}^4n*LB@3V8*e*JsQi`wBX2!+w1^77~ zYF(-`M=|&-9*CZ@P3Wns3!XipxVS&_ms8I8sB&hf$~i#g6jKiU`aar(J-oIlat3kb zhVz>{d1FSII&*%DuS}iqR+&2A?a?;aM_W_-+)Ly)+tfbhlBQrz+j8$)d}ht~t8W>9 zy>Eq8nQ;TUBEs2$_~8cG>tr0S!LJ?Ofn*j$?@l7>EO{vmrp zK1Y9IhdI~S5WKV6;9DryJ{A0B z9$=q(f1qCWS5*E-(9ay(#7Eq=^b7d@x;Rc9p3kJg5`!uD|3SZEiQL{g2>eO;3d^V6 z%P${M#V5jFGb4{L7LX}VK8X0I(&x3dqcchC(6xr(U#mOBqx?F~?=R?-zQvhaN#D5h zW{vg)H-jni`z_>bTcP!{Z*9ij@4CaflsoY*-8>fEg_oPl;URdTIEUYaUd9N=M~||P z{c^wh?(Ts_k6O%}u9P!jZd_z%PBhy7p1YsiL0^pKySzj9D$r?vjG%|kbNu$Uo$vZ& z!wVyWkNPFgmGy{E51A9{W6gx=1yow*BJ1DA_S< z>)%c7Ic?v=@8g~5U}x>8CdY2z-MC*m_PcaD%DdPq%Wh>XGjt1sXusmVH_$)CBQJjE zV8&zNs^%kF^Z5q)>h#}voG&|-zR>;ovgTU++@+JW$7_qhS@btV-v|YWrPnyU%8WT+ zqUhQWyZsLXa_c+FN!NUSgc}>xo6nQSTDG3}#>`2GbIja<*hj-V#V_@zX8MKtitMr% z!}-o#1a5oHx|tV;2Y$W;4_VVO@{oV}3p_jRNOlMH-{d(q75r6Q;-`3f$lb-JZjA*S(VL2Z#+014 z2dGzmxSP+FywB+TtolkMg&~d&ta zN_Uot$9EvxNS+;EX(i^|haIqz=kh%JnV)kmkaC4-71|eR?Pm`@E@QW5t;)B^pZR_KYWit} z-y7)X7PoJf=i7%|f(>!G+m|ng&bLW_TV*+RSW~XMuEaaVo_1nH@7rnqV$)rNf7>|D zH*E%oS7YCqzu<8*7`zU>Y>q7GG_k7Tsp9ym4}`c^!^E!hbo^rIQaZYYjOem30u$u74FDBFgG03BYsKhF&&%Bx}m<%(t7| z`2Rl(TJ^F^;x|$+e4BrX<(s!S!j<#0WRzYNH{65-SBj5H4du3s+S$|6AmkiEj z4&GWoUdG9G<)uFK=jOR?zo2YOm|9dfRei!D)~ebOZ)FXsrqDk9PeFGbqR@W2Iat3U zLuST5c|LLN!2|Kiv%_NgKFFTXnN||7USnK|p9x=M%xBI+&HZ*rXRptZ=3%wQjBE@jN84Wf&8=Pc@1 zKc^cWY?=>V%@t-8*aspv(XRZ9$Zz=BUTjCF729KSoU{(=-g5bj#O8?VEVj3tos-yn zF2AvZ?Xct_h06$gDBrj>KNY*P4OW6RFu7R zTE0VrWc_>AZEA+u)&}JLN96sO%d-Jv?Yao#*&Nz?vdgoRY0n&Z);`q!@ID{U-WY6n zZaoCg?t%V0T%JXS+Mg58W>Us%muI{yfj-R({C!<|vuQRwn@Jt*AsgG-;TidhU7o3J zgZV#9-WA_Ocg`knEB9?Zf)2wE#TAdQ+RJ{gp{TwHe#dJDYTs;)^=v4)Z^rqv6*Cr% zw)eT9pNVrPoqYZQ?)K@19@B5`DRlISwI}ODmp2s^_LybxW*Y6Pad}e%Ez`uCf%b!G zyeV*aGacSMF+CA~AYk;#=tE?B;*!U6>*Y%#EYvxTC^WyguwVU4-OwXH60<(|5k7|I z-YB#7x}tXdX#0XwD5uh)rK3`GaG%(#0rX^m-O(lfXi;OYwR>fyyB-S9%^bz)=1 z^8!2H>tEzwPJY8%+Ipq;KRh@M89&2blQ$k|&A5UwFJ!9_?x8-2$dFH%*Rb>`yNr&7GOZ)UV^_{GZBX z4mn;nXTUnCV*+@%Ag*eC6N^ef=+j^@wQT{O{wwa_Yv}zwV(N$t8YEI1$3m#3pYswg$FJ6dT9b)RbT5;BJFnSYm)V?igp;w)9_EQ~_uWU2fXvkSMQK-HGJ1pBSER?606 zzkdm5-CypG4z)pk1Ja4|fKz-sS&!ypJzMhb|CL3$`HFQw$!udb;u6{7U%&MK6X|k$ig~dQhwy(x zS$_BVAn9^>z|NaSj3j6>^#8oT)*PydJxoRH(fl?JP=z|z@*(w_3*Y_oK)u%A*9 zRg~^C5DB$u9YW`F+mYvMjH?aIa~heK+{JuG`xEgGa;j$O@7A0uVvex4J9=$H&4RUN z%@`gUTjNjt%~><;MHW8?meJ1Gd~^i}TQ%z3WZ^>)=CjC(Bp1-bkY~Y6A3)PJ^&=b6g^~D$Y)${u^ zzaL6AYpjpP+Xoy+d(nHXZ>kLWc4;kL_d-`8FH0-oN{{Yq#@$-hzJh(%H;5NC&)orVLH{Pq2UUUF=WvPU~ETCiF$?6QM?D zeM0pdO?h3B^!s5RJ)89j=C+03&{|$r7_%bu7xbUHnxyx=V9X-+V*GJd($+F+3fr^} zw+X#!VBVrQVt2`2?}8ub(se7~4f=vDZ{NWG8&%f@>&w`qRm|Hb z$7^!sN3xGetNl(*p`d)vZjyIg{>Uc(b)c17vnbrzD9nY1HyZUD6qt7vpC+0My zbo@HX>tcPtKkgSu$Jw7h@f>tKsCC=DS+^xNT5Dc%tyWlQFz^-^18)KY?-2%$0s~K9 z8?Qw#;fv9O0VzFr?pbsVJ~f<1JJDw&Yx15-yLCTo<{fexA3O}yT?S6y2cud!zs;B{ zY`TT{gW4xt()#F4Q#@>fC#~Yi50RTN$>q&)6YRO-O?Q~ID#sq`$u9C_b+i~9T8NA$ zxHtq22T4Xjj}`}q?z+^)A>LPdGGd%?u++Kdp*tM9kBRrEmZq_##GiB#!?NzqcWQ_E(4PcdJT zdjYM!_?(ozdv>Knye3TZ9ejbEs>NE64X#*35W+b^Qu$rdVL9?u%l>h+JZe>pas@N6yC zEml~A2iQy4AJ88DT{Eq=8e$C8hD+_E_Sh@ixG-f6vD+6R&-$L-wES%PkwU7v|fqkEHL9L??hN z6UjRkzR%?U+5A6;Hm^eOz>9HjY#s$enKiRJF`P8er^o`bMGrrlZZy0xy-!S%c@LeHx z{$|D~+54+Jdmqe?FSHWkb(lJ>(h~b`@Lu1F&(S1p_-gp;DJ`?t&SYN`9MRb4)s>`+ z{*{)Ww)_sd{QcT%k8Hus=;M}P;p#25^p7(ckGa>di8~GT?%v=q)~tuI-#DCi!-?&^ z56{kBd+Q=2c(-?_)*Mz7w{bP|jm_xmYA{&sJjRXhsJ)dKJkUJA=vrNgJ=xbz(b7(T zP+#RZA&xvoASWmVla3p@s}9u&>@XG!eHemo&IUVtVAajb5izow7+9tYd*of3@Qs<8rAvXX7)zlpZ3*-A>hYz z!VjnIr+{-OGtbI1{zK|}@6Qd?o0voycxr5X^jN+Jp+Guq%e_4Y`0ea55YK2DdNhqS zKx{{qyJn*qA6w-6B08e@>_p3l2jm474@y zKKcCw_j~o93GVmvo$nR@>9c1!xczPPB6DnQUd28la@Dx0vC)%noG~ydV|39nGQP## zbGsG!vK|PXVeL0Cr%{Z1Zx0|P;}@%=*wjYW$jQiC z@Ta5>IXircmhg8F&+tk56R1nc_)n5CdTM0Mc%Lrg^s!81c6d$?GDa>&e!a=q%Y!|j z*rqyjZDdTjm69>*N0PDjETe;<6&V?Q#g|et67QlD9o`ukvmTU`F=dQ^Hr)x}eJ^`L z-^-qmO{niR4-)Ss>It0@?P^N%60tfeB)GY#Rp$T^2j zleTp@bG?B5^-~?6?53@AC!^n$-$B0{g1Y})>vSWXGZ7Qh@o1Kd>zeCEBac-JkK&c+ zXbpX*Cdd8(Wg7oJ(uL#f-J5%J3-T$6VULxY32J)WMkH`8XMzokTlpcy~5DW__d-%+dOY#wFo` z!Hl`k$=K%IC)~(bFMf+IY(4H`F0+R}#(80raNL{ktV2%G+Msg| z%Z+KPQi#EZe*+;?&=C@`BXedhpw^Gn_Rvjc5NKdv6{eS5^Q2 z-^nEHqzmavH@Xq9X$w@WlEk()B`k%i6$%tupRFaB8gb?d%n&+H*;q)*{2mgkKZ48WaiF2=e*B*f4|TB zoa6ffF?h+`x0FGT)uIP;SMFE!0cMT-7sIUYJGHfh9G~)!t5d$|<44A(yZ0~$-8ql| z7p8s=TjAH2wWH6s1E=zG%Fn&u#})51aPRO_!c_*W;sMzwgDZS3(KZ-U6f>UuW#ykf z3*O$LkIcK;q@%mSSJT&WgRcYniLdkefUolpvAhMoes}Z8e&Ors&!q4*r62fu6u&nD zeFw^4kAJFv{57=?_&O?puXX*z*MBK99BYYC&FZv>be=;z8@rqBV6WagQ4 zE@pK3AhU0$)7aRf-rB{oQqSfY9~K;Cvx|cQa$@Y6)vHN-`ouD5iG55i3)n@)A^7lG z!_htS^5G4gsysTW57W=mp6%iZzq9cVc+-As+2UCAx73A^`ys|jVq25a>DWZ^lAmjh z6bc99S|dI$@&4u?kF41!Udo_V5}ar1_aE`zt!I0-@J)Eh$XuoTs!8}&_*UT_{3>ix znqLLIzPLHXH}&w%m$LEA+%EV=epN8On*n~KdG5*^E#Dvm+4<&^_){y1+pRwZuRX%u zTH5cGiH8I<>@DAHJp#T#jt$>Hn>4;*?$RBXp5^gYCw~gxMtsqJj{ZYG-qqc>CSENi z=9>Zk%;SHljREI*F<=MZtm>I>njX#Yrx+_1eI(tVItTtFt`qOnR#G>LpAoS&iMyeB z486q~f7{u!t<4LE+{Y({yxPD_9_qrMI>7SKr!5bqtsOOSZ!x^9wVkZGXH*6cHHF;Y z)uwo8@d&5%@@zbW+y!;dYU`WFX&(#cyAk>oeSWSvqNfs-gWNoykBYPNQF~MR9mDG9 ztK8}6tpjDm29NZfkH(9Sh)oP1!Q*LsWZ``2Opn)8$7J*dxHjw4Ps2aY!bi{RKl6Zo zT6>5CoAzhRm-pwYy>Ee4(e}be)I&CBAp?)YCol)L}kPfiux7p>c1{a~LUjh3$;62T3?TT`+`!0p9wm&sUY)clhy8&4w&8nS>t7?->1wZjhb( z0q=d|)1GenJ^bbAri@%9bB{4+!Rg7@coPdL{@X&XO0l2exi#a;PJ^c;%f_c#v%D;V zZn{W(MO^6l>|V@g)_nGy`P3F-!1|_1W%bdO4diuL$6U$UVyHYZcTstX9|wZp#9Yo5 z9$C?l;9Micl|#^f$~!5CDP3jG&nR$A{3kl>sZP%^dh6aP7!-#j=JcMo)_n-RfhP=a zL3i<%=B$`+J^w|IrQ$8&nTy@mlF+$JS2LfhsZ9!b z_0FapGG}5ua@6|1Im&&OjA3KEI~3#n@DXdvz>TqG^lf5D-FxxPMg_JkyOoq@1MuA^9ZANlKoBcb*y^TH37+GCVZg z@{o87xk~ee;7yaSls)s~+f!$yc;>7hdHa|%?S8iSwjQ22UpzxD;AiL>qhq4I&jI}Y z7|Rm_%mJJuTqB!-9KhpF_c?$&lmoaM*n67;SRat9@!+UGIe-Hh&(8sz>*K33ux}gv zs=ZpGTfOom=={^Zn!?d~Vzfo@wRBWko& zMKzBay_7x=*^XGW$?$ywUEsxQsr~3rekz5(2|oV9^0&FKxf-9Fy25l{X@8r?WL+>k zzBOWULE{Z>>UWPV8#RLUh1uX_jA7A;+uU(Yy*|y^B{?nf7mFTM#)CqWg_+N#i0361) zEs=hhlqH|3eZebDjoW%?E}Qc3TxbqYNpE=hOzq{d`Ai$TUwcN1FN}V{ziNTjig$KF zYn@$@T#1carTk44+t?qij$5E5xuK!s7@|U~MO3B`beSB5+ z-=Cb0Kd>+S$=excU;2}O{{Zyt!JoYMblwT?8-H?$l{M+^{`ix`onB2JymQRaee)+j z1JB5xybWIU;*aia-Tl6gh(FL5Ti2n}Y^_q2@Y@etcNg&X*Vetx9DQ3i(U&)D-9g-A z-XB{xE+B7b`1ot;KA(F-0DpbS=Vtl}qXYce7hmC12Il_db3gt*%V$x?{oq|i{mSP) zd}c~Vjr4IA?Y%$xW_50KdebNSr_)D)zuxNfHxEw9i&maA20AIgh?7rH-dvk=Z zOZthg2Y|n~`1*bTUk{So?2rHcfdIZP^YPV#Ox_v5QD0;-Q>Ps!99f%TW%7<5VjS*< zp6-6dz}!EX{DO}&Wbz-2L;aG;7gwcZ@{nHQY-K-jmZ`_$EBlAD_YVMPPXut5cW3|f z*tG$iJr68KE_>j!pMEK&yZXgvw!WdJpEzqaF!znmwEm(T=#YT!U&Q|9{;cIK3E=G8 zKF%^@L*lZ&)VM6Y%;JkXW}YkA5}>9+_%$3h;Q^ zT8urnCc47owN7g>n;gzZAeV51{xc8aByTN-_&&`2JMf-ASFOcN(tL+jbgadU<9kP* zVUwR{7;p0oY4uWuryluDMxH_A-t2Tm zVxhjQ#S~kQC-Nr^12kCL|7O83ic)w7S&@${QdL(nlNo+&77%e z<@-aD3F)EYeD`qlo3UqI=^@V7Nz+60bN7wm?6n0~^qx;P9@euSI!kmI=Pq>UAz+I&vo4&WhuXk@P!GMy_YOU@v1dKB<<}W{h;d^}c2E;)_UL%)!P1Am z4yv*`$m09Y8b6F499+@%z=4*ZXj}KAaLrZO_z7CXGS-8C$a{H~pN_Zu)R+3h(ddI* zZuny|IWP!Ba>>F30$ChVP$4O~xeI}|!1Cz1oz&87JPR!^@B(AxNu z*mBkR?d6&DH4*z6t?MX2FLfrO``}-ER zb?iy7w(US@?#FGvm~L%bm^zK`_bqN)0v}1{Hp0KT_OF}1Xk`+;oh$!(5qTJ}|hEu?Gx@ zwY|YkX}MyL%sQ6YoB`n1v5;5u_xq@Rh5I$Op5ISg{Q}r~i>p6OP2p-Q^7aS$*BNkT ztAz^g^(hJ9>H;5E_!k{}G1%v$m_vIs3*!w=E zb>?u+B&JSC=QU}6l=08-&2%QT`Aoc#oI&5s?297bqq>@dvGMwCPjzY!MJ;E%9>E;t z13p>g?E_1kmVT~~JoCCKwV&4Ptpo0kJj4jErs}sR57ya(oEZzw3cMQCAZ(d>U3Y4{ zo1V3Ym4g~ZJj3|}O`OLgIth2;OLFC$+3nRzt(jo<>`i{j>by0lrPk-EZ}RG->^)fU zjOvqAE0sWoecsWTUfohTB#HhMk;?+^!xxVb%3+O%S*G#PzXT;lmd&WLg9O(WQ z-Z~H-H1%loQwTq6KlT>#mxYVqRd~QV*O+`Je6JYIKW}?G^HBUFee2io=ZSZrq0X0( z?5Iv+b8+4iTTKnLS2wotDNnZcR4=1G>qP3ayn0fj4>@b+V&q+CgMG>FgDesMSEgzm zbjH8O|5om+IXAu9Dc{MNEFJmcH51EpF3zhj`Z!*Z(v#rR!?E30%UH^%>5MV$&q^{! zbN(B!ci@=$=$s1OzY+h%=$ie&nPRUXo>d1WJeLf2+A{Hc0dvrKT;gx-WuFb6RrfUu z9KXVu8$Usp%mlysJPiIXEKp4{bEvK;k8{q<&f<`}YYw!S;j|@ZBk!CKxw-?7shU0y zhbvnT28YI`^pPiT>%dp;c=EwM^5j7|=E>8=Pd)JD+fR1SlTQGXc=Fr>Je?dpRXSNb zx!;yOQO=aJI@!oN@{`7gb&fmC_j%W>NbS$f;`77jh#eaXj~|I{{Muf`*YCQ)*AYIxDpNYIgTE@#b?}#L zej1OV>m~$nRsznB$cD4t=sNM3)pgIFG{W#$Z*le^aAwY@&EPLn=W6-Ot9ecFS4S?m z7@k7MCDC#6;eLS3cs$ivzx|zYJfB&2{EWcnj$}_o&o+0@7ks|Toqjueq-S%}ag^2O z8oqjEd5&zZtqVU`x(R#-ZEn0c&uv)>E{_G5OSqe?gWpcT=6-@b9QgqmUD0}-kIz2x z+%X;aTv3)Qp8H52dG1>9nJb>F=!WM$;p3$Gj1P7e92u>)V7by@@Ccy>~8 z1bf7)IcqY?J~8ER0S= zugPDQ50n{4-1E54d#9k&PR8#@k0U;pL}O%KF~N;Iy2LzX7b-3?D;`m#j(Ez zCdCZLPw@Ef;*-&T(Z2aBw|+kNxTW|mi%-|JZ0`W>oa6|sztSeW^x&`jqJvMf`zz>P1#pK5|muZS`Sg zK5lcTEAKs_Z}G=iaGNV#c?k3AN>~1laSZ?U(O(|jA1G6jdB+@A&K?PjboyDIUs|zdS3&Lyz|m_urwo|Lfpqp#JiCh3xGlhK=Lb zw2&i764$C8>9P)drS22;^CV?HzWT^hCj@YoD*14o^G z(VLhy?|*#U=FSEjGpuj&x&*j$WdnYVe0605!oIxrQKz+@pL-nb8QM1-<>e4ZE#2Vg z=Zw=IUt-i=;GHWqNbH_)~Zg6yAKXFvP7x?JBKJwA$_YsatI&fs~k(h&oeTza6>5MwB;3K&@AfTA>uqy@}D!GN>ZP|ns+06J<7@5HBwW;XYMwc z%XjrpuC5T;3&**6H8r|tFvwf`c#LlOhB&!{Z*0u`3^Lg* z-}J-Ey5qa&$cbB zTEoHAbg@Q(F7$P+YA977$Ndpo{q>Z1vBUbwbI0XPwFkO`4)uI>ow2GMtXZq!-Mp_9UcV7s>MmBs z@AG^Y@6GvgCaLJ&?R@RIrJ3`6n6ro#o21Q`cQxPT1DNke3ilp;%^fFQ(bcYxWzO@O zEc48ZU-r}#=J>aM()8AM*&LU5F~=7_Vdof4zk|cytEf97wbxSTuxjs;xrc*VO!0-* zXA;ehJ8pw_XPEB#JB9v&_dM#(Fx6xE`#9J8`#5PAD^Bg>Y@(gko>W7n^;)gB7BEKU z{Tk+-5VFiVtL`Kf9FoK21=0hByUw(Cg{iH9kNUD(fNwhAb&i~AZ*;-r)*;NRLpIQ} zy3zd>-it-Mh6(@Y0|3uzWn}Cv#s2?Wfm-YksL(?TmU< z-}X;#>eaVLcI;Qx zeQ>qh0rLD((RRG8{~X_7XbTT$%;XHm)Ey;e2wvw6-3wN4X)XG<@Vo^)CTH_5_}a=@ zf;!hXMem80-Y2pieFE#zUX6|69W#Gwd*=k`JxAkY&>OfD(U803tb8v&BfbD9s@ZD+ zhU208R&am($jAn-ZuEdw)sgDnuO;~U#}$AR(Q~jz&r!_#enZF9oOSM@?is;vH$2*z zj^5da&ny{Xbf?ZOH*}N?SUT#QUOkfyi7%{Z^XYj1&nz8zZtm=bjygNJ6Ai(iY^RY; z;<2o<$=nllj{Bv*SJ(w&MzcFF-pZi{X&_nT3OD?lUw@&0FU%N`|z*ygOOkb-YJI z-Q{KG(lNh)EJCZGES?agA@9pC5e*;s*qEBMJaTx*6KOgYyPB1bR>xLFU)3fd2^t)Tr^z7{cxw}0JEd?XBHb1zs3q8x&o%Jl|Y&3Ju z2D0YECOx|d_=0+Nf#8K#3~k~2l%5T{LkdL)$go)AnD3`%c@cE@=DAN3+;a_*8e0>s*-bbg=Yqtjcju`AkZ7_sd4#u5|Fw zE_AT5PriSYp@V7DNe9cG%x!1Wkja}C_g*G_S`PJTnIV&FMaxRXC`H65>_rIY zb00f*ouXTP8ydr3UazyciCIhxN-U~7iH#49?{VkZ$|pE&CQgZ-*7`H#yq4I)>{AO* zG;xaIA9EMTMD7BaSXLih(SRS$T_7vUc&|LMyP|xt@B1Rh$=!}Sle<9J1JKyn@BIWZ z%2MtqvM~zpcj(+10l#-fXPs+e(#nu~2=vt&vWZE-c?*3kDd2y2=+;?F>X5)A|K^SdEdnFoA(Ggg^5zyJDm$FUhQ*$e&pz90<)`t|zb2QHJJ|3d#k_EIMM=)eB^Qz=_{hUnN^xkRt+3tRbJ^#9(pl_$^Z zLN1wKPkzr|j>(Wq+H~@JtpDok)(W4F8Mg9g$03&)`wMh_ieeEHhnPG3vgB!z?L^dZ z*Zyycj;|o&o#=?Y2<8wvazUaacUQ*P!y41Q=j>rMHZjfTN#Bp2=$L097bIJeB@QvU z7-Er=&>5;7P3S$^`*Fz3v5^hl{+Cn^D5g8)xob)}Ak|ms4!&vJn{I4lM*MN_oKTIi zkpaFnIUvU9iGEjE`}nN2kEwZejz4_*J${Fk!vOts@B7iBUuHhG5Anyx13v4Qv(XPb zoRxmiKdT(VJGso|eeTnHHKKCt@z5&iC|&d3dP%sC*F$Us(^ zqz~l>J^`$I)8~1od{E7=m~ZC%dy}7y_JgL$+XFVz()4?be+D#FT>oRqXl1H4$YK3C zTdmh#dEOLa?RXIDG~{KF&4lWQSo=2T@v!GmYvJo1=V$WA+c~o%B3%jn3Jawxoi_># zd56zhzYrhz=U+IScd@7X7}iumW^FvB!?^Q`I7|H*oeRyCr%%kdVIqAr)~}gTW_|z0 z5c~S4JH_t!$sYbpUWNEU=N#zljV-LL)0SL4ccXHK53*IB;7kz%JFx0*M8?lLzX ziOl(-7rUFES>J z^&pZ3#nySqMa5g~n!^%FwP@4-FsI>^faB&}DxV&2!0{R&q=+MtW{et|&p^@PMXk*SWQ!SBr z1zn?a)TEoVo}}E8cTb!>dknv=gHF)br=5RB1ht#Hq$lfbtwB%+?Zj6w^)mFK{#8Gu z{$Jq#rALpcc{5WF_5x1nN5L7Pu5E9?ss070`WKuZA1It=O&b4Lav({%PWl&|KOQKY`-tve9w?ml+_}9bNAxdz zo;XlA_Yr@Vyhq@Cr*eSuK5H+_5&etqe;6p7><8GZ@=pJPbL&9iH1!vI(H_yi;9NUU zI8FX;FTzRxg7cJt!ikT&SLsgwg7c7p!f9%%_98y%UvTF6a0c=Qic2EYLB_`2FtNiw z9q{j|GwuBIW#!+R8a89os4JC^YwG1Ed%jmk&WBhZzt{L<dIN|cd)7m3axDPi?>aL|Ypf|8q@U5E8sYCw@$q2qB#%xuc+eW{PYoVU zZ~YIpa9`o!A4UDg!^bl4a9khoaOm`|@$dzUho2ifq|V4l=LO`!=zc2~h8L_{bnpT= z?gcN*1P4YgXeZf8@dA5F7^6cjh!>4qkS8#;jr``M+5cMMnCZGAHlD28&tEPT$%n?43BK6CGKm1_mwN7UO~0)R^C(lb5wVB-Rp&3Jr%LISF7R4 zdlEkX_mRkZ^z_yvHLps|D?;vtJCTC%axwEVv8JW3bQ1GOk2&evkKr{h>7UGbp{K6i z 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

+
+

coolify

+ + + + {coolify ? ( +
+

+ {coolify.label} +

+ {coolify.version ?

Version: {coolify.version}

: null} +

{coolify.message}

+ {coolify.binary ?

Binary: {coolify.binary}

: null} +
+ ) : null} +
+

Current team

{currentTeam ? ( diff --git a/routes/v5.php b/routes/v5.php index 16525bf73..766047255 100644 --- a/routes/v5.php +++ b/routes/v5.php @@ -5,4 +5,5 @@ use Illuminate\Support\Facades\Route; Route::middleware('v5.authenticated')->group(function () { Route::get('/', HomeController::class)->name('home'); + Route::get('/coolify/version', [HomeController::class, 'coolifyCliVersion'])->name('coolify.version'); }); diff --git a/scripts/coold-vm.sh b/scripts/coold-vm.sh index b43f50c32..177c289d3 100755 --- a/scripts/coold-vm.sh +++ b/scripts/coold-vm.sh @@ -40,7 +40,7 @@ if [ "$BUILDER_CAPACITY" = "0" ]; then BUILDER_ENABLED="false" fi TEMPLATE="$ROOT/dev/lima/coold.yaml" -GENERATED="$ROOT/.dev/lima/coold.generated.yaml" +GENERATED="$ROOT/.dev/lima/${INSTANCE}.generated.yaml" GUEST_COOLIFY_ROOT="/workspace/coolify" usage() { @@ -436,8 +436,11 @@ wait_for_lima_start() { lima_shell sudo sh -c 'test -f /var/log/cloud-init-output.log && tail -n 12 /var/log/cloud-init-output.log || true' 2>/dev/null | awk '{ print "[guest] " $0; fflush(); }' || true if ! printf '%s' "$status" | grep -q running; then - kill "$start_pid" >/dev/null 2>&1 || true - break + if kill -0 "$start_pid" 2>/dev/null; then + kill "$start_pid" >/dev/null 2>&1 || true + disown "$start_pid" >/dev/null 2>&1 || true + fi + return fi else message="$(latest_lima_message)" @@ -503,7 +506,7 @@ up_with_logs() { wait_for_lima_start wait_for_guest_provisioning - echo "==> VM is ready. Run cooldctl bootstrap via: scripts/dev.sh up" + echo "==> VM is ready. Run coolify bootstrap via: scripts/dev.sh up" } cmd="${1:-}" diff --git a/scripts/dev.sh b/scripts/dev.sh index 1d389a0c3..45f8a8f03 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -100,30 +100,11 @@ host_os() { esac } -cooldctl_bin() { - printf '%s\n' "$ROOT/.dev/bin/cooldctl" +coolify_cli_bin() { + printf '%s\n' "$ROOT/.dev/bin/coolify" } -build_local_cooldctl() { - local bin - local coold_repo - - bin="$(cooldctl_bin)" - coold_repo="$(read_coolify_env COOLIFY_COOLD_REPO /Users/heyandras/devel/coold)" - - if [ ! -d "$coold_repo/cooldctl" ]; then - echo "ERROR: macOS cooldctl release artifact is not available yet and local coold repo was not found at ${coold_repo}." >&2 - echo "Set COOLIFY_COOLD_REPO=/path/to/coold or build/copy cooldctl to ${bin}." >&2 - exit 1 - fi - - echo "==> Building local macOS cooldctl from ${coold_repo}" - (cd "$coold_repo" && cargo build -p cooldctl) - mkdir -p "$(dirname "$bin")" - install -m 0755 "$coold_repo/target/debug/cooldctl" "$bin" -} - -ensure_cooldctl() { +ensure_coolify() { local bin local version local arch @@ -131,63 +112,84 @@ ensure_cooldctl() { local url local tmpdir - bin="$(cooldctl_bin)" - version="$(read_coolify_env COOLIFY_COOLDCTL_VERSION "$(read_coolify_env COOLIFY_COOLD_VERSION nightly)")" + bin="$(coolify_cli_bin)" + version="$(read_coolify_env COOLIFY_CLI_VERSION "$(read_coolify_env COOLIFY_COOLD_VERSION nightly)")" arch="$(host_arch)" os="$(host_os)" - if [ "$os" = "darwin" ]; then - build_local_cooldctl + if [ -x "$bin" ] && "$bin" --version >/dev/null 2>&1 && [ "${COOLIFY_CLI_FORCE_DOWNLOAD:-false}" != "true" ]; then return fi - if [ -x "$bin" ] && "$bin" --version >/dev/null 2>&1 && [ "${COOLIFY_COOLDCTL_FORCE_DOWNLOAD:-false}" != "true" ]; then - return - fi - - url="https://github.com/coollabsio/coold/releases/download/${version}/cooldctl-${os}-${arch}.tar.gz" - echo "==> Installing cooldctl from ${url}" + url="https://github.com/coollabsio/coold/releases/download/${version}/coolify-${os}-${arch}.tar.gz" + echo "==> Installing coolify from ${url}" mkdir -p "$(dirname "$bin")" tmpdir="$(mktemp -d)" - trap 'rm -rf "$tmpdir"' RETURN - curl -fsSL --retry 3 --max-time 120 -o "$tmpdir/cooldctl.tar.gz" "$url" - tar -xzf "$tmpdir/cooldctl.tar.gz" -C "$tmpdir" - install -m 0755 "$tmpdir/cooldctl" "$bin" + if ! curl -fsSL --retry 3 --max-time 120 -o "$tmpdir/coolify.tar.gz" "$url"; then + rm -rf "$tmpdir" + return 1 + fi + tar -xzf "$tmpdir/coolify.tar.gz" -C "$tmpdir" + install -m 0755 "$tmpdir/coolify" "$bin" + rm -rf "$tmpdir" } lima_ssh_target() { local index="$1" local instance - local ssh instance="$(coold_vm_instance "$index")" - ssh="$(limactl list 2>/dev/null | awk -v name="$instance" 'NR > 1 && $1 == name {print $3}')" - if [ -z "$ssh" ] || [ "$ssh" = "-" ]; then - echo "ERROR: could not determine SSH target for Lima VM ${instance}. Start it first with scripts/dev.sh up." >&2 + if [ ! -f "$HOME/.lima/${instance}/ssh.config" ]; then + echo "ERROR: Lima SSH config for ${instance} was not found. Start it first with scripts/dev.sh up." >&2 exit 1 fi - printf '%s\n' "$ssh" + printf 'lima-%s\n' "$instance" } -cooldctl_nodes_arg() { +lima_ssh_config() { + local count + local config="$ROOT/.dev/lima/ssh.config" + local instance + count="$(coold_vm_count)" + + mkdir -p "$(dirname "$config")" + : > "$config" + + for index in $(seq 1 "$count"); do + instance="$(coold_vm_instance "$index")" + if [ ! -f "$HOME/.lima/${instance}/ssh.config" ]; then + echo "ERROR: Lima SSH config for ${instance} was not found. Start it first with scripts/dev.sh up." >&2 + exit 1 + fi + + cat "$HOME/.lima/${instance}/ssh.config" >> "$config" + printf '\n' >> "$config" + done + + printf '%s\n' "$config" +} + +coolify_nodes_arg() { local count local nodes="" + local node count="$(coold_vm_count)" for index in $(seq 1 "$count"); do + node="$(lima_ssh_target "$index")" || return 1 if [ -n "$nodes" ]; then nodes="${nodes}," fi - nodes="${nodes}$(lima_ssh_target "$index")" + nodes="${nodes}${node}" done printf '%s\n' "$nodes" } -cooldctl_wg_listen_overrides_arg() { +coolify_wg_listen_overrides_arg() { local count local overrides="" local node @@ -204,7 +206,7 @@ cooldctl_wg_listen_overrides_arg() { printf '%s\n' "$overrides" } -cooldctl_wg_endpoint_overrides_arg() { +coolify_wg_endpoint_overrides_arg() { local count local overrides="" local node @@ -221,45 +223,63 @@ cooldctl_wg_endpoint_overrides_arg() { printf '%s\n' "$overrides" } -cooldctl_ssh_key() { - read_coolify_env COOLIFY_COOLDCTL_SSH_KEY "$HOME/.lima/_config/user" +coolify_ssh_key() { + read_coolify_env COOLIFY_CLI_SSH_KEY "$HOME/.lima/_config/user" } -cooldctl_ssh_user() { - read_coolify_env COOLIFY_COOLDCTL_SSH_USER "$USER" +coolify_ssh_user() { + read_coolify_env COOLIFY_CLI_SSH_USER "$USER" } -cooldctl_bootstrap_command() { - ensure_cooldctl +coolify_bootstrap_command() { + local nodes + local ssh_config + local listen_overrides + local endpoint_overrides + ensure_coolify + + nodes="$(coolify_nodes_arg)" || return 1 + ssh_config="$(lima_ssh_config)" || return 1 + listen_overrides="$(coolify_wg_listen_overrides_arg)" || return 1 + endpoint_overrides="$(coolify_wg_endpoint_overrides_arg)" || return 1 cat < +Usage: scripts/dev.sh coolify Commands: - install Download/install the nightly cooldctl dev binary - path Print the local cooldctl path + install Download/install the nightly coolify dev binary + path Print the local coolify path bootstrap-command Print the dev Lima bootstrap command without running it - run Run cooldctl with arbitrary args + run Run coolify with arbitrary args Example: - scripts/dev.sh cooldctl bootstrap-command + scripts/dev.sh coolify bootstrap-command USAGE ;; *) - echo "unknown cooldctl command: $command" >&2 - echo "Run: scripts/dev.sh cooldctl help" >&2 + echo "unknown coolify command: $command" >&2 + echo "Run: scripts/dev.sh coolify help" >&2 exit 1 ;; esac @@ -415,15 +435,8 @@ up() { if [ "$coold_vm_enabled" != "false" ]; then echo "==> Starting ${count} Coolify coold VM(s) before Spin..." - vm_pids="" for index in $(seq 1 "$count"); do - ( - coold_vm "$index" up - ) & - vm_pids="${vm_pids} $!" - done - for pid in $vm_pids; do - wait "$pid" + coold_vm "$index" up done else echo "==> COOLIFY_COOLD_VM_ENABLED=false; skipping coold VM." @@ -433,8 +446,8 @@ up() { spin up -d "$@" if [ "$coold_vm_enabled" != "false" ]; then - echo "==> Bootstrapping coold VM mesh with cooldctl..." - cooldctl_bootstrap + echo "==> Bootstrapping coold VM mesh with coolify..." + coolify_bootstrap for index in $(seq 1 "$count"); do configure_flux_dev_for_vm "$index" @@ -911,7 +924,7 @@ Commands: corrosion Inspect Corrosion state, config, logs, and registered containers firewall Manage dev coold firewall allow rules example-nginx Start/check example nginx containers with coold DNS - cooldctl Install/run the released cooldctl dev helper + coolify Install/run the released coolify dev helper USAGE } @@ -945,8 +958,8 @@ case "$cmd" in example-nginx) example_nginx "$@" ;; - cooldctl) - cooldctl_dev "$@" + coolify) + coolify_dev "$@" ;; -h|--help|help|"") usage diff --git a/tests/Feature/V5/HomeTest.php b/tests/Feature/V5/HomeTest.php index d4b4b96dc..26914cf3a 100644 --- a/tests/Feature/V5/HomeTest.php +++ b/tests/Feature/V5/HomeTest.php @@ -9,6 +9,7 @@ use App\Models\Team; use App\Models\User; use App\Services\Flux\FluxHealth; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Process; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Schema; use Mockery\MockInterface; @@ -105,10 +106,10 @@ it('serves the v5 inertia shell', function () { ->assertSee('v5-ready', false) ->assertSee('Running') ->assertSee('Flux is running.') - ->assertSee('coolify-coold-dev') - ->assertSee('coolify-coold-dev-2') - ->assertSee('100.64.0.10') - ->assertSee('100.64.0.11') + ->assertSee('coold-dev') + ->assertSee('coold-dev-2') + ->assertSee('100.64.0.1') + ->assertSee('100.64.0.2') ->assertSee('builder') ->assertSee('builderCapacity') ->assertSee('V5 Shared Team') @@ -173,6 +174,50 @@ it('shows when flux is unavailable', function () { ->assertSee('Flux socket was not found.'); }); +it('checks the installed coolify version', function () { + createSharedUserAndTeamTables(); + [$user, $team] = createV5UserWithTeam(); + + Process::fake([ + '*' => Process::result(output: 'coolify nightly-20260616', exitCode: 0), + ]); + + $this + ->actingAs($user) + ->withSession(['currentTeam' => $team]) + ->getJson('/v5/coolify/version') + ->assertSuccessful() + ->assertJson([ + 'available' => true, + 'label' => 'Installed', + 'version' => 'coolify nightly-20260616', + 'message' => 'Installed version: coolify nightly-20260616.', + 'binary' => '/usr/local/bin/coolify', + ]); +}); + +it('shows when coolify version check fails', function () { + createSharedUserAndTeamTables(); + [$user, $team] = createV5UserWithTeam(); + + Process::fake([ + '*' => Process::result(errorOutput: 'not found', exitCode: 127), + ]); + + $this + ->actingAs($user) + ->withSession(['currentTeam' => $team]) + ->getJson('/v5/coolify/version') + ->assertSuccessful() + ->assertJson([ + 'available' => false, + 'label' => 'Unavailable', + 'version' => null, + 'message' => 'not found', + 'binary' => '/usr/local/bin/coolify', + ]); +}); + function fakeFluxHealth(bool $available = true, string $message = 'Flux is running.'): void { app()->instance(FluxHealth::class, Mockery::mock(FluxHealth::class, function (MockInterface $mock) use ($available, $message) { @@ -218,3 +263,25 @@ function createSharedUserAndTeamTables(): void $table->unique(['team_id', 'user_id']); }); } + +/** + * @return array{0: User, 1: Team} + */ +function createV5UserWithTeam(): array +{ + $user = User::withoutEvents(fn () => User::query()->create([ + 'name' => 'Margaret Hamilton', + 'email' => 'margaret@example.com', + 'email_verified_at' => now(), + 'password' => 'password', + ])); + $team = Team::withoutEvents(fn () => Team::query()->create([ + 'name' => 'V5 Tooling Team', + 'description' => null, + 'personal_team' => false, + 'show_boarding' => false, + ])); + $user->teams()->attach($team, ['role' => 'owner']); + + return [$user, $team]; +} From 586588196d99a90b61d03ff53661c94b6b12745f Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 13:59:05 +0200 Subject: [PATCH 007/178] chore(dev): remove bundled cooldctl binary --- .dev/bin/cooldctl | Bin 16026008 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 .dev/bin/cooldctl diff --git a/.dev/bin/cooldctl b/.dev/bin/cooldctl deleted file mode 100755 index 57a106667956481b345b857cbf21e4e50ce0ee1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16026008 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 nDzXJ{J$5u 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

`P&eraIdACOJe2YG{#F|#pWHe)bQbPa5& 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 z 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

)} - -
-

coold servers

- - {cooldServers.length === 0 ? ( -

No coold serverss have been added yet.

- ) : ( -
    - {cooldServers.map((host) => ( -
  • - {host.host} ({host.status}) — SSH {host.sshUser}@{host.host}:{host.sshPort};{' '} - {host.capabilities.join(', ')}; builder{' '} - {host.builderEnabled - ? `enabled, capacity ${host.builderCapacity}` - : 'disabled'} -
  • - ))} -
- )} -
- -
-

coolify

- - -

Bootstrap server

- - - - - - - - - -
- Advanced mesh options - - - - - - - - -
- - - - {privateKeys.length === 0 ? ( -

Add a private key before bootstrapping a server.

- ) : null} - - - {bootstrapResult ? ( -
-

- {bootstrapResult.label} -

-

{bootstrapResult.message}

- {bootstrapResult.exitCode !== null ? ( -

Exit code: {bootstrapResult.exitCode}

- ) : null} - {bootstrapResult.output ?
{bootstrapResult.output}
: null} - {bootstrapResult.errorOutput ?
{bootstrapResult.errorOutput}
: null} -
- ) : null} -
- -

Current team

- - {currentTeam ? ( -
-
Name
-
{currentTeam.name}
- -
Description
-
{currentTeam.description || 'No description'}
- -
Your role
-
{currentTeam.role}
-
- ) : ( -

No team selected.

- )} - -

Your teams

- -
    - {teams.map((team) => ( -
  • - {team.name} ({team.role}) -
  • - ))} -
); diff --git a/tests/Feature/V5/HomeTest.php b/tests/Feature/V5/HomeTest.php index e05b06564..e914f6cef 100644 --- a/tests/Feature/V5/HomeTest.php +++ b/tests/Feature/V5/HomeTest.php @@ -24,7 +24,6 @@ beforeEach(function () { Schema::dropIfExists('v5_servers'); Schema::dropIfExists('v5_clusters'); - Schema::dropIfExists('v5_projects'); Schema::dropIfExists('private_keys'); Schema::dropIfExists('team_user'); Schema::dropIfExists('teams'); @@ -52,22 +51,9 @@ it('uses separated v5 middleware groups', function () { ->and($groups['v5.authenticated'])->toContain(EnsureCurrentTeam::class); }); -it('creates v5 project tables in the shared database', function () { - createSharedUserAndTeamTables(); - - $migration = include database_path('migrations/2026_06_04_050157_create_v5_projects_table.php'); - $migration->up(); - - expect(Schema::hasTable('v5_projects'))->toBeTrue() - ->and(Schema::hasColumns('v5_projects', [ - 'id', - 'team_id', - 'created_by_user_id', - 'name', - 'description', - 'created_at', - 'updated_at', - ]))->toBeTrue(); +it('reuses existing projects instead of creating v5 projects', function () { + expect(file_exists(database_path('migrations/2026_06_04_050157_v5_create_projects_table.php')))->toBeFalse() + ->and(file_exists(app_path('Models/V5/Project.php')))->toBeFalse(); }); it('creates v5 cluster tables and lets each server belong to one cluster', function () { @@ -75,7 +61,7 @@ it('creates v5 cluster tables and lets each server belong to one cluster', funct Schema::dropIfExists('v5_servers'); Schema::dropIfExists('v5_clusters'); - $clusterMigration = include database_path('migrations/2026_06_16_130649_create_v5_clusters_table.php'); + $clusterMigration = include database_path('migrations/2026_06_16_130649_v5_create_clusters_table.php'); $clusterMigration->up(); expect(Schema::hasTable('v5_clusters'))->toBeTrue() @@ -89,14 +75,9 @@ it('creates v5 cluster tables and lets each server belong to one cluster', funct 'updated_at', ]))->toBeTrue(); - Schema::dropIfExists('v5_servers'); - - $serverMigration = include database_path('migrations/2026_06_16_130650_create_v5_servers_table.php'); + $serverMigration = include database_path('migrations/2026_06_16_130650_v5_create_servers_table.php'); $serverMigration->up(); - $serverClusterMigration = include database_path('migrations/2026_06_16_131229_add_cluster_id_to_v5_servers_table.php'); - $serverClusterMigration->up(); - expect(Schema::hasColumn('v5_servers', 'cluster_id'))->toBeTrue(); }); @@ -106,15 +87,12 @@ it('creates v5 server tables in the shared database', function () { Schema::dropIfExists('v5_servers'); Schema::dropIfExists('v5_clusters'); - $clusterMigration = include database_path('migrations/2026_06_16_130649_create_v5_clusters_table.php'); + $clusterMigration = include database_path('migrations/2026_06_16_130649_v5_create_clusters_table.php'); $clusterMigration->up(); - $migration = include database_path('migrations/2026_06_16_130650_create_v5_servers_table.php'); + $migration = include database_path('migrations/2026_06_16_130650_v5_create_servers_table.php'); $migration->up(); - $serverClusterMigration = include database_path('migrations/2026_06_16_131229_add_cluster_id_to_v5_servers_table.php'); - $serverClusterMigration->up(); - expect(Schema::hasTable('v5_servers'))->toBeTrue() ->and(Schema::hasColumns('v5_servers', [ 'id', @@ -136,20 +114,21 @@ it('creates v5 server tables in the shared database', function () { ]))->toBeTrue(); }); -it('includes v5 project tables in the dev testing schema', function () { +it('includes v5 tables in the dev testing schema', function () { $schema = file_get_contents(database_path('schema/testing-schema.sql')); - expect($schema)->toContain('CREATE TABLE IF NOT EXISTS "v5_projects"') - ->and($schema)->toContain('"team_id" INTEGER NOT NULL') + expect($schema)->toContain('"team_id" INTEGER NOT NULL') ->and($schema)->toContain('"created_by_user_id" INTEGER NOT NULL') - ->and($schema)->toContain('2026_06_04_050157_create_v5_projects_table') + ->and($schema)->not->toContain('CREATE TABLE IF NOT EXISTS "v5_projects"') + ->and($schema)->not->toContain('2026_06_04_050157_v5_create_projects_table') ->and($schema)->toContain('CREATE TABLE IF NOT EXISTS "v5_servers"') ->and($schema)->toContain('"cluster_id" INTEGER') ->and($schema)->toContain('CREATE TABLE IF NOT EXISTS "v5_clusters"') ->and($schema)->toContain('"private_key_id" INTEGER') - ->and($schema)->toContain('2026_06_16_130650_create_v5_servers_table') - ->and($schema)->toContain('2026_06_16_130649_create_v5_clusters_table') - ->and($schema)->toContain('2026_06_16_131229_add_cluster_id_to_v5_servers_table') + ->and($schema)->toContain('2026_06_16_130650_v5_create_servers_table') + ->and($schema)->toContain('2026_06_16_130649_v5_create_clusters_table') + ->and($schema)->not->toContain('2026_06_16_131229_add_cluster_id_to_v5_servers_table') + ->and($schema)->not->toContain('2026_06_16_132000_make_v5_server_private_key_nullable') ->and($schema)->not->toContain('v5_hosts'); }); @@ -186,16 +165,20 @@ it('serves the v5 inertia shell', function () { ->assertSee('Home', false) ->assertDontSee('v5-ready', false) ->assertDontSee('This page is served from Laravel through Inertia and React') + ->assertDontSee('Bootstrap server') + ->assertDontSee('privateKeys', false) ->assertSee('Running') ->assertSee('Flux is running.') ->assertSee('"clusters":[]', false) - ->assertSee('"cooldServers":[]', false) + ->assertDontSee('cooldServers', false) ->assertDontSee('coold-dev') ->assertDontSee('100.64.0.1') - ->assertSee('V5 Shared Team') - ->assertSee('Shared team details') - ->assertSee('owner') - ->assertSee($user->email); + ->assertDontSee('Current team') + ->assertDontSee('Your teams') + ->assertDontSee('currentTeam', false) + ->assertDontSee('teams', false) + ->assertDontSee('V5 Shared Team') + ->assertDontSee('Shared team details'); }); it('shows v5 clusters with their servers on the inertia shell', function () { @@ -263,8 +246,8 @@ it('selects a shared team when the session has no current team', function () { ->get('/v5') ->assertSuccessful() ->assertSessionHas('currentTeam') - ->assertSee('Auto Selected Team') - ->assertSee('admin'); + ->assertDontSee('Auto Selected Team') + ->assertDontSee('admin'); }); it('shows when flux is unavailable', function () { @@ -430,9 +413,10 @@ it('runs coolify bootstrap from dynamic UI input and a selected team private key ->withSession(['currentTeam' => $team]) ->get('/v5') ->assertSuccessful() - ->assertSee('"host":"192.0.2.10"', false) - ->assertSee('"status":"installed"', false) - ->assertSee('"capabilities":["coold","builder"]', false); + ->assertDontSee('"host":"192.0.2.10"', false) + ->assertDontSee('"capabilities":["coold","builder"]', false); + + expect(V5Server::query()->where('host', '192.0.2.10')->where('status', 'installed')->exists())->toBeTrue(); $sshKeyPath = null; From 295addb6b08c590c569974a7d550f71d8707cccb Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:10:40 +0200 Subject: [PATCH 011/178] refactor(dev): replace v5:sync-dev-lima-servers with V5DevLimaSeeder Switch Lima VM dev-environment sync from a custom Artisan command to a database seeder. The seeder creates/updates the Development-Lima cluster and its two servers idempotently, reading ssh_user from the COOLIFY_CLI_SSH_USER env var (exposed via config('coold.dev_ssh_user')). dev.sh now passes COOLIFY_CLI_SSH_USER and runs db:seed instead of building per-server --server flag arrays. --- config/coold.php | 1 + database/seeders/DatabaseSeeder.php | 1 + database/seeders/V5DevLimaSeeder.php | 85 +++++++++++++++++++ scripts/dev.sh | 24 ++---- tests/Feature/DevEnvironmentExampleTest.php | 8 ++ .../DevScriptFirewallDelegationTest.php | 9 +- tests/Feature/V5/HomeTest.php | 23 +++++ 7 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 database/seeders/V5DevLimaSeeder.php diff --git a/config/coold.php b/config/coold.php index 86a28a91a..2468eac40 100644 --- a/config/coold.php +++ b/config/coold.php @@ -6,4 +6,5 @@ return [ 'corrosion_version' => env('COOLIFY_CORROSION_VERSION', 'v1.0.0'), 'dev_builder_capacity' => (int) env('COOLIFY_COOLD_VM_BUILDER_CAPACITY', 2), 'dev_builder_enabled' => (int) env('COOLIFY_COOLD_VM_BUILDER_CAPACITY', 2) > 0, + 'dev_ssh_user' => env('COOLIFY_CLI_SSH_USER', get_current_user()), ]; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 4f5c4431a..3ec75c4f5 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -35,6 +35,7 @@ class DatabaseSeeder extends Seeder if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) { $this->call([ DevelopmentRailpackExamplesSeeder::class, + V5DevLimaSeeder::class, ]); } } diff --git a/database/seeders/V5DevLimaSeeder.php b/database/seeders/V5DevLimaSeeder.php new file mode 100644 index 000000000..1151f8fb3 --- /dev/null +++ b/database/seeders/V5DevLimaSeeder.php @@ -0,0 +1,85 @@ +find(0) ?? Team::query()->orderBy('id')->first(); + $user = User::query()->find(0) ?? User::query()->orderBy('id')->first(); + + if (! $team instanceof Team || ! $user instanceof User) { + return; + } + + $cluster = Cluster::query()->updateOrCreate([ + 'team_id' => $team->id, + 'name' => self::CLUSTER_NAME, + ], [ + 'created_by_user_id' => $user->id, + 'description' => 'Local Lima development cluster managed by scripts/dev.sh.', + ]); + + $privateKey = PrivateKey::query() + ->where('team_id', $team->id) + ->where('is_git_related', false) + ->orderBy('id') + ->first(); + + $builderCapacity = max(0, (int) config('coold.dev_builder_capacity', 2)); + $builderEnabled = $builderCapacity > 0; + $capabilities = $builderEnabled ? ['coold', 'builder'] : ['coold']; + $sshUser = (string) config('coold.dev_ssh_user', get_current_user()); + + foreach ($this->servers() as $server) { + Server::query()->updateOrCreate([ + 'team_id' => $team->id, + 'host' => $server['host'], + 'ssh_port' => $server['ssh_port'], + ], [ + 'cluster_id' => $cluster->id, + 'created_by_user_id' => $user->id, + 'private_key_id' => $privateKey?->id, + 'name' => $server['name'], + 'ssh_user' => $sshUser, + 'status' => 'installed', + 'capabilities' => $capabilities, + 'builder_enabled' => $builderEnabled, + 'builder_capacity' => $builderCapacity, + 'last_bootstrapped_at' => now(), + ]); + } + } + + /** + * @return array + */ + private function servers(): array + { + return [ + [ + 'name' => 'coold-dev', + 'host' => 'lima-coold-dev', + 'ssh_port' => 22, + ], + [ + 'name' => 'coold-dev-2', + 'host' => 'lima-coold-dev-2', + 'ssh_port' => 22, + ], + ]; + } +} diff --git a/scripts/dev.sh b/scripts/dev.sh index e0f6014a4..6b8a600d0 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -417,29 +417,17 @@ follow_logs() { } sync_v5_dev_lima_servers() { - local count - local builder_capacity - local args=() - local instance - local node + local ssh_user - count="$(coold_vm_count)" - builder_capacity="$(read_coolify_env COOLIFY_COOLD_VM_BUILDER_CAPACITY 2)" - - for index in $(seq 1 "$count"); do - instance="$(coold_vm_instance "$index")" - node="$(lima_ssh_target "$index")" - args+=(--server "${instance}|${node}|$(coolify_ssh_user)|22") - done + ssh_user="$(coolify_ssh_user)" echo "==> Running pending migrations before syncing v5 dev Lima state..." spin exec -T coolify php artisan migrate --force - echo "==> Syncing dev Lima VM(s) into v5 clusters/servers..." - spin exec -T coolify php artisan v5:sync-dev-lima-servers \ - --cluster="Development-Lima" \ - --builder-capacity="$builder_capacity" \ - "${args[@]}" + echo "==> Seeding dev Lima VM(s) into v5 clusters/servers..." + spin exec -T \ + -e COOLIFY_CLI_SSH_USER="$ssh_user" \ + coolify php artisan db:seed --class=V5DevLimaSeeder --force } configure_flux_dev_for_vm() { diff --git a/tests/Feature/DevEnvironmentExampleTest.php b/tests/Feature/DevEnvironmentExampleTest.php index d5f2320cd..2462a113e 100644 --- a/tests/Feature/DevEnvironmentExampleTest.php +++ b/tests/Feature/DevEnvironmentExampleTest.php @@ -29,3 +29,11 @@ it('defaults coold dev VM settings in Laravel config', function () { ->and(config('coold.dev_builder_capacity'))->toBe(2) ->and(config('coold.dev_builder_enabled'))->toBeTrue(); }); + +it('runs the v5 dev Lima seeder with the normal development database seeder', function () { + $databaseSeeder = file_get_contents(database_path('seeders/DatabaseSeeder.php')); + $developmentSeederBlock = str($databaseSeeder)->after("if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {")->before(' }')->toString(); + + expect($developmentSeederBlock)->toContain('DevelopmentRailpackExamplesSeeder::class') + ->and($developmentSeederBlock)->toContain('V5DevLimaSeeder::class'); +}); diff --git a/tests/Feature/DevScriptFirewallDelegationTest.php b/tests/Feature/DevScriptFirewallDelegationTest.php index f243adc55..b776ef38f 100644 --- a/tests/Feature/DevScriptFirewallDelegationTest.php +++ b/tests/Feature/DevScriptFirewallDelegationTest.php @@ -59,13 +59,14 @@ it('retries dev coolify bootstrap because fresh Lima setup can complete across p ->and($script)->toContain('fresh Lima hosts can finish setup after partial bootstrap phases'); }); -it('syncs bootstrapped Lima VMs into v5 development server state', function () { +it('seeds bootstrapped Lima VMs into v5 development server state', function () { $script = file_get_contents(base_path('scripts/dev.sh')); expect($script)->toContain('sync_v5_dev_lima_servers()') - ->and($script)->toContain('v5:sync-dev-lima-servers') - ->and($script)->toContain('--cluster="Development-Lima"') - ->and($script)->toContain('--server "${instance}|${node}|$(coolify_ssh_user)|22"'); + ->and($script)->toContain('COOLIFY_CLI_SSH_USER="$ssh_user"') + ->and($script)->toContain('db:seed --class=V5DevLimaSeeder --force') + ->and($script)->not->toContain('v5:sync-dev-lima-servers') + ->and($script)->not->toContain('--server "${instance}|${node}|$(coolify_ssh_user)|22"'); }); it('supports down cleanup as the preferred VM cleanup command', function () { diff --git a/tests/Feature/V5/HomeTest.php b/tests/Feature/V5/HomeTest.php index e914f6cef..363efb56e 100644 --- a/tests/Feature/V5/HomeTest.php +++ b/tests/Feature/V5/HomeTest.php @@ -11,6 +11,7 @@ use App\Models\User; use App\Models\V5\Cluster; use App\Models\V5\Server as V5Server; use App\Services\Flux\FluxHealth; +use Database\Seeders\V5DevLimaSeeder; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Process; @@ -465,6 +466,28 @@ it('syncs dev Lima VMs into v5 clusters and servers', function () { ->and(V5Server::query()->where('name', 'coold-dev-2')->where('host', 'lima-coold-dev-2')->exists())->toBeTrue(); }); +it('seeds dev Lima VMs into v5 clusters and servers idempotently', function () { + createSharedUserAndTeamTables(); + [$user, $team] = createV5UserWithTeam(); + createV5PrivateKey($team, 'Dev Lima Key'); + config()->set('coold.dev_builder_capacity', 2); + + (new V5DevLimaSeeder)->run(); + (new V5DevLimaSeeder)->run(); + + $cluster = Cluster::query()->where('name', 'Development-Lima')->sole(); + + expect($cluster->team_id)->toBe($team->id) + ->and($cluster->created_by_user_id)->toBe($user->id) + ->and($cluster->description)->toBe('Local Lima development cluster managed by scripts/dev.sh.') + ->and(V5Server::query()->count())->toBe(2) + ->and(V5Server::query()->where('name', 'coold-dev')->where('host', 'lima-coold-dev')->where('ssh_user', get_current_user())->where('ssh_port', 22)->exists())->toBeTrue() + ->and(V5Server::query()->where('name', 'coold-dev-2')->where('host', 'lima-coold-dev-2')->where('ssh_user', get_current_user())->where('ssh_port', 22)->exists())->toBeTrue() + ->and(V5Server::query()->where('status', 'installed')->count())->toBe(2) + ->and(V5Server::query()->where('builder_enabled', true)->where('builder_capacity', 2)->count())->toBe(2) + ->and(V5Server::query()->where('cluster_id', $cluster->id)->count())->toBe(2); +}); + function fakeFluxHealth(bool $available = true, string $message = 'Flux is running.'): void { app()->instance(FluxHealth::class, Mockery::mock(FluxHealth::class, function (MockInterface $mock) use ($available, $message) { From bc6a12d614028a964c4e5141023cec51c21a4863 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:18:12 +0200 Subject: [PATCH 012/178] docs: remove coold VM dev setup and container roles sections from README --- README.md | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/README.md b/README.md index 46204ea5e..b387d87e8 100644 --- a/README.md +++ b/README.md @@ -29,55 +29,6 @@ You can find the installation script source [here](./scripts/install.sh). > [!NOTE] > Please refer to the [docs](https://coolify.io/docs/installation) for more information about the installation. - -## Local dev with coold VM - -For v5 development that needs a packaged `coold` endpoint VM with Corrosion, use: - -```bash -scripts/dev.sh up -``` - -This starts two Lima endpoint VMs by default, configures a WireGuard mesh between them, starts the Docker stack in the background, mints dev host JWTs with `php artisan flux:dev --caps=coold,builder`, installs them into the VMs, starts each VM `coold` agent service with builder capacity, and follows Coolify + VM agent logs by default. Flux runs with the Coolify container, not inside the VM. Set `COOLIFY_COOLD_VM_COUNT=1` for a single endpoint, `COOLIFY_COOLD_VM_ENABLED=false` to skip the VMs, `COOLIFY_COOLD_VM_BUILDER_CAPACITY=0` to disable builder capability, or `COOLIFY_DEV_FOLLOW_LOGS=false` to leave `up` detached. Use `scripts/dev.sh down` to stop the stack and VM agent; set `COOLIFY_COOLD_VM_STOP_ON_DOWN=true` if you also want the VM stopped. The dev entrypoints are intentionally kept to `scripts/dev.sh` for the full stack and `scripts/coold-vm.sh` for VM-only operations. - -Useful Corrosion checks: - -```bash -scripts/dev.sh corrosion check -scripts/dev.sh corrosion containers -scripts/dev.sh corrosion config -scripts/dev.sh corrosion sql 'select count(*) from service_endpoints;' -``` - -## Container roles and Flux - -The Coolify image can run different process roles with `COOLIFY_CONTAINER_ROLE`. The value can be a single role or a comma-separated list. If `all` is present anywhere in the list, every role starts. - -- `all` (default): self-hosted mode; runs the web process, worker services, and Flux when configured. -- `web`: web/API process only; s6 worker services and Flux sleep unless they are also listed. -- `worker`: Horizon, Laravel scheduler worker, and optional Nightwatch agent. -- `horizon`: Horizon only. -- `scheduler` or `scheduler-worker`: Laravel scheduler worker only. -- `nightwatch` or `nightwatch-agent`: optional Nightwatch agent only. -- `flux`: Flux only; used by Cloud/HA deployments that scale coold connection routers separately. - -For example, `COOLIFY_CONTAINER_ROLE=web,flux` starts the web container plus Flux, while `COOLIFY_CONTAINER_ROLE=web,all` still starts all services. - -Flux is installed from the coold nightly release into `/usr/local/bin/flux`. Containers running the `all` or `flux` role expose Flux on port `6443` and use these runtime variables: - -```env -COOLIFY_FLUX_GRPC_BIND=0.0.0.0:6443 -COOLIFY_FLUX_UNIX_SOCKET_PATH=/run/coolify/flux.sock -COOLIFY_FLUX_JWT_PRIVATE_KEY_PATH=/var/www/html/storage/app/flux/jwt.priv -COOLIFY_FLUX_JWT_PUBLIC_KEY_PATH=/var/www/html/storage/app/flux/jwt.pub -COOLIFY_FLUX_ALLOW_PUBLIC_BIND=1 -COOLIFY_FLUX_ID=flux-eu-1 -COOLIFY_FLUX_PUBLIC_URL=grpcs://flux-eu-1.example.com:6443 -COOLIFY_FLUX_INTERNAL_URL=http://coolify-flux-eu-1.internal:6443 -``` - -If `COOLIFY_FLUX_ENABLED=false` is set, the Flux s6 service sleeps even for `all` and `flux` roles. The Flux s6 service creates a persistent JWT keypair on first boot when the key files are missing. The current Coolify image only installs the nightly Flux artifact during the Docker build; the s6 service verifies the binary at runtime and sleeps with a clear error if the published artifact is not compatible with the Alpine base image. - ## Support Contact us at [coolify.io/docs/contact](https://coolify.io/docs/contact). From c178dfdb394c1c5f480a85cf85654b6255887b26 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 16 Jun 2026 19:38:21 +0200 Subject: [PATCH 013/178] feat(v5): add shadcn/ui with button, select, separator, and navbar --- .agents/skills/shadcn/SKILL.md | 267 + .agents/skills/shadcn/agents/openai.yml | 5 + .agents/skills/shadcn/assets/shadcn-small.png | Bin 0 -> 1049 bytes .agents/skills/shadcn/assets/shadcn.png | Bin 0 -> 3852 bytes .agents/skills/shadcn/cli.md | 290 + .agents/skills/shadcn/customization.md | 209 + .agents/skills/shadcn/evals/evals.json | 47 + .agents/skills/shadcn/mcp.md | 105 + .agents/skills/shadcn/registry.md | 277 + .agents/skills/shadcn/rules/base-vs-radix.md | 306 + .agents/skills/shadcn/rules/composition.md | 195 + .agents/skills/shadcn/rules/forms.md | 192 + .agents/skills/shadcn/rules/icons.md | 101 + .agents/skills/shadcn/rules/styling.md | 162 + .claude/skills/shadcn | 1 + app/Http/Controllers/V5/HomeController.php | 128 + components.json | 25 + jsconfig.json | 9 + package-lock.json | 5569 ++++++++++++++++- package.json | 10 +- resources/css/v5/app.css | 165 +- resources/js/v5/Pages/Home.jsx | 63 +- resources/js/v5/components/app-navbar.jsx | 119 + resources/js/v5/components/ui/button.jsx | 61 + resources/js/v5/components/ui/select.jsx | 185 + resources/js/v5/components/ui/separator.jsx | 27 + resources/js/v5/lib/utils.js | 6 + resources/views/v5/app.blade.php | 31 +- routes/v5.php | 1 + skills-lock.json | 11 + tests/Feature/V5/HomeTest.php | 274 +- vite.config.js | 21 +- 32 files changed, 8788 insertions(+), 74 deletions(-) create mode 100644 .agents/skills/shadcn/SKILL.md create mode 100644 .agents/skills/shadcn/agents/openai.yml create mode 100644 .agents/skills/shadcn/assets/shadcn-small.png create mode 100644 .agents/skills/shadcn/assets/shadcn.png create mode 100644 .agents/skills/shadcn/cli.md create mode 100644 .agents/skills/shadcn/customization.md create mode 100644 .agents/skills/shadcn/evals/evals.json create mode 100644 .agents/skills/shadcn/mcp.md create mode 100644 .agents/skills/shadcn/registry.md create mode 100644 .agents/skills/shadcn/rules/base-vs-radix.md create mode 100644 .agents/skills/shadcn/rules/composition.md create mode 100644 .agents/skills/shadcn/rules/forms.md create mode 100644 .agents/skills/shadcn/rules/icons.md create mode 100644 .agents/skills/shadcn/rules/styling.md create mode 120000 .claude/skills/shadcn create mode 100644 components.json create mode 100644 jsconfig.json create mode 100644 resources/js/v5/components/app-navbar.jsx create mode 100644 resources/js/v5/components/ui/button.jsx create mode 100644 resources/js/v5/components/ui/select.jsx create mode 100644 resources/js/v5/components/ui/separator.jsx create mode 100644 resources/js/v5/lib/utils.js create mode 100644 skills-lock.json diff --git a/.agents/skills/shadcn/SKILL.md b/.agents/skills/shadcn/SKILL.md new file mode 100644 index 000000000..dcdb75458 --- /dev/null +++ b/.agents/skills/shadcn/SKILL.md @@ -0,0 +1,267 @@ +--- +name: shadcn +description: Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn/ui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn init", "create an app with --preset", or "switch to --preset". +user-invocable: false +allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *) +--- + +# shadcn/ui + +A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI. + +> **IMPORTANT:** Run all CLI commands using the project's package runner: `npx shadcn@latest`, `pnpm dlx shadcn@latest`, or `bunx --bun shadcn@latest` — based on the project's `packageManager`. Examples below use `npx shadcn@latest` but substitute the correct runner for the project. + +## Current Project Context + +```json +!`npx shadcn@latest info --json` +``` + +The JSON above contains the project config and installed components. Use `npx shadcn@latest docs ` to get documentation and example URLs for any component. + +## Principles + +1. **Use existing components first.** Use `npx shadcn@latest search` to check registries before writing custom UI. Check community registries too. +2. **Compose, don't reinvent.** Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table. +3. **Use built-in variants before custom styles.** `variant="outline"`, `size="sm"`, etc. +4. **Use semantic colors.** `bg-primary`, `text-muted-foreground` — never raw values like `bg-blue-500`. + +## Critical Rules + +These rules are **always enforced**. Each links to a file with Incorrect/Correct code pairs. + +### Styling & Tailwind → [styling.md](./rules/styling.md) + +- **`className` for layout, not styling.** Never override component colors or typography. +- **No `space-x-*` or `space-y-*`.** Use `flex` with `gap-*`. For vertical stacks, `flex flex-col gap-*`. +- **Use `size-*` when width and height are equal.** `size-10` not `w-10 h-10`. +- **Use `truncate` shorthand.** Not `overflow-hidden text-ellipsis whitespace-nowrap`. +- **No manual `dark:` color overrides.** Use semantic tokens (`bg-background`, `text-muted-foreground`). +- **Use `cn()` for conditional classes.** Don't write manual template literal ternaries. +- **No manual `z-index` on overlay components.** Dialog, Sheet, Popover, etc. handle their own stacking. + +### Forms & Inputs → [forms.md](./rules/forms.md) + +- **Forms use `FieldGroup` + `Field`.** Never use raw `div` with `space-y-*` or `grid gap-*` for form layout. +- **`InputGroup` uses `InputGroupInput`/`InputGroupTextarea`.** Never raw `Input`/`Textarea` inside `InputGroup`. +- **Buttons inside inputs use `InputGroup` + `InputGroupAddon`.** +- **Option sets (2–7 choices) use `ToggleGroup`.** Don't loop `Button` with manual active state. +- **`FieldSet` + `FieldLegend` for grouping related checkboxes/radios.** Don't use a `div` with a heading. +- **Field validation uses `data-invalid` + `aria-invalid`.** `data-invalid` on `Field`, `aria-invalid` on the control. For disabled: `data-disabled` on `Field`, `disabled` on the control. + +### Component Structure → [composition.md](./rules/composition.md) + +- **Items always inside their Group.** `SelectItem` → `SelectGroup`. `DropdownMenuItem` → `DropdownMenuGroup`. `CommandItem` → `CommandGroup`. +- **Use `asChild` (radix) or `render` (base) for custom triggers.** Check `base` field from `npx shadcn@latest info`. → [base-vs-radix.md](./rules/base-vs-radix.md) +- **Dialog, Sheet, and Drawer always need a Title.** `DialogTitle`, `SheetTitle`, `DrawerTitle` required for accessibility. Use `className="sr-only"` if visually hidden. +- **Use full Card composition.** `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`. Don't dump everything in `CardContent`. +- **Button has no `isPending`/`isLoading`.** Compose with `Spinner` + `data-icon` + `disabled`. +- **`TabsTrigger` must be inside `TabsList`.** Never render triggers directly in `Tabs`. +- **`Avatar` always needs `AvatarFallback`.** For when the image fails to load. + +### Use Components, Not Custom Markup → [composition.md](./rules/composition.md) + +- **Use existing components before custom markup.** Check if a component exists before writing a styled `div`. +- **Callouts use `Alert`.** Don't build custom styled divs. +- **Empty states use `Empty`.** Don't build custom empty state markup. +- **Toast via `sonner`.** Use `toast()` from `sonner`. +- **Use `Separator`** instead of `
` or `
`. +- **Use `Skeleton`** for loading placeholders. No custom `animate-pulse` divs. +- **Use `Badge`** instead of custom styled spans. + +### Icons → [icons.md](./rules/icons.md) + +- **Icons in `Button` use `data-icon`.** `data-icon="inline-start"` or `data-icon="inline-end"` on the icon. +- **No sizing classes on icons inside components.** Components handle icon sizing via CSS. No `size-4` or `w-4 h-4`. +- **Pass icons as objects, not string keys.** `icon={CheckIcon}`, not a string lookup. + +### CLI + +- **Never decode preset codes or build preset URLs manually.** Use `npx shadcn@latest preset decode `, `preset url `, or `preset open `. For project-aware preset detection, use `npx shadcn@latest preset resolve`. +- **Apply preset codes directly with the CLI.** Use `npx shadcn@latest apply ` for existing projects, or `npx shadcn@latest init --preset ` when initializing. + +## Key Patterns + +These are the most common patterns that differentiate correct shadcn/ui code. For edge cases, see the linked rule files above. + +```tsx +// Form layout: FieldGroup + Field, not div + Label. + + + Email + + + + +// Validation: data-invalid on Field, aria-invalid on the control. + + Email + + Invalid email. + + +// Icons in buttons: data-icon, no sizing classes. + + +// Spacing: gap-*, not space-y-*. +
// correct +
// wrong + +// Equal dimensions: size-*, not w-* h-*. + // correct + // wrong + +// Status colors: Badge variants or semantic tokens, not raw colors. ++20.1% // correct ++20.1% // wrong +``` + +## Component Selection + +| Need | Use | +| -------------------------- | --------------------------------------------------------------------------------------------------- | +| Button/action | `Button` with appropriate variant | +| Form inputs | `Input`, `Select`, `Combobox`, `Switch`, `Checkbox`, `RadioGroup`, `Textarea`, `InputOTP`, `Slider` | +| Toggle between 2–5 options | `ToggleGroup` + `ToggleGroupItem` | +| Data display | `Table`, `Card`, `Badge`, `Avatar` | +| Navigation | `Sidebar`, `NavigationMenu`, `Breadcrumb`, `Tabs`, `Pagination` | +| Overlays | `Dialog` (modal), `Sheet` (side panel), `Drawer` (bottom sheet), `AlertDialog` (confirmation) | +| Feedback | `sonner` (toast), `Alert`, `Progress`, `Skeleton`, `Spinner` | +| Command palette | `Command` inside `Dialog` | +| Charts | `Chart` (wraps Recharts) | +| Layout | `Card`, `Separator`, `Resizable`, `ScrollArea`, `Accordion`, `Collapsible` | +| Empty states | `Empty` | +| Menus | `DropdownMenu`, `ContextMenu`, `Menubar` | +| Tooltips/info | `Tooltip`, `HoverCard`, `Popover` | + +## Key Fields + +The injected project context contains these key fields: + +- **`aliases`** → use the actual alias prefix for imports (e.g. `@/`, `~/`), never hardcode. +- **`isRSC`** → when `true`, components using `useState`, `useEffect`, event handlers, or browser APIs need `"use client"` at the top of the file. Always reference this field when advising on the directive. +- **`tailwindVersion`** → `"v4"` uses `@theme inline` blocks; `"v3"` uses `tailwind.config.js`. +- **`tailwindCssFile`** → the global CSS file where custom CSS variables are defined. Always edit this file, never create a new one. +- **`style`** → component visual treatment (e.g. `nova`, `vega`). +- **`base`** → primitive library (`radix` or `base`). Affects component APIs and available props. +- **`iconLibrary`** → determines icon imports. Use `lucide-react` for `lucide`, `@tabler/icons-react` for `tabler`, etc. Never assume `lucide-react`. +- **`resolvedPaths`** → exact file-system destinations for components, utils, hooks, etc. +- **`framework`** → routing and file conventions (e.g. Next.js App Router vs Vite SPA). +- **`packageManager`** → use this for any non-shadcn dependency installs (e.g. `pnpm add date-fns` vs `npm install date-fns`). +- **`preset`** → resolved preset code and values for the current project. Use `npx shadcn@latest preset resolve --json` when you only need preset information. + +See [cli.md — `info` command](./cli.md) for the full field reference. + +## Component Docs, Examples, and Usage + +Run `npx shadcn@latest docs ` to get the URLs for a component's documentation, examples, and API reference. Fetch these URLs to get the actual content. + +```bash +npx shadcn@latest docs button dialog select +``` + +**When creating, fixing, debugging, or using a component, always run `npx shadcn@latest docs` and fetch the URLs first.** This ensures you're working with the correct API and usage patterns rather than guessing. + +## Workflow + +1. **Get project context** — already injected above. Run `npx shadcn@latest info` again if you need to refresh. +2. **Check installed components first** — before running `add`, always check the `components` list from project context or list the `resolvedPaths.ui` directory. Don't import components that haven't been added, and don't re-add ones already installed. +3. **Find components** — `npx shadcn@latest search`. +4. **Get docs and examples** — run `npx shadcn@latest docs ` to get URLs, then fetch them. Use `npx shadcn@latest view` to browse registry items you haven't installed. To preview changes to installed components, use `npx shadcn@latest add --diff`. +5. **Install or update** — `npx shadcn@latest add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components](#updating-components) below). +6. **Fix imports in third-party components** — After adding components from community registries (e.g. `@bundui`, `@magicui`), check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `npx shadcn@latest info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project. +7. **Review added components** — After adding a component or block from any registry, **always read the added files and verify they are correct**. Check for missing sub-components (e.g. `SelectItem` without `SelectGroup`), missing imports, incorrect composition, or violations of the [Critical Rules](#critical-rules). Also replace any icon imports with the project's `iconLibrary` from the project context (e.g. if the registry item uses `lucide-react` but the project uses `hugeicons`, swap the imports and icon names accordingly). Fix all issues before moving on. +8. **Registry must be explicit** — When the user asks to add a block or component, **do not guess the registry**. If no registry is specified (e.g. user says "add a login block" without specifying `@shadcn`, `@tailark`, `owner/repo`, etc.), ask which registry to use. Never default to a registry on behalf of the user. +9. **Switching presets** — Ask the user first: **overwrite**, **partial**, **merge**, or **skip**? + - **Inspect current preset**: `npx shadcn@latest preset resolve`. Use `--json` when you need structured values. + - **Inspect incoming preset**: `npx shadcn@latest preset decode `. Use `preset url ` or `preset open ` to share or open the preset builder. + - **Overwrite**: `npx shadcn@latest apply `. Overwrites detected components, fonts, and CSS variables. + - **Partial**: `npx shadcn@latest apply --only theme,font`. Updates only the selected preset parts without reinstalling UI components. Supported values are `theme` and `font`; comma-separated combinations are allowed. `icon` is intentionally not supported, because icon changes may require full component reinstall and transforms. + - **Merge**: `npx shadcn@latest init --preset --force --no-reinstall`, then run `npx shadcn@latest info` to list installed components, then for each installed component use `--dry-run` and `--diff` to [smart merge](#updating-components) it individually. + - **Skip**: `npx shadcn@latest init --preset --force --no-reinstall`. Only updates config and CSS, leaves components as-is. + - **Important**: Always run preset commands inside the user's project directory. `apply` only works in an existing project with a `components.json` file. The CLI automatically preserves the current base (`base` vs `radix`) from `components.json`. If you must use a scratch/temp directory (e.g. for `--dry-run` comparisons), pass `--base ` explicitly — preset codes do not encode the base. + +## Updating Components + +When the user asks to update a component from upstream while keeping their local changes, use `--dry-run` and `--diff` to intelligently merge. **NEVER fetch raw files from GitHub manually — always use the CLI.** + +1. Run `npx shadcn@latest add --dry-run` to see all files that would be affected. +2. For each file, run `npx shadcn@latest add --diff ` to see what changed upstream vs local. +3. Decide per file based on the diff: + - No local changes → safe to overwrite. + - Has local changes → read the local file, analyze the diff, and apply upstream updates while preserving local modifications. + - User says "just update everything" → use `--overwrite`, but confirm first. +4. **Never use `--overwrite` without the user's explicit approval.** + +## Quick Reference + +```bash +# Create a new project. +npx shadcn@latest init --name my-app --preset base-nova +npx shadcn@latest init --name my-app --preset a2r6bw --template vite + +# Create a monorepo project. +npx shadcn@latest init --name my-app --preset base-nova --monorepo +npx shadcn@latest init --name my-app --preset base-nova --template next --monorepo + +# Initialize existing project. +npx shadcn@latest init --preset base-nova +npx shadcn@latest init --defaults # shortcut: --template=next --preset=nova (base style implied) + +# Apply a preset to an existing project. +npx shadcn@latest apply a2r6bw +npx shadcn@latest apply a2r6bw --only theme +npx shadcn@latest apply a2r6bw --only font +npx shadcn@latest apply a2r6bw --only theme,font + +# Inspect preset codes and project preset state. +npx shadcn@latest preset decode a2r6bw +npx shadcn@latest preset url a2r6bw +npx shadcn@latest preset open a2r6bw +npx shadcn@latest preset resolve +npx shadcn@latest preset resolve --json + +# Add components. +npx shadcn@latest add button card dialog +npx shadcn@latest add @magicui/shimmer-button +npx shadcn@latest add owner/repo/item +npx shadcn@latest add --all + +# Preview changes before adding/updating. +npx shadcn@latest add button --dry-run +npx shadcn@latest add button --diff button.tsx +npx shadcn@latest add @acme/form --view button.tsx +npx shadcn@latest add owner/repo/item --dry-run + +# Search registries. +npx shadcn@latest search @shadcn -q "sidebar" +npx shadcn@latest search @tailark -q "stats" +npx shadcn@latest search owner/repo -q "login" +npx shadcn@latest search # all configured registries +npx shadcn@latest search @shadcn -q "menu" -t ui # filter by item type + +# Get component docs and example URLs. +npx shadcn@latest docs button dialog select + +# View registry item details (for items not yet installed). +npx shadcn@latest view @shadcn/button +npx shadcn@latest view owner/repo/item +``` + +**Named presets:** `nova`, `vega`, `maia`, `lyra`, `mira`, `luma` +**Templates:** `next`, `vite`, `start`, `react-router`, `astro` (all support `--monorepo`) and `laravel` (not supported for monorepo) +**Preset codes:** Version-prefixed base62 strings (e.g. `a2r6bw` or `b0`), from [ui.shadcn.com](https://ui.shadcn.com). + +## Detailed References + +- [rules/forms.md](./rules/forms.md) — FieldGroup, Field, InputGroup, ToggleGroup, FieldSet, validation states +- [rules/composition.md](./rules/composition.md) — Groups, overlays, Card, Tabs, Avatar, Alert, Empty, Toast, Separator, Skeleton, Badge, Button loading +- [rules/icons.md](./rules/icons.md) — data-icon, icon sizing, passing icons as objects +- [rules/styling.md](./rules/styling.md) — Semantic colors, variants, className, spacing, size, truncate, dark mode, cn(), z-index +- [rules/base-vs-radix.md](./rules/base-vs-radix.md) — asChild vs render, Select, ToggleGroup, Slider, Accordion +- [cli.md](./cli.md) — Commands, flags, presets, templates +- [registry.md](./registry.md) — Authoring source registries, `include`, item definitions, dependencies, GitHub registry rules +- [customization.md](./customization.md) — Theming, CSS variables, extending components diff --git a/.agents/skills/shadcn/agents/openai.yml b/.agents/skills/shadcn/agents/openai.yml new file mode 100644 index 000000000..ab636da86 --- /dev/null +++ b/.agents/skills/shadcn/agents/openai.yml @@ -0,0 +1,5 @@ +interface: + display_name: "shadcn/ui" + short_description: "Manages shadcn/ui components — adding, searching, fixing, debugging, styling, and composing UI." + icon_small: "./assets/shadcn-small.png" + icon_large: "./assets/shadcn.png" diff --git a/.agents/skills/shadcn/assets/shadcn-small.png b/.agents/skills/shadcn/assets/shadcn-small.png new file mode 100644 index 0000000000000000000000000000000000000000..547154b97f2298335159c23eec1dac0d147a1246 GIT binary patch literal 1049 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBDAAG{;hE;^%b*2hb1<+n z3NbJPS&Tr)z$nE4G7ZRL@M4sPvx68lplX;H7}_%#SfFa6fHVkr05M1pgl1mAh%j*h z6I`{x0%imor0saV%ts)_S>O>_%)r1c48n{Iv*t(uO^eJ7i71Ki^|4CM&(%vz$xlkv ztH>0+>{umUo3Q%e#RDspr3imfVamB1>jfNYSkzLEl1NlCV?QiN}Sf^&XRs)CuG zfu4bq9hZWFf=y9MnpKdC8&o@xXRDM^Qc_^0uU}qXu2*iXmtT~wZ)j<0sc&GUZ)Btk zRH0j3nOBlnp_^B%3^4>|j!SBBa#3bMNoIbY0?6FNr2NtnTO}osMQ{LdXGvxn!lt}p zsJDO~)CbAv8|oS8!_5Y2wE>A*`4?rT0&NDFZ)a!&R*518wZ}#uWI2*!AU*|)0=;U- zWup%dHajlKxQFb(K%V94;uvBfm>Yb$>yU#$kCbgiC(9RwrlwA(rsW(``(6H=zq@!* zUB_~Trk_lTdxPh$yxDTsVY&L;b+6{tRm^+d+gl^OQcCIBok=%y)Vhx@dR1ceL3r{0 z9=2nMXx8DxEkhL{v?(>~8{qDBkfB!u-iDB`| z-5d%Ae82YI%n8Zg9$mRN?o-|V)V*=5b-R>a>}P2{=pcK^B(&B-W{C#Z!Q%b*ueK>n zK6ymYLRneebCKDSzcqHEHFopo-mkH{zIkt2Z0^086Tko7%N)NxoZYSDM1jSUwPpuS zSeq*wzrC2D(tq4pZ#s9QP@Cd8Q^wW3*2cL_519?*;#4`B;+ei#o;C{Kkamm3Jooa; zE$3K-+c(6ShTjelW_B*W5o zcS6z34IR5C-SIF8m(lui^IOy!-~We?b1?PSGniCYR=ZyR^%<1lJzf1=);T3K0RU@N BSy=!8 literal 0 HcmV?d00001 diff --git a/.agents/skills/shadcn/assets/shadcn.png b/.agents/skills/shadcn/assets/shadcn.png new file mode 100644 index 0000000000000000000000000000000000000000..b7b6814acc25073e5f48099b1fd3f70c47bfb1c3 GIT binary patch literal 3852 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 **IMPORTANT:** Always run commands using the project's package runner: `npx shadcn@latest`, `pnpm dlx shadcn@latest`, or `bunx --bun shadcn@latest`. Check `packageManager` from project context to choose the right one. Examples below use `npx shadcn@latest` but substitute the correct runner for the project. + +> **IMPORTANT:** Only use the flags documented below. Do not invent or guess flags — if a flag isn't listed here, it doesn't exist. The CLI auto-detects the package manager from the project's lockfile; there is no `--package-manager` flag. + +## Contents + +- Commands: init, apply, add (dry-run, smart merge), search, view, docs, info, build +- Templates: next, vite, start, react-router, astro +- Presets: named, code, URL formats and fields +- Switching presets + +--- + +## Commands + +### `init` — Initialize or create a project + +```bash +npx shadcn@latest init [components...] [options] +``` + +Initializes shadcn/ui in an existing project or creates a new project (when `--name` is provided). Optionally installs components in the same step. + +| Flag | Short | Description | Default | +| ----------------------- | ----- | --------------------------------------------------------- | ------- | +| `--template