| 1 | # Installing Codewhale |
| 2 | |
| 3 | > 阅读简体中文版:[zh_hans/INSTALL.md](zh_hans/INSTALL.md) (not yet updated for this revision) |
| 4 | |
| 5 | Codewhale is an open-source coding agent that runs in your terminal. You give |
| 6 | it a task ("fix the failing test", "add a CLI flag"). It reads your repository, |
| 7 | edits files and runs commands. In the default **Ask** posture it applies file |
| 8 | edits inside the workspace immediately (and shows you the diff), but asks before |
| 9 | running shell commands, so commit or stash anything you care about first. It |
| 10 | works with many model providers. **DeepSeek** is the default. |
| 11 | |
| 12 | The command is `codewhale`. `codew` is a shorter alias for the same program. |
| 13 | |
| 14 | This guide was written by installing **v0.10.0** (released 2026-09-22) on a |
| 15 | fresh **Ubuntu 24.04 x86_64** machine, on every path described here. Every |
| 16 | command shown was run and its output checked (see the [install receipts](https://github.com/codewhale-hq/Codewhale/blob/37ecdfcc49bc68a9b0d058b97c3946e62c34bd31/docs/install-report/v0.10.0-2026-09-23/RECEIPTS.md)). Steps that |
| 17 | could not be run on that machine are marked **(untested on this VM: reason)**. |
| 18 | macOS, Windows and Android are out of scope, apart from a few notes. A second |
| 19 | pass re-ran the installer, manual-download, archive and npm paths, the no-key |
| 20 | checks and zsh completion on **macOS 26.1 (Apple silicon)**; see |
| 21 | [macOS notes](#macos-notes). Steps that need a model call were not re-run |
| 22 | there. |
| 23 | |
| 24 | Install commands that use `latest` resolve to the latest **published** GitHub |
| 25 | Release or package. Between releases, `main` may already describe the next |
| 26 | version (for example a v0.10.1 source candidate before its tag). A |
| 27 | candidate isn't installable until its tag, checksums and release assets |
| 28 | exist. |
| 29 | |
| 30 | --- |
| 31 | |
| 32 | ## 60-second quickstart (Linux or macOS) |
| 33 | |
| 34 | ```bash |
| 35 | # 1. Install. Downloads two checksum-verified binaries into ~/.local/bin (no sudo). |
| 36 | curl -fsSL https://codewhale.net/install.sh | sh |
| 37 | |
| 38 | # 2. Make sure ~/.local/bin is on your PATH, now and in future terminals. |
| 39 | echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # zsh: use ~/.zshrc |
| 40 | export PATH="$HOME/.local/bin:$PATH" |
| 41 | codewhale --version # -> codewhale 0.10.0 (1be1a703b975) |
| 42 | |
| 43 | # 3. Give it a DeepSeek API key (from https://platform.deepseek.com/api_keys). |
| 44 | codewhale auth set --provider deepseek # prompts for the key; nothing is echoed |
| 45 | codewhale auth status --provider deepseek # "active source: secret store" |
| 46 | |
| 47 | # 4. Run your first task inside a git repository. |
| 48 | cd ~/your-project |
| 49 | codewhale |
| 50 | ``` |
| 51 | |
| 52 | In the TUI, type something concrete: |
| 53 | |
| 54 | ```text |
| 55 | create a Python file primes.py that prints the first 10 primes, run it, and show me the output |
| 56 | ``` |
| 57 | |
| 58 | Codewhale writes the file, shows you a diff, then asks **APPROVAL: bash |
| 59 | python3 primes.py – Do you want to proceed?** Press `y` to allow it once. It |
| 60 | runs the command and reports the output. Press `Ctrl-D` (with an empty input |
| 61 | box) to quit. It prints the command to resume the session later. |
| 62 | |
| 63 | > **If nothing happens after you send your first message,** you have no key |
| 64 | > configured. v0.10.0 doesn't warn you in that case. Press **F3**. If DeepSeek |
| 65 | > shows `missing key`, press Enter, paste the key, then pick a model and |
| 66 | > confirm. |
| 67 | |
| 68 | --- |
| 69 | |
| 70 | ## Contents |
| 71 | |
| 72 | 1. [Before you start](#1-before-you-start) |
| 73 | 2. [Install: recommended installer](#2-recommended-installer-curl--sh) |
| 74 | 3. [Install: manual download from GitHub Releases](#3-manual-download-from-github-releases) |
| 75 | 4. [Install: npm](#4-npm) |
| 76 | 5. [Install: Cargo / build from source](#5-cargo-and-building-from-source) |
| 77 | 6. [Install: Homebrew (Linux) and Nix](#6-homebrew-on-linux-and-nix) |
| 78 | 7. [Updating and rolling back](#7-updating-and-rolling-back) |
| 79 | 8. [API keys and providers](#8-api-keys-and-providers) |
| 80 | 9. [Shell completions](#9-shell-completions) |
| 81 | 10. [Running it: TUI, headless, resume](#10-running-it) |
| 82 | 11. [Terminal notes (Ghostty and others)](#11-terminal-notes) |
| 83 | 12. [Uninstalling and what Codewhale leaves behind](#12-uninstalling) |
| 84 | 13. [Troubleshooting](#13-troubleshooting) |
| 85 | 14. [Appendix: other platforms (not re-tested in this revision)](#appendix-other-platforms-not-re-tested-in-this-revision) |
| 86 | |
| 87 | --- |
| 88 | |
| 89 | ## 1. Before you start |
| 90 | |
| 91 | | You need | Why | |
| 92 | |---|---| |
| 93 | | Linux x86_64 or arm64, or macOS | Prebuilt binaries exist for these. The Linux binaries are **static** (musl), so they have no glibc or libdbus dependency and run on any distro. | |
| 94 | | `curl` (or `wget`) and `sha256sum` (or `shasum`) | The installer uses them to download and verify. | |
| 95 | | A model provider key, e.g. [DeepSeek](https://platform.deepseek.com/api_keys) | Codewhale does nothing useful without a model. | |
| 96 | | `git` (recommended) | Codewhale works best inside a git repository. | |
| 97 | | Optional: Python 3, Node.js 20+ | If present, Codewhale enables its Python and JS execution tools (`codewhale doctor` lists them). | |
| 98 | |
| 99 | **Which install path?** |
| 100 | |
| 101 | * **Most people:** the [recommended installer](#2-recommended-installer-curl--sh). |
| 102 | It's the fastest (about 6 s here), verifies checksums, and supports |
| 103 | `codewhale update`. |
| 104 | * **Air-gapped or security-reviewed machines:** |
| 105 | [manual download](#3-manual-download-from-github-releases). |
| 106 | * **You already manage CLI tools with npm:** [npm](#4-npm). |
| 107 | * **No prebuilt binary for your platform, or you want to build it yourself:** |
| 108 | [Cargo](#5-cargo-and-building-from-source). |
| 109 | |
| 110 | Pick **one**. Several installs on one machine end up fighting over PATH (see |
| 111 | [Troubleshooting](#13-troubleshooting)). |
| 112 | |
| 113 | **Privacy note:** Codewhale sends aggregate usage counts (PostHog) **by |
| 114 | default**. To turn this off permanently: |
| 115 | `codewhale config set telemetry false`, or export `CODEWHALE_TELEMETRY=0`, |
| 116 | which always wins. The TUI also checks GitHub for updates at startup |
| 117 | (`[update] check_for_updates` in `~/.codewhale/config.toml`). |
| 118 | |
| 119 | --- |
| 120 | |
| 121 | <a id="recommended-official-github-releases"></a> |
| 122 | |
| 123 | ## 2. Recommended installer (`curl | sh`) |
| 124 | |
| 125 | **Prerequisites:** curl, `sha256sum` (Linux) or the built-in `shasum` (macOS), |
| 126 | a writable home directory. No sudo, no Node, no Rust. |
| 127 | |
| 128 | ```bash |
| 129 | curl -fsSL https://codewhale.net/install.sh | sh |
| 130 | ``` |
| 131 | |
| 132 | What it does (verified): |
| 133 | |
| 134 | * It detects your platform (`linux-x64`, `linux-arm64`, `macos-x64`, |
| 135 | `macos-arm64`). It refuses Android/Termux and riscv64 with a clear message. |
| 136 | * It downloads `codewhale-<platform>`, `codew-<platform>` and |
| 137 | `codewhale-artifacts-sha256.txt` from the latest GitHub Release, and verifies |
| 138 | both binaries against the manifest. If either doesn't match, it stops before |
| 139 | installing anything (`codewhale install: checksum mismatch for …`). |
| 140 | * It installs `~/.local/bin/codewhale` and `~/.local/bin/codew`: two identical |
| 141 | 78 MB files. |
| 142 | * It **never uses sudo and never edits your shell profile.** It refuses to |
| 143 | install into system or package-manager directories (`/usr/bin`, |
| 144 | `~/.cargo/bin`, Homebrew, `node_modules`, `/nix/store`…) and refuses to |
| 145 | overwrite a *different* existing `codewhale`. |
| 146 | |
| 147 | Expected output: |
| 148 | |
| 149 | ``` |
| 150 | Installing Codewhale for linux-x64 |
| 151 | Release assets: https://github.com/codewhale-hq/CodeWhale/releases/latest/download |
| 152 | Install dir: /home/you/.local/bin |
| 153 | Checksums verified |
| 154 | Installed checksummed release commands: |
| 155 | /home/you/.local/bin/codewhale |
| 156 | /home/you/.local/bin/codew |
| 157 | … |
| 158 | PATH selects no codewhale command; this install is /home/you/.local/bin/codewhale |
| 159 | … |
| 160 | Put /home/you/.local/bin first on PATH in future shells (run once; this installer does not edit shell profiles): |
| 161 | echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc |
| 162 | Then run: . ~/.bashrc (or open a new terminal) |
| 163 | … |
| 164 | ``` |
| 165 | |
| 166 | ### macOS notes |
| 167 | |
| 168 | Re-checked on macOS 26.1, Apple silicon (`macos-arm64`), with a fresh `HOME`: |
| 169 | |
| 170 | * The installer printed `Installing Codewhale for macos-arm64`, verified |
| 171 | checksums with the system tools, and installed `codewhale` and `codew` |
| 172 | (64 MiB each, Mach-O arm64) in 4.3 s. Both report |
| 173 | `codewhale 0.10.0 (1be1a703b975)`. They ran without a Gatekeeper prompt. |
| 174 | * When Node isn't on `PATH`, it also prints `Computer Use is included and needs |
| 175 | Node.js 20 or newer on PATH.` The core TUI works without Node, but Computer Use |
| 176 | and the JavaScript execution tool (`js_execution`) stay unavailable until Node |
| 177 | is on `PATH`. |
| 178 | * `codewhale doctor` behaves as on Linux (exit 0, `All checks complete!` with no |
| 179 | key, file-based secret store under `~/.codewhale/secrets/`), except that it |
| 180 | reports `✓ sandbox available: macos-seatbelt`. |
| 181 | |
| 182 | ### Put it on your PATH |
| 183 | |
| 184 | If the installer says `PATH selects no codewhale command`, `~/.local/bin` isn't |
| 185 | on your PATH **in this shell**. The `codewhale.net/install.sh` installer then |
| 186 | prints the matching line from the block below for your `$SHELL` (zsh, bash, |
| 187 | fish, or a POSIX `sh`; for any other shell, or a directory name with quotes, |
| 188 | `$`, backticks or backslashes, it tells you to add the directory yourself). It |
| 189 | never edits a shell profile itself. The `install.sh` inside a release archive |
| 190 | prints only the current-shell `export` line. On Ubuntu and Debian, `~/.profile` adds |
| 191 | `~/.local/bin`, but only if the directory existed when you *logged in*. So: |
| 192 | |
| 193 | * a new SSH or login shell picks it up automatically; |
| 194 | * a new terminal **window** on a desktop (GNOME Terminal, Ghostty, …) usually |
| 195 | doesn't, until you log out and back in. I hit |
| 196 | `bash: codewhale: command not found` in Ghostty right after installing. |
| 197 | |
| 198 | Fix it once: |
| 199 | |
| 200 | ```bash |
| 201 | echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc # bash (macOS login bash: ~/.bash_profile, or ~/.profile if only that exists) |
| 202 | # echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc # zsh |
| 203 | # fish_add_path ~/.local/bin # fish (untested on this VM) |
| 204 | export PATH="$HOME/.local/bin:$PATH"; hash -r |
| 205 | command -v codewhale codew |
| 206 | ``` |
| 207 | |
| 208 | ### Options |
| 209 | |
| 210 | ```bash |
| 211 | # Choose the directory (must be absolute; created if missing) |
| 212 | curl -fsSL https://codewhale.net/install.sh | CODEWHALE_INSTALL_DIR="$HOME/.local/codewhale/bin" sh |
| 213 | # Install a specific release |
| 214 | curl -fsSL https://codewhale.net/install.sh | CODEWHALE_VERSION=v0.9.13 sh |
| 215 | # Show help |
| 216 | curl -fsSL https://codewhale.net/install.sh | sh -s -- --help |
| 217 | ``` |
| 218 | |
| 219 | ### Verify |
| 220 | |
| 221 | ```bash |
| 222 | codewhale --version # codewhale 0.10.0 (1be1a703b975) |
| 223 | codew --version # same |
| 224 | codewhale doctor # diagnostics; see the note in §8 about what it does NOT check |
| 225 | ``` |
| 226 | |
| 227 | ### Re-running the installer |
| 228 | |
| 229 | * Same version already installed: harmless. It prints |
| 230 | `Already installed: …` and exits 0. |
| 231 | * Different version already installed: it **refuses** |
| 232 | (`codewhale install: refusing to replace existing …/codewhale`), exits 1 and |
| 233 | changes nothing. It downloads ~160 MB before refusing. Use |
| 234 | [`codewhale update`](#7-updating-and-rolling-back) instead. |
| 235 | |
| 236 | ### Upgrade / uninstall |
| 237 | |
| 238 | * Upgrade: `codewhale update` (see §7). |
| 239 | * Uninstall: `rm ~/.local/bin/codewhale ~/.local/bin/codew`, then see §12 for |
| 240 | data. |
| 241 | |
| 242 | --- |
| 243 | |
| 244 | ## 3. Manual download from GitHub Releases |
| 245 | |
| 246 | Use this when you want to see and verify every byte yourself. Releases: |
| 247 | <https://github.com/codewhale-hq/CodeWhale/releases>. Each platform has **bare |
| 248 | binaries** (`codewhale-linux-x64`, `codew-linux-x64`, …) and an **archive** |
| 249 | (`codewhale-linux-x64.tar.gz`) that holds the same two binaries plus an |
| 250 | `install.sh`. |
| 251 | |
| 252 | ### 3a. Bare binaries |
| 253 | |
| 254 | ```bash |
| 255 | mkdir -p ~/codewhale-dl && cd ~/codewhale-dl |
| 256 | base=https://github.com/codewhale-hq/CodeWhale/releases/latest/download |
| 257 | curl -fsSLO "$base/codewhale-linux-x64" # use linux-arm64 on ARM |
| 258 | curl -fsSLO "$base/codew-linux-x64" |
| 259 | curl -fsSLO "$base/codewhale-artifacts-sha256.txt" |
| 260 | sha256sum -c codewhale-artifacts-sha256.txt --ignore-missing |
| 261 | # codew-linux-x64: OK |
| 262 | # codewhale-linux-x64: OK |
| 263 | mkdir -p ~/.local/bin |
| 264 | install -m 755 codewhale-linux-x64 ~/.local/bin/codewhale |
| 265 | install -m 755 codew-linux-x64 ~/.local/bin/codew |
| 266 | ``` |
| 267 | |
| 268 | Then [put `~/.local/bin` on PATH](#put-it-on-your-path) and run |
| 269 | `codewhale --version`. On macOS the assets are `codewhale-macos-arm64` and |
| 270 | `codew-macos-arm64` (`-macos-x64` on Intel), and the built-in `shasum` verifies |
| 271 | them (tested on macOS 26.1, Apple silicon): |
| 272 | |
| 273 | ```bash |
| 274 | /usr/bin/shasum -a 256 -c codewhale-artifacts-sha256.txt --ignore-missing |
| 275 | # codew-macos-arm64: OK |
| 276 | # codewhale-macos-arm64: OK |
| 277 | ``` |
| 278 | |
| 279 | The `codewhale-macos-arm64.tar.gz` archive verifies the same way against |
| 280 | `codewhale-bundles-sha256.txt`, and its `./install.sh` installs into |
| 281 | `~/.local/bin` (tested). |
| 282 | |
| 283 | To pin a release, replace `latest/download` with `download/vX.Y.Z`, and take |
| 284 | the manifest from the same tag. |
| 285 | |
| 286 | ### 3b. Archive |
| 287 | |
| 288 | ```bash |
| 289 | cd "$(mktemp -d)" |
| 290 | base=https://github.com/codewhale-hq/CodeWhale/releases/latest/download |
| 291 | curl -fsSLO "$base/codewhale-linux-x64.tar.gz" |
| 292 | curl -fsSLO "$base/codewhale-bundles-sha256.txt" # note: *bundles*, not *artifacts* |
| 293 | sha256sum -c codewhale-bundles-sha256.txt --ignore-missing |
| 294 | # codewhale-linux-x64.tar.gz: OK |
| 295 | tar -xzf codewhale-linux-x64.tar.gz |
| 296 | cd codewhale-linux-x64 && ./install.sh # -> ~/.local/bin; PREFIX=/some/dir ./install.sh -> /some/dir/bin |
| 297 | ``` |
| 298 | |
| 299 | The archive's `install.sh` behaves like the website installer: no sudo, it |
| 300 | leaves differing existing files alone, and it prints the same PATH hint. |
| 301 | |
| 302 | **Upgrade:** `codewhale update` works for both 3a and 3b, because they're |
| 303 | "direct binary" installs. **Uninstall:** delete the two files (see §12). |
| 304 | |
| 305 | --- |
| 306 | |
| 307 | ## 4. npm |
| 308 | |
| 309 | **Prerequisites:** Node.js 18+ and npm, with a **global prefix you can write |
| 310 | to**. npm installs the registry's latest published version, never an |
| 311 | unpublished source candidate. |
| 312 | |
| 313 | ```bash |
| 314 | npm install -g codewhale |
| 315 | codewhale --version |
| 316 | ``` |
| 317 | |
| 318 | The package is a small wrapper. Its `postinstall` step downloads the same |
| 319 | `codewhale`/`codew` release binaries, checks them against the release's SHA-256 |
| 320 | manifest, and links `codewhale` and `codew` into npm's global `bin`. The whole |
| 321 | thing took 6 s here. |
| 322 | |
| 323 | **Windows npm sessions:** Node remains the native program's launcher for the |
| 324 | whole session. A process-name kill such as `taskkill /IM node.exe` or |
| 325 | `Get-Process node | Stop-Process -Force` can interrupt this and other npm |
| 326 | Codewhale sessions and prevent normal terminal cleanup. Stop only the server |
| 327 | PID you started or the process owning its port, or use Codewhale's task |
| 328 | cancellation. The Windows |
| 329 | native archive/installer avoids this npm-parent dependency; this does not |
| 330 | remove Node requirements for optional JavaScript tools. Codewhale's Windows |
| 331 | shell safety floor holds recognized image-wide Node kills even in Full Access. |
| 332 | An external hard kill or an arbitrary program that terminates the launcher |
| 333 | cannot be made graceful by this shell-command check. |
| 334 | |
| 335 | ### If you get `EACCES: permission denied` |
| 336 | |
| 337 | That means Node is installed system-wide (apt, `/usr/local`, `/opt`), and your |
| 338 | user can't write to its global prefix: |
| 339 | |
| 340 | ``` |
| 341 | npm error code EACCES |
| 342 | npm error Error: EACCES: permission denied, mkdir '/opt/node22/lib/node_modules/codewhale' |
| 343 | ``` |
| 344 | |
| 345 | **Don't use `sudo npm`.** Either use a per-user Node (nvm, fnm, volta), or |
| 346 | point npm at a directory you own. I tested the second option: |
| 347 | |
| 348 | ```bash |
| 349 | npm config set prefix "$HOME/.npm-global" |
| 350 | echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc |
| 351 | export PATH="$HOME/.npm-global/bin:$PATH" |
| 352 | npm install -g codewhale |
| 353 | command -v codewhale codew # ~/.npm-global/bin/codewhale, ~/.npm-global/bin/codew |
| 354 | ``` |
| 355 | |
| 356 | ### Notes |
| 357 | |
| 358 | * npm hides the download progress. Add `--foreground-scripts` to see it |
| 359 | (`codewhale: selected GitHub Releases for v0.10.0 … done.`). The chosen |
| 360 | source is also written to |
| 361 | `$(npm prefix -g)/lib/node_modules/codewhale/bin/downloads/codewhale.source`. |
| 362 | * The package uses 157 MB on disk. |
| 363 | * On macOS 26.1 (Apple silicon, Homebrew Node 25) an install into a user-owned |
| 364 | prefix (`npm install -g --prefix <dir> codewhale`) took 3 s and linked |
| 365 | `codewhale` and `codew`, both `codewhale 0.10.0 (1be1a703b975)`. |
| 366 | * **Upgrade:** `npm install -g codewhale@latest`. `codewhale update` refuses |
| 367 | on npm installs. It prints migration instructions and exits 1 with |
| 368 | `error: The package-managed executable was not changed.` |
| 369 | * **Specific version:** `npm install -g codewhale@0.9.13`. |
| 370 | * **Uninstall:** `npm uninstall -g codewhale`. This removes only the program, |
| 371 | not your data (§12). |
| 372 | |
| 373 | --- |
| 374 | |
| 375 | <a id="4-install-via-cargo-any-tier-1-rust-target"></a><a id="7-build-from-source"></a> |
| 376 | |
| 377 | ## 5. Cargo and building from source |
| 378 | |
| 379 | Use this if there's no prebuilt binary for your platform, or you want to |
| 380 | compile it yourself. One Cargo package is required: |
| 381 | `codewhale-cli` installs the `codewhale` command. npm and prebuilt releases also |
| 382 | expose `codew` as a convenience name for the same compiled runtime; Cargo does |
| 383 | not create that alias, so add `alias codew=codewhale` to your shell rc if you |
| 384 | want the short name. |
| 385 | |
| 386 | ### Prerequisites (Debian/Ubuntu) |
| 387 | |
| 388 | ```bash |
| 389 | sudo apt-get install -y build-essential pkg-config libdbus-1-dev git |
| 390 | # Rust via rustup (the distro's cargo is too old for this edition-2024 workspace) |
| 391 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y |
| 392 | source "$HOME/.cargo/env" |
| 393 | rustc --version # the workspace declares rust-version = 1.89 |
| 394 | ``` |
| 395 | |
| 396 | `libdbus-1-dev` **is required**. Without it the build fails after about a |
| 397 | minute with: |
| 398 | |
| 399 | ``` |
| 400 | error: failed to run custom build command for `libdbus-sys v0.2.7` |
| 401 | The system library `dbus-1` required by crate `libdbus-sys` was not found. |
| 402 | ``` |
| 403 | |
| 404 | Fedora/RHEL: `sudo dnf install -y gcc make pkgconf-pkg-config dbus-devel` |
| 405 | **(untested on this VM: Ubuntu only)**. |
| 406 | |
| 407 | ### 5a. From crates.io |
| 408 | |
| 409 | ```bash |
| 410 | cargo install codewhale-cli --locked |
| 411 | codewhale --version |
| 412 | ``` |
| 413 | |
| 414 | Tested result: **works**, with current stable Rust (1.98.1). |
| 415 | * It took **25 min 31 s** on 4 vCPU and 15 GB RAM, and pulled about 470 MB |
| 416 | into `~/.cargo/registry`. |
| 417 | * It installs one 122 MB file, `~/.cargo/bin/codewhale`. That's a normal |
| 418 | glibc-linked binary, and it needs `libdbus-1` at runtime. |
| 419 | * `codewhale --version` prints `codewhale 0.10.0`, with no commit hash. |
| 420 | * Headless and TUI smoke tests passed. |
| 421 | |
| 422 | > **v0.10.0 declared "Rust 1.88+", which was wrong.** The workspace now |
| 423 | > declares 1.89, the version CI's MSRV job builds. With 1.88.0 the v0.10.0 |
| 424 | > install fails in seconds: |
| 425 | > `rustc 1.88.0 is not supported by the following package: serde-saphyr@1.3.0 requires rustc 1.89`. |
| 426 | > Use current stable (`rustup update stable`). |
| 427 | |
| 428 | ### 5b. From a git checkout |
| 429 | |
| 430 | ```bash |
| 431 | git clone --depth 1 --branch v0.10.0 https://github.com/codewhale-hq/CodeWhale.git |
| 432 | cd CodeWhale |
| 433 | cargo install --path crates/cli --locked # installs ~/.cargo/bin/codewhale |
| 434 | ``` |
| 435 | |
| 436 | Things to know (observed): |
| 437 | |
| 438 | * The repo contains `rust-toolchain.toml` (`channel = "stable"`). The first |
| 439 | `cargo` command inside the checkout **silently downloads the latest stable |
| 440 | toolchain** (about 250 MB), whatever your default is. |
| 441 | * The workspace treats every compiler warning as an error. With Rust 1.89 |
| 442 | the build **fails** after about 11 minutes with 8 |
| 443 | `error: this lint expectation is unfulfilled` errors in `codewhale-tui`. Use |
| 444 | the stable toolchain the repo selects. Don't pass an older `+toolchain`. |
| 445 | * The workspace release profile uses thin LTO. On a 4-vCPU / 15 GB VM, the |
| 446 | `codewhale-tui` crate alone compiled for more than an hour, peaking at |
| 447 | 6–8 GB of RAM. Budget 16 GB or more, and expect this to be the slowest install |
| 448 | path by far. `target/` grew past 1.2 GB. |
| 449 | |
| 450 | Tested result: **works** on the repo-selected stable Rust (1.98.1). |
| 451 | * `Finished release profile … in 83m 12s`. A Nix build competed for CPU and |
| 452 | memory for most of that time, so treat it as an upper bound. |
| 453 | * `target/` ended at **3.1 GB**. Delete it afterwards with `cargo clean`. |
| 454 | * The binary reports `codewhale 0.10.0 (dev)`, and `exec` worked. |
| 455 | * Cargo prints `warning: default toolchain implicitly overridden with |
| 456 | stable-x86_64-unknown-linux-gnu by rustup toolchain file`, which is harmless. |
| 457 | * **Cargo builds provide no `codew`.** |
| 458 | |
| 459 | **Upgrade:** re-run the same `cargo install … --force` (for crates.io, you can |
| 460 | add `--version X.Y.Z`). `codewhale update` refuses Cargo installs. |
| 461 | **Uninstall:** `cargo uninstall codewhale-cli`, then §12. |
| 462 | |
| 463 | --- |
| 464 | |
| 465 | ## 6. Homebrew on Linux and Nix |
| 466 | |
| 467 | ### Homebrew on Linux: works, but not with the command the old docs gave |
| 468 | |
| 469 | Prerequisite: Homebrew itself. Its installer needs sudo **once**, to create |
| 470 | `/home/linuxbrew/.linuxbrew`. Without sudo rights it stops with |
| 471 | `Insufficient permissions to install Homebrew to "/home/linuxbrew/.linuxbrew"`. |
| 472 | Ask an admin to run |
| 473 | `sudo mkdir -p /home/linuxbrew/.linuxbrew && sudo chown $USER /home/linuxbrew/.linuxbrew`, |
| 474 | then re-run the installer. Afterwards, add |
| 475 | `eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)"` to `~/.bashrc`, |
| 476 | as its "Next steps" say. |
| 477 | |
| 478 | ```bash |
| 479 | brew install Hmbown/deepseek-tui/codewhale # full name: taps and trusts in one step |
| 480 | ``` |
| 481 | |
| 482 | The two-step form (`brew tap Hmbown/deepseek-tui` then `brew install |
| 483 | codewhale`) **fails on Homebrew 7.x**: |
| 484 | |
| 485 | ``` |
| 486 | Error: Refusing to load formula hmbown/deepseek-tui/codewhale from untrusted tap hmbown/deepseek-tui. |
| 487 | Run `brew trust --formula hmbown/deepseek-tui/codewhale` or `brew trust hmbown/deepseek-tui` to trust it. |
| 488 | ``` |
| 489 | |
| 490 | Run `brew trust hmbown/deepseek-tui` first, or use the full name above. |
| 491 | |
| 492 | Tested with Homebrew 7.0.6 against the v0.10.0 tap formula: the install took |
| 493 | 73 s. The tap formula tracks the latest release and downloads the official |
| 494 | release binaries, so there's no compile. It provides **both** `codewhale` and |
| 495 | `codew`. The `Hmbown/deepseek-tui` tap formula also depends on `node`, which |
| 496 | pulled in 31 bottles (~560 MB) on Linux. That `node` dependency belongs to |
| 497 | this tap formula only. The core TUI runs without Node; Computer Use and the JS |
| 498 | execution tool use it when it is on PATH. |
| 499 | |
| 500 | * **Upgrade:** `brew upgrade codewhale`. (`codewhale update` refuses, and |
| 501 | suggests migrating.) |
| 502 | * **Uninstall:** `brew uninstall codewhale && brew untap Hmbown/deepseek-tui`. |
| 503 | This also autoremoves the tap's node dependency and anything else it pulled |
| 504 | in. Homebrew's |
| 505 | download cache (`~/.cache/Homebrew`, ~330 MB) stays until |
| 506 | `brew cleanup --prune=all`. |
| 507 | |
| 508 | ### Nix: partially tested |
| 509 | |
| 510 | ```bash |
| 511 | # flakes are still experimental; the tested setup enabled them once: |
| 512 | mkdir -p ~/.config/nix |
| 513 | echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf |
| 514 | nix run github:codewhale-hq/CodeWhale -- --version |
| 515 | # one-off alternative (untested on this VM): nix --extra-experimental-features 'nix-command flakes' run github:codewhale-hq/CodeWhale -- --version |
| 516 | ``` |
| 517 | |
| 518 | Nix 2.35 installed fine; single-user mode needs `/nix` created by root once. |
| 519 | Flakes resolved. What I learned before stopping: |
| 520 | |
| 521 | * There's **no binary cache**, so this is a full source build of the |
| 522 | **main branch**, not the v0.10.0 release. The binary reports |
| 523 | `codewhale 0.10.0 (dev)`. |
| 524 | * The build step took 30 min on 4 cores. The package then runs its **test |
| 525 | suite** (`doCheck`), which recompiles the workspace in test mode. That took |
| 526 | over 70 minutes and more than 8 GB of RAM for one rustc process, and I |
| 527 | stopped it at 105 minutes. So `nix run` completing, `nix build`, and |
| 528 | `nix profile install/remove` are **(untested on this VM: build did not |
| 529 | finish in the time budget; the VM's proxy also required an |
| 530 | `--override-input fenix …` workaround)**. |
| 531 | * Nix provides only `codewhale`; there's no `codew` (it builds just the |
| 532 | `codewhale-cli` package). |
| 533 | |
| 534 | Unless you already live in Nix, use §2 instead. |
| 535 | |
| 536 | --- |
| 537 | |
| 538 | ## 7. Updating and rolling back |
| 539 | |
| 540 | These work for installs from §2 and §3 (direct binaries). Package-manager |
| 541 | installs (npm, Cargo, Homebrew) must be updated with their own tool. |
| 542 | |
| 543 | ```bash |
| 544 | codewhale update --check |
| 545 | # Current binary: /home/you/.local/bin/codewhale |
| 546 | # Current version: v0.9.13 |
| 547 | # Latest stable release: v0.10.0 |
| 548 | # Update available. Run `/home/you/.local/bin/codewhale update` to install v0.10.0. |
| 549 | codewhale update |
| 550 | # Downloading codewhale-linux-x64... |
| 551 | # SHA256 checksum verified against codewhale-artifacts-sha256.txt from GitHub Releases. |
| 552 | # ✅ Successfully updated to v0.10.0! |
| 553 | # Updated binaries: |
| 554 | # - /home/you/.local/bin/codewhale (codewhale-linux-x64) |
| 555 | # - /home/you/.local/bin/codew (codewhale-linux-x64) |
| 556 | ``` |
| 557 | |
| 558 | It updates `codewhale` **and** `codew` together. It took 10 s here. Run it |
| 559 | again and you get `Already up to date; no download needed.` Other options: |
| 560 | `--beta` and `--proxy <URL>`. |
| 561 | |
| 562 | <a id="roll-back-to-a-previous-release"></a> |
| 563 | |
| 564 | ### Rolling back (e.g. to v0.9.13) |
| 565 | |
| 566 | `codewhale update` never downgrades, and `CODEWHALE_VERSION=0.9.13 codewhale |
| 567 | update` just says "Already up to date". To roll back, replace the files: |
| 568 | |
| 569 | ```bash |
| 570 | dir="$(dirname "$(command -v codewhale)")" # the install PATH actually selects |
| 571 | rm "$dir/codewhale" "$dir/codew" |
| 572 | curl -fsSL https://codewhale.net/install.sh | CODEWHALE_VERSION=v0.9.13 CODEWHALE_INSTALL_DIR="$dir" sh |
| 573 | hash -r; codewhale --version # codewhale 0.9.13 (a0b81f619b66) |
| 574 | ``` |
| 575 | |
| 576 | Tested with both the default `~/.local/bin` and a custom |
| 577 | `CODEWHALE_INSTALL_DIR`. Use it only for installer, manual or archive |
| 578 | installs. Never point it at an npm, Cargo or Homebrew directory. |
| 579 | |
| 580 | Or keep both versions side by side, and put the old one first on PATH: |
| 581 | |
| 582 | ```bash |
| 583 | curl -fsSL https://codewhale.net/install.sh | CODEWHALE_VERSION=v0.9.13 CODEWHALE_INSTALL_DIR="$HOME/.local/codewhale-0.9.13" sh |
| 584 | export PATH="$HOME/.local/codewhale-0.9.13:$PATH"; hash -r |
| 585 | ``` |
| 586 | |
| 587 | To return to the latest after an in-place rollback, run `codewhale update`. |
| 588 | (Tested: 0.9.13 → 0.10.0.) |
| 589 | |
| 590 | npm: `npm install -g codewhale@0.9.13`. Cargo: |
| 591 | `cargo install codewhale-cli --version 0.9.13 --locked --force` **(untested on |
| 592 | this VM: only 0.10.0 was built)**. |
| 593 | |
| 594 | --- |
| 595 | |
| 596 | ## 8. API keys and providers |
| 597 | |
| 598 | ### Where Codewhale looks for a key (first match wins) |
| 599 | |
| 600 | 1. `--api-key <KEY>` on the command line |
| 601 | 2. `api_key` in `~/.codewhale/config.toml` |
| 602 | 3. the secret store written by `codewhale auth set` |
| 603 | 4. the environment variable (`DEEPSEEK_API_KEY` for DeepSeek) |
| 604 | |
| 605 | This order matters. **A key in config or the secret store beats |
| 606 | `DEEPSEEK_API_KEY`.** If you rotate your key by exporting a new env var, an |
| 607 | old stored key keeps being used. I tested this: a wrong key in `config.toml` |
| 608 | plus the correct env var gives `Authentication Fails … ****beef is invalid`. |
| 609 | |
| 610 | ### Ways to set a DeepSeek key (all tested) |
| 611 | |
| 612 | **Environment variable.** Good for trying it out and for CI: |
| 613 | ```bash |
| 614 | export DEEPSEEK_API_KEY=sk-... # add to ~/.bashrc / ~/.zshenv to persist |
| 615 | ``` |
| 616 | |
| 617 | **`auth set`.** Saves the key for every folder: |
| 618 | ```bash |
| 619 | codewhale auth set --provider deepseek # prompts: "Enter API key for deepseek:" |
| 620 | printf '%s\n' "$KEY" | codewhale auth set --provider deepseek --api-key-stdin # scripted |
| 621 | # -> saved API key for deepseek to file-based ("/home/you/.codewhale/secrets/secrets.json") (config contains metadata only) |
| 622 | ``` |
| 623 | The file-based message prints the resolved secret-store path; an explicit |
| 624 | `CODEWHALE_HOME` changes that location. |
| 625 | |
| 626 | On Linux, the key is stored in **plaintext** in |
| 627 | `~/.codewhale/secrets/secrets.json`, with mode 0600. It is not in an OS |
| 628 | keyring. Note that in v0.10.0, `auth set` also writes |
| 629 | `default_text_model = "deepseek-v4-pro"` into your config, switching you from |
| 630 | the default `deepseek-flash` to the pricier Pro model. Change it back with |
| 631 | `/model` in the TUI, or edit `~/.codewhale/config.toml`. |
| 632 | |
| 633 | **Inside the TUI.** Press **F3** (or type `/provider`), select DeepSeek, press |
| 634 | Enter, paste the key (masked), pick a model, and confirm. This also writes the |
| 635 | secret store, and keeps `deepseek-flash`. |
| 636 | |
| 637 | **Config file.** `~/.codewhale/config.toml`: |
| 638 | ```toml |
| 639 | [providers.deepseek] |
| 640 | api_key = "sk-..." |
| 641 | ``` |
| 642 | |
| 643 | ### Check which key is active |
| 644 | |
| 645 | ```bash |
| 646 | codewhale auth status --provider deepseek |
| 647 | # active source: env (last4: ...xxxx) # or: secret store / config / missing |
| 648 | # lookup order: config -> secret store -> env |
| 649 | codewhale doctor --probe-api |
| 650 | # · Testing connection... ✓ API connection successful |
| 651 | ``` |
| 652 | |
| 653 | Use `auth status`. Plain `codewhale doctor` does **not** tell you: it prints |
| 654 | `deepseek: env_source=not inspected` even when the key is set, and it exits 0 |
| 655 | even when no key is found. |
| 656 | |
| 657 | ### Remove a stored key |
| 658 | |
| 659 | ```bash |
| 660 | codewhale auth clear --provider deepseek |
| 661 | # cleared API key for deepseek from config and secret store |
| 662 | ``` |
| 663 | |
| 664 | It doesn't unset `DEEPSEEK_API_KEY` in your shell, and it leaves the |
| 665 | `default_text_model` line that `auth set` added. |
| 666 | |
| 667 | ### Other providers |
| 668 | |
| 669 | `codewhale auth list` shows about 50 providers (OpenRouter, Anthropic, OpenAI, |
| 670 | Moonshot, Ollama, …). The pattern is the same: |
| 671 | `codewhale auth set --provider <name>`, or the provider's env var. Local models |
| 672 | (Ollama, vLLM, SGLang) need no key. Only DeepSeek was tested here. |
| 673 | |
| 674 | --- |
| 675 | |
| 676 | <a id="8-shell-completions"></a> |
| 677 | |
| 678 | ## 9. Shell completions |
| 679 | |
| 680 | ```bash |
| 681 | # bash (needs the bash-completion package) |
| 682 | mkdir -p ~/.local/share/bash-completion/completions |
| 683 | codewhale completion bash > ~/.local/share/bash-completion/completions/codewhale |
| 684 | |
| 685 | # zsh |
| 686 | mkdir -p ~/.zfunc |
| 687 | codewhale completion zsh > ~/.zfunc/_codewhale |
| 688 | # in ~/.zshrc, if not already there: |
| 689 | # fpath=(~/.zfunc $fpath) |
| 690 | # autoload -Uz compinit && compinit |
| 691 | |
| 692 | # fish |
| 693 | mkdir -p ~/.config/fish/completions |
| 694 | codewhale completion fish > ~/.config/fish/completions/codewhale.fish |
| 695 | ``` |
| 696 | |
| 697 | Each script registers both `codewhale` and `codew`. `codewhale completions` is |
| 698 | an alias. Open a new shell afterwards. Regenerate after upgrading. |
| 699 | |
| 700 | How well they work in v0.10.0 (tested interactively): |
| 701 | |
| 702 | * **bash:** fully works (`codewhale comp<Tab>`, `codew auth <Tab><Tab>`). |
| 703 | * **fish:** sub-commands complete with descriptions, but |
| 704 | `codewhale completion <Tab>` offers files instead of shell names. |
| 705 | * **zsh:** only the first word completes. After a sub-command |
| 706 | (`codewhale auth <Tab>`), zsh wrongly lists the top-level commands again |
| 707 | (same on macOS zsh 5.9, where it offers all 126 top-level entries). |
| 708 | |
| 709 | PowerShell and Elvish scripts are generated too **(untested on this VM: shells |
| 710 | not installed)**. |
| 711 | |
| 712 | --- |
| 713 | |
| 714 | ## 10. Running it |
| 715 | |
| 716 | ### The TUI |
| 717 | |
| 718 | ```bash |
| 719 | cd your-git-repo |
| 720 | codewhale |
| 721 | ``` |
| 722 | |
| 723 | * The composer is at the bottom. The footer shows the permission posture |
| 724 | (`ask`), the mode (`work`) and the model (`DeepSeek · deepseek-flash`). |
| 725 | * **Shift+Tab** cycles the permission posture: Ask → Auto-Review → Full Access. |
| 726 | **Tab** (with an empty composer) cycles the mode: Plan → Work → Operate. |
| 727 | * In **Ask**, file edits in the workspace are applied and shown as a diff. |
| 728 | Shell commands stop at an **APPROVAL** prompt: `y` allow once, `a` allow for |
| 729 | this session, `n` deny, `Esc` abort the turn. |
| 730 | * Useful keys: **F1** help (or `/help`), **Ctrl-K** command palette, **F3** |
| 731 | provider/model picker, **Ctrl-R** resume a past session, **Ctrl-U** clear the |
| 732 | input (**Ctrl-Z** restores it), **Ctrl-C** cancel or quit, **Ctrl-D** quit |
| 733 | with an empty input. Full list: [KEYBINDINGS.md](KEYBINDINGS.md). |
| 734 | * On exit it prints `To resume this session, run codewhale resume <id>`. |
| 735 | |
| 736 | Codewhale creates a `.codewhale/` directory in your repo. Ignore its contents |
| 737 | but keep the committable `constitution.json` (these are the same patterns |
| 738 | `/init` writes): |
| 739 | |
| 740 | ```gitignore |
| 741 | **/.codewhale/* |
| 742 | !**/.codewhale/constitution.json |
| 743 | ``` |
| 744 | |
| 745 | ### Headless (scripts, CI) |
| 746 | |
| 747 | ```bash |
| 748 | codewhale exec "Reply with exactly: pong" # one-shot answer, no tools |
| 749 | codewhale exec --auto "create primes.py that prints the first 10 primes and run it" # tools, auto-approved |
| 750 | codewhale exec --json "…" # summary JSON (provider, model, usage, output) |
| 751 | codewhale exec --auto --output-format stream-json "…" # one JSON event per line |
| 752 | ``` |
| 753 | |
| 754 | `--auto` auto-approves shell commands, so use it only in a repo or sandbox you |
| 755 | trust. |
| 756 | |
| 757 | Plain `exec` offers the model no tools. Only `--auto`, `--yolo`, |
| 758 | `--allowed-tools` or resuming a session opens a tool surface; limits such as |
| 759 | `--max-turns`, `--disallowed-tools`, `--sandbox` and the output format never |
| 760 | add tools (tool-only flags print a warning). If the provider stops a reply at |
| 761 | its output limit, the model is asked to continue and the printed answer is the |
| 762 | whole reply. A plain run takes at most 8 model steps unless `--max-turns` sets |
| 763 | another limit; a reply still cut off at that limit fails the run. |
| 764 | |
| 765 | ### Resuming |
| 766 | |
| 767 | ```bash |
| 768 | codewhale resume <session-id> # or a unique prefix, e.g. e2525dfb |
| 769 | codewhale -c # continue the most recent session in this folder |
| 770 | codewhale sessions # list saved sessions |
| 771 | codewhale exec --continue "…" # headless follow-up to the latest session |
| 772 | codewhale exec --resume <id> "…" |
| 773 | ``` |
| 774 | |
| 775 | In v0.10.0, only **TUI sessions** and **`--output-format stream-json`** exec |
| 776 | runs are saved. A plain `codewhale exec`/`exec --auto` run is *not* saved, so a |
| 777 | following `exec --continue` fails with `No saved sessions found for workspace`. |
| 778 | |
| 779 | --- |
| 780 | |
| 781 | ## 11. Terminal notes |
| 782 | |
| 783 | ### Ghostty (tested: Ghostty 1.3.1 on Linux/X11) |
| 784 | |
| 785 | Everything I checked worked in Ghostty with its default config |
| 786 | (`TERM=xterm-ghostty`, `COLORTERM=truecolor`). Screenshots are kept with the |
| 787 | [install receipts](https://github.com/codewhale-hq/Codewhale/tree/37ecdfcc49bc68a9b0d058b97c3946e62c34bd31/docs/install-report/v0.10.0-2026-09-23/screenshots). |
| 788 | |
| 789 | | Check | Result | |
| 790 | |---|---| |
| 791 | | Colours / truecolor gradient, box drawing, Unicode (✓ é 日本語) | ✅ | |
| 792 | | Window resize (1504×886 → 800×500 → back) reflows cleanly | ✅ | |
| 793 | | Mouse wheel scrolls the transcript, with a jump-to-bottom button | ✅ | |
| 794 | | Paste (`Ctrl+Shift+V`), multi-line: inserted, not sent | ✅ | |
| 795 | | F1, F3, Ctrl-K, Ctrl-R, Tab, Shift+Tab, Ctrl-U/Ctrl-Z, Ctrl-C, Ctrl-D | ✅ | |
| 796 | | Window title shows state (`waiting on you…`, `✓ done`) | ✅ | |
| 797 | | Exit restores the terminal (normal screen, cursor, no mouse-reporting garbage) | ✅ | |
| 798 | |
| 799 | Ghostty on Linux starts a **non-login** shell, so it reads `~/.bashrc` and not |
| 800 | `~/.profile`. That's why you need the PATH line in `~/.bashrc` (§2). |
| 801 | |
| 802 | You may notice small dots and a faint label (e.g. `other · drift`) drifting |
| 803 | across empty space after a turn. That's Codewhale's decorative "ambient life" |
| 804 | whale, not a rendering bug. |
| 805 | |
| 806 | ### Other terminals |
| 807 | |
| 808 | tmux eats **F1**, so use `/help` there. Some key chords (Ctrl-Shift-…, Ctrl-Tab) |
| 809 | need a terminal with an enhanced keyboard protocol; [KEYBINDINGS.md](KEYBINDINGS.md) lists |
| 810 | portable alternatives. Windows users should use Windows Terminal |
| 811 | **(untested on this VM)**. |
| 812 | |
| 813 | --- |
| 814 | |
| 815 | ## 12. Uninstalling |
| 816 | |
| 817 | ### Step 1: forget stored keys (if you used `auth set` or F3) |
| 818 | |
| 819 | ```bash |
| 820 | codewhale auth clear --provider deepseek |
| 821 | ``` |
| 822 | |
| 823 | ### Step 2: remove the program |
| 824 | |
| 825 | | Installed with | Remove with | |
| 826 | |---|---| |
| 827 | | installer (§2) or manual (§3) | `rm ~/.local/bin/codewhale ~/.local/bin/codew` (or your `CODEWHALE_INSTALL_DIR`) | |
| 828 | | npm | `npm uninstall -g codewhale` | |
| 829 | | Cargo | `cargo uninstall codewhale-cli` | |
| 830 | | Homebrew | `brew uninstall codewhale && brew untap Hmbown/deepseek-tui` (also removes its node dependency) | |
| 831 | |
| 832 | ### Step 3: remove data. No uninstaller does this for you. |
| 833 | |
| 834 | | Path | What it is | Size seen | |
| 835 | |---|---|---| |
| 836 | | `~/.codewhale/` | config.toml, **secrets/secrets.json (plaintext keys)**, sessions/, logs/, catalog/ (model list, ~5 MB), skills/, builtin-plugins/, tasks/, automations/, crashes/, audit.log, composer history | 6–7 MB | |
| 837 | | `~/.deepseek/snapshots/` | v0.10.0 stores its per-turn **copies of your workspaces** here (a legacy path). Contains the contents of every repo you ran it in. | 0.2–0.6 MB here; grows with repo size | |
| 838 | | `<every repo you used>/.codewhale/` | per-workspace state/lock dir | tiny | |
| 839 | | completion files | `~/.local/share/bash-completion/completions/codewhale`, `~/.zfunc/_codewhale`, `~/.config/fish/completions/codewhale.fish` | – | |
| 840 | | PATH lines you added | `~/.bashrc`, `~/.zshrc`, `~/.profile` | – | |
| 841 | |
| 842 | ```bash |
| 843 | rm -rf ~/.codewhale ~/.deepseek/snapshots |
| 844 | rmdir ~/.deepseek 2>/dev/null # removes the parent only if it is now empty |
| 845 | # per-repo dirs, e.g.: |
| 846 | find ~ -type d -name .codewhale -prune -print # review, then delete the ones you want |
| 847 | ``` |
| 848 | |
| 849 | Codewhale wrote nothing outside `$HOME` and the repos it was used in: no |
| 850 | system files, services or cron jobs. (I checked every file owned by the test |
| 851 | users outside their home directories.) The commands above delete only |
| 852 | `~/.deepseek/snapshots`. If you still use the older DeepSeek-TUI, the rest of |
| 853 | `~/.deepseek` (its config and sessions) is left alone. |
| 854 | |
| 855 | --- |
| 856 | |
| 857 | ## 13. Troubleshooting |
| 858 | |
| 859 | Every error below was hit while writing this guide. |
| 860 | |
| 861 | **`bash: codewhale: command not found` right after installing.** |
| 862 | `~/.local/bin` isn't on PATH in this terminal. See |
| 863 | [Put it on your PATH](#put-it-on-your-path). |
| 864 | |
| 865 | **`npm error code EACCES … permission denied, mkdir '…/lib/node_modules/codewhale'`.** |
| 866 | Your Node is system-owned. See [§4](#if-you-get-eacces-permission-denied). |
| 867 | Don't use sudo. |
| 868 | |
| 869 | **`error: DeepSeek API key not found.` (from `codewhale exec`)** |
| 870 | No key anywhere. Follow the printed steps, or see §8. |
| 871 | |
| 872 | **The TUI shows your message but never answers.** |
| 873 | No key (v0.10.0 doesn't say so). Press F3 → DeepSeek → Enter → paste the key. |
| 874 | |
| 875 | **`error: Responses API request failed … Authentication Fails, Your api key: ****dead is invalid`.** |
| 876 | The key is wrong or revoked. Run `codewhale auth status --provider deepseek` |
| 877 | to see *which* source is being used. Remember that config and the secret store |
| 878 | beat the env var. Fix with `codewhale auth set --provider deepseek`, or |
| 879 | `codewhale auth clear --provider deepseek` to fall back to the env var. In the |
| 880 | TUI, a bad key sends you to a "Choose your model provider" screen that marks |
| 881 | DeepSeek `last check failed (authentication)`. |
| 882 | |
| 883 | **`error: Network error: SSE stream request failed after HTTP/1.1 fallback: Responses API request failed. … on Windows or proxy networks, try CODEWHALE_FORCE_HTTP1=1 …`.** |
| 884 | Despite the wording, on Linux this usually just means **no connection to |
| 885 | `api.deepseek.com`**. Check with `curl -sI https://api.deepseek.com` (a `401` |
| 886 | response is fine; it means the host is reachable). If you're behind a proxy, |
| 887 | make sure `HTTPS_PROXY` is exported. `codewhale doctor --probe-api` only says |
| 888 | `✗ API connection failed` for both bad keys and network problems. |
| 889 | |
| 890 | **`codewhale install: refusing to replace existing ~/.local/bin/codewhale`.** |
| 891 | A different version is already installed there. Run `codewhale update`, or |
| 892 | delete the two files first (§7 rollback), or install into a fresh |
| 893 | `CODEWHALE_INSTALL_DIR`. |
| 894 | |
| 895 | **`codewhale install: checksum mismatch for codew-linux-x64`.** |
| 896 | The download was corrupted or tampered with. Nothing was installed. Retry, and |
| 897 | if it repeats, don't use a mirror. |
| 898 | |
| 899 | **`error: The package-managed executable was not changed.` (from `codewhale update`)** |
| 900 | You installed with npm, Cargo or Homebrew. Update with that tool instead. |
| 901 | |
| 902 | **`error: failed to run custom build command for libdbus-sys` (Cargo).** |
| 903 | Run `sudo apt-get install -y libdbus-1-dev pkg-config`. |
| 904 | |
| 905 | **`error: No saved sessions found for workspace …` (from `exec --continue`).** |
| 906 | The previous run was plain-text `exec`, which isn't saved. Use the TUI, or |
| 907 | `--output-format stream-json`. |
| 908 | |
| 909 | **zsh completion suggests the wrong things after the first word.** |
| 910 | Known v0.10.0 bug. bash and fish are fine. |
| 911 | |
| 912 | **Getting help:** `codewhale doctor --json` produces a diagnostics bundle |
| 913 | without secrets. |
| 914 | |
| 915 | --- |
| 916 | |
| 917 | ## Appendix: other platforms (not re-tested in this revision) |
| 918 | |
| 919 | The sections below are carried over unchanged from the previous revision of |
| 920 | this page. They were **not re-run** for the v0.10.0 install test above |
| 921 | (out of scope: Windows, macOS, Android/Termux, FreeBSD, mainland-China |
| 922 | mirrors), apart from the macOS paths noted in [macOS notes](#macos-notes). |
| 923 | Known contradictions with the published v0.10.0 assets, found by inspecting |
| 924 | them ([details](https://github.com/codewhale-hq/Codewhale/blob/37ecdfcc49bc68a9b0d058b97c3946e62c34bd31/docs/install-report/v0.10.0-2026-09-23/DOC_DEFECTS.md), D15 and D16): |
| 925 | |
| 926 | * The winget manifest kept in `packaging/winget/` is stale (0.9.6) and not the |
| 927 | published package; winget serves `HunterBown.CodeWhale`, see |
| 928 | [Windows winget](#windows-winget). |
| 929 | * v0.10.0 publishes both `codewhale-windows-x64.zip` (with an `install.bat` |
| 930 | that copies to `%USERPROFILE%\bin`) and `codewhale-windows-x64-portable.zip`; |
| 931 | the sections below mention only the first. |
| 932 | * The standalone `codewhale.bat` launcher works only next to the x64 exe. |
| 933 | |
| 934 | ### Supported platforms and assets |
| 935 | |
| 936 | The [latest stable release](https://github.com/codewhale-hq/CodeWhale/releases/latest) |
| 937 | publishes Linux x64/arm64, macOS x64/arm64, Windows x64/arm64, and Android arm64 |
| 938 | assets. Artifact presence is distinct from platform qualification. |
| 939 | The table below describes the current source tree's platform and secondary |
| 940 | packaging support; `latest` installation still selects the published release. |
| 941 | Android/Termux is preview pending real-device QA. Linux ARM64 is available from |
| 942 | v0.8.8 onward. Linux RISC-V prebuilts are temporarily paused because the locked |
| 943 | `rquickjs-sys` dependency does not ship `riscv64gc-unknown-linux-gnu` bindings. |
| 944 | |
| 945 | | Platform | Architecture | GitHub release asset | npm install | `cargo install` | |
| 946 | | ------------ | ------------ | ----------------------------------------------------- | :---------: | :-------------: | |
| 947 | | Linux | x64 (x86_64) | `codewhale-linux-x64`, `codew-linux-x64` | ✅ | ✅ | |
| 948 | | Linux | arm64 | `codewhale-linux-arm64`, `codew-linux-arm64` | ✅ | ✅ | |
| 949 | | Android / Termux | arm64 (aarch64) | `codewhale-android-arm64.tar.gz` (published in v0.9.12; device support is preview) | ⚠️⁴ preview | ⚠️⁴ preview | |
| 950 | | Linux | riscv64 | temporarily unsupported until upstream bindings land | ❌¹ | ❌³ | |
| 951 | | macOS | x64 | `codewhale-macos-x64`, `codew-macos-x64` | ✅ | ✅ | |
| 952 | | macOS | arm64 (M-series) | `codewhale-macos-arm64`, `codew-macos-arm64` | ✅ | ✅ | |
| 953 | | Windows | x64 | `codewhale-windows-x64.exe`, `codew-windows-x64.exe` | ✅ | ✅ | |
| 954 | | Windows | arm64 | `codewhale-windows-arm64.exe`, `codew-windows-arm64.exe` | ✅ | ✅ | |
| 955 | | Linux x64 or arm64 on musl (Alpine) | native arch | matching static Linux asset | ✅ (static) | ✅ | |
| 956 | | Other Linux (musl on other arches) | — | build from source | ❌¹ | ✅² | |
| 957 | | FreeBSD 14+ / OpenBSD | x64, arm64 | `cargo install codewhale-cli --locked` (no prebuilt; see § FreeBSD) | ❌ | ✅² | |
| 958 | |
| 959 | ¹ The npm package will exit with a clear error and point you here. |
| 960 | ² Provided your toolchain can compile a recent Rust workspace; see |
| 961 | [Build from source](#5-cargo-and-building-from-source) below. |
| 962 | ³ RISC-V source builds currently need upstream `rquickjs-sys` RISC-V bindings or |
| 963 | a bindgen-enabled dependency build. |
| 964 | ⁴ The current npm wrapper recognizes Android arm64 and resolves |
| 965 | the matching `codewhale` and `codew` Android assets. npm |
| 966 | installation works only for a package version whose GitHub Release publishes |
| 967 | those matching assets. The Android/Termux path remains preview-only until the |
| 968 | real-device compile, startup, approval, file-tool, and update checks tracked |
| 969 | in #4236 and #4242 are complete. |
| 970 | |
| 971 | Android / Termux is not the same target as Linux arm64. Do not install the |
| 972 | Linux `codewhale-linux-arm64` archive in Termux; use the Termux-specific |
| 973 | Android archive when a release or release candidate publishes one, or build |
| 974 | from source inside Termux. |
| 975 | |
| 976 | The current Linux **x64 and arm64** assets are **static musl builds**. |
| 977 | The x64 release path has used musl since v0.8.65; v0.9.6 extends the same build |
| 978 | and static-launch check to arm64. These binaries have no glibc dependency and |
| 979 | run on their matching architecture across Ubuntu, Debian, RHEL/CentOS, and |
| 980 | Alpine/musl. SQLite is bundled through `rusqlite`, so no separate `libsqlite3` |
| 981 | runtime package is needed. |
| 982 | |
| 983 | #### Linux ARM64 portability |
| 984 | |
| 985 | Linux arm64 assets before v0.9.6 were GNU libc builds and could inherit the |
| 986 | Ubuntu 24.04 build host's `GLIBC_2.39` floor. Ubuntu 22.04 ships glibc 2.35, so |
| 987 | those older arm64 binaries can fail with errors such as: |
| 988 | |
| 989 | ```text |
| 990 | version `GLIBC_2.39' not found |
| 991 | ``` |
| 992 | |
| 993 | The npm wrapper, `codewhale update`, and the Unix archive installer retain their |
| 994 | GNU-binary preflight for older releases. The current arm64 build instead uses |
| 995 | `aarch64-unknown-linux-musl`, so it has no `GLIBC_*` floor. If you are installing |
| 996 | an earlier release on an older arm64 distribution, use: |
| 997 | |
| 998 | ```bash |
| 999 | cargo install codewhale-cli --locked # installs `codewhale` |
| 1000 | ``` |
| 1001 | |
| 1002 | > **Linux ARM64 note (v0.8.7 and earlier).** v0.8.7 and earlier do **not** |
| 1003 | > publish a Linux ARM64 prebuilt; users on HarmonyOS thin-and-light, Asahi |
| 1004 | > Linux, Raspberry Pi, AWS Graviton, etc. saw `Unsupported architecture: arm64` |
| 1005 | > from `npm i -g codewhale`. v0.8.8 publishes `codewhale-linux-arm64`, so a plain `npm i -g codewhale` works |
| 1006 | > on any glibc-based ARM64 Linux. If you're stuck on v0.8.7, jump to |
| 1007 | > [Build from source](#5-cargo-and-building-from-source) — `cargo install` works fine. |
| 1008 | > For HarmonyOS PC and OpenHarmony cross-build setup, see |
| 1009 | > [HarmonyOS and OpenHarmony](HarmonyOS.md). |
| 1010 | |
| 1011 | ### Migrating from npm, Cargo, or another installation |
| 1012 | |
| 1013 | #### Migrating from npm, Cargo, or another installation |
| 1014 | |
| 1015 | Package managers continue to own their files. `codewhale update` gives migration |
| 1016 | instructions for npm, Cargo, Homebrew, and Omarchy instead of overwriting them. |
| 1017 | Known system/package directories are also protected. A `CODEWHALE_INSTALL_METHOD=binary` |
| 1018 | override cannot bypass a recognized managed path. |
| 1019 | |
| 1020 | Create a fresh destination when `~/.local/bin` is occupied or a sibling command |
| 1021 | has different bytes. This leaves every existing installation in place: |
| 1022 | |
| 1023 | ```bash |
| 1024 | mkdir -p "$HOME/.local" |
| 1025 | codewhale_install_dir="$(mktemp -d "$HOME/.local/codewhale-release.XXXXXX")" |
| 1026 | curl -fsSL https://codewhale.net/install.sh | CODEWHALE_INSTALL_DIR="$codewhale_install_dir" sh |
| 1027 | "$codewhale_install_dir/codewhale" --version |
| 1028 | export PATH="$codewhale_install_dir:$PATH" |
| 1029 | hash -r |
| 1030 | command -v codewhale codew |
| 1031 | "$codewhale_install_dir/codewhale" update --check |
| 1032 | ``` |
| 1033 | |
| 1034 | After verifying the version and command paths, keep that directory first in your |
| 1035 | shell profile. In PowerShell, use `Get-Command codewhale, codew -All` to inspect |
| 1036 | resolution; run the selected executable using its full path. A successful update |
| 1037 | only changes its own install directory, so another earlier PATH entry can still |
| 1038 | launch an older copy. |
| 1039 | |
| 1040 | Modern matched `codewhale`, `codew`, and compatibility copies update from the |
| 1041 | same verified bytes. Symlinks to the running binary are preserved. A different |
| 1042 | or unrelated sibling is named in the error and left untouched; no sibling is |
| 1043 | executed merely to guess its owner. Use the fresh-directory migration above |
| 1044 | for older installs with separate dispatcher/TUI binaries. |
| 1045 | |
| 1046 | To retain a secondary package-managed install, use its manager: |
| 1047 | |
| 1048 | ```bash |
| 1049 | npm install -g codewhale@latest |
| 1050 | # or |
| 1051 | cargo install codewhale-cli --locked --force |
| 1052 | ``` |
| 1053 | |
| 1054 | Homebrew uses `brew upgrade codewhale`; Omarchy uses `omarchy update`. These |
| 1055 | commands update their own copies, so verify PATH again afterward. |
| 1056 | |
| 1057 | <a id="android--termux-arm64"></a> |
| 1058 | |
| 1059 | ### Android / Termux arm64 (preview) |
| 1060 | |
| 1061 | Termux runs on Android's Bionic libc and uses `$PREFIX` as its Unix prefix, so |
| 1062 | it needs a Termux-specific Android arm64 archive. The Linux arm64 release asset |
| 1063 | targets standard Linux with musl; Android uses a distinct Rust target, so the |
| 1064 | Linux asset should not be used there. |
| 1065 | |
| 1066 | Install the minimum archive/runtime tools first: |
| 1067 | |
| 1068 | ```bash |
| 1069 | pkg update |
| 1070 | pkg install -y ca-certificates curl tar gzip coreutils |
| 1071 | ``` |
| 1072 | |
| 1073 | When the release includes `codewhale-android-arm64.tar.gz`, install it with the |
| 1074 | archive's bundled installer. Passing `PREFIX="$PREFIX"` matters: the installer |
| 1075 | defaults to `~/.local`, while Termux users normally expect commands under |
| 1076 | `$PREFIX/bin`. |
| 1077 | |
| 1078 | ```bash |
| 1079 | cd "$HOME" |
| 1080 | curl -L -O https://github.com/codewhale-hq/CodeWhale/releases/latest/download/codewhale-android-arm64.tar.gz |
| 1081 | curl -L -O https://github.com/codewhale-hq/CodeWhale/releases/latest/download/codewhale-bundles-sha256.txt |
| 1082 | sha256sum -c codewhale-bundles-sha256.txt --ignore-missing |
| 1083 | |
| 1084 | tar xzf codewhale-android-arm64.tar.gz |
| 1085 | cd codewhale-android-arm64 |
| 1086 | PREFIX="$PREFIX" ./install.sh |
| 1087 | hash -r |
| 1088 | ``` |
| 1089 | |
| 1090 | If you are validating from source or building a release candidate locally, |
| 1091 | install the build packages before running Cargo: |
| 1092 | |
| 1093 | ```bash |
| 1094 | pkg install -y rust clang pkg-config make git |
| 1095 | cargo install codewhale-cli --locked # installs `codewhale` |
| 1096 | ``` |
| 1097 | |
| 1098 | The normal first-run setup path is implemented, but its Android interaction is |
| 1099 | still part of the preview QA above. Prefer provider environment variables for |
| 1100 | temporary credentials. `codewhale auth set` is available, but the Termux build |
| 1101 | has no supported OS keyring integration and falls back to file-backed secrets |
| 1102 | by writing `~/.codewhale/config.toml` and mirroring keys to |
| 1103 | `~/.codewhale/secrets/secrets.json`. Both are plaintext files protected by |
| 1104 | `0600` permissions and are not encrypted at rest. |
| 1105 | |
| 1106 | ```bash |
| 1107 | codewhale auth set --provider deepseek |
| 1108 | codewhale auth status |
| 1109 | codewhale doctor |
| 1110 | ``` |
| 1111 | |
| 1112 | Maintainers should use this repeatable smoke checklist for a Termux / Android |
| 1113 | arm64 release candidate: |
| 1114 | |
| 1115 | ```bash |
| 1116 | command -v codewhale codew |
| 1117 | test -x "$PREFIX/bin/codewhale" |
| 1118 | test -x "$PREFIX/bin/codew" |
| 1119 | |
| 1120 | codewhale --version |
| 1121 | codewhale doctor |
| 1122 | codewhale exec --auto "run pwd" |
| 1123 | ``` |
| 1124 | |
| 1125 | Known limitations: |
| 1126 | |
| 1127 | - Commands inherit Android's per-app UID, SELinux, and seccomp protections and |
| 1128 | any permissions granted to Termux. Codewhale's opt-in bubblewrap |
| 1129 | child-process sandbox is Linux-only and is not built on Android, so approved |
| 1130 | commands receive no Codewhale-specific filesystem narrowing. |
| 1131 | - The Termux build has no supported Android Keystore or desktop Secret Service |
| 1132 | integration. Use `codewhale auth status` to confirm the active source and |
| 1133 | prefer provider environment variables when file-backed plaintext storage is |
| 1134 | not acceptable. |
| 1135 | - Terminal rendering varies by Android terminal app. The TUI always owns the |
| 1136 | alternate screen. If a terminal app cannot render the full-screen TUI, |
| 1137 | use `codewhale exec` for headless runs instead. |
| 1138 | |
| 1139 | ### China / mirror-friendly install |
| 1140 | |
| 1141 | When installing from mainland China, configure mirrors for both **rustup** |
| 1142 | (the Rust toolchain installer) and **Cargo** (the package registry) to avoid |
| 1143 | TLS timeouts and download failures. |
| 1144 | |
| 1145 | **Step 1: Install Rust via a rustup mirror** |
| 1146 | |
| 1147 | ```bash |
| 1148 | # PowerShell |
| 1149 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
| 1150 | (New-Object Net.WebClient).DownloadFile('https://win.rustup.rs/x86_64', 'rustup-init.exe') |
| 1151 | |
| 1152 | # git-bash / msys2 |
| 1153 | export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup |
| 1154 | export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup |
| 1155 | ./rustup-init.exe -y --default-toolchain stable |
| 1156 | |
| 1157 | # Linux / macOS |
| 1158 | export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup |
| 1159 | export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup |
| 1160 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable |
| 1161 | ``` |
| 1162 | |
| 1163 | If the TUNA mirror is slow from your network, `rsproxy.cn` is another |
| 1164 | rustup mirror option for Linux/macOS: |
| 1165 | |
| 1166 | ```bash |
| 1167 | export RUSTUP_DIST_SERVER=https://rsproxy.cn |
| 1168 | export RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup |
| 1169 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable |
| 1170 | ``` |
| 1171 | |
| 1172 | The `RUSTUP_DIST_SERVER` and `RUSTUP_UPDATE_ROOT` environment variables must |
| 1173 | be set **before** running rustup-init; the toolchain download otherwise hits |
| 1174 | the same TLS handshake problem as the installer. |
| 1175 | |
| 1176 | **Step 2: Configure Cargo registry mirror** |
| 1177 | |
| 1178 | ```toml |
| 1179 | # ~/.cargo/config.toml |
| 1180 | [source.crates-io] |
| 1181 | replace-with = "tuna" |
| 1182 | |
| 1183 | [source.tuna] |
| 1184 | registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/" |
| 1185 | ``` |
| 1186 | |
| 1187 | `rsproxy`, Tencent COS, and Aliyun OSS mirrors work the same way; pick whichever |
| 1188 | is fastest from your network. |
| 1189 | |
| 1190 | ### Omarchy / AUR |
| 1191 | |
| 1192 | On Omarchy, install the prebuilt AUR package: |
| 1193 | |
| 1194 | ```bash |
| 1195 | omarchy pkg aur add codewhale-bin |
| 1196 | codewhale --version |
| 1197 | ``` |
| 1198 | |
| 1199 | `codewhale-bin` packages the same checksum-pinned Linux release archives as the |
| 1200 | other binary install paths and provides both `codewhale` and `codew`. It does |
| 1201 | not carry a separate Codewhale version; the existing `codewhale-tui` |
| 1202 | compatibility command remains an alias to the same runtime. Package updates |
| 1203 | arrive through `omarchy update`; the in-app updater leaves the pacman-owned |
| 1204 | binary to Omarchy. |
| 1205 | |
| 1206 | The AUR update follows the matching Codewhale tag and release assets, so it may |
| 1207 | appear after the GitHub release while its generated `PKGBUILD` and `.SRCINFO` |
| 1208 | are validated. Release-maintainer instructions live in |
| 1209 | [`packaging/aur/README.md`](../packaging/aur/README.md). |
| 1210 | |
| 1211 | --- |
| 1212 | |
| 1213 | ### Windows |
| 1214 | |
| 1215 | #### Windows Scoop |
| 1216 | |
| 1217 | The `codewhale` package is listed in Scoop's main bucket: |
| 1218 | |
| 1219 | ```powershell |
| 1220 | scoop update |
| 1221 | scoop install codewhale |
| 1222 | codewhale --version |
| 1223 | ``` |
| 1224 | |
| 1225 | Scoop manifests are maintained outside this repository's release workflow and |
| 1226 | can lag GitHub/npm/Cargo releases. Use npm or manual GitHub release downloads |
| 1227 | when you need the newest version immediately. |
| 1228 | |
| 1229 | #### Windows winget |
| 1230 | |
| 1231 | The published winget package is **`HunterBown.CodeWhale`** (verified in |
| 1232 | [microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs/tree/master/manifests/h/HunterBown/CodeWhale) |
| 1233 | on 2026-10-04; latest published version 0.10.0). It is a portable x64 package: |
| 1234 | winget downloads `codewhale-tui-windows-x64.exe`, installs it as the `codewhale` |
| 1235 | command, and pulls in the Microsoft Visual C++ 2015+ x64 runtime. |
| 1236 | |
| 1237 | ```powershell |
| 1238 | winget install HunterBown.CodeWhale |
| 1239 | codewhale --version |
| 1240 | ``` |
| 1241 | |
| 1242 | Update with `winget upgrade HunterBown.CodeWhale` or `codewhale update`. Each |
| 1243 | version goes through winget-pkgs review after the GitHub Release, so winget can |
| 1244 | lag GitHub/npm/Cargo; use npm or the GitHub Release asset when you need the |
| 1245 | newest version immediately. |
| 1246 | |
| 1247 | Known limits of the winget route: |
| 1248 | |
| 1249 | * **x64 only.** The published manifest has no ARM64 installer. On Windows ARM64, |
| 1250 | use `npm install -g codewhale` under native ARM64 Node.js, or download |
| 1251 | `codewhale-windows-arm64.zip` from GitHub Releases. |
| 1252 | * **`codewhale` only.** The short `codew` alias is not installed by winget; use |
| 1253 | `codewhale`. |
| 1254 | * The manifest in this repository (`packaging/winget/`) is not the one winget |
| 1255 | serves; see [`packaging/winget/README.md`](../packaging/winget/README.md). |
| 1256 | |
| 1257 | #### Windows NSIS Installer |
| 1258 | |
| 1259 | A standalone NSIS-based installer is available starting with v0.8.50 for |
| 1260 | Windows users who prefer a traditional double-click setup (no npm, no Scoop, no |
| 1261 | Cargo required). |
| 1262 | |
| 1263 | The NSIS installer currently contains the Windows x64 binaries. Windows ARM64 |
| 1264 | users should install through npm running under native ARM64 Node.js or download |
| 1265 | `codewhale-windows-arm64.zip` from the same release; both paths then use native |
| 1266 | ARM64 binaries. |
| 1267 | |
| 1268 | **Download** `CodeWhaleSetup.exe` from the |
| 1269 | [Releases page](https://github.com/codewhale-hq/CodeWhale/releases/latest). |
| 1270 | |
| 1271 | **Install** by double-clicking the setup executable. The installer: |
| 1272 | |
| 1273 | - Installs `codewhale.exe` and `codew.exe` side-by-side (single binary, no `codewhale-tui.exe`) into |
| 1274 | `%LOCALAPPDATA%\Programs\CodeWhale\bin` |
| 1275 | - Installs `codewhale.bat`, which prefers Windows Terminal (`wt.exe`) when it is on `PATH` and |
| 1276 | otherwise launches the exe directly |
| 1277 | - Creates a current-user Start Menu shortcut that opens that launcher, not the raw `.exe` |
| 1278 | - Adds the install directory to the **current user** `PATH` |
| 1279 | - Registers in Windows **Apps & Features** for easy uninstall |
| 1280 | |
| 1281 | Uninstall removes the binaries, `codewhale.bat`, the Start Menu shortcut, and the user `PATH` entry. |
| 1282 | |
| 1283 | **Silent install** (for IT admins, SCCM, Intune): |
| 1284 | |
| 1285 | ```powershell |
| 1286 | CodeWhaleSetup.exe /S |
| 1287 | ``` |
| 1288 | |
| 1289 | The installer is per-user and does not request elevation. Run silent installs in |
| 1290 | the target user's context, or use a deployment tool that can run the installer |
| 1291 | for each user profile that needs Codewhale. |
| 1292 | |
| 1293 | The release-built installer is currently unsigned and may trigger Windows |
| 1294 | SmartScreen. Verify the SHA-256 checksum from `codewhale-artifacts-sha256.txt` |
| 1295 | before deploying, and sign the installer in your internal deployment pipeline if |
| 1296 | your environment requires signed application packages. |
| 1297 | |
| 1298 | **Build the installer yourself** (requires [NSIS](https://nsis.sourceforge.io)): |
| 1299 | |
| 1300 | ```powershell |
| 1301 | cd scripts\installer |
| 1302 | # Place codewhale.exe and codew.exe here (single binary, no codewhale-tui.exe), then: |
| 1303 | makensis /DVERSION=<version> codewhale.nsi |
| 1304 | ``` |
| 1305 | |
| 1306 | **Manual fallback** — if the installer is blocked by group policy, see the |
| 1307 | [CLASSROOM_INSTALL.md](CLASSROOM_INSTALL.md) guide for step-by-step PowerShell |
| 1308 | commands. |
| 1309 | |
| 1310 | > **Deploying to a classroom or lab?** See the full |
| 1311 | > [Classroom Install Checklist](CLASSROOM_INSTALL.md) for silent install, |
| 1312 | > API key provisioning, imaging notes, and troubleshooting. |
| 1313 | |
| 1314 | <a id="freebsd"></a> |
| 1315 | |
| 1316 | ### FreeBSD, cross-compiling, Windows source builds |
| 1317 | |
| 1318 | #### FreeBSD 14+ source-build workaround (#1097) |
| 1319 | |
| 1320 | FreeBSD has no prebuilt GitHub Release asset — `npm install -g codewhale` intentionally |
| 1321 | fails with `Unsupported platform: freebsd` and points to Cargo. Install from source: |
| 1322 | |
| 1323 | ```bash |
| 1324 | pkg install -y rust pkgconf git |
| 1325 | cargo install codewhale-cli --locked # installs `codewhale` |
| 1326 | codewhale --version |
| 1327 | codewhale doctor |
| 1328 | ``` |
| 1329 | |
| 1330 | The `rquickjs` FreeBSD bindings are generated at build time via `bindgen` (see |
| 1331 | `1582ba965`/`5eb0385e8`). No separate `pkg install codewhale` port exists yet — |
| 1332 | a native port is tracked as the follow-up to #1097 under `packaging/freebsd/` |
| 1333 | (contributions welcome). Validate with `cargo check --target x86_64-unknown-freebsd -p codewhale-cli --locked` |
| 1334 | on the release branch; the 7×1 release matrix (Linux musl x64/arm64, |
| 1335 | Android arm64, macOS x64/arm64, Windows x64/arm64) stays 7 targets — FreeBSD is a |
| 1336 | source-build target, not a prebuilt asset. |
| 1337 | |
| 1338 | #### Cross-compiling from x64 to ARM64 Linux |
| 1339 | |
| 1340 | The release asset uses `aarch64-unknown-linux-musl` and is built on a native ARM |
| 1341 | runner. If you want to build a GNU-linked ARM64 Linux binary on an x64 Linux |
| 1342 | host (e.g. for a HarmonyOS / openEuler ARM64 thin-and-light), use |
| 1343 | [`cross`](https://github.com/cross-rs/cross), which wraps the official Rust |
| 1344 | cross-targets in a Docker container: |
| 1345 | |
| 1346 | ```bash |
| 1347 | # Once |
| 1348 | rustup target add aarch64-unknown-linux-gnu |
| 1349 | cargo install cross --locked |
| 1350 | |
| 1351 | # Per build |
| 1352 | cross build --release --target aarch64-unknown-linux-gnu -p codewhale-cli # single binary |
| 1353 | ``` |
| 1354 | |
| 1355 | The resulting binary lands in |
| 1356 | `target/aarch64-unknown-linux-gnu/release/codewhale`. Copy it to the ARM64 host |
| 1357 | (e.g. via `scp`) and make it executable. This local GNU build is distinct from |
| 1358 | the portable musl release asset; either executable can be copied under the |
| 1359 | `codew` convenience name. |
| 1360 | |
| 1361 | If you don't have Docker available, install the cross-linker directly and let |
| 1362 | Cargo do the work: |
| 1363 | |
| 1364 | ```bash |
| 1365 | sudo apt-get install -y gcc-aarch64-linux-gnu |
| 1366 | rustup target add aarch64-unknown-linux-gnu |
| 1367 | |
| 1368 | cat >> ~/.cargo/config.toml <<'EOF' |
| 1369 | [target.aarch64-unknown-linux-gnu] |
| 1370 | linker = "aarch64-linux-gnu-gcc" |
| 1371 | EOF |
| 1372 | |
| 1373 | cargo build --release --target aarch64-unknown-linux-gnu -p codewhale-cli # single binary |
| 1374 | ``` |
| 1375 | |
| 1376 | Producing `aarch64-unknown-linux-musl` while cross-compiling requires an |
| 1377 | appropriate musl cross-linker. The release workflow avoids that extra moving |
| 1378 | part by building and launching the musl binary on GitHub's native ARM runner. |
| 1379 | |
| 1380 | #### Windows build from source |
| 1381 | |
| 1382 | Building on Windows requires the **MSVC C toolchain** from |
| 1383 | [Visual Studio Build Tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) |
| 1384 | (the free workload-selectable installer, not the full IDE). |
| 1385 | |
| 1386 | **Prerequisites (Windows)** |
| 1387 | |
| 1388 | 1. Install Visual Studio 2022 Build Tools — select the **"Desktop development |
| 1389 | with C++"** workload. |
| 1390 | 2. Install [Rust](https://rustup.rs) 1.89+ (see the |
| 1391 | [China mirror instructions](#china--mirror-friendly-install) above if |
| 1392 | downloading from mainland China). |
| 1393 | 3. Install [Git for Windows](https://git-scm.com/download/win) (provides `git` |
| 1394 | and the `git-bash` terminal). |
| 1395 | |
| 1396 | **Recommended terminals**: Windows Terminal, `git-bash`, or PowerShell. |
| 1397 | `cmd.exe` works but has a small buffer and limited PATH behavior. |
| 1398 | |
| 1399 | **Setting up the MSVC environment** |
| 1400 | |
| 1401 | Visual Studio Build Tools install `cl.exe` to a versioned directory but do |
| 1402 | **not** add it to `PATH` globally. You must set the environment manually or |
| 1403 | use a Developer Command Prompt. The required variables are: |
| 1404 | |
| 1405 | ```powershell |
| 1406 | # Adjust version numbers to match your installation |
| 1407 | $msvc = "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207" |
| 1408 | $sdk = "C:\Program Files (x86)\Windows Kits\10" |
| 1409 | $sdkv = "10.0.26100.0" |
| 1410 | |
| 1411 | $env:INCLUDE = "$msvc\include;$msvc\atlmfc\include;$sdk\Include\$sdkv\ucrt;$sdk\Include\$sdkv\um;$sdk\Include\$sdkv\shared" |
| 1412 | $env:LIB = "$msvc\lib\x64;$msvc\atlmfc\lib\x64;$sdk\Lib\$sdkv\ucrt\x64;$sdk\Lib\$sdkv\um\x64" |
| 1413 | $env:LIBPATH = "$msvc\lib\x64;$msvc\atlmfc\lib\x64" |
| 1414 | $env:CC = "$msvc\bin\Hostx64\x64\cl.exe" |
| 1415 | $env:CXX = "$msvc\bin\Hostx64\x64\cl.exe" |
| 1416 | $env:PATH = "$msvc\bin\Hostx64\x64;$env:PATH" |
| 1417 | ``` |
| 1418 | |
| 1419 | Alternatively, open a **"Developer Command Prompt for VS 2022"** (available |
| 1420 | from the Start Menu after installing Build Tools), which runs `vcvars64.bat` |
| 1421 | to configure all of the above automatically. Then add `cargo` to `PATH` inside |
| 1422 | that session and run `cargo build` from the project root. |
| 1423 | |
| 1424 | **Cargo registry mirror** — on Windows the mirror config goes to |
| 1425 | `%USERPROFILE%\.cargo\config.toml`. See [Step 2 above](#china--mirror-friendly-install). |
| 1426 | |
| 1427 | **Build** |
| 1428 | |
| 1429 | ```bash |
| 1430 | git clone https://github.com/codewhale-hq/CodeWhale.git |
| 1431 | cd CodeWhale |
| 1432 | set CARGO_HTTP_CHECK_REVOKE=false # may be needed behind some Chinese ISPs |
| 1433 | cargo build --release |
| 1434 | ``` |
| 1435 | |
| 1436 | The Cargo-built binary appears at `target\release\codewhale.exe`. Release |
| 1437 | packaging separately exposes the same executable as `codew.exe`. |
| 1438 | |
| 1439 | > Prefer not to build? Install via npm, Cargo, GitHub Releases, or the CNB |
| 1440 | > mirror — see the sections above. |
| 1441 | |
| 1442 | ### Older-release and regional troubleshooting |
| 1443 | |
| 1444 | #### `Unsupported architecture: arm64 on platform linux` |
| 1445 | |
| 1446 | You're on a release earlier than v0.8.8 that doesn't publish Linux ARM64 |
| 1447 | binaries. Use the GitHub installer in a fresh directory as described above, or use |
| 1448 | `cargo install` per [Section 4](#5-cargo-and-building-from-source). |
| 1449 | |
| 1450 | #### `MISSING_COMPANION_BINARY` after upgrading an older install |
| 1451 | |
| 1452 | The current single binary runs the TUI in-process and does not require a |
| 1453 | companion executable. This error identifies a stale pre-v0.9.5 dispatcher. |
| 1454 | Use the fresh-directory GitHub migration above, then verify the selected |
| 1455 | `codewhale` and `codew` paths. Do not download another separate runtime. |
| 1456 | |
| 1457 | #### `codewhale update` reports `no asset found for platform codewhale-linux-aarch64` |
| 1458 | |
| 1459 | Older updaters used Rust architecture names that did not match the published |
| 1460 | asset names. Use the official installer in a fresh directory as described above, |
| 1461 | then run the newly installed command by its full path. |
| 1462 | |
| 1463 | #### npm download is slow or times out from mainland China |
| 1464 | |
| 1465 | On Linux x64 the npm wrapper already probes GitHub Releases and the CNB |
| 1466 | first-party checksum manifests in parallel and downloads binaries only from |
| 1467 | the first source that validates. You do not need `CODEWHALE_USE_CNB_MIRROR=1` |
| 1468 | for that automatic path. |
| 1469 | |
| 1470 | If both first-party sources fail, set `CODEWHALE_RELEASE_BASE_URL` to a |
| 1471 | mirrored release-asset directory (rsproxy, TUNA, Tencent COS, Aliyun OSS), |
| 1472 | or skip npm entirely and use the Cargo mirror setup in |
| 1473 | [Section 4](#5-cargo-and-building-from-source). The legacy |
| 1474 | `DEEPSEEK_TUI_RELEASE_BASE_URL` name is still accepted. `CODEWHALE_USE_CNB_MIRROR=1` |
| 1475 | still forces CNB only on Linux x64 / OpenHarmony x64. |
| 1476 | |
| 1477 | #### `codewhale update` is blocked by GitHub from mainland China |
| 1478 | |
| 1479 | `codewhale update` prefers GitHub Releases. On supported Linux x64 targets, |
| 1480 | a failed GitHub manifest permits the matching CNB manifest and binary fallback. |
| 1481 | If GitHub metadata is also unreachable, explicitly select a known published CNB |
| 1482 | version (`CODEWHALE_USE_CNB_MIRROR=1 CODEWHALE_VERSION=X.Y.Z codewhale update`) |
| 1483 | or a binary mirror below. Existing newer builds are kept. |
| 1484 | |
| 1485 | Building from the CNB source mirror with Cargo is a secondary option. Cargo |
| 1486 | installs its own `codewhale` command: |
| 1487 | |
| 1488 | To check the latest release without downloading or replacing binaries, run |
| 1489 | `codewhale update --check`. |
| 1490 | |
| 1491 | ```bash |
| 1492 | cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-cli --locked --force # single binary |
| 1493 | ``` |
| 1494 | |
| 1495 | If you operate a binary asset mirror, `codewhale update` can use it directly: |
| 1496 | |
| 1497 | ```bash |
| 1498 | CODEWHALE_RELEASE_BASE_URL=https://your-mirror.example.com/CodeWhale/vX.Y.Z/ \ |
| 1499 | CODEWHALE_VERSION=X.Y.Z \ |
| 1500 | codewhale update |
| 1501 | ``` |
| 1502 | |
| 1503 | The mirror directory must contain `codewhale-artifacts-sha256.txt` and the |
| 1504 | platform binaries from the GitHub release. The legacy |
| 1505 | `DEEPSEEK_TUI_RELEASE_BASE_URL` mirror variable remains supported as an alias. |
| 1506 | |
| 1507 | `codewhale update` only talks HTTPS, and only to GitHub's release hosts, the CNB |
| 1508 | mirror, and the host of the `CODEWHALE_RELEASE_BASE_URL` you set; every |
| 1509 | redirect hop is held to the same rule, so a plain-`http://` mirror is refused. |
| 1510 | A private mirror therefore works as soon as its base URL is HTTPS. If that |
| 1511 | mirror redirects asset downloads to a separate download host (a CDN or an |
| 1512 | object-store domain), name that host too: |
| 1513 | |
| 1514 | ```bash |
| 1515 | CODEWHALE_UPDATE_ALLOWED_HOSTS=cdn.your-mirror.example.com,objects.example.net \ |
| 1516 | CODEWHALE_RELEASE_BASE_URL=https://your-mirror.example.com/CodeWhale/vX.Y.Z/ \ |
| 1517 | CODEWHALE_VERSION=X.Y.Z \ |
| 1518 | codewhale update |
| 1519 | ``` |
| 1520 | |
| 1521 | The error message for a refused host names it and this variable. |
| 1522 | |
| 1523 | ### Windows and npm-download troubleshooting |
| 1524 | |
| 1525 | #### Windows: `TLS handshake eof` or `CRYPT_E_REVOCATION_OFFLINE` from `rustup-init` |
| 1526 | |
| 1527 | The TLS handshake to `static.rust-lang.org` fails from behind the GFW or |
| 1528 | certain Chinese ISPs. Set the rustup mirror environment variables **before** |
| 1529 | running the installer: |
| 1530 | |
| 1531 | ```bash |
| 1532 | # git-bash / msys2 |
| 1533 | export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup |
| 1534 | export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup |
| 1535 | ./rustup-init.exe -y --default-toolchain stable |
| 1536 | ``` |
| 1537 | |
| 1538 | If you see `CRYPT_E_REVOCATION_OFFLINE` from Cargo after Rust is installed, |
| 1539 | also set `CARGO_HTTP_CHECK_REVOKE=false` during `cargo build`. |
| 1540 | |
| 1541 | #### Windows: MSVC compiler (`cl.exe`) not found during `cargo build` |
| 1542 | |
| 1543 | Visual Studio Build Tools do not add `cl.exe` to the global `PATH`. Either: |
| 1544 | |
| 1545 | 1. Open **"Developer Command Prompt for VS 2022"** from the Start Menu, add |
| 1546 | `%USERPROFILE%\.cargo\bin` to `PATH` in that window, and run `cargo build` |
| 1547 | from there; or |
| 1548 | 2. Set the MSVC environment variables manually — see the |
| 1549 | [Windows build from source](#windows-build-from-source) section for the |
| 1550 | PowerShell snippet. |
| 1551 | |
| 1552 | Verify the compiler is reachable: `cl.exe /?` should print help text. |
| 1553 | |
| 1554 | #### Windows: `拒绝访问 (os error 5)` when Cargo executes build scripts |
| 1555 | |
| 1556 | Third-party antivirus software (Huorong, 360, Kaspersky, etc.) may block |
| 1557 | Cargo from executing freshly-compiled build-script binaries |
| 1558 | (e.g. `libsqlite3-sys`, `aws-lc-sys`, `instability`). The error is |
| 1559 | path-agnostic — moving `target-dir` does not help. |
| 1560 | |
| 1561 | **Symptoms**: `could not execute process ... build-script-build (never executed)` |
| 1562 | |
| 1563 | **Workarounds** (pick one): |
| 1564 | |
| 1565 | 1. **Add the project's `target/` directory to your AV exclusions list.** |
| 1566 | 2. **Close the antivirus software temporarily** during `cargo build`. |
| 1567 | 3. **Use the GitHub Release installer/archive instead** — the release assets |
| 1568 | ship prebuilt binaries and skip the Cargo build entirely |
| 1569 | ([Section 6](#3-manual-download-from-github-releases)). |
| 1570 | 4. **Use `cargo install codewhale-cli --locked`** from crates.io — this |
| 1571 | changes the binary path, which some AV tools treat differently. |
| 1572 | |
| 1573 | To verify that the build-script binary itself is valid (not corrupted), locate |
| 1574 | it under `target/debug/build/<crate>/build-script-build` and run it manually: |
| 1575 | |
| 1576 | ```bash |
| 1577 | target/debug/build/libsqlite3-sys-*/build-script-build |
| 1578 | # If this runs but panics with "NotPresent" (no C compiler), the binary is |
| 1579 | # fine — the AV is blocking Cargo's process-spawning path specifically. |
| 1580 | ``` |
| 1581 | |
| 1582 | #### npm binary download times out |
| 1583 | |
| 1584 | If `codewhale` waits several seconds and prints `connect ETIMEDOUT` or |
| 1585 | `EAI_AGAIN` while fetching from `github.com`, the npm wrapper installed |
| 1586 | successfully but the prebuilt binary download is blocked or unreliable on |
| 1587 | your network. This download is separate from the npm registry package |
| 1588 | download. On Linux x64 the wrapper first races the small GitHub and CNB |
| 1589 | checksum manifests and does not wait for a full GitHub binary to time out |
| 1590 | before using a valid CNB manifest. |
| 1591 | |
| 1592 | Use one of these paths: |
| 1593 | |
| 1594 | 1. Set a proxy and retry: |
| 1595 | |
| 1596 | ```bash |
| 1597 | export HTTPS_PROXY=http://your-proxy:port |
| 1598 | codewhale |
| 1599 | ``` |
| 1600 | |
| 1601 | 2. Mirror the release assets internally and set `CODEWHALE_RELEASE_BASE_URL`: |
| 1602 | |
| 1603 | ```bash |
| 1604 | export CODEWHALE_RELEASE_BASE_URL=https://your-mirror.example.com/CodeWhale/ |
| 1605 | codewhale |
| 1606 | ``` |
| 1607 | |
| 1608 | The directory must contain `codewhale-artifacts-sha256.txt` and the platform |
| 1609 | binaries from the GitHub release. |
| 1610 | |
| 1611 | 3. Install via Cargo, which builds locally and does not download GitHub release |
| 1612 | assets. See [Section 4](#5-cargo-and-building-from-source). |
| 1613 | |
| 1614 | 4. Download both matching `codewhale` and `codew` |
| 1615 | binaries from the [Releases page](https://github.com/codewhale-hq/CodeWhale/releases), |
| 1616 | place them in a directory on `PATH`, and make them executable. See |
| 1617 | [Section 6](#3-manual-download-from-github-releases). |
| 1618 |