VT Code Update System Guide

August 10, 2026 · View on GitHub

This guide covers VT Code's update system, including release channels, version pinning, and configuration options.

Overview

VT Code includes a built-in update system that can check for and install updates from GitHub Releases. The system supports:

  • Multiple release channels (stable, beta, nightly)
  • Version pinning for staying on specific versions
  • Configurable update behavior via ~/.vtcode/update.toml
  • Download mirrors for better availability

Standalone updates use VT Code's native replacement pipeline: the updater selects the exact target archive, streams it with the configured timeout, verifies published SHA-256 metadata when available, rejects unsafe archive paths, and replaces only the vtcode/vtcode.exe executable. When an update is triggered from the TUI (/update or the startup update prompt), the pipeline reports per-phase progress — a live download progress bar with byte count and percentage, plus Verifying checksum, Extracting archive, and Installing new binary phase messages — so the update never appears to hang. Binaries built with the former self_update-based updater (v0.141.0–v0.141.4) cannot use this flow directly, but the legacy updater compatibility bridge lets them self-update to v0.141.6+ without a manual bootstrap install.

Asset extensions by platform

The updater picks the archive by target suffix — .zip for Windows (x86_64-pc-windows-msvc) and .tar.gz for macOS and Linux — then extracts the platform executable (vtcode on Unix, vtcode.exe on Windows) with flate2+tar or zip. Checksum sidecars are matched in this order: the modern <archive>.sha256, the legacy extension-stripped vtcode-<v>-<target>.sha256, then the aggregate checksums.txt. Windows ARM is unsupported until the build pipeline publishes that target; such users should use the install script.

Legacy updater compatibility bridge (v0.141.0-v0.141.4)

Releases v0.141.0 through v0.141.4 ship the self_update 1.0.0-rc.6 crate with the archive-tar feature but not compression-tar-gz, so their vtcode update fails on a .tar.gz archive with CompressionNotEnabledError: 'gz' compression not supported. These binaries are already shipped, so the fix has to work with their existing asset-selection logic rather than change it.

How the legacy updater selects an asset (verified against the crate source):

  1. It calls asset_for(target, Some("{target}.tar.gz")), which returns the first asset whose name contains(target) AND contains("{target}.tar.gz").
  2. GitHub's releases API returns the assets array sorted alphabetically by name (ascending) — upload order is irrelevant — so "first match" is the alphabetically-first matching asset.
  3. The downloaded file is saved under the asset's own name, and detect_archive reads the final path extension. Anything other than zip/tar/tgz/gz is treated as a plain uncompressed binary (ArchiveKind::Plain), and extract_file copies the raw bytes verbatim to <dir>/vtcode — no gzip feature required.

Starting with v0.141.6, every release also publishes a raw executable asset named compat-vtcode-<v>-<target>.tar.gz.compat. It contains the {target}.tar.gz substring (so the legacy identifier matches it) and its final extension is .compat (so it is treated as a plain binary). Crucially, the compat- prefix sorts before vtcode- (c < v), so it is the alphabetically-first match and the legacy updater picks it instead of the broken .tar.gz. The v0.141.5+ updater ignores these assets (its matcher requires starts_with("vtcode-") AND ends_with("{target}.tar.gz" / "{target}.zip")) and uses the real archive, so both generations install byte-identical binaries.

⚠️ The compat- prefix is load-bearing. Naming the asset vtcode-<v>-<target>.tar.gz.compat (no prefix) does not work: it sorts after the normal vtcode-<v>-<target>.tar.gz, so the legacy updater would still pick the broken .tar.gz and fail. The invariant "compat name sorts before the normal archive name" is enforced by scripts/tests/test_release_assets.sh.

These .compat assets are temporary and may be removed once the supported upgrade floor exceeds v0.141.4. They are generated by scripts/release-assets.sh from the same normal archives used by installers and covered by checksums.txt. Windows is included by default (the bridge also rescues Windows v0.141.0-v0.141.4 users, whose updater never matched the published .zip); set RELEASE_REQUIRE_WINDOWS=false only for an emergency macOS/Linux rescue when Windows CI is flaky.

Quick Start

Check for Updates

# Check and install updates
vtcode update

# Check only (don't install)
vtcode update --check

List Available Versions

# List recent versions
vtcode update --list

# List more versions
vtcode update --list --limit 20

Pin to a Specific Version

# Pin to a specific version
vtcode update --pin 0.85.3

# Unpin and resume following the channel
vtcode update --unpin

Release Channels

# Switch to beta channel
vtcode update --channel beta

# Switch to nightly channel
vtcode update --channel nightly

# Back to stable
vtcode update --channel stable

View Configuration

# Show current update configuration
vtcode update --show-config

Release Channels

VT Code follows three release channels:

Stable (Default)

  • Purpose: Production-ready releases
  • Update frequency: Every 2-4 weeks
  • Recommended for: Most users, production environments
  • Quality: Fully tested and validated
# ~/.vtcode/update.toml
channel = "stable"

Beta

  • Purpose: Pre-release testing
  • Update frequency: Weekly
  • Recommended for: Early adopters, testing new features
  • Quality: Feature-complete, minor bugs possible
# ~/.vtcode/update.toml
channel = "beta"

Nightly

  • Purpose: Bleeding edge builds
  • Update frequency: Daily (automated builds)
  • Recommended for: Contributors, extreme early adopters
  • Quality: May contain bugs, rapid iteration
# ~/.vtcode/update.toml
channel = "nightly"

Version Pinning

Version pinning allows you to stay on a specific version, disabling automatic updates until you unpin.

When to Pin

  • Waiting for a bug fix in the next release
  • Stability requirements for production
  • Testing compatibility with specific version
  • Avoiding a problematic release

Pin to a Version

vtcode update --pin 0.85.3

This creates/updates ~/.vtcode/update.toml:

[pin]
version = "0.85.3"

Unpin

vtcode update --unpin

Configuration File

Location: ~/.vtcode/update.toml

Example Configuration

# VT Code Update Configuration

# Release channel to follow
# Options: stable (default), beta, nightly
channel = "stable"

# Version pinning (optional)
# Uncomment to pin to a specific version
# [pin]
# version = "0.85.3"
# reason = "Waiting for bug fix in next release"
# auto_unpin = false

# Download mirrors (optional)
# [mirrors]
# primary = "https://github.com/vinhnx/vtcode/releases"
# fallbacks = [
#     "https://mirror.example.com/vtcode",
# ]
# geo_select = true

# Auto-update check interval in hours (0 = disable)
check_interval_hours = 24

# Download timeout in seconds
download_timeout_secs = 300

# Keep backup of previous version after update
keep_backup = true

# Auto-rollback on startup if new version fails
auto_rollback = false

Configuration Options

OptionTypeDefaultDescription
channelString"stable"Release channel: stable, beta, or nightly
pin.versionStringnullPinned version (null = follow channel)
pin.reasonStringnullUser note for pinning
pin.auto_unpinBooleanfalseAuto-remove pin after successful update
mirrors.primaryStringGitHubPrimary download mirror URL
mirrors.fallbacksArray[]Fallback mirror URLs
mirrors.geo_selectBooleantrueEnable geographic mirror selection
check_interval_hoursInteger24Hours between update checks (0 = disable)
download_timeout_secsInteger300Download timeout in seconds
keep_backupBooleantrueKeep backup of previous version
auto_rollbackBooleanfalseAuto-rollback on startup failure

CLI Reference

vtcode update

Check for and install updates.

Options:

  • --check - Check only, don't install
  • --force - Force reinstall even if up-to-date
  • --list - List available versions
  • --limit <N> - Number of versions to list (default: 10)
  • --pin <VERSION> - Pin to specific version
  • --unpin - Remove version pin
  • --channel <CHANNEL> - Set release channel
  • --show-config - Show current configuration

Examples:

# Check and install
vtcode update

# Check only
vtcode update --check

# List versions
vtcode update --list

# Pin version
vtcode update --pin 0.85.3

# Switch to beta
vtcode update --channel beta

Update Behavior

Managed Installs

If VT Code was installed via a package manager, the update system will detect this and provide the appropriate update command:

  • Homebrew: brew upgrade vtcode
  • Cargo: cargo install vtcode --force
  • npm: npm install -g @vinhnx/vtcode@latest --registry=https://npm.pkg.github.com
  • Standalone: Direct update via vtcode update

Backup and Rollback

When keep_backup = true (default), the previous version is kept after update. If auto_rollback = true, VT Code will automatically revert to the backup if the new version fails to start.

Update Checks

By default, VT Code checks for updates every 24 hours. The check timestamp is cached in ~/.cache/vtcode/last_update_check.

To disable automatic checks:

check_interval_hours = 0

Troubleshooting

Update Fails to Download

  1. Check internet connectivity
  2. Try a different mirror:
    [mirrors]
    primary = "https://mirror.example.com/vtcode"
    
  3. Increase timeout:
    download_timeout_secs = 600
    

Binary Permissions Issues

On Unix systems, ensure the binary has execute permissions:

chmod +x ~/.local/bin/vtcode

Rollback to Previous Version

If an update causes issues:

  1. Manual rollback: Download previous version from GitHub Releases
  2. Auto-rollback: If enabled, happens automatically on startup failure
    auto_rollback = true
    

Check Current Version

vtcode --version

Force Update

If you suspect corruption:

vtcode update --force

Integration with CI/CD

For automated environments, you can:

  1. Pin versions to ensure consistency:

    vtcode update --pin 0.85.3
    
  2. Disable auto-checks:

    check_interval_hours = 0
    
  3. Use specific channels for testing:

    channel = "beta"
    

Security Considerations

  • Updates are downloaded from GitHub Releases over HTTPS
  • Binary signatures are verified automatically
  • Backup versions are kept for rollback safety
  • Configuration file is user-controlled (~/.vtcode/update.toml)