Settings
Every surface of the SETTINGS dialog in the order it shows them, plus what sits around it: hooks, the Linux server, updates and where Robion keeps its data on disk.
The dialog
- ⚙ in the rail or Settings… in the app menu (⌘,). Sections in the left column:
Project, Application, Appearance, Agents, Remote access, Servers,
Notifications, Tools, Privacy, Controls, Automations. ⌘F opens “search
settings…” over every section. Most rows need save (“unsaved changes” → “all saved”);
Appearance applies immediately. Tokens go to the keychain, never into
config.json.
Project (per project)
- Project type: development (terminals, tree and git) or workshop (the design panel is the anchor, the agent runs without a terminal tab). Steward → let the Steward ignore this project (since 0.18): out of the briefing, never proposed for.
- Tags (comma-separated, filter the rail). Colour (12 colours: tints the icon or the rail dot, the stripe on tabs, the frame of the selected project). Icon: a grid of 72 monochrome icons shown before the name in the rail, ⌘K and on the phone; × = none; an emoji set earlier stays as text until you pick one. Both also in the rail’s right-click menu.
- Related projects: the agent can get them as
--add-dir(New task defaults below). - New task by hand: own worktree / Tasks of the Steward and automations: own worktree
(since 0.20; “own branch” until 0.20.8): whether a task starts in its own worktree (
claude --worktree); the segment next to new task switches it any time; unattended work defaults to an own worktree. Base of a new worktree: local HEAD (unpushed commits included) or origin default branch. Worktrees directory: empty =<root>/.claude/worktrees, the only place Claude Code enforces isolation in; a custom directory gives a plain worktree without it. - New task defaults pre-fill the ⋯ popover next to new task (sandbox, related projects); each task can override them.
- Worktree setup script: runs in the new worktree before the agent starts (
.env,pnpm install);ROBION_PROJECT_ROOT,ROBION_WORKTREE,ROBION_WORKTREE_SLUG,PORTare set; without one, files matched by.worktreeincludeare copied. Task teardown script: runs in the task folder when it is closed (PORT,ROBION_TASK). Output inlogs/setup-<branch>.logandlogs/teardown-<task>.log. - Port range: each task gets two ports (
PORT,ROBION_PORTS); empty = no allocation. - Notes for the agent → open CLAUDE.md (starter template when missing; needs a running task). Remove project → remove from Robion: gone from the rail, files kept. Delete project → delete with files (since 0.20.4): the same, and the project folder with everything in it moves to the Trash, where the Finder can put it back; the confirm names the folder. While the project has an open task both buttons are greyed out and the hint says “close the project’s open tasks first (N open)” — end the tasks in TASKS or the tab, then come back; a refusal the server still makes (“Project has N open task(s); close them first”) shows in red at the bottom of the dialog, which stays open. Both drop the worktrees Robion made whose work is merged or clean (one with unmerged work outside the folder stays on disk). Delete is offered for projects of the local server only: a remote (headless) server has no trash to restore from, so there the button is greyed out — remove the project and delete the folder on the server.
Application
- Shared by all projects on this Mac. Max. open files (the next file closes the one open
the longest; 0 = no limit).
config.jsononly:agentTaskLimit(open tasks one agent may have started, default 3; 0 = agents start no tasks — tasks.md). - “Open in editor” command (
{file},{line}; empty =code -g, otherwiseopen). - Side question from a selection (since 0.20.36): the question the Explain this chip
under a selected terminal text asks (tasks.md → Side questions);
{text}stands for the selection, a template without it gets the selection appended; empty = “Explain this: “…”” in the app’s language. Set it to ask, and so be answered, in another language than the UI. Folder for new projects: new project (⊕ in the rail, File → New Project…, the phone) creates its folder withgit inithere; empty = off. Choose… picks it. - Inactive projects (days, since 0.20.27): the rail folds a project nobody touched for this many days — no prompt, no new task started by hand, no agent at work, waiting or with an unread result — into the INACTIVE · n group at the bottom (workspace.md); 0 = never.
- Usage statistics (reads Claude Code transcripts for the rail widget and STATISTICS, ⇧⌘U); Claude subscription per month (the design panel prices a design as its share of the month; empty = Claude Code’s API estimate); Track subscription limits (polls with the Claude Code OAuth token from the keychain).
- Agent in workshop projects: per-session settings for workshop agents (a lower effort,
the plain output style, optionally another model; your defaults never change). Log hook
events (every payload into
logs/events.jsonlandlogs/mod.jsonl).
Appearance
- Applies immediately. Language (English / Čeština; app, menu, server texts and the phone; reloads the window). Theme: dark, Midnight, Graphite, OLED black, Catppuccin Mocha, Catppuccin Macchiato, light, system (follows macOS). Interface size (⌘+ / ⌘−, ⇧⌘0 = 100 %), Terminal font, Terminal cursor and Editor cursor (block / bar / underline), Blinking cursor, Smooth caret.
- File editor typing (since 0.20.10, all on by default, per computer; open editors follow at
once): Wrap long lines (a long line breaks at the panel edge instead of scrolling
sideways), Brackets (the bracket matching the one under the caret lights up; a typed
([{"gets its closer, Backspace removes the pair, Enter between them opens an indented line), Auto-indent (a new line keeps the indent, a closing bracket steps back out). - Side panel left / right (tree and git; files from the tree open next to it); Side panel reveal: pinned (⌘B folds it to the icon strip) or on hover (since 0.19). Language and theme are shared with the server and phone; sizes are per computer.
Agents
- Maker Pack: the Claude Code plugin from github.com/biokys/robion-maker-pack (skills for physical products: parametric CAD, drawings, BOM); install, update, remove; a warning names a personal skill of the same name. The status line says “Maker Pack has an update” → update (agents pick it up in their next session).
- Hold permission requests: how long the server holds a permission (and, since 0.20.28, an
agent’s question) when nobody at the desktop shows the pane, so the rail or the phone can
answer; opening the pane ends the hold; 0 = do not hold. Restore agents after
start-up (after a Mac restart each task comes back via
--resumeor its handoff); Handoff when parking (writes.robion/handoff-<slot>.mdbefore ending; since 0.20.28 the session writes it itself over its own context — faster, no second claude — the headless fork is the fallback); Wait for the turn to finish (seconds on system shutdown). Terminals run in the pane host, Robion’s own terminal daemon (the only backend; the tmux backend and its Terminal backend switch are gone since 0.20.9 — a config.json that still says"paneBackend": "tmux"is read as the pane host). After an update an older pane host may keep running the sessions; the status line offers replace now… (tasks.md, “Parking and Robion restarts”) — otherwise it replaces itself once the last session ends. - Pane host → restart… (since 0.20.26): replaces the pane host at any time, not only after an update — the same park-and-resume as replace now… (a confirm first; the button reads restarting… and the status line shows the progress while it runs). For when no new terminal opens anywhere and a new task fails with “posix_spawnp failed” (troubleshooting.md).
Remote access
- “Phone via Tailscale”: enable / disable, then pair phone (QR code + link, 10 minutes, single use) — steps and error texts in phone.md. Hold permissions for remote access (max. 55 s, Claude Code stops listening to the hook at 60 s); Allowed tailnet accounts (empty = anyone in the tailnet who has the token); Keep Mac awake (a closed lid still sleeps unless power and an external monitor are connected); New token → generate a new token (signs out all devices and hooks; pair the phone again).
- desktop in a browser (since 0.20.36): open in a browser on this Mac (the default
browser opens the desktop at
/d/, paired at once) and, with remote access on, link for another device (a one-time link to copy; new QR code mints another). The whole window in a browser — workspace.md, “The desktop in a browser”.
Servers
- Rows: this computer, connected, connecting…, disconnected — retrying, not paired, “update the server (vX)” on a protocol mismatch. Per server: settings (name, ssh host, new-projects folder, editor command), paired devices with revoke, remove (its projects leave the rail; the server is untouched).
- A server paired here is relayed to the phone as well (since 0.20.17): the phone’s overview
gets a strip per server with that server’s projects, its pushes come through this Mac’s
server, and nothing is set up on the phone (phone.md, “Servers on the phone”). The server
reads the pairing files this section writes (
servers/<id>.jsonin the App Support dir); remove drops the box from the phone too. - Linux server: on the box
curl -fsSL https://robion.app/install.sh | sh(Node ≥ 22.13, Tailscale with HTTPS certificates andsudo tailscale set --operator=$USER, Claude Code logged in); it prints a pairing link → Add a server → connect (or enter URL and token manually). Its projects join the rail under the server’s name; new ones can be scaffolded, imported or cloned there (clone to “server”… in the rail). - update to X runs
robion-server updateon the box (builds beside the running version, switches atomically, restarts — agents survive): “updating to X…”, “restarting…”; after 20 minutes without a return the button comes back pointing at the box’supdate.log. On the box:robion-server status,logs,restart,pair,doctor,backup;versionsanduse <v>roll back. A protocol bump parks a remote until the box runs the matching release — and tells an older box to update itself first: the row reads “server vX” with “updating to Y…” beside it, then “restarting…”, and the desktop re-probes/healthevery 30 s and reconnects. “update the server (vX)” in red stays for a box nobody can update from here (a source install, a box newer than this app, a failed wrapper):robion-server updateover ssh. restart and install X appears here once a Robion update is downloaded.
Notifications
- Notifications on this Mac: a system notification when an agent waits for you, ends with an error or finishes a turn — only while the window is not active; a click opens the task. Push to phones → send a test notification (Web Push to every subscribed phone).
Tools
- Empty path = automatic detection (PATH, /Applications): OpenSCAD, kicad-cli, Python with build123d; Detected tools shows version and path or “not found”. Print bed (mm; the 3D panel draws it and reports a model that does not fit); 3D render timeout.
Privacy
- Send anonymous usage statistics (PostHog, EU; on by default, takes effect at once).
What is sent: versions, OS and CPU, UI language, terminal backend, counts of projects,
tasks and servers, which optional parts are on, which client did which action (key names
only). What is never sent: paths, names, prompts, replies, terminal output, file
contents, log lines, URLs, hostnames, e-mail; the IP gives the country and is discarded. The
install id is a random UUID in
telemetry.json. Full list inTELEMETRY.md;ROBION_TELEMETRY=0turns it off for scripts. - Why dialogs name Robion: macOS attributes everything run inside Robion (shells, Claude Code, tools) to Robion, so its dialogs say “Robion wants to access …”; one grant covers every agent. “Robion wants to access data from other apps” (macOS 26; docker, a browser an agent started) is safe to allow. If you click Don’t Allow only that access fails; change it in System Settings (buttons open Privacy & Security and its panes).
Controls
- panels (JSON): the project’s control panels as the agent defined them, editable by hand (rename, reorder, delete). command probes: agent-defined status checks that run shell commands while a panel is open — allow / revoke per project.
Automations
- Labels only; the behaviour is in automations.md. Run automations, Tasks per day, Quiet hours, Ticket poll interval, Inbox proposals expire after, Keep history for (since 0.20.4; days, 7–365).
- Steward: Let the Steward plan on schedule, Schedule (five cron fields, local time; the hint shows the next plan), Standing instructions (STEWARD.md) (the file in the Steward’s folder, editable by hand), Steward memory (memory.md) (since 0.20.4: what the Steward wrote down for itself — correct a wrong line, or empty it and it starts from scratch), Autonomy (1 · proposes / 2 · starts safe ones), Supervise finished tasks, Follow-ups per task, Proposals per run, Model (since 0.20.4 a choice: default = your Claude Code model, Fable 5.1, Opus 5, Sonnet 5.5, Sonnet 5, Haiku 4.5, or custom… with a model id; the Inbox shows what the last plan cost).
- Rhythm (since 0.20.12): Robion knows when nothing needs you (every agent runs, none
waits for a permission, an answer or a look) and when something will; this section lets it
use that time for you. “Nothing needs you” strip (off by default): one quiet line above
the workspace, “Nothing needs you right now — 2 tasks running. Stand up, take a walk.” with
the hint that Robion calls (the phone push, the dock badge) when a turn ends or an agent
asks; not today hides it until tomorrow, × for this stretch; it comes back when the
next stretch begins. Show after (minutes of waiting on agents before the strip appears,
default 5). A break is (minutes without keyboard or mouse anywhere on the Mac, default 5:
a shorter pause does not interrupt the “at the desk” count that the
desk.sittingtrigger uses — see automations.md). The strip counts every connected server’s agents together; on a headless server without a desktop nobody reports presence, sodesk.sittingnever fires there anddesk.waitingfires regardless of presence. - Issue trackers: one connection per tracker, shared by every project; rules react to
tickets assigned to you and the JIRA panel reads from it; Robion never writes to a
tracker. Jira site URL (Jira Cloud), Jira account e-mail, Jira API token
(id.atlassian.com → Security → API tokens; kept in the keychain) → connect /
disconnect. GitLab URL (gitlab.com or your own), GitLab personal access token
(scope
read_api). GitHub API URL (leave empty for github.com; GitHub Enterprise Server:https://HOST/api/v3), GitHub personal access token (fine-grained with Issues, Pull requests and Checks read — Checks for thechecks:failurerules of automations.md — or classic withrepo) → connect / disconnect; GitHub state shows “connected as” or the connection problem (a bad token, a rate limit with the time it resets). A rule’s query is a string of GitHub search qualifiers ( is:pr review-requested:@me); see automations.md. Adding, importing and cloning projects: see workspace.md. - Slack (own section under Automations): messages, mentions and reactions in the channels
the Robion bot is a member of become the
slack.*rule triggers of automations.md the moment they happen — Slack pushes them over one outbound connection (Socket Mode), so there is no polling and no public address. Needs a workspace-internal Slack app (api.slack.com → Your Apps → Create → From scratch) with Socket Mode on, an app-level token withconnections:write, the bot scopeschannels:history,groups:history,app_mentions:read,reactions:read,users:read,channels:read,groups:read(the last three turn ids into names in the event text and list the bot’s channels), the event subscriptionsmessage.channels,message.groups,app_mention,reaction_added,member_joined_channel,member_left_channel(the last two tell Robion the bot was invited somewhere or removed, so the channel list follows without a restart; it is re-read every 10 minutes anyway), and the app installed to the workspace. Forslack.dmrules add the scopesim:history,mpim:history, the eventsmessage.im,message.mpim, and in App Home switch on “Allow users to send Slash commands and messages from the messages tab”, or nobody can write to the bot. Slack app-level token (xapp-…), Slack bot token (xoxb-…) → connect / disconnect; both tokens are tried against Slack before they are stored in the keychain. Your Slack member ID (since 0.20.36;U…, Slack → your profile → ⋯ → Copy member ID): what “me” means in the conditions of a Slack rule —"user": "me", or{"not": "me"}for everyone but you; a bot token cannot tell who installed the app. Empty, such a condition never holds, so a rule “everyone except me” fires for nobody rather than for you too. Slack state shows “connected to”, “connecting…”, “not connected” or the problem ( invalid_auth= a wrong token;link_disabled= Socket Mode is off for the app), and under it “the bot listens in #a, #b” — the channels the bot is a member of, the only ones whose messages arrive. “the bot is in no channel yet” →/invite @<app name>in the channel. Robion never posts to Slack.
How Robion sees a session
- Agent states (running / waiting for you), the chat on the phone, the live context in the
rail and the answers to permissions come from Robion’s own hooks module: a component of the
Claude Code plugin Robion ships, loaded into every session Robion starts (since 0.20.28,
through
CLAUDE_CODE_PLUGIN_DIRS, so a fork or a child session inherits it). Nothing is written into~/.claude/settings.jsonany more; a Robion that put hooks and a status line shim there before takes them out once, at its first start (a backup next to the file). A server started with--no-hooks(a throwaway) never touches the file. - Needs Claude Code 2.1.287 or newer — the release that introduced mods. With an older one the session runs, but the task reports nothing and the server log says so.
- In the terminal,
/robionopens a pane with the task as Robion sees it: title, project and folder, branch, ports, every controls panel with its values, and who is watching (the desktop shows the pane, a phone is connected);/robionagain refreshes it. When the phone allows, denies or answers, a toast in the terminal’s corner says so. - “Robion’s hooks module did not load in this session” on a task (desktop: under the terminal’s status line; phone: a strip above the chat) means Claude Code started in the pane but never reported from the plugin: its state stays unknown, the phone chat and the context in the rail stay empty, permissions cannot be answered from the phone. See troubleshooting.md.
Updates
- Checked at start, every 6 hours and after wake; a new version downloads by itself. The status line shows “Robion X · downloading N %”, then “Robion X is ready” with restart (agents and terminals keep running and reconnect) and hide. The app menu adds Restart and Install X above Check for Updates…; “Later” installs on quit. A failed check says why (offline, release not published yet). A version that waits for a restart does not stop the checks (since 0.20.19; before, the app could only install the downloaded one): the quiet check and Check for Updates… look for a newer release, download it in place of the waiting one, and finding none offer the restart.
- Help → What’s New shows the release notes (opens once by itself after an update). A session that outlived an update sees “Robion was updated, restart this session” on every tool result and a note on the task timeline (since 0.19).
Where data lives on disk
~/Library/Application Support/Robion/(Linux:~/.local/share/robion/):config.json(language,theme,servers, …),projects/,tasks/,logs/(server.log,desktop.logfor renderer errors,events.jsonl— add them as LOG sources),token,servers/(remote tokens),mcp.json,usage.sqlite,webpush.json,telemetry.json,automations.sqlite,board.json,steward/(STEWARD.md, briefings, plans).- In a project:
.robion/is git-excluded scratch —uploads/(photos from the phone and the design panel),handoff-<slot>.md; worktrees under.claude/worktrees/by default. - “SERVER FAILED” points at
logs/desktop.log(why a server start failed, since 0.20.7) andlogs/server.log; running agents live in the pane host and are safe. “An older Robion server is running on port …”: quit it or useROBION_PORT. - Help → Keyboard Shortcuts (⌘/) lists every shortcut by group: application, tasks, panels, view.