简体中文 | English
This document covers every installation method in detail: the recommended installer script, manual binary installation with the same layout, go install, building from source, self-update, and uninstall/migration. For the shortest path, see the README Quick Start.
Configuration, database, and logs always live under ~/.token-usage (Windows: %USERPROFILE%\.token-usage). The script and manual binary installations also put the binary there — ~/.token-usage/bin/token-usage (Windows: %USERPROFILE%\.token-usage\bin\token-usage.exe) — exposed through your user PATH, with no sudo or administrator privileges needed; go install and the direct development build (go build) place the binary elsewhere (see their sections). The methods differ in upgrade semantics:
- Official Release binary (installed by the script below, by the AI-agent instruction, or manually): supports in-place self-update — the binary is the real file on PATH, which is exactly what the self-update source check requires.
- Built from source (
make build/go build): reports a dev form (Version = dev, orvX.Y.Z-devfor a plain-build pseudo-version) and cannot self-update by default; runtoken-usage update --forceto switch to an official Release asset (automatic updates then work normally), or rebuild and replace the file manually.
Published assets (the platforms with official binaries — also the platforms supported by self-update):
token-usage-darwin-arm64(macOS Apple Silicon)token-usage-darwin-amd64(macOS Intel)token-usage-windows-amd64.exe(Windows)
curl -fsSL https://raw.githubusercontent.com/YuLaiZ/token-usage/main/scripts/install.sh | bashTo pin a specific Release tag:
curl -fsSL https://raw.githubusercontent.com/YuLaiZ/token-usage/main/scripts/install.sh | TAG=vX.Y.Z bashThe script detects your architecture, downloads the latest stable official Release, verifies its SHA256 against the official SHA256SUMS, installs it to ~/.token-usage/bin/token-usage without sudo, automatically removes any leftover copy from the old installation layout (with manual-removal guidance when that directory is not writable, and with corresponding manual guidance in other cases — such as a directory occupying that path — or when deletion fails, without affecting the installation), and adds ~/.token-usage/bin to your user PATH by appending a marker block to your shell rc file (zsh and bash only — zsh: ~/.zshrc; bash: the first file login shells read — ~/.bash_profile first, then ~/.bash_login, then ~/.profile; for other shells the script prints manual PATH guidance instead). Open a new terminal and run token-usage version to confirm. To install an RC, pass its exact tag with TAG=vX.Y.Z-rc.N.
Non-login interactive shells (some IDE integrated terminals read
~/.bashrcinstead of login files) do not load the login file; addexport PATH="$HOME/.token-usage/bin:$PATH"there yourself if needed. Interactive zsh terminals always read~/.zshrc.
After installing the binary, the script also sets up shell completion automatically (skipped when INSTALL_DIR is overridden):
- zsh: before writing anything, the installer verifies the completion-directory chain is safe — it checks ownership, group/other writability, and macOS ACLs on every level from your home directory up to the filesystem root, and refuses to write when any level can be modified by others. Group/other-writable directories owned by you get a precise
chmod go-wrepair command; other findings — foreign ownership, threatening ACL entries, symlink or non-directory components — get case-specific guidance instead (manual inspection, ACL removal commands, or administrator repair). When the zsh completion system (compinit) is not enabled yet, it asks interactively:1repairs the reported group/other-writable directories withchmod go-w(the fix Homebrew itself recommends; no sudo is needed for directories you own, and a directory that cannot be repaired stops the whole step atomically with guidance) and enables standardcompinit,2enablescompinitwith the directory security check skipped (compinit -u),3skips completion. Without an interactive terminal the step is skipped with manual guidance. An existing completion marker is migrated idempotently — re-running the installer never duplicates it. - fish: the completion file is written into the fish completion directory automatically, with no prompts (an absolute
XDG_CONFIG_HOMEis respected; the same directory-chain safety checks apply, from the config root up). - bash: no automatic setup — the missing bash-completion package is the bottleneck, so the script prints a pointer to it instead.
Set INSTALL_COMPLETION=yes to run the zsh path non-interactively (useful for AI-agent one-line installs): it takes the recommended default — repair permissions and enable standard compinit, both without security trade-offs. Any completion-setup failure only prints a hint and never affects the installation result.
irm https://raw.githubusercontent.com/YuLaiZ/token-usage/main/scripts/install.ps1 -OutFile "$env:TEMP\install.ps1"
powershell -ExecutionPolicy Bypass -File "$env:TEMP\install.ps1"Two commands run in order: the first downloads the installer to a temporary file, the second executes it — paste both lines into one PowerShell window. The installer deliberately does not use the one-pipe irm ... | iex form: the downloaded script starts with a UTF-8 BOM, which Invoke-Expression cannot parse.
To pin a specific Release tag, run the downloaded script with -Tag:
powershell -ExecutionPolicy Bypass -File "$env:TEMP\install.ps1" -Tag vX.Y.ZThe script downloads the latest stable official Release, verifies its SHA256 against the official SHA256SUMS, installs it to %USERPROFILE%\.token-usage\bin\token-usage.exe without administrator privileges, and appends %USERPROFILE%\.token-usage\bin to the user PATH with a type-preserving registry write (the existing REG_EXPAND_SZ value type and %VAR% entries are kept as-is), then broadcasts WM_SETTINGCHANGE so the new PATH is picked up without signing out (if the broadcast fails, the script prints a sign-out-and-back-in hint). Open a new terminal window from the Start menu or taskbar and run token-usage version to confirm. To install an RC, pass its exact tag with -Tag vX.Y.Z-rc.N.
After the PATH step, the installer also offers to set up shell completion by writing a small guarded block into your PowerShell profile ($PROFILE, resolved per host — Windows PowerShell 5.1 and PowerShell 7 have separate profiles, so run the installer once in each if you use both). It asks [Y/n] with Y as the default. The block is written atomically (same-directory temp file, then rename); existing profile content is preserved byte-for-byte in any ASCII-compatible encoding (UTF-8 with BOM, UTF-8 without BOM, or GBK/ANSI); UTF-16-encoded profiles are left untouched with a manual pointer; and re-running the installer is idempotent — a complete, unmodified marker block is detected and skipped. Set $env:INSTALL_COMPLETION = 'yes' before running the script to skip the question and write the block directly. Completion-setup failures only print a hint and never affect the installation result.
On an old TLS environment the first
irmstep still runs before the script, so the in-script TLS fallback cannot rescue it: run[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12in the current session first, then run the download step.
A binary installed from an official Release can update itself in place:
token-usage update # update to the latest stable Release
token-usage update --check # only check; writes no local files
token-usage update --version vX.Y.Z # update (or check) a specific Release tagupdate only replaces the current binary when it is the official Release asset for the reported version — its SHA256 must match the official asset hash for that version. Development builds (Version = dev or a pseudo-version from make build, make build-all, or go install), symlinked copies, and version/hash mismatches are treated as untrusted: a plain update refuses to overwrite and prints manual-install guidance. Of these, a hash mismatch (a re-signed binary or go install pkg@vX.Y.Z) and a dev build can be overridden explicitly with update --force; symlinked copies and non-official tags cannot. Self-update supports exactly the platforms with official assets (darwin/arm64, darwin/amd64, windows/amd64); on any other platform, update reports that there is no official asset and asks you to install manually. See trust and source verification in the CLI Reference for the full rules, exit codes, side effects, and the Windows asynchronous-replacement note.
Why no symlink into PATH: the self-update source check requires the running executable to be the real binary file. A call through a symlink resolves to the symlink path and is rejected. That is why this layout puts
~/.token-usage/binitself on PATH instead of placing a link in another directory.
Manual installation performs the same layout by hand — the binary at ~/.token-usage/bin/token-usage (Windows: %USERPROFILE%\.token-usage\bin\token-usage.exe), with the bin directory added to your user PATH. A SHA256-verified official asset is equivalent to the script installation and supports in-place self-update.
# `releases/latest/download/...` always points to the newest stable Release
# and never resolves to a prerelease. To install a specific version, use the
# Releases page URL for that tag instead.
curl -fsSL -o token-usage-darwin-arm64 https://github.com/YuLaiZ/token-usage/releases/latest/download/token-usage-darwin-arm64
curl -fsSL -o SHA256SUMS https://github.com/YuLaiZ/token-usage/releases/latest/download/SHA256SUMS
# Verify the SHA256 against the Release's SHA256SUMS:
shasum -a 256 -c SHA256SUMS --ignore-missing
chmod u+x token-usage-darwin-arm64
mkdir -p ~/.token-usage/bin
mv token-usage-darwin-arm64 ~/.token-usage/bin/token-usageThen add ~/.token-usage/bin to your PATH: append this block to your shell rc file (zsh: ~/.zshrc; bash: the first file login shells read — ~/.bash_profile first, then ~/.bash_login, then ~/.profile):
# >>> token-usage path >>>
export PATH="$HOME/.token-usage/bin:$PATH"
# <<< token-usage path <<<Non-login interactive shells (some IDE integrated terminals read
~/.bashrcinstead of login files) do not load the login file; addexport PATH="$HOME/.token-usage/bin:$PATH"there yourself if needed. Interactive zsh terminals always read~/.zshrc.
Open a new terminal and verify with token-usage --help and token-usage version.
Downloaded the binary with a browser instead of
curl? Browser-saved files carry thecom.apple.quarantineattribute, and the official binaries are ad-hoc signed, which Gatekeeper does not accept for quarantined files: the first run is killed silently (no output, exit code 137). Re-signing in place fixes it:codesign --sign - --force ~/.token-usage/bin/token-usageRemoving the attribute alone (
xattr -d com.apple.quarantine ...) may not be enough because Gatekeeper caches its verdict. Files downloaded withcurl(or the official script) never get the attribute and are unaffected.Note the side effect: re-signing rewrites the binary's signature section, so its SHA256 no longer matches the official
SHA256SUMSand a plaintoken-usage updatetreats the binary as unverified and refuses to overwrite. Runtoken-usage update --forceto have the update replace it with an official asset (automatic updates then work normally again), or install manually.
# Download from the newest stable Release (latest/download never resolves to
# a prerelease; use the Releases page URL for a specific tag), then verify
# the SHA256 against the Release's SHA256SUMS:
curl.exe -fsSL -o token-usage-windows-amd64.exe https://github.com/YuLaiZ/token-usage/releases/latest/download/token-usage-windows-amd64.exe
curl.exe -fsSL -o SHA256SUMS https://github.com/YuLaiZ/token-usage/releases/latest/download/SHA256SUMS
# Verify the SHA256 against the Release's SHA256SUMS. Abort before installation
# if the exact asset entry is absent or its expected hash does not match:
$sumsEntry = Select-String -Path SHA256SUMS -Pattern '^[0-9a-fA-F]{64} token-usage-windows-amd64\.exe$' | Select-Object -First 1
if ($null -eq $sumsEntry) { throw 'SHA256SUMS has no hash for token-usage-windows-amd64.exe.' }
$expected = ($sumsEntry.Line -split '\s+')[0].ToLowerInvariant()
$actual = (Get-FileHash .\token-usage-windows-amd64.exe).Hash.ToLower()
if ($actual -ne $expected) { throw "SHA256 MISMATCH: expected $expected, got $actual" }
'SHA256 OK'
New-Item -ItemType Directory -Force $env:USERPROFILE\.token-usage\bin | Out-Null
Move-Item token-usage-windows-amd64.exe $env:USERPROFILE\.token-usage\bin\token-usage.exe -ForceThen append %USERPROFILE%\.token-usage\bin to the user PATH with a type-preserving registry write, which keeps the existing REG_EXPAND_SZ value type and %VAR% entries intact. The already-contained check below also matches existing unexpanded entries (e.g. %USERPROFILE%\.token-usage\bin) by expanding them first, mirroring the installer's semantics — expansion applies only to REG_EXPAND_SZ values. Do not use setx or [Environment]::SetEnvironmentVariable: setx truncates long values, and SetEnvironmentVariable rewrites the value as REG_SZ with %VAR% entries permanently expanded.
$dir = "$env:USERPROFILE\.token-usage\bin"
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true)
$raw = $key.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
$kind = if ($key.GetValueNames() -contains 'Path') { $key.GetValueKind('Path') } else { [Microsoft.Win32.RegistryValueKind]::ExpandString }
$norm = ($raw -split ';') | ForEach-Object {
$lit = $_.Trim().TrimEnd('\')
$exp = if ($kind -eq 'ExpandString') { [Environment]::ExpandEnvironmentVariables($_).Trim().TrimEnd('\') } else { $lit }
@($lit, $exp)
}
if ($norm -notcontains $dir) {
$new = if ([string]::IsNullOrEmpty($raw)) { $dir } else { $raw.TrimEnd(';') + ';' + $dir }
$key.SetValue('Path', $new, $kind)
}
$key.Close()A direct registry write does not broadcast the environment change: sign out and back in, then open a new terminal window from the Start menu or taskbar and verify with
token-usage --helpandtoken-usage version.
git clone https://github.com/YuLaiZ/token-usage.git && cd token-usage
make build # produces ./token-usage (make build-all produces dist/token-usage-windows-amd64.exe)Put the built binary into the bin directory and add it to your PATH exactly as in the official-asset steps above (~/.token-usage/bin/token-usage on macOS, %USERPROFILE%\.token-usage\bin\token-usage.exe on Windows). A source-built binary reports a dev form (Version = dev, or vX.Y.Z-dev for a plain-build pseudo-version) and cannot self-update by default; run token-usage update --force to switch to an official Release asset (automatic updates then work normally), or rebuild and replace the file under the bin directory manually.
go install github.com/YuLaiZ/token-usage/cmd/token-usage@latestThe binary is installed to $GOBIN (by default ~/go/bin); ensure that directory is on PATH. Configuration and logs remain under ~/.token-usage/. Verify the installation with token-usage --version. A binary installed with a Release tag (for example, go install github.com/YuLaiZ/token-usage/cmd/token-usage@vX.Y.Z) is not byte-identical to the official asset; run token-usage update --force once to replace it with an official Release asset, after which normal self-update works. The same applies when @latest resolves to a Release tag. If @latest resolves to a development version or an explicit pseudo-version, inspect token-usage version: dev and vX.Y.Z-dev displays are eligible for --force.
git clone https://github.com/YuLaiZ/token-usage.git && cd token-usage
go build -o token-usage ./cmd/token-usage
./token-usage --help
./token-usage --versionUninstalling leaves no system-wide leftovers:
-
Stop the daemon if it is running:
token-usage daemon stop. -
If autostart was ever enabled, first run
token-usage config set daemon.autostart false. This removes the autostart definition (the~/Library/LaunchAgents/<label>.plistfile on macOS, the Registry Run entry on Windows) so it does not keep pointing at a deleted binary and fail at every login. -
Delete the application directory:
rm -rf ~/.token-usage(Windows:Remove-Item -Recurse -Force $env:USERPROFILE\.token-usage). The current terminal may still have the deleted binary cached; runhash -rand confirmtoken-usageno longer resolves, or simply open a new terminal and confirm. -
Remove the PATH configuration.
macOS: delete the marker block from your shell rc file:
# >>> token-usage path >>> export PATH="$HOME/.token-usage/bin:$PATH" # <<< token-usage path <<<
Windows: preferably remove the
bindirectory entry and write the remaining entries back with the same type-preservingMicrosoft.Win32.Registrydirect write used at install time (deleting thePathvalue outright if no other entries remain), keeping theREG_EXPAND_SZvalue type and%VAR%literals. Like the install snippet, entry matching expands unexpanded entries first, but only forREG_EXPAND_SZvalues, so an existing%USERPROFILE%entry is removed as well:$dir = "$env:USERPROFILE\.token-usage\bin" $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true) if ($key.GetValueNames() -contains 'Path') { $raw = $key.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) $kind = $key.GetValueKind('Path') $kept = ($raw -split ';') | Where-Object { $lit = $_.Trim().TrimEnd('\') $exp = if ($kind -eq 'ExpandString') { [Environment]::ExpandEnvironmentVariables($_).Trim().TrimEnd('\') } else { $lit } $_ -and ($lit -ne $dir) -and ($exp -ne $dir) } if (@($kept).Count -gt 0) { $key.SetValue('Path', ($kept -join ';'), $kind) } else { $key.DeleteValue('Path') Write-Output 'No remaining entries; the Path value has been deleted.' } } else { Write-Output 'Path value not found; nothing to clean up.' } $key.Close()
or delete the
%USERPROFILE%\.token-usage\binentry through the modern "Edit environment variables for your account" dialog and verify thePathvalue type is stillREG_EXPAND_SZ(the legacy list editor has a known issue of rewriting it asREG_SZ). Do not usesetxor[Environment]::SetEnvironmentVariable— the former truncates values, the latter degrades the value type. After a direct registry write, sign out and back in (or confirm through the "Edit environment variables for your account" dialog) before new terminal windows pick up the change. -
If you ever followed the old symlink tutorial, also remove the leftover link:
/usr/local/bin/token-usageon macOS,%LOCALAPPDATA%\Microsoft\WindowsApps\token-usage.exeon Windows.
Migration notes:
- If an older
token-usagecopy sits earlier on PATH (the old Windows tutorial put the exe in an arbitrary directory), locate it withwhich token-usage/Get-Command token-usageand remove it; an earlier entry shadows the new layout. - If autostart was enabled before you reinstalled, run
token-usage config set daemon.autostart trueonce in a new terminal (after the PATH change has taken effect) so the definition is rebuilt at the new location. If the configuration file was deleted during uninstall, runtoken-usage config initfirst —config setfails when no configuration file exists.