# PI-Desktop Plugin Manifest File Structure: Complete Schema Guide

> Explore the PI-Desktop plugin manifest file structure. Understand the complete schema for declaring plugin identity entry points UI configuration contributions and security policies.

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

---

**A PI-Desktop plugin manifest is a single [`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json) file located at the root of the plugin folder that declares the plugin's identity, entry points, UI configuration, contributions, and security policies using a frozen JSON schema.**

The PI-Desktop plugin system, maintained in the `vastsa/PI-Desktop` repository, requires every extension to provide a strictly validated manifest at its root. Understanding the PI-Desktop plugin manifest file structure ensures your plugin loads correctly and receives only the permissions it strictly requires.

## Required Root Fields

Every **manifest.json** must include five mandatory fields 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):

- **`schemaVersion`** – Currently fixed to `1` to lock the schema revision.
- **`id`** – A unique reverse-domain identifier (e.g., `com.example.my-plugin`).
- **`name`** – Human-readable plugin name.
- **`version`** – Semantic version string.
- **`main`** – Relative path to the runtime entry point (typically [`main.js`](https://github.com/vastsa/PI-Desktop/blob/main/main.js)).

All path strings in the manifest are **relative to the plugin root** and must not contain absolute paths or `..` directory traversals according to the manifest validation rules.

## UI Configuration Section

The optional **`ui`** object defines a panel window that renders inside a sandboxed Electron container:

- **`ui.panel`** – Relative path to the HTML entry (e.g., [`renderer/index.html`](https://github.com/vastsa/PI-Desktop/blob/main/renderer/index.html)).
- **`ui.width`** and **`ui.height`** – Initial dimensions in pixels.
- **`ui.resizable`** – Boolean allowing window resizing.
- **`ui.title`** – Window title string.

Declaring `ui.panel` implicitly requires the `ui.panel` permission, though explicit declaration in the `permissions` array is recommended for clarity.

## Contributions Block

The **`contributes`** object declares how the plugin extends PI-Desktop capabilities. Each contribution type follows its own schema (e.g., `PluginCommandContrib`, `PluginAgentToolContrib`):

- **`contributes.commands`** – Registers command palette entries.
- **`contributes.agentTools`** – Exposes tools to the agent system.
- **`contributes.skills`** – Declares reusable skill definitions.
- **`contributes.agentExtensions`** – Extends agent behavior.
- **`contributes.settings`** – Contributes configuration schemas.
- **`contributes.themes`** – Registers UI themes.
- **`contributes.mcpServers`** – Declares Model Context Protocol servers.
- **`contributes.services`** – Registers background services.
- **`contributes.bus`** – Message-bus participation.
- **`contributes.views`** – Custom view contributions.
- **`contributes.sessionSources`** – Session data providers.

## Security Policies and Permissions

The manifest separates high-level capabilities from granular resource access:

**`permissions`** – A flat array of high-level host permissions such as `fs.read`, `fs.write`, `net.fetch`, or `agent.tool.register`.

**`fs`** – Defines exact file-system scopes with `read`, `write`, and `delete` rules using glob patterns. An empty or missing `fs` policy grants **no** file system access.

**`net.domains`** – Lists permitted egress hostnames for network requests. Omitting this blocks all outbound connections.

**`engines`** – Specifies host compatibility (e.g., `"piDesktop": ">=0.1.0"`).

**`activationEvents`** – Controls lifecycle triggering (e.g., `onCommand:my-first-plugin.open`, `onStartup`).

## Minimal Working Example

The following manifest represents the minimal valid structure recognized by the PI-Desktop loader:

```json
{
  "schemaVersion": 1,
  "id": "local.my-first-plugin",
  "name": "My First Plugin",
  "version": "0.1.0",
  "main": "main.js",
  "ui": {
    "panel": "renderer/index.html",
    "title": "My First Plugin",
    "width": 480,
    "height": 360
  },
  "contributes": {
    "commands": [
      {
        "id": "my-first-plugin.open",
        "title": "Open My First Plugin Panel",
        "keywords": ["hello", "panel"]
      }
    ]
  },
  "permissions": ["ui.panel"],
  "engines": { "piDesktop": ">=0.1.0" },
  "activationEvents": ["onCommand:my-first-plugin.open", "onStartup"]
}

```

This example follows the minimal plugin specification found in [`docs/plugin-development.md`](https://github.com/vastsa/PI-Desktop/blob/main/docs/plugin-development.md).

## Standard Plugin Package Layout

A complete plugin package combines the manifest with runtime assets in a specific directory structure:

- **[`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json)** – The schema-declaring file discussed above.
- **[`main.js`](https://github.com/vastsa/PI-Desktop/blob/main/main.js)** – The Node.js entry point exported by the `main` field; implements lifecycle hooks such as `onLoad` and `onUnload`.
- **[`renderer/index.html`](https://github.com/vastsa/PI-Desktop/blob/main/renderer/index.html)** – The sandboxed UI markup referenced by `ui.panel`.
- **[`README.md`](https://github.com/vastsa/PI-Desktop/blob/main/README.md)** – Documentation for installation and usage.

Reference implementations exist in `examples/plugins/hello/` within the repository, demonstrating the canonical layout that the PI-Desktop host expects.

## Summary

- The PI-Desktop plugin manifest is a single **[`manifest.json`](https://github.com/vastsa/PI-Desktop/blob/main/manifest.json)** at the package root.
- Required fields are **`schemaVersion`**, **`id`**, **`name`**, **`version`**, and **`main`**.
- Optional **`ui`** configuration defines sandboxed panel windows with specific dimensions and permissions.
- The **`contributes`** block registers commands, tools, skills, themes, and services with individual sub-schemas.
- Security is enforced through explicit **`permissions`**, **`fs`** globs, and **`net.domains`** lists; absent policies deny access.
- All paths must be relative to the plugin root; absolute paths and `..` traversals are rejected by the validator.

## Frequently Asked Questions

### What fields are mandatory in a PI-Desktop plugin manifest?

The manifest must contain **`schemaVersion`**, **`id`**, **`name`**, **`version`**, and **`main`**. The `id` must follow reverse-domain notation, and `main` must point to a valid runtime entry point relative to the plugin root. Omitting any of these five fields causes validation to fail during plugin load.

### How does the `fs` policy work in manifest.json?

The **`fs`** object defines granular file-system access using `read`, `write`, and `delete` arrays containing glob patterns. For example, `"fs": { "read": ["data/*.json"] }` permits reading only JSON files in the `data/` directory. If the `fs` key is missing or empty, the plugin receives no file system access regardless of high-level permissions declared in the `permissions` array.

### Can I use absolute paths in the manifest `main` or `ui` fields?

No. The specification explicitly forbids absolute paths and `..` parent directory traversals in all path fields. All paths must be relative to the plugin root folder. The validator 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) rejects manifests violating this rule to prevent directory traversal attacks.

### What is the difference between `permissions` and `contributes` in the manifest?

**`permissions`** requests capabilities from the host (e.g., `ui.panel`, `fs.read`, `net.fetch`), acting as a security contract. **`contributes`** declares what the plugin provides to the host, such as commands, agent tools, or settings schemas. While `permissions` asks for access, `contributes` registers functionality that PI-Desktop surfaces to users and agents.