Skip to content

feat(gateway): in-app version check + upgrade dialog (RFC #8170 phase 1)#8173

Draft
NiuBlibing wants to merge 1 commit into
zeroclaw-labs:masterfrom
NiuBlibing:feat/web-upgrade-dialog
Draft

feat(gateway): in-app version check + upgrade dialog (RFC #8170 phase 1)#8173
NiuBlibing wants to merge 1 commit into
zeroclaw-labs:masterfrom
NiuBlibing:feat/web-upgrade-dialog

Conversation

@NiuBlibing

@NiuBlibing NiuBlibing commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Base branch: master
  • What changed and why: Phase 1 (read-only) of the dashboard upgrade affordance from the RFC. The sidebar version tag (bottom-left) becomes a clickable button that opens an Upgrade dialog showing current vs. latest release + release notes, with an accent dot when a newer release exists. Today that tag is purely informational and upgrading requires leaving the dashboard for the CLI.
    • zeroclaw update --check gains a --json mode and UpdateInfo now carries release notes/url/published_at, so the gateway renders real release info while the CLI stays the single source of truth for update logic.
    • New gateway version.rs: GET /api/version/check spawns zeroclaw update --check --json (cached 1h, never fails the dashboard) and a read-only restart classification (cached for the process lifetime); /api/status gains restart_mode/restart_hint + the two config flags.
    • New config gateway.check_updates (default true) and gateway.allow_self_upgrade (default false), both exposed in the dashboard config UI.
    • Web: checkVersion API + types, useVersionCheck hook (mount / 6h / visibility refresh), sidebar update dot, and the UpgradeDialog Info view.
  • Scope boundary: Read-only only. No upgrade execution, no binary swap, no restart — those are later RFC phases. allow_self_upgrade is wired into config/status but gates nothing yet (no upgrade endpoint in this PR). OpenAPI registration for the new route is deferred (the spec is hand-curated and has no completeness test).
  • Blast radius: GET /api/status response shape (additive fields), one new GET endpoint, the sidebar footer component, two additive config keys, and a new --json flag on zeroclaw update --check. The version check shells out to the running binary's own update --check.
  • Linked issue(s): Related RFC: In-app upgrade with optional supervised restart from the web dashboard #8170 (implements RFC phase 1; the RFC issue stays open for discussion).
  • Labels: suggest type: feature, scope: gateway, scope: web.

Validation Evidence (required)

Ran in a git worktree off master.

Note: an initial test run reported 274 passed but that was a stale zeroclaw-gateway test binary served from a CARGO_TARGET_DIR shared with another checkout of the same package version. After forcing a rebuild the count is 277 passed and includes the three new version::tests::* cases (shown below). Evidence corrected accordingly.

```
$ cargo fmt --all -- --check

(no output, exit 0)

$ cargo clippy --all-targets -- -D warnings # full workspace
Finished `dev` profile [unoptimized + debuginfo] target(s) in 9m 18s

exit 0, no warnings (recompiled clean after the restart-info caching change too)

$ cargo test -p zeroclaw-gateway --lib # after forced rebuild
test version::tests::cli_check_json_roundtrips ... ok
test version::tests::detect_restart_returns_a_nonempty_hint ... ok
test version::tests::restart_mode_as_str_is_stable ... ok
test result: ok. 277 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

$ cargo test -p zeroclaw-config --lib checklist_gateway_serde_roundtrip
test schema::tests::checklist_gateway_serde_roundtrip ... ok
test result: ok. 1 passed; 0 failed

$ npm run build # web/ (tsc -b && vite build)
✓ built in 2.32s

exit 0; only the pre-existing >500 kB chunk-size advisory

```

  • Commands run and tail output: above. cargo clippy --all-targets compiled the whole workspace including the main zeroclawlabs binary (the update.rs/main.rs changes), so those are type-/lint-checked.
  • Beyond CI — what did you manually verify? The three new version.rs unit tests (restart classification + CLI-JSON parse) and the gateway-config serde roundtrip with the two new keys, all passing. I did not run a live gateway end-to-end against the real GitHub API, and did not exercise the dashboard in a browser.
  • If any command was intentionally skipped, why: Used scoped cargo test -p zeroclaw-gateway -p zeroclaw-config instead of a full-workspace cargo test — a full run is prohibitively long locally; the touched Rust lives in these two crates plus the main binary (covered by clippy --all-targets). CI runs the full battery.

Security & Privacy Impact (required)

  • New permissions, capabilities, or file system access scope? No
  • New external network calls? YesGET /api/version/check spawns zeroclaw update --check, which reaches the GitHub releases API. This call already existed in the CLI; this PR makes it reachable from the authenticated dashboard. Mitigations: behind require_auth, gated by gateway.check_updates (read-only), and cached 1h to stay under GitHub's unauthenticated rate limit.
  • Secrets / tokens / credentials handling changed? No
  • PII, real identities, or personal data in diff, tests, fixtures, or docs? No

Compatibility (required)

  • Backward compatible? Yes
  • Config / env / CLI surface changed? Yes — additive only: gateway.check_updates (default true), gateway.allow_self_upgrade (default false), and a new --json flag on zeroclaw update --check. Older configs deserialize unchanged (serde defaults); no migration needed.
  • Upgrade steps for existing users: none required.

Rollback (required for risk: medium and risk: high)

Low risk: git revert <sha>. allow_self_upgrade defaults off and gates nothing yet; check_updates is read-only.

@github-actions github-actions Bot added core Auto scope: root src/*.rs files changed. config Auto scope: src/config/** changed. gateway Auto scope: src/gateway/** changed. labels Jun 22, 2026
…bs#8170 phase 1)

Phase 1 (read-only) of the dashboard upgrade affordance: the sidebar
version tag becomes a clickable button that opens an Upgrade dialog
showing current vs. latest release and release notes. No upgrade
execution or restart yet — those are later RFC phases.

- update: add `--json` to `zeroclaw update --check`, and surface
  release notes/url/published_at in UpdateInfo so the gateway can render
  them (keeps the CLI as the single source of truth).
- config: new `gateway.check_updates` (default true) and
  `gateway.allow_self_upgrade` (default false), both exposed in the
  dashboard config UI.
- gateway: new `version.rs` with `GET /api/version/check` (spawns
  `zeroclaw update --check --json`, cached 1h) plus read-only restart
  classification; `/api/status` gains `restart_mode`/`restart_hint` and
  the two config flags.
- web: `checkVersion` API + types, `useVersionCheck` hook, sidebar
  update dot, and the `UpgradeDialog` Info view.

Related zeroclaw-labs#8170
@NiuBlibing NiuBlibing force-pushed the feat/web-upgrade-dialog branch from d301a6f to 77a29f9 Compare June 22, 2026 15:42
@Audacity88 Audacity88 added enhancement New feature or request web security Auto scope: src/security/** changed. domain:security Security domain domain:architecture Architecture domain risk: high Auto risk: security/runtime/gateway/tools/workflows. size: L Auto size: 501-1000 non-doc changed lines. needs-maintainer-review labels Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Auto scope: src/config/** changed. core Auto scope: root src/*.rs files changed. domain:architecture Architecture domain domain:security Security domain enhancement New feature or request gateway Auto scope: src/gateway/** changed. needs-maintainer-review risk: high Auto risk: security/runtime/gateway/tools/workflows. security Auto scope: src/security/** changed. size: L Auto size: 501-1000 non-doc changed lines. web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants