Repository navigation
feat(desktop): add an Electron app that runs Ovis on bundled herdr-core and Bun - #2691
Conversation
…re and Bun app/electron downloads pinned herdr-core 0.1.17 and Bun 1.4.2 at build time, checked against their SHA-256, stages the server as the installer runs it, and packages an AppImage or a dmg and zip. At run time it starts its own hc core (HC_SESSION=ovis) from a copy in its data folder, runs the server with OVIS_RUNTIME=herdr-core on loopback with its own state folder, and shows a connection screen until the server answers. It adds a tray and electron-updater plumbing that stays off without a feed. No server, client or shared code changes. Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Runs app/electron's unit tests and type check and builds an unsigned AppImage, or dmg and zip, as artifacts for pull requests that touch it. Publishes nothing. Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
…uring a quit A quit asked for inside the cancelled before-quit was dropped, so the app needed a second SIGTERM when no server was running. Also sets the Linux desktop name so window managers link the window to its launcher. Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 21 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
- The core and the server start through bash, which closes the descriptors Chromium leaves open, so the long-lived core no longer holds the app's files, sockets and pipes. - A server is recorded with its start time as soon as it is spawned; a quit during its start stops it, and the leftover check matches the start time, not just the command line. - Start, restart and Try again run one at a time. - Only microphone media is granted, never the camera. - A blank window a page opens for a sign-in is allowed and hands its address to the default browser; only the connection screen's own file URL is a local page. - HC_SOCKET is not passed to the app's core. - Each build re-checks cached downloads against their pins and unpacks them afresh, and adds the release's Rust PTY host when it matches this checkout. Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Review round 1: what changedReviewed at
Found while checking these: the hc core inherited ~60 descriptors Chromium leaves open across exec (cache files, IPC sockets, the DevTools listener), and kept them after the app quit. The core and the server now start through Not changed:
CodeRabbit does not review drafts, so no CodeRabbit review has run on this PR. |
- Settings dropped from the server's environment are dropped under their names from before the rename too, which the server would otherwise take back. - A leftover server is ended only when its start time was recorded and matches. - No server is started when a quit came during the steps before it; a failed page load no longer clears the record of a running server. - Each run's log is closed when its server ends. - The descriptor-closing wrapper reads /proc/$$/fd as intended; its test checks the exact descriptors the parent left open. - Packages carry Ovis's own LICENSE and THIRD_PARTY_NOTICES.md. Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Review round 2: what changedRound 2 at
Left as they are (no further fix rounds):
Validation for this head: |
… with the pid - A copy of hc newer than the bundled one is kept instead of asking it to go back, which hc refuses (an app rolled back after a newer one). - The server's record is written once, with its start time read synchronously, so a crash right after the spawn never leaves a record without one. - The listening line is found after any amount of earlier output: the end of the output is kept, not its start. Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Review at
|
| Finding | Resolution |
|---|---|
Rolling the app back to an older hc fails every start: hc update --from refuses an older build (reproduced) |
installCore compares versions first and keeps a copy that is the same or newer. Checked with the real binaries: a running 0.1.17 copy and a bundled 0.1.16 start fine and stay on 0.1.17. Unit tests. |
| A crash right after the spawn could leave a record without a start time | The record is written once, with the start time read synchronously from ps. Unit test. |
| More than 64 KiB of startup output hid the listening line | The end of the output is kept, not its start. Unit test with 200 KiB of output. |
Left as known limits (LOW): a socket = in hc's own config overrides HC_SESSION (in the PR description), and builds without a matching Rust PTY host fall back to Node.
Also merges origin/main (with #2693). Validation: bun run check fast passes on the merged head; app/electron bun test (29 pass) and bun run typecheck.
Review at
|
|
Merge note: owner approved the desktop shell screens and the new desktop.yml workflow on 2026-11-04, and chose to keep the existing same-PC loopback rule (noted as a known limit). CodeRabbit skipped these heads; merged on the omo review (CLEAR receipt at cd1287e), two Codex Terra rounds (findings fixed or noted above) and green checks. app/mac and app/windows stay as they are. |
Summary
Adds
app/electron, a desktop app (Electron, Linux and macOS) that carries everything Ovis needs and runs it itself: the Ovis server on a bundled Bun, and a bundled herdr-core (hc) for the terminals. Nothing else has to be installed. The existing Mac (app/mac) and Windows (app/windows) shells are untouched, and nothing inserver/,src/orshared/changes: the app only launches the server and opens a window on it.scripts/runtimes.tspins herdr-core 0.1.17 (releases.herdr.dev manifest) and Bun 1.4.2 (the CI Bun, oven-shSHASUMS256.txt) per platform with their SHA-256.scripts/build.ts stagedownloads them at build time, refuses a checksum mismatch, checks each binary reports the pinned version, then stages the server as the installer runs it (sources, built client, production packages). No binaries are committed.HC_SESSION=ovis(never thedefaultsession another hc client uses), then runs the server withOVIS_RUNTIME=herdr-core,OVIS_HC_BIN,HOST=127.0.0.1and its ownOVIS_STATE_DIR. The core outlives the app as hc runs it for every client; a newer bundled hc replaces the copy withhc update --from, so terminals keep running. The server keeps its port between runs while it is free (page storage stays), and a server left behind by a killed app is ended on the next start, only when it is still this app's Bun on its server.renderer/connect.html): the two steps, what failed with the end of its output, Try again and Show logs; English and Korean.OVIS_UPDATE_FEEDat build time bakes the feed in;OVIS_UPDATE_URLoverrides it at run time;OVIS_UPDATES=0turns it off. Off in development and without a feed (so off by default today).file:pages only.THIRD_PARTY_NOTICES.mdlists all of it, including that the unmodified Bun binary statically links JavaScriptCore/WebKit (LGPL-2), as Bun's own license file states.CI (needs the maintainer's OK)
.github/workflows/desktop.ymlbuilds the app onubuntu-24.04(AppImage) andmacos-15(dmg + zip, unsigned) for PRs touchingapp/electron, runs its unit tests and type check, and keeps the installers as artifacts. It publishes nothing. It is a workflow change, so it waits for the maintainer's OK; it is in its own commit and can be dropped.Validation
bun run check faston the branch: workflow syntax, generated types/themes, typecheck, build, unit tests (10891 pass, 0 fail), actionlint: all ok.app/electron:bun test(22 pass) andbun run typecheck, on Linux x64 and on macOS arm64 (eamac, fresh/tmpclone, deleted afterwards).bun scripts/build.tsstaged herdr-core 0.1.17 and Bun 1.4.2 (checksums verified, versions checked) and builtOvis-0.4.22-x86_64.AppImage. Ran the dev app and the AppImage (APPIMAGE_EXTRACT_AND_RUN=1, no FUSE on that host) under Xvfb with an isolated hc session (HC_SESSION=ovis-qa, mktempXDG_*/HOME/user data): connection screen while the core starts, then the Ovis window; a terminal started in that core (hc run --bg) showed live in Ovis's Terminal view; killing the server switched to the "Ovis stopped" screen and Try again recovered it; a restart reused the saved port and the running core; a broken server showed its error output on the failure screen (English and Korean); quitting stopped the server and left the core running, as designed.hc update --from: swapping an isolated 0.1.16 core to 0.1.17 kept its terminal running (terminals kept, output still readable).bun run distbuilt an unsigned.dmgand.zip; the app, opened with an isolated hc session and user data, started its core and server and loaded Ovis; Quit stopped the server.