From 088664aefda86edb2af32135f62a6c5e730f2b0e Mon Sep 17 00:00:00 2001 From: vikingowl Date: Thu, 26 Mar 2026 13:27:46 +0100 Subject: [PATCH] docs: add CLAUDE.md for plugins workspace --- CLAUDE.md | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b98670c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,158 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +Official native plugins for the [Owlry](https://somegit.dev/Owlibou/owlry) application launcher. Each plugin is compiled as a shared library (`.so`) and loaded by the `owlry-core` daemon at runtime via the ABI-stable plugin interface. + +## Build & Development Commands + +```bash +just build # Debug build (all plugins) +just release # Release build (all plugins, LTO + stripped) +just plugin # Build specific plugin release (e.g., just plugin calculator) +just plugins # Alias for release build of all plugins +just check # cargo check + clippy +just test # Run tests +just fmt # Format code +just show-versions # List all plugin crate versions +just install-local # Build release + install all .so to /usr/lib/owlry/plugins/ + +# Build a specific plugin manually +cargo build -p owlry-plugin-calculator --release +# Output: target/release/libowlry_plugin_calculator.so + +# Bump versions +just bump-crate owlry-plugin-weather 0.5.0 # Bump specific plugin +just bump-all 0.5.0 # Bump all plugins +``` + +## Workspace Structure + +``` +owlry-plugins/ +├── Cargo.toml # Workspace root +├── crates/ +│ ├── owlry-plugin-bookmarks/ # Firefox/Chrome bookmarks +│ ├── owlry-plugin-calculator/ # Math expression evaluation +│ ├── owlry-plugin-clipboard/ # Clipboard history (cliphist) +│ ├── owlry-plugin-emoji/ # Emoji picker +│ ├── owlry-plugin-filesearch/ # File search (fd/mlocate) +│ ├── owlry-plugin-media/ # Media player controls (widget) +│ ├── owlry-plugin-pomodoro/ # Pomodoro timer (widget) +│ ├── owlry-plugin-scripts/ # User script runner +│ ├── owlry-plugin-ssh/ # SSH host picker +│ ├── owlry-plugin-system/ # System actions (shutdown, reboot, etc.) +│ ├── owlry-plugin-systemd/ # systemd user unit control +│ ├── owlry-plugin-weather/ # Weather display (widget) +│ └── owlry-plugin-websearch/ # Web search providers +├── aur/ # AUR PKGBUILDs for all plugins + meta-packages +└── docs/ # Plugin development documentation +``` + +## Plugin API Dependency + +All plugins depend on `owlry-plugin-api` from the core repo. Currently referenced as a local path (for development), will be a git dependency for releases: + +```toml +# In each plugin's Cargo.toml +[dependencies] +owlry-plugin-api = { path = "/path/to/owlry/crates/owlry-plugin-api" } +``` + +Each plugin crate is compiled as `cdylib`: + +```toml +[lib] +crate-type = ["cdylib"] +``` + +## Plugin Architecture + +Every plugin exports a single C-ABI function: + +```rust +#[no_mangle] +pub extern "C" fn owlry_plugin_vtable() -> &'static PluginVTable +``` + +The `PluginVTable` provides function pointers for: +- `info()` - Plugin metadata (name, version, description) +- `providers()` - List of providers the plugin offers (id, name, prefix, icon, position, priority) +- `provider_init(id)` - Initialize a provider instance +- `provider_refresh(handle)` - Populate/reload items (static providers) +- `provider_query(handle, query)` - Search items (dynamic providers) +- `provider_drop(handle)` - Clean up provider instance + +All types cross the ABI boundary using `abi_stable` crate types (`RVec`, `RStr`, `RString`, etc.). + +### Provider Categories + +| Category | Plugins | Behavior | +|----------|---------|----------| +| Static | bookmarks, clipboard, emoji, scripts, ssh, system, systemd | `refresh()` populates items at startup; `query()` filters them | +| Dynamic | calculator, websearch, filesearch | `query()` generates results per keystroke | +| Widget | weather, media, pomodoro | Displayed at top of results via `position: Widget` | + +### Submenu System + +Plugins can return items with `SUBMENU:plugin_id:data` as the command. When the user selects such an item, the daemon calls `provider_query(handle, "?SUBMENU:data")` to get contextual action items (e.g., systemd service start/stop/restart). + +## Adding a New Plugin + +1. Create crate: `cargo init --lib crates/owlry-plugin-myplugin` +2. Set `crate-type = ["cdylib"]` in Cargo.toml +3. Add `owlry-plugin-api` and `abi_stable` dependencies +4. Implement `owlry_plugin_vtable()` returning a static `PluginVTable` +5. Add the crate to workspace members in root `Cargo.toml` +6. Register the provider ID prefix in the core repo's `ProviderFilter` if desired + +See `docs/PLUGIN_DEVELOPMENT.md` for detailed guidance. + +## AUR Packaging + +The `aur/` directory contains PKGBUILDs for: + +| Category | Packages | +|----------|----------| +| Plugins (13) | `owlry-plugin-{bookmarks,calculator,clipboard,emoji,filesearch,media,pomodoro,scripts,ssh,system,systemd,weather,websearch}` | +| Meta-bundles | `owlry-meta-essentials`, `owlry-meta-widgets`, `owlry-meta-tools`, `owlry-meta-full` | + +Plugin `.so` files are installed to `/usr/lib/owlry/plugins/` with consistent naming: `libowlry_plugin_*.so`. + +All plugin PKGBUILDs include `.install` files that clean up old plugin files on upgrade. + +## Testing + +```bash +# Run all plugin tests +just test + +# Test a specific plugin +cargo test -p owlry-plugin-calculator +``` + +Most plugins are tested via their `query()` and `refresh()` implementations. The `owlry-plugin-api` crate provides the types needed for test assertions. + +## External Dependencies + +Some plugins require external tools at runtime: + +| Plugin | Dependencies | +|--------|-------------| +| clipboard | `cliphist`, `wl-clipboard` | +| filesearch | `fd` or `mlocate` | +| emoji | `wl-clipboard`, `noto-fonts-emoji` | +| systemd | `systemd` (user services) | +| bookmarks | None (bundled SQLite via `rusqlite`) | +| media | D-Bus (MPRIS) | +| websearch | `xdg-open` or configured browser | + +## Key Patterns + +- All plugins are `cdylib` crates producing `.so` files +- ABI stability via `abi_stable` crate - never break the vtable contract +- Plugin API v3: `ProviderInfo` includes `position` (Normal/Widget) and `priority` fields +- Plugins have independent versions from the core (currently 0.4.x) +- No direct dependency on GTK or UI code - plugins are pure data providers