5 KiB
5 KiB
Codex Task: Core App — FrankenPHP Native Desktop App
Context
You are working on cmd/core-app/ inside the host-uk/core Go monorepo. This is a working native desktop application that embeds the PHP runtime (FrankenPHP) inside a Wails v3 window. A single 53MB binary runs Laravel 12 with Livewire 4, Octane worker mode, and SQLite — no Docker, no php-fpm, no nginx, no external dependencies.
It already builds and runs. Your job is to refine, not rebuild.
Architecture
Wails v3 WebView (native window)
|
| AssetOptions.Handler → http.Handler
v
FrankenPHP (CGO, PHP 8.4 ZTS runtime)
|
| ServeHTTP() → Laravel public/index.php
v
Laravel 12 (Octane worker mode, 2 workers)
├── Livewire 4 (server-rendered reactivity)
├── SQLite (~/Library/Application Support/core-app/)
└── Native Bridge (localhost HTTP API for PHP→Go calls)
Key Files
| File | Purpose |
|---|---|
main.go |
Wails app entry, system tray, window config |
handler.go |
PHPHandler — FrankenPHP init, Octane worker mode, try_files URL resolution |
embed.go |
//go:embed all:laravel + extraction to temp dir |
env.go |
Persistent data dir, .env generation, APP_KEY management |
app_service.go |
Wails service bindings (version, data dir, window management) |
native_bridge.go |
PHP→Go HTTP bridge on localhost (random port) |
laravel/ |
Full Laravel 12 skeleton (vendor excluded from git, built via composer install) |
Build Requirements
- PHP 8.4 ZTS:
brew install shivammathur/php/php@8.4-zts - Go 1.25+ with CGO enabled
- Build tags:
-tags nowatcher(FrankenPHP's watcher needs libwatcher-c, skip it) - ZTS php-config: Must use
/opt/homebrew/opt/php@8.4-zts/bin/php-config(NOT the default php-config which may point to non-ZTS PHP)
# Install Laravel deps (one-time)
cd laravel && composer install --no-dev --optimize-autoloader
# Build
ZTS_PHP_CONFIG=/opt/homebrew/opt/php@8.4-zts/bin/php-config
CGO_ENABLED=1 \
CGO_CFLAGS="$($ZTS_PHP_CONFIG --includes)" \
CGO_LDFLAGS="-L/opt/homebrew/opt/php@8.4-zts/lib $($ZTS_PHP_CONFIG --ldflags) $($ZTS_PHP_CONFIG --libs)" \
go build -tags nowatcher -o ../../bin/core-app .
Known Patterns & Gotchas
- FrankenPHP can't serve from embed.FS — must extract to temp dir, symlink
storage/to persistent data dir - WithWorkers API (v1.5.0):
WithWorkers(name, fileName string, num int, env map[string]string, watch []string)— 5 positional args, NOT variadic - Worker mode needs Octane: Workers point at
vendor/laravel/octane/bin/frankenphp-worker.phpwithAPP_BASE_PATHandFRANKENPHP_WORKER=1env vars - Paths with spaces: macOS
~/Library/Application Support/has a space — ALL .env values with paths MUST be quoted - URL resolution: FrankenPHP doesn't auto-resolve
/→/index.php— the Go handler implements try_files logic - Auto-migration:
AppServiceProvider::boot()runsmigrate --forcewrapped in try/catch (must not fail during composer operations) - Vendor dir: Excluded from git (
.gitignore), built at dev time viacomposer install, embedded by//go:embed all:laravelat build time
Coding Standards
- UK English: colour, organisation, centre
- PHP:
declare(strict_types=1)in every file, full type hints, PSR-12 via Pint - Go: Standard Go conventions, error wrapping with
fmt.Errorf("context: %w", err) - License: EUPL-1.2
- Testing: Pest syntax for PHP (not PHPUnit)
Tasks for Codex
Priority 1: Code Quality
- Review all Go files for error handling consistency
- Ensure handler.go's try_files logic handles edge cases (double slashes, encoded paths, path traversal)
- Add Go tests for PHPHandler URL resolution (unit tests, no FrankenPHP needed)
- Add Go tests for env.go (resolveDataDir, writeEnvFile, loadOrGenerateAppKey)
Priority 2: Laravel Polish
- Add
config/octane.phpwith FrankenPHP server config - Update welcome view to show migration status (table count from SQLite)
- Add a second Livewire component (e.g., todo list) to prove full CRUD with SQLite
- Add proper error page views (404, 500) styled to match the dark theme
Priority 3: Build Hardening
- Verify the Taskfile.yml tasks work end-to-end (
task app:setup && task app:composer && task app:build) - Add
.gitignoreentries for build artifacts (bin/core-app, temp dirs) - Ensure
go.workandgo.modare consistent
CRITICAL WARNINGS
- DO NOT push to GitHub — GitHub remotes have been removed deliberately. The host-uk org is flagged.
- DO NOT add GitHub as a remote — Forge (forge.lthn.ai / git.lthn.ai) is the source of truth.
- DO NOT modify files outside
cmd/core-app/— This is a workspace module, keep changes scoped. - DO NOT remove the
-tags nowatcherbuild flag — It will fail without libwatcher-c. - DO NOT change the PHP-ZTS path — It must be the ZTS variant, not the default Homebrew PHP.