Repository navigation
Releases: morewebs/OpenRemote
Release list
OpenRemote nightly - 2026-11-02
OpenRemote nightly - 2026-11-02
Built from main at 74271bb on 2026-11-02 11:36 UTC.
This is the automated nightly channel: unsigned test builds, replaced every night,
at URLs that never change - https://github.com/morewebs/OpenRemote/releases/download/nightly/OpenRemote-Setup-x64.exe,
and the same name for the msi, the AppImage, the deb, the dmg and the apk.
The stable channel is releases/latest. Nightlies report the stable version in-app
(the build is not version-stamped yet) - this page's commit is the identity.
Since the last nightly (74271bb)
OpenRemote 0.4.8
A bookmark you keep on one computer is on the others.
0.4.7 shipped the plumbing that carries browser settings and bookmarks between
your computers and the bars that draw them, but nothing a person did reached it:
the console kept bookmarks in its own storage. This release closes that, so the
sentence the last two release notes had to take back is true now.
Changed
- Bookmarks follow the account. The star writes to the rows the daemon keeps
on disk, which is the store the sync note reads, so a page kept on this
computer appears on the account's other computers and comes back if you keep it
again. Removing a bookmark removes it everywhere: the deletion travels as its
own row, so a computer that was switched off cannot bring it back. - A computer that was reset catches up. A device whose browser store started
again used to have every note it sent ignored, silently, because its sequence
began at one again. A note now says which run it came from, and the receiver
reads it rather than skipping it. - The bar tells you when it is a memory. If the daemon refuses a bookmark
write or does not answer in time, the row goes back and the bar says the list
is what this window last saw, instead of showing a save that never happened.
Known
- Your reading history, cookies and the tabs to restore stay on the computer that
made them. They are not part of the account. - Browser settings have the same plumbing and nothing in the console writes
them yet, so in practice they do not travel: only bookmarks do. - An installed app still does not look for a newer version. Moving to a newer
release means running a newer installer over it, oropenremote --updateif
you installed through npm.
OpenRemote 0.4.7
Chats you can arrange, and a Browser section that says what the browser keeps.
Three things the console had no way to do, all of them about the lists you live
in all day.
Added
- Move a chat to another project. The chat's own row menu has Move to
project, which opens this machine's project picker where the menu was, with No
project first and the chat's current project marked. A chat with a turn in
flight is refused in the daemon's own words; a running chat that is between
turns restarts its harness in the new folder, and the transcript keeps a line
saying where it moved. Whether the agent's own conversation continues depends
on its harness: one that finds its session record continues where it was, and
one that does not starts a fresh conversation in the new folder. - Pin a chat. Pin, from the same row menu, keeps a chat at the top of its
project's list, in the order you pinned them, with a pin mark on the row.
Unpin puts it back where its activity puts it. Pins are this computer's
arrangement, not something the account carries. - Lists that page. A project draws five chats and the flat Chats list
fifteen, with a quiet "Show N more" line that opens the rest of that list for
the session. Nothing is hidden that you cannot get back in one press. - Settings > Browser. What the browser keeps on this computer, in one place
and in plain words: how many bookmarks, how many pages read, that a private
tab is never recorded, that cookies and site data live in the profile the
pages share, and where downloads land. Clear history and Clear bookmarks ask
once, the way the other destructive rows do. Two rows say where the work is
done instead of offering a button that would do nothing: the shell clears site
data tab by tab, and the downloads list is the browser's own page.
Known
- An installed app still does not look for a newer version. Moving to a newer
release means running a newer installer over it, oropenremote --updateif
you installed through npm. - A chat moved between projects is not moved from another device: the route is
local to the daemon that runs the chat. - Bookmarks do not follow you to another computer yet, and neither do the pages
you read. The daemon can already carry browser settings and bookmarks between
your devices, but the console keeps its bookmarks in its own storage and does
not write them there yet, so nothing about them leaves this machine.
OpenRemote 0.4.6
A private tab stays private, and a new tab shows what you have been reading.
A small release, an hour after 0.4.5, for three things that were worth not
leaving in a published build.
Fixed
- A private tab was being written into this window's history. The console
promised, in its own design contract, that a private page is kept from history
and from anything that reads it, and the promise was not kept: the shell said
which tabs were private and the console never read the flag. It does now, so
neither the history list nor the address bar's suggestions can name a page read
in private. - A peer's browser note had no ceiling. Settings and bookmarks arrive from
your other devices, and nothing bounded them: one note could carry a million
rows or a row of a hundred megabytes. There are ceilings now, a note over one
is refused whole before a single row is written, and the refusal is logged on
the device that received it.
Added
- The new tab page shows your reading. A new tab used to be a search box on
an empty page; it now draws the addresses this window has read under it, newest
first, one row per address, six at most, each opening in the tab. It is the
same record the history list draws, so nothing in it was read in a private tab.
Smaller
- The address bar's suggestion list, the bookmarks bar and the history list are
now driven end to end by the project's own DOM smoke: 31 checks, no skips, read
from a real window rather than from source text.
Known
- An installed app still does not look for a newer version. Moving to a newer
release means running a newer installer over it, oropenremote --updateif
you installed through npm. - Bookmarks do not follow you to another computer yet, and neither do the pages
you read. The daemon can already carry browser settings and bookmarks between
your devices, but the console keeps its bookmarks in its own storage and does
not write them there yet, so nothing about them leaves this machine.
OpenRemote 0.4.5
An agent can drive a real browser, and the console keeps the pages you read.
This is 0.4.4 and 0.4.5 together. 0.4.4 was tagged but never reached the
download page: its Linux and macOS builds failed on a dependency that was
declared for Windows only, so the browser that release described was never
published anywhere. The builds compile, and this is that release with the
night after it folded in: the browser's bookmarks, its history and its
suggestions, and a set of fixes where the console had been telling you
something it had not checked.
OpenRemote is one window for the agent harnesses on your computer - Claude
Code, Codex, grok, pi, opencode, agy - and the built-in browser is part of the
product now: pages live in a pane beside the chat, and the chat's agent can
open, read and click them through its own tools.
The browser, and how to use it
Open the pane. Four ways, all the same pane: the Browser tile in the
sidebar, beside Plugins and Automations; Ctrl+Shift+B (the shortcuts sheet
lists it as "Show or hide the browser"); the globe in the floating icons at the
top right; or the command palette, Ctrl+K then "Show or hide the browser".
The pane sits at the right of the window, keeps its tabs when you close it, and
its width is yours to drag.
What it is. Chrome's arrangement on this machine's own engine: a tab strip,
an address bar, back and forward, find, print, DevTools in a dev build. Pages
are WebView2 on Windows and WebKit elsewhere, in a profile of their own, so they
never share storage with the console. No bundled Chromium is downloaded.
How an agent uses it. Every chat's harness is started with OpenRemote's own
MCP server, and that server carries the browser's tools: open a tab, navigate,
read a page as text, click, type, press keys, hover, scroll, pick an option,
wait for text, take a screenshot, read the console and network, run a script,
upload a file from the chat's folder. A tab an agent opens is drawn off screen
until you show it and is marked with its chat; your own click takes control
back, and the agent is told. A private tab is kept from agents and history
until you hand it over.
What it will not do. Uploads only come from the chat's own folder. Pages
cannot reach the app's own addresses. A page's downloads land in your Downloads
folder, and the console keeps one row per download with its own id, so two of
them are never confused.
Reading, kept
- Bookmarks. The star beside the address bar, or Ctrl+D, keeps the page
on the bookmarks bar and opens a small editor for its name and folder. The
same press on a kept page edits that bookmark instead of making a second one,
so an address is always one row. A bookmark with no name is drawn as its
address, and the bar appears only while something is kept. - History. Grouped by the day it happened, newest first, five hundred pages
per window, opened from the pane's own menu. A row opens its address, and
Clear history asks once before it empties. - Suggestions. Typing into the address bar ranks one address once: a title
that starts with the letters beats the same letters inside a title, a kept
bookmark beats a plain visit of the same quality, and the newer visit comes
first among equals. The arrows move the highlight and Enter opens it, with the
field keeping the focus. - All three stay on this computer. Nothing about your reading is sent anywhere,
and none of it needs an account.
The console stops telling you things it has not checked
- A saved setup settles silently. Pressing a setup whose model or project is
gone applies what it still can and says nothing about the difference. - The numbers match the lists. Metrics counts the active chats, names a state
it cannot classify instead of dropping it, and a "ran" line no longer invents a
time for a stamp in the future. - Cost and thinking tokens were counting twice. The daemon re-reports a
turn's usage when a stream reconnects, and the console had no way to tell that
turn from a new one, so the row doubled. Both payloads now name their turn,
and a repeated report replaces its own tally instead of adding to it. - A picker can always be searched. Typing into any dropdown threw when a
caller's row had no name yet, which is every list while it loads. - The dropdown keeps its keyboard, takes the press it consumed, and
re-clamps when the window shrinks. A dialog hands the keyboard back to the
control you actually pressed. - A refused write says so: archiving, and a copy the clipboard refused.
- Two projects that read the same name say which folder they are, and a
project list that failed to load no longer reads as a machine with none.
Known
- An installed app still does not look for a newer version. Moving to a newer
release means running a newer installer over it, oropenremote --updateif
you installed through npm. - The browser's pane is not on a phone; a phone lists and drives chats, not tabs.
- Bookmarks and history do not follow you to another computer yet. They are this
device's, on purpose for now; the account carries chats and machines.
OpenRemote 0.4.3
A console that stops telling you things it has not checked, and a saved setup that stops narrating itself.
OpenRemote is one window for the agent harnesses on your computer - Claude Code, Codex, grok, pi, opencode, agy. This release is a night of narrow reads, one surface at a time, fixing places where a screen said something the state did not support.
The console stops telling you things it has not checked
- A saved setup settles silently. Pressing a setup whose model or project is no longer here used to print a sentence about the difference ("gemini-4-argon-medium is not one Antigravity lists any more, so the chat starts on its default model"). It now applies what it still can and says nothing. Two notes about the chat in front of you stay: a model list that did not load, and a model dropped by a harness switch.
- The metrics count what the lists count. The Metrics view counted archived chats, so its total disagreed with the sidebar under it, and a status this console does not know was dropped from the sentence with nothing said. It counts the active chats now, and names the ones it cannot classify.
- A "ran" line stops inventing a time. A
last_runstamp in the future was printed as an ordinary past run; a machine whose clock is ahead says so instead. - The changes surface says what it could read. An edit report in a shape the fold does not recognise used to produce "No file changes in this chat", the opposite of what the harness reported. Its headline also counted lines from reports that never landed; those are named beside the counts now.
- Pairing counts down honestly. The code's clock rounded to the nearest second, so it read "Expired" with half a second still working, and "1:00" for fifty-nine seconds. It rounds up, and a phone list that could not be read says so instead of reading as empty.
- A signed-out agent says where to sign in. In the harness manager the row showed the state and, on onboarding, no way to act on it.
- An endpoint's address is printed without the credentials in it. A URL pasted with a user and secret in it validated fine and was rendered in the clear beside a masked key field.
- Privacy mode covers the settings search. An archived chat's title was blurred in the list and readable in the search results one tab over.
- Compact density says what it covers. It pulls in the settings, list and sidebar rows; the transcript keeps its spacing.
- A refused archive write says so. Restore left the row where it was with nothing said while the toggles in the same pane reported the identical refusal.
- Two projects that read the same name say which folder they are, a project whose folder is gone is drawn as what it is, and a project list that failed to load no longer reads as a machine with no projects.
- The phone's own screen stops addressing a desktop user, its device card looks openable without a hover, and a failed account read says the Cloud did not answer instead of checking for ever.
The shell, the keyboard and the one dropdown
- Escape in a field outside the chat stops interrupting the turn. Clearing the sidebar's search with Escape also aborted the running turn the sidebar was showing.
- A dialog hands the keyboard to the control you actually pressed, and to a defined place when that control is gone, never to the body.
- The dropdown keeps its keyboard, its press and its place. Closing a picker lost focus to the top of the document, one press could dismiss the picker and the dialog behind it, and a menu open while the window shrank hung past the edge.
- A mode switch no longer leaves the other mode's chat in the pane, and the review over a chat follows the chat you are looking at rather than the primary pane's.
- An install keeps its answer. Closing the harness manager mid-install threw the daemon's failure away, and every other Install button went dead with no reason on screen.
The client and the data loop
- A timeout carries a status, an install has a ceiling again (ten minutes plus a second, so the daemon always answers first), and a success whose body could not be read is an error rather than an empty answer.
- Pointing the console at another daemon no longer keeps the old one's chats, and the poll beat waits for the boot before it owns the lists.
- The fold cursor moves only past an event the timeline took. A throw used to consume its own event, and now a payload it cannot read becomes an announced gap rather than a pane that redials for ever.
- A poll beat older than the newest folded event no longer puts the old answer back. The gate uses the daemon's own event stamp, so a finished turn cannot flicker to running and an error line cannot vanish for a beat.
openremote-daemon --helpanswers the usage and exits 0 instead of "unknown command" and 2.
The gate itself
The DOM smoke grew to 22 checks with no skips and now clears a leftover overlay or split with a note, presses a row only where it is on screen, and presses the row menu's mark item. A test that assumed an LF checkout now holds on Windows too.
Known
- The daemon workspace's
cargo fmt --all --checkand three clippy lints stay red on the committed tree: they are in files carrying uncommitted work, and the repair is onecargo fmtplus three small edits once that work lands. - An installed app still does not look for a newer version. Moving to a newer release means running a newer installer over it, or
openremote --updateif you installed through npm.
OpenRemote 0.4.2
A machine-side CLI that says what it knows, a console that says why a rule cannot run, and a second way in for people who live in a terminal.
OpenRemote is one window for the agent harnesses on your computer - Claude Code, Codex, grok, pi, opencode, agy. Most of what changed here is small and honest rather than new: places where a command or a pane answered a question it had not actually asked.
Install from a terminal
npm install -g @morewebs/openremote, thenopenremote. No installer to download. The first run fetches the prebuilt desktop app once (about 28MB), checks both binaries against the release's own checksums, keeps them under%LOCALAPPDATA%\moreweb\openremote\<release>\, and starts the console. Later runs need no network at all.openremote --updatemoves to a newer release,--versionsays which one is cached,--whereprints the path it would start. Windows x64 for now; on macOS and Linux it says so and points at the release page. A release that was built without the portable pair reports where to get the installer instead of downloading something half-right.
The machine-side CLI says what it knows
- A flag where a code belongs is refused, not sent.
openremote-daemon enroll --data-dir /srv/openremoteused to hand--data-dirto the registry as the pairing code, so the first thing a person met was "that code is not valid" - and the sensible next step was to mint another code for a flag. It now names the flag, prints the one usage line, and exits 2. The same extraction caughtenroll --data-dir /srv/x, which the arity check had counted as an extra code. - An expired install code says so. A mistyped or expired code answered with the wire token (
invalid_code) or the generic refusal. It now reads: "That code is not valid. Codes are single use and expire after five minutes; mint a new one from the machine list." When the registry sends its own sentence, that sentence is kept; an unknown failure still carries its HTTP status so it can be identified. statusstopped claiming reachability it never measured. The line came from a record the last daemon left behind, so a healthy machine would print "Connecting to OpenRemote Cloud." for ever, and "Reachable" could never print at all. The one state the files do hold - a credential the registry refused - is still printed, because signing in again is the only way back; everything else is silence. Asking a daemon that is actually running whether the relay is blocked is a follow-up, not something this command can guess.agent --data-dir /srv/openremoteno longer runs against the default folder. A command that takes no arguments refuses one, names it back, prints the one usage line and exits 2 - which is what a unit file written the obvious way needed to hear.
The console
- A rule that cannot run says why, and the list agrees with the palette. A rule whose machine left the account was still offered Run now in the list while Ctrl+K refused to offer it at all, and its machine was named by a raw id. One predicate answers for both now, with a title per reason ("The machine this rule ran on is no longer in your account", "Its machine has not come online yet") and a row that says what the machine is.
- Editing a rule no longer moves it. When the saved machine was not in the online list, the editor seeded its picker from the first online one, so changing a schedule silently rewrote where the rule runs. The saved machine is kept and shown as offline; a machine that has left the account turns Save off with a line saying where to go instead.
- A chat called "Settings" is the chat. Ctrl+K broke every tie by insertion order, and every action is inserted before every chat, so a chat with its own name lost to the Settings view and Enter opened the view. A tie now prefers the label that begins with the query, then a chat over an action, then the order the rows came in - and only when two rows scored exactly the same.
- A dropped stream says it is reconnecting. A stream that drops is retried with a backoff that grows to half a minute, and nothing outside the stream knew: the transcript stopped while the status still said running. The pane header says the word quietly after the title, and the sidebar row's tooltip repeats it.
- Restoring a saved layout asks first, naming how many panes close and that the chats themselves stay in the sidebar - and asks nothing when the window is empty, when the shape is already on screen, or when the shape cannot open at all. A shape saved in a wide window also came back as slivers in a narrow one; it is fitted to the window it lands in now, every pane held at a readable width.
- Search finds a chat inside a folded project. A chat in a folded project could not be found from the sidebar's own search, because its row only draws while the project is open. A search opens the projects it matches and folds them back when the query is cleared, and a folded project is remembered across restarts.
- A capped group says it is capped. The palette stopped at eight rows per group and said nothing, so a query matching nine hid the ninth. A cut group now ends with "and N more" over "Refine the search to narrow it".
- Discover and the endpoint pane say a failed read failed. "No plugins found" and "the refresh failed" were the same screen, and the endpoint pane could say "No custom endpoints yet" over a poll that never answered. Both say what happened, in the pane's own error style, with a Try again that runs the same call.
- Three chats waiting ask at once instead of one after another, so the waiting lines arrive together and a failed ask costs only its own line.
Known
- An installed app still does not look for a newer version. Moving to a newer release means running a newer installer over it, or
openremote --updateif you installed through npm.
Installing this
The installers are unsigned by decision, so Windows shows SmartScreen the first time: More info, then Run anyway. On macOS, right-click the app and choose Open. Android refuses an update whose version code does not exceed the one installed; this build's code is higher.
Linux gets both an AppImage, which runs anywhere, and a .deb for Debian and Ubuntu. Windows gets the same app twice, as a setup .exe and an .msi, for whichever your machine prefers. The Android file is the one APK, listed under both its version-free and versioned names. The daemon download, SHA256SUMS and the third-party notices are for servers, not desktops.
If you would rather not run an installer at all, npm install -g @morewebs/openremote puts an openremote command in your terminal that does the same job.
Upgrading keeps your chats, your settings and any paired phone.
No account is needed for Local mode: chats, harnesses, plugins and rules all run on this computer, and nothing about them is sent anywhere. Cloud mode is the part that talks to a relay, and it runs only if you sign in to it. If you find something wrong, the issue tracker is the fastest way to tell us.
OpenRemote 0.4.1
A console that admits what it does not know, a browser pane with real tabs, and a first day that works.
OpenRemote is one window for the agent harnesses on your computer - Claude Code, Codex, grok, pi, opencode, agy - and this release is the trust pass: every list, button and failure now says what is true.
The console feels different
- A list that has not answered is not an empty list. Chats, projects and devices say they are reading until the daemon replies. The sidebar no longer announces "No chats yet" over a request it has not made, and an unanswered device list no longer reads as an empty account.
- What a destructive press takes is on the button. "Remove it and its key", "Remove it and its schedule", "Remove it and its launch command", and the project row's line: the project goes; its chats move to Chats and the folder on disk is never touched. The safe answer comes first, the second press is the one that acts, and only one removal runs at a time.
- The app quotes what it does not know. A harness's failure reads in its own words; a daemon that stopped answering is named with its last words, and the row offers a Restart where this build can start one; a daemon that is still booting is not reported as a dead one. The same failure reads the same way on every screen.
- Ready means ready. The daemon announces itself when it can answer, not when it has bound a port, so a cold start no longer reads as a dead daemon.
- The keyboard is one layer at a time. Esc closes the dialog on top and nothing beneath it, a dialog holds the keyboard while it is open and hands it back to the control that opened it, and a picker opened from the keyboard lands back on its trigger. The sidebar is one Tab stop, with the arrows moving between chats and Home and End going to the ends. Right-click works in a text field again.
- Privacy mode covers what you typed. A name you entered yourself is veiled like everything else, and no Settings row disappears because privacy is on.
New
- Tabs in the browser pane. Ctrl+T opens one, Ctrl+W closes the active one, Ctrl+Shift+T reopens the last closed (five deep), and the tab's menu closes the others or everything to the right. The strip draws whole tabs only, with the rest behind one control that says how many, and Ctrl+K lists the open tabs and reopens a closed one.
- The pane header says which chat it holds, with the saved layouts a menu away from it.
- Copy a chat as Markdown from Ctrl+K: who spoke, what each tool ran, and how each decision was answered, with a long tool output capped and marked as shortened.
- Run a rule from the palette, without opening Automations first.
- The project line says what it holds: each project's head carries how many chats it has, and shows when one of them is unread.
- Saved setups. New chat keeps a chip for each saved setup, one of them the default, and a preset keeps only the model, effort and approval word its harness still offers, saying what it could not bring.
- Unread, and one page for what moved. A chat you have not read lifts one quiet step; Ctrl+K lists what moved while you were away and marks it all read in one press.
- One prompt, every harness. A race sends the same prompt to two to four harnesses at once, one per pane, and refuses before creating anything when there are not enough harnesses or free panes.
- Stop everything, and stop one harness. One action ends every running chat after naming them, another stops one harness's chats, and a chat on another computer is named and skipped rather than failed.
- A waiting chat says what it is waiting for, under its title in the Needs you group, read-only. Archiving a chat offers Undo for eight seconds.
- Changes in this chat gathers every file a harness reported changing, folded by path, with a diff and a note that it is what the harness reported rather than a git diff.
- A chat can become a recurring job, a chat can be renamed from wherever it is, and a pane layout can be named and restored later.
- A first day that works. A computer with no agent installed is offered the installer during setup, empty states say what the thing is for, and the window fits the screen it opens on, remembers the size you chose, and centres itself when a monitor it last opened on is gone.
Fixed
- The daemon row says which state the daemon is in and offers the control that exists, instead of a disabled dash where a button should be.
- Settings rows that remove something put the safe answer first, and say on the button what goes with the record.
- Privacy mode no longer hides Settings rows, and veils a name you typed.
- The sidebar and the command palette stop redoing work the poll did not change, so a large chat list and a long transcript cost the window less on every beat.
- A permission word survives a harness switch, and a preset stops promising a mode the harness lost.
- Restart waits for the old daemon to stop, keeping its last words for the failure row, and a maximized window no longer stores the screen's size as the size to restore to.
- A synced chat deleted from another device is no longer removed while its harness is still running: the row stays, the failure is logged, and the delete retries on the next sync beat. A sign-in that could not clean up the previous account's copies stops before saying you are signed in, and leaving Cloud exits with the answer the account gave.
Known
- A very long streaming turn still copies its transcript on every token. That is the next performance pass; nothing is wrong with the data.
Installing this
The installers are unsigned by decision, so Windows shows SmartScreen the first time: More info, then Run anyway. On macOS, right-click the app and choose Open. Android refuses an update whose version code does not exceed the one installed; this build's code is higher.
Linux gets both an AppImage, which runs anywhere, and a .deb for Debian and Ubuntu. Windows gets the same app twice, as a setup .exe and an .msi, for whichever your machine prefers. The Android file is the one APK, listed under both its version-free and versioned names. The daemon download, SHA256SUMS and the third-party notices are for servers, not desktops.
Upgrading keeps your chats, your settings and any paired phone.
No account is needed for Local mode: chats, harnesses, plugins and rules all run on this computer, and nothing about them is sent anywhere. Cloud mode is the part that talks to a relay, and it runs only if you sign in to it. If you find something wrong, the issue tracker is the fastest way to tell us.
OpenRemote 0.4.0
A browser beside the chat, a real plugin store, and a phone that pairs by pointing a camera at the screen.
OpenRemote is one window for the agent harnesses on your computer - Claude Code, Codex, grok, pi, opencode, agy - running side by side. The daemon and the console only talk to each other on 127.0.0.1. Local chats never leave the machine, there is no telemetry, and nothing here needs an account.
This release is mostly about places to be. A chat can now open a web page next to itself, the Plugins page grew a store, and the Mobile screen can hand a chat to a phone without a sign-in of any kind.
A page next to the chat
Split a chat to the right and the pane is a real browser, not a preview of one.
- Tabs, an address bar that also searches, back and forward, and reload.
- Select this element puts the page into a picking mode: hover highlights, a click takes the element's CSS selector, its kind and its own words, and drops them into the composer as text the agent can read.
- Console menus, dialogs and the command palette always stay visible over the page, even though the page is a native view drawn above everything else.
- A page cannot start a download on its own. The attempt is listed in the console's downloads and nothing is written to your disk unless you go ask a browser that prompts.
- Talking to the page never opens a debugging port, so nothing else on the machine can attach to the built-in browser. A page that stops answering costs one failed call, not the pane - while an element pick waits as long as you need, because how long you take to choose is yours.
Pair a phone with a camera, no account
Scan the code on the Mobile screen and the phone is paired. That is the whole setup.
- The code is eight characters from an alphabet with no look-alikes, so it can be read out loud or typed by hand if the camera will not focus. It lives for five minutes, five wrong guesses burn it, and 40 bits of it are random. The socket it opens is this computer's own LAN address on one of six fixed ports, and it closes when no code is live and no phone is paired.
- The owner token never appears in the code, in the page, in an answer, or in a log line. The phone gets its own token, kept here as a SHA-256 digest in an owner-only file, and exactly one route accepts it.
- The page a phone loads has no external assets and no network off its own origin, and it can ask exactly one thing: a read-only summary of what this computer has installed and which chats are recent.
- It is plain HTTP on your own network, which both screens say out loud. The first pairing asks your firewall for permission, once.
- Pairing works while Cloud says you are signed out, because it has nothing to do with the account.
Plugins became a store
Discover lists real marketplaces, and a marketplace is Claude Code's own catalog read exactly as it is, so any catalog that works in Claude Code works here.
- One file,
.claude-plugin/marketplace.json. OpenRemote's extra facts about an entry - its runtime, the powers it asks for - ride in a field Claude Code ignores. - Catalogs are cached after the first fetch, so Discover works offline against the last refresh.
- Nothing installs from a listing. An entry resolves to a fetch, and the install still goes through the same review screen that names the runtime and spells out each power in plain words.
- MCP servers on this computer are listed where the plugins are, with the same care about what a server is allowed to do.
Three new screens
- Account shows who is signed in, what the device keys are, and what another device on the account can ask this computer to do - the honest version, not a promise.
- Mobile is both halves of the phone story in one place: pair by code, or sign in and drive a machine.
- Metrics is the console's own numbers, measured rather than estimated.
Find anything from the keyboard
- A command palette (Ctrl+K, Cmd+K on a Mac) that reaches every view, every chat and every setting.
- A shortcut sheet (Ctrl+/) listing what the keyboard can do. Both keys are rebindable.
- Settings gained a search field, so a setting can be typed instead of hunted.
- In a chat,
@suggests the files of the workspace the way the chat sees them: what git tracks, plus the untracked files it does not ignore. - Model names carry their maker's mark, taken from the harness's own catalog. An unknown maker shows the name alone rather than a guess.
Esc closes one layer, not the whole stack
Nine dialogs used to listen for the same key, so one press closed everything - and in Manage endpoints it took a half-written rule with it. Now the top layer takes the key and the layer underneath stays open.
The app says what is wrong with the daemon
When the daemon will not start, the window shows the shell's own sentence for why, cleaned up and capped, instead of "connecting" forever. A daemon that dies at boot fails in seconds. A daemon that says nothing is reported as silent.
Stopping a chat stops everything it started
A stopped chat used to leave its helpers running. Ending it now walks the whole tree of processes it created, on Windows and elsewhere, and keeps walking even when a child has rewritten its own identity.
Cloud, told straight
- Leaving Cloud keeps the device recoverable, and a damaged identity says which part is damaged instead of pretending to be healthy.
- A dead credential stops claiming the computer is online.
- The mesh bounds what a peer can make this computer do, and a peer can no longer grow a process here without a limit.
docs/cloud-trust-model.mdis the route-by-route table: what a peer of the same account can ask, what protects you instead, and which rows the tests cannot exercise.
Hardening worth naming
- A prompt leaves the command line: it reaches the harness on stdin or a private file, so it never sits in a process list for other users to read.
- A model name that looks like a command line flag is not treated as one.
- A plugin catalog entry cannot point outside its own folder, and a marketplace URL cannot turn into extra git arguments.
- A tab's name cannot carry a direction override into the window title.
- CI now refuses a release tag whose manifests disagree, whose notes are missing, or whose Android version code does not exceed the last release - and refuses a capability file that widened a tab's scope.
Installing this
The installers are unsigned by decision, so Windows shows SmartScreen the first time: More info, then Run anyway. On macOS, right-click the app and choose Open. Android refuses an update whose version code does not exceed the one installed; this build's code is higher than the last. Linux gets an AppImage, and the machine installer for a headless computer carries a checksum file the install script refuses to ignore.
Upgrading keeps your chats, your settings and any paired phone.
Nothing is sent anywhere by this app. If you find something wrong, the issue tracker is the fastest way to tell us.
OpenRemote 0.3.2
A quiet release: the hardening pass. Nothing new - everything made
stronger, faster to trust, and harder to break.
OpenRemote is one desktop window for the coding-agent harnesses on your
machine - Claude Code, Codex, Grok Build, Pi Agent, OpenCode and
Antigravity - run side by side. A Rust daemon wraps the harness CLIs and
serves the console over localhost; the desktop app ships the daemon
inside, so nothing leaves the machine. No telemetry.
This version is the product of a full audit of the console, the daemon,
the harness drivers, the Cloud mesh, and the build pipeline - every fix
below was found by that audit, implemented, and re-verified by an
independent review.
Answers that arrive, questions that wait
A structured question from Claude Code - the pick-one prompts - was
answered as a denial no matter what you clicked: your choice never
reached the model. It does now, in the harness's own words, end to end.
A chat that keeps its numbers
The running cost and thinking-token totals used to snap back to zero
every couple of seconds. They don't anymore. Tool results also pair
with the right call now - parallel edits no longer swap their outputs.
The console under strain
- A malformed frame no longer derails an event stream; it's skipped
and the stream keeps reading. - Every request the console makes now has a timeout, so a stuck daemon
shows the error banner instead of spinning forever. - A chat deleted on another device no longer keeps an empty pane
retrying its stream. - Big turns - a multi-thousand-line file write, a long streaming reply -
no longer freeze the transcript; long output is capped with a note. - "Reopen: Last view" finally restores the chat you were in, not the
New chat screen.
The daemon under failure
- A harness that crashes at boot fails the chat in seconds, not a
minute of silence. - Stopping a chat drains its last events and closes open decisions
instead of leaving them answerable against a dead process. - Closing the app sweeps the harness processes it started instead of
orphaning them. - On Windows, harness CLIs no longer flash a console window per
prompt. - A corrupt local database is set aside and rebuilt from the session
logs instead of failing every start. - Webhook-triggered automations deduplicate deliveries and cool down,
so a sender's retries no longer open three chats.
Cloud that recovers
- Signing back in after the backend rotates its auth (or after this
device was removed and re-added) actually restarts the encrypted
mesh; before, only a full restart did. - A machine removed from the account can re-enroll with a fresh install
code; before, one refusal locked it out forever. - A dropped network connection mid-sync no longer strands a chat's
replication. - Devices with unusable keys are refetched instead of pinned broken.
The installers and updates
- The Android build's internal version finally advanced: 0.3.2
installs cleanly over 0.3.0 and 0.3.1. (Updating from 0.3.1 was
blocked by a version-code bug in that release; uninstall-first
works, but this is the proper fix.) - The release pipeline preflights before building: version agreement
across every manifest, release notes present, Android version code
strictly higher - mismatches fail in seconds, not after a
half-hour build. - Rebuilds of a re-pushed tag no longer mix assets from two versions.
- The Linux machine installer's daemon download is checksum-verified
against a published SHA256SUMS, as before, now built with a pinned
toolchain.
Also in this release
- Deleting a synced chat from the sidebar, archived-chat management in
Settings (shipped on main since 0.3.1), and a calmer New chat
layout. - CI now compiles and lints the desktop shell itself on every push -
before this pass, its first compile of a change was on a release
runner.
Downloads
| Platform | File |
|---|---|
| Android 8+ | OpenRemote_0.3.2_universal.apk |
| Windows 10+ (x64) | OpenRemote_0.3.2_x64_en-US.msi or OpenRemote_0.3.2_x64-setup.exe |
| Linux (x64) | OpenRemote_0.3.2_amd64.AppImage or OpenRemote_0.3.2_amd64.deb |
| Linux machine (the install command) | openremote-daemon-linux-x86_64 |
Install
- Android: open the APK and let it install. Updating from 0.3.1
may require uninstalling first (see above); 0.3.2 and later update
normally. - Windows: run the installer. The daemon starts with the app; the
token handshake is automatic. If you had 0.3.1 running, the new
daemon replaces it on next start. - Linux:
chmod +xthe AppImage and run it, or install the.deb.
Machines enrolled via the install command pick the new daemon on
their nextopenremote-daemonupdate or a re-run of the install
command.
What's next
Multiple folders per project, the plugin marketplace, and the tablet
fit.