Guide · Manifest
manifest.json reference
One JSON file per plugin. Declares identity, capabilities, permissions, and optional sub-blocks for exec, rate limits, and settings.
Complete example
Add a $schema reference at the top of manifest.json for autocomplete and inline validation in any editor that supports JSON Schema (VS Code does out of the box). The schema is published at /plugin-manifest.schema.json.
{
"$schema": "https://petty.ericli.tech/plugin-manifest.schema.json",
"id": "my-plugin",
"name": "My Plugin",
"author": "Your Name",
"version": "1.0.0",
"description": "One-line description shown in the plugin list.",
"homepage": "https://github.com/you/my-plugin",
"script": "main.js",
"icon": "icon.png",
"capabilities": ["quips", "watchers"],
"permissions": ["network", "storage"],
"exec": {
"allowlist": ["git", "docker"],
"timeout": 30000
},
"rateLimits": {
"merge-conflict-alert": "10m",
"daily-briefing": "23h"
},
"settings": [
{
"key": "apiKey",
"type": "string",
"label": "API Key",
"default": ""
}
]
}Required fields
| Field | Type | Description |
|---|---|---|
id | string | Unique plugin identifier. Must match the folder name. Allowed characters: [a-zA-Z0-9_-]. |
name | string | Human-readable name shown in Settings. |
script | string | Path to JS entry point, relative to the plugin folder. Must resolve inside the plugin directory (no ../). |
capabilities | string[] | What the plugin does. See capabilities → |
permissions | string[] | What system access the plugin needs. See permissions → |
Optional fields
| Field | Type | Description |
|---|---|---|
author | string | Plugin author name. |
version | string | Semver version string. |
description | string | One-line description. |
homepage | string | URL to plugin's homepage. |
icon | string | Path to icon image, relative to plugin folder. |
exec | object | Required if permissions contains "exec". See below. |
rateLimits | object | Named cooldowns consumed by petty.rateLimit. See below. |
settings | array | Declarative settings schema. See settings → |
exec block
If your plugin declares the exec permission, you must also provide an exec block.
"exec": {
"allowlist": ["git", "docker"],
"timeout": 30000
}| Field | Type | Required | Description |
|---|---|---|---|
allowlist | string[] | Yes | Commands this plugin is allowed to run. Non-empty. |
timeout | number | No | Default timeout in milliseconds for all exec calls. Falls back to 300000 (5 min) if unspecified. |
rateLimits block
Named cooldowns consumed by petty.rateLimit.canFire / fire. Values are duration strings with units s/m/h/d.
"rateLimits": {
"merge-conflict-alert": "10m",
"daily-briefing": "23h",
"battery-low-warning": "1h"
}Each id is scoped to this plugin; two plugins can use the same id without collision. Cooldowns persist across restarts — “once per hour” means once per hour of wall-clock time, not once per launch.