The bookmarks provider opened Firefox's places.sqlite directly via
rusqlite, which pulled libsqlite3-sys with its bundled feature to
compile sqlite3.c statically. In clean Arch chroots the bundled feature
kept slipping out of the resolved feature graph and the chroot build
failed at link time with every sqlite3_* symbol undefined. Inline
features = ["bundled"] on the optional dep didn't help; neither did
the explicit "rusqlite/bundled" feature wiring (commit 7569b2d).
Rather than fight Cargo's resolver further, defer the bookmarks
provider alongside the widgets per the same pattern (D20 -> D22).
Returns in a later 2.x release with a pure-Rust reader:
- Chromium's Bookmarks file is already JSON.
- Firefox exposes JSON backups under ~/.mozilla/firefox/<profile>/
bookmarkbackups/<dated>.jsonlz4 — needs lz4 + JSON parse, no SQLite.
Removed:
- crates/owlry/src/providers/bookmarks.rs
- bookmarks module + registration in providers/mod.rs
- bookmarks feature + rusqlite dep in Cargo.toml
- ProvidersConfig.bookmarks field (existing user configs that still
have 'bookmarks = true' silently ignore it — serde default behavior)
- :bm prefix from README's search-prefix table
- bookmarks acknowledgement in README + ROADMAP roadmap section
Cargo.lock loses rusqlite, libsqlite3-sys, fallible-iterator,
fallible-streaming-iterator, foldhash, hashlink, rsqlite-vfs,
sqlite-wasm-rs (-80 lines).
PKGBUILD: owlry-plugin-bookmarks stays in replaces= (any user who has
it installed still needs a clean upgrade), but moved from the 'folded'
comment block to the 'deferred (D20+)' block.
Docs:
- README: bookmarks removed from optional-providers list, feature
table, search-prefix table, config example. Added to upcoming
roadmap section alongside widgets.
- ROADMAP: 'Bookmarks return' subsection added next to 'Widget
providers return'.
- CLAUDE.md: provider tree updated.
- docs/RESTRUCTURE-V2.md: new decision D22 with chroot-build
rationale; task #6 plugin count 8 -> 7 -> 6.
245 tests pass with --features full (was 252; the 7 bookmarks unit
tests went with the module). Build verified locally; chroot build
should now succeed since libsqlite3-sys is no longer in the graph
at all.
Closes the v2 plugin conversion. Six providers ported from the
owlry-plugins sibling repo into the single owlry crate as feature-
gated modules. Each follows the same pattern established by systemd:
drop extern "C"/PluginItem/ProviderHandle/owlry_plugin! scaffolding,
implement Provider or DynamicProvider directly on a regular struct.
Static providers (Provider trait, populate via refresh):
- providers/bookmarks.rs — Firefox + Chromium bookmarks via rusqlite,
favicon cache preserved. dep: rusqlite (bundled), feature: bookmarks
- providers/clipboard.rs — cliphist history. feature: clipboard
- providers/emoji.rs — bundled emoji list with keyword tags.
feature: emoji
- providers/ssh.rs — ~/.ssh/config host extraction. feature: ssh
Dynamic providers (DynamicProvider trait, generate per query):
- providers/filesearch.rs — fd / mlocate shellout with extract_search_term
for ':file' and '/' triggers. feature: filesearch
- providers/websearch.rs — URL builder with DuckDuckGo/Google/custom
engines. TODO: plumb engine through constructor once Lua config lands
(Phase 3). feature: websearch
Wiring:
- Cargo.toml: 7 per-provider features + 'full' meta-feature. rusqlite
added as optional dep (only pulled in with feature 'bookmarks').
- config/mod.rs: ProvidersConfig gains 6 new bool fields (defaults true)
- providers/mod.rs: gated module declarations + new_with_config takes a
config snapshot and registers each provider behind its feature flag
Verification across feature axes:
- --no-default-features: 178 tests pass (feature-gated modules excluded)
- default (systemd only): 186 tests pass
- --features full: 233 tests pass (+55 from the 6 new conversions)
Tasks #6 and #7 complete.
Workspace shrinks from 2 members to 1. The daemon, IPC layer,
providers, config, frecency store, GTK4 UI, and CLI now live in a
single `crates/owlry` crate exposing both a library (so integration
tests can reach daemon types) and a binary.
Structural changes:
- crates/owlry-core/ deleted; all source moved into crates/owlry/src/
via git mv to preserve history
- crates/owlry/src/lib.rs added with module declarations
- crates/owlry/src/main.rs rewritten as thin entry that uses owlry::*
- crates/owlry/src/providers/mod.rs absorbs owlry-core's providers/mod.rs
and pulls dmenu into the same module tree
- All owlry_core:: refs in src/ rewritten to crate::
- All owlry_core:: refs in tests/ rewritten to owlry::
- systemd/owlryd.service: ExecStart=/usr/bin/owlry -d (single binary)
- justfile: drop owlry-core/owlry-lua/owlry-rune build steps; daemon
runs via 'cargo run -p owlry -- -d'
- owlry version: 1.0.10 -> 2.0.0-dev
Tests: 178 still pass (156 lib + 14 ipc + 8 server). No test changes
needed — moved files retained their inline test modules.
Task #2 complete.
Delete the entire dynamic-loading infrastructure that produced issue #5
and the per-API-bump plugin breakage cycle:
- crates/owlry-plugin-api/ (ABI-stable interface, gone)
- crates/owlry-lua/ (Lua runtime cdylib, gone — replaced by mlua in Phase 3)
- crates/owlry-rune/ (Rune runtime cdylib, gone per D3)
- owlry-core/src/plugins/ (loader, manifest, registry, watcher — all gone)
- owlry-core/src/providers/native_provider.rs
- owlry-core/src/providers/lua_provider.rs
- owlry-core/src/providers/config_editor.rs (per D11, 1127 LOC)
- owlry/src/plugin_commands.rs (per CLI restructure, 1296 LOC)
Provider trait gains submenu_actions(), execute_action(), prefix(),
icon(), position(), priority() as default methods so future built-in
providers can declare their UI metadata directly instead of relying on
the hardcoded match table.
ProviderManager simplified: drops native_providers,
static_native_providers, dynamic_providers, widget_providers,
runtimes, runtime_type_ids, plugin_registry fields and the
reload_runtimes / find_native_provider / get_widget_item /
widget_type_ids methods. ProviderPosition enum carries the Normal/
Widget distinction on the trait instead.
IPC Request::PluginList and Response::PluginList removed; Submenu
and PluginAction stay (route to Provider trait methods now).
owlry -d / --daemon flag added as the future daemon entry point; the
old owlryd binary is still produced from owlry-core for Phase 1
compatibility but will fold into the single binary in task #2.
Workspace shrinks from 5 members to 2. Tests: 142 passed.
LOC: -13,796 / +273 (net -13,523).
Tasks #3, #4, #5 complete.
reqwest 0.13 defaults to rustls -> aws-lc-rs which requires cmake/nasm
in minimal build environments (AUR chroot). Switch all direct reqwest
users to native-tls (system OpenSSL) to fix clean chroot build failures
reported by users.
Affected crates: owlry-core, owlry-lua, owlry-rune
PKGBUILD: add openssl to depends for all three runtime packages
Also add scripts/aur-local-test for clean chroot testing workflow
Search queries in daemon mode now run on a background thread via
DaemonHandle::query_async(). Results are posted back to the main
thread via glib::spawn_future_local + futures_channel::oneshot.
The GTK event loop is never blocked by IPC, eliminating perceived
input lag.
Local mode (dmenu) continues to use synchronous search since it
has no IPC overhead.
The UI now uses a SearchBackend abstraction that wraps either:
- CoreClient (daemon mode): connects to owlry-core via IPC for search,
frecency tracking, submenu queries, and plugin actions
- Local ProviderManager (dmenu mode): unchanged direct provider access
Key changes:
- New backend.rs with SearchBackend enum abstracting IPC vs local
- app.rs creates CoreClient in normal mode, falls back to local if
daemon unavailable
- main_window.rs uses SearchBackend instead of ProviderManager+FrecencyStore
- Command execution stays in the UI (daemon only tracks frecency)
- dmenu mode path is completely unchanged (no daemon involvement)
- Added terminal field to IPC ResultItem for proper terminal launch
- Added PluginAction IPC request for plugin command execution
- Add owlry-core dependency to owlry Cargo.toml
- Remove dependencies from owlry that moved to owlry-core:
fuzzy-matcher, freedesktop-desktop-entry, libloading, notify-rust,
thiserror, mlua, meval, reqwest
- Forward feature flags (dev-logging, lua) to owlry-core
- Update all imports in owlry source files to use owlry_core::
for moved modules (config, data, filter, providers, plugins,
notify, paths)
- Delete original source files from owlry that were moved
- Create minimal providers/mod.rs that only re-exports DmenuProvider
- Move plugins/commands.rs to plugin_commands.rs (stays in owlry
since it depends on CLI types from clap)
- Restructure app.rs to build core providers externally and pass
them to ProviderManager::new() instead of using the old
with_native_plugins() constructor