Guide · Permissions & capabilities
The trust model
Plugins are trusted code — JavaScript running against a native bridge with file-system and subprocess access. The permission system is a transparency tool, not a sandbox.
Capabilities
Capabilities declare what roles your plugin plays. They're informational (for marketplace browsing) and in two cases gate specific host features.
| Capability | What it enables |
|---|---|
quips | Plugin pushes ambient quips via petty.quips.suggest(…). Informational hint — doesn't gate anything. |
reactions | Plugin subscribes to host events (hook:*, pet:*, …) to react. No additional contract. |
watchers | Plugin uses timers (petty.schedule.*) to poll state. No additional contract. |
menu-items | Plugin adds items to Petty's right-click menu via petty.menu.add(…). |
file-actions | Gates petty.fileActions. Registers custom drop actions in the context menu when files are dropped on Petty. |
tts-provider | Gates petty.tts. Registers a custom text-to-speech backend; once selected in Settings → Voice provider, every petty.pet.speak() call routes through this plugin. |
A plugin can declare multiple capabilities. Apart from file-actions and tts-provider, they're soft hints — declaring reactions doesn't force you to subscribe to events, it just documents intent.
Permissions
Permissions gate which petty.* namespaces are injected into your plugin's JavaScript context. If you don't declare a permission, the corresponding namespace is undefined — check with if (petty.network) before calling.
| Permission | Grants access to | Trust level |
|---|---|---|
system | petty.system (time, idle minutes, location) | Low |
storage | petty.storage (persistent key-value per plugin) | Low |
calendar | petty.calendar (upcoming events via EventKit) | Medium — reads calendar data |
weather | petty.weather (current conditions) | Low |
clipboard | petty.clipboard (read-only clipboard access) | Medium — can read sensitive copied content |
active-app | petty.activeApp (frontmost app bundle id / name) | Low |
network | petty.network.fetch (HTTP/HTTPS GET) | Medium — can contact any server |
exec | petty.exec.run (allowlisted subprocesses) | High — read below |
system and storage back always-on services — every plugin sees petty.system and petty.storage whether or not they're declared. Listing them in the manifest is still a good habit: it documents intent, and the marketplace UI uses the declared list to show users what the plugin touches.
The exec permission
This is the most powerful permission Petty grants. Understand exactly what it does before you grant it — or ship a plugin that requires it.
- Command scope. Plugins can only run commands listed in
exec.allowlist. A plugin with"allowlist": ["git"]cannot runrmorcurl. - No argument restrictions. Once a command is allowlisted, the plugin can pass any arguments. A plugin with
gitallowlisted can rungit clone(which triggers git hooks),git config(which writes files), and so on. - Full environment inheritance. Subprocesses inherit Petty's full environment, including any env vars set when Petty was launched (
GITHUB_TOKEN,AWS_ACCESS_KEY_ID,OPENAI_API_KEY, …). If your shell startup exports secrets, plugins withexeccan see them. - PATH resolution. Commands resolve through
/usr/bin/envusing your currentPATH. So"git"finds whichevergitis first inPATH— usually/usr/bin/gitor/opt/homebrew/bin/git.
The network permission
Plugins with network can make HTTP/HTTPS requests to any URL. file://, ftp://, and other schemes are blocked. There is no per-plugin domain allowlist — grant network and the plugin can reach the entire public internet.