@synthryn/sypi-remote
v0.6.0-beta.20260816.6a00fcae
Published
Optional authenticated remote host and official PWA for SyPi
Maintainers
Readme
SyPi Remote
SyPi Remote is the optional, official web and mobile surface for a running SyPi workspace. It ships an authenticated local host and an installable PWA. It is not a native app and it does not use a hosted relay.
Start
Install it once from SyPi:
Open Settings > Extensions and select remote.
Then run:
/remoteOpen the private pairing link on the device. The browser generates its own signing key; there are no API keys, cloud accounts, notification credentials, or copied bearer tokens to configure. Pairing links expire after ten minutes and can be used once.
/remote prefers a private Tailscale Serve path at /sypi. If Tailscale is not
installed or signed in, localhost remains available. SyPi Remote never uses
Tailscale Funnel and has no public-network mode. It preserves other Serve
handlers, refuses a pre-existing /sypi path owned by another service, and
does not reset Serve configuration when it stops.
Use /remote local before starting to keep the host on this computer only.
Use /remote tailnet to restore private-tailnet mode. /remote pair creates a
fresh link, /remote status reports the current address, and /remote stop
stops the local host.
Private Serve deployment checklist
Run these read-only preflight commands on the SyPi host before changing the remote mode:
tailscale version
tailscale status --json
tailscale serve status --jsonRecord the existing Serve handlers from the JSON, including /, /notes, and
any other site-specific paths. Do not proceed if another service owns /sypi.
SyPi must remain bound to http://127.0.0.1:<port> and, in tailnet mode, its
reported address must be https://<node-dns-name>/sypi/. A local-mode address
must remain http://127.0.0.1:<port>.
Use this command lifecycle for a controlled restart:
/remote status
/remote stop
/remote tailnet
/remote
/remote status
/remote pairAfter start, run tailscale serve status --json again and confirm every
unrelated handler is unchanged. Confirm the pair link is fresh, is shown only
to the intended device, and is not reused after its ten-minute lifetime. A
localhost-only deployment can use /remote local instead of /remote tailnet.
Prefer /remote stop for rollback. If a stopped SyPi process leaves a mapping,
first run tailscale serve status --json and continue only when /sypi points
exactly to the SyPi loopback port created by this run. Remove only that endpoint
with the matching Serve command, then verify the unrelated handlers again:
tailscale serve --https=443 --set-path /sypi off
tailscale serve status --jsonNever use tailscale serve reset, Funnel, route, DNS, or prefs commands for
this deployment; they exceed the SyPi-owned mapping boundary.
What the PWA includes
- resumable live transcript and durable attention queue
- one-tap copy of the latest reply and clipboard paste into the composer
- incremental transcript updates with off-screen rendering containment for long sessions
- concurrent agent roster, spawning, messaging, cancellation, merge, and discard
- mobile approval, confirmation, and question handling with stale-response rejection
- Markdown render/source views, working-tree diffs, file browsing, and guarded editing
- a project terminal for trusted workspaces
- browser-native dictation and text-to-speech when the device supports them
- photo-library and rear-camera uploads with previews, removal, and on-device resizing
- text-file attachments
- a mobile terminal key deck with arrows, escape, tab, navigation, and common control keys
- Web Push notifications generated from a private per-install VAPID key
- session browsing, switching, and creation
- offline message and file-write queues with idempotency and file-etag revalidation
- paired-device revocation and narrowly matched approval rules
Every interactive control has a touch target of at least 44 CSS pixels. The layout is single-column on phones, a rail workspace on larger screens, and it honors the device safe area and reduced-motion preference.
Security boundary
The server listens only on 127.0.0.1. Tailnet access is provided by the
private Tailscale Serve path. Requests other than pairing and static PWA assets
must carry an ECDSA P-256 device signature over the method, exact request path,
timestamp, nonce, and body hash. The host rejects stale timestamps and replayed
nonces. Revocation closes that device's live event stream immediately.
Project paths are containment checked after resolving symlinks. File writes and terminal access require a project SyPi already trusts. Writes are atomic, require the file etag observed by the editor, and ask again for likely secret files. Terminal commands run with the same local operating-system permissions as the SyPi process; revoke a lost device immediately.
Private device keys, push keys, preferences, and subscriptions live under the SyPi state root with owner-only file permissions. They are never written into a user repository.
Backend contract
The official PWA uses the same 0.2 HTTP/SSE contract available to another
paired web client:
POST api/pairexchanges a one-time fragment ticket and public JWKGET api/snapshotreturns session, agents, decisions, devices, and capabilitiesGET api/events?after=<revision>streams resumable SSE envelopesGET api/capabilities,api/capability, andapi/capabilities/<module>describe the capability manifestPOST api/capabilitiesandapi/capabilities/invokeinvoke a declared capability actionGET api/entries?before=<count>&limit=<count>reads a bounded transcript windowPOST api/messages,api/agents,api/decisions, andapi/terminalmutate live workGET api/files,api/file, andapi/diff;PUT api/fileedits with an etagPOST api/sessions/newandapi/sessions/switchcontrol session lifecyclePOST api/push,PUT api/settings, andDELETE api/devices/<id>manage the device
All paths are relative to the served PWA scope, including /sypi/ on a tailnet.
The protocol definition and authentication rules are normative in
spec/remote-api.md in the SyPi source distribution.
Optional system capabilities
Tailscale is optional and only needed for private access from another device.
node-pty is optional; when its native binary is unavailable, Terminal uses a
basic non-PTY shell stream. Neither capability blocks localhost chat, files,
agents, diffs, speech, or notifications.
