Add server-synced roster so the phone remote reconnects across sessions#81
Merged
Merged
Conversation
The phone keeps its paired-device roster ({name, base, token}) only in the
browser's localStorage. That gets evicted (Safari's ~7-day cap on an
un-installed site), starts empty in a new browser/origin, and looks brand-new
after a DHCP IP change -- so a multi-device setup has to be re-paired from
scratch every time, which is poor UX.
Back the roster up on each paired Portal: the phone pushes its full roster to
every device whenever it changes, and pulls-and-merges when it pairs one. After
a storage wipe you pair a single Portal with its PIN and the rest come back
automatically ("pair one, restore all"), instead of re-pairing the fleet.
- RemoteRoster: SharedPreferences-backed store + a pure, unit-tested sanitiser
(validate/dedupe-by-base/clamp/cap) so a malformed upload can't wedge it.
- RemoteRoutes: auth-gated GET/POST /remote/roster. The on-screen PIN that mints
a session is the same gate that releases the roster -- reading it is no more
powerful than pairing each Portal in person.
- RemoteHtml: push on pair/add/forget/rename; pull-and-merge on pair and on
startup; local token always wins on conflict so a fresh session isn't clobbered.
- Docs: reconnecting + security trade-off (tokens now also live on each Portal),
with the home-screen-install tip as the durable-storage path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0163p2xPMLPceBaiNLHk2soK
Installing the remote to the home screen is the durable-storage path that complements the synced roster: an installed app's storage isn't evicted the way a browser tab's is, so the paired roster simply persists. - RemoteRoutes: public GET /remote/manifest.webmanifest (standalone display, Immortal name/colours) and GET /remote/app-icon?size= which renders the app's own adaptive launcher icon to PNG at the requested size -- the installed remote wears the same face as the app, with no new binary assets. - RemoteHtml: link the manifest + apple-touch-icon, theme-color and iOS web-app meta; request navigator.storage.persist() on load; add a dismissible "Add to Home Screen" tip in the Devices tab (hidden once installed/standalone). - Docs: installable-PWA note in the reconnect section + API rows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0163p2xPMLPceBaiNLHk2soK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The phone keeps its paired-device roster ({name, base, token}) only in the
browser's localStorage. That gets evicted (Safari's ~7-day cap on an
un-installed site), starts empty in a new browser/origin, and looks brand-new
after a DHCP IP change -- so a multi-device setup has to be re-paired from
scratch every time, which is poor UX.
Back the roster up on each paired Portal: the phone pushes its full roster to
every device whenever it changes, and pulls-and-merges when it pairs one. After
a storage wipe you pair a single Portal with its PIN and the rest come back
automatically ("pair one, restore all"), instead of re-pairing the fleet.
(validate/dedupe-by-base/clamp/cap) so a malformed upload can't wedge it.
a session is the same gate that releases the roster -- reading it is no more
powerful than pairing each Portal in person.
startup; local token always wins on conflict so a fresh session isn't clobbered.
with the home-screen-install tip as the durable-storage path.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_0163p2xPMLPceBaiNLHk2soK