feat(web): show a host-offline state when the host stops instead of retrying in a loop

Merged
GN
8d ago
+829-31

Summary

  • A host that stops on purpose closes each socket with the close code 1001. The web client treated this as a network fault and retried in a loop.
  • This change shows an explicit host-offline state. The client then checks the host at a slow pace and reconnects when it answers.

Related Issue

Closes #1070

Searched open and closed PRs for the same problem. No PR covers it. This is the last PR of the read-model work in #1070. It builds on the watch PRs (#1094, #1096, #1110).

Type of Change

  • feat: new feature
  • fix: bug fix
  • docs: documentation only
  • style: formatting or non-functional styling changes
  • refactor: internal cleanup with no behavior change
  • perf: performance improvement
  • test: adds or updates tests
  • build: build or dependency changes
  • ci: CI/CD workflow changes
  • chore: maintenance or tooling
  • revert: reverts a previous change

What Changed

  • The control socket, the terminal socket and the persistence socket read the close code. Code 1001 puts the client in the host-offline state. No backoff loop runs.
  • While the host is offline, the client asks GET /health every 15 seconds. It also asks on a user retry, a wake and a network-online signal. It reconnects when the host answers.
  • The status bar, the terminal overlay and the chat panel show "Host offline". Selecting the indicator retries at once. Screen readers hear the same text.
  • The web client has a per-project terminal-set hook.
  • The change log and the API contract describe the new state.
  • Desktop is unchanged.

How It Was Tested

  • bun run ci (Biome lint + format + imports, strict mode)
  • bun run typecheck
  • bun run test
  • cargo clippy --all-targets -- -D warnings (in src-tauri)
  • cargo test (in src-tauri)
  • Manual verification completed
  • Not applicable

This change has no Rust edits. New tests cover the close code on each socket, the slow health probe, the retry and the status text. I also ran a local termul-server and the web client in Chromium. After I stopped the server, the indicator changed from "Connected" to "Host offline". The probe kept asking at a slow pace, with no reconnect loop.

Screenshots or Recordings

The lamp in the status bar, before and after the host stops (1440x900, dark theme, zoomed).

Connected:

Connected lamp

Host offline (accessible name: "Host offline. Select to retry."):

Host offline lamp

CI & Review Gate

  • All CI checks pass (PR Validation, Rust Checks, Build Verification, Security Scans)
  • Code review comments from CodeRabbit / Claude have been addressed or resolved
  • No unresolved review findings remain

Checklist

  • My PR title follows the conventional commit format used by this repo
  • I linked the related issue or explained why none exists
  • I updated docs when needed
  • I added or updated tests when needed
  • I verified the change does not introduce unrelated modifications
  • I read AGENTS.md and followed the contributor guidelines
  • A human reviewed the complete diff before submission

Summary by cubic

Shows a host-offline state when the host stops with close code 1001, instead of retrying in a loop. The client no longer backoff-reconnects against a stopped host; it shows "Host offline" in the status bar, terminal overlay and chat panel, asks GET /health every 15 seconds (plus on retry, wake or network-online), and reconnects when the host answers. The probe sends the auth bearer header so a gated host answers it.

  • Applies to /ws, /terminal/ws and the persistence socket; any other close code (e.g. 1012 on host restart) keeps the existing backoff.
  • The terminal channel enters host-offline only when a terminal is live; otherwise it stays idle and connects lazily.
  • Adds a per-project terminal-set hook backed by the host terminals watch.
  • Tests now use close code 1012 for restart scenarios so the 1001 host-offline path stays distinct.
  • Desktop is unchanged.

Summary by CodeRabbit

  • New Features

    • Added host-offline status across connection, chat, and terminal indicators, with a Retry action.
    • When the host intentionally shuts down, the app pauses automatic reconnect attempts and checks periodically for availability. Retry, wake, and network recovery can trigger an immediate check; connections resume when the host is available.
    • Added a client API for viewing the current set of host terminals.
  • Bug Fixes

    • Improved live explorer refresh to recover from dropped updates and reconnects.
  • Documentation

    • Documented the updated connection behavior and protocol version 7.