Documentation
Authoring Feathers
Build a toowl Feather plugin — manifest, HostApi, and hot-start lifecycle.
Feathers are toowl plugins — sidebar panels and palette actions that hot-start on demand so launch stays fast.
Plugin types
| Type | Crate pattern | When to use |
|---|---|---|
| In-process | toowl-plugin-* linked into toowl-app | First-party, low-latency (Claude, Nest, MCP Hub, Scout) |
| Subprocess | JSON-RPC over stdio | Third-party; capability-gated |
Manifest (subprocess)
Third-party subprocess plugins live in ~/.config/toowl/plugins/<name>/plugin.toml:
id = "my-feather"
name = "My Feather"
version = "0.1.0"
program = "./my-feather-binary"
capabilities = ["pane_spawn"]
The id field is used for enable/disable in config before spawn — disabled plugins must not start a subprocess.
Plugin trait (in-process)
Implement toowl_plugin::Plugin:
init(&mut self, ctx: &InitCtx, host: &mut dyn HostApi)— keep minimal; defer FS watchers untilPluginEvent::PerchOpenedbuild_sidebar(&mut self, ctx: &ViewCtx) -> Option<View>— Perch UI treeon_event(&mut self, event: PluginEvent, host: &mut dyn HostApi)— clicks, palette, lifecycle
HostApi capabilities
spawn_pane— new tab/split with commandinject_pane/inject_input— paste into active PTYopen_url/http_get— browser and HTTP (requiresnetworkallowlist)show_banner— pane-attached notificationsread_file/watch_path— filesystem accessstate_get/state_set— plugin-scoped persistence
Hot-start contract
Plugins register at startup but must not spawn subprocesses, watch filesystems, or block the first frame until the user opens the Perch or invokes a palette action. Failures surface as inline View::Banner in the sidebar.
Testing locally
TOOWL_DEV_PLUGINS=dummy cargo run --release
TOOWL_DEV_PLUGINS=none cargo run --release # bisect: no plugins
bash scripts/feather-new.sh my-feather python
Publish to the Aviary
See the Aviary and the wire protocol. Run bash scripts/feather-submit.sh <id> before opening a PR.