Skip to content

Concepts

A blip is one live item: a stat, a running agent session, a game score. An extension can emit several blips (each with its own key) from one update() call. Blipbar’s Claude Code extension emits one per agent session.

A layout is the shape of a blip’s data: stat, progress, session, list, score, countdown, or meter (Builders: one per layout). You pick one per blip; the Mac app’s renderer owns every pixel. There’s no view to design: the same blip shows as an ear beside the camera, a row, a tile and an opened item, because it’s data, not a view.

A state is what’s happening right now. Every layout supports every state, and the renderer decides how each looks (color, motion, whether it peeks). You never pick a color: you pick the state that’s actually true, and the look follows from that.

State Means How it shows
idle Nothing happening Calm
running Work in progress Calm, with progress or elapsed time
attention Needs a decision or input from the person Amber. The only state that plays the notch’s attention animation, and it reminds again while it waits
stalled No progress for too long Amber
success Finished well Green, then settles back to calm after a few seconds
failure Finished badly, or something’s wrong Red, then settles back to calm after a few seconds
stale The data is old Dimmed, with when it was last updated
offline No connection Dimmed, with when it was last updated
empty Nothing to show yet Calm

Entering attention, stalled, success or failure can peek the notch open briefly. A state with a color also has a shape (!, ✓, ×), so color is never the only signal.

The host owns the lifecycle. Your extension doesn’t run a server, a cron job, or a setInterval. The app decides when your code runs: on launch, on the manifest’s interval, when a webhook arrives, when a watched file changes, when someone presses an action. The Node runtime that hosts your code checks your declared permissions and validates everything you emit before it reaches the app. This is deliberate, not a limitation: it’s how Blipbar keeps idle CPU near zero, and why your manifest (which Blipbar shows people before they install) can say what your extension does without anyone reading your code.

A tool is the other thing an extension can offer: a small utility the user opens from the notch’s tool tray and runs on demand (look up a package, decode a token). Tools declare their inputs and return typed output; the same kit draws them as Blipbar’s own. See Tools.

Full snapshots, not diffs. ctx.emit() sends everything about a blip every time, not just what changed. The app can join late, drop a message, or reconnect and still render correctly, with no “catch up” logic anywhere. Emit a blip’s complete state, always, even the fields that didn’t change since last time.