New features
- Delete account erases your Ovis account, in the apps or app.ovis.sh.
- The relay tab lists your account's other PCs to connect or add.
- Settings → Appearance imports a theme from a Base16 color file.
- GJC and omp suggest your next prompt as grey text in Chat.
- An ovis command adds this PC to your account from its terminal.
Improvements
- A split pane has a Close button in its top-right corner.
- The desktop app tells you as soon as an update is ready.
- The PC's CPU, memory and disk show in the status bar by default.
- On a phone, the header is calmer, with one Chat/Terminal button.
- An HTML page in the file viewer runs scripts only when you ask.
Bug fixes
- herdr-core terminals keep your login shell's sign-ins and colour.
- Korean and other input-method typing keeps up in the terminal again.
- A chat message is no longer typed into one of Codex's own screens.
- Ctrl+Backspace in the terminal deletes the word before the cursor.
- A Claude subagent's report shows in its task card in Chat again.
Full changelog
These notes are long: Settings in an install of 0.5.2 or earlier shows only their start. Read
them all in CHANGELOG.md.
Added
- Delete account: in the phone apps and app.ovis.sh (Devices → Account) and in the desktop app
(Settings → Devices and PCs → Account), Delete account erases your
Ovis account and everything the account service keeps for it, at once and for good. The button
asks once and says what goes and what stays first: devices stay paired with your PCs until you
revoke them there, and a subscription that still renews has to be cancelled before the account
can go. A PC's page opened in a browser says where to delete instead.
(#3635) - The chat's message box offers the prompt GJC or omp suggests next (GJC's
promptSuggestions,
omp'scomposer.predictions) as grey text, as it does for Claude Code: Tab, or the Suggestion
chip on a touch screen, puts it into the box. A suggestion the agent cut short at its input box's
edge is not offered.
(#3540 by @najy97) - The installer puts an
oviscommand in~/.local/bin(Linux and macOS):ovis addadds the PC to
your Ovis account from its terminal,ovis pairshows a pairing code andovis statussays whether
the app runs. It finds the installed Ovis each time it runs, so updates need no new command, and
on a plugin first installed beforeovis addexisted it runs the release that Settings → Updates
installed for that plugin and port, found with the plugin's ownenvand.envsettings. Anovis
of your own in~/.local/binis never replaced, and none is written where it would take the name of
anotherovison your PATH; one that comes first there keeps the name until~/.local/binis put
before it.
(#3542) curl -fsSL https://ovis.sh/install.sh | sh -s -- --add(orOVIS_ADD=1) ends the install by adding
the PC to your account at the terminal; without a terminal to answer at, or while the app is not
running yet, the installer prints the command to run. Its last lines now nameovis add, and say to setOVIS_TOKENfirst on a PC other
people log in to.
(#3542)- A PC whose relay pass allows no new device sessions (account limits) now tells the relay of a new
device that pairs with it, so the relay closes that device4403while passes are enforced: no
device is made, the pairing code is not spent, and no failed pairing is counted. Devices the PC
already knows sign in as before, one of them that pairs again with the key it saved is not
refused, and a client that has not paired learns nothing of the limit. The relay'ssyncnow
also says its pass mode (relay_pass.mode), andGET /api/relaysays whether the relay enforces
passes now (pass.enforced).
(#3516) - The PC shows "This account has reached its relay data limit for new connections" whenever it
refuses new devices, also on a relay that enforces passes without naming a date.
(#3516) - Add a connection → Ovis relay lists your account's other PCs, as the SSH tab lists its PCs: Connect
opens one already in this app, and Add pairs this PC with another through the relay once a device of
your account approves it by picking the digits this PC shows. That PC adds this one as a plain paired
device, not an account member, and nothing is signed for the account. An older or offline PC says so.
(#3642) - Settings → Devices and PCs → Add a connection → Ovis relay now has "Add with a QR code" on a PC
that is in no account, whether or not the page is signed in: press Show the QR code and scan it
with a device that is signed in to your Ovis account, and the PC joins that account with no
number to type and no approval on the PC. The code is made only on that press, is shown as a QR
code alone with no code to type, and is ended when the dialog closes, another tab opens, the
page is reloaded or closed, the page was hidden for a minute, or after 30 minutes. The dialog
then says which account the PC joined, whether it is the one this browser is signed in to, and
which device of that account added it, with "Not me: revoke every device", which comes first
unless the account is this browser's own; any other device that paired meanwhile is named and
asked about, with "Not me: remove it" first, and the notice cannot be closed while one is
unanswered. A notice that was not answered comes back the next time Devices and PCs is opened.
(#3551) - A PC that is already in an account shows no QR code there and makes no code for one: the tab
says which account the PC is in and to sign in to that account on the device and open the PC
there (a device the PC does not know yet is approved once, by picking its number on a device
that is already a member of the PC). A QR code that is up when the PC joins an account is taken
back and leaves the screen.
(#3551) - Settings → Devices and PCs on a PC's own page says where a browser opens the account's other PCs
(one link to app.ovis.sh under them), and a PC the account has not heard from for two days has
Remove from list, behind a confirm that says it revokes nothing and that the PC is listed again
if it is used again. An account with no PC says so, and that each way of signing in is a separate
Ovis account until they are linked.
(#3546) - Settings → Appearance → Theme file imports a theme from a file of colors: a Base16 scheme as its
projects publish it (YAML or JSON), or one JSON file with a dark and a light side. Only colors
are read from a file, never code or CSS. Ovis derives every color it draws from the sixteen and
holds them to the contrast floors of its own themes, so text stays readable and a selected row
stays visible whatever the file says. An imported theme is a card beside the built-in ones, is
shared with the other devices of the PC, and is drawn from the first frame. Importing a file
again replaces the held theme of the same name and sides, so an edited file does not pile up
copies. Dark or light is told by the colors the file writes, not by what it calls them, and a
JSON file that does not parse is said to be invalid JSON. docs/themes.md
describes the file.
(#3547)
Changed
- Signing in on a PC with Sign in and add this PC (Settings → Devices and PCs → Account, the
first-run welcome) now adds that PC to the account in the same step: it lists itself and waits
for one of your devices to add it, with no second "Add this PC to my account" press. Only a
button that says it adds the PC does: a plain "Sign in", a provider's own button and the desktop
app's sign-in add nothing and keep the "Add this PC to my account" button, as does a sign-in
that was already there. With the relay off, one button, "Turn on the relay and add this PC",
does both; the relay is never turned on without a press. The PC is listed only under the
account that just signed in; a listing that gets no answer within a minute, or whose screen is
closed, is dropped, its pairing window is closed, and the button comes back.
(#3584) - Stop waiting on the add-this-PC screen now closes the PC's pairing window at once instead of
letting it run out. The PC has one pairing window, so this also ends a phone pairing in
progress through "Copy a link without a code".
(#3584) - A device that only watches a PC is no longer shown the "Add this PC to my account" button, which
it could not use.
(#3584) - An agent's row in the sidebar no longer spends its title on the agent's name: one whose title was
only "Claude Code" (or another agent's name) is titled by its workspace instead, and the line does
not repeat the name beside the agent's mark. A label you gave the pane is kept as it is, the
tooltip still says the agent's own title, and a screen reader still hears which agent it is.
With Group agents by state, Within a state: Name orders the rows by the title each one shows.
(#3525) ovis add --approve(alsologinandlink) andpair --approveno longer ask y/N about a
device that wants in. The question shows the device's six digits and asks for them: typing all six
(with or without the space) or the last three approves that request, and Enter by itself declines
it. An answer so names the request it is for: a line begun for another request, or typed ahead,
approves nothing.
(#3581)bun scripts/plugin.ts addandloginnow runlink, the terminal command that signs a PC with
no screen in and adds it to your account. While it waits it reopens its approval window every 30
seconds and waits for an Ovis server that restarts instead of ending the sign-in, so a restart no
longer leaves the window closed for up to nine minutes. It stops by itself after 30 minutes, also
with a request left unanswered, and asks again about a request whose answer did not reach the
server.
(#3539)ovis add(alsologinandlink) now ends in one QR code: after the sign-in, scan it with a
device that is signed in to the same Ovis account (or type its code at app.ovis.sh) and the PC
joins the account, with no Add to press, no digits to compare and nothing to answer in the
terminal. The code is a key to the PC, so it is drawn only on a terminal (--printwrites it
anyway), on the terminal's other screen, which the command leaves when a device paired, when
the run stops and on Ctrl+C (a terminal without such a screen, or a recording of the session,
keeps the drawing of a code that no longer works). It is taken back when the run ends, however
it does short of the process being killed, and comes three codes at most (about 30 minutes).
The command then says which account the PC joined and which of that account's devices added
it. A device that got in with the code without being in that account is asked about, and only
the word keep keeps it: anything else, no answer, Ctrl+C, the terminal closing or an error
removes it (a line that comes within a second and a half of the question, and the first line
after the question changed, answer nothing and it is asked again). When the PC ended in another
account than the one that signed in, every device that came since the code was shown is removed
without a question, and the command fails. When the PC's devices cannot be read as the run
ends, the command says that one may still be paired and where to revoke it.ovis add --approvekeeps the earlier way: the adding device's request is approved in the terminal by
typing its six digits.
(#3586)- The desktop app now tells you when an update is ready instead of waiting for you to open the
tray menu: one system notification per version ("Ovis X.Y.Z is ready"), whose click opens the
window, and a line in the window with the same Restart to Update as the tray. The line can be
closed for that version, and the connection screen shows it too, so an app whose server cannot
start still offers its update.
(#3549) - The desktop app checks for an update every hour instead of every 6 hours, and no longer
downloads again a version it already holds.
(#3549) - The move to herdr-core says before it starts that each pane opens a new shell from your login
profile, so variables set by hand in a pane stay behind.
(#3652) - An HTML file opened in the file viewer is drawn without its scripts until you press Run
scripts above it; its HTML and CSS still show. A page's script could reach other hosts over
WebRTC and take the keyboard from the app, so it now runs only when you ask. Beside the pane, a
page whose script takes the keyboard anyway has its scripts turned off again.
(#3607) - A split pane's header ends with Close pane in its top-right corner, Zoom pane just left of it.
It closes as the pane menu's Close pane does, asking first for a working or blocked agent or
the workspace's last pane.
(#3641) - The selected PC's CPU, memory and fullest disk now show in the status bar by default. Turn them
off for a device in Settings → Devices and PCs → More settings → PC load in the status bar.
(#3532) - On a phone the header is calmer: it no longer counts the running and finished sessions beside More
(the workspace list still shows each one, and More keeps its dot for a session waiting for you), and
Chat / Terminal is one button that switches to the other view instead of a two-option switch.
(#3674) - A message the PC held for a reason of its own (a lost connection, a turn that never started, a
send it refused) keeps Send now only while the PC can still confirm that nothing was typed:
on its own live connection, or once the same browser reconnects, reloads or shows it in another
tab within ten minutes of losing the connection. Past those ten minutes, after this server or
the PC's server restarts or updates, and on a remote PC that runs an older version, it now shows
"Not confirmed. Check the terminal before sending again." with Copy and Discard, where it used
to keep Send now. A message you held yourself (Alt+Enter, or any follow-up with automatic
sending off) is not affected: it stays held until its Send now.
(#3173) - Settings → Devices and PCs shows the Account group at the top of the page instead of inside More
settings, so the sign-in the relay depends on is in view.
(#3546) - Terminal mode no longer draws an accent outline around the terminal while it has the keyboard
focus, as before 0.5.2; the current pane's title still marks where keys go.
(#3664)
Fixed
- A PC waiting to be added to your account keeps its pairing window open: it reopens every 30
seconds and when you return to the tab, so an Ovis restart no longer refuses the other device
for up to nine minutes. The screen resumes waiting after a reload, says "This PC is in your
account" by itself once a device added it (and that your other devices can open it only once
that device has let them in), stops after 30 minutes with a Keep waiting button, and names any
signed-in device (not only a phone) and the six digits it will show.
(#3544) - A device you just approved on one PC no longer waits up to five minutes for your account's other
PCs: a PC now reads its account mailbox when a sign-in fails, at most once a minute, and lets the
device in when its approval is there. A device that asks before its approval arrived may still be
told to try again for up to a minute.
(#3537) - An agy or grok pane waiting on a background task or timer no longer reads DONE and alerts, then
reads BG again, when one lookup of its session fails: the wait is dropped only when the next
lookup, ten seconds later, fails too. A pane whose session cannot be found is no longer looked up
on every refresh: only every ten seconds, and when its status changes.
(#3572) - An Antigravity pane no longer counts another process's background tasks, or shows the greeting
of a new conversation, when its agent exits and that process number is reused while Ovis looks
its conversation up: the pane's process is asked of herdr a second time before its locks are
read, and the answer stands only when it is still the same process once they are.
(#3573) - An Agy reply that a background task, timer or subagent wakes after it finished is a turn of its
own, with its own times, instead of joining the reply before it.
(#3472 by @jimbb) - In the Android app, a link to another server on the PC's own host (a dev server on another
port, such ashttps://pc.example.ts.net:7231) now opens in the phone's browser instead of
replacing Ovis inside the app, where there was no way back.
(#3626 by @mdobro) - Opening a tool's row, or pressing "Show all" on a long output, at the end of a chat no longer
scrolls you past what you opened now and then. It happened when the click came within a tenth of
a second of the chat moving to its end (Jump to latest, or an answer still being written): the
list was still keeping the end in view, so the lines you had just opened were scrolled past to
the new end.
(#3622) - Going to the end of a long chat (dragging the scrollbar there, or End) no longer jumps back now and
then to where you were reading. It happened when a row was still being measured in that moment,
such as a long output you had just unfolded drawing its lines: the chat's list moved the view back
to where it had last seen it.
(#3650) - Claude chat: a background subagent's report shows in its "Background task ended" card again,
rendered as Markdown. Claude Code now sends it back as a separate message, which the chat showed
as raw text while the card only said where the report went.
(#3660) ovis add --approve(alsologinandlink) no longer takes a line typed ahead as the answer to
a device that asks to join: only a line typed after a request's question and its six digits showed
answers it. A line typed during the sign-in, while nothing was asked, twice at one question, or
within a second and a half of a question showing (a key pressed twice) is dropped with a line
saying so. So is the first line that comes after a request left the screen unanswered, whenever it
comes: the terminal may still hold what was typed for that request, and the question is asked
again.
(#3581)ovis add --approverun without a terminal (yes | ovis add --approve, a pipe, a file,ssh
without-t) approves nothing, whenever its lines come: it says so, names the way out and declines every request. It
also says so when the terminal's input ends (Ctrl+D), and stops at once when reading the
terminal fails.
(#3581)ovis addopens its last approval window and lists the PC anew in time when the PC's server
answers slowly near the end of the run, and puts the PC back in the account's list while the
account's other devices are still being brought in.
(#3581)linkno longer reports "This PC is in your account" before that is true: it waits until the
account's other devices are brought in, names the account, and fails with what to do when the PC
ended in another account than the one that signed in. Run again while those devices are still
coming in, it waits for them rather than reporting the PC as done.
(#3539)- A chat message is no longer typed into one of Codex's own screens: the
/model,/permissions,
/review,/theme,/resumeand/experimentallists,/rename's field, the/statusline
and/keymapeditors, the agents view, the/diffpager, Find and the search through earlier
prompts. herdr reports Codex at rest while one is open, so the message was pasted into it and its
Enter took the row under the cursor: it could change the permission mode, trust a folder, or
save a model for every new session. The message now stays in the box until the screen is closed
in the terminal, and a queued one is held with that reason until you send it.
(#3103, reported by @nocstah)
(#3612) - Codex at Ultra reasoning effort marks its composer
»: a new pane's chat now opens empty instead
of "Conversation unavailable", its first answer shows, and the notice that a command's screen is
still open in the terminal works there. (#3103,
reported by @nocstah)
(#3612) - A Codex pane herdr reports no thread for no longer stays on "Conversation unavailable" in three
cases: its last answer is longer than the screen or holds a code block, its last answer is a
short word such as "ok", or a second Codex has just started in its folder and was asked nothing
yet. Chat shows the conversation while that finished turn is on screen, and the terminal again
while the pane works on its next turn. It still shows the terminal whenever the screen could be
another conversation's: a prompt or a tool's output that quotes one, two conversations that
ended on the same text or were asked the same prompt, or, for a long answer, another Codex
conversation with a turn under way. All three cases need the list of conversations Codex has
loaded, which cannot be read on Windows: there they stay on the terminal.
(#3558,
#3559,
#3560 by @vibewriter-hand)
(#3582) - A Codex visualization reference in a chat answer is drawn as a card with the file's name and
Open preview, which opens the file in the file viewer, instead of raw reference text.
(#3450 by @cheol-95) - The desktop app on the beta update channel is offered beta builds on Linux and Mac. Each commit
on main whose checks passed was built for it, but the builds were never uploaded, so the app
found no beta feed and stayed on the release it had.
(#3554) - Restart to Update in the desktop app no longer leaves Ovis with its server stopped and nothing
installed. A downloaded update whose file is gone (a newer download that failed removed it) is
no longer offered and is downloaded again at the next check; on a Mac the update is offered
only once the system's updater holds it; an AppImage in a folder it cannot write does not
offer updates it could not install; and an install that fails at once starts Ovis again.
(#3549) - A file docked beside the pane takes clicks on Preview, Source and Page over 24px of height
instead of the 18px they are drawn at, so a mouse no longer has to aim at the thin label.
(#3527) - A focused text field or select no longer draws two accent lines, one inside the other: it shows
the focus ring alone and its border keeps its resting colour. This is what a dialog's first field
looked like as it opened (Add PC's SSH field, the palette's search), and it covers the terminal's
input line, a reply comment's field, the prompt card's custom answer and the welcome's two
choices too. A rename field in the sidebar draws its ring inside the field, where the list no
longer cuts its top edge.
(#3556) - On a phone, text fields and selects (the sidebar filter, Settings' choices) follow the interface font
size like the labels beside them instead of staying at 16px. On an iPhone or iPad a field that is
pressed or takes the focus grows to at least 16px and keeps it while it has the focus, so Safari does
not zoom the page into it.
(#3339 by @Noobear)
(#3583) - A grok pane keeps its background-task count, and the hold of a turn that ended on a task, when
herdr names no session for it for a moment: the pane was looked up as another session, not
found, and read as holding nothing for about ten seconds.
(#3598) - A grok session herdr has just named is looked up at once: it waited up to ten seconds when a
lookup of the pane's session before it, or of the pane before herdr named any session, had failed.
(#3598) - With herdr-core, a workspace's menu offers New worktree and Open worktree… on a PC whose git is
older than 2.36, such as Ubuntu 22.04's git 2.34: listing the repository's checkouts failed
there, so neither was offered
(#3478, reported by @datacas).
(#3571) - On herdr-core, terminals Ovis opens (the move from herdr's included) start in your login shell's
environment, in colour, whatever process started the core: a core a coding agent's shell or a
service started no longer turns colour off in every pane (Claude Code drew without highlights)
or leaves out the sign-in tokens your profile exports. Your profile's PATH comes first, followed
by the core's own folders. Ovis reads that environment once when it starts, so a token your
profile changes reaches new panes after Ovis restarts; what the core itself carries is checked
for each new terminal, so a restarted core is followed. Where the core carries aNO_COLORyour
login profile does not set (from whatever started it, environment.d orlaunchctl setenv
included), it is set empty in these panes, which turns colour back on for most tools; tools that
only check whetherNO_COLORexists (consola, used by Vite and Nuxt; colorette; kleur) stay
without colour there until herdr-core lets a variable be removed. Set it in the profile to keep
it. A server whose core already runs no longer waits for the login shell when it starts.
(#3652) - Back and Forward go to the pane of the entry they land on when the app was about to draw a change
at that moment (a pane's status arriving, the New workspace dialog writing its fields to the
address). Before, the press could do nothing, and the entry it landed on was overwritten with the
place just left. Forward off a file that a tab switch had left under it (Reopen files on return)
and a jump back from Settings past the pane it opened over (the browser's Back menu) failed that
way every time.
(#3614) - On Windows,
scripts/plugin.ps1passes a command's flags on (plugin.ps1 link --code) instead of
dropping them.
(#3542) - An iPad home-screen app typed into with a hardware keyboard (iPadOS 26) no longer flashes on every key:
a visual viewport that shrinks for a single frame is not taken for an on-screen keyboard.
(#3341 by @Noobear)
(#3583) - An iPad home-screen app in landscape no longer slides the whole screen up and back when a field takes
the focus: the shell fits the area below the status bar, also at Safari's page zoom.
(#3340 by @Noobear)
(#3583) - On an iPad running iPadOS 26 or later, a home-screen app in a window no longer has the header's first
button under the window's close, minimize and full-screen controls; the header leaves their room,
also at Safari's page zoom. A full-screen app keeps the header as it was.
(#3338 by @Noobear)
(#3583) - Tapping a key on the key bar on Android no longer hides the soft keyboard while it is up.
(#3597 by @mdobro) - Opening the whole output of a Letta Code tool call no longer stalls every other request and
terminal while its transcript is searched: one very long line held the server for seconds. The
search runs on a file thread, one transcript at a time, and reads a long line once instead of
copying it again at every read. While no file thread is free the output answers "try again" (503)
rather than "not found", and a pane that moved to another conversation meanwhile gets no output.
(#3575) - Opening the whole output of a Letta Code tool call answers "try again" (503), not "not found",
when the search of its transcript ran out of time before the end, where the call may still be.
And a pane seen on another conversation while the request made its last check gets no output.
(#3598) - A Mac's PC load in the status bar includes memory: memory in use is read from
vm_statas
Activity Monitor's Memory Used (App Memory, wired and compressed), so the file cache is not counted.
(#3281 by @vibewriter-hand) - A phone's tab list and the pane pickers fill the open tab's and the selected pane's row, as the
sidebar fills the selected workspace and agent, and keep its name in bold.
(#3289 by @hrudek) - New folder requests the mobile keyboard's Done action instead of advancing to the workspace label,
so the existing Enter action can create the folder without an extra control.
(#3678 by @hongho55) - Opening the whole output of an OmO tool call gives no output when the pane was seen on another
session while the request made its last check: the session before's output was answered.
(#3598) - A message the queue sends to an omp that is still starting (a new workspace's first message, a
queued message, Send now) waits until omp takes input, as a message sent at once already did,
for an omp that runs herdr's omp integration. Typed earlier, on a slow start, it stayed in omp's
input box and never ran while its row said sent. Its row says Waiting for omp to start…
meanwhile; a message sent from the chat in that time goes behind it, and once anything is typed in
the terminal (also with its input line) the waiting messages, and the ones sent until omp has
started, are held for you to send, rather than sent together with it.
(#3624) - A new workspace's first message whose pane closed while it was being sent goes with that pane,
instead of turning up, held, in the next pane that got its id.
(#3624) - Stop waiting on Add this PC now also closes a pairing window that a listing given up for getting
no answer opens late, a listing stopped on its way opens no window and reads nothing more, and a
wait begun right after it asks for its window only once that close was answered, so a late close
no longer shuts the new wait's window.
(#3609) - A wait to add a PC that is taken up again (after a reload, or every time it reopens its window)
first reads which PC answers, from a request that opens nothing: an address that now answers for
another PC no longer gets a pairing window opened on it, and is no longer said to be the PC
that was added.
(#3609) - The PC's approval prompt is entered on the prompt itself by Shift+Tab too, not on its buttons, and
a key cannot press Approve for a second after the focus came into the prompt. Its guards now count
to when a key or a click was made, so one already on its way when the prompt arrived or moved
approves nothing on a busy page.
(#3609) - A pairing confirmed for one sign-in no longer adds the PC to another account when the hosted app
reloads itself for a newer build before the PC opens and another sign-in is stored by then: the
PC then opens with the key this device holds and joins no account. That holds over a second
reload too (a reloaded page that is itself reloaded or closed while it connects), also for a
pairing confirmed with a key of the device's own.
(#3609) - A wait to add a PC whose address starts answering for another PC just as it reopens its window
closes the window that request opened on the other PC, instead of leaving it open for up to ten
minutes with no screen waiting.
(#3609) install.sh --adddiscards what was typed in the terminal while the installer worked before its
add step starts, so a line typed ahead no longer answers a device's approval there; where it
cannot be discarded, the installer prints the command to run instead. It starts the add step
only on a release whose add tells a line typed ahead from an answer: on an older one (up to
0.5.2, which asks y/N) it says to update first and prints the command.
(#3609)ovis add --approve(alsologinandlink) andpair --approveask about a device more
carefully. A line that is neither the request's digits nor empty (ayout of habit, a mistyped
digit) no longer declines the request for good: it answers nothing, one line says what approves
and what declines, and the question is asked again; Enter by itself still declines. Three or six
digits that are not the request's are said to be just that, with the hint that the request may be
another device's and that Enter declines it. Full-width digits typed with an input method approve
as the digits they are. A request whose last three digits another request shares (one asked about
earlier in the run, or waiting now) asks for all six, and only all six approve it; one already
asked about with three is asked about again with all six when such a request comes to wait beside
it.
(#3609)ovis add --approveandpair --approveno longer take what was typed before a question as part
of its answer: the terminal's input is discarded as a request's question first shows, and the
first line after an answer that did not reach the PC's server answers nothing. Where the input
cannot be discarded (Windows), the first line after each question answers nothing instead and the
question is asked again. Digits typed before a question showed are discarded with the rest, so
Enter pressed at it then declines: type them once the question shows.
(#3609)pair --approveasks asovis adddoes: a second line sent right behind an answer no longer
answers the next request, a line counts only a second and a half after its question showed,
and input that is not a terminal (printf '456\n' | ovis pair --approve,sshwithout-t)
answers nothing: the command says so and fails, and declines no request, so each keeps
waiting. It reads the waiting requests once more before it sends an approval typed as three
digits, and asks for all six when another request that ends in them has come since. An answer
the PC's server does not take is asked for again instead of ending the command with an error.
(#3609)- The question
ovis addasks about a device its QR code let in discards what was typed before
it showed, and reads the word keep typed full-width as the same word.
(#3609) - A pairing code that someone on the LAN started while nothing was paired no longer pairs a device
after the first one is paired: it ends when the pairing gate closes.
(#3613) - A connection that another machine on the LAN opened while nothing was paired no longer stays able
to type into panes and read them once the first device is paired or the relay is turned on. It is
closed when the pairing gate closes, as that machine's new requests already were refused.
(#3610) - Ovis lets go of OpenCode's event stream within seconds of OpenCode leaving its last pane, even
when herdr says nothing of it (seen on a busy host): herdr may change the pane's agent without an
event, or keep calling it OpenCode with only the shell left in front. A pane that holds the stream
is now read again each time its check is due, and the shell alone in front releases it. On Linux,
the pane's own OpenCode stopped with Ctrl+Z keeps it, also when started through a launcher such as
npx, so a message sent before is still followed afterfg; another OpenCode stopped in the same
shell does not. On macOS, a stopped OpenCode still releases it.
(#3645) - On a 320 px phone in Japanese at the largest interface text size, the alerts notice's Dismiss
button no longer ends up past the right edge of the screen: the button's label wraps onto two
lines instead.
(#3531) - A message queued for a Claude Code pane no longer goes into the turn a
/loopwakeup or another
scheduled task just resumed: for up to a minute after the wakeup it waits for that turn to end,
whatever herdr reads the pane as meanwhile; after that minute the queue goes by herdr's reading
of the pane again. When such a turn is interrupted before it finishes, the pane's queue can stay
held for up to about a minute after the pane shows as idle; Send now still sends a waiting
message at once. A wakeup that fires while a message is being typed, in the few tenths of a
second between its paste and its Enter, leaves the text in Claude's input line, with the message
marked as not confirmed, instead of sending it into that turn.
(#3574) - A message queued for a Claude Code pane no longer goes into the turn Claude just began by itself
because a background task ended (a subagent, a background command, a monitor or a workflow), once
Claude has written that turn's prompt: for up to a minute after that it waits for the turn to end,
whatever herdr reads the pane as meanwhile, as after a/loopwakeup. A message already waiting
when the turn begins can still go into it if herdr reads the pane as idle before Claude writes
that prompt, as before this change. When such a turn is interrupted, or ends in a session
whose Claude Code writes no end-of-turn entry, the pane's queue can stay held for up to about a
minute after the turn began though the pane shows as idle, and for as long as such turns keep
beginning less than a minute apart; Send now still sends a waiting message at once. A turn that
begins this way while a message is being typed, in the few tenths of a second between its paste
and its Enter, leaves the text in Claude's input line, with the message marked as not confirmed,
instead of sending it into that turn. That can happen to a message that waited behind a turn
during which the task ended, as that turn's end both sends the message and begins the new turn.
(#3629) - A queued follow-up held when the connection drops or reloads before anything is typed now
recovers as Held message — review and send with Send now enabled once the browser
reconnects, instead of staying stuck as "Not confirmed. Check the terminal before sending
again."
(#3173 by @jimbb) - A held message is typed once when herdr moves its pane while one tab's Send now is on its
way: the other tab's copy under the pane's new ID is refused until that send ends, and then
reads as sent.
(#3608) - A held message that a Send now may have typed stays "not confirmed" in another tab for its
whole ten minutes, also after its first connection's record is gone.
(#3608) - A pane that takes the ID of one that ended is no longer offered the ended pane's held message
with Send now.
(#3608) - A held message's Send now in another tab ends with the PC's receipt also when this device's
clock is set back.
(#3608) - A PC waiting to be added to an account keeps its pairing window when its server restarts (an update),
for the rest of the window's ten minutes, instead of refusing the device that then asks. The window
closes on Revoke all, Reset relay identity and turning the relay off, andPOST /api/relay/link/close
closes it on request.
(#3535) - The PC's prompt for a device that adds it to your account now says what to do: type the PC's
number on that device, then press Approve. It used to ask you to compare digits the other device
never shows. Every approval prompt on the PC also shows the seconds left, can be answered by
keyboard while Settings is open (it takes the focus there, on the prompt and not on Approve, and
never from a terminal or a field you are typing in; from a field in Settings, Tab reaches it
after Settings' own controls), and is announced as devices waiting, not phones. Approve ignores
a key or a click that comes right after its prompt arrived, moved up or was given the focus, and
the second click of a double-click, so approving one device never approves the next by accident.
(#3570) - A new phone or browser that the relay turns away because the PC's account is past its relay
limit now says so, and that devices already added still connect, instead of showing a failed
connection.
(#3520) - A PC the Ovis relay already refused for its account now says so over the pane even when the
browser's clock is before the date the relay announced, instead of only the sign-in reminder or
nothing.
(#3579) - A relay pass that follows another within a minute now reaches the relay: the PC sends it once the
relay takes renewals again, instead of at once, when the relay dropped it and kept the older pass
for half a day. A pass that arrived while the PC was still connecting is sent as soon as it has.
(#3516) - Comments waiting on a pane's replies are no longer deleted when its herdr is replaced (a restart, a
runtime switch): Recover unsent text offers them as the message they would have gone with, each
quote followed by its comment.
(#3680) - A Windows PC no longer reads a path on another host's network share for a link or an address that
names one: a Markdown link ([x](//host/share/a.md), also written with backslashes,
percent-encoded or after~/), a tool call's file row, or an Ovis address with?file=,?read=
or a new workspace'scwd=. Opening one asked that host for the file with your sign-in. A share
one of your panes works in or your home folder is on, and WSL's own files (\\wsl$\…,
\\wsl.localhost\…), open as before.
(#3621) - A connection, a watch-only device included, can no longer make the PC run more than 64 of the
processes that draw a watched pane: a watch names its pane by a pane's id, a pane has one such
process at a time, and one connection watches at most 64 panes.
(#3621) - A message of tens of thousands of line breaks followed by a letter no longer stalls the PC's
server, and every terminal with it, while it is refused.
(#3621) - Revoking a device now also ends a pairing code that device started or was handed, and the code
to type bound to it. Before, on a PC in no account, a device could start a code, be revoked, and
the code still paired another device for up to ten minutes.
(#3616) - Searching a conversation that holds a very long line of
[that never close (a pasted log,
minified text) no longer stalls the server. Such a line was read in time that grew with the
square of its length, 36 seconds for 200,000 characters, and every terminal and request waited
until the search was done.
(#3565) - A password asked by
gitover HTTPS (Password for 'https://you@host':), a key passphrase asked
byssh-addorssh-keygen(Enter passphrase for /home/you/.ssh/id_ed25519:) and the password
of an SSH host given as an IPv6 address are masked prompts now, assudo's andssh's already
were: the Password or PIN field takes the input line's place, what is typed is kept out of
drafts, and a queued or inserted message is no longer typed into the prompt. A key whose path has
y/nor a colon in it (/home/andy/notes/key,/keys/id:work) is recognized too. With a PC not
yet updated the field still answers the prompt: its text is typed into the terminal directly.
(#3566) - More password requests are masked prompts: an interactive ssh sign-in (
(you@host) Password:),
doas,sudoin any language and sudo-rs,passwd,mysql, gpg'sPassphrase:and openssl's
Enter PEM pass phrase:.
(#3591) - The Password or PIN field leaves once the program has read its answer, even while its prompt is
still the last text on the screen (git signing in,sudorunning a quiet command): a second Send
there could wait in the terminal and reach the shell. With a PC not yet updated the field says that
what you type goes to the terminal unchecked.
(#3591) - Settings → Devices and PCs no longer says "Needs approval" for every other PC of your account: a
PC's own Settings cannot tell that, so a listed PC now reads "In your account".
(#3524) - Settings: a terminal or chat font size typed in full-width digits (
16, as a Japanese, Korean or
Chinese keyboard can enter them) is taken as the number instead of being refused.
(#3530) - When adding a PC to your account fails in the hosted app, the sheet now says what happened and
what to do, with Try again: a new PC that is no longer waiting says to keep its Account screen
open on it, and a join that nobody approved says to open that PC on a device that already uses
it, or to pair with a QR or code. The join sheet says so before you ask, and a listed PC past
its ten minutes reads "Join · a device of your account connected to it approves" instead of
"Add window closed · an account member must approve".
(#3545) - A signed-in dashboard with no PC now says how to add one: install Ovis on the PC (the macOS or
Linux line and the Windows line each have a Copy button), sign in there with the same provider
account, and choose Add this PC to my account. It also says that GitHub and Google are separate
Ovis accounts until linked (an account signed in with Apple is told a PC signs in with GitHub or
Google only), and Check again re-reads the account's PCs at once instead of waiting for the
next refresh, also when a read was already under way. When the account's PCs could not be read,
the steps are not shown under that notice.
(#3543) - app.ovis.sh opens a PC as soon as it is paired, instead of stopping at a Ready screen with an
Open PC button; that screen now appears only when adding the PC to your account failed, where
it offers Try again. While you are signed in, the PC opens once this device has joined it
under your account (a moment later, or after 15 seconds when the PC is slow to answer), so
that step no longer disconnects a terminal you just opened. A PC paired with a QR or a code
no longer says "Adding it to your account…" for a minute.
(#3555) - When you are signed in and open a pairing link for a PC your account does not list, the
question now reads "Add {name} to your account?", says that every device of your account will
be able to open it, and shows the PC's ID.
(#3555) - A pairing link's question is asked again when what it said stopped being true before you
pressed its button (you signed in or out in another tab, signed in as another account, or the
PC left your account), so a pairing never does more to your account than the screen said.
The question waits for your sign-in and your account's list of PCs instead of guessing, for at
most 8 seconds when either does not answer, and says "Checking your account…" meanwhile. Not
now stops a pairing whose button was already pressed.
(#3555) - A pairing whose question said this device gets a key of its own no longer adds the PC to an
account you signed in to meanwhile when the page reloads for a newer version before the PC
opens. Opening the PC later while signed in adds it to your account, as before.
(#3555) - A split half showing a pane that herdr's own window moved to another workspace follows it to its
new ID even when the roster shows the move before the server's notice of it, instead of closing.
(#3669) - A PC added over SSH with "Use Default session" starts herdr's default session by itself after that
PC restarts also when another herdr session is already running there. Before, it stopped and asked
which session to use.
(#3576) - A PC saved in herdr (
herdr machine) for which "Use Default session" was chosen keeps that choice:
the next refresh of herdr's saved machines, or a restart of this app, no longer ties it to the
default session's socket again, which stopped it at "the herdr session chosen for this PC is no
longer running" after that PC restarted.
(#3576) - Adding a PC over SSH that runs its own Ovis on herdr-core asks which to use in two more cases, both
on a PC where this app's bridge runtime is not installed yet: when that Ovis is an older one that
does not list herdr sessions and the dialog names no session (herdr's default session there is
offered beside it), and when herdr's socket there is only what a stopped herdr left. Before, the
PC was set up as a herdr PC without asking, and in the second case a new herdr was started beside
its Ovis.
(#3576) - Adding a PC over SSH that runs both its own Ovis and herdr sessions no longer says "Connection
failed": the dialog, the PC's card and the line under the header ask which to use, with that
PC's own Ovis first as the main choice, the herdr sessions running beside it after it, and
starting a new herdr last.
(#3636) - On Windows with Git for Windows' ssh (the one Ovis uses when Git is installed), a program that
happens to hold the local tunnel port when Ovis connects to an SSH PC no longer receives that PC's
bridge access token: the connection waits for ssh to report that its own forward is open, and fails
with ssh's own error when the port is taken. With Windows' own OpenSSH, which reports nothing of this
to Ovis, the connection works as before. A program that takes the port on purpose can still share it
with ssh on Windows; that case is not closed yet.
(#3666) - Add a connection → SSH no longer looks empty in an open LAN window, which the PC keeps its list of
known PCs from: one line now says where that list can be seen (on the PC itself, or from a device
paired with it directly).
(#3517) - Korean, and other text typed through an input method, keeps up with fast typing in the terminal
again: the box that shows the syllable being composed measures its glyph once per glyph and font
instead of on every change, which made the browser recalculate the whole page's style several
times per key.
(#3596 by @Kuhave) - A Codex visualization reference with a display mode Ovis does not know is drawn as its card
instead of raw reference text. Each card's Open preview button names its file to a screen
reader, and copying a selection of a card gives the file's name and the title on two lines,
without the button's words.
(#3589) - On a device that only watches, the rows of the composer's background tasks list answer again: a
running task's detail and the fold of ended tasks open however often the pane draws, and so do
the rows of an OMP pane's side conversations list. Since 0.5.2 they stopped answering as soon as
the pane drew again with the list open, and stayed that way.
(#3618) - A Windows PC whose Ovis state folder was migrated connects over SSH again: the bridge's launcher and
the bridge itself no longer go through the migration junction (.config\herdr-web-ui), which a
process an SSH session starts may not traverse, so adding it no longer waits minutes and ends
"Bridge did not start". The bridge's part takes effect with the next remote bundle.
(#3673) - Windows PCs reconnect over SSH after the Ovis state-directory migration, without failing to
write the bridge launcher, start herdr in the desktop session or read startup status through an
untrusted mount point. Registry paths with brackets are treated literally, and the bridge keeps
starting from the user's home directory.
(#3633 by @yeongjo) - After herdr restarts, the sidebar's row menu and the command palette no longer offer New worktree
and Open worktree… for a moment on the earlier herdr's answer, which may be about another folder
under the same workspace ID: the items come back once the new herdr's folder is checked.
(#3578) - A workspace folder whose check for a git repository failed is no longer checked again each time
workspaces change places or its PC is selected, only when the PC's workspaces change, the PC
reconnects or herdr restarts.
(#3578) - A link that opens New workspace with a WSL folder (
\\wsl$\…,\\wsl.localhost\…) fills in that
folder again, instead of leaving it out and showing another one.
(#3671) - On macOS, the first terminal Ovis opens on a herdr-core core that a coding agent started with
herdr-core server startis in colour too: it no longer keeps the agent'sNO_COLOR=1(Claude
Code drew there without colour) while later terminals were already fixed.
(#3688) - Ctrl+Backspace in the terminal deletes the word before the cursor instead of one character: it
sends Ctrl+W, in every program (in vim or nano Ctrl+W keeps its own meaning there). Input held
after a disconnect drops that word too. A pane drawn as a mirror (a Windows PC's) keeps Ctrl+H,
which Windows shells already read as the word erase.
(#3686) - On Windows, Ovis no longer runs an
hcit finds outside your profile folder while it looks for
herdr-core: not one on the PATH in a folder such asC:\tools, which every account on the PC
can write, nor one in Program Files, nor a bareOVIS_HC_BIN=hcfound there. Set
OVIS_HC_BINto the full path of anhckept elsewhere.
(#3687)
Maintenance
- The self-hosted runner's client-build cache keeps each build under the CI run whose job built it,
and a job restores only its own run's. Before, a pull request's run could hand in a build under
the key of a new commit of main ahead of main's own run, and main's Integration and Browser
jobs, and a release validated by that run, would have tested that build. The launcher installed
on every runner host that uses the cache must be updated (copyscripts/self-hosted-runner
again withrsync -a; no restart, which would cancel the jobs in flight); until then no build
is restored there and every job builds.
(#3585) - The runner's build cache takes a build in only from the container whose job handed it in, for a
job that started once that container had: a claim naming the run of the slot's next job, or of a
killed container's job that GitHub still lists as running, is refused, and so is a build an
earlier job left in an outbox that could not be emptied. An old entry that cannot be removed is
moved out of the names jobs read instead of being tried and logged every second.
(#3585) - The Release run no longer runs the whole CI a second time when main's own CI run already passed
the same commit: it takes that run, waiting up to 40 minutes for one still going, and still runs
Fast checks itself, beside that wait and on GitHub's runner, where the unit tests the self-hosted
runner skips run.
It runs the whole CI itself whenever main's run is missing, failed, was rerun more than once or
cannot be read. Its newrevalidateinput runs the whole CI in the Release run as before, and
Actions → Release validation is a dry run of the decision that publishes nothing.
(#3567) - Self-hosted CI runner: each runner slot has a docker network of its own. The runners of a PC
shared one loopback so thatscripts/check.ts's slots, which are loopback ports, bounded the
herdr-backed lanes of all of them, and a job on one slot could reach a server another job's tests
kept there with no token, type into a pane behind it, and so run commands in that job's
container. The slots are now lock files in a volume every runner mounts (CHECK_SLOTS_DIR), held
withflock, with the same limit, queue and holder names. On such a launcher a herdr-backed lane
of a commit from before stops at once and says to take main in. The launcher must be copied and
restarted on each runner PC.
(#3628) - Self-hosted CI runner: the launcher waits two seconds before every container of a slot, the first
after its own start included, so the build cache never takes a job of a container that was killed
with the launcher for the job of the container after it.
(#3628)