feat: add self-update command and auto-update infrastructure#224
Merged
Conversation
Add `cargo agents self-update` which downloads prebuilt binaries from GitHub releases (falling back to `cargo install`), and startup auto-update checks gated by a new `auto-update` config (off/warn/on, default warn). Introduce `state.toml` to track the binary version and throttle update checks to once per 24 hours. New config keys: - `auto-update`: off | warn | on (default warn) - `self-update-source`: binary | source (default binary) Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude <claude@anthropic.com>
nikomatsakis
commented
May 14, 2026
Member
Author
nikomatsakis
left a comment
There was a problem hiding this comment.
We need to setup some kind of test infra. I would like to have integration tests and show that e.g. the re-exec works mid-command and also with hooks. The question is how to set that up in a way that is "mockable". At the worst, we can have some kind of env variables or other test flags.
| plugins::ensure_plugin_sources(&sym, cli.update).await; | ||
|
|
||
| // Auto-update check (skip for hooks and self-update itself). | ||
| if !is_hook |
Member
Author
There was a problem hiding this comment.
The behavior around hooks is an interesting question. I think we should execute the check but only for hooks but add the warning as guidance to the agent to suggest to the human to run self-update. We can do the auto updates as normal.
…vior - Switch version check from crates_io_api to `cargo search` (respects registry config/mirrors/proxies). - Extract `cargo_command()` helper (checks SYMPOSIUM_CARGO env, used across init, self_update, installation) so tests can mock cargo. - Add unit tests for search output parsing, tarball extraction, and binary installation. - Add integration tests for self-update command and state.toml. - For hooks: auto-update = "on" still runs silently; "warn" is skipped (stderr isn't visible to the agent). Hook-context guidance is a follow-up. - Add dedicated reference page for `cargo agents self-update`. Co-authored-by: Claude <claude@anthropic.com>
Replace the process-global SYMPOSIUM_CARGO env var with a `cargo_override` field on `Symposium` and a `cargo_command()` method. Tests use `ctx.set_mock_cargo()` which writes a mock script and sets the override on the test's isolated Symposium instance — no env var mutation, so tests run in parallel safely. Thread `&Symposium` through `find_workspace_root()`, `self_update()` / `check_upgrade()` / `latest_version()`, `install_cargo_crate()` / `install_cargo_crate_sync()`, and `cargo_install()` so all cargo invocations use the override. Co-authored-by: Claude <claude@anthropic.com>
Move the periodic update check from the binary into `self_update::maybe_check_for_update()` and call it from `cli::run()` so it's exercised by tests via `ctx.symposium()`. The binary only retains the hook path (hooks bypass cli::run) and the re-exec step (process-level concern). New integration tests: - sync_triggers_update_check: verifies sync runs the update check (mock cargo returns 99.0.0, state.toml records the check) - sync_skips_update_check_when_throttled: verifies 24h throttle - self_update_skips_check_when_disabled: verifies auto-update = off Co-authored-by: Claude <claude@anthropic.com>
Add Output::capturing() mode that collects messages into a buffer instead of printing. Update ctx.symposium() to use it so tests can inspect output. Assert that sync_triggers_update_check sees the "99.0.0 is available" warning and the self-update nudge. Co-authored-by: Claude <claude@anthropic.com>
Use expect_test snapshots to verify exact output for both the warn-enabled and warn-disabled cases: - sync_triggers_update_check: snapshot includes the "99.0.0 is available" warning before normal init output - self_update_skips_check_when_disabled: snapshot shows only normal init output with no update warning Co-authored-by: Claude <claude@anthropic.com>
Add auto_update_on_re_execs_into_new_binary: runs the real binary as a subprocess with auto-update = "on" and self-update-source = "source". The mock cargo's install handler replaces the binary with a script that prints "SURPRISE!". After auto-update + re-exec the test asserts the new binary actually ran. Also split maybe_check_for_update into two: - maybe_warn_for_update (sync, used by cli::run for warn-only path) - maybe_check_for_update (async, used by the binary for on + re-exec) The binary now runs the full check for all commands (not just hooks), so auto-update = "on" re-execs correctly for sync/init/etc. from_environment() reads SYMPOSIUM_CARGO env var so subprocess tests can inject mock cargo without touching process-global state in the test runner. Co-authored-by: Claude <claude@anthropic.com>
Extract AutoUpdateFixture helper for subprocess auto-update tests. Add auto_update_re_execs_on_hook alongside the existing sync test: pipes a SessionStart JSON payload into `cargo-agents hook claude session-start` and asserts the mock-installed "SURPRISE!" binary ran after re-exec. Co-authored-by: Claude <claude@anthropic.com>
When auto-update = "warn", the session-start hook now checks for a newer version and includes the nudge in the hook output's additionalContext field, so the agent can relay it to the user. Previously the warn path was silently skipped for hooks. The binary's startup check no longer runs the warn path for hooks (to avoid consuming the throttle window before the hook runs). The "on" re-exec path still runs for hooks in the binary. New test: session_start_hook_warns_about_update_in_context verifies the nudge appears in additionalContext via prompt_or_hook simulation. Co-authored-by: Claude <claude@anthropic.com>
On Linux, overwriting a running executable with `cat >` fails with ETXTBSY. Use a temp file + `mv -f` instead — atomic rename works even while the binary is executing. Co-authored-by: Claude <claude@anthropic.com>
… prompt - Remove the binary download path entirely (UpdateSource enum, target_triple, download_release, extract_tarball, extract_zip, install_binary, cargo_bin_dir). Self-update now always uses `cargo install symposium --force`. - Change auto-update default from "warn" to "on". - Add interactive auto-update prompt to `cargo agents init` (Auto-update / Warn / Off, defaulting to auto-update). - Update all docs and tests. Co-authored-by: Claude <claude@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Add
cargo agents self-updatewhich downloads prebuilt binaries from GitHub releases (falling back tocargo install), and startup auto-update checks gated by a newauto-updateconfig (off/warn/on, default warn). Introducestate.tomlto track the binary version and throttle update checks to once per 24 hours.New config keys:
auto-update: off | warn | on (default warn)self-update-source: binary | source (default binary)Disclosure questions
AI disclosure.
Questions for reviewers.