Dulus Bar — a cross-platform Dynamic Island for your AI agents (Windows / macOS / Linux)
Project description
Dulus Bar 🦅
A cross-platform Dynamic Island for your AI agents.
Free. Native. MIT. Works with any agent — no account, no cloud, no lock-in.
pip install dulus-bar
Dulus Bar hugging the macOS notch — hover to expand, agents report in live.
Dulus Bar puts a floating status island at the top of your screen that shows every AI coding agent you're running — Claude Code, Codex, Gemini, Cursor, Dulus, and any other CLI — and lets you Allow / Deny their permission prompts without diving back into a terminal.
It's the idea itself, shipped for everyone. Not tied to Dulus — wrap any agent and it shows up. We built the island we wanted; here it is for the whole world. 🌎
- All platforms — Windows, macOS, and Linux.
- macOS notch-native — on MacBooks with a camera notch the island hugs the notch and stays visible across every Space and full-screen app.
- Reveal on hover — everywhere else it rests as a slim tab at the top edge and slides open when your mouse approaches, or when an agent needs you.
- Any agent — anything with a CLI works through a thin wrapper; well-known agents get their own icon and accent color.
- 100% local — no cloud, no account, no telemetry. One WebSocket on
127.0.0.1:17372.
Install
Requires Python 3.10+.
pip install dulus-bar
dulusbar
That's it — the island appears at the top of your screen. Move your mouse to the top-center to reveal it; right-click the tray icon for the menu.
From source (for the wired-agent extras)
git clone https://github.com/Dulus-Ai/Dulus-bar.git
cd Dulus-bar
# macOS / Linux
./setup.sh
# Windows
.\setup.ps1
Linux tip: for click-to-focus of a terminal on X11, install
wmctrlorxdotool.macOS:
setup.shalso builds the native SwiftUI/AppKit notch surface using the Swift toolchain in Xcode Command Line Tools. The Python process stays the local WebSocket hub; Windows and Linux use the PyQt overlay.
Wire up any AI agent — zero monopoly
Dulus Bar is agent-agnostic. Wrap any CLI and it reports to the island:
python wrappers/agent_wrapper.py "Codex" codex fix auth bug
python wrappers/agent_wrapper.py "Gemini" gemini
python wrappers/claude_wrapper.py # Claude Code helper
agent_wrapper.py "Display Name" <command> [args...] reports that agent to the
bar. Known names (Claude, Codex, Gemini, Cursor, Copilot, Kimi, DeepSeek, Grok,
Qwen, Mistral, Windsurf, Zed, Aider, Ollama, …) get a curated icon + color;
anything else gets a stable auto-assigned color.
Or right-click the island → Open agent… and pick any executable from a file dialog — Dulus Bar launches it in its own terminal, already wired.
Works beautifully with Dulus (optional)
If you run Dulus, the island also shows the active model
and live context usage — e.g. kimi/kimi-k2.5 · ctx 38%. But you never need
Dulus to use Dulus Bar. The bar is the gift; Dulus is just one of many agents it
speaks to.
What it does
- Floating island, top-center (or notch-anchored on macOS).
- Lists active agents with a live status dot (running / waiting / done / error).
- When an agent asks for permission, shows Allow / Deny right on the island and forwards your choice back to the agent over stdin.
- Reveals on hover, pops open on agent activity, and stays open on a permission request until you answer.
- Click an agent to jump to its terminal / editor window.
How it works
Agents connect to a tiny local WebSocket hub and send status; the island renders it and relays your Allow/Deny back.
Agent → bar:
{ "agent": "Claude", "type": "tool_request", "session_id": "abc123",
"payload": { "tool": "Bash", "args": "rm -rf build/" } }
Event types: session_started, message, tool_request, tool_approved,
tool_denied, completed, error. (model / ctx payload fields are optional.)
Bar → agent (Allow/Deny):
{ "type": "decision", "session_id": "abc123", "payload": { "approved": true } }
dulus_bar/
overlay.py Floating island UI (PyQt6), notch-aware + reveal-on-hover
server.py WebSocket hub (ws://127.0.0.1:17372)
agents.py Per-agent icon + accent color registry
native/ win32 / pyobjc / wmctrl window focus per platform
wrappers/
base_wrapper.py Shared: pipe stdio, detect prompts, inject Allow/Deny
agent_wrapper.py Generic wrapper for any CLI agent
macos/ Native SwiftUI/AppKit notch surface
Build a standalone binary (optional)
pip install pyinstaller
pyinstaller --noconfirm DulusBar.spec
Output lands in dist/ — DulusBar.exe on Windows, DulusBar.app on macOS
(bundled as an LSUIElement, so no Dock icon).
Platform notes
- Windows — fully tested.
pywin32for window focus; PyQt overlay with reveal-on-hover. - macOS — notch hugging + always-visible via
pyobjc. Without it, still runs as a plain top-most island. - Linux — X11 window focus via
wmctrl/xdotool; on Wayland the island shows and stays on top, jump-to-terminal is best-effort.
Contributing
PRs welcome — new agent icons/colors, platform fixes, packaging. Open an issue, fork it, ship it.
License
MIT. Use it, fork it, ship it. We shipped the idea on purpose — no monopoly.
Built by one builder in the Dominican Republic 🇩🇴 — for everyone. 🦅
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dulus_bar-0.3.2.tar.gz.
File metadata
- Download URL: dulus_bar-0.3.2.tar.gz
- Upload date:
- Size: 880.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
120af27876b04a7e9123b890f4272df30c8a4da1a9413d98f6642ba5e10fa6e3
|
|
| MD5 |
d5bde5e0415066da4bcaeb6671784132
|
|
| BLAKE2b-256 |
eaeeed7915d024a4afdd806f39c5ed5d1c9edea581fd7f33390a13d97e6c028b
|
File details
Details for the file dulus_bar-0.3.2-py3-none-any.whl.
File metadata
- Download URL: dulus_bar-0.3.2-py3-none-any.whl
- Upload date:
- Size: 878.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6afdbc2a625d85503f1baeb4be851bf73591cf699210d5fd193a6d52756416cd
|
|
| MD5 |
4bee0b9c91480deb5745165327c275d6
|
|
| BLAKE2b-256 |
f965e6bf50f6a8771dbe76781cb9e272a23e59f2f4e6308982406af7980edbc5
|