Skip to main content

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

MIT Python Platforms


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 wmctrl or xdotool.

macOS: setup.sh also 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. pywin32 for 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dulus_bar-0.3.0.tar.gz (879.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dulus_bar-0.3.0-py3-none-any.whl (877.6 kB view details)

Uploaded Python 3

File details

Details for the file dulus_bar-0.3.0.tar.gz.

File metadata

  • Download URL: dulus_bar-0.3.0.tar.gz
  • Upload date:
  • Size: 879.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for dulus_bar-0.3.0.tar.gz
Algorithm Hash digest
SHA256 cf04be369bb625f667242c9e9c43001aa54d4e2e88f28574ce8bbbec0d1081d6
MD5 9ef93d6c80836c7207329f15857a899a
BLAKE2b-256 c4376935ef38c2fc1f7db52e0916332ac97c47225f55d6379a1e3145e7e8d4d5

See more details on using hashes here.

File details

Details for the file dulus_bar-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: dulus_bar-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 877.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for dulus_bar-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7cb6e83c5454b75656ddab436594fb1a80bc1bf9a9198d9d17cc854aef3558f5
MD5 4f7470124726998604a8ec056b1593a2
BLAKE2b-256 ed54341d3a05b840a86e4ece61374cdc8408e03e15f53bba064b12e5728b62b3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page