feat(updates): add release settings page - #844
Conversation
🔐 Codex Security Review
Review SummaryOverall Risk: NONE FindingsNo security, correctness, or reliability findings met the bar in the reviewed diff. NotesReviewed Generated by Codex Security Review | |
6343893 to
8706b54
Compare
8706b54 to
370f44e
Compare
00f1c84 to
67a2df3
Compare
67a2df3 to
ebaa30b
Compare
ebaa30b to
3405a51
Compare
3405a51 to
0d4eefa
Compare
93e7d47 to
355ee5f
Compare
355ee5f to
c89c567
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new permission-gated Settings → Updates surface in the ProtoFleet client that lets instance:update holders view the running server version, see an eligible release (with release notes + manual install command), and opt into Stable vs Stable+RC with stale-response protection during channel persistence/refetch.
Changes:
- Adds the
/settings/updatesroute with lazy loading and idle-time prefetch wiring. - Introduces the
Updatessettings page UI (status states, channel mutation/refetch sequencing, and stale-response guard). - Centralizes install-command clipboard + toast feedback in a shared (ProtoFleet-local) helper and adds focused unit tests.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| docs/plans/2026-07-27-001-feat-release-update-notifications-plan.md | Updates the implementation plan to reflect request ordering + disabled-controls behavior. |
| client/src/protoFleet/router.tsx | Registers the new Settings → Updates route with lazy loading. |
| client/src/protoFleet/routePrefetch.ts | Adds the Updates page importer to the settings prefetch tier. |
| client/src/protoFleet/features/updates/copyInstallCommand.ts | Adds a shared helper for copying the install command with consistent toast feedback. |
| client/src/protoFleet/features/settings/components/Updates.tsx | Implements the Updates settings page (status rendering, channel save + refetch flow, stale-response guard). |
| client/src/protoFleet/features/settings/components/Updates.test.tsx | Adds unit tests covering rendering, permissions, copy behavior, request ordering, and pending-control disabling. |
| client/src/protoFleet/config/navItems.ts | Adds a nav entry for Settings → Updates gated by instance:update. |
| client/src/protoFleet/config/navItems.test.ts | Verifies the Updates nav item permission gate. |
| client/src/protoFleet/api/clients.ts | Adds the InstanceUpdateService client export used by the Updates page. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf402be4f9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f18196ecb1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9124a111d3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Reviewable diff: +370/-2 across 7 files (excludes generated, test, and story files).
Summary
Adds Settings → Updates for permission holders, showing the running server version, eligible release, exact manual install command, and Stable + RC opt-in. Update discovery failures remain distinct from the up-to-date state, while request sequencing and bounded mutation lifecycle coordination prevent stale channels or install commands during saves, navigation, and ambiguous network failures. If update authority is revoked, the page reports it, removes the stale client permission, and redirects to a settings route the operator can access; delayed failures perform global auth cleanup only for the session that originated them.
Stack: #841, #842, and #843 are merged; this PR is relative to
main. Remaining notification and host-execution work continues in #845, #835, #836, #837, #838, #839, and #840.How it works
The permission-gated route loads
GetUpdateStatus. Available status renders either the eligible release and command or the up-to-date state; unavailable discovery gets a neutral state. A channel change persists throughSetReleaseChannelwith a 30-second deadline, keeps channel and copy controls disabled, and then refetches authoritative status. Request sequence numbers ignore late status responses, while a route remount waits for any save started by its predecessor; the deadline guarantees that shared barrier settles. Ambiguous non-auth save failures, including deadlines, refetch because the server may have committed before the response was lost. Each request captures the auth session installed at login. Same-session failures still pass through global auth handling after unmount or request replacement, while obsolete page state and toasts remain suppressed; failures from a replaced session are discarded so they cannot log out or remove permissions from its successor. Mounted permission denial also shows a revocation notice and redirects through the permission-aware settings landing helper.Areas of the code involved
features/settings/components/Updates.tsxfeatures/updates/copyInstallCommand.tsapi/clients.tsnavItems.ts,router.tsx,routePrefetch.tsdocs/plans/...release-update-notifications-plan.mdKey technical decisions & trade-offs
instance:updateafter permission denial so stale update controls disappear without discarding unrelated cached authority.fleet:read; otherwise Preferences is the safe fallback.Testing & validation
npm run test -- --run src/protoFleet/features/settings/components/Updates.test.tsx(28 tests)npm exec eslint -- src/protoFleet/features/settings/components/Updates.tsx src/protoFleet/features/settings/components/Updates.test.tsxnpm exec --no -- tsc --noEmit