The desktop
Text

The desktop

The menu bar works like the classic Mac it resembles:

  • Apple menu — About This Computer (see below).
  • File — New VM…, Upload to Workspace…, Close Window, Refresh.
  • Windows — reopen the core windows: Virtual Machines, Chat, Newsfeed, Icon Editor, Configuration, Daemon Log.
  • Special — Mac OS 9, Join… (pair another exe machine), Cloudflare Status and Setup Wizard, Set API Token….
  • Help — this page, and the Agent Skill Guide for handing exe to a coding agent.
  • Show All Windows — the button at the right, left of the magnifier: every open window shrinks into a grid. The one under the pointer turns blue and shows its name; click it to bring it forward, or click the desk, the button again, or press Escape to put them all back. The desktop menu reaches it as showall.
  • Search — the magnifier: one box finds VMs, chat sessions, notes and todos.

About This Computer, under the Apple menu, is the OS 9 box: the build, the machine, its addresses (click one to copy), Built-in Memory, how much of it is allotted to running VMs, Disk Space where VM disks live, and Largest Unused Block — what the host could still hand a new VM. Below the rule, one memory bar per running VM shows its allotment, scaled so the largest fills the column, with exe's own footprint as the first row. It refreshes every few seconds while open.

Updates arrive by themselves. When the daemon restarts with a new desktop or new system apps, an open desktop notices and reloads — a few seconds after the daemon is back, at once in a tab you are not looking at. It waits while you are typing or clicking, while a menu or dialog is up, and for as long as there is unsaved work: text typed into a field and still there (in a closed window too), an editor with unsaved changes, unsaved Icon Editor pixels. While work holds it, the Apple menu shows Reload for Update to take the update anyway. A restart that changes nothing the browser runs leaves your windows alone.

Right-click the desktop (long-press on a phone) for the desktop menu: a NeXT-style menu at the pointer, with shortcuts to VMs, apps, windows and tools. Choose Customize… to edit it. The Desktop context menu chapter covers the format, every supported action and examples.

Desktop icons: Workspace (shared files), Terminal (a shell on this host machine), Claude Code and Codex (each appears when its CLI is installed on this host; one persistent session per agent, so closing the window and reopening it returns to the same conversation), one icon per VM, one per installed app, plus Newsfeed, Chat (appears when Ollama is reachable) and the Trash. Double-click opens things.

The Control Strip in the bottom-left corner is OS 9's tray. Its first module is the Cloudflare heartbeat: the lamp on the cloud is green while the tunnel is healthy, yellow when it needs attention, grey while it is still checking. Its menu shows the tunnel's replicas and edge connections, plus this node's request rate, active requests, totals and origin errors. Open Cloudflare Status… for the same live counters and connector uptime. Local traffic refreshes every five seconds while either view is open; tunnel-wide connection counts refresh every 30 seconds. Traffic totals are for this node's connector, include every hostname on its tunnel, and reset when cloudflared restarts. Unavailable data is shown as a dash. The menu also offers the Setup Wizard and Check Now. Right of it, on a machine with Tailscale installed, the Tailscale module: a panel of nine lamps that lights Tailscale's four while the tailnet is connected, blue while the machine's traffic leaves through an exit node, yellow when something needs attention (a health warning, a login due), all dim while Tailscale is off. Its menu says which machine this is and how many devices are online; Tailscale Active and Inactive turn it on and off; Exit Node picks one of the devices offering one (and Allow LAN Access); Devices lists the online ones and Serve the Tailscale Serve rules — pick a row to copy its address; then Accept Routes, Use Tailscale DNS, Shields Up and Tailscale SSH toggle (rest the pointer on one for what it does), and Admin Console… opens Tailscale's. Turning it off or raising shields while the desktop is itself reached through Tailscale asks first, because the desktop would go with it. The daemon asks the tailscale CLI on the machine and changes only those settings (GET /v1/tailscale, POST /v1/tailscale/set); it runs as Tailscale's operator user, so no sudo. Beside it, the Solana ticker shows a token's coin and its dollar price: SOL, or PUMP, MET or SKR — pick the one the tile wears from its menu. The menu lists them all with their day change, and the ecosystem tokens with their price in SOL as well — the zeros after the point fold into a small sunk count, so PUMP's 0.00003717 SOL reads 0.0₄3717 SOL, MET's 0.002404 SOL reads 0.0₂2404 SOL, and the column lines up (a dollar price folds from three zeros); the figures are Coinbase's public spot prices, fetched once a minute by the daemon and shared by every desktop on the node. Notify Me of Big Moves in that menu turns on push notifications for this device (on a phone, the app added to the Home Screen): you hear when a token moves more in an hour or a day than it rarely does — SOL 2.5% / 6%, PUMP 5% / 12%, MET 6% / 15%, SKR 8% / 25% — never more than four times per token in 24 hours; a move that qualifies while the four are spent is counted into the next one. Recent Moves lists the last ones, Send a Test Notification checks the road, and the menu item again turns it off. Next to it, the agent usage meter shows how many tokens Claude Code or Codex has used on this machine today — pick the agent the tile wears from its menu, and Show Plan Limit puts the fullest of that agent's usage windows there instead (46% wk). The menu lists both agents with today's tokens and their five-hour and weekly windows, the windows in columns so one agent's week stands under the other's (a window an agent lacks stays blank); each agent's submenu splits today and the last seven days into tokens sent fresh, read back from the prompt cache and written, draws the week as a column a day — a figure on the busiest day and on today, every day's own split in its tooltip — and says when each window resets. The daemon counts from the CLIs' own logs — Claude Code's transcripts, Codex's rollouts — so every session on the machine is in, not only the ones opened from this desktop (GET /v1/agents/usage). Claude Code's windows are as fresh as its last reply in a Claude Code window here; Codex's are read live on the ChatGPT sign-in. An agent appears once it is installed and has left figures; with neither, the tile stays away. The tab at the right hides the strip down to the tab alone.

With notifications on, the daemon also watches the sky over the first city in the Weather app — the row your drag put on top. When Open-Meteo's quarter-hour rows put rain in the next 60 minutes, a push says Rain possible soon — or likely, when the chance is high — and a second one says Next hour looks dry when a fresh forecast clears it. Three more hazards ride the same watch, their lines the National Weather Service's own: Dangerous heat at a feels-like of 105°F, High wind at gusts of 35 mph, and Fire weather when humidity at or under 15% meets those gusts — a red-flag hour that then keeps the plain wind push quiet, so a Santa Ana taps once. Each hazard clears with its own easing push, at most four warnings per hazard in 24 hours, in °F and mph for a US city and °C and km/h elsewhere. Reorder the Weather list and the watcher follows; there is no setting to flip.

A Claude Code window's status line shows the session's figures at its right — the model, context in use, tokens, cost and the plan's 5-hour and 7-day usage windows — kept current after every reply by Claude Code's own status-line hook; hover for the long form. A status line of your own in ~/.claude/settings.json keeps working inside the terminal. A Codex window's shows the ChatGPT subscription's 5-hour and weekly usage windows (the sign-in under Configuration → OpenAI), re-read once a minute while the window is open; hover for the reset times.

The mouse wheel scrolls back through the conversation in either window. Claude Code takes the wheel itself and scrolls its own transcript. Codex leaves its transcript to the terminal, and on a host with tmux that is the tmux session's history: the wheel scrolls it there (tmux's copy mode, with its [123/980] position at the top right), and typing returns to the live screen first, so the keys reach Codex as in any terminal. Text selection is unchanged: drag in a Codex window, Shift+drag (Option+drag on a Mac) in a Claude Code window, which tracks the mouse.

To hand the agent a file — a screenshot, a log, a document — drag it from your computer onto the window. It is uploaded to the Workspace root, the same as a drop on the desktop, and its path on this machine is typed at the cursor, quoted if it needs it, so "look at this" is all the prompt then needs; the agent reads the file from there (Claude Code shows an image it is given a path to). Several files arrive as several paths. A plain Terminal window takes a drop the same way; a VM's window does not, since a host path means nothing in the guest. If the window's link is down when the upload lands — a laptop back from sleep, the daemon restarting — the file is in the Workspace all the same, and its path waits in a row under the terminal: Insert types it once the window is connected again, Copy puts it on the clipboard for another window, Dismiss forgets it. Nothing is uploaded twice.

On a host with tmux, a Claude Code or Codex window lists the agent's sessions down its left, one row per tmux session, titled the way the CLI titles its terminal — Claude Code keeps that on its current task, and Codex, which the desktop starts with its terminal title set to the thread, on the thread's name (a session started before that keeps its old title until it is restarted). Click a row and the window moves to that session; New starts another conversation in a session of its own, at the top: the list runs latest first, the icon's own session at the bottom. While the window shows another session, a pulsing green dot marks one still working and a black dot one that waits for you — its turn finished, or a permission or question pending. Claude Code reports those through its hooks; Codex through its notify command, which the desktop points at the session (a notify of your own in ~/.codex/config.toml still runs after it), and through the terminal bell, which the desktop has Codex ring at the end of a turn and for an approval so tmux notes it while no window is looking. Hover a row for which. The status line's figures follow the session on screen. A window opens on the session it showed last — from any browser, and after the daemon restarts: tmux itself remembers where the window was — with its row scrolled into view, and dragging the line between the list and the terminal sets the list's width, kept with the window's layout. A row's contextual menu opens with when the session started, in grey, then starts a new session, copies the row's title, or archives the session, after a dialog: the session and its process end, and the conversation stays on this machine for /resume inside Claude Code or Codex — the desktop keeps no list of its own. Archive shows only once the conversation exists; when the window was showing that session it moves to the one before it.

A window whose link drops — the tab left behind while the laptop slept, a network that came and went, the daemon restarted — reconnects on its own, in the background, to the session it showed; a window whose tmux client was detached with the sessions still there does the same. Only when the agent's last session has ended does it stop and say so: close and reopen it for a fresh conversation. The same session can be open in more than one window at once — a phone beside the desktop — and the terminal takes the size of whichever was attached, typed in or resized last.

A Codex thread started elsewhere on this machine — in the ChatGPT app on your phone (its remote Codex runs here), the Codex app, VS Code — is a conversation on this machine all the same, and the Codex window's column lists the latest ten under a rule below its sessions, titled the way the app titles them, with a hollow dot (a green one while a turn runs there). Hover a row for where and when it started. Click it, or choose Continue Here from its menu, and the thread opens in a session of its own, in the folder it was started in: the row moves up among the sessions and the conversation carries on here; leave it be and it stays where it is. The API takes the same: POST /v1/agents/codex/sessions with {"resume": "<thread id>"}, and GET …/sessions lists the threads beside the sessions.

The column is also an API, for tools that want a conversation you can watch: GET /v1/agents/claude/sessions lists the rows with their states, POST /v1/agents/claude/sessions opens a numbered session with a first message (and, for Claude Code, a session to resume or fork, a permission mode and a model), POST …/sessions/<name>/prompt types a message into one, DELETE …/sessions/<name> ends it. The message's prompt goes in as a paste, and Claude Code treats pasted text as material rather than as your words, so give the request a say as well: one line, typed ahead of the paste, that tells the session what to do with it. The hub watcher builds this way: an instruction you post in one of Claude's hub threads opens as a session in the Claude Code window's column, works there in view, reports in the thread when it is done and stays open in the window to be continued.

Windows behave like OS 9 windows: drag the title bar to move, drag the left/right/bottom edges or the grow corner to resize, click the shade box to collapse a window to its title bar, the zoom box to toggle its size. The whole layout — positions, stacking, which windows are open — is saved on the daemon and mirrored live to every browser looking at this desk, so dragging a window here moves it on your other screens too.

On a phone the desktop becomes a home screen of icons and windows go fullscreen, one at a time; a tapped icon swells and fades as its window comes up, and closing a window walks back through the stack like a phone's back button. In a Claude Code or Codex window a finger drag scrolls back through the session's history, and a flick keeps it going. In Todo and Weather a finger scrolls the list; to move a row, press and hold it for half a second until it tints, then drag it to its new place.

Over HTTPS — a Tailscale Serve address, say — the desktop installs as an app: Add to Home Screen on an iPhone or iPad, the install button in Chrome's or Edge's address bar. It then opens in a window of its own with the menu bar right under the status bar. When the daemon is not answering — restarting, or the device offline — the desktop shows an alert in place of the browser's error page and comes back by itself once the daemon does.

Every system icon is hand-plotted pixel art, and Windows → Icon Editor lets you repaint it: the gallery lists each one (the VM Mac, folders, documents, the Trash, built-in apps such as Mac OS 9, the minis in search results, even the Apple menu), and double-clicking opens a fat-bits editor — pencil, eraser, eyedropper, fill, undo, the Platinum palette plus a custom color well. Save applies the art everywhere at once, follows the desk into every browser and joined node, and survives restarts; Revert brings the factory icon back. On a VM icon, pixels painted the factory screen-green keep changing color with the VM's state. New Icon… adds icons of your own on a 32×32 or 16×16 grid — draw them, copy their SVG for use anywhere, delete them when done. System icons can only be repainted, never deleted. Restored editors keep their position, stacking and shaded state even when their icon loads after the desktop layout.

Contents