ThreeKingdomsSlingshot/.claude/skills/unity-cli/references/diagnostics-maintenance.md

33 KiB
Raw Permalink Blame History

Diagnostics & maintenance — unity-cli command reference

Part of the unity-cli skill. See that skill's SKILL.md for CLI install, global flags, environment variables, exit codes, and common workflows. All global flags (--format json, --non-interactive, --yes, --proxy, …) apply to every command below.


Logs — application logs

# Show last 20 log lines (default)
unity logs

# Show last 50 lines
unity logs --tail 50

# Follow in real-time (like tail -f)
unity logs --follow

# Filter by level
unity logs --level error
unity logs --level warn

# Available levels: trace, debug, info, warn, error, fatal

The CLI writes its own cli-log.json (separate from the Hub's info-log.json) and records its version on every start. unity logs, unity bug, and unity doctor read the CLI's own log.

Not the Unity Editor log. unity logs shows the CLI's activity, not the Editor's Editor.log. To read Editor-side output — for example the compile errors that force an Editor into Safe Mode and block the Pipeline connection — read Editor.log directly (see integration-advanced.md → Recovering from Safe Mode for its per-platform path and the full recovery loop).


Doctor — system diagnostics

# Full system report
unity doctor --format json

# Includes: platform info, auth status, installed editors, recent log lines, resolved proxy
unity doctor --tail 50

unity doctor reports real session state (matching unity auth status) and surfaces the resolved proxy URL, its source, and auth source. It carries an Accelerator section alongside the Proxy one, reporting the resolved endpoint and its source and — when a project is in scope — that project's cache-server mode and pinned endpoint. Three states, mirroring Proxy: a table, a plain No Unity Accelerator configured. (the common case, not a fault), or Accelerator state unknown when the configuration could not be read. Nothing there is a check: whether the endpoint answers is doctor --ci's question, because the default collector is synchronous and cannot make a network call. It also runs environment health checks and reports pass/warn per check (in every output format): whether the unity binary's directory is actually on PATH (the top post-install pitfall on Windows, where a new terminal is needed), whether multiple unity binaries shadow each other on PATH, whether Windows long-path support is enabled, and whether a git credential helper is configured (git-credential-helper: advisory for the git-token flows in projects clone/create/link vcs; the row is omitted on machines without git).

A "Third-party components" section lists every open-source runtime dependency the binary bundles — the .NET runtime plus each direct NuGet package — with its version and SPDX license identifier, and points at https://spdx.org/licenses/ for the full texts (not embedded, to keep the binary small). It's generated from the CLI's own build configuration, so it can never drift from what actually shipped, and it's informational only — never a pass/fail check.


CI init — scaffold a working CI workflow

unity ci init writes a committed CI workflow generated from the project. Use it instead of assembling the steps by hand — it wires up the CLI's own CI features in the right order and encodes the parts that are otherwise learned by trial and error.

# GitHub Actions -> .github/workflows/unity.yml (the default provider).
# With no --project-path, it works on the directory you ran it from.
unity ci init

# GitLab CI -> .gitlab-ci.yml
unity ci init --provider gitlab

# Scope the workflow to a build target (validated like `unity build --target`)
unity ci init --target Android

# Review it before committing to anything
unity ci init --dry-run

# Another project; replace a workflow that is already there
unity ci init --project-path ./MyProject --overwrite

The generated workflow installs the CLI, restores the editor download cache and the project's Library/ folder, installs the editor version from ProjectSettings/ProjectVersion.txt, activates a license, runs unity doctor --ci as a preflight, runs the tests with a JUnit report, builds, uploads the report and the build, and returns the license seat in a teardown step that runs even when the job failed or was cancelled.

What it derives from the project: the editor version (rejected unless it parses as a real Unity version, since it is interpolated into an install command on the runner), and the editor module the build target needs where that is unambiguous — Android, iOS, tvOS, WebGL, WindowsStoreApps, VisionOS, Lumin. The standalone desktop targets get no module, because each has il2cpp / mono / server variants and picking one from the target alone would be a guess; asking for StandaloneOSX or StandaloneWindows64 warns that the install step needs a --module you choose.

Secrets are referenced by name only. The command never reads a credential and the generated file never contains one — it expects UNITY_SERVICE_ACCOUNT_ID, UNITY_SERVICE_ACCOUNT_SECRET, and UNITY_LICENSE_SERIAL to exist as repository secrets, and reports which ones to add after it writes.

Two things about licensing that the workflow states in comments, because they surprise people: service-account auth covers Unity services, not the editor licence, and unity license activate --personal is rejected outright for a service account. The generated step therefore activates from a serial, and ships the floating-server and offline-.ulf alternatives as commented blocks beside it.

The project rides --project-path, like list, status, mcp configure, pipeline install and collaboration — not a positional operand as on build / test / cache key. It takes a path, not a registry project name, and defaults to the current directory, so the common case is a bare unity ci init from the project root.

Interactive vs scripted. On a real terminal, anything you didn't pass is asked for: a picker for the provider, one for the build target, and one for how many parallel jobs to split the tests across (all three open on their default, so Enter accepts), plus a confirm before replacing a workflow that already exists. A flag always wins over its prompt, so --provider gitlab --target Android --shards 4 asks nothing.

Nothing prompts when any one of these holds — --non-interactive (or UNITY_NON_INTERACTIVE), a machine --format (json, ndjson, tsv), --format github, or a redirected stdout. In that case the unpassed values take their defaults (github, StandaloneLinux64, no sharding) and an existing workflow is an exit-2 error naming --overwrite rather than a question. That means a CI job or a script gets identical behaviour whether or not it happens to be attached to a terminal.

Splitting the suite: --shards <n>. Off by default, and offered by the picker on a terminal. Accepts 2 to 64 — 1 is rejected rather than generating a one-leg matrix, so there is no flag spelling for "no sharding"; omit it instead. More shards than tests is safe, because unity test --shard reports an empty slice and skips the editor instead of quietly running the whole suite.

unity ci init --shards 4
unity ci init --provider gitlab --shards 8

Two things the generated matrix handles that a hand-written one usually does not. unity test --shard N/M splits the suite using an NUnit report from an earlier run, because the Editor cannot enumerate tests without running them — so a cold pipeline has nothing to split. Rather than fail, one shard runs the whole suite to write that inventory while the rest stand down: the first run is green and costs exactly one full suite. And a stale inventory is the dangerous case, since a test added after it was written would belong to no shard and run nowhere — green, and not running the new test. So the cached inventory is bound to a hash of every .cs, .asmdef, .asmref and packages-lock.json in the repository, and any change to them re-seeds the suite in full. (unity cache key deliberately ignores script changes, which is right for a Library/ cache and wrong for this, so the inventory gets its own key.)

The trade: a run that touches C# pays for one full unsharded suite, and a run that does not — assets, scenes, shaders, config, a retry, a scheduled build — is split n ways. Never slower than the unsharded workflow, and never under-tested. The build gets its own job, since inside the matrix it would run once per shard and burn n licence seats; both providers aggregate the per-shard JUnit reports themselves, so there is no merge step.

--dry-run prints the workflow to stdout and nothing else, so it pipes into a file or a diff. --format json reports the written paths in data.paths, plus the resolved provider, editor version, build target, and module. Exit 2 on an unknown --provider, an invalid --target, an existing workflow file without --overwrite, or a stray positional argument; exit 6 when the directory isn't a Unity project or its editor version can't be read. Templates are embedded in the binary, so this works offline and always matches the CLI it ships with.


Doctor --ci — preflight before a long pipeline step

# First step of a CI job: fail in seconds instead of after a long build
unity doctor --ci

# Per-check results a workflow can branch on
unity doctor --ci --format json

# Failed checks become inline annotations on the pull request
unity doctor --ci --format github

--ci replaces the diagnostic report with a preflight: it verifies the environment can actually finish a build or test run and exits non-zero when it cannot, so a pipeline fails fast rather than tens of minutes into a build. It checks an activatable license, the project's required editor, free disk space, and reachability of the Unity services endpoint, and folds the PATH / long-path / git-credential-helper checks in as advisory rows that never fail a job.

Exit codes distinguish the two kinds of bad news, so a workflow can retry only what is worth retrying:

Exit Meaning
0 Every blocking check passed. Warnings do not fail the preflight.
6 A definitive failure — no license, the required editor is not installed, disk below the floor. Retrying will not help.
7 The preflight could not reach a verdict because a required service was unreachable. Worth a retry.

A 6 outranks a 7 when both occur, so a real blocker is never reported as retryable.

--ci also probes the configured Unity Accelerator, so a CI agent learns the cache server is down in seconds instead of discovering it as an unexplained twenty-minute import. This check never blocks, in any arm — an Accelerator is an accelerator, so an unreachable one is a warn (ACCELERATOR_UNREACHABLE, classified retryable) and a machine with none configured is an info row (ACCELERATOR_NOT_CONFIGURED). A project that does not use an Accelerator can never have its preflight failed by it. The probe targets the endpoint the CLI would hand to the Editor (the resolver's answer), not the project's own pinned endpoint.

Every check carries a machine-readable code (LICENSE_NONE, EDITOR_NOT_INSTALLED, DISK_SPACE_LOW, NETWORK_UNREACHABLE, …) plus a remediation hint. In --format json the per-check results stay in data even on failure, with one coded entry per failure in errors. Output is redacted and carries no tokens and no absolute user paths, so it is safe to paste into a public CI log.

--ci is always explicit — it is never inferred from CI=true, because a report that silently changed shape and exit code on a runner would be a trap. Note that the CLI already defaults to --format tsv whenever stdout is redirected, which in CI it usually is; that output leads with a verdict row.


Diagnose update — why this install is or is not updating

unity diagnose update
unity diagnose update --json

Reports how this install resolves updates: the channel it tracks, the manifest it reads, the version it found, and whichever condition is holding an update back. Reach for it when unity self-update reports nothing to do but a newer version is known to exist, or when an install seems pinned to an old version.


Diagnose proxy — proxy diagnostic report

# Print a redacted, paste-safe proxy diagnostic report for support
unity diagnose proxy

# Machine-readable
unity diagnose proxy --json

Reports the resolved proxy and where it came from, PAC configuration, CA bundle, and credential-store and Kerberos checks — redacted so it's safe to paste into a support ticket. A copy is also written to the logs directory. For per-request proxy logging over the course of a repro, use the global --log-proxy flag (or UNITY_LOG_PROXY=1), which writes one redacted entry per outbound request to proxy-request.json.


Diagnose accelerator — Unity Accelerator diagnostic report

# Resolved endpoint, project cache-server settings, and whether the endpoint answers
unity diagnose accelerator

# Machine-readable
unity diagnose accelerator --json

A working Accelerator and a broken one produce identical output apart from wall-clock time. This is the command that tells them apart. It reports four sections:

  • Resolved configuration — the endpoint and its source (env / settings / none), and whether the Accelerator was disabled. This command does not accept --accelerator or --no-accelerator (both are scoped to run / test / build), so it reports what the env var and the persisted setting resolve to — the endpoint any command would start from, before a one-shot override.
  • Environment variables — UNITY_ACCELERATOR by presence only, never by value (a host and port is infrastructure detail a support paste should not carry). The character length is included, enough to tell "set" from "set to empty".
  • Project cache server — the project's m_CacheServerMode (as Unity's own inspector labels it) and m_CacheServerEndpoint, and whether they agree with the resolved endpoint. There is no "void case": a project's cache-server mode never makes an injected endpoint moot — command-line flags always win — so the report states a mismatch as a fact without claiming which side the Editor uses.
  • Reachability — a raw TCP connect with a 5-second timeout, reporting elapsed time and a familiar error code on failure (ENOTFOUND, ECONNREFUSED, ETIMEDOUT, …). A successful connect proves the port is reachable, not that an import will get a cache hit, and the report says so.

An unreachable endpoint is a reported row, not a command failure — the command exits 0 having successfully diagnosed a broken endpoint. --format json emits the standard envelope; every other format writes the plaintext report raw to stdout so it survives a pipe or a CI log. --quiet is honoured. Full explanation of the mechanism: apps/cli/docs/accelerator.md.


Environment

# Show environment paths
unity env --format json

# Returns: user data path, editor install path, download cache path, config path, CLI version, resolved proxy

Version — machine-readable version object

# Bare version string (backward compatible, unchanged)
unity --version

# Structured version object
unity version --format json

# The --version flag also honors an explicit format set before it
unity --format json --version

unity version reports the CLI version, release channel (stable, beta, …), commit, platform, architecture, and runtime — the same version fact env and doctor carry, as one parseable object. It honors --format (human, json, tsv, ndjson); human output is the bare version string.

A bare unity --version still prints only the version string, so scripts that parse it are unaffected. The --version flag switches to the structured object only when an explicit machine format is given before it (unity --json --version, unity --format json --version, or UNITY_FORMAT=json unity --version) — the flag terminates parsing, so a trailing format after --version is not seen. For order-independent machine output, prefer the unity version subcommand.


Cache

# Show cache location and size
unity cache info --format json

# Clear download cache
unity cache clean --yes

Cache key — deterministic key for CI cache steps

unity cache key prints one hash derived from the inputs that actually invalidate a project's build cache: the editor version, the resolved package set, and (optionally) the build target. Use it as the key: of a CI cache step instead of hand-rolling the hashing.

# Print the key for the project in the current directory
unity cache key

# Scope it to a build target — a Library/ folder is platform-specific
unity cache key --target Android

# Any project path
unity cache key ./MyProject

Whenever stdout is not an interactive terminal — a pipe, a redirect, or any CI runner — the key is the only thing written to it, so it drops straight into a shell substitution or a workflow expression. (On an interactive colour terminal the CLI's usual one-line banner still prints above it, as it does for every command; --quiet suppresses that.)

Pass the project path if the workflow's working directory isn't the project:

- id: cachekey
  run: echo "key=$(unity cache key MyProject --target Android)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v4
  with:
    path: MyProject/Library
    key: Library-${{ steps.cachekey.outputs.key }}

What moves the key, and what doesn't:

  • Changes when the editor version (ProjectSettings/ProjectVersion.txt), the package set (Packages/packages-lock.json, falling back to Packages/manifest.json), or --target changes.
  • Does not change for unrelated edits — scenes, scripts, assets, or project settings other than the version file.
  • Is identical across machines and operating systems for the same inputs. Line endings and a UTF-8 BOM are normalized before hashing, so a Windows checkout with core.autocrlf and a Linux one agree. No paths, usernames, or timestamps enter the hash.

--format json returns the key plus each component's raw value and hash, so one invocation can build a layered key with fallback levels:

unity cache key --target Android --format json

--component <editor|packages|target> prints just one component's hash for the fallback levels themselves. Under --format json it also sets data.key to that component, so jq -r .data.key means the same thing either way:

# Restore any cache built for this editor, whatever the packages were
unity cache key --component editor

Runs without an editor and without network access. Exit 2 on an unknown --target or --component (a silently-accepted typo would produce a key nothing else matches); exit 6 when the directory isn't a Unity project. A project with neither package file still emits a key, with a warning that it doesn't cover the package set.


The CLI defaults to opt-out. On the first interactive run a prompt is shown once before any data is collected; it now requires an explicit y or n — pressing Enter alone re-asks instead of silently recording the opt-out default, so an accidental keystroke can't lock in an answer. Ctrl-C skips the prompt and keeps the opt-out default. Non-interactive, CI, piped, and --quiet contexts silently keep the opt-out default.

Running unity analytics opt-in or opt-out permanently answers the first-run prompt, so a choice recorded from a script (where the prompt never appears) isn't asked again on the next interactive run. To suppress the prompt without recording a choice — for a wrapper script on an interactive terminal that must never absorb it — set UNITY_NO_CONSENT_PROMPT (analytics stay off until you explicitly opt in).

# Show current consent status
unity analytics status
unity analytics status --format json

# Opt in to anonymous usage data collection
unity analytics opt-in

# Opt out (the default)
unity analytics opt-out

Consent is stored in the shared Hub privacy preferences, so opting out in the CLI also opts out in Hub, and vice versa. When opted in, the CLI records which commands run (registered command names only — never your arguments, paths, or project names), editor uninstalls, project open/create (editor version and template id only), CLI self-update/uninstall outcomes, unity shell and unity mcp session usage, and unity doctor / unity bug results. When opted out (the default), no events are sent.

Separately from analytics, the CLI reports anonymous crashes and errors via Sentry to help fix bugs (no IP address or hostname; home-directory paths and token-like values scrubbed before send), aligned with the Unity Hub. Opting in to analytics additionally attaches an anonymized machine id so crash-free-user rates can be computed; opted-out users stay fully anonymous. Set UNITY_NO_CRASH_REPORT to disable crash reporting entirely.

Separately again, every run — including one that never sees the consent prompt (CI, an agent, a machine --format) — sends one anonymous cli telemetry usage ping, so total CLI usage can be counted regardless of the analytics opt-in state. It is not a measure of who opted in and carries no user, machine, or session identifier (a fresh random id per invocation, never persisted) and no consent state — just which Unity tool sent it, the CLI version, and whether the run looks like CI. Set UNITY_NO_CLI_INVOKED_TELEMETRY=1 to disable it. unity analytics status discloses it alongside the opt-in state.


Changelog

Show the release notes for the installed CLI version, or with --target, for another release. --target latest shows the newest release on your channel, the one unity self-update would install:

unity changelog
unity changelog --target 1.0.0-beta.10
unity changelog --target latest
unity changelog --format json

Docs — version-matched Unity documentation

Open the documentation page for a class or topic in the default browser, matched to the editor version of the project you are in:

unity docs GameObject                    # scripting API reference
unity docs --manual Coroutines           # the manual instead
unity docs --search "physics raycast"    # the documentation search results
unity docs --url Rigidbody.AddForce      # print the URL, do not open it
unity docs --cli use-unity-cli           # the Unity CLI's own documentation
unity docs --hub project-create          # the Unity Hub documentation
unity docs --cloud developer-data/collection-settings   # Unity Cloud

The version is read from the current project's ProjectSettings/ProjectVersion.txt — no editor has to be installed. Outside a project, the current documentation is used. --editor-version overrides it and accepts either a full version (6000.0.26f1) or a version branch (6000.0); an unparseable value is a usage failure rather than a silent fallback to the wrong version's docs.

For an agent, --url is the useful mode: it prints the resolved address to stdout and opens nothing, so it composes into a citation or a review comment. --format json carries the same address plus the version the page was matched to (null when no project version was found), which is how a caller tells a version-matched answer from a fallback one.

A topic that cannot name a documentation page — a phrase, or anything with a path separator — falls back to the documentation search for that section rather than composing an address that would 404. A trailing .html is dropped, so a page name pasted out of a browser address bar resolves.

Documentation sets outside the Editor docs

--cli, --hub and --cloud look the topic up on Unity's documentation platform instead of the Editor documentation. These are separate bodies of documentation rather than newer addresses for the same pages, so the two sites answer different questions:

Flag Documentation
(default) Editor scripting API reference, version-matched
--manual Editor manual, version-matched
--cli The Unity CLI
--hub The Unity Hub
--cloud Unity Cloud

Those pages are not versioned by editor, so they take no version: --editor-version alongside one of them is a usage failure rather than a value that gets quietly dropped. The four selectors are mutually exclusive, and passing two is a usage failure too rather than one of them silently winning.

Page names on these sets are lowercase and hyphenated, and may carry more than one segment (developer-data/collection-settings). Anything else — a phrase, or a name in the wrong case — falls back to the platform's search page, the same fallback rule the Editor sections use.


Language

# Show current language and available options
unity language

# Set language by code
unity language --set en
unity language --set ja
unity language --set zh-hans

# Alias
unity lang --set ko

On a TTY with no flags, shows an interactive selection prompt. --set accepts common spellings of a language code — BCP-47 (ja-JP), locale (ja_JP), a bare language (ja), or a bare region (jp) — and resolves them case-insensitively when the match is unambiguous (zh still asks you to pick zh_cn or zh_tw). Display names and ordering come from the shared Hub language catalog. The regional variants Spanish (Latin America), French (Canada), and Portuguese (Portugal) are no longer offered; Spanish, French, and Portuguese (Brazil) remain.


Completion — shell tab completion

Generate and install shell completion scripts:

# Supported shells: bash, zsh, fish, powershell
unity completion bash
unity completion zsh
unity completion fish
unity completion powershell

Bug — report a bug

Interactive bug reporter that collects system info and recent logs, then submits to Unity:

# Interactive — prompts for each field
unity bug

# Non-interactive — supply the report through flags (works from scripts, CI, piped shells)
unity bug \
  --title "Editor crashes on project open" \
  --description "Opening MyGame hard-crashes the editor." \
  --steps "Open the CLI" --steps "Run unity open MyGame" --steps "Editor window closes" \
  --reproducibility always \
  --area editor \
  --email you@example.com \
  --attachments ./crash.log ./notes.txt \
  --share-project .

Prompts for title, description, email, reproducibility level, and which area the issue is in. As of 0.1.0-beta.8 it collects the same diagnostic system information as the Unity Hub bug reporter (including GPU details).

The report can also be supplied entirely through flags — --title, --description, --steps (repeatable, one line per value), --reproducibility <first-time|sometimes|always>, and --email (defaults to your Unity account email when signed in; otherwise required). On a terminal, any flags you pass skip their prompts and the remaining fields still ask; a non-interactive run submits without prompting. A non-interactive run with missing or invalid fields fails fast with a usage error (exit 2) listing the exact flags to add.

Use --area <cli|pipeline-package|editor|licensing|not-sure> to say which part of Unity the issue is in: the CLI itself, the connection to the Editor or the Pipeline package (com.unity.pipeline), the Editor or your project, or licensing and signing in. Pass it whenever you know, because a failure that surfaces in CLI output is otherwise easy to misroute as a CLI bug when the Editor or the Pipeline package is at fault. It's optional and never blocks a report: pass not-sure when you don't know, or leave it out. On a terminal without --area, the reporter asks, with "Not sure" preselected; a non-interactive run without it submits with no area, the same report it sent before the flag existed. An unknown value is a usage error (exit 2). The answer is sent with the report as an Issue area: line in the report text, which is what triage sees.

Use --attachments <paths...> (repeatable) to attach extra files — for example a crash log or a zipped copy of a subset of assets. Each path must be an existing, readable file; a folder is rejected (zip it yourself first), and a missing or unreadable path fails fast with a usage error (exit 2) naming the offending path.

Use --share-project <path> (use . for the current directory) to attach a copy of the Unity project the bug is about — the same stripped-project packaging the Editor's bug reporter uses. It sends the source folders plus a slimmed Library, excluding the regenerable caches and build output (Library caches, Temp, Build, Logs, VCS/IDE metadata, MemoryCaptures, CrashReports), so you don't have to zip the project yourself. A path that isn't a Unity project fails fast with exit 2. The archive is streamed from disk during upload, so there's no size limit — even a multi-gigabyte project copy uploads without being buffered in memory.

Interactively, when you don't pass --attachments or --share-project, the reporter asks whether to attach files and whether to include a project copy. When the area answer is editor or pipeline-package, the project-copy question first explains why a copy helps with those issues; it still defaults to no, and nothing is shared unless you answer yes. Everything — attachments and the project copy — is bundled into the same archive as the auto-collected logs.

unity bug mcp: check for known issues before filing

Before filing a report, add Unity's Issue Tracker MCP server to an AI assistant so it can search for known issues on your behalf:

unity bug mcp claude
unity bug mcp --list
unity bug mcp cursor --local
unity bug mcp claude --dry-run

unity bug mcp [client] is exactly unity mcp configure [client] --server issue-tracker. It delegates to the same mcp configure execution with the target server fixed, so it accepts the same client argument and the same --list, --local, --yes, and --dry-run flags (no --server flag here, since the server is already fixed). See the MCP configuration section in integration-advanced.md for the full client list, config paths, and what each flag does; unity bug --help also points here. This adds no new required prompt to the bug-report wizard, since it's a separate, optional subcommand, and the interactive wizard prints a one-line reminder about it before asking its own questions.


Self-update — update the CLI itself

# Check for available updates
unity self-update --check --format json

# Show changelog for the new version
unity self-update --changelog

# Update (interactive confirmation)
unity self-update

# Update without prompts
unity self-update --yes

# Install a specific version (v0.2.0 works too; latest is the same as no --target)
unity self-update --target 0.2.0

# Select update channel (stable or beta)
unity self-update --channel beta

# Dry-run: show what would change
unity self-update --dry-run

# Rollback to previous version
unity self-update --rollback

unity self-update detects how the CLI was installed and updates accordingly (unity upgrade is still accepted as an alias):

  • curl | sh install — keeps updating itself in place.
  • Linux AppImage — updates in place: downloads the new .AppImage artifact, verifies its checksum against the release manifest, and atomically replaces the AppImage you launched (--rollback restores the previous one). The embedded zsync update info is preserved, so external updaters (AppImageUpdate, Gear Lever) keep working.
  • Package-manager install — points you at the owning manager instead of replacing the binary. The .deb and .rpm packages are published to Unity's apt and rpm repositories on every beta and GA release (rpm packages are GPG-signed), so a package-managed install stays current through the system package manager: sudo apt update && sudo apt upgrade unity-cli on Debian/Ubuntu, sudo dnf upgrade unity-cli on Fedora/RHEL.

Downloads go through the CLI’s regular download engine: an interrupted download (a dropped connection, a closed lid, a Ctrl-C) resumes from where it left off on the next unity self-update, and a Brotli-compressed artifact is preferred when the release publishes one — verified against its own checksum and again after decompression. A release with no compressed artifact for your platform falls back to the raw download.

--check, --changelog, and --dry-run work everywhere. The background "update available" notice is package-manager-aware: when the release manifest says your install's package manager already carries the new version, the notice suggests that manager's exact upgrade command instead of unity self-update; installs whose manager doesn't carry the release yet stay quiet.

The same background check also warns when a self-installed unity and a Homebrew-managed one are both on PATH — a state where which unity keeps resolving to the self-installed copy while brew upgrade updates the other, so the two silently drift apart. The notice points at unity self-uninstall -y to remove the self-installed copy so Homebrew is the only one managing updates going forward.


Self-uninstall — remove the CLI

# Uninstall the CLI (interactive confirmation)
unity self-uninstall

# Uninstall without prompts
unity self-uninstall --yes

# Also remove config and data files
unity self-uninstall --purge --yes

# Dry-run: show what would be removed
unity self-uninstall --dry-run

unity implode was removed in 0.1.0-beta.8 (it was previously a deprecated alias). Use unity self-uninstall.