fix(install): expose `altimate-code` from the standalone installers

HK
2h ago
+923-28

Issue for this PR

Closes #1563

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

  • install (curl one-liner): adds ~/.altimate/bin/altimate-code as a relative symlink to altimate. This happens after a download, after a --binary install, and on the "already installed" exit, so re-running the one-liner (or altimate upgrade) also fixes existing installs. On that exit, the alias is only refreshed when the matching binary is the one in ~/.altimate/bin, so it never runs a different version than the one just checked. Before, the script deleted any altimate-code it found there.
    • ln -sfn overwrites a pre-v0.7.1 altimate-code binary, so that name can't run a stale build. It also replaces a link to a directory instead of writing into it.
    • A real directory at that path is left alone, with a warning.
    • A --binary with an unrelated basename gets no alias.
  • install.ps1: writes two shims next to altimate.exe, both after install and on the "already installed" exit (with the same local-match rule; the install dir is compared as normalized paths in PowerShell and by identity with -ef in bash, so a symlinked HOME or a trailing slash in PATH still matches). Shims follow the binary across upgrades (which rename the running exe aside) and need no symlink privilege.
    • altimate-code.cmd ("%~dp0altimate.exe" %*, exit /b %ERRORLEVEL%) for cmd.exe and PowerShell.
    • An extensionless sh shim for Git Bash/MSYS shells, which don't use PATHEXT. npm also writes a .ps1 shim; it's left out because an execution policy that blocks scripts would break the name. Like every .cmd shim, the .cmd passes arguments through cmd.exe (%VAR% expands, unquoted & | ^ are interpreted), so the README tells scripts to call altimate.
    • An existing file or link at a shim path is replaced, never written through. Order: the .cmd first; then a stray altimate-code.exe, which PATHEXT would otherwise put in front of the .cmd, is removed once the .cmd exists; then the sh shim. A failed .cmd write leaves the old .exe and the sh shim as they were.
    • A leftover altimate-code.exe.old is cleaned up.
    • Alias failures only warn; they never abort the install.
  • altimate uninstall: for curl installs, the summary (including --dry-run) and the manual-removal hint list the other installer files that exist in ~/.altimate/bin: every alias form (including leftover altimate-code.exe.old / altimate.exe.old), plus altimate.exe when you're running from a copied altimate-code.exe. Directories are never listed, and nothing outside that directory is either, so an unrelated altimate-code in ~/.local/bin is never named. On Windows the commands are Remove-Item -LiteralPath '…' -Force (PowerShell), elsewhere rm '…'; paths are single-quoted literals, so $, backticks or quotes in them are never expanded.
  • Docs: README and the troubleshooting page no longer say the standalone install exposes only altimate.

How did you verify your code works?

  • The real one-liner, end to end on macOS arm64. cat install | bash (what curl … | bash runs) with a throwaway HOME and a system-only PATH, downloading the real v0.12.7 release with its checksum verified:
    • Fresh install: creates ~/.altimate/bin/altimate-code -> altimate, and altimate-code --version prints 0.12.7.
    • Default flags: the installer adds ~/.altimate/bin to .zshrc, and a fresh zsh -i finds altimate-code.
    • Pre-fix install, re-run: the alias is added on the "Version 0.12.7 already installed" path, with no re-download.
    • Stale legacy altimate-code binary, re-run: it is replaced by the alias.
    • Repeated re-run: still exactly one link.
    • Control: the same test against main's installer leaves only altimate, and altimate-code is command not found.
  • packages/opencode/test/install/install-alias.test.ts runs the real bash installer against a throwaway HOME. It covers:
    • --binary;
    • an offline download, with a curl stub serving a local release archive;
    • the already-installed exit;
    • a stale altimate-code binary;
    • re-runs;
    • a link to a directory, and a real directory, at the alias path;
    • altimate.exe → altimate-code.exe;
    • an unrelated --binary name.
  • packages/opencode/test/cli/uninstall-hint.test.ts covers the uninstall hint list for Unix, Windows, a copied alias, and directories outside ~/.altimate/bin.
  • test/windows/install.Tests.ps1 extracts Install-Alias from the script's syntax tree and covers:
    • the content of both shims;
    • the .cmd shim running for real, with cmd.exe standing in for altimate.exe, checking arguments and exit code;
    • a hard link, and a junction or directory link, at the shim path;
    • keeping altimate-code.exe, and the Git Bash shim, when the .cmd can't be written;
    • .old cleanup.
  • Locally with pwsh 7.6 + Pester 6.2: 17 pass, 2 skipped. The skipped ones (cmd.exe execution, a Windows directory symlink) only run on Windows; CI's Pester job runs them on windows-latest.
  • The extensionless shim ran under a real sh from a path containing a space. "a b", "%PATH%", "^&!", "$HOME" and "" were all forwarded unchanged, and exit code 7 propagated.
  • Each new regression test was checked by removing the code it guards and confirming the test fails.
  • bun test test/install test/cli/uninstall-hint.test.ts test/skill/release-v0.7.1-binary-adversarial.test.ts test/skill/release-v0.7.2-adversarial.test.ts test/branding test/upstream: 1131 pass. Typecheck and prettier pass.

Follow-ups (not changed here)

  • check_version and "already installed": it treats any altimate / altimate-code on PATH at the requested version as "already installed" and exits, even when that binary is outside ~/.altimate/bin (e.g. an npm or Homebrew install). That predates this PR. Here the alias is only refreshed when the match is the local binary.
  • Windows PowerShell 5.1: altimate upgrade and the documented one-liner run under 5.1, but CI's Pester job runs only pwsh 7. A second shell: powershell run would cover it.
  • 8.3 short-name PATH entries aren't expanded by the local-match check. Such an install skips the alias on the "already installed" exit; it never aliases the wrong binary.
  • Plugin docs: the "curl, Homebrew and PowerShell installers install only altimate" wording in altimate-claude-plugin#8 and altimate-codex-plugin#5 should be updated once this merges.

Cost side effects

None.

Screenshots / recordings

N/A, not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
  • I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Standalone installations now provide an altimate-code alias alongside altimate.
    • Windows installations support command-line and MSYS shell aliases, with safer handling of existing files.
    • Uninstall guidance now identifies and removes installer-created companion files.
  • Bug Fixes

    • Reinstalling or updating now refreshes aliases to point to the correct executable.
    • Existing installations avoid creating aliases for unrelated binaries or conflicting directories.
  • Documentation

    • Updated installation and troubleshooting guidance explains alias availability, Windows behavior, and compatibility with older releases.