kittymux

Notifications and inbox

What reaches you and when: one desktop notification per event, a bell that never moves your focus, an inbox for everything, and switches to quiet it.

kittymux tells you about an agent only when you are not looking at it. Focusing the agent clears the cue.

Cues when you are elsewhere

CueWhenTurn it off
Tab glyph and a stripe on the railAny tab and any pane of it. A question in a split you are not in still lights the tab.Not switchable.
Header badges ! 2 ✓ 1Agents that need you or finished unseen, across every tab of the window.Not switchable.
Desktop notification: needs you or limitAn agent starts waiting or hits its limit. It shows the question.kittymux notify off, or KITTYMUX_NOTIFY=0.
Desktop notification: finishedA run of 15 seconds or more ends unseen. Quick replies stay quiet.kittymux notify done off, or KITTYMUX_NOTIFY_DONE=0.
Window manager urgencyAn agent starts waiting or hits its limit. This is kitty's own bell path.touch ~/.local/state/kittymux/bell-off, or KITTYMUX_BELL=0.
ctrl+alt+yJumps to the next agent that needs you, longest-waiting first.Not switchable.

A window seen for the first time never notifies, so restarting kittymux does not replay old completions.

Who sends what

SourceShown by kittymux?
kittymux: needs you, hit a limit, finishedYes. This is the one notification per event.
The agent itself, through an OSC 9, 99 or 777 escapeDropped from the desktop by a filter_notification rule in kittymux.conf, but recorded in the inbox.
kitty's own, such as command finished or config reloadUntouched.
Any other program in a terminalUntouched, unless its title starts with an agent name.

Before kittymux filtered anything, an event could notify twice: once from the agent through kitty and once from kittymux. Now each event notifies once. Delete the filter_notification line in kittymux.conf to let the agents' own notifications through again, and expect doubles.

Every notification wears its agent's own mark, with the kitty icon as the fallback. Notifications are rate limited: one per window every 10 seconds and five in total every 10 seconds. The sixth inside 10 seconds is not shown, though the bar still shows the state.

Jump to it

Notifications carry a Jump to it action. It focuses that window through kitty's remote control, then hyprctl on Hyprland, and lands on the pane that is asking. With dunst, use middle-click or dunstctl action. With mako or swaync, click. A daemon without actions still shows the text.

A notification never takes your focus

A bell in an unfocused window makes kitty ask the window manager for attention. Some compositors answer by focusing that window and switching workspace, for example Hyprland with misc:focus_on_activate on. Then every bell becomes a forced focus change.

kittymux reads that option when kitty loads its configuration. When the compositor would do this, it turns the bell request off and does not ring its own bell. kittymux doctor says so, and kittymux explain records each skipped bell. The only things that move focus are things you do: a click, kittymux inbox jump, ctrl+alt+y or a notification's Jump to it action.

To keep attention requests on anyway, touch ~/.local/state/kittymux/attention-on. Other compositors are not inspected. If a bell steals focus on sway, KDE or GNOME, set window_alert_on_bell no in your kitty.conf.

When a plain terminal is waiting for you

Agents are not the only thing that stops and waits. sudo pacman -Syu sits at a password prompt, ssh asks for a passphrase, paru asks Proceed with installation? [Y/n]. If you are in another tab, nothing says so. kittymux treats these like an agent that needs you: one notification with Jump to it, and one event in the inbox.

It needs two kinds of evidence. The prompt must be the last line on the screen, where a prompt waits. And it must be either wording only that tool prints, such as [sudo] password for you:, or printed while that tool leads the terminal, such as pacman or ssh. The same words in scrollback, in a file you are reading or in an agent's reply are not a prompt.

SwitchCovers
sudosudo, doas, su, pkexec waiting for your password
loginpromptssh and git asking for a passphrase, a password or to trust a host
pkgpromptpacman, paru, yay, apt, dnf and similar waiting for a yes or a no

All three are on by default. kittymux features off sudo turns one off.

  • It waits one second before announcing, so a password you type at once is not news. It stays quiet for the pane you are looking at.
  • The text is fixed: "sudo is asking for your password". The line on the screen holds your user name or a host, and it is never stored or logged. Nothing you type is read.
  • When the prompt goes away, the event is marked read. A wrong password that asks again is a new event.
  • It does not change the tab's state mark. The notification and the inbox carry it.

Quiet things down

Muting quiets the interruption, never the news. Every event still goes to the inbox, the bar and kittymux pick.

kittymux notify mute 1h        # no popups and no bells for an hour (up to 30 days)
kittymux notify status         # on, muted for another 42m, or off; bells; unread in the inbox
kittymux notify unmute
kittymux notify off            # everything off; "on" turns it back on
kittymux notify done off       # only the finished popups; "done on" restores them
kittymux snooze 2h             # this agent window only; --window ID, or --clear to end it

A snooze is stored in a private file, not in a window variable. Any program in a window can set its own window variables with an escape sequence, so an agent could otherwise silence the very popup that says it wants something. Snoozes and mutes are capped at 30 days, and a corrupt value never silences anything for good.

Private mode

A notification shows a line of your screen, such as "Approve: rm -rf x?". Some daemons keep a history or show notifications on the lock screen. To reduce every notification to "agent needs you", run touch ~/.local/state/kittymux/notify-private or set KITTYMUX_NOTIFY_PRIVATE=1. In private mode the inbox keeps no message body either.

The inbox

Everything that wants your attention is a typed event in one private store, from the most authoritative source available, and de-duplicated: the same occurrence reported by several sources inside 45 seconds is one event and one popup.

SourceWhat it isConfidence
agentWhat the agent announced itself: its own notification, captured natively from kitty, or its hook.High
hookThe agent's hooks through mux-status.High
screenPositive evidence on the pane's screen: a permission prompt, usage-limit text, or a busy marker that went quiet.Low for a completion, high otherwise
KindMeaningPops up?
permissionAn approval prompt.Yes.
questionThe agent asks you something.Yes.
limitA usage or rate limit. The reset time is parsed when it is shown.Yes, once per agent per reset.
doneA run finished.Only if the agent said so itself after 15 seconds of work, or if inferred from a quiet screen after 60 seconds.
errorThe agent reported a failure.Inbox only.
infoAnything else the agent said.Inbox only.

Text from an agent is classified conservatively. What is not recognised is info, never guessed into a completion. "Waiting for your input" is an idle notice, not a new completion.

kittymux inbox                  # unread, newest first. --all shows read ones too; --json prints the snapshot
kittymux inbox ack ID           # mark read. "ack --all" marks everything
kittymux inbox clear            # dismiss unread; "clear --all" dismisses everything
kittymux inbox jump             # focus the one that needs you most; marks it read
kittymux inbox watch            # one JSON line per new event, for scripts
kittymux inbox ledger           # how long agents waited on you; --json prints the numbers

Focusing a window acknowledges everything it reported.

How long agents wait for you

An agent that asks for you, with a permission prompt or a question, is waiting from the moment its event first appeared until you first looked at it: you focused its window, marked it read or dismissed it. While it is unread it is waiting now. The Inbox view of the panel shows this as a card under the events: how long agents waited on you today, the median, a week of bars, and how many are waiting right now. kittymux inbox ledger prints the same as a sentence.

It measures how fast you got to each agent, not how long an answer took. One wait counts for at most an hour toward a total, so a night away does not swamp a day, and the longest wait is shown as it was. It is only as complete as the inbox, which keeps its newest 200 events, and it is a number for you: nothing is sent anywhere.

For widgets

~/.local/state/kittymux/inbox-snapshot.json is the stable file a shell panel watches. It is rewritten atomically after every change.

{"version": 1, "updated": 1790000000.0, "unread": 2, "needs_you": 1,
 "events": [ {"id": "18f3a-4321-7", "t": 1790000000.0, "pid": 4321, "w": "77", "kind": "permission", "severity": "needs-you",
              "agent": "claude", "tab": "api", "title": "claude needs permission", "body": "Claude needs your permission to use Bash",
              "sources": ["agent", "screen"], "confidence": "high", "status": "unread", "count": 2} ] }

events is newest first, at most 60. pid and w identify the kitty process and the window. New fields may be added, so consumers must ignore fields they do not know. The version changes only for breaking changes.

A panel needs only to watch that file, render events, and run kittymux inbox jump ID or ack ID on click. For a status bar, kittymux inbox --waybar prints a ready module:

// ~/.config/waybar/config.jsonc
"custom/kittymux": { "exec": "kittymux inbox --waybar", "return-type": "json", "interval": 5, "on-click": "kittymux pick --menu rofi", "hide-empty-text": true }

It is empty when nothing is unread, shows ◆ N when N agents need you and ✓ N for finished-unseen. A Quickshell starting point lives in addons/quickshell. It follows this contract and is untested, because Quickshell is not installed on the author's machine.

Known limits

  • The filter works on titles. kitty's filter_notification cannot see which window sent a notification, so a program that titles its own notification "Claude" or "Codex" is dropped too.
  • Events the screen scanner cannot see are lost. If an agent notifies about something kittymux cannot detect, nobody shows it. Remove the filter_notification line to get the agents' own notifications back.
  • Notification text is screen text. Private mode is opt-in.
  • Daemons differ. Tested with dunst on Hyprland. Mako, swaync, KDE and GNOME are untested.
  • The jump action uses kitty's socket. If it lives in world-writable /tmp, other local users could squat the name. kittymux doctor warns about this.

On this page