Scaffolding a Plugin ==================== Generate the project structure with the CLI: .. code-block:: bash forkbit plugin init --id com.example.release_notes --name "Release Notes" --non-interactive This creates: .. code-block:: text release_notes/ plugin.json — manifest main.py — plugin code settings.json — settings schema The Manifest ------------ Open ``plugin.json``: .. code-block:: json { "id": "com.example.release_notes", "name": "Release Notes", "version": "0.1.0", "entry": "main.py", "min_app_version": "0.2.0", "requirements": [] } Key fields: - **id** — unique reverse-domain identifier (``com..``) - **name** — display name shown in ForkBit - **version** — semver version of your plugin - **entry** — Python file containing your ``BasePlugin`` subclass - **requirements** — pip dependencies (vendored at build time) - **min_app_version** — minimum ForkBit version required The Entry Point --------------- Open ``main.py``: .. code-block:: python from PySide6.QtCore import Qt from PySide6.QtWidgets import QLabel, QVBoxLayout from forkbit_sdk import BasePlugin class ReleaseNotesPlugin(BasePlugin): def on_ready(self) -> None: layout = QVBoxLayout(self.container) layout.setAlignment(Qt.AlignmentFlag.AlignTop) status = QLabel("Plugin loaded successfully.") layout.addWidget(status) This is the minimal plugin. The app calls :meth:`~forkbit_sdk.BasePlugin.on_ready` after injecting all context — you build your UI inside :attr:`~forkbit_sdk.BasePlugin.container`. Validate it: .. code-block:: bash forkbit plugin validate release_notes You should see all checks pass. Next: :doc:`dev-mode` to load your plugin in ForkBit without building, or skip ahead to :doc:`ui`.