commit ea211e142148262d73f847237db002cfe9c713dd Author: Zhongwei Li Date: Sun Nov 30 08:50:21 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..178d6f3 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "frankenphp", + "description": "Interacts with the FrankenPHP App Server.", + "version": "0.0.0-2025.11.28", + "author": { + "name": "Tim Green", + "email": "rawveg@gmail.com" + }, + "skills": [ + "./skills/frankenphp" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5e730a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# frankenphp + +Interacts with the FrankenPHP App Server. diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..fb1983c --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,56 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:rawveg/skillsforge-marketplace:frankenphp", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "6645323cb8690377b9ada43a278ac1d57a774e0a", + "treeHash": "3b48f304a9effffdd4bef1dc9901cbc44c9f748fcc1cf22a4807c901650e890c", + "generatedAt": "2025-11-28T10:27:51.003459Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "frankenphp", + "description": "Interacts with the FrankenPHP App Server." + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "f2646a8392f23c91812bcd3efc04bf3278404076b188e9c45690a1e3b48f75f2" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "99602f15c3904e854b1330e5b1cb053e022cbf0182732d6512b8affbe116f27a" + }, + { + "path": "skills/frankenphp/plugin.json", + "sha256": "344a45e37dec7746748e2195b8461812c881eacafd74b057043a1b610dee294b" + }, + { + "path": "skills/frankenphp/SKILL.md", + "sha256": "591dcc23481ced5a369c1929b6d6cbc22470225f6dff35881c6d6abcf21c60ad" + }, + { + "path": "skills/frankenphp/references/index.md", + "sha256": "82e439f88f4cbc5cc892165a4672f7a44f788d7739d1817a4b113b2406754160" + }, + { + "path": "skills/frankenphp/references/other.md", + "sha256": "29a7025b2eabc518d5376db7de44b164767c7f136b158b307198b287c516a2b8" + } + ], + "dirSha256": "3b48f304a9effffdd4bef1dc9901cbc44c9f748fcc1cf22a4807c901650e890c" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/frankenphp/SKILL.md b/skills/frankenphp/SKILL.md new file mode 100644 index 0000000..466faa0 --- /dev/null +++ b/skills/frankenphp/SKILL.md @@ -0,0 +1,357 @@ +--- +name: frankenphp +description: FrankenPHP Documentation - Modern PHP application server built on Caddy +--- + +# FrankenPHP Skill + +Comprehensive assistance with FrankenPHP development - a modern PHP application server built on top of the Caddy web server. FrankenPHP enables persistent PHP processes with worker mode, automatic HTTPS, HTTP/2, HTTP/3, and real-time capabilities via Mercure integration. + +## When to Use This Skill + +This skill should be triggered when: +- Setting up or configuring FrankenPHP server +- Implementing FrankenPHP worker mode for performance optimization +- Integrating FrankenPHP with Laravel, Symfony, or other PHP frameworks +- Deploying PHP applications with Docker using FrankenPHP +- Converting traditional PHP apps to use persistent workers +- Configuring automatic HTTPS, HTTP/2, or HTTP/3 +- Implementing real-time features with Mercure +- Creating standalone, self-executable PHP applications +- Optimizing PHP application performance with persistent processes +- Troubleshooting FrankenPHP worker mode or configuration issues + +## Quick Reference + +### Installation & Basic Server + +**Install via curl (Linux/macOS):** +```bash +curl https://frankenphp.dev/install.sh | sh +mv frankenphp /usr/local/bin/ + +# Start server in current directory +frankenphp php-server +``` + +**Install via Homebrew:** +```bash +brew install dunglas/frankenphp/frankenphp +frankenphp php-server +``` + +**Quick Docker deployment:** +```bash +docker run -v $PWD:/app/public \ + -p 80:80 -p 443:443 -p 443:443/udp \ + dunglas/frankenphp +``` + +### Basic Worker Mode + +**Start worker with standalone binary:** +```bash +frankenphp php-server --worker /path/to/your/worker/script.php +``` + +**Docker with worker mode:** +```bash +docker run \ + -e FRANKENPHP_CONFIG="worker /app/public/index.php" \ + -v $PWD:/app \ + -p 80:80 -p 443:443 -p 443:443/udp \ + dunglas/frankenphp +``` + +**Worker with 42 processes:** +```bash +docker run \ + -e FRANKENPHP_CONFIG="worker ./public/index.php 42" \ + -v $PWD:/app \ + -p 80:80 -p 443:443 -p 443:443/udp \ + dunglas/frankenphp +``` + +### Custom Worker Script + +**Basic worker pattern:** +```php +boot(); + +$handler = static function () use ($myApp) { + try { + echo $myApp->handle($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER); + } catch (\Throwable $exception) { + (new \MyCustomExceptionHandler)->handleException($exception); + } +}; + +$maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0); +for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests) { + $keepRunning = \frankenphp_handle_request($handler); + $myApp->terminate(); + gc_collect_cycles(); + if (!$keepRunning) break; +} + +$myApp->shutdown(); +``` + +### Laravel Integration + +**Laravel Octane installation:** +```bash +composer require laravel/octane +php artisan octane:install --server=frankenphp +php artisan octane:frankenphp +``` + +**Laravel with Docker:** +```bash +docker run -p 80:80 -p 443:443 -p 443:443/udp \ + -v $PWD:/app \ + dunglas/frankenphp +``` + +**Laravel Caddyfile:** +``` +{ + frankenphp +} + +localhost { + root public/ + encode zstd br gzip + php_server { + try_files {path} index.php + } +} +``` + +**Octane with file watching:** +```bash +php artisan octane:frankenphp --watch +``` + +### Symfony Integration + +**Symfony worker with runtime:** +```bash +composer require runtime/frankenphp-symfony + +docker run \ + -e FRANKENPHP_CONFIG="worker ./public/index.php" \ + -e APP_RUNTIME=Runtime\\FrankenPhpSymfony\\Runtime \ + -v $PWD:/app \ + -p 80:80 -p 443:443 -p 443:443/udp \ + dunglas/frankenphp +``` + +### Worker Management + +**Watch files for changes (auto-reload):** +```bash +frankenphp php-server --worker /path/to/worker.php \ + --watch="/path/to/your/app/**/*.php" +``` + +**Restart workers via API:** +```bash +curl -X POST http://localhost:2019/frankenphp/workers/restart +``` + +**Configure max consecutive failures (Caddyfile):** +``` +frankenphp { + worker { + max_consecutive_failures 10 + } +} +``` + +### Superglobals in Worker Mode + +**Accessing worker-bound vs request-bound values:** +```php +