| 1 | # Environment-specific caveats |
| 2 | |
| 3 | > 阅读简体中文版:[zh_hans/ENVIRONMENTS.md](zh_hans/ENVIRONMENTS.md)。 |
| 4 | |
| 5 | Standard build/test/run commands live in `AGENTS.md` and `CONTRIBUTING.md`. |
| 6 | This file records only the non-obvious quirks of particular environments, so |
| 7 | they do not cost context on machines that will never hit them. |
| 8 | |
| 9 | ## Cursor Cloud VMs |
| 10 | |
| 11 | - **System build dep:** the build needs `libdbus-1-dev` (pulled in by |
| 12 | `crates/secrets` for the OS keyring). It is installed by the startup update |
| 13 | script; if a `cargo build` fails with a `dbus`/`pkg-config` error, that dep is |
| 14 | missing. |
| 15 | - **`rustup default` must be set:** some tests and runtime paths spawn shells in |
| 16 | temp dirs *outside* this checkout (e.g. `run_verifiers_background_*`, sub-agent |
| 17 | worktrees). Those spawned shells only see the repo's `rust-toolchain.toml` |
| 18 | override while inside `/workspace`, so without a global default they fail with |
| 19 | "rustup could not choose a version of rustc to run". The update script runs |
| 20 | `rustup default stable` to fix this. |
| 21 | - **Known env-specific test failures at `/workspace` (not code bugs):** because |
| 22 | the checkout sits directly under `/`, two `codewhale-tui` subagent tests fail |
| 23 | here — `git_repo_root_reports_attempted_paths_when_no_repo_found` (cannot |
| 24 | create a temp dir in the unwritable parent `/`) and |
| 25 | `create_isolated_worktree_reports_friendly_error_when_no_repo_found` (walking |
| 26 | up to `/` discovers `/workspace` itself as a repo). Both pass when the repo is |
| 27 | checked out under a normal, writable parent. |
| 28 | |
| 29 | ## Running the agent without provider API keys |
| 30 | |
| 31 | Point Codewhale at any local OpenAI-compatible endpoint via the keyless |
| 32 | `vllm`/`ollama`/`sglang` providers: |
| 33 | |
| 34 | ```sh |
| 35 | CODEWHALE_PROVIDER=vllm VLLM_BASE_URL=http://127.0.0.1:8000/v1 VLLM_MODEL=<id> \ |
| 36 | codewhale exec --auto "..." |
| 37 | ``` |
| 38 | |
| 39 | `codewhale exec` (add `--auto` for tool use) is the non-interactive path to |
| 40 | exercise the full agent loop. |
| 41 | |
| 42 | ## Keeping the host awake during a turn |
| 43 | |
| 44 | While an interactive TUI turn is in flight, Codewhale holds the platform's |
| 45 | idle-sleep assertion, so an unattended machine does not idle into sleep |
| 46 | mid-turn and lose the work: |
| 47 | |
| 48 | - macOS: `caffeinate -i` |
| 49 | - Linux: `systemd-inhibit --what=idle --why="Codewhale turn in flight" --mode=block cat`, |
| 50 | where `cat` reads a pipe Codewhale holds for the turn |
| 51 | |
| 52 | The assertion is released the moment the turn ends — on Linux by closing that |
| 53 | pipe, so `cat` exits and `systemd-inhibit` follows without leaving a process |
| 54 | behind — and it covers *idle* sleep only: an explicit `sleep` / `pmset sleepnow`, a closed lid, or a low battery |
| 55 | still suspends the machine. Headless hosts — `exec`, app-server, CI — never |
| 56 | hold it, so a shared runner's power policy is untouched. Windows is not |
| 57 | implemented: `SetThreadExecutionState` is thread-affine and needs a holder that |
| 58 | pins the thread, so the gap is deliberate rather than silent. |
| 59 | |
| 60 | If a turn is suspended anyway, the engine notices on wake — wall-clock elapsed |
| 61 | diverging from monotonic elapsed by more than the suspend threshold — reports |
| 62 | `System sleep detected; connection lost — retrying request`, and re-issues the |
| 63 | request instead of failing the turn (#2990). |
| 64 | |
| 65 | ## Windows PowerShell execution policy |
| 66 | |
| 67 | The shell tool runs PowerShell with `-ExecutionPolicy Bypass`. That sets only |
| 68 | the policy of the child process it launches: nothing is persisted, no |
| 69 | administrator rights are needed, and your own PowerShell windows keep their |
| 70 | policy. Without it, a machine whose local policy is `Restricted` (the Windows |
| 71 | client default) or `AllSigned` refuses the temporary `.ps1` script Codewhale |
| 72 | writes for multiline commands (#6745). |
| 73 | |
| 74 | A policy set by Group Policy (the `MachinePolicy` or `UserPolicy` rows of |
| 75 | `Get-ExecutionPolicy -List`) outranks the process scope. On such a machine, |
| 76 | multiline commands are still refused and PowerShell's refusal is returned as |
| 77 | the command's error; Codewhale does not work around an administrator-enforced |
| 78 | policy. Single-line commands run through `-Command`, which the execution |
| 79 | policy does not govern. Scripts that a command itself calls run under the same |
| 80 | process scope; the shell tool's approval and sandbox settings, not the |
| 81 | execution policy, decide what may run. |
| 82 | |
| 83 | To let the machine or user policy apply instead, set |
| 84 | `CODEWHALE_POWERSHELL_EXECUTION_POLICY=inherit` before starting Codewhale: the |
| 85 | shell tool then omits `-ExecutionPolicy` entirely, so a `Restricted` or |
| 86 | `AllSigned` policy refuses multiline commands that need the temporary `.ps1` |
| 87 | script. Unset, `bypass`, or any other value keeps the default `Bypass`. |
| 88 | |
| 89 | ## Consolidated runtime commands |
| 90 | |
| 91 | The current `codewhale` binary runs the TUI in-process. Release installers copy |
| 92 | the same bytes to the optional `codew` short command; no sibling |
| 93 | `codewhale-tui` executable is required. `DEEPSEEK_TUI_BIN` remains a legacy |
| 94 | replay/migration setting, not a current install requirement. |
| 95 |