Skip to content

feat(cua-driver-rs): check-update CLI verb + check_for_update MCP tool#1734

Merged
f-trycua merged 2 commits into
mainfrom
feat/check-update-cli-mcp
May 27, 2026
Merged

feat(cua-driver-rs): check-update CLI verb + check_for_update MCP tool#1734
f-trycua merged 2 commits into
mainfrom
feat/check-update-cli-mcp

Conversation

@f-trycua
Copy link
Copy Markdown
Collaborator

@f-trycua f-trycua commented May 27, 2026

Summary

Add a focused, machine-readable update-check surface so both humans and Hermes-style agents can ask "is there a newer cua-driver?" without scraping cua-driver update text output.

Three new surfaces, all reading from the same primitive (version_check::check_update_state) so the CLI, MCP, and launch-time banner never disagree on which release is latest:

  • cua-driver check-update [--json] [--no-cache] — pure check verb, never installs. Default text output for humans; --json emits the same payload as the MCP tool; --no-cache forces a fresh GitHub round-trip (bypasses the existing 20h cache).
  • cua-driver update --json — same JSON payload from the existing apply verb. The text behaviour of cua-driver update (no --json) is byte-for-byte unchanged for backward compat.
  • check_for_update MCP tool — read-only, idempotent, empty input schema. Mirror of check-update --json. Registered from main.rs via a small register_into(&mut ToolRegistry) shim so the ureq + rustls + ring dep tree stays in cua-driver and never reaches cua-driver-core (which would break cross-target Windows builds from macOS host).

How Hermes (and any MCP client) will consume this

# Direct CLI — for shell scripts:
if cua-driver check-update --json | jq -e .update_available > /dev/null; then
  cua-driver update --apply
fi
// MCP — for agents:
{"method":"tools/call","params":{"name":"check_for_update","arguments":{}}}
// Returns structuredContent with the full UpdateState schema documented
// in docs/content/docs/cua-driver/guide/getting-started/updating.mdx

JSON schema (same shape on both paths):

Field Type Notes
current_version string Running binary's CARGO_PKG_VERSION.
latest_version string | null Highest non-draft non-prerelease cua-driver-rs-v* tag. null on fetch failure with no cache.
update_available bool Strict semver compare.
source string "github_releases" today.
checked_at string ISO-8601 UTC.
cache_hit bool Whether we short-circuited via the 20h on-disk cache.
install_command string | null Shell one-liner. null when up-to-date.
release_notes_url string | null GitHub release URL. null when up-to-date.
error string | null Human-readable failure reason.

What was NOT done (intentional)

  • No --apply on check-update — separation of intent. Apply lives on update.
  • No apply variant of the MCP tool — installing over MCP forces self-replacement of the running MCP server.
  • No auto-update / background-apply behaviour.
  • Launch-time banner code (maybe_announce_update) untouched.

Verification run locally

  • cargo build --release -p cua-driver (macOS) — clean.
  • cargo check -p platform-windows --target=x86_64-pc-windows-msvc — clean.
  • cargo check -p platform-linux — clean (existing warnings only).
  • cargo test -p cua-driver --bin cua-driver version_check — 22/22 pass.
  • ~/.local/bin/cua-driver check-update — text path.
  • ~/.local/bin/cua-driver check-update --json | jq .update_available — parseable, branches cleanly.
  • ~/.local/bin/cua-driver check-update --no-cache --json — fresh fetch (cache bypassed).
  • ~/.local/bin/cua-driver call check_for_update '{}' — MCP path returns the same JSON shape via structuredContent.
  • ~/.local/bin/cua-driver update — text output byte-for-byte identical to pre-change behaviour.
  • ~/.local/bin/cua-driver update --json — structured payload, no text noise.
  • ~/.local/bin/cua-driver list-tools | grep check_for_update — tool registered on macOS.

The existing cua-driver-rs-v* releases on trycua/cua are all marked prerelease=true on GitHub today, which the canonical filter (pick_latest_release) strips — so live runs currently surface "no matching cua-driver-rs-v* release in response" in the error field. This is pre-existing behaviour shared with cua-driver update; the JSON path still returns a well-formed payload and exits with the documented code, so consumers can detect and report it.

Test plan

  • Land a non-prerelease cua-driver-rs-v* tag and re-verify update_available: true/false flips correctly across the version boundary.
  • Verify --no-cache triggers a fresh fetch (delete ~/.cua-driver-rs/version_check.json and observe re-write).
  • Confirm Hermes can consume the JSON via its existing tool-call wrapper.
  • Smoke-test on Windows + Linux that check_for_update is listed in cua-driver list-tools and returns the same shape.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added check-update command to verify available updates with JSON and cache options.
    • Added update check via MCP tool integration.
    • Pre-release versions now included in update availability checks.
  • Documentation

    • New update guide covering check and apply workflows.

Review Change Stack

Add a focused, machine-readable update-check surface so both humans and
Hermes-style agents can ask "is there a newer cua-driver?" without
scraping `cua-driver update` text output.

New surfaces (all share `version_check::check_update_state` so they
never disagree on which release is "latest"):

- `cua-driver check-update [--json] [--no-cache]` — pure check verb,
  never installs. Default human text; `--json` for scripted consumers;
  `--no-cache` bypasses the 20h cache.
- `cua-driver update --json` — same structured payload from the existing
  apply verb. Text behaviour unchanged when `--json` isn't passed.
- `check_for_update` MCP tool — read-only, idempotent, empty input
  schema. Registered from `main.rs` so the dep on `ureq` stays in
  `cua-driver` and doesn't propagate into `cua-driver-core` (which would
  break cross-target Windows builds from macOS host via `ring`).

Telemetry event `cua_driver_check_update`, docs page at
`/cua-driver/guide/getting-started/updating`, SKILL.md one-liner under
the shell-management section.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview May 27, 2026 2:56pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d69f884f-530d-430b-8849-da9c6bd0c309

📥 Commits

Reviewing files that changed from the base of the PR and between de698cb and 1a04bb0.

⛔ Files ignored due to path filters (1)
  • libs/cua-driver/rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • docs/content/docs/cua-driver/guide/getting-started/installation.mdx
  • docs/content/docs/cua-driver/guide/getting-started/meta.json
  • docs/content/docs/cua-driver/guide/getting-started/updating.mdx
  • libs/cua-driver/rust/Skills/cua-driver/SKILL.md
  • libs/cua-driver/rust/crates/cua-driver/src/check_update_tool.rs
  • libs/cua-driver/rust/crates/cua-driver/src/cli.rs
  • libs/cua-driver/rust/crates/cua-driver/src/main.rs
  • libs/cua-driver/rust/crates/cua-driver/src/version_check.rs

📝 Walkthrough

Walkthrough

This PR introduces a complete update-checking feature for cua-driver. It adds a new check_update_state() API for querying the latest GitHub release with caching, an MCP tool to expose this via LLM context, a check-update CLI command, and comprehensive documentation. Pre-releases are now accepted as valid update targets.

Changes

Update Check Feature

Layer / File(s) Summary
Update state model and check logic
libs/cua-driver/rust/crates/cua-driver/src/version_check.rs
New UpdateState struct and check_update_state(no_cache) function provide JSON-serializable update snapshots with cache-first behavior (20-hour freshness). Release selection now accepts pre-releases. Public visibility for RELEASE_TAG_PREFIX and fetch_latest_version().
MCP tool implementation
libs/cua-driver/rust/crates/cua-driver/src/check_update_tool.rs
CheckForUpdateTool invokes check_update_state() on a blocking thread, formats human-readable text and structured JSON output, and registers into tool registries.
CLI check-update command and update --json
libs/cua-driver/rust/crates/cua-driver/src/cli.rs
New Command::CheckUpdate { json, no_cache } and run_check_update_cmd() for pure checks. run_update_cmd() accepts json parameter to gate text output and print structured payloads. Telemetry event wired.
Tool and command wiring across platforms
libs/cua-driver/rust/crates/cua-driver/src/main.rs
Injects check_update_tool into macOS (via new registry builder helpers), Windows, and Linux registries. Updates CLI dispatch to forward check-update and update commands with correct parameters.
Update flow documentation and guides
docs/content/docs/cua-driver/guide/getting-started/*, libs/cua-driver/rust/Skills/cua-driver/SKILL.md
New "Updating" guide documents background banner checks, check-update command, --json schema with examples, MCP tool behavior, and update --apply installation flow. Links from installation guide and navigation metadata updated.

Sequence Diagram

sequenceDiagram
  participant User
  participant CheckUpdateCLI
  participant MCP_LLM
  participant check_update_state
  participant GitHubAPI
  participant DiskCache
  User->>CheckUpdateCLI: cua-driver check-update --json
  CheckUpdateCLI->>check_update_state: check_update_state(no_cache=false)
  check_update_state->>DiskCache: load (20h freshness)
  alt Cache valid
    DiskCache-->>check_update_state: UpdateState
  else Cache miss/stale
    check_update_state->>GitHubAPI: fetch latest (accept pre-release)
    GitHubAPI-->>check_update_state: release tag
    check_update_state->>DiskCache: save UpdateState
  end
  check_update_state-->>CheckUpdateCLI: UpdateState {update_available, latest_version, ...}
  CheckUpdateCLI->>User: JSON stdout
  MCP_LLM->>check_update_state: invoke check_for_update tool
  check_update_state-->>MCP_LLM: text + structured {update_available, ...}
Loading

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • trycua/cua#1673: Introduces the updater.rs shim and installer-script delegation that cua-driver update --apply delegates to when the check-update feature detects an available update.

Poem

🐇 A rabbit's ode to checking for updates:
Release tags now flow from GitHub's nest,
Pre-release versions pass the test,
Check-update sings in JSON bright,
MCP tools run the checks just right! 🚀

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/check-update-cli-mcp

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

cua-driver-rs is pre-1.0 and the CD pipeline marks every release
`prerelease=true` by convention (visible on every cua-driver-rs-v*
release on `trycua/cua`). The previous filter — written when the
banner was added before any release existed — silently stripped them,
so both `cua-driver update` and the new `cua-driver check-update`
returned "no matching cua-driver-rs-v* release in response" against
the real GitHub.

Drop the `prerelease` skip in `pick_latest_release`. Drafts are still
filtered (drafts are explicitly not for consumption). Doc-comment +
unit test renamed + updated to reflect the new behaviour.

Verified live: `cua-driver check-update` against 0.3.1 now correctly
reports "You're on the latest release." with `latest_version: "0.3.1"`
in JSON.
@f-trycua f-trycua marked this pull request as ready for review May 27, 2026 14:59
@f-trycua f-trycua merged commit 7d893ce into main May 27, 2026
6 of 10 checks passed
@f-trycua f-trycua deleted the feat/check-update-cli-mcp branch May 27, 2026 15:00
f-trycua added a commit to trycua/hermes-agent that referenced this pull request May 27, 2026
… hardcoded version floor

Replace the per-OS MIN_CUA_DRIVER_VERSION soft-warning (hardcoded, rot-prone)
with cua-driver's native check-update — the source-of-truth freshness check
shipped in trycua/cua#1734 (`check-update --json` CLI verb / `check_for_update`
MCP tool).

- cua_backend: cua_driver_update_check() shells `check-update --json`
  (stdin=DEVNULL so a pre-NousResearch#1734 driver that falls through to a stdin read
  fails fast instead of blocking; timeout-guarded). Returns None when
  indeterminate (verb absent / offline / error payload / unparseable) so
  callers stay quiet. cua_driver_update_nudge() formats the one-liner; the
  startup nudge runs off-thread so the (cached, ~20h) GitHub poll never
  blocks the first computer_use action.
- status: `hermes computer-use status` reports current/latest and an
  "update available" line via the native check.
- update: install_cua_driver(upgrade=True) skips the network re-install when
  the driver reports it's already on the latest release.
- Graceful on pre-NousResearch#1734 drivers (e.g. 0.2.18 on the dev host): verb absent →
  stay quiet (verified: returns None in ~0.4s).
- tests: TestUpdateCheck replaces TestVersionWarning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant