Panels
Every panel a person meets in the Robion desktop: what it shows, how it opens (tree, ⌘K, a shortcut, the agent) and what can be done in it. The design panel is only pointed at here — workshop.md has the whole maker flow.
Opening, closing, arranging
- Files open from the tree in the side panel (⌘B Toggle Side Panel), from ⌘K (Commands…; files are searched in the active task from 2 characters) or from the agent (open_file; open_files shows up to 16 files as a grid). They land as tabs in a group beside the side panel.
- Max. open files (⚙): “the next file closes the one open the longest; 0 = no limit; unsaved files are never closed”. Tab right-click: maximize panel, close panel, close all tabs; double-click a tab or ⇧⌘↩ maximizes; ⌘W closes; ⌥⌘L is Reset Layout.
- Window menu (since 0.20.8): the tool panels Activity ⇧⌘A, Statistics ⇧⌘U, Jira ⇧⌘J, MCP Servers ⇧⌘M, Controls ⇧⌘O, Log ⇧⌘L, Browser ⇧⌘B; the screens Overview ⌘0, Board, Inbox ⌘I, Automations; then Waiting Agent ⌘J, Commands… ⌘K, Recent Panels ⌘E, Task 1–9 ⌘1–9. The tree and git are not in it: they sit in the side panel (⌘B). Searching is Edit → Find ▸ Find File… ⌘F, Search in Files… ⇧⌘F, Search Terminals… ⌥⌘F. Help → Keyboard Shortcuts ⌘/ lists them all.
File panel (viewer, editor)
- A text file opens editable at once; autosave fires about 0.8 s after typing stops (⌘S saves now); the header shows the line count and “unsaved…” in amber until saved. A write the server refuses because the agent changed the file meanwhile is shown; autosave then waits until you save or reload. Over 2 MB: read-only; binary: a hex view (up to 16 MB). The scroll position survives a project switch and a relaunch (since 0.20). open in editor (⌥↵) hands the file to the external editor.
- Typing: long lines wrap, brackets pair and lines auto-indent (since 0.20.10); each is a switch in ⚙ → Appearance (Wrap long lines, Brackets, Auto-indent). No completion, no lint — a place to fix a value, not an IDE.
- Wrapping per file (since 0.20.31): wrap in the header (bright while on) or a right-click in the text → wrap long lines switches wrapping for this file only, without touching the setting; the choice sticks with the tab (a relaunch brings it back) and a file without one follows ⚙ → Appearance. Toggling back to the setting’s value forgets the choice. The right-click menu also has find… ⌘F, go to line… ⌘⌥G and open in editor ⌥↵; the markdown panel’s source view has the same button and menu.
- Find in the file (since 0.20.10): ⌘F with the caret in the editor opens a find/replace bar above the text (Find, Replace, next, previous, all, match case, regexp, by word, replace, replace all); ⌘G / ⇧⌘G step through the matches, ⌘⌥G asks for a line number, Esc closes the bar. With the focus outside an editor ⌘F is still Find File….
- Header buttons: 3D on
.scad,.py,.step/.stp,.stl,.3mf,.glb,.kicad_pcb; DRC on.kicad_pcb, ERC on.kicad_sch. - Viewer by type: images (
png jpg gif webp bmp ico avif svg), PDF, DXF, Gerber/Excellon layers (gbr ger gtl gbl gto gbo gts gbs gtp gbp gko gm1 gm2 drl xln) → media panel;.md→ markdown panel;.html/.htm→ HTML panel;.scad .kicad_pcb .stl .3mf .glb .step .stp→ 3D panel; anything else,.pyincluded, → the text editor (3D renders a build123d script on request).
Markdown and HTML panels
- Markdown: preview renders it; source switches the same panel to the editor with autosave (since 0.20). Each view keeps its own scroll position across a project switch, a relaunch and a trip to the other view (the editor since 0.20, the preview since 0.20.4). HTML: the page renders in a sandboxed frame served from the task folder (relative CSS, scripts and images resolve); source, reload and the ⌖ picker (see the web preview) work here too.
Media panel (images, SVG, PDF, DXF, Gerber)
- Images and SVG as they are; DXF converted to SVG inside the app (no external tool); Gerber and drill files rendered to SVG by the server; PDF page by page (fit width, − / +).
- “drag pans · wheel zooms · ⟳ rotates · ☾ darkens white backgrounds”: fit, ⟳ 90°, ☾ dark (remembered). A save reloads the file. Δ original compares with the baseline “before the last agent turn” (the slider swipes, ◐ blend overlays); “the file was not in the baseline (new file) or no baseline captured” when there is nothing to compare with.
Diff panel
- Title “Δ
”. Opens from a file row of the GIT section, a commit’s files, or the agent (open_diff; request_review opens diffs only for up to three files). Scopes: since the last agent turn (baseline snapshot vs. now, see GIT), staged, unstaged, one commit. Over 5000 lines the rest is cut (“open the source instead”). - Review notes: “click a line number to select the line, shift+click extends the selection”, write in NOTE TO AGENT (“what the agent should do with the selected lines — ⌘⏎ sends”); send to agent delivers “the next prompt: file, line range, the lines themselves and your note”. Refused when the diff belongs to no task or the agent is waiting for a permission or a choice (“send the note afterwards”).
GIT section of the side panel
- Under the tree in the side panel (⌘B); ⇧⌘G shows it; the caption folds it. It follows the active task and its checkout (the caption switches checkouts, 0.20), refreshes on any file change and says “not a git repository” outside git. Header: the branch, ↑n unpushed commits in amber (they want an action), ↓n behind, dim.
- Review: a baseline snapshot of the working tree is taken on every agent turn (or by capture baseline; before that “no baseline captured yet — one is taken on every agent turn (M3), or manually”). Files differing from it list under since the last agent turn (the ✓ reviewed button and the “awaiting review” header are gone since 0.20.16 — the list is the review). The agent’s request_review puts its note on the task timeline and opens the side panel with the GIT section lit for a moment (0.18).
- uncommitted changes: a checkbox per file (stage / unstage), a click opens the diff. earlier on this branch = commits above the default branch (on it: recent commits); a commit row expands to its files. worktrees lists the checkouts.
- Commit (0.20.15): under the uncommitted list a commit message… field and a commit
button commit exactly what the checkboxes staged, in the task’s checkout (its worktree, or
the project root). The button is disabled with the reason as its tooltip: “nothing staged —
tick the files to commit first”, “write a commit message first”; the server refuses the
same rather than committing nothing. No amend, no automatic add of unstaged files. Hooks run
as in a terminal; “committed
” or what git/the hook printed appears under the field. - Push (0.20.15): its own push section, apart from the commit field, shows
branch → upstreamand n unpushed commits (amber), nothing to push, or no upstream yet (the would-beorigin/<branch>in italics). push… does not push yet: it opens a question naming the destination — “push→ origin/ ?”, or for a branch without an upstream ” has no upstream yet — push —set-upstream origin ?” (shown in italics as the would-be destination) — with push now and cancel. Never force. Git’s answer stays below as text: “pushed to origin/ ” with the remote’s messages, or the rejection (”! [rejected] … fetch first”), an authentication failure (no password prompt: the push fails instead of hanging), “detached HEAD — there is no branch to push”. Both actions refresh the section.
Web preview panel
- Opens from the preview :port button in the top bar when the task has a port (⚙ → project → Port range: “each task gets two ports (PORT, ROBION_PORTS)”), from Window → Browser (⇧⌘B), ⌘K open web preview, a link control, or the agent (open_url).
- Loopback only: “only local previews (localhost) render in the app — use ↗ to open it in the browser”. Until the server answers: “nothing is listening on port N yet … retrying every 2 s — start the dev server in the task terminal (PORT is set)”. Remote server: “port N is listening on the remote machine — tunnel it to preview here” → open a tunnel and preview here.
- ⌖ select element: click an element, choose change or question, write “what should the agent do with this element — ⌘⏎ sends”, optionally attach screenshot; it goes out “as the next prompt: page, selector, element text and your note”. When the agent asks for a pick (request_element_pick) the preview opens with its note as a chip. Refusals: “this preview belongs to no agent task”, “the page is not ready for picking yet”. The agent’s own screenshots (preview_screenshot) capture this panel as you see it and go to the agent only.
3D panel (model viewport)
- Formats: OpenSCAD
.scad, build123d.py(via 3D), STEP, STL, 3MF, GLB, KiCad.kicad_pcb. Rendering runs on the server with OpenSCAD, Python with build123d and kicad-cli, found automatically or set in ⚙ → Tools (Detected tools shows version and path or “not found”). A missing tool shows ”not found. Install it or set … in config.json” in the panel; 3D render timeout kills a render after the set time. - Header: model / source (the code, read-only here), refresh, fit, the readout “N △ · x × y × z mm · volume · took s”, output (the tool’s log), Δ original (“show the baseline version (before the last agent turn) as a translucent ghost”), ⌸ bed (draws the Print bed from ⚙ → Tools and says “the model fits” / “the model does not fit”), SpaceMouse (3Dconnexion over WebHID), DRC on boards.
- “drag rotates · wheel zooms · right button pans · double-click fits”; the panel re-renders
when the file changes on disk. “WebGL context was lost — close the panel and open it again”.
Live customizer: a controls panel whose viewport is the model re-renders on every slider
change (OpenSCAD gets
-D key=value, a Python model readsROBION_PARAMS) — workshop.md.
CHECKS panel (KiCad DRC / ERC)
- The DRC / ERC button of a
.kicad_pcb/.kicad_schfile panel or of the 3D panel; the tab reads “DRC”. kicad-cli runs on the server; the header says “N errors · N warnings · took s” or “no findings”. Filters all / errors / warnings, incl. excluded, run again, output (the raw log).
LOG panel
- Window → Log (⇧⌘L); one per project; it also opens by itself when an agent defines sources. Only the agent defines them (“no log sources defined — an agent adds them with set_log_sources”) — ask it to watch a file or a streaming command.
- Command sources need approval: “Command log sources run shell commands in this project and
need your approval.” → Allow commands → “Run the command log sources of “
”? They execute shell commands on this machine and restart until removed.” - “no log lines yet — sources stream only while this panel is open”: nothing is collected while the panel is closed. Filters: source chips (click toggles one), all levels or ”≥ level”, text “filter (or /regex/)”; follow the tail vs “paused (scroll to the bottom to follow again)”; clear the view. Times are local HH:MM:SS.mmm; errors red, warnings amber. Right-click a line → send this line to the agent (source, level, time and the line arrive as the next prompt; the agent pulls the surrounding lines with query_logs).
- Robion’s own logs, worth adding as file sources:
~/Library/Application Support/Robion/logs/holdsserver.log,desktop.log(renderer errors, crash screens),events.jsonl(hook payloads when Log hook events is on),setup-<branch>.log,teardown-<task>.log.
CONTROLS panel
- Window → Controls (⇧⌘O) or ⌘K open controls: the CONTROLS overview with a project section (the persistent launcher) and a task section (knobs of the open task, gone when it closes). A panel an agent defines opens (or focuses) as a tab of its own named after its label (open as a tab from the overview); up to 12 named panels per scope, each with its own values, groups (collapse/expand), pages (general is the default) and viewport.
- Empty: “No controls yet. Ask the agent in a task — “make me buttons for the dev server on
port 7700, tests and lint” — and it defines them here through the Robion MCP (set_controls).”
/robion:cockpitbuilds a panel from what the project has (package.json scripts, Makefile…). - Kinds you can meet: buttons (a confirm dialog before running; hotkeys 1–9 — “press N while the panel has focus”, also on the stream deck), toggles (on/off), numbers and sliders, selects (dropdown or segments), text, checklists, status badges (static, a live probe, or a run button’s state “not run yet” / “running…” / “stopped”), progress bars, steps pipelines, links (loopback URL → web panel, else the browser), image tiles (refresh when the file changes; a click opens it), choices cards (image, description, fact chips; single or multi), galleries, tables. Tooltips say what a button does: “runs: …”, “types into the agent: …”, “opens: …”, “sets: …”, “stops what “…” started”, “starts an agent task: …”.
- A run button starts a shell task; its output viewport shows “running…”, “finished (exit 0)” or “failed (exit N)” with stop, to a tab, hide; a silent button pulses and only a failure shows a terminal; a failed run offers send the failure to the agent. Send buttons type into the agent’s pane (task scope: that task; project scope: your active task — “needs an active Claude Code task in this project”). Task buttons start a new agent task. The agent reads values when it asks (get_controls); changes also reach it with your next prompt.
- Probes: port, file and http probes sample by themselves while the panel is open; a command
probe stays paused until allow (“Allow the agent-defined command probes to run
automatically in “
”?”); revoke under ⚙ → project → command probes. - edit opens ⚙ → project → panels (JSON): “an array of panels, each with name/label/icon, controls, values, groups and viewport. Edit the JSON to rename, reorder or delete; a button’s ${key} must name a toggle/number/select/text/checklist of the same panel.” A popped-out tab of a removed panel says “This controls panel no longer exists (the agent removed it).” The phone renders the same cockpit.
Activity panel (task timeline)
- Window → Activity (⇧⌘A), ⌘K open activity, or a task tab’s right-click activity…: “task timeline: prompts, waits, decisions, results, restores” (rows typed task, prompt, permission, question, decision, message, done, idle, error, ended, note; source desktop, phone or agent). The header sums “new tokens (in + out + cache write) · out tokens · turns / prompts / tools · running · waiting for you”. request_review notes land here.
STATISTICS panel
- ⇧⌘U, the rail’s USAGE widget or ⌘K open statistics; it reads Claude Code transcripts (the Usage statistics switch in ⚙). Ranges today / 7 d / 30 d / 90 d / all, all projects / this project only; KPIs (sessions, prompts, turns, tool calls, output tokens, agents ran, waited for you, median wait, interrupts, failures), charts (tokens, agent time, activity, “when you prompt”), tables (projects — a click selects the project — models, tools, MCP, skills). The rail shows the 5h session and week limits when Track subscription limits is on (“limits: sign in in Claude Code (/login)” otherwise).
JIRA panel
- Window → Jira (⇧⌘J). “Jira is not connected — connect it in ⚙ → automations (issue trackers)”; the token comes from id.atlassian.com → Security → API tokens and lives in the keychain. Read-only: Robion never writes to a tracker.
- Search “ticket key, text, or jql: …”, scopes mine / active sprint / epics /
recent, load more. An issue shows description, fields, sub-tasks, in epic, links,
attachments, comments; open in Jira, copy key, create task (“new task named after
the ticket key; the agent gets the description as its prompt; with a worktree per project
settings (branch rb/
-…)”). Offline: “Jira unreachable — showing the last known version”.
MCP panel
- Window → MCP Servers (⇧⌘M): the MCP servers Claude Code knows, this project only or all projects; columns server, where (user = ~/.claude.json, folder, .mcp.json, plugin), state (unchecked, “running · N ms”, sign-in, error, “disabled in N folders”, rejected, awaiting approval, plugin disabled), tools, ~tokens (what the tool definitions cost in every context), calls. check / check all starts each server and lists its tools. “read-only — servers are added and removed in Claude Code (claude mcp add / remove, /mcp)”.
Design panel
- DESIGN: the design record of a Maker Pack task. The anchor tab of a workshop project; in
a development project the DESIGN button in the top bar opens it for a task with a record,
and it opens by itself when the agent writes
design.json. All details: workshop.md.
Recent panels (⌘E)
- Window → Recent Panels: the open panels, most recently used first. The top row is the panel active before the current one, so ⌘E + ↩ bounces between the last two; ⌘E again or ↓ walks down. Agent terminals lead with their state dot, files with an icon and their folder.
When a panel breaks
- One panel: “panel crashed — The rest of the app keeps running. Close the tab, or reopen it after the bug is fixed.” A viewer that cannot read a file says “file cannot be displayed”.
- The workspace: “the workspace crashed — Other projects, the Inbox and settings keep running.”
Buttons try again, start from the default layout (“the saved layout is the usual
culprit”), copy the error; the error is in
logs/desktop.log(since 0.19). - The app: “Robion crashed — Something broke outside the workspace.” reload the window “almost always helps; the server and the agents keep running.”