How to Develop and Install Plugins for PI-Desktop: Complete Developer Guide
PI-Desktop provides a three-layer plugin architecture comprising the Plugin SDK, Plugin DevKit CLI, and Host Integration layer, enabling developers to extend the desktop with AI skills, tools, and UI panels through a sandboxed, permission-based system.
The vastsa/PI-Desktop repository ships a production-ready plugin system designed for third-party extensibility. Developers can enhance the AI desktop environment by creating new skills for natural language commands, exposing system tools for the AI to invoke, or building custom React-based UI panels. This guide covers the complete workflow for PI-Desktop plugin development, from initial scaffolding to marketplace publication and local installation.
Understanding the PI-Desktop Plugin Architecture
The plugin system is split into three distinct layers that handle different aspects of the development and runtime lifecycle.
Plugin SDK Layer
The Plugin SDK provides type-safe helpers and runtime bridges for plugin code. Located in packages/plugin-sdk/src/index.ts, this layer exposes the window.pluginBridge interface and validates manifest schemas. It exports the core registration functions—registerSkill, registerTool, and registerPanel—that bind your code to the host environment.
Plugin DevKit Layer
The Plugin DevKit supplies the command-line interface for scaffolding and packaging. The source in packages/plugin-devkit/src/cli.ts implements the pi-plugin CLI, which handles project generation, linting, and publishing workflows. This layer ensures that manifest.json files conform to the specification defined in docs/spec/07-plugins/02-plugin-manifest-schema.md.
Host Integration Layer
The Host Integration layer manages sandboxed execution within Electron. The preload script at apps/desktop/electron/preload/plugin-panel.ts creates an isolated Chromium window for each plugin UI, injects the SDK bridge, and enforces permission boundaries. This architecture ensures that untrusted third-party code cannot access the main process without explicit authorization.
Setting Up Your Development Environment
Before creating plugins, clone the PI-Desktop repository and install dependencies using the package manager specified in the project root.
git clone https://github.com/vastsa/PI-Desktop.git
cd PI-Desktop
pnpm install
Start the desktop application in development mode to enable hot-reloading of plugins:
pnpm dev
Creating Your First PI-Desktop Plugin
New plugins are scaffolded using the DevKit CLI, which generates a TypeScript project structure with all necessary configuration files.
Scaffolding with the CLI
Run the pi-plugin CLI to create a new plugin project:
npx pi-plugin new my-awesome-plugin
This command generates a directory containing:
manifest.json— The plugin descriptor conforming to the JSON schema indocs/spec/07-plugins/02-plugin-manifest-schema.mdsrc/index.ts— The TypeScript entry point that imports from@pi-desktop/plugin-sdksrc/theme.css— Optional CSS variables for styling the plugin panel, including the default--pi-plugin-titlebar-height: 46pxfor alignment
Configuring the Manifest
The manifest.json file declares your plugin's metadata, permissions, and contributions to the system. A minimal manifest defines the plugin ID, version, entry point, and any AI capabilities it provides.
{
"id": "my-awesome-plugin",
"name": "My Awesome Plugin",
"version": "0.1.0",
"description": "Demo plugin showing hello-world skill",
"main": "dist/index.js",
"permissions": [],
"contributes": {
"skills": ["helloWorld"]
}
}
Implementing Plugin Features
The Plugin SDK exposes three primary extension points: skills for AI commands, tools for function calling, and panels for custom UI.
Registering Skills
Skills are commands exposed to the AI that users can invoke through natural language or the command palette. Import registerSkill from @pi-desktop/plugin-sdk and define the execution logic in the run method.
import { registerSkill } from '@pi-desktop/plugin-sdk'
registerSkill({
name: 'helloWorld',
description: 'Returns a friendly greeting',
async run() {
return '👋 Hello from My Awesome Plugin!'
},
})
Exposing Tools
Tools provide callable functions that the AI can invoke during task execution, similar to function calling in large language models. The registerTool function accepts a JSON schema that validates input parameters at runtime.
import { registerTool } from '@pi-desktop/plugin-sdk'
registerTool({
name: 'math.add',
description: 'Adds two numbers',
schema: { a: 'number', b: 'number' },
async run({ a, b }) {
return a + b
},
})
Building UI Panels
To create a graphical interface, implement a React component in src/Panel.tsx and register it using registerPanel. The host embeds this component in a sandboxed window with isolated CSS scope. The SDK automatically injects the theme.css file to maintain visual consistency with the desktop theme.
Testing and Packaging Your Plugin
The development workflow supports local testing before marketplace distribution.
Local Development Mode
From your plugin directory, start the watch mode compiler:
pnpm dev
In the running PI-Desktop application, open the settings menu and select Load development plugin. Navigate to your plugin's root folder to activate it. The plugin's name, icon, and registered commands will immediately appear in the command palette, allowing you to test /helloWorld invocations without restarting the host.
Packaging for Distribution
When ready for release, package your plugin into a distributable zip file:
pnpm pack
This command compiles TypeScript assets, validates the manifest.json against the official schema, and bundles everything into an archive suitable for publication. To distribute publicly, push to the official marketplace repository:
pnpm publish
This uploads the package to vastsa/pi-desktop-plugins and updates the catalog.json file that PI-Desktop queries for available plugins.
Installing and Managing Plugins
End users can acquire plugins through the built-in Plugin Center or manual installation of development builds.
Installing from the Marketplace
Open the Plugin Center from the sidebar, browse the marketplace catalog, and click Install on any published plugin. The host downloads the package, verifies its cryptographic checksum, and extracts it to ~/.pi-desktop/plugins/installed/. After installation, skills and tools become available to the AI immediately, while UI panels appear as new entries in the Plugin Panel section.
Loading Development Plugins
For testing unpublished work, use the Load development plugin option in the overflow menu (⋮). Select the plugin's root folder—such as examples/plugins/roundtable—to activate it in the current session. This method bypasses the marketplace and loads the code directly from the dist/ directory specified in your manifest.
Security and Permissions
Every plugin executes within a sandboxed preload script context that restricts access to system APIs. The bridge at window.pluginBridge only exposes functionality explicitly declared in the manifest.json permissions array. As documented in docs/spec/07-plugins/13-plugin-permissions-matrix.md, individual capabilities like fs.read or fs.write must be requested separately. Attempting to call an unpermitted API raises a runtime error that the host logs for debugging.
The plugin lifecycle—defined in docs/spec/07-plugins/05-plugin-lifecycle.md—includes distinct Load, Activate, Deactivate, and Update stages. During the Load stage, the host validates the manifest, instantiates the SDK runtime, and executes any onLoad hooks. Deactivation cleanly unregisters all symbols and destroys the sandbox window, ensuring no residual processes remain after uninstallation.
Summary
- PI-Desktop plugins extend the application through three layers: the SDK (
packages/plugin-sdk/src/index.ts), the DevKit CLI (packages/plugin-devkit/src/cli.ts), and the Electron host preload (apps/desktop/electron/preload/plugin-panel.ts). - Scaffold new projects using
npx pi-plugin newand define capabilities inmanifest.jsonaccording to the schema indocs/spec/07-plugins/02-plugin-manifest-schema.md. - Register functionality using
registerSkill,registerTool, andregisterPanelfrom@pi-desktop/plugin-sdkto expose AI commands, executable functions, and React-based UI components. - Test locally by running
pnpm devin the plugin folder and loading the development build through the desktop's plugin management interface. - Distribute plugins via
pnpm packfor local sharing orpnpm publishto submit to thevastsa/pi-desktop-pluginsmarketplace catalog. - Install plugins through the Plugin Center for marketplace packages, or load development copies manually for testing; production installs reside in
~/.pi-desktop/plugins/installed/.
Frequently Asked Questions
How do I register a new skill for the AI to use?
Import registerSkill from @pi-desktop/plugin-sdk in your entry file and call it with a configuration object containing name, description, and an async run function. The skill becomes available in the command palette immediately after the plugin activates, and users can invoke it by typing the skill name preceded by a forward slash.
What file system permissions are required for plugin operations?
File system access requires explicit declaration in the manifest.json permissions array. For read-only access, include "fs.read"; for write operations, include "fs.write". The host enforces these permissions at runtime according to the matrix documented in docs/spec/07-plugins/13-plugin-permissions-matrix.md, throwing a runtime error if unauthorized access is attempted.
Where are plugins stored after installation?
Published plugins install to ~/.pi-desktop/plugins/installed/ on the user's system. The host manages this directory automatically when you install from the Plugin Center, verifying package checksums before extraction. Development plugins loaded via Load development plugin remain in their original source locations and are not copied to this directory.
How do I update a plugin without losing user settings?
When you publish a new version using pnpm publish, the host detects the update through the catalog.json file. During the update process, PI-Desktop reloads the plugin bundle while preserving settings stored under the plugin's namespace. The lifecycle hooks documented in docs/spec/07-plugins/05-plugin-lifecycle.md ensure state persistence across version changes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →