Skip to content

Blog

Agent controls should feel like design tools.

Abstract window panels motif in coral on dark steel.

Nobody reads a paragraph to pick the pen tool. In a design tool you read an icon, a state, maybe a hover label, and you act. When agent switching went into memi Studio, that was the bar: a harness control should read like a tool, not like a settings form. This post dissects one control, piece by piece: the icon, the dot, the label, and what happens when you click it while it is broken. Each piece turned out to need real machinery.

Icon first, labels the same day

The run mode rail went icon first during the big hardening day (commit bd06f09, 2026-05-26), and the composer agent controls were tightened to icon-only the next day (f9b2ed7, 2026-05-27). Icon-only survived roughly as long as it took to watch someone hesitate over an unfamiliar glyph.

Hover labels landed that same day (commit 2030ab5, 2026-05-27). Every icon names itself on hover, and keyboard focus reveals the same label, so the compactness costs nothing in clarity and nothing in accessibility. The lesson was not subtle: icon-first is the right call, but it ships with labels in the same commit window or it ships broken. We did not get a grace period between the two.

A status dot is a claim about the world

The ready dot next to each agent looks like decoration. It is the most load-bearing pixel in the strip, because everything else assumes it tells the truth.

A dot that turns green because a binary exists on PATH is a guess. The harness manifest instead carries an authProbe command per harness: claude auth status for Claude Code, codex login status for Codex. The dot reports the probe result. Ready means the probe passed, setup needed means it did not, and offline and blocked are their own states rather than optimistic greens.

The surprise was that honest status is a data problem, not a styling problem. The visual design of the dot took an afternoon. Encoding per-harness probes, install checks, and setup steps into the manifest so the dot has something true to say is where the work went.

Blocked states carry their own fix

The manifest also encodes knownFailurePatterns: regexes over harness output that map a failure to a specific setup step. When a Codex run dies with output matching “not logged in|login|unauthorized”, the failure routes to the codex-sign-in step. The blocked state arrives holding its own next action.

So clicking a blocked agent does not open documentation. It opens the exact step, with a copyable command. The manifest keeps those commands as copy-ready strings: npm install -g @anthropic-ai/claude-code, codex login, hermes model. A blocked dot with no next action is just a small insult delivered in red, and we kept finding that the fix was always knowable in advance if we bothered to encode it.

Setup lives one layer deeper

Early provider settings printed everything inline: install instructions, auth caveats, model notes, all at equal weight next to the controls. It was technically honest and practically unreadable. Provider settings were simplified and the long setup text pushed one layer deeper (commit 3ca8b0f, 2026-05-26).

The rule that survived: state belongs inline, explanation belongs one layer in. Inline means the dot, the selected outline, the run-in-progress state. Tooltips, the inspector, and settings hold the words. The strip stays scannable because nothing on it requires reading a sentence.

The feel is enforced by tests, twice in one day

The part I did not expect: keeping controls feeling like tools required CI. A guard for font token consistency landed twice in one day under the same commit name (commits a27f0e and ed7b0d6, 2026-05-26), alongside a UI typography hygiene guard (3dec7f9). The same gate needing to land twice before sundown tells you exactly how fast type drift creeps back into a moving codebase. One control with slightly off type reads as a bug even when it works perfectly.

The readiness UI itself is e2e-tested too. Since commit 425a62e (2026-05-27), the test suite waits for primary harness readiness before exercising flows, which means a regression where the dot lies does not just mislead a user, it fails the build. The honesty of the status surface is a tested invariant, not a hope.

Three jobs, three surfaces

The operating rule underneath all of this: default UI is for choosing and running. Inspector UI is for understanding. Settings UI is for configuring. Codex and Claude Code hold visible controls because they are the default workbench agents; Ollama, OpenCode, Hermes, and the rest stay contextual until configured or needed, so the strip never becomes a provider catalog.

A designer’s mental model is “ask Codex to patch the component, ask Claude to review the flow, use the local model offline.” The controls speak that language. The receipts for commands, files, and costs are all still there, one layer in, where understanding happens.

The whole pattern compresses to one sentence: icon first, label on hover, status probed, fix on click, setup one layer deeper. Every clause in that sentence has a commit behind it, and two of them have CI gates making sure the sentence stays true.