# PI-Desktop Plugin Contribution Points: A Complete Guide to Extending the Desktop

> Explore PI-Desktop plugin contribution points including Panels, Views, Commands, and more. Learn how to extend the desktop environment via manifest.json and permissions.

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

---

**PI-Desktop plugins extend the desktop environment through eleven distinct contribution points—including Panels, Views, Commands, Agent Tools, Skills, Themes, Services, Bus, Settings, and MCP—that are declared in [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) and validated against requested permissions.**

The PI-Desktop platform (vastsa/PI-Desktop) provides a comprehensive plugin architecture that allows developers to enhance functionality through standardized extension mechanisms. Understanding the available PI-Desktop plugin contribution points is essential for building rich integrations that seamlessly blend with the core desktop experience.

## Understanding the Contribution Point Architecture

When a PI-Desktop plugin loads, the host reads its [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) file and validates the declared capabilities against the **PluginCapability** enum defined in [[`packages/shared/src/types/plugins.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/types/plugins.ts)](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/types/plugins.ts#L24-L36). Each capability corresponds to a specific contribution point that UI components, the command palette, the AI agent process, or core services consume.

The host stores these capabilities in the plugin summary as `capabilities?: PluginCapability[]` and only activates contributions after verifying the plugin has requested the necessary permissions (e.g., `ui.panel`, `agent.tool.register`, `background.service`).

## The Eleven Core Contribution Points

### Panel

The **Panel** contribution point supplies a dedicated HTML page that appears in the desktop's side-bar. Declared via the `ui` object in [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) using the key `ui.panel`, this point requires the `ui.panel` permission. The manifest specifies the entry HTML file, dimensions, and localized titles.

### Views

**Views** register work-panel tabs with distinct titles, icons, and entry points. Using the `contributes.views` array, plugins can inject multiple view containers that appear alongside native panels. Each view requires an `id`, `title` object for localization, `icon`, and `entry` path.

### Commands

The **Commands** contribution point adds entries to the command palette through `contributes.commands`. These commands can bind to activation events or keyboard shortcuts, enabling users to trigger plugin functionality directly from the global command interface.

### Agent Tools

**Agent Tools** extend the AI agent's capabilities by registering callable functions via `contributes.agentTools`. Each tool requires a `name`, `description`, and JSON `schema` defining parameters. For example, a tool named `echo_text` allows the agent to process text through the plugin's logic.

### Skills

The **Skills** contribution point registers Markdown-based knowledge sources using `contributes.skills`. These files provide contextual information that the AI agent can invoke as reference material during conversations, specified as an array of file paths like [`./skills/hello.md`](https://github.com/vastsa/PI-Desktop/blob/main/./skills/hello.md).

### Themes

**Themes** supply CSS styling options that users can select through `contributes.themes`. Each theme declares an `id`, `label`, `path` to the CSS file, and a `base` theme (e.g., `dark`). This requires the `ui.theme` permission to modify the desktop's appearance.

### MCP (Multi-Client Portable)

The **MCP** contribution point is reserved for future multi-client-plugin interfaces. Declared via `contributes.mcp`, this placeholder in the `PluginCapability` enum will eventually allow plugins to expose portable interfaces across different client implementations.

### Services

**Services** declare background processes that run continuously using `contributes.services`. Each service requires a unique `id` and `label`, along with the `background.service` permission. These services persist throughout the desktop session, handling tasks like heartbeat monitoring.

### Bus

The **Bus** contribution point enables inter-plugin communication through the internal message bus. Declared via `contributes.bus`, plugins specify `publish` and `subscribe` topic arrays. This requires `bus.publish` and `bus.subscribe` permissions for event-driven architecture support.

### Settings

**Settings** define configuration options that appear in the plugin settings UI using `contributes.settings`. Each setting specifies a `key`, `type` (string, boolean, number), `default` value, and display `title`, allowing users to customize plugin behavior without editing files.

### Agent Extensions

The **Agent Extension** contribution point adds ExtensionAPI modules that run within the agent process via `contributes.agentExtensions`. Currently experimental, this allows deep integration with the AI agent's runtime environment.

## Validation and Runtime Activation

The activation flow begins in [[`packages/plugin-sdk/src/index.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/index.ts)](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/index.ts), where SDK utilities validate contribution shapes against the manifest schema. The SDK enforces permission checks before the host loads any contributions.

Runtime registration occurs in [[`apps/desktop/electron/main/services/plugin-services.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/services/plugin-services.ts)](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/services/plugin-services.ts), which handles the actual loading, registration, and unregistration of contribution points based on the validated manifest.

## Complete Manifest Example

Below is a minimal manifest demonstrating all supported PI-Desktop plugin contribution points, taken from the Hello example plugin:

```json
{
  "id": "demo.hello",
  "name": "Hello",
  "version": "0.2.0",
  "ui": {
    "panel": "renderer/index.html",
    "width": 420,
    "height": 320,
    "title": { "en": "Hello Plugin", "zh-CN": "你好插件" }
  },
  "contributes": {
    "views": [{ 
      "id": "greetings", 
      "title": { "en": "Hello Panel" }, 
      "icon": "sparkles", 
      "entry": "views/greetings.html", 
      "order": 10 
    }],
    "commands": [{ 
      "id": "hello.open", 
      "title": "Hello: Open Panel", 
      "category": "Demo" 
    }],
    "agentTools": [{ 
      "name": "echo_text", 
      "description": "Echo text back to the agent", 
      "schema": { 
        "type": "object", 
        "properties": { 
          "text": { "type": "string" } 
        }, 
        "required": ["text"] 
      } 
    }],
    "skills": ["./skills/hello.md"],
    "themes": [{ 
      "id": "midnight", 
      "label": "Hello Midnight", 
      "path": "themes/midnight.css", 
      "base": "dark" 
    }],
    "services": [{ 
      "id": "greeter", 
      "label": "Greeter heartbeat" 
    }],
    "bus": { 
      "publish": ["demo.hello.greeted", "demo.hello.tick"], 
      "subscribe": ["demo.**"] 
    },
    "settings": [{ 
      "key": "greeting", 
      "type": "string", 
      "default": "Hello from plugin", 
      "title": "Greeting" 
    }]
  },
  "permissions": [
    "ui.panel", "ui.view", "ui.theme",
    "agent.tool.register", "agent.prompt.inject",
    "background.service", "bus.publish", "bus.subscribe"
  ],
  "activationEvents": ["onCommand:hello.open", "onStartup"]
}

```

## Summary

- PI-Desktop exposes **eleven contribution points**: Panel, Views, Commands, Agent Tools, Skills, Themes, MCP, Services, Bus, Settings, and Agent Extensions.
- Each contribution point maps to a specific key in [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) and a corresponding value in the **PluginCapability** enum located in [`packages/shared/src/types/plugins.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/types/plugins.ts).
- The host validates all contributions against explicitly requested **permissions** before activation.
- Runtime activation occurs through [`plugin-services.ts`](https://github.com/vastsa/PI-Desktop/blob/main/plugin-services.ts), while schema validation happens in the plugin SDK.
- Plugins must declare `activationEvents` to control when their contributions load.

## Frequently Asked Questions

### What permissions are required for UI-based contribution points?

UI contribution points require specific permissions: `ui.panel` for side-bar panels, `ui.view` for work-panel views, and `ui.theme` for custom themes. Without these permissions in the manifest, the host will reject the contribution even if declared in `contributes.views` or `contributes.themes`.

### How does the host validate agent tool contributions?

The SDK validates agent tools through the schema defined in `contributes.agentTools`, checking for required fields including `name`, `description`, and parameter schema. The host also verifies the plugin has requested `agent.tool.register` permission before exposing the tool to the AI agent process.

### Can a plugin use multiple contribution points simultaneously?

Yes, plugins can combine multiple contribution points in a single manifest. The Hello example plugin demonstrates this by simultaneously providing Panels, Views, Commands, Agent Tools, Skills, Themes, Services, Bus, and Settings contributions, provided all relevant permissions are declared.

### Where are contribution capabilities stored at runtime?

After validation, contribution capabilities are stored in the plugin summary as the `capabilities` array of type `PluginCapability[]`, defined in [`packages/shared/src/types/plugins.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/types/plugins.ts). This array persists in the plugin's runtime state, allowing the desktop to track which extension points are active.