# Platform support: Linux, WSL, macOS CST-Agent targets POSIX systems: Linux (glibc and musl), WSL 2 and macOS. Native Windows builds are covered separately in `README-windows.md`. ## Build | Platform | Dependencies | Build | |---|---|---| | Debian / Ubuntu / WSL | `build-essential pkg-config libcurl4-openssl-dev libncurses-dev` | `make` | | Fedora | `gcc make pkgconf libcurl-devel ncurses-devel` | `make` | | Arch | `base-devel curl ncurses` | `make` | | Alpine (musl) | `build-base pkgconf curl-dev ncurses-dev` | `make` | | NixOS | `nix-shell` (uses `shell.nix`) | `make` | | macOS | `xcode-select --install`, `brew install ncurses curl pkg-config` | `make` | `make install PREFIX=~/.local` installs the binary; CMake works too (`cmake -B build && cmake --build build && ctest --test-dir build`). The Makefile picks `ncursesw`, then `ncurses`, through pkg-config. On macOS it adds Homebrew's keg-only `ncurses`/`curl` to `PKG_CONFIG_PATH`; without Homebrew it falls back to the system `-lncurses` (wide-character capable). Verified so far: NixOS x86_64 with gcc and clang (`-Werror`, `make check`, `make asan`, ctest), and every source compiled `-fsyntax-only` with `x86_64-unknown-linux-musl-gcc` without warnings. Full musl, macOS and WSL builds run in CI (`.gitea/workflows/ci.yml`; the macOS job needs a runner and the `HAVE_MACOS_RUNNER` variable) or by hand with the checklist below. ## Files | What | Where | |---|---| | API keys (one per provider, entered in the TUI or with `--ask-key`) | `$XDG_CONFIG_HOME/cst-agent/credentials` (default `~/.config/cst-agent/`), mode 0600 | | Last provider, models, effort and approval mode | `$XDG_CONFIG_HOME/cst-agent/settings.json` | | Sessions, undo snapshots, exports | `/.agent/` (git-ignored automatically) | | Saved permission rules | `/.agent/permissions.json` | | Project notes injected into the prompt | `/AGENTS.md` (or `CST.md`) | ## Shell sandbox In the default `auto` approval mode, `run_shell` runs inside an OS sandbox when one is available. Commands may read and execute anything but may only write beneath the workspace, the temp directory, `/dev/null` and `/dev/tty`. | Platform | Sandbox | Notes | |---|---|---| | Linux 5.13+ | Landlock (raw syscalls, no extra library) | ABI ≥ 4 (6.7+) also blocks TCP connect/bind | | macOS | `sandbox_init` profile | also denies network | | Android / Termux | none | falls back to the read-only rules | | WSL 2 | Landlock when the WSL kernel enables it | otherwise rules | | Older kernels, Windows | none | falls back to the read-only rules | The status bar and sidebar show `auto · landlock`, `auto · seatbelt` or `auto · rules`. `CST_SANDBOX=off` disables the sandbox. When a sandboxed command looks blocked, the TUI asks whether to rerun it outside the sandbox. The ruleset is built in the parent; the forked child only calls `prctl` and `landlock_restrict_self` (async-signal-safe), so the agent itself is never confined. ## Terminal notes - UTF-8 locale gives the full UI. Under a non-UTF-8 locale, or with `CST_ASCII=1`, box and icon glyphs fall back to ASCII. - `NO_COLOR=1` turns colours off. - `/copy` uses OSC 52. iTerm2 needs "Applications in terminal may access clipboard"; tmux needs `set -g set-clipboard on`; Windows Terminal (WSL) supports it out of the box. - Bracketed paste needs ncurses (all platforms above). - macOS Terminal.app sends Option+Enter as Esc+Enter only with "Use Option as Meta key"; Ctrl+N always inserts a newline. ## Acceptance checklist Run on each platform before a release. Use a scratch git repository as the workspace and a real API key (entered when the TUI asks for it). Build and tests: - [ ] `make` has no warnings; `make check` passes - [ ] `make asan` passes (Linux; macOS: `make CFLAGS="-fsanitize=address,undefined -g" check`) - [ ] `cmake -B build && cmake --build build && ctest --test-dir build` passes - [ ] `make install PREFIX=/tmp/cst && /tmp/cst/bin/cst-agent --help` CLI: - [ ] `--list-sessions`, `--new`, `--resume `, `--continue` behave as documented - [ ] `--headless --prompt "list the files"` prints a transcript and exits 0 - [ ] First start asks for a provider and key; the credentials file is mode 0600 - [ ] Second start reuses provider, model and effort without asking TUI: - [ ] Typing Chinese/emoji keeps the cursor in the right column; ←→ Home End work - [ ] Pasting a multi-line block does not send it; Enter sends - [ ] `/` shows the command popup, Tab completes, `@` completes file paths - [ ] Esc cancels a running turn; Esc on an empty prompt does nothing; Ctrl+C twice quits - [ ] A long `run_shell` (e.g. `sleep 30`) stops promptly on Esc - [ ] Write permission shows the diff; `a` saves a rule; `p` saves a shell prefix rule - [ ] `ask_user` modal accepts a number, an arrow selection and typed text - [ ] Todo panel appears while tasks are open; Ctrl+T hides it - [ ] `/undo` restores files changed by the last turn; `/retry` re-asks - [ ] `/diff`, `/export`, `/status`, `/tools off grep`, `/yolo` work - [ ] Mouse: click a tool card to expand it, click in the input to move the cursor, click a picker row; `/mouse` turns it off - [ ] Tab toggles Build/Plan, Shift+Tab cycles ask/auto/yolo, Ctrl+P opens the palette - [ ] `/model` lists the provider's `/models` (marked `(api)`); a wrong key is re-asked - [ ] `auto` mode: `echo x > ~/outside` in run_shell asks "Rerun outside the sandbox?" (Linux 5.13+/macOS); with `CST_SANDBOX=off`, `ls` runs and `touch x` asks - [ ] Resize the terminal during streaming: layout recovers - [ ] `NO_COLOR=1` and `CST_ASCII=1` render readable screens WSL specifics: - [ ] Workspace under `/mnt/c/...` works (slower IO is expected); `~/project` is recommended - [ ] Windows Terminal: mouse wheel scroll and OSC 52 `/copy` macOS specifics: - [ ] Builds with Homebrew ncurses and with the system ncurses (`brew unlink ncurses`) - [ ] Terminal.app and iTerm2: arrows, Home/End, PgUp/PgDn, bracketed paste