Plugin Manifest
Every plugin requires a manifest.json file that describes the plugin and its modules.
Basic structure
{
"id": "my-plugin",
"name": "My Plugin",
"modules": [
{
"id": "my-panel",
"name": "My Panel",
"main": "index.html",
"type": "panel"
}
]
}
Top-level fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique plugin identifier. Use lowercase with hyphens. |
name | string | Yes | Human-readable name displayed in the UI. |
modules | array | Yes | Array of module definitions. |
Module fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique module identifier within the plugin. |
name | string | Yes | Human-readable name for the module. |
main | string | Yes | Entry point file (usually index.html). |
type | string | Yes | Module type: panel, editor, service, or blank. |
permissions | array | No | List of permissions the module requires. |
order | number | No | Sort order for panels (lower = higher in sidebar). |
fileAssociations | array | No | File extensions this editor handles (for editor type). |
Module types
Panel
Displays in the left sidebar. Use for navigation, file explorers, or tool interfaces.
{
"id": "file-browser",
"name": "Files",
"main": "index.html",
"type": "panel",
"order": 0
}
Editor
Opens files of specific types. Appears in the main content area.
{
"id": "markdown-editor",
"name": "Markdown Editor",
"main": "index.html",
"type": "editor",
"fileAssociations": [".md", ".markdown"]
}
Service
Runs in the background without UI. Use for background processing or maintaining state.
{
"id": "sync-service",
"name": "Sync Service",
"main": "service.html",
"type": "service"
}
Blank
Minimal module that loads but has no designated UI slot. Useful for registering LLM tools without needing a visible panel.
{
"id": "tools-only",
"name": "AI Tools",
"main": "index.html",
"type": "blank"
}
Permissions
Declare permissions your plugin needs:
{
"id": "my-panel",
"name": "My Panel",
"main": "index.html",
"type": "panel",
"permissions": ["fs.watch", "ui:read"]
}
Available permissions
| Permission | Description |
|---|---|
fs.watch | Subscribe to file system change events |
ui:read | Read UI state (open tabs, etc.) |
Most SDK methods work without explicit permissions. Permissions are only required for specific features like file watching.
Multiple modules
A single plugin can contain multiple modules:
{
"id": "my-plugin",
"name": "My Plugin",
"modules": [
{
"id": "sidebar-panel",
"name": "My Panel",
"main": "panel.html",
"type": "panel"
},
{
"id": "md-editor",
"name": "Markdown Editor",
"main": "editor.html",
"type": "editor",
"fileAssociations": [".md"]
},
{
"id": "background",
"name": "Background Service",
"main": "service.html",
"type": "service"
}
]
}
File associations
For editor modules, specify which file extensions to handle:
{
"id": "image-viewer",
"name": "Image Viewer",
"main": "index.html",
"type": "editor",
"fileAssociations": [".png", ".jpg", ".jpeg", ".gif", ".webp"]
}
When a user opens a file with a matching extension, your editor will be used.