Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
193a236
chore(relay): add a dictionary part for the relay dashboard
devswha Nov 7, 2026
b6c1f0a
feat(relay): add a dashboard model of the account's PCs
devswha Nov 7, 2026
74921d4
feat(relay): open the hosted app on a sign-in screen
devswha Nov 7, 2026
ccc4fd0
docs(relay): describe the sign-in-first front page
devswha Nov 7, 2026
9eb4fec
docs(relay): point the remaining front-page mentions at the sign-in s…
devswha Nov 7, 2026
556db83
feat(relay): show a dashboard of your PCs after sign-in
devswha Nov 7, 2026
15ecd0d
feat(relay): show the connection map and fit the dashboard on phones
devswha Nov 7, 2026
8f27b19
docs(changelog): note the relay sign-in screen and dashboard
devswha Nov 7, 2026
e4ccde5
fix(relay): polish the relay dashboard's translations
devswha Nov 7, 2026
ec0db29
fix(relay): close the dashboard refresh race and show join failures i…
devswha Nov 7, 2026
82fde9a
fix(relay): say ready, not connected, for a paired PC and extend the …
devswha Nov 7, 2026
71029dd
fix(relay): show an offline PC as offline in its dashboard row
devswha Nov 7, 2026
94f841a
test(relay): check the Ready wording in the dictionaries, not the ren…
devswha Nov 7, 2026
85c876f
test(relay): cover the sign-in screen and dashboard in a real browser
devswha Nov 7, 2026
bf1b447
fix(relay): count only account PCs and keep the phone tab order top t…
devswha Nov 7, 2026
7f6546b
Merge remote-tracking branch 'origin/main' into feat/relay-dashboard
devswha Nov 7, 2026
207ac08
fix(relay): keep Join on an offline dashboard row that can still be j…
devswha Nov 7, 2026
e5e5d26
fix(relay): keep the dashboard's directory reads in order and sign ou…
devswha Nov 7, 2026
f0ce8e9
fix(relay): say a QR pairing is not in the account yet, and keep a co…
devswha Nov 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 39 additions & 12 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3718,7 +3718,9 @@ Alert rows of the table above from the `--droplet-*` roles in `src/styles.css`.
About links the repository.
- In the hosted relay shell (app.ovis.sh, `<meta name="ovis-shell">`, lib/shellMode.ts) the page
opens with a **This app** group of two rows the native build never shows: **Change PC** (a neutral button to the
shell's front page, which lists every paired PC, the same row the iOS app gets for its own list)
shell's front page: the paired-PC list, or, signed out where the account service runs, the sign-in
screen with that list behind **Continue without an account**; the same row the iOS app gets for
its own list)
and **Forget this PC** (a neutral button that asks once in a `ConfirmDialog`, **Forget**, then
deletes this phone's key for the PC and leaves for the front page). Neither is destructive on the
PC, which keeps listing the phone until it is revoked there, so neither is a `.btn-danger`.
Expand Down Expand Up @@ -4376,22 +4378,47 @@ Alert rows of the table above from the `--droplet-*` roles in `src/styles.css`.
for the flow; the states and their words are this app's, in the token gate's own frame, so a
phone that pairs through the relay and one that pairs with a code see the same room. Neither
the Codex nor the Claude app has a hosted relay shell to follow.
- Account part (components/AccountPcs.tsx, lib/account/), only on the front page and only when
- Account part (components/AccountPcs.tsx, RelayDashboard.tsx, RelayMap.tsx, AddPcSheet.tsx,
lib/account/, lib/relay/dashboard.ts), only on the front page and only when
the page names an account service (`<meta name="ovis-account-service">`, account.ovis.sh unless
the build names another) and, in a browser, it is app.ovis.sh, the one page a sign-in comes back
to; otherwise the front page is the saved-PC list above, unchanged. Signed out: **Continue with GitHub** and **Continue
with Apple**, two equal neutral `.btn`s (App Review 4.8 wants Apple wherever another provider
is, and neither is the one to pick), a `--fs-xs` dim line on what the account service learns,
then the QR route under a hairline (an `h2`, the page keeps one `h1`). With saved PCs the list
comes first and the sign-in follows it. Signed in: **Your PCs** with "Signed in with GitHub"
under it, one row per PC of the account merged with the PCs this device is paired with: the
name, and under it a `--fs-sm` dim line in words (Paired; This device is not approved on it
yet; Offline, last seen 3 h ago; Its Ovis needs an update to join the account), no badge. Only
a paired PC is a link with a chevron; the others are plain rows. The `<main>` adds
`data-account-state` (`signed-out`, `signing-in`, `signed-in`) for scripts; each row
`data-pc-state`. Precedent: Tailscale's admin machine list (every machine of the account, its
state in words) for the list, and Signal's linked devices for keeping trust on devices already
linked rather than on the sign-in.
all under one **Sign in to Ovis** title (the page's one `h1`) and a line on what the relay is for.
Under them, quiet links: **Pair with a QR or code**, and only when this device holds pairings,
**Continue without an account (N PCs)**, which opens the dashboard below in local mode (this
device's own pairings, `data-dashboard-mode="local"`, the sidebar's foot offering the sign-in).
- Dashboard (signed in, or local mode): the shell's one wide screen, not the card. A sidebar of
places (Overview, PCs, Devices, Relay; Settings a row with no page yet) with the provider, Sign
out and Remove this device at its foot; a top bar with the title, a count line (the PCs the
account's directory lists: a PC paired by QR alone is a row, not one of them) and **Add a PC**,
the one primary action. Under it, a notice for the first PC waiting on this device, then a
summary strip of three cells (PCs as Ready / Needs you / Offline counts; Relays, each host with
its PC count and regional or global; Needs attention, each PC and its state in words), the
connection map (RelayMap.tsx: this device, each relay, the PCs behind it, wires that flow only
for a PC seen lately; a route list instead on a phone), and the PCs table: name with a dim line
(new in your account, in your account, paired by QR), state in words, relay host, last seen,
and the one action its state allows (Open, Add for a PC new in the account, Join for another
one waiting on this device, Update, Details), filtered by All / Ready / Needs you. One account
read on load, again when the page comes into view and every 60 s while it stays in view. The
`<main>` adds `data-account-state` (`signed-out`, `signing-in`, `signed-in`) for scripts; each
row `data-pc-state`.
- Add-a-PC sheet (AddPcSheet.tsx): a modal sheet with four segmented bars and a step list, in the
mode the row picked: **Add** types the six digits the new PC shows, then approves on that PC;
**Join** asks through the account, shows this device's digits, and an account member approves
on another device. **Add a PC** opens it with no PC, saying how one is added and leading to the
QR and code screen. It drives the shell's existing join, Pair, match and Cancel; the join goes
on in the sheet over the PC's own page, failure included (its words and Try again are the
shell's own screen's), except a new identity, which keeps the shell's screen with its ids and
Forget.
- Phone (760 px and under): the sidebar becomes a bottom tab bar (Overview, PCs, Devices,
Settings) over the safe area, its foot the page's last section, rendered after the page so that
Tab follows the eye (Add a PC first, Sign out after the table); and the map its route list.
- Precedent: GOAT's Fleet console (a telemetry strip over the machines) for the dashboard, and
its onboarding bars and connection steps for the sheet; Tailscale's admin machine list (every
machine of the account, its state in words) for the table; Signal's linked devices for keeping
trust on devices already linked rather than on the sign-in. No code or pixels are borrowed.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
- Relay files keep the existing file viewer and its Paseo-style file bar, rather than adding a
separate remote-files screen. A client without a resource-capable service worker shows the
usual file note as an alert when the 64 MiB limit is exceeded. Copy link and new-tab actions
Expand Down
8 changes: 8 additions & 0 deletions changelog.d/relay-dashboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
### Changed
- app.ovis.sh now opens on a sign-in screen, with pairing by QR code or code and PCs paired
without an account one link away.

### Added
- The dashboard brings your PCs together with an at-a-glance summary, a connection map of relays
and PCs, and a step-by-step sheet for adding or joining a PC. The map animates only PCs your
account has seen lately.
13 changes: 7 additions & 6 deletions docs/account.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,16 @@ messages):
a pairing window with `POST /api/relay/link` and the header `x-ovis-local-only: 1`. What that window takes is decided on
this PC only: it is never listed to account members (`remote-pairings`) or approved by one, even
once the PC has members. The screen keeps the window open while it waits.
2. On any device already in the account, the PC shows as a card, **Add {name} to your account?**,
for 10 minutes after the directory took it. Its key comes from the directory and is checked
against its id, as for any PC there; the person then **types the six digits the new PC shows**
(not a tap: the directory's name is anyone's), and approves on the PC.
2. On any device already in the account, the dashboard lists the PC as new in the account, with
**Add** on its row, for 10 minutes after the directory took it. **Add** opens the Add-a-PC sheet.
The PC's key comes from the directory and is checked against its id, as for any PC there; the
person then **types the six digits the new PC shows** (not a tap: the directory's name is
anyone's), and approves on the PC.
3. The device is then the PC's first member: it links, and enrolls the PC
([Enrolling a PC](#enrolling-a-pc)), so the account's other devices are let in and introduced.

A wrong number ends that comparison; the person starts again from the card. QR codes and pairing
codes stay under **Other ways** for a device without an account.
A wrong number ends that comparison; the person starts again from **Add** on the dashboard. A device without an account
pairs with a QR code or pairing code behind **Pair with a QR or code** on the sign-in screen.

### Introductions

Expand Down
5 changes: 3 additions & 2 deletions docs/relay.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,9 @@ then waits for the approval. A PC that declines, or does not approve in time, le

**Pairing with a typed code.** For a device with no camera pointed at the PC, **Show a code to
type** under the QR code shows ten characters, `XXXXX-XXXXX` (Crockford base32: no I, L, O or U;
O, I and L typed are read as 0, 1 and 1), and **Pair with a code** on app.ovis.sh's front page takes
them. The code finds the PC and hands the device the same offer the QR code carries, then the
O, I and L typed are read as 0, 1 and 1), and **Pair with a code** on app.ovis.sh takes them
(on its front page, or behind **Pair with a QR or code** on the sign-in screen when the account
service runs). The code finds the PC and hands the device the same offer the QR code carries, then the
device pairs with the six-digit code in it as a scanned QR code does: nothing else admits it
([`shared/relay-pair-code.ts`](../shared/relay-pair-code.ts),
[`server/relay/pair-code.ts`](../server/relay/pair-code.ts),
Expand Down
Loading
Loading