Windows: official port -- UCRT static build, UTF-8 throughout, Low IL sandbox, ncurses TUI, installer; v0.6.0
ci / linux (clang) (push) Canceled after 0s
ci / linux (gcc) (push) Canceled after 0s
ci / sanitizers (push) Canceled after 0s
ci / musl (push) Canceled after 0s
ci / macos (push) Canceled after 0s

Build
  * cross build switches to pkgsCross.ucrt64 (shell-win.nix); curl (Schannel),
    winpthreads and ncurses 6.6 are linked statically, so the release is
    cst-agent.exe + busybox.exe (busybox-w32 Unicode) with no extra DLLs
  * windres embeds a manifest with activeCodePage=UTF-8 and a version resource
  * ncurses 6.6 Windows console driver patches (mouse button state, A_DIM,
    wide-char declarations): scripts/patches/
  * scripts/bootstrap_msys2.sh builds the same release natively in MSYS2
    UCRT64; PR #1's MINGW64 notes now point there
  * vendor/tre-regex (musl's TRE) provides <regex.h> on MinGW

UTF-8
  * paths cross the system call boundary as UTF-16 (*W APIs); console code
    pages set to 65001 and restored on exit; files are read and written in
    binary mode
  * child output that is not valid UTF-8 is decoded from the console, OEM or
    ANSI system code page
  * read_file hides CR; edit_file, apply_patch and write_file keep CRLF line
    endings and a UTF-8 BOM

OS layer and processes
  * os_dir_* and cst_fnmatch replace the POSIX-only directory walks in
    subagent, plugins, skills, undo and fs_tools; realpath / path_under and
    symlink rejection work on Windows
  * every child goes through CreateProcessW with its own environment block
    inside a Job Object, so timeouts and Esc end the whole process tree

Sandbox (auto mode, "auto · lowil")
  * run_shell runs with a restricted Low integrity token; the workspace gets
    an inheritable Low label once, the sandbox TEMP is labeled Low, and the
    credentials file gets a no-read-up label
  * drive roots, the profile and system folders are never labeled
  * network commands still ask, since Low IL does not block the network;
    Access denied and MSYS2's 0xc0000142 offer a rerun outside the sandbox
  * /sandbox lists labeled folders, /sandbox reset-labels restores them

TUI
  * raster console fonts are switched to Consolas / NSimSun while running
  * the home logo falls back to text when the console font lacks U+2580
  * mouse drag copy goes to the Windows clipboard

Distribution
  * scripts/install_windows.ps1 installs a Gitea release into
    %LOCALAPPDATA%\Programs\cst-agent and adds it to the user PATH;
    cst-agent-update.cmd reruns it; scripts/release_windows.sh uploads the
    zip with the token taken from the environment
  * scripts/run_windows.bat is gone; docs/README-windows.md is rewritten

Tests
  * new test_lowil, test_win_utf8 and test_os_dir; tests made portable
    (cst_test_util.h)
  * scripts/win_test.sh and scripts/winvm/ run the suite on English and
    Chinese Windows Server VMs as Administrator, a standard user and a
    Chinese user name: 29/29 on all six
This commit is contained in:
WHC
2026-10-06 23:08:14 +08:00
parent 9862c29f58
commit 2a43ae6622
84 changed files with 9784 additions and 1083 deletions
+23 -5
View File
@@ -48,12 +48,13 @@ write beneath the workspace, the temp directory, `/dev/null` and `/dev/tty`.
| Linux 5.13+ | Landlock (raw syscalls, no extra library) | ABI ≥ 4 (6.7+) also blocks TCP connect/bind |
| Linux 5.5+ without Landlock (Android / Termux, WSL, older distros), x86_64 / aarch64 | seccomp user-notify | refuses IPv4/IPv6 sockets; see below |
| macOS | `sandbox_init` profile | also denies network |
| Older kernels, Windows | none | falls back to the read-only rules |
| Windows 10 1903+ | Low integrity restricted token + Job Object | writes need a Low label (given to the workspace once); network is not blocked, so network commands still ask; see `README-windows.md` |
| Older kernels | none | falls back to the read-only rules |
The status bar and sidebar show `auto · landlock`, `auto · seccomp`,
`auto · seatbelt` or `auto · rules`. `CST_SANDBOX=off` disables the
sandbox; `CST_SANDBOX=landlock` or `CST_SANDBOX=seccomp` allows only that
kind. When a sandboxed command looks blocked, the TUI asks whether to rerun
`auto · seatbelt`, `auto · lowil` or `auto · rules`. `CST_SANDBOX=off`
disables the sandbox; `CST_SANDBOX=landlock`, `seccomp` or `lowil` allows
only that kind. When a sandboxed command looks blocked, the TUI asks whether to rerun
it outside the sandbox. The policy is built in the parent; the forked child
only makes a few async-signal-safe syscalls before `exec`, so the agent
itself is never confined.
@@ -140,7 +141,7 @@ TUI:
- [ ] 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/Termux/macOS); with `CST_SANDBOX=off`, `ls` runs and `touch x` asks
sandbox?" (Linux/Termux/macOS/Windows); 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
@@ -149,6 +150,23 @@ WSL specifics:
- [ ] Workspace under `/mnt/c/...` works (slower IO is expected); `~/project` is recommended
- [ ] Windows Terminal: mouse wheel scroll and OSC 52 `/copy`
Windows specifics (`scripts/win_test.sh` runs the tests on English and
Chinese VMs as Administrator, a standard user and a Chinese user name):
- [ ] `install_windows.ps1 -Zip dist\cst-agent-*.zip` installs, adds the user
PATH; `cst-agent-update -Zip ...` works while `cst-agent.exe` runs
- [ ] conhost with a raster font: Chinese renders (font switched), and the
old font is back after exit; Windows Terminal renders the same
- [ ] Chinese input via IME, paste, mouse click / drag-copy / wheel
- [ ] Workspace under `C:\Users\<中文名>\项目`: read/write/edit/apply_patch
keep CRLF and BOM; `run_shell` output in Chinese is readable on a
936 system
- [ ] `auto · lowil`: first command reports the label; `echo x > C:\outside`
asks to rerun; `curl ...` asks before running; `/sandbox reset-labels`
restores the label
- [ ] Esc during `sleep 30 & sleep 30` returns at once and leaves no
`busybox.exe` behind
macOS specifics:
- [ ] Builds with Homebrew ncurses and with the system ncurses (`brew unlink ncurses`)