Parent
#130
What to build
The daily sync experience — renderer side only: the engine loop itself (continuous long-poll consumption, at-launch catch-up, reconnect/backoff, debounced push) is #133's scope; this ticket surfaces it. A status widget in the sidebar footer shows the sync state (syncing / up-to-date / offline-with-pending / error), an always-visible "Sync now" action, and a popover with the last successful sync, any errors, and the decrypt-quarantine list when non-empty. A new machine's first run prompts "Join an existing space" (paste the secret) as the primary action; completing onboarding (join or create) turns on the sync.enabled kill switch. While offline, local edits queue with a pending badge and auto-sync on reconnect. A synced conversation that cannot be resumed on this machine is shown with a "not resumable" state.
Acceptance criteria
Blocked by
- 3 (engine), 4 (E2E encryption — no user-triggerable sync ships before bodies are encrypted), 5 (pairing)
Parent
#130
What to build
The daily sync experience — renderer side only: the engine loop itself (continuous long-poll consumption, at-launch catch-up, reconnect/backoff, debounced push) is #133's scope; this ticket surfaces it. A status widget in the sidebar footer shows the sync state (syncing / up-to-date / offline-with-pending / error), an always-visible "Sync now" action, and a popover with the last successful sync, any errors, and the decrypt-quarantine list when non-empty. A new machine's first run prompts "Join an existing space" (paste the secret) as the primary action; completing onboarding (join or create) turns on the
sync.enabledkill switch. While offline, local edits queue with a pending badge and auto-sync on reconnect. A synced conversation that cannot be resumed on this machine is shown with a "not resumable" state.Acceptance criteria
sync:statustyped event and asyncRPC namespace.sync.enabled, and Settings can disable it (kill switch surfaced).useSyncExternalStore) and its event wiring are covered by node-project tests against a fake relay/engine; the widget's visual states are browser-suite coverage (not part of the agent gate — reportnot-runwhen the infra is absent).Blocked by