Agent control overlay

When an agent operates a native macOS window, OpenProgram draws two things above that window: a status pill that says the agent is in control, and an agent pointer at the last action. A webpage the agent operates shows the same pointer. This page defines how both look and move, which colour they use, and the rules that keep them from getting in the user's way.

Preview

The same moment in a chat app: the agent has just clicked the message box. The left panel is the earlier rendering; the right panel is the current one. Use the buttons to play a click, a typing step and the finished state.

Before

After

Accent #5b5bd6, a placeholder (see Accent colour). Everything else is neutral.

Surfaces

TargetWhat is drawnWhere the code is
Native macOS window (computer_use window actions)Status pill and agent pointer, in a borderless, non-activating, click-through NSPanel run by a helper process per controlled window.gui_harness/adapters/mac_indicator.py, started by _WindowControlIndicator in mac_window.py. OpenProgram ships it through program-patches/gui_harness.patch on top of the pinned Harness commit.
Webpage tab in the desktop AppAgent pointer in a transparent, unfocusable, click-through window above the page.apps/desktop/main/action-cues.js places the window; menu-overlay/action-cue renders it.
Chat preview (PiP) and the web buildAgent pointer in a pointer-events: none layer over the preview image.ActionCueTravel in browser-control-bar.tsx.

All three web surfaces draw the same component, AgentCursor. The webpage status (Active, Pausing…, Paused) stays in the page toolbar and the floating control described in GUI Agent. A webpage gets no second status pill.

Status pill

Agent pointer

Accent colour

The product is moving off the earlier orange and terracotta accent toward its own palette around deep indigo, violet and teal, which is being designed separately. The overlay therefore uses a cool indigo-violet, #5b5bd6, as a placeholder. That value lives in exactly two places, which must stay equal:

Only the pointer fill, its ripple, its tag and the live dot use the accent. The pill, its text and the keylines are neutral, so swapping in the final brand accent changes nothing else.

Safety rules

Relation to the GUI Agent design

The GUI Agent design sets the rules this page follows: the indicator is non-activating and ignores the mouse, it follows the window and stays visible under occlusion, clicks show a brief ring, cues belong to the target and never move the user's pointer, and reduced motion uses static marks. The earlier rendering kept those rules but not its look:

AspectEarlier renderingNow
PositionWindow's upper-left corner, over the window's own controls.Top centre of the window, in the title-bar area.
Wording控制中 · WeChat · 34327 (“In control · WeChat · 34327”): Chinese only, with the window id, which reads as a process id.“OpenProgram is using WeChat” in the system language; no ids.
SizeFixed 224 × 28pt badge; long names were truncated.26pt tall, as wide as its text.
ColourSaturated purple fill for the badge and the marker.Dark neutral glass; the accent only on the pointer and the dot.
Pointer42pt purple ring with a white SF Symbol inside, changing per action.Accent arrow with its tip on the point, plus a small action tag.
MotionThe marker jumped between points.Eased glide; parked pointer before the first action.
Click feedbackNone; the ring was permanent.One brief ripple after a press or selection.
StoppingNothing on the overlay.Nothing on the overlay, by design (below).

Where this page departs from the request it answers

Implementation status

Implemented as described for the native helper (through the Harness source patch) and for all three web surfaces. The native panel has been rendered with real AppKit over a desktop window and captured from the screen: the pill, the arrow, the tag and the completed state draw as specified. It has not yet been accepted in the installed App while driving a real app such as WeChat. The ripple and the glide have been checked only through unit tests of the motion rules (tests/test_indicator_presentation.py in the Harness), not by watching them on screen.