feat(cua-driver-rs): announce new versions at startup (#1535) - #1536
Conversation
Introduces crates/cua-driver/src/version_check.rs with the building blocks for the startup "new version available" banner: - fetch_latest_version(): ureq-based GitHub releases call, filtered to the cua-driver-rs-v* tag prefix; shared with the update subcommand which now delegates to it instead of shelling out to curl with its own JSON-walking code path - VersionCache + read_cache / write_cache against ~/.cua-driver-rs/version_check.json (last_checked_at, latest version, dismissed_versions) - is_newer() strict semver compare; pre-release detection so source builds never get nagged - dismiss_version() append + idempotent persist - 22 unit tests covering semver edge cases (0.2.0 > 0.1.99, release > pre-release of same triple), cache round-trip in a tempdir, dismissal persistence, 20-hour refresh threshold, env-var + config opt-out, JSON release-list filtering No callers yet — maybe_announce_update is wired into the mcp / serve / doctor entry points in the next commit. semver = "1" and tempfile (dev-dep) added to Cargo.toml. Refs: #1535 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires version_check::maybe_announce_update() into the three long-running interactive entry points on both the macOS and non-macOS main() paths: - mcp (in-process MCP server, also runs before the daemon-proxy decision so users on either dispatch path see the banner) - serve (Unix-socket daemon, fires before the permissions gate) - doctor (interactive diagnostic command) Deliberately NOT called from --version, list-tools, describe, call, or dump-docs — those produce machine-readable stdout that gets piped through jq from scripts, and a banner would corrupt their output. The call is sync, returns immediately, and spawns the network round trip on either tokio::task::spawn_blocking (when a runtime is live) or a short-lived OS thread otherwise. Network failures stay silent (tracing::debug! only); the next launch retries. dismiss_version() is the one piece of the public API with no in-binary caller today — kept #[allow(dead_code)] for the future interactive prompt path (TUI / GUI helper) so the persistence layer stays in one place. Refs: #1535 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- PARITY.md: new "Startup flow: update-available banner" section covering the cache file shape, 20-hour refresh, opt-out layers, HTTP client, shared release-fetch with `cua-driver update`, and dismissal API - cua-driver/guide/getting-started/installation.mdx: Callout explaining the stderr banner, the cache location, the scripted-context skip list, and the env / config opt-out paths - cua-driver/reference/cli-reference.mdx: "Startup banner" subsection under `cua-driver update` linking the manual subcommand to the proactive surfacing path Refs: #1535 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR adds a non-blocking background version-check banner to ChangesUpdate available banner for interactive entry points
Sequence DiagramsequenceDiagram
participant User as User
participant MainEntry as main.rs<br/>(serve/doctor/mcp)
participant MaybeAnnounce as maybe_announce_update()
participant Background as Background thread
participant CheckAndAnnounce as check_and_announce()
participant GitHub as GitHub Releases API
participant Cache as ~/.cua-driver-rs/<br/>version_check.json
participant Stderr as stderr
User->>MainEntry: cua-driver serve (or doctor/mcp)
MainEntry->>MaybeAnnounce: call at startup
MaybeAnnounce->>Background: spawn(check_and_announce)
MaybeAnnounce-->>MainEntry: return immediately
MainEntry->>MainEntry: continue serve/doctor/mcp
Background->>CheckAndAnnounce: run in background
CheckAndAnnounce->>Cache: read cache & check age
alt cache < 20 hours old
Cache-->>CheckAndAnnounce: use cached latest_version
else cache >= 20 hours old or missing
CheckAndAnnounce->>GitHub: HTTP GET /repos/trycua/cua/releases
GitHub-->>CheckAndAnnounce: JSON array of releases
CheckAndAnnounce->>CheckAndAnnounce: filter cua-driver-rs-v* tags
CheckAndAnnounce->>Cache: write latest version & timestamp
end
CheckAndAnnounce->>Cache: read dismissed_versions
alt latest is strictly newer && not dismissed
CheckAndAnnounce->>Stderr: print banner:<br/>✨ cua-driver v... is available<br/>Update with: cua-driver update
end
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
docs/content/docs/cua-driver/guide/getting-started/installation.mdx (1)
117-120: ⚡ Quick winIncomplete list of excluded commands.
Lines 117-120 state that
--version,list-tools,describe,call, anddump-docsskip the banner, but the list is incomplete. According to PARITY.md lines 1836-1843, additional commands also skip the banner:mcp-config,update,stop,status,recording,config,diagnose, andtelemetry install-event. The CLI reference (line 396-397 of cli-reference.mdx) includesmcp-configbut not the others.Consider either:
- Listing all excluded commands consistently across all three docs, or
- Rephrasing to make clear this is a partial list: "One-shot and machine-readable entry points such as
--version,list-tools,describe,call,dump-docs, and others are not instrumented."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/content/docs/cua-driver/guide/getting-started/installation.mdx` around lines 117 - 120, The documentation states that scripted/machine-readable entry points are not instrumented but lists an incomplete set; update the text in installation.mdx to either enumerate all commands that skip the banner (include --version, list-tools, describe, call, dump-docs, mcp-config, update, stop, status, recording, config, diagnose, and telemetry install-event drawn from PARITY.md) or rephrase the sentence to indicate this is a partial list (e.g., "One-shot and machine-readable entry points such as --version, list-tools, describe, call, dump-docs, and others are not instrumented") so the docs are consistent with PARITY.md and cli-reference.mdx.docs/content/docs/cua-driver/reference/cli-reference.mdx (1)
396-399: ⚡ Quick winIncomplete list of excluded commands (same issue as installation.mdx).
Lines 396-399 list machine-readable subcommands that skip the banner but omit several:
update,stop,status,recording,config,diagnose, andtelemetry install-eventare also excluded per PARITY.md lines 1836-1843.For consistency, either list all excluded commands or rephrase to indicate this is a representative sample: "Machine-readable and one-shot subcommands (such as
--version,list-tools,describe,call,dump-docs,mcp-config, and others) deliberately do NOT emit the banner..."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/content/docs/cua-driver/reference/cli-reference.mdx` around lines 396 - 399, The sentence listing machine-readable subcommands is incomplete — it omits `update`, `stop`, `status`, `recording`, `config`, `diagnose`, and `telemetry install-event` (per PARITY.md) — so either expand the list to include those exact commands (alongside `--version`, `list-tools`, `describe`, `call`, `dump-docs`, `mcp-config`) or replace the sentence with a concise representative phrase such as: "Machine-readable and one-shot subcommands (such as `--version`, `list-tools`, `describe`, `call`, `dump-docs`, `mcp-config`, and others) deliberately do NOT emit the banner" so the intent is clear and stays accurate; update the text in cli-reference.mdx accordingly.libs/cua-driver-rs/PARITY.md (1)
1800-1804: 💤 Low valueAdd language specifier to fenced code block.
The code block showing the banner format is missing a language specifier. Add one for proper syntax highlighting and to resolve the markdownlint warning.
📝 Proposed fix
-``` +```text ✨ cua-driver v0.1.4 is available (you have v0.1.3). Update with: cua-driver update Release notes: https://github.com/trycua/cua/releases/tag/cua-driver-rs-v0.1.4</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@libs/cua-driver-rs/PARITY.mdaround lines 1800 - 1804, In PARITY.md, locate
the fenced code block containing the banner text starting with "✨ cua-driver
v0.1.4 is available (you have v0.1.3)." and add a language specifier (e.g.,
text) to the opening fence so the block becomestext ... ``` to enable
proper syntax highlighting and silence the markdownlint warning.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Nitpick comments:
In@docs/content/docs/cua-driver/guide/getting-started/installation.mdx:
- Around line 117-120: The documentation states that scripted/machine-readable
entry points are not instrumented but lists an incomplete set; update the text
in installation.mdx to either enumerate all commands that skip the banner
(include --version, list-tools, describe, call, dump-docs, mcp-config, update,
stop, status, recording, config, diagnose, and telemetry install-event drawn
from PARITY.md) or rephrase the sentence to indicate this is a partial list
(e.g., "One-shot and machine-readable entry points such as --version,
list-tools, describe, call, dump-docs, and others are not instrumented") so the
docs are consistent with PARITY.md and cli-reference.mdx.In
@docs/content/docs/cua-driver/reference/cli-reference.mdx:
- Around line 396-399: The sentence listing machine-readable subcommands is
incomplete — it omitsupdate,stop,status,recording,config,
diagnose, andtelemetry install-event(per PARITY.md) — so either expand the
list to include those exact commands (alongside--version,list-tools,
describe,call,dump-docs,mcp-config) or replace the sentence with a
concise representative phrase such as: "Machine-readable and one-shot
subcommands (such as--version,list-tools,describe,call,dump-docs,
mcp-config, and others) deliberately do NOT emit the banner" so the intent is
clear and stays accurate; update the text in cli-reference.mdx accordingly.In
@libs/cua-driver-rs/PARITY.md:
- Around line 1800-1804: In PARITY.md, locate the fenced code block containing
the banner text starting with "✨ cua-driver v0.1.4 is available (you have
v0.1.3)." and add a language specifier (e.g.,text) to the opening fence so the block becomestext ... ``` to enable proper syntax highlighting and
silence the markdownlint warning.</details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: Organization UI **Review profile**: CHILL **Plan**: Pro **Run ID**: `4a30011d-fff7-4cc6-a414-978e9334bf4e` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 5e27549541ef55e8d466bd18e9d82baf363bbfbf and 5f2753b212b49f5b6019cf6fb4b4d29214bb6585. </details> <details> <summary>⛔ Files ignored due to path filters (1)</summary> * `libs/cua-driver-rs/Cargo.lock` is excluded by `!**/*.lock` </details> <details> <summary>📒 Files selected for processing (7)</summary> * `docs/content/docs/cua-driver/guide/getting-started/installation.mdx` * `docs/content/docs/cua-driver/reference/cli-reference.mdx` * `libs/cua-driver-rs/PARITY.md` * `libs/cua-driver-rs/crates/cua-driver/Cargo.toml` * `libs/cua-driver-rs/crates/cua-driver/src/cli.rs` * `libs/cua-driver-rs/crates/cua-driver/src/main.rs` * `libs/cua-driver-rs/crates/cua-driver/src/version_check.rs` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
- installation.mdx: expand the list of subcommands that skip the banner (add `mcp-config`, `update`, `stop`, `status`, `recording`, `config`, `diagnose`, `telemetry install-event`) so the doc matches the actual call-site enumeration. - cli-reference.mdx / mcp-tools.mdx: regenerate against current Swift source. (The previous file diverged from the generator output for the same reason flagged in #1522 — accumulated drift from version bumps + upstream docstring edits.) Side-effect: the standalone "Startup banner" prose the previous agent added to the auto-generated cli-reference.mdx is now gone; the user-facing docs for this feature live in installation.mdx where edits survive regen. - PARITY.md: add `text` language specifier to the example banner code fence (MD038 lint fix).
Closes #1535.
Summary
Adds a non-blocking "new version available" banner to the long-running interactive entry points of
cua-driver-rs(mcp,serve,doctor). The check runs on a background task at startup, hits the GitHub releases API once per ~20 hours (cached on disk), and prints a small two-line banner to stderr if a newercua-driver-rs-v*release exists and the user hasn't dismissed it.Banner format:
What's in this PR
crates/cua-driver/src/version_check.rs— new module:pub fn maybe_announce_update()— sync, returns instantly; spawns the network check ontokio::task::spawn_blocking(or a short-lived OS thread for sync entry points)pub(crate) fn fetch_latest_version()—ureq-based GitHub releases call, filtered to thecua-driver-rs-v*tag prefix, drafts + pre-releases excludedread_cache/write_cacheagainst~/.cua-driver-rs/version_check.jsonwith a 20-hour refresh thresholdpub fn is_newer(latest, current) -> bool— strict semver compare; pre-release sorts below releasepub fn dismiss_version(version: &str)— appends todismissed_versionsfor the future interactive "skip until next version" pathcrates/cua-driver/src/main.rs— wiresmaybe_announce_update()into theMcp,Serve, andDoctorarms on both the macOS and non-macOSmain()pathscrates/cua-driver/src/cli.rs—run_update_cmdnow delegates to the sharedversion_check::fetch_latest_version()/version_check::is_newer()instead of shelling out tocurlwith its own JSON-walking code pathcrates/cua-driver/Cargo.toml— addssemver = "1"andtempfile(dev-dep)libs/cua-driver-rs/PARITY.md— new "Startup flow: update-available banner" section covering behavior, cache shape, opt-out layers, HTTP client, and shared release-fetch withcua-driver updatedocs/content/docs/cua-driver/guide/getting-started/installation.mdx+docs/content/docs/cua-driver/reference/cli-reference.mdx— user-facing docs for the banner, the cache, the scripted-context skip list, and the env / config opt-out pathsOpt-out (three layers, any one disables the check)
CUA_DRIVER_RS_UPDATE_CHECK=false(also0,no,off; case-insensitive) — single invocationupdate_check_enabled = falsein~/.cua-driver/config.json— permanent (set viacua-driver config set update_check_enabled false)CARGO_PKG_VERSIONwith a pre-release suffix (-dev,-rc.1,-beta, …) — auto-skips for source / dev buildsSkipped entry points
--version,list-tools,describe,call,dump-docs,mcp-config,update,stop,status,recording,config,diagnose,telemetry install-event— these are routinely piped from scripts and a banner would corrupt their parseable output.Tests
22 new unit tests in
version_check::tests, all passing:is_newersemver edge cases (0.2.0 > 0.1.99,0.1.3 > 0.1.3-dev, equal / older returns false, unparseable returns false)-dev,-rc.1,-beta, garbage input)tempfile::tempdir()dismissed_versionspersistence (append, idempotent re-dismissal)is_enabledupdate_check_enabled = falseconfig flag disables;true/ missing leaves onpick_latest_releasefilters out Swift-port tags, drafts, and pre-releasesTest plan
cargo build --release -p cua-driver— clean build (1 pre-existing unrelated warning)cargo test -p cua-driver version_check::— 22 passed, 0 failedcua-driver --version— no banner pollution, printscua-driver 0.1.3CUA_DRIVER_RS_UPDATE_CHECK=false cua-driver list-tools— clean machine-readable output, no bannercua-driver mcpfrom an outdated install (e.g.CARGO_PKG_VERSIONpatched to0.1.0) and verify the banner lands on stderr within ~5scua-driver mcpwithin 20h and verify the cache file is reused (~/.cua-driver-rs/version_check.jsonmtime unchanged, no HTTP request intracing::debug!output withCUA_LOG=debug)~/.cua-driver/config.jsonwith{"update_check_enabled": false}and verify the check is skipped (no banner, no debug-log fetch line)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
mcp,serve,doctor). Displays a banner on stderr when a newer release is available, with options to disable via environment variable or configuration.Documentation