Skip to content

System info in the bottom status bar (exploration 0233) - #289

Merged
crs48 merged 6 commits into
mainfrom
claude/0233-system-info-in-the-bottom-status-bar
Jun 26, 2026
Merged

System info in the bottom status bar (exploration 0233)#289
crs48 merged 6 commits into
mainfrom
claude/0233-system-info-in-the-bottom-status-bar

Conversation

@crs48

@crs48 crs48 commented Jun 26, 2026

Copy link
Copy Markdown
Owner

What

Turns the status bar's lone hub dot into a layered sync connection cluster (exploration 0233). The bar stays calm when healthy and speaks up only when something is off-nominal — answering "are my changes safe?", not just "is the hub connected?".

Tier A — always on: a connection chip (dot + terse label) backed by a new useSyncVitals() aggregator that folds useHubStatus, useIsOffline, and the SyncManager's readonly props + lifecycle/verification/reconciliation events into one reactive object.

Tier B — only when off-nominal: conditional chips — ⇡ N pending (offline queue), an integrity (hash/signature verification failure), and a storage ◐ N% (OPFS pressure past 85%, via a new useStorageEstimate()).

Tier C — on demand: a click-through popover anchored above the bar carrying the deep detail (last change, lifecycle phase, tracked/pool counts, runtime mode, storage breakdown, last verification failure) plus a Reconcile action. Diagnostics (lamport/security level/billing plan) deliberately stay out of the always-on row.

Mobile has no status bar, so a matching sync glyph in the top bar opens the same detail in a bottom sheet.

Why

A rich pool of reactive sync signals existed but never reached the user — connected could coexist with a non-empty offline queue, a degraded lifecycle, or a recent verification failure. This surfaces them following VS Code's status-bar guidance (workspace status left, limit items, color as last resort) and local-first norms (subtle when healthy, a quiet badge + retry when not).

Verification

  • New sync-format.test.ts — 15 unit tests over the pure decision/format logic (coarse-state mapping, integrity gate, storage thresholds, byte/time formatting).
  • Live browser preview (desktop + mobile): bar renders at exactly 24px, one line; connection chip reads offline with a no-hub session; typing a mutation live-bumped the ⇡ 2 pending chip; popover opens from chip click and closes on Escape; storage estimate read 602 KB / 9.9 GB and the storage chip correctly stayed hidden at 0%; mobile glyph reflects state and opens the matching sheet.
  • pnpm --filter xnet-web typecheck, eslint, and prettier all clean.

Scope is apps/web only — no publishable package changed, so no changeset (changelog fragment included).

🤖 Generated with Claude Code

xNet Test and others added 6 commits June 26, 2026 14:03
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
useSyncVitals() folds hub status, the browser online flag, and the
SyncManager's readonly props + lifecycle/verification/reconciliation
events into one reactive object. useStorageEstimate() wraps
navigator.storage.estimate() for coarse OPFS pressure. Pure decision/
format logic (coarse state, integrity gate, byte/time/threshold) lives
in sync-format.ts with unit tests. (exploration 0233)
Replace the status bar's static hub dot with a connection cluster: an
always-on chip (dot + terse label), conditional tier-B chips that only
appear off-nominal (⇡ N pending, integrity ⚠, storage ◐ N%), and one
click-through popover anchored above the bar carrying the deep detail
(last change, lifecycle phase, tracked/pool counts, runtime mode,
storage breakdown, last verification failure) plus a Reconcile action.
Mobile has no status bar, so a matching health glyph in the top bar
opens the same detail in a bottom sheet. Diagnostics (lamport/security
level/billing plan) stay out of the always-on row. (exploration 0233)
#287)

PR #287 added an always-on durable-storage indicator to the status bar.
Combine it with the 0233 sync cluster: keep main's <StorageStatus/>,
drop the now-redundant storage chip + useStorageEstimate hook, and source
the popover's storage row from the canonical useStorageStatus + the shared
lib/format-bytes (no duplication).
@crs48
crs48 temporarily deployed to pr-289 June 26, 2026 21:34 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jun 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🖼️ UI changes in this PR

Screens

✏️ Home _(SSIM 0.998)_
before after diff
before after diff

Auto-captured by CI · run. Informational — not a blocking check.

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #289.

github-actions Bot added a commit that referenced this pull request Jun 26, 2026
@crs48
crs48 merged commit a0ea9ef into main Jun 26, 2026
13 of 14 checks passed
@crs48
crs48 deleted the claude/0233-system-info-in-the-bottom-status-bar branch June 26, 2026 21:40
github-actions Bot added a commit that referenced this pull request Jun 26, 2026
* The deep detail panel shared by the desktop popover and the mobile sheet.
* Presentation over the sync vitals + durable-storage status, plus Reconcile.
*/
export function SystemInfoDetails({ vitals }: { vitals: SyncVitals }) {
* reconciliation events for instant transitions, plus a slow poll so the
* offline-queue count (which can change with no lifecycle event) stays fresh.
*/
export function useSyncVitals(): SyncVitals {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants