6 Commits

Author SHA1 Message Date
35a0f580c3 chore(owlry-rune): bump version to 0.4.6 2025-12-30 20:23:58 +01:00
7ed36c58c2 chore(owlry-lua): bump version to 0.4.6 2025-12-30 20:23:57 +01:00
7cccd3b512 chore(plugins): bump all plugins to 0.4.6 2025-12-30 20:23:48 +01:00
9f6d0c5935 chore: bump version to 0.4.6 2025-12-30 20:23:38 +01:00
026a232e0c docs: add ROADMAP.md with feature ideas
- High value/low effort: hot-reload, frecency pruning, :recent, clipboard images
- Medium effort: universal actions, plugin settings UI, result capture
- Bigger bets: window switcher, cross-device sync, natural language, plugin marketplace
- Technical debt: meval→evalexpr, API compat, per-plugin config

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 09:04:55 +01:00
1557119448 docs: comprehensive documentation update
README.md:
- Fix bundle package names (add meta- prefix)
- Add Firefox support to bookmarks plugin description
- Add system paths table (plugins, runtimes, example config)
- Add Quick Start section for copying example config
- Expand config example with providers section

docs/PLUGINS.md:
- Add Firefox support to bookmarks
- Fix bundle package names
- Remove outdated [plugins.weather] and [plugins.pomodoro] config examples

docs/PLUGIN_DEVELOPMENT.md:
- Fix Rust edition from 2024 to 2021
- Add position and priority fields to ProviderInfo
- Add ProviderPosition enum documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 08:49:30 +01:00
22 changed files with 176 additions and 72 deletions

34
Cargo.lock generated
View File

@@ -2373,7 +2373,7 @@ dependencies = [
[[package]]
name = "owlry"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"chrono",
"clap",
@@ -2402,7 +2402,7 @@ dependencies = [
[[package]]
name = "owlry-lua"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"chrono",
@@ -2420,7 +2420,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-api"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"serde",
@@ -2428,7 +2428,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-bookmarks"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"dirs",
@@ -2440,7 +2440,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-calculator"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"meval",
@@ -2449,7 +2449,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-clipboard"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"owlry-plugin-api",
@@ -2457,7 +2457,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-emoji"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"owlry-plugin-api",
@@ -2465,7 +2465,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-filesearch"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"dirs",
@@ -2474,7 +2474,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-media"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"owlry-plugin-api",
@@ -2482,7 +2482,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-pomodoro"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"dirs",
@@ -2494,7 +2494,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-scripts"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"dirs",
@@ -2503,7 +2503,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-ssh"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"dirs",
@@ -2512,7 +2512,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-system"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"owlry-plugin-api",
@@ -2520,7 +2520,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-systemd"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"owlry-plugin-api",
@@ -2528,7 +2528,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-weather"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"dirs",
@@ -2541,7 +2541,7 @@ dependencies = [
[[package]]
name = "owlry-plugin-websearch"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"abi_stable",
"owlry-plugin-api",
@@ -2549,7 +2549,7 @@ dependencies = [
[[package]]
name = "owlry-rune"
version = "0.4.5"
version = "0.4.6"
dependencies = [
"chrono",
"dirs",

View File

@@ -32,10 +32,10 @@ yay -S owlry
yay -S owlry-plugin-calculator owlry-plugin-weather
# Or install bundles:
yay -S owlry-essentials # calculator, system, ssh, scripts, bookmarks
yay -S owlry-widgets # weather, media, pomodoro
yay -S owlry-tools # clipboard, emoji, websearch, filesearch, systemd
yay -S owlry-full # everything
yay -S owlry-meta-essentials # calculator, system, ssh, scripts, bookmarks
yay -S owlry-meta-widgets # weather, media, pomodoro
yay -S owlry-meta-tools # clipboard, emoji, websearch, filesearch, systemd
yay -S owlry-meta-full # everything
# For custom Lua/Rune plugins
yay -S owlry-lua # Lua 5.4 runtime
@@ -53,7 +53,7 @@ yay -S owlry-rune # Rune runtime
| `owlry-plugin-clipboard` | History via cliphist |
| `owlry-plugin-emoji` | 400+ searchable emoji |
| `owlry-plugin-scripts` | User scripts |
| `owlry-plugin-bookmarks` | Chrome, Brave, Edge bookmarks |
| `owlry-plugin-bookmarks` | Firefox, Chrome, Brave, Edge bookmarks |
| `owlry-plugin-websearch` | Web search (`? query`) |
| `owlry-plugin-filesearch` | File search (`/ filename`) |
| `owlry-plugin-systemd` | User services with actions |
@@ -158,6 +158,21 @@ Owlry follows the [XDG Base Directory Specification](https://specifications.free
| `~/.local/share/owlry/scripts/` | User scripts |
| `~/.local/share/owlry/frecency.json` | Usage history |
System locations:
| Path | Purpose |
|------|---------|
| `/usr/lib/owlry/plugins/*.so` | Installed native plugins |
| `/usr/lib/owlry/runtimes/*.so` | Lua/Rune script runtimes |
| `/usr/share/doc/owlry/config.example.toml` | Example configuration |
### Quick Start
```bash
# Copy example config
mkdir -p ~/.config/owlry
cp /usr/share/doc/owlry/config.example.toml ~/.config/owlry/config.toml
```
### Example Configuration
```toml
@@ -169,8 +184,8 @@ tabs = ["app", "cmd", "uuctl"]
# launch_wrapper = "uwsm app --" # Auto-detected
[appearance]
width = 700
height = 500
width = 850
height = 650
font_size = 14
border_radius = 12
# theme = "owl" # Or: catppuccin-mocha, nord, dracula, etc.
@@ -178,17 +193,18 @@ border_radius = 12
[plugins]
disabled = [] # Plugin IDs to disable, e.g., ["emoji", "pomodoro"]
# Per-plugin configuration (new in 0.4.0)
[plugins.weather]
provider = "wttr.in" # or: openweathermap, open-meteo
location = "Berlin" # city name or "lat,lon"
# api_key = "..." # Required for OpenWeatherMap
[providers]
applications = true # .desktop files
commands = true # PATH executables
frecency = true # Boost frequently used items
frecency_weight = 0.3 # 0.0-1.0
[plugins.pomodoro]
work_mins = 25 # Work session duration
break_mins = 5 # Break duration
# Web search engine: google, duckduckgo, bing, startpage, brave, ecosia
search_engine = "duckduckgo"
```
See `/usr/share/doc/owlry/config.example.toml` for all options with documentation.
## Plugin System
Owlry uses a modular plugin architecture. Plugins are loaded from:

91
ROADMAP.md Normal file
View File

@@ -0,0 +1,91 @@
# Owlry Roadmap
Feature ideas and future development plans for Owlry.
## High Value, Low Effort
### Plugin hot-reload
Detect `.so` file changes in `/usr/lib/owlry/plugins/` and reload without restarting the launcher. The loader infrastructure already exists.
### Frecency pruning
Add `max_entries` and `max_age_days` config options. Prune old entries on startup to prevent `frecency.json` from growing unbounded.
### `:recent` prefix
Show last N launched items. Data already exists in frecency.json — just needs a provider to surface it.
### Clipboard images
`cliphist` supports images. Extend the clipboard plugin to show image thumbnails in results.
---
## Medium Effort, High Value
### Actions on any result
Generalize the submenu system beyond systemd. Every result type gets contextual actions:
| Provider | Actions |
|----------|---------|
| Applications | Open, Open in terminal, Show .desktop location |
| Files | Open, Open folder, Copy path, Delete |
| SSH | Connect, Copy hostname, Edit config |
| Bookmarks | Open, Copy URL, Open incognito |
| Clipboard | Paste, Delete from history |
This is the difference between a launcher and a command palette.
### Plugin settings UI
A `:settings` provider that lists installed plugins and their configurable options. Edit values inline, writes to `config.toml`.
### Result action capture
Calculator shows `= 5+3 → 8`. Allow pressing Tab or Ctrl+C to copy the result to clipboard instead of "launching" it. Useful for calculator, file paths, URLs.
---
## Bigger Bets
### Window switcher with live thumbnails
A `windows` plugin using Wayland screencopy to show live thumbnails of open windows. Hyprland and Sway expose window lists via IPC. Could replace Alt+Tab.
### Cross-device bookmark sync
Firefox and Chrome sync bookmarks across devices. Parse sync metadata to show "recently added on other devices" or "bookmarks from phone".
### Natural language commands
Parse simple natural language into system commands:
```
"shutdown in 30 minutes" → systemd-run --user --on-active=30m systemctl poweroff
"remind me in 1 hour" → notify-send scheduled via at/systemd timer
"volume 50%" → wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.5
```
Local pattern matching, no AI/cloud required.
### Plugin marketplace
A curated registry of third-party Lua/Rune plugins with one-command install:
```bash
owlry plugin install github-notifications
owlry plugin install todoist
owlry plugin install spotify-controls
```
The script runtimes make this viable without recompiling.
---
## Technical Debt
### Replace meval with evalexpr
`meval` depends on `nom v1.2.4` which will be rejected by future Rust versions. Migrate calculator plugin and Lua runtime to `evalexpr` v13+.
### Plugin API backwards compatibility
When `API_VERSION` increments, provide a compatibility shim so v3 plugins work with v4 core. Prevents ecosystem fragmentation.
### Per-plugin configuration
Current flat `[providers]` config doesn't scale. Design a `[plugins.weather]`, `[plugins.pomodoro]` structure that plugins can declare and the core validates.
---
## Priority
If we had to pick one: **Actions on any result**. It transforms every provider from "search and launch" to "search and do anything". The ROI is massive.

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-lua"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-api"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-bookmarks"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-calculator"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-clipboard"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-emoji"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-filesearch"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-media"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-pomodoro"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-scripts"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-ssh"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-system"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-systemd"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-weather"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-plugin-websearch"
version = "0.4.5"
version = "0.4.6"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-rune"
version = "0.4.5"
version = "0.4.6"
edition = "2024"
rust-version = "1.90"
description = "Rune scripting runtime for owlry plugins"

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry"
version = "0.4.5"
version = "0.4.6"
edition = "2024"
rust-version = "1.90"
description = "A lightweight, owl-themed application launcher for Wayland"

View File

@@ -143,9 +143,10 @@ chmod +x ~/.local/share/owlry/scripts/backup.sh
**Prefix:** `:bm`
**Package:** `owlry-plugin-bookmarks`
Browser bookmarks from Chromium-based browsers.
Browser bookmarks from Firefox and Chromium-based browsers.
**Supported browsers:**
- Firefox (reads places.sqlite)
- Google Chrome
- Brave
- Microsoft Edge
@@ -236,13 +237,7 @@ Current weather displayed at the top of results.
- OpenWeatherMap (requires API key)
- Open-Meteo (no API key required)
**Configuration:**
```toml
[plugins.weather]
provider = "wttr.in" # or: openweathermap, open-meteo
location = "London" # city name or "lat,lon" (empty for auto-detect)
# api_key = "..." # Required for OpenWeatherMap
```
**Note:** Weather configuration is currently embedded in the plugin. Future versions will support runtime configuration.
**Features:**
- Temperature, condition, humidity, wind speed
@@ -274,13 +269,6 @@ MPRIS media player controls.
Pomodoro timer with work/break cycles.
**Configuration:**
```toml
[plugins.pomodoro]
work_mins = 25 # Work session duration (default: 25)
break_mins = 5 # Break duration (default: 5)
```
**Features:**
- Configurable work session duration
- Configurable break duration
@@ -301,17 +289,17 @@ For convenience, plugins are available in bundle meta-packages:
| Bundle | Plugins |
|--------|---------|
| `owlry-essentials` | calculator, system, ssh, scripts, bookmarks |
| `owlry-widgets` | weather, media, pomodoro |
| `owlry-tools` | clipboard, emoji, websearch, filesearch, systemd |
| `owlry-full` | All of the above |
| `owlry-meta-essentials` | calculator, system, ssh, scripts, bookmarks |
| `owlry-meta-widgets` | weather, media, pomodoro |
| `owlry-meta-tools` | clipboard, emoji, websearch, filesearch, systemd |
| `owlry-meta-full` | All of the above |
```bash
# Install everything
yay -S owlry-full
yay -S owlry-meta-full
# Or pick a bundle
yay -S owlry-essentials owlry-widgets
yay -S owlry-meta-essentials owlry-meta-widgets
```
---

View File

@@ -23,7 +23,7 @@ Edit `Cargo.toml`:
[package]
name = "owlry-plugin-myplugin"
version = "0.1.0"
edition = "2024"
edition = "2021"
[lib]
crate-type = ["cdylib"]
@@ -38,7 +38,7 @@ Edit `src/lib.rs`:
use abi_stable::std_types::{ROption, RStr, RString, RVec};
use owlry_plugin_api::{
owlry_plugin, PluginInfo, PluginItem, ProviderHandle, ProviderInfo,
ProviderKind, API_VERSION,
ProviderKind, ProviderPosition, API_VERSION,
};
extern "C" fn plugin_info() -> PluginInfo {
@@ -59,6 +59,8 @@ extern "C" fn plugin_providers() -> RVec<ProviderInfo> {
icon: RString::from("application-x-executable"),
provider_type: ProviderKind::Static,
type_id: RString::from("myplugin"),
position: ProviderPosition::Normal,
priority: 0, // Use frecency-based ordering
}].into()
}
@@ -198,12 +200,19 @@ pub struct ProviderInfo {
pub icon: RString, // Default icon name
pub provider_type: ProviderKind, // Static or Dynamic
pub type_id: RString, // Short ID for badges
pub position: ProviderPosition, // Normal or Widget
pub priority: i32, // Result ordering (higher = first)
}
pub enum ProviderKind {
Static, // Items loaded at startup via refresh()
Dynamic, // Items computed per-query via query()
}
pub enum ProviderPosition {
Normal, // Standard results (sorted by score/frecency)
Widget, // Displayed at top when query is empty
}
```
### PluginItem