What
Gate the live-update poll on the loaded source being a local path, and stop presenting it as available for a remote one.
Why
LIVE_UPDATES.ENABLED defaults to true and setupLiveUpdates() polls /api/manifest every 5s for the app's lifetime, regardless of what kind of source is loaded.
That only makes sense for a local working tree. The poll compares the manifest's content_signature, which tracks the tree's mtime / size / dirty state — things that change when you edit files on disk. A remote source is cloned once via ensure_clone and is not re-fetched from origin on each poll, so its signature cannot change. Every poll for a remote repo is a scan that can never report anything.
Two costs:
- Wasted work on both ends, every 5 seconds, for the whole session.
- The UI implies liveness that isn't there. The footer status dot runs its slow heartbeat animation whenever polling is on, and the Updates settings tab offers "Enabled" and a poll interval with a tip that says the city "re-renders in place whenever the project's files change" — none of which is reachable for a remote repo.
Sketch
srcKind(src) in app/src/utils/sources.ts already classifies SourceKind.Local vs SourceKind.Remote, and CURRENT_SOURCE holds the applied source, so the predicate is available without new plumbing.
- Skip the poll in
setupLiveUpdates() when the current source is remote. It already re-reads CURRENT_SOURCE each tick, so this can be part of the same check rather than a separate subscription.
- Reflect it in the Updates settings tab: the toggle should read as unavailable with a reason, not sit there enabled while doing nothing.
- Reflect it in the footer status dot, which currently heartbeats on
LIVE_UPDATES.value.ENABLED alone.
Open questions
- Should a remote source poll
origin instead? "Live" for a remote repo would mean fetching new commits, which is a different and much heavier feature than watching a working tree. Worth deciding whether this issue closes the door on that or leaves room for it.
- Where should the predicate live so the poll, the settings tab, and the footer all read one source of truth rather than each calling
srcKind themselves.
What
Gate the live-update poll on the loaded source being a local path, and stop presenting it as available for a remote one.
Why
LIVE_UPDATES.ENABLEDdefaults totrueandsetupLiveUpdates()polls/api/manifestevery 5s for the app's lifetime, regardless of what kind of source is loaded.That only makes sense for a local working tree. The poll compares the manifest's
content_signature, which tracks the tree's mtime / size / dirty state — things that change when you edit files on disk. A remote source is cloned once viaensure_cloneand is not re-fetched from origin on each poll, so its signature cannot change. Every poll for a remote repo is a scan that can never report anything.Two costs:
Sketch
srcKind(src)inapp/src/utils/sources.tsalready classifiesSourceKind.LocalvsSourceKind.Remote, andCURRENT_SOURCEholds the applied source, so the predicate is available without new plumbing.setupLiveUpdates()when the current source is remote. It already re-readsCURRENT_SOURCEeach tick, so this can be part of the same check rather than a separate subscription.LIVE_UPDATES.value.ENABLEDalone.Open questions
origininstead? "Live" for a remote repo would mean fetching new commits, which is a different and much heavier feature than watching a working tree. Worth deciding whether this issue closes the door on that or leaves room for it.srcKindthemselves.