Skip to content

Menu bar status item for busy AI agents#670

Draft
ivnnv wants to merge 3 commits into
gnachman:masterfrom
ivnnv:ai-menu-bar-status
Draft

Menu bar status item for busy AI agents#670
ivnnv wants to merge 3 commits into
gnachman:masterfrom
ivnnv:ai-menu-bar-status

Conversation

@ivnnv

@ivnnv ivnnv commented May 23, 2026

Copy link
Copy Markdown
Contributor

Opt-in menu bar status item showing how many AI agents are currently working. Off by default, gated on the new ShowMenuBarItem advanced setting. The existing UIElement plus statusBarIcon combination still installs the same item for dock-less mode.

The icon recolors the existing StatusItem template asset orange and replaces the dollar glyph with the count (1 to 9, or + at 10 or more). Idle keeps isTemplate true so light/dark menu bars auto-tint.

Count is the union of two sources, deduped by namespaced id: terminal sessions whose OSC 21337 status text starts with "Working" (case-insensitive — so Working, Working…, Working… 24s all count, but Waiting/Idle/custom statuses don't), and ChatBroker chats whose agent participant is currently typing (the built-in AI chat).

Screenshot 2026-05-23 at 23 59 02 Screenshot 2026-05-23 at 23 58 57 Screenshot 2026-05-23 at 23 58 51 Screenshot 2026-05-23 at 23 58 40

Test plan:

  • Toggle Settings > Advanced > ShowMenuBarItem on; idle dollar icon appears.
  • In any pane, run printf '\e]21337;status=Working;indicator=#ffa500\a' and confirm orange icon with count 1; repeat in more panes to climb, + at 10 or more.
  • Clear with printf '\e]21337;status=;indicator=\a' and confirm idle returns.
  • Set a non-working status with printf '\e]21337;status=Waiting;indicator=#5f87ff\a' and confirm the badge does not tick up. Same with status=Idle.
  • Open the built-in AI chat, send a prompt, confirm the badge ticks up while the agent is typing.

ivnnv added 3 commits May 23, 2026 19:18
A new "Show menu bar item" preference (Settings > Advanced,
ShowMenuBarItem) installs an NSStatusItem independent of the existing
"Exclude from Dock" gating. The icon shows the template StatusItem
image plus an orange badge with the count of currently-working agents
(pulled from TypingStatusModel), and the badge disappears when no
agents are working. Clicking opens the existing status bar menu.

Adds TypingStatusModel.chatIDs(forParticipant:) so the controller can
recompute the busy set after each typingStatus broker update without
extending the Update enum. The legacy inline NSStatusItem creation in
iTermApplication setIsUIElement: is replaced by a refresh call into
the new controller, which still honors the existing UIElement +
statusBarIcon advanced setting combination for backward compatibility.
ChatBroker delivers updates synchronously on the publisher's thread, so
the controller's typing-status handler was mutating state and touching
AppKit off-main. Hop to the main queue before reading busyChatIDs or
updating the status item.

The previous icon implementation drew the template glyph into a bitmap
and assigned the composite with isTemplate=false, which broke automatic
tinting in dark menu bars. Replace it with a layered approach: the
status item button keeps the unmodified template image, and a custom
BadgeView subview draws the orange count badge in the top-right corner
only when busy count > 0.

Promote the menu bar item toggle from a plain iTermPreferences key to
a real DEFINE_BOOL in iTermAdvancedSettingsModel so it appears in the
Settings > Advanced search UI.
Replace the badge-overlay approach with an icon rendered from the original StatusItem.png mask: tint the mask orange and replace the dollar glyph with the busy count (1-9, or + at 10 or more). When idle, the unmodified template image renders as before.

Count is the union of OSC 21337 tab indicators and ChatBroker agent typing chats, deduped by namespaced id so a Claude Code session in a terminal pane and a built-in AI chat both contribute one each.
@gnachman

Copy link
Copy Markdown
Owner

Interesting idea but I think the scope is too narrow. I can see the value of a global status indicator but it needs to be useful more broadly to justify the added complexity. When clicked it should show something useful, like a list of sessions sorted by status, maybe integrate with triggers, which sessions have had bells. I'll keep mulling this over.

@ivnnv

ivnnv commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

sure @gnachman, I wanted to keep this one atomic but yeah this could be expanded on click to show the status of each of the tabs/agents right there and clicking to take you directly to the upfront app, at the given tab/agent you select, I could implement it in this very PR if you want 👍🏽

@ivnnv
ivnnv marked this pull request as draft May 31, 2026 08:36
carvalhoviniciusluiz added a commit to carvalhoviniciusluiz/it2agent that referenced this pull request Jul 22, 2026
Import upstream gnachman#670 ("Menu bar status item for busy
AI agents") behind the new spawnterm.agent_menubar capability flag
(default OFF). When the flag is OFF, behavior is identical to stock
iTerm2: the controller only shows a status item for the legacy
"excluded from Dock + status bar icon" combination and never draws a
busy-count badge. When the flag is ON, the independent menu bar item
(gated additionally by the ShowMenuBarItem Advanced setting) and the
orange busy-agent count badge become available.

The flag is the master switch, wired in the three synced places
(spawnterm-flag, spawnterm_flag.py, iTermSpawnTermCapabilities) plus
the docs, and gated inside AIMenuBarStatusController.refreshOnMain.

Adapted from upstream gnachman#670.

Co-authored-by: carvalhoviniciusluiz <carvalhoviniciusluiz@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
carvalhoviniciusluiz added a commit to carvalhoviniciusluiz/it2agent that referenced this pull request Jul 22, 2026
…an#670/gnachman#673) + 3 new AI flags + agent guide

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants