jpskill.com
🛠️ 開発・MCP コミュニティ

pelican-panel-plugins

Pelicanゲームパネルのプラグイン開発を支援し、機能追加、設定、権限、ルーティングなど、拡張に関するあらゆる質問に対応することで、開発者がより簡単にPelicanの機能を拡張できるようにするSkill。

📜 元の英語説明(参考)

Write, scaffold, explain, and debug plugins for the Pelican gaming panel. Use this skill whenever the user wants to create a Pelican plugin, add functionality to the Pelican panel, build a FilamentPHP resource or page for Pelican, register custom permissions, add plugin settings, write plugin routes, or asks anything about Pelican plugin development — even if they just say "I want to add something to Pelican" or "how do I extend Pelican".

🇯🇵 日本人クリエイター向け解説

一言でいうと

Pelicanゲームパネルのプラグイン開発を支援し、機能追加、設定、権限、ルーティングなど、拡張に関するあらゆる質問に対応することで、開発者がより簡単にPelicanの機能を拡張できるようにするSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o pelican-panel-plugins.zip https://jpskill.com/download/8683.zip && unzip -o pelican-panel-plugins.zip && rm pelican-panel-plugins.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/8683.zip -OutFile "$d\pelican-panel-plugins.zip"; Expand-Archive "$d\pelican-panel-plugins.zip" -DestinationPath $d -Force; ri "$d\pelican-panel-plugins.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して pelican-panel-plugins.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → pelican-panel-plugins フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Pelican Panel Plugins

Pelican は Laravel + FilamentPHP 上に構築されたオープンソースのゲームサーバー管理パネルです。プラグインを使用すると、コアファイルに触れることなく機能を追加できます。

⚠️ プラグインシステムは現在も活発に開発中です。一部の機能は変更される可能性があります。

クイックリファレンス

📖 詳細ガイド:

新しいプラグインの Scaffolding

パネルディレクトリ内(デフォルトでは /var/www/pelican)で実行します。

php artisan p:plugin:make

これにより、plugin.json、メインプラグインクラス、サービスプロバイダー、および設定ファイルを含む基本的な構造が作成されます。

重要: プラグインフォルダ名は、plugin.jsonid フィールドと完全に一致する必要があります。

プラグインの構造

plugins/my-plugin/
├── plugin.json              # メタデータと設定
├── config/
│   └── my-plugin.php       # 設定値 (env 変数を使用)
├── database/
│   └── migrations/         # 自動検出されるマイグレーション
├── lang/                   # 翻訳 (名前空間: my-plugin::strings.key)
├── resources/
│   └── views/              # Blade ビュー (名前空間: my-plugin::view-name)
├── routes/                 # オプションのルートファイル
└── src/                    # アプリケーションロジック (PSR-4 オートロード)
    ├── MyPlugin.php        # メインプラグインクラス
    ├── Filament/
    │   ├── Admin/          # 管理パネルコンポーネント
    │   │   ├── Pages/
    │   │   ├── Resources/
    │   │   └── Widgets/
    │   ├── App/            # サーバーリストパネル
    │   └── Server/         # サーバー管理パネル
    ├── Models/
    ├── Policies/           # 自動検出される
    ├── Providers/          # 自動検出されるサービスプロバイダー
    ├── Console/Commands/   # 自動検出される artisan コマンド
    └── Http/
        └── Controllers/

標準の Laravel の場所にあるものはすべて自動検出されます: マイグレーション、プロバイダー、コマンド、ポリシー。

plugin.json

{
    "id": "my-plugin",
    "name": "My Plugin",
    "author": "Your Name",
    "version": "1.0.0",
    "description": "Short description",
    "category": "plugin",
    "namespace": "MyName\\MyPlugin",
    "class": "MyPlugin",
    "panels": ["admin", "server"],
    "panel_version": "^1.2.0",
    "composer_packages": {
        "vendor/package": "^1.0"
    }
}
フィールド 必須
id フォルダ名と一致する必要があります
namespace PHP 名前空間ルート (\ はバックスラッシュに使用)
class メインクラス名 (src/ 内)
category plugintheme、または language
panels いいえ パネル ID の配列。すべてのパネルの場合は省略
panel_version いいえ 最小パネルバージョン (例: ^1.2.0)
composer_packages いいえ 外部依存関係

メインプラグインクラス

src/{ClassName}.php にあります:

namespace MyName\MyPlugin;

use Filament\Contracts\Plugin;
use Filament\Panel;

class MyPlugin implements Plugin
{
    public function getId(): string
    {
        return 'my-plugin';
    }

    public function register(Panel $panel): void
    {
        $id = str($panel->getId())->title(); // "Admin", "App", "Server"

        // Filament コンポーネントを自動検出
        $panel->discoverPages(
            plugin_path($this->getId(), "src/Filament/$id/Pages"),
            "MyName\\MyPlugin\\Filament\\$id\\Pages"
        );
        $panel->discoverResources(
            plugin_path($this->getId(), "src/Filament/$id/Resources"),
            "MyName\\MyPlugin\\Filament\\$id\\Resources"
        );
        $panel->discoverWidgets(
            plugin_path($this->getId(), "src/Filament/$id/Widgets"),
            "MyName\\MyPlugin\\Filament\\$id\\Widgets"
        );
    }

    public function boot(Panel $panel): void
    {
        //
    }
}

3 つの Filament パネル

パネル ID エリア ユースケース
admin 管理エリア リソース、設定、管理のための完全な CRUD
app サーバーリスト 最小限の UI (デフォルトではナビゲーションなし)
server サーバー管理 テナントスコープ (現在のサーバーコンテキスト)

app パネルでナビゲーションを有効にする

use App\Filament\App\Resources\Servers\ServerResource;
use App\Enums\CustomizationKey;

public function register(Panel $panel): void
{
    parent::register($panel);

    if ($panel->getId() === 'app') {
        ServerResource::embedServerList();
        $panel->navigation(true);
        $panel->topbar(function () {
            $nav = user()?->getCustomization(CustomizationKey::TopNavigation);
            return in_array($nav, ['topbar', 'mixed', true], true);
        });
        $panel->clearCachedComponents();
    }
}

コアリソースの拡張

サービスプロバイダーの register() 内でコアクラスの静的メソッドを呼び出します。

use App\Filament\Admin\Resources\Users\UserResource;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Models\Role;

public function register(): void
{
    // リレーションマネージャータブを追加
    ServerResource::registerCustomRelations(MyRelationManager::class);

    // パーミッションを登録
    Role::registerCustomDefaultPermissions('myModel');
    Role::registerCustomModelIcon('myModel', 'tabler-star');
}

利用可能なカスタマイズトレイト (app/Traits/Filament/ で全て確認):

  • CanModifyResource - リレーションマネージャー、カスタムアクション
  • CanCustomizePage - ウィジェット、ヘッダーアクション
  • CanModifyForm / CanModifyTable - フォーム/テーブルフック

プラグイン設定

メインクラスに HasPluginSettings を実装します。


use App\Contracts\Plugins\HasPluginSettings;
use App\Traits\EnvironmentWriterTrait;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;

class MyPlugin implements Plugin, HasPluginSettings
{
    use EnvironmentWriterTrait;

    public function getSettingsForm(): array
    {
        return [


(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Pelican Panel Plugins

Pelican is an open-source game server management panel built on Laravel + FilamentPHP. Plugins let you add functionality without touching core files.

⚠️ The plugin system is still in active development — some features may change.

Quick Reference

📖 Detailed Guides:

Scaffolding a New Plugin

Run inside the panel directory (/var/www/pelican by default):

php artisan p:plugin:make

This creates the basic structure with plugin.json, main plugin class, service provider, and config file.

Critical: The plugin folder name must exactly match the id field in plugin.json.

Plugin Structure

plugins/my-plugin/
├── plugin.json              # Metadata and configuration
├── config/
│   └── my-plugin.php       # Config values (use env vars)
├── database/
│   └── migrations/         # Auto-discovered migrations
├── lang/                   # Translations (namespaced: my-plugin::strings.key)
├── resources/
│   └── views/              # Blade views (namespaced: my-plugin::view-name)
├── routes/                 # Optional route files
└── src/                    # App logic (PSR-4 autoloaded)
    ├── MyPlugin.php        # Main plugin class
    ├── Filament/
    │   ├── Admin/          # Admin panel components
    │   │   ├── Pages/
    │   │   ├── Resources/
    │   │   └── Widgets/
    │   ├── App/            # Server list panel
    │   └── Server/         # Server management panel
    ├── Models/
    ├── Policies/           # Auto-discovered
    ├── Providers/          # Auto-discovered service providers
    ├── Console/Commands/   # Auto-discovered artisan commands
    └── Http/
        └── Controllers/

Everything in standard Laravel locations is auto-discovered: migrations, providers, commands, policies.

plugin.json

{
    "id": "my-plugin",
    "name": "My Plugin",
    "author": "Your Name",
    "version": "1.0.0",
    "description": "Short description",
    "category": "plugin",
    "namespace": "MyName\\MyPlugin",
    "class": "MyPlugin",
    "panels": ["admin", "server"],
    "panel_version": "^1.2.0",
    "composer_packages": {
        "vendor/package": "^1.0"
    }
}
Field Required Notes
id Must match folder name
namespace PHP namespace root (use \\ for backslashes)
class Main class name (in src/)
category plugin, theme, or language
panels No Array of panel IDs or omit for all panels
panel_version No Minimum panel version (e.g., ^1.2.0)
composer_packages No External dependencies

Main Plugin Class

Located in src/{ClassName}.php:

namespace MyName\MyPlugin;

use Filament\Contracts\Plugin;
use Filament\Panel;

class MyPlugin implements Plugin
{
    public function getId(): string
    {
        return 'my-plugin';
    }

    public function register(Panel $panel): void
    {
        $id = str($panel->getId())->title(); // "Admin", "App", "Server"

        // Auto-discover Filament components
        $panel->discoverPages(
            plugin_path($this->getId(), "src/Filament/$id/Pages"),
            "MyName\\MyPlugin\\Filament\\$id\\Pages"
        );
        $panel->discoverResources(
            plugin_path($this->getId(), "src/Filament/$id/Resources"),
            "MyName\\MyPlugin\\Filament\\$id\\Resources"
        );
        $panel->discoverWidgets(
            plugin_path($this->getId(), "src/Filament/$id/Widgets"),
            "MyName\\MyPlugin\\Filament\\$id\\Widgets"
        );
    }

    public function boot(Panel $panel): void
    {
        //
    }
}

The Three Filament Panels

Panel ID Area Use Case
admin Admin area Full CRUD for resources, settings, management
app Server list Minimal UI (no nav by default)
server Server management Tenant-scoped (current server context)

Enabling Navigation on app Panel

use App\Filament\App\Resources\Servers\ServerResource;
use App\Enums\CustomizationKey;

public function register(Panel $panel): void
{
    parent::register($panel);

    if ($panel->getId() === 'app') {
        ServerResource::embedServerList();
        $panel->navigation(true);
        $panel->topbar(function () {
            $nav = user()?->getCustomization(CustomizationKey::TopNavigation);
            return in_array($nav, ['topbar', 'mixed', true], true);
        });
        $panel->clearCachedComponents();
    }
}

Extending Core Resources

Call static methods on core classes inside a service provider's register():

use App\Filament\Admin\Resources\Users\UserResource;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Models\Role;

public function register(): void
{
    // Add a relation manager tab
    ServerResource::registerCustomRelations(MyRelationManager::class);

    // Register permissions
    Role::registerCustomDefaultPermissions('myModel');
    Role::registerCustomModelIcon('myModel', 'tabler-star');
}

Available customization traits (check app/Traits/Filament/ for all):

  • CanModifyResource - Relation managers, custom actions
  • CanCustomizePage - Widgets, header actions
  • CanModifyForm / CanModifyTable - Form/table hooks

Plugin Settings

Implement HasPluginSettings on your main class:

use App\Contracts\Plugins\HasPluginSettings;
use App\Traits\EnvironmentWriterTrait;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;

class MyPlugin implements Plugin, HasPluginSettings
{
    use EnvironmentWriterTrait;

    public function getSettingsForm(): array
    {
        return [
            TextInput::make('api_key')
                ->required()
                ->default(fn () => config('my-plugin.api_key')),
        ];
    }

    public function saveSettings(array $data): void
    {
        $this->writeToEnvironment([
            'MY_PLUGIN_API_KEY' => $data['api_key'],
        ]);

        Notification::make()->title('Settings saved')->success()->send();
    }
}

Always prefix env vars with your plugin ID to avoid conflicts.

Permissions

Admin Role Permissions

In your service provider's register():

use App\Models\Role;

// Shorthand: registers viewList, view, create, update, delete
Role::registerCustomDefaultPermissions('myModel');

// Custom permissions
Role::registerCustomPermissions([
    'myModel' => ['export', 'approve'],
    'server'  => ['customAction'], // extend existing model
]);

// Optional: icon for permission group
Role::registerCustomModelIcon('myModel', 'tabler-star');

Subuser Permissions

use App\Models\Subuser;

// New permission group
Subuser::registerCustomPermissions('myFeature', ['read', 'write'], 'tabler-bolt', false);

// Append to existing group
Subuser::registerCustomPermissions('console', ['myCustomAction']);

Routes

Create a RouteServiceProvider in src/Providers/:

use Illuminate\Foundation\Support\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Route;

class MyPluginRoutesProvider extends RouteServiceProvider
{
    public function boot(): void
    {
        $this->routes(function () {
            // Simple route
            Route::get('/my-plugin/test', [TestController::class, 'index'])
                ->name('my-plugin.test');

            // Load from file
            Route::prefix('/my-plugin')
                ->group(plugin_path('my-plugin', 'routes/web.php'));

            // Append to client API
            Route::middleware(['api', 'client-api', 'throttle:api.client'])
                ->prefix('/api/client/servers/{server}')
                ->scopeBindings()
                ->group(plugin_path('my-plugin', 'routes/api-client.php'));
        });
    }
}

Models & Relationships

Add Relationship to Core Models

In your service provider's boot():

use App\Models\Server;
use MyPlugin\Models\Ticket;

public function boot(): void
{
    Server::resolveRelationUsing('tickets', fn (Server $server) => 
        $server->hasMany(Ticket::class, 'server_id', 'id')
    );
}

Now $server->tickets works everywhere.

Policies

use App\Policies\DefaultAdminPolicies;

class MyModelPolicy
{
    use DefaultAdminPolicies;

    protected string $modelName = 'myModel';
}

This automatically checks admin role permissions based on the registered model name.

Translations

Place in lang/{locale}/ (e.g., lang/en/strings.php):

return [
    'welcome' => 'Welcome',
    'item' => 'Item|Items', // Pluralization
];

Usage:

trans('my-plugin::strings.welcome')
trans_choice('my-plugin::strings.item', 2) // "Items"

Views

Place in resources/views/:

view('my-plugin::my-view')
// → plugins/my-plugin/resources/views/my-view.blade.php

Common Patterns

FilamentPHP Components

See FilamentPHP Patterns for:

  • Resources (CRUD interfaces)
  • Pages (custom pages)
  • Widgets (dashboard components)
  • Relation Managers (manage related records)
  • Custom Actions (reusable buttons)
  • Form components (inputs, selects, toggles)
  • Table columns and filters

Advanced Patterns

See Advanced Patterns for:

  • Model events and hooks
  • Enums with Filament interfaces
  • Service classes
  • HTTP controllers and API routes
  • Artisan commands and scheduling
  • HTTP macros for external APIs
  • Database migrations
  • Error handling

Complete Example

See Complete Plugin Walkthrough for a step-by-step guide building a "Server Notes" plugin.

Publishing a Plugin

  1. Open plugin.json and remove the meta block (internal use only)
  2. Zip the entire plugin folder
  3. Share the zip — users install via panel UI Import button or manually drop into plugins/

Publish to the community:

Tips & Gotchas

  • Namespace in plugin.json: Use \\ (double backslash) for namespace separators
  • Migration naming: Use numeric prefixes (001_, 002_) to control execution order
  • Environment variables: Always prefix with your plugin ID (e.g., MY_PLUGIN_*)
  • Panel context: Use Filament::getTenant() to get current server in server panel
  • Auto-discovery: Service providers, commands, migrations, and policies are auto-discovered
  • Relation managers: Must be registered on core resources via registerCustomRelations() in service provider's register() method
  • Testing: Use php artisan migrate:fresh --seed to reset and test migrations
  • Permissions: Register in service provider's register(), not boot()

Getting Help