Bundled Widgets¶
The repository's widgets/ directory contains examples ranging from minimal API demonstrations to complete integrations. Copy only the widgets you want into your configured widgets_dir, together with the lib/ directory when the widget imports shared modules.
Catalog¶
| Widget | Purpose | Requirements | Inbox publisher |
|---|---|---|---|
simple.lua |
Minimal stateful toggle | None | No |
group_demo.lua |
Groups, shared styling, and popups | None | No |
context-menu.lua |
Native right-click menu API | gh for its example action |
No |
popup-context-menu.lua |
Popup and context menu on one item | None | No |
inbox-demo.lua |
Representative inbox test messages | Native inbox enabled | Yes |
brew.lua |
Homebrew updates in its own popup | brew in [app.env].PATH |
No |
brew-inbox.lua |
Homebrew updates and actions | brew in [app.env].PATH |
Yes |
github.lua |
GitHub notifications popup | Authenticated gh; bundled GitHub SVG asset |
No |
github-inbox.lua |
GitHub notifications | Authenticated gh |
Yes |
gitlab.lua |
Assigned GitLab work items | Authenticated glab; optional GITLAB_HOST |
No |
gitlab-inbox.lua |
Assigned GitLab work items | Authenticated glab; optional GITLAB_HOST |
Yes |
network.lua |
Native network snapshot | Network agent | No |
wifi+vpn.lua |
Read-only tunnel indicator | Network agent | No |
tailscale.lua |
Tailscale state and controls | tailscale; optional TAILSCALE command setting |
No |
wireguard.lua |
Network Extension VPN control | Service name in lib/secrets.lua |
No |
Choose one presentation¶
Do not load both presentation variants for the same service:
- choose
brew.luaorbrew-inbox.lua - choose
github.luaorgithub-inbox.lua - choose
gitlab.luaorgitlab-inbox.lua
The regular variants own a bar icon and popup. The inbox variants publish snapshots into the shared native inbox and register their operations as source actions.
The Tailscale widget uses left click to bring Tailscale up or down. Its right-click menu lists the
currently advertised exit nodes and a Disabled option. Selecting one changes Tailscale's own
persistent state; EasyBar does not duplicate the selected node in config.toml.
GitHub and GitLab inbox items expose a dedicated Mark as read action. GitHub also acknowledges the notification through the GitHub API. GitLab publishes assigned work items rather than notification records, so its action updates EasyBar's persistent local read state.
GUI environment¶
Apps opened from Finder or Spotlight do not inherit .zshrc. Make required CLIs and instance settings explicit:
[app.env]
PATH = "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
GITLAB_HOST = "https://gitlab.example.com"
TAILSCALE = "/opt/homebrew/bin/tailscale"
Authenticate tools in a terminal before starting the corresponding widget:
gh auth login
glab auth login --hostname gitlab.example.com
See Environment for precedence and GUI-launch behavior.
Shared modules and assets¶
Several examples import retry, shell, text, or secrets from widgets/lib. Preserve that directory structure when copying them. File-backed assets are resolved relative to the widget with easybar.asset(...); copy those assets as well.
Keep the secrets helper at widgets/lib/secrets.lua. Do not place a copy at the top level: EasyBar executes every top-level *.lua file as a widget entrypoint, while files below lib/ are loaded only through require(...). Edit the module before copying wireguard.lua, then copy lib/secrets.lua with the widget.
The GitHub, GitLab, and Homebrew inbox examples keep system_woke immediate for the rest of EasyBar, then schedule their own three-second network settling delay with easybar.after(...). Their read-only refresh checks use the shared pure-Lua retry helper with two- and five-second backoff. Authentication failures and Homebrew/GitHub mutations remain one-shot. Ordinary CLI invocations use easybar.spawn_async(...); shell execution is reserved for examples that genuinely need shell syntax.
Diagnostics¶
The GitHub, GitLab, and Homebrew inbox widgets emit semantic operation logs:
debugfor refresh reasons, action routing, and published item countstracefor command attempts, retry scheduling, and wake-delay handlinginfofor user-triggered mutations and cancellationwarnorerrorfor invalid responses, exhausted retries, and failed mutations
The widget file name is attached automatically as a structured widget field. Transport byte counts
remain trace-only and are emitted once per direction, so normal debug logs focus on what the widget
was doing rather than every internal socket boundary.
Lua loader and command failures also appear in EasyBar's logs. The Homebrew examples maintain a
bounded brew-widget.log in the configured logging directory. Use Lua Logging,
Commands, and Troubleshooting when an example does
not update.