# How to Develop and Install Plugins for PI-Desktop: Complete Developer Guide

> Learn to develop and install plugins for PI-Desktop with this guide. Leverage the plugin SDK and DevKit CLI to extend PI-Desktop functionality with AI skills, tools, and UI panels.

- Repository: [Lan/PI-Desktop](https://github.com/vastsa/PI-Desktop)
- Tags: how-to-guide
- Published: 2026-09-11

---

**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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) files conform to the specification defined in [`docs/spec/07-plugins/02-plugin-manifest-schema.md`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/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.

```bash
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:

```bash
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:

```bash
npx pi-plugin new my-awesome-plugin

```

This command generates a directory containing:
- [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) — The plugin descriptor conforming to the JSON schema in [`docs/spec/07-plugins/02-plugin-manifest-schema.md`](https://github.com/vastsa/PI-Desktop/blob/main/docs/spec/07-plugins/02-plugin-manifest-schema.md)
- [`src/index.ts`](https://github.com/vastsa/PI-Desktop/blob/main/src/index.ts) — The TypeScript entry point that imports from `@pi-desktop/plugin-sdk`
- [`src/theme.css`](https://github.com/vastsa/PI-Desktop/blob/main/src/theme.css) — Optional CSS variables for styling the plugin panel, including the default `--pi-plugin-titlebar-height: 46px` for alignment

### Configuring the Manifest

The [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/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.

```json
{
  "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.

```typescript
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.

```typescript
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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/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:

```bash
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:

```bash
pnpm pack

```

This command compiles TypeScript assets, validates the [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) against the official schema, and bundles everything into an archive suitable for publication. To distribute publicly, push to the official marketplace repository:

```bash
pnpm publish

```

This uploads the package to `vastsa/pi-desktop-plugins` and updates the [`catalog.json`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) permissions array. As documented in [`docs/spec/07-plugins/13-plugin-permissions-matrix.md`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/index.ts)), the DevKit CLI ([`packages/plugin-devkit/src/cli.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-devkit/src/cli.ts)), and the Electron host preload ([`apps/desktop/electron/preload/plugin-panel.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/preload/plugin-panel.ts)).
- **Scaffold new projects** using `npx pi-plugin new` and define capabilities in [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) according to the schema in [`docs/spec/07-plugins/02-plugin-manifest-schema.md`](https://github.com/vastsa/PI-Desktop/blob/main/docs/spec/07-plugins/02-plugin-manifest-schema.md).
- **Register functionality** using `registerSkill`, `registerTool`, and `registerPanel` from `@pi-desktop/plugin-sdk` to expose AI commands, executable functions, and React-based UI components.
- **Test locally** by running `pnpm dev` in the plugin folder and loading the development build through the desktop's plugin management interface.
- **Distribute plugins** via `pnpm pack` for local sharing or `pnpm publish` to submit to the `vastsa/pi-desktop-plugins` marketplace 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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/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`](https://github.com/vastsa/PI-Desktop/blob/main/docs/spec/07-plugins/05-plugin-lifecycle.md) ensure state persistence across version changes.