Add rules.toml: declarative event->action automation without Lua

Adds a bread.rules built-in module plus a breadd/src/core/rules.rs
parser/validator so the common "when event X happens, do Y" case
(dock connect script, AC-disconnect notification, keyboard rate on
connect) no longer requires hand-written init.lua.

- rules.toml is optional, XDG_CONFIG_HOME-aware (mirrors breadd.toml's
  config_path() resolution), and purely additive alongside init.lua.
- Each [[rule]] needs `on` (event suffix, "bread." implied, wildcards
  supported) and exactly one of run/exec/notify. `run` names a single
  script (tilde-expanded + shell-quoted so spaces in the path can't be
  word-split); `exec` is a raw shell command line passed through as-is;
  `notify` shows a desktop notification.
- Rule data is threaded into the bread.rules Lua module via globals
  set just before it loads (same technique load_profiles() already
  uses for __profiles_path), avoiding any need to hand-escape values
  into generated Lua source text.
- Parse/validation failures surface through the existing module
  load-error path (Lua error() -> run_on_load -> set_module_status),
  so a bad rules.toml shows up via `bread doctor` exactly like a
  broken hand-written module would, without blocking other valid
  rules in the same file.
- Documentation.md gets a new Getting-started fast path plus a
  Dictionary entry; README's Configuration section gets a short
  pointer. Since: v1.5.
This commit is contained in:
Breadway 2026-08-04 22:05:26 +08:00
parent 96639516b1
commit 45b5aee117
7 changed files with 904 additions and 6 deletions

View file

@ -150,11 +150,33 @@ default_urgency = "normal"
notify_send_path = "notify-send"
[modules]
builtin = true # load built-in modules (monitors, devices, workspaces, binds)
builtin = true # load built-in modules (monitors, devices, workspaces, binds, rules)
disable = [] # list of built-in module names to disable
```
Your automation lives in `~/.config/bread/init.lua`. Modules placed in `~/.config/bread/modules/` are auto-loaded after `init.lua`:
For the common "when event X happens, do Y" case, you don't need Lua at
all — drop rules straight into `~/.config/bread/rules.toml` and skip
`init.lua` entirely:
```toml
# ~/.config/bread/rules.toml
[[rule]]
on = "device.dock.connected"
run = "~/.config/bread/scripts/dock-connected.sh"
[[rule]]
on = "power.ac.disconnected"
notify = "Unplugged"
```
It's optional and purely additive alongside `init.lua` — see
[Getting started in Documentation.md](Documentation.md#getting-started) for
the full schema (`run` vs `exec` vs `notify`, wildcard `on` patterns, and
how a malformed rule surfaces via `bread doctor`).
For anything beyond a single action per event, your automation lives in
`~/.config/bread/init.lua`. Modules placed in `~/.config/bread/modules/` are
auto-loaded after `init.lua`:
```lua
-- ~/.config/bread/init.lua