Platform support¶
Clauster runs on Linux, macOS, and Windows, and the same test suite exercises all three in CI. Most capabilities behave identically everywhere; the matrix below is the single source of truth for what works where and which platform-bound mechanism backs each cell. When a row changes, update it here rather than restating the gap in another doc — the scattered notes elsewhere point back to this matrix.
Legend: ✓ works · ✗ not available — an honest platform gap, not a defect. Bracketed numbers point at the notes below.
Capability matrix¶
| Capability | Linux | macOS | Windows |
|---|---|---|---|
| Standard (Server Mode) bridge | ✓ | ✓ | ✓ [1] |
| Interactive Session (PTY) bridge | ✓ | ✓ | ✓ [2] [3] |
| Hosted channel (claustrum) | ✓ | ✓ | ✓ [4] |
Dashboard claude login |
✓ | ✓ | ✓ [5] |
Config-write CLI (claude mcp / claude plugin) |
✓ | ✓ | ✓ [6] |
| Per-bridge CPU % / RSS memory [7] | ✓ | ✓ | ✓ |
| Per-bridge disk I/O rate | ✓ | ✗ [8] | ✓ |
| Advisory file locking (config writes + bridge lifecycle) | ✓ | ✓ | ✓ [9] |
Owner-only file modes (0o600 / 0o700) |
✓ | ✓ | ✓ [10] |
Directory fsync (crash durability) |
✓ | ✓ | ✓ [11] |
Service-unit install (install-service) [12] |
✓ | ✓ | ✓ |
Notes¶
- Windows spawns the bridge with
CREATE_NEW_PROCESS_GROUPand stops it viaCTRL_BREAK_EVENT; POSIX usesstart_new_session+SIGINT. - POSIX uses
pty.openpty+termios; Windows drives a ConPTY keeper via pywinpty (#903), which needs theptyextra — without itlaunch_mode: ptyfalls back to Server Mode. The extra pulls pywinpty on Windows and pyte everywhere (the live pty-screen terminal view needs it on every OS). Install it withpip install 'clauster[pty]'on a package install, orclauster deps install ptyon the standalone binary — the extra is intentionally not bundled there, anddeps installside-loads it instead (#904; seeclauster deps). - Stopping an Interactive Session on Windows is a hard kill: the bridge
lives in the keeper's separate ConPTY console, so the graceful
CTRL_BREAKcan't reach it — the local process is reaped, but the cloud session isn't deregistered (it re-registers on the next launch). Linux/macOS get the orderly double-SIGINT. - Windows dials claustrum's named pipe (discovered via
rpc.pipe) rather than theAF_UNIXsocket, and clauster spawns the daemon with-listen-pipeplus a-token-filehandoff (a numeric token fd isn't usable there). Round-trip validated (#902). - Subscription sign-in (
claude auth login, plain pipes) works everywhere; the long-livedsetup-tokenflow runs under a POSIX PTY on Linux/macOS and a ConPTY (pywinpty) on Windows (#905). Because a ConPTY echoes written input back — which a parent can't disable the way POSIXtermiosdoes — the operator-pasted code is registered and redacted out of any returned/logged output. Like the Interactive Session, the Windows ConPTY path needs theptyextra (pip install 'clauster[pty]'); without itsetup-tokenfails closed with a clear message (subscription sign-in still works). - Routes exercised on the Windows CI cells + VM.
psutil.cpu_times/memory_infoon every platform.psutilhas no per-processio_counterson macOS, so a bridge card'sdisk_read_bps/disk_write_bpsfields are blank there.- An in-process lock serializes clauster's own concurrent writers on every
OS; POSIX additionally takes an advisory
fcntl.flock, which also guards other clauster processes — the config/CLAUDE.mdwriters, and since #949 the per-project spawn/stop/forget/adopt sections, so a headless CLI/MCP writer serializes against the live server. Cross-clauster-process serialization therefore needs the POSIX flock; a single clauster process is fully covered everywhere. Neither lock coordinates with theclaudeCLI (which takes no lock) — that's covered by the atomicos.replace(no torn files) plus the caller's external-edit hash guard. - POSIX sets
0700/0600mode bits; Windows sets an equivalent owner-only ACL on the state dir viaicacls(remove inheritance; grant only the current user + SYSTEM). The Windows ACL is best-effort: the defaultstate_dir(under%USERPROFILE%) already inherits a user + SYSTEM + Administrators ACL, so ificaclscan't run (absent, a domain/service account with no resolvableUSERNAME, a non-zero exit) clauster logs a loud warning and proceeds on the inherited ACL rather than blocking every state write. Relocatestate_diroutside the user profile and you should tighten it yourself. - POSIX
fsyncs the parent directory after a rename; Windows can'tfsynca directory handle, but NTFS journals the metadata so the rename is recovered on reboot — equivalent durability via a different mechanism. ops.render_service_unitrenders a systemd unit on Linux, a launchd plist on macOS (launchdkind), and a Shawl service-install script on Windows (windowskind). Windows requires Shawl (clauster deps install shawl) before running the generated script. The generated systemd unit setsKillMode=processso live pty bridges survive asystemctl restart(under systemd's defaultKillMode=control-groupthey would be reaped —clauster doctorwarns when an installed unit is set that way);KillModeis a systemd concept, so this applies on Linux only — launchd and the Windows service have no equivalent.