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 living in the macOS notch
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 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.1.tar.gz (879.7 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.1-py3-none-any.whl (877.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: dulus_bar-0.3.1.tar.gz
  • Upload date:
  • Size: 879.7 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.1.tar.gz
Algorithm Hash digest
SHA256 16ad83e5334cb04402a2ee45a47aaff509cb5455137c9e6ab11627c7c3578edf
MD5 2dce1c3789674d04ea4dfd18d946d268
BLAKE2b-256 fb13232374c0ecebcd455b1bbce8a93a0690b8d019a80ce996e11bc3c268a85b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dulus_bar-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 877.7 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 04c80179f203f71ded5d7d754a44d5d62979b53aae21cf700dc9a4218c897883
MD5 66c936858af261b7c898a417a00eccb0
BLAKE2b-256 9037a2553f8ec0ef14804baec0a0759af27d8f5f0d32c576f1c9e9a37ed5c6a5

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