- TUI: centered home screen with logo, boxed input with mode line, sidebar (>=120 cols), Ctrl+P palette, Tab Build/Plan, Shift+Tab approval cycle, mouse (cards, cursor, pickers, wheel), /sidebar /mouse /approval - /models probing: key check on entry (401 re-asks), API models in /model - Shell sandbox in C: Linux Landlock (writes limited to workspace/tmp, ABI>=4 blocks TCP), macOS sandbox_init, rules fallback elsewhere - Approval modes ask/auto/yolo (default auto); read-only command whitelist; ask to rerun outside the sandbox when a command looks blocked - Upgradable bootstrap scripts (git pull --ff-only, rebuild, reinstall) and cst-agent-update; cst-agent --version - tests: test_sandbox, test_models
5.9 KiB
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 | <workspace>/.agent/ (git-ignored automatically) |
| Saved permission rules | <workspace>/.agent/permissions.json |
| Project notes injected into the prompt | <workspace>/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=1turns colours off./copyuses OSC 52. iTerm2 needs "Applications in terminal may access clipboard"; tmux needsset -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:
makehas no warnings;make checkpassesmake asanpasses (Linux; macOS:make CFLAGS="-fsanitize=address,undefined -g" check)cmake -B build && cmake --build build && ctest --test-dir buildpassesmake install PREFIX=/tmp/cst && /tmp/cst/bin/cst-agent --help
CLI:
--list-sessions,--new,--resume <prefix>,--continuebehave 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;
asaves a rule;psaves a shell prefix rule ask_usermodal accepts a number, an arrow selection and typed text- Todo panel appears while tasks are open; Ctrl+T hides it
/undorestores files changed by the last turn;/retryre-asks/diff,/export,/status,/tools off grep,/yolowork- Mouse: click a tool card to expand it, click in the input to move the
cursor, click a picker row;
/mouseturns it off - Tab toggles Build/Plan, Shift+Tab cycles ask/auto/yolo, Ctrl+P opens the palette
/modellists the provider's/models(marked(api)); a wrong key is re-askedautomode:echo x > ~/outsidein run_shell asks "Rerun outside the sandbox?" (Linux 5.13+/macOS); withCST_SANDBOX=off,lsruns andtouch xasks- Resize the terminal during streaming: layout recovers
NO_COLOR=1andCST_ASCII=1render readable screens
WSL specifics:
- Workspace under
/mnt/c/...works (slower IO is expected);~/projectis 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