The desktop menu opens at the pointer when you right-click an empty part of the desktop. Unlike the menu bar, it is yours to write: a short text file with a label and an action on each line, so that what you open most is one right-click away.
For you:
terminal btop opens btop in a window of its own, and any other command on the host works the same way.@vms, @apps and @windows show this desktop's VMs, apps and open windows each time the menu opens. Each VM brings a submenu to open, start, stop or restart it.For a coding agent, such as Claude Code or Codex:
GET /v1/ui/menu and replaces it with PUT /v1/ui/menu. The daemon checks what it sends as it checks Save, so a file with a mistake never replaces your menu.Right-click an empty part of the desktop, or long-press it on a touch screen. A quick two-finger tap also opens the menu; on a phone this works inside an ordinary window too, away from controls, menus and dialogs. It is a NeXT-style menu: it opens where the pointer is, with its submenus beside it.
The factory menu offers New VM, Terminal, Workspace, lists of VMs, apps and windows, Show All Windows, Show Desktop, tools, Cloudflare and Help. Its last item is Customize…, which opens the menu editor.
Save checks the format first: an error identifies and selects the bad line, and your current menu stays in place until the file is valid.
Until you save a menu of your own, the editor shows the factory menu. Its opening comments describe the format and name every action.
The scrollbars run along the document's right and bottom edges; drag the resize tile where they meet to make the editor wider or taller.
Your menu is stored as System :menu.txt (normally ~/.exe/appdata/System/menu.txt). The file is there only once you have saved a menu of your own.
A saved change reaches other open desktops and syncs to joined nodes; see Joining desks together. Each desktop fills the automatic lists from its own VMs, installed apps and open windows.
A menu of your own keeps its contents when the factory menu changes, so a new shortcut in the factory menu does not appear in yours by itself. Add it to your own file with Customize….
An agent, or a script of your own, reaches the same menu over HTTP:
GET /v1/ui/menu answers with the menu's text in text, the parsed menu in menu, and default, which is true while the factory menu is in use.PUT /v1/ui/menu takes the new text as the request body, in plain text, and applies it as Save does. A file with a mistake changes nothing and is answered 400 with {"error": "line N: …"}. An empty body restores the factory menu.$ curl -s http://127.0.0.1:7777/v1/ui/menu $ curl -s -X PUT --data-binary @menu.txt http://127.0.0.1:7777/v1/ui/menu
When api_token is set, both calls need the Authorization: Bearer <token> header; see Configuration.
Write one item per line. Separate the label from its action with a tab or at least two spaces. Single spaces are fine inside a label; two spaces end it. Action names, list names and VM tab names are lowercase and case-sensitive.
In the format examples below, <TAB> means a tab character, not the literal text <TAB>. The complete example menu further down uses spaces and can be copied directly.
| Line | Meaning |
|---|---|
Terminal<TAB>terminal | A label, a tab, then an action. Two or more spaces work too. |
Tools | A submenu heading. Put at least one indented item below it. |
- | A separator. A line made only of several hyphens works too. |
# My shortcuts | A comment on its own line; it may be indented. Blank lines are ignored. |
@apps | Insert an automatic list at this position. |
Applications<TAB>@apps | Put an automatic list inside a named submenu. |
A line that starts with # is a comment and one that starts with @ is read as a list, so a label cannot begin with either. Put comments on their own lines, rather than after an action.
Indent submenu children consistently, for example with two spaces per level. The top level has no indentation. When returning to a parent level, use exactly its earlier indentation. Only a plain submenu heading can have indented children; an action or automatic list cannot.
The following table lists every supported action. In the syntax column, angle brackets mark a required value and square brackets an optional one; replace these placeholders rather than typing the brackets. Each action needs a label before it, as in My terminal<TAB>terminal.
| Action syntax | What it does |
|---|---|
about | Open About This Computer. |
newvm | Open the New VM dialog. |
upload | Open Upload to Workspace. |
closewin | Close the front window. |
showall | Show All Windows: toggle the overview of all open windows. |
showdesk | Show Desktop: slide every open window off to the edge of the screen, and back. |
refresh | Refresh the VM and app lists, including My Apps when it is open. |
terminal [command] | Open a new terminal on the host. With a command, run that command instead of an interactive shell. |
claude | Open the host's Claude Code window. Disabled when its CLI is unavailable. |
codex | Open the host's Codex window. Disabled when its CLI is unavailable. |
workspace [folder] | Open the Workspace root, or a folder relative to that root. |
edit <file> | Open a file in the text editor, using a path relative to the Workspace root. |
app <name> | Open an installed app by its app ID. Disabled when it is unavailable. |
vm <name> [tab] | Open a VM's detail window, optionally on a specific tab (see VM tabs). Defaults to Services; disabled if the VM does not exist on this node. |
chat [vm] | Open Chat. With a VM name, show that VM's chats and pin new chats to it; without one, show all chat sessions. Disabled when Chat is unavailable. |
winvms | Open the Virtual Machines window. |
winmyapps | Open My Apps, the window of published sites and their domains. |
winchat | Open Chat with all sessions, the same as chat without an argument. Disabled when Chat is unavailable. |
winnews | Open the Newsfeed. |
winicons | Open the Icon Editor. |
winconfig | Open Configuration. |
winlog | Open the Log Viewer. |
search | Open desktop Search. |
trash | Open the Trash. |
join | Open the Node Sync dialog (Special → Node Sync…) to pair another exe node. |
hubjoin | Open the Hub app on Join a Hub, its four steps for joining a hub. |
cfstatus | Open Cloudflare Status. |
cfwizard | Open the Cloudflare Setup Wizard. |
token | Open the API Token dialog (Special → Set API Token…) for this browser. |
url <address> | Open an http:// or https:// address in a new browser tab. |
docs | Open this manual in the desktop, in the exe Documentation window. |
skillguide | Open the Agent Skill Guide. |
update | Open Software Update. |
welcome | Open the Welcome window. |
customize | Open this menu's editor. |
There is no separate macos9, macosx or macosxintel action in the customization format; use app macos9, app macosx and app macosxintel.
Except for terminal, arguments are separated by whitespace: quotation marks do not combine words into one argument. A Workspace path or app name containing spaces therefore cannot be used directly in an edit, workspace or app item. Use workspace to browse to that file or folder, or @apps to list apps by their display names.
For workspace and edit, use relative paths such as Projects/demo or Projects/demo/README.md. Absolute paths and paths that escape the Workspace are rejected.
For built-in apps, use their lowercase IDs: app macos9, app macosx, app hub, app bluepencil, app dict or app analytics. Other apps use their installed folder name; see Apps.
The command after terminal is kept as one command line, including spaces, quotes and shell operators. For example, Monitor<TAB>terminal btop opens btop on the host if it is installed. To reach a VM's shell instead, use vm <name> term.
On Linux and macOS the command runs in the host user's login shell; on Windows it runs in PowerShell. The terminal session ends when the command exits.
A command's window opens at 80×31 characters at least — what btop needs with its GPU box, and room enough for any other tool — and cannot be dragged smaller. It remembers its size and position, so the next open of the same command puts it back where it was left.
Choosing the item again while the command runs brings its window forward; after the command has exited, it runs it again in the same window's place.
Use these values as the optional second argument to vm. For example, Demo terminal<TAB>vm demo term opens the Terminal tab of the VM named demo.
| Tab | Opens |
|---|---|
svc | Services (the default). |
term | Terminal. |
vibe | Agent. |
expose | Expose. |
sess | Sessions. |
notes | Notes. |
These lists fill themselves when you open the menu. Use a list name alone to insert its entries in place, or give it a label to make a submenu. They take no arguments. An empty list shows a disabled No VMs, No Apps or No Windows entry.
| List | Contents | Named submenu example |
|---|---|---|
@vms | Every VM on this node, each with an operations submenu. | Virtual Machines<TAB>@vms |
@apps | Installed apps, including built-in apps, shown by their display names. | Applications<TAB>@apps |
@windows | Open windows on this desktop, sorted by title. Pick one to bring it forward. | Windows<TAB>@windows |
Each @vms submenu offers Open, Open Terminal, btop, Chat with this VM, Start or Stop, Restart, Copy IP, Expose Port… and Publish to GitHub…. Availability follows the VM's state, its IP and Chat availability. Delete is not included.
These operations are supplied by @vms; names such as start, stop and restart are not standalone customization actions.
@apps leaves out Welcome, which has no desktop icon either; the welcome action opens it.
This example uses two spaces between a label and its action, and two spaces of indentation for each submenu level. Replace demo and the Workspace paths with your own VM and files; install btop on the host to use the monitor shortcut.
# My desktop menu
New VM… newvm
Terminal terminal
Workspace workspace
-
Projects
Demo folder workspace Projects/demo
Demo README edit Projects/demo/README.md
Demo terminal vm demo term
Demo notes vm demo notes
Tools
Monitor terminal btop
Claude Code claude
Codex codex
Mac OS 9 app macos9
Hub app hub
Virtual Machines @vms
Applications @apps
Windows @windows
Show All Windows showall
Show Desktop showdesk
-
Help
Using exe docs
Online documentation url https://exe.v2core.com/docs/
Customize… customize
The menu may contain up to 300 entries, counting headings, actions, automatic-list entries in the file and separators across all levels. Expanded list contents do not count toward that limit.
Labels may be up to 60 characters; the file must be UTF-8 and at most 64 KiB. You can nest three submenu levels below the root (four levels in total).
If you remove customize, the desktop appends Customize… so you can always get back to the editor. If a stored or synced file cannot be parsed, the desktop uses the factory menu and adds The menu file has an error… to open the editor on the problem.
To reset, choose Restore Defaults and confirm, or clear the editor completely and Save. This removes the custom menu from every desktop sharing the desk. Only an empty or whitespace-only file restores defaults; a file containing just comments is still a custom menu.