Add a beta firmware update visibility setting - #92
Conversation
Beta and stable releases were shown identically everywhere (dashboard, device detail, update dialog, and the CLI), with no way to hide beta-only updates by default. Adds a "Show beta updates" preference (off by default) that suppresses beta-only update signals across the app, while keeping the explicit manual channel picker (web dialog, `device update --channel beta`) able to select beta regardless of the setting. Backend: new available_firmware_channel field on DiscoveredDevice, tracking which channel an available update came from, set by both the RPC scan gateway (Gen2+) and the legacy Gen1 gateway (previously never checked there at all), and serialized through the /scan API response. Web: new showBetaUpdates setting (default off) in Settings; dashboard table, device header, and device actions card all filter through it; channel badges (beta orange, stable blue) where both channels are relevant; the update dialog's channel select only lists Beta when the setting is on; fixes an "Updates: Available" indicator that read raw summary.has_updates unfiltered, a channel select that always defaulted to stable instead of the channel that explains the button's state, and a button/badge overflow at narrower viewport widths. CLI: new --include-beta flag on scan, device list, and device status (off by default). A beta-only update reports as no update needed in table output, and the detail view's "Updates Available" line is omitted entirely when the only release is a hidden beta, matching how an already-up-to-date device displays today. BREAKING CHANGE: scan, device list, and device status now hide a beta-only update by default where they previously always showed it — scripts/automation parsing CLI output may observe a behavior change with no flag change on their end. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VApHaH9KZ6BPV9SwvUAVLH
04a89fd to
1ef8f78
Compare
jfmlima
left a comment
There was a problem hiding this comment.
Hey @valentinocossar thanks also for this one, left a few comments, let me know your thoughts 👍
| onValueChange={(value: UpdateChannel) => | ||
| setUpdateChannel(value) | ||
| } | ||
| disabled={!showBetaUpdates} |
There was a problem hiding this comment.
With the setting off this filters Beta out of the options and disables the whole select, so a device whose only release is a beta can't be updated from the web at all. That doesn't match the settings copy this PR adds ("You can still manually select the beta channel when updating a device"), the bulk actions dialog (which still offers Beta unconditionally), or the CLI (--channel beta always works). Can we keep Beta always selectable here and let the setting gate only the unsolicited signals (badges, status downgrade, indicators)? A preference that silently blocks an action feels like a trap.
| available_firmware_version: str | None = Field( | ||
| None, description="Version an available update would install" | ||
| ) | ||
| available_firmware_channel: str | None = Field( |
There was a problem hiding this comment.
Core already has UpdateChannel(str, Enum), and with use_enum_values=True the serialization stays identical. What do you think about typing this UpdateChannel | None instead of raw literals? Same on the web side, "stable" | "beta" | null instead of string.
| else: | ||
| self._format_legacy_device_table(devices, title) | ||
|
|
||
| def _effective_status(self, device: DiscoveredDevice, include_beta: bool) -> str: |
There was a problem hiding this comment.
We can't avoid the ts copy, but for the Python side what do you think about a small method on DiscoveredDevice in core, so the rule and its tests live in one place?
|
|
||
| return None | ||
|
|
||
| def _parse_update_version( |
There was a problem hiding this comment.
This re-derives "has stable update" with different precedence than _parse_update_flag: a payload with has_update false but differing versions was NO_UPDATE_NEEDED before and becomes UPDATE_AVAILABLE now. Can we make one defer to the other, and cover that case in the tests?
Summary
Beta and stable firmware releases were shown identically everywhere — dashboard table, device detail page, update dialog, and the CLI — with no way to hide beta-only updates by default. This adds a "Show beta updates" preference (off by default) that suppresses beta-only update signals across the app, while keeping the explicit manual channel picker (web dialog,
device update --channel beta) fully able to select beta regardless of the setting.Backend
available_firmware_channelfield onDiscoveredDevice, tracking which channel (stable/beta) an available update came from — set by both the RPC scan gateway (Gen2+) and the legacy Gen1 gateway (previously Gen1 devices never surfaced this at the scan-list level at all, nor did they ever check the beta channel there — parity fix included), and serialized through the/scanAPI response.Web
showBetaUpdatessetting (defaultfalse) in Settings, persisted client-side.showBetaUpdatescheck; the update dialog's channel picker only lists Beta when the setting is on (manual override removed by design decision during review — see discussion).summary.has_updates(unfiltered) instead of the same filtered data as everything else; the update-channel select now preselects whichever channel actually explains the button's state instead of always defaulting to stable; a button/badge overflow at narrower viewport widths.CLI
--include-betaflag onscan,device list, anddevice status(off by default, mirroring the web default). A beta-only update now reports as no update needed in table output, and the detail view's "Updates Available" line is omitted entirely when the only release is a hidden beta — matching exactly how an already-up-to-date device displays today (no partial hint).packages/cli/README.mdupdated with the new flag and default behavior.This changes the default output of
scan,device list, anddevice status— a beta-only update that was previously always visible is now hidden unless--include-betais passed. If this project follows SemVer for its release tags (currently up tov1.8.5), this likely warrants a major version bump (v2.0.0) rather than a patch/minor, since existing scripts/automation parsing CLI output could observe a behavior change with no flag change on their end.Test plan
packages/core(996 tests),packages/api(111 tests) — full suites pass, including new coverage for channel detection (RPC gateway: stable/beta/both/none; legacy Gen1 gateway: stable/beta-only/both, mirroring the RPC gateway's cases; settle-path)--include-betafilter (table view effective-status downgrade, detail-view filtering including the beta-only-hidden case, flag wiring/help text on all 3 commands)lint,format:check,type-check,buildall pass (no test runner exists in this package)black/ruff/mypyclean acrosspackages/core,packages/api,packages/cli; pre-commit hooks pass--include-betastates🤖 Generated with Claude Code
https://claude.ai/code/session_01VApHaH9KZ6BPV9SwvUAVLH