Gaivota Plugin System
Gaivota's plugin system allows you to create virtual folders - smart folders that filter and transform emails using Lua scripts.
Quick Start
- Place a
.luafile in~/.gaivota/plugins/ - Restart Gaivota or trigger a plugin scan
- Accept the installation prompt
- Your virtual folder appears in the sidebar
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ Plugin Lifecycle │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ~/.gaivota/plugins/links.lua │
│ │ │
│ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Plugin Discovery │───▶│ Metadata Parsing │ │
│ │ (scan_plugins) │ │ (Lua VM) │ │
│ └─────────────────┘ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Installation │ │
│ │ • Save LuaScript to DB │ │
│ │ • Create VirtualFolder │ │
│ │ (per account) │ │
│ └──────────┬───────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Runtime Execution │ │
│ │ filter(email, user_email) → boolean │ │
│ │ render(email, metadata) → VirtualEmail │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Plugin Structure
Minimal Plugin
~/.gaivota/plugins/my-filter.lua
-- Required: Plugin metadata
metadata = {
name = "My Filter",
description = "Filters emails by custom criteria",
version = "1.0",
creates = {
virtual_folder = {
name = "My Folder",
description = "Emails matching my criteria",
icon = "filter" -- Lucide icon name
}
}
}
-- Required: Filter function
-- Returns true to include email in virtual folder
function filter(email, user_email)
return email:subject():match("important")
end
-- Required: Render function
-- Transforms how email appears in virtual folder
function render(email, metadata_list)
return {
subject = email:subject(),
sender = email:sender_name() or email:sender(),
preview = email:preview(),
body_html = "<p>" .. (email:preview() or "") .. "</p>"
}
end
Required Components
Every plugin must have:
metadatatable - Plugin information and what it createsfilter(email, user_email)function - Returnstrueto include emailrender(email, metadata_list)function - Returns display data
Plugin Discovery
Gaivota scans ~/.gaivota/plugins/ for:
- Single-file plugins:
*.luafiles (e.g.,links.lua) - Folder plugins: Directories with
init.lua(e.g.,my-plugin/init.lua)
Folder Plugin Structure
For complex plugins with multiple files:
~/.gaivota/plugins/
└── my-complex-plugin/
├── init.lua # Entry point (required)
├── helpers.lua # Additional modules
└── templates.lua # HTML templates
Available Icons
The icon field in metadata accepts any Lucide icon name:
| Icon Name | Use Case |
|---|---|
link | Links, URLs |
folder | Generic folder |
mail | Email-related |
star | Starred, favorites |
tag | Tags, labels |
bookmark | Saved items |
heart | Liked items |
zap | Quick actions |
bell | Notifications |
filter | Filtered views |
Managing Plugins
Access the Plugins settings tab to view, enable, disable, or remove installed plugins:

Next Steps
- API Reference - Complete Lua API documentation
- Examples - Full plugin examples with explanations
- Security - Sandbox model and limitations
- Troubleshooting - Common issues and solutions