bread/examples/modules/README.md
Breadway 6841163620 Add capability-scoped module API (Workstream D)
ModuleManifest gains a structured [[permissions]] field (bread-shared's
new ModulePermission/PermissionKind, shared between bread-cli and breadd
so the two never drift on what a permission "type" string means).

breadd now gives every third-party module's Lua chunk a scoped _ENV
instead of the shared global table: load_scoped_lua_file builds a fresh
`bread` table containing only baseline bindings (event subscription,
timers, json, module/store, logging, and the pure-Lua sugar built on top
of those) plus whatever the manifest's permissions grant, with a
metatable __index falling back to the real globals for everything else
(stdlib, require/package - so require("bread.devices") keeps working,
since builtins load unscoped and their closures capture that environment
lexically regardless of the caller's). _G is explicitly rebound to the
scoped table itself to close the obvious escape hatch. A module with no
manifest, or a manifest with no permissions key, keeps full ambient
access unchanged (today's behavior) but is now tracked as `ungated` in
module status and surfaced by `bread doctor`. An explicit `permissions =
[]` is scoped for real but not flagged, since that's a deliberate
declaration.

Adds `bread modules audit <name>`: a best-effort text scan of a module's
.lua files suggesting a [[permissions]] block to paste into its manifest.

Converts examples/modules/cpu-temp-widget.lua into a directory module
with a worked bread.module.toml (fs.read + widget) as the reference
example. Documentation.md gets a new "Capability-scoped modules" section
covering the taxonomy, the require()/closure mechanism, and an explicit
note that path/bin scoping is recorded but not yet enforced per-call -
that's the out-of-process module sandboxing workstream this manifest
schema is laid down for. API_VERSION bumped 1.4.0 -> 1.5.0.
2026-08-04 22:24:16 +08:00

3.1 KiB

Example bread modules

Ready-to-use modules for common desktop automations. Unlike the snippets in ../../Examples.md (which teach the porting patterns), these are complete files you can drop in as-is.

Installing

Modules in ~/.config/bread/modules/ are auto-discovered — copy a file in and reload; no init.lua edit needed:

cp low-battery-warning.lua ~/.config/bread/modules/
bread reload

cpu-temp-widget/ is a directory (not a flat file) with a bread.module.toml manifest declaring its [[permissions]] — see Capability-scoped modules. Either copy the whole directory into ~/.config/bread/modules/, or install it properly so the manifest travels with it:

bread modules install ./cpu-temp-widget
bread reload

The other modules here are flat files with no manifest — they load exactly like today, with full, ungated bread.* access (bread doctor will note that). Run bread modules audit <name> on an installed one any time to get a suggested [[permissions]] block for its own bread.module.toml.

Modules

File What it does Config needed
low-battery-warning.lua Critical notification once when the battery runs low; resets on AC. none
pause-media-on-headphone-unplug.lua Runs playerctl pause when a headphone/earbud device disconnects. none (needs playerctl)
dock-monitors.lua Applies a multi-monitor layout when an external display connects, reverts when removed. edit output names/resolutions
active-window-widget.lua Shows the focused window next to the workspace pills in breadbar, via bread.widget + bread.state.watch. none
cpu-temp-widget/ Live CPU temperature readout in breadbar's stats area, via bread.widget + bread.fs.read on a timer. Directory module with a bread.module.toml declaring fs.read + widget — the permission-manifest worked example. edit TEMP_PATH for your hwmon layout
bluetooth-toggle-widget.lua One-click Bluetooth power toggle in breadbar's tray, via bread.widget + a click handler. none
focus-mode-widget.lua Click-to-toggle "Focus" profile that mutes audio; a widget as an action launcher, not just a readout, and stays in sync with profile changes triggered elsewhere. none (needs wpctl)
workflow-status-widget.lua Surfaces bread.workflow.list() in breadbar's tray — shows whichever workflow (e.g. dock-workflow.lua, below) is currently running or failed, hidden otherwise. none
git-branch-widget.lua Shows the repo + branch of whichever git repo the focused kitty tab is sitting in; yellow when dirty. Entirely self-contained in Lua — no adapter behind it. kitty remote control (see the module's header comment)

Each module is the standard skeleton — bread.module{...}, an on_load that registers subscriptions, return M — so they double as references for writing your own. See ../../Documentation.md for the full event list and Lua API.