Skip to content

Platform Integration

Z-M-Huang edited this page Apr 28, 2026 · 4 revisions

Platform Integration

How stud-cli behaves on the three supported host platforms: Linux, macOS, and Windows. This page is a cross-platform contract, not a portability apology — the differences are narrow, but they are real and worth pinning down.


Supported platforms

Platform Notes
Linux Primary development platform.
macOS Supported first-class.
Windows Supported with the caveats below. Uses the native shell (cmd, PowerShell) semantics; WSL2 is indistinguishable from Linux for stud-cli.

No BSD / Solaris / Plan 9. No "POSIX in general" claim — only the three above.


Directory resolution

The platform path resolver for user-global storage is native per OS and is pure: callers inject process.env and os.homedir(), and the resolver returns joined paths without side effects.

Platform Global config dir Global data dir Global cache dir
Linux $XDG_CONFIG_HOME/stud-cli if set and non-empty, else $HOME/.config/stud-cli $XDG_DATA_HOME/stud-cli if set and non-empty, else $HOME/.local/share/stud-cli $XDG_CACHE_HOME/stud-cli if set and non-empty, else $HOME/.cache/stud-cli
macOS $HOME/Library/Application Support/stud-cli $HOME/Library/Application Support/stud-cli $HOME/Library/Caches/stud-cli
Windows %APPDATA%\stud-cli if set and non-empty, else %USERPROFILE%\AppData\Roaming\stud-cli %APPDATA%\stud-cli if set and non-empty, else %USERPROFILE%\AppData\Roaming\stud-cli %LOCALAPPDATA%\stud-cli\Cache if set and non-empty, else %USERPROFILE%\AppData\Local\stud-cli\Cache

Path construction invariant

All platform paths are constructed with the native path API (path.join with the platform-specific joiner). Core must not hard-code / or \\ separators into returned paths. This is especially important for Windows, where the returned strings must use Win32 separators even when tests run on a non-Windows host.

Environment access invariant

Native environment reads are intentionally narrow:

  • allowed surface: get(name) and has(name)
  • has(name) returns false for unset values and for explicitly empty-string values
  • no bulk-read API is exposed
  • banned shapes include list, entries, all, keys, dump, or any equivalent "return the whole env" helper

This preserves invariant #2: core never offers a convenience API that can dump the process environment into model context.

Canonicalization

Every resolved path is canonicalized before trust-list lookup and manifest recording:

  • Symlinks: resolved to their final target. Two launches through different symlinks that target the same directory resolve to the same trust entry.
  • Windows junctions and reparse points: resolved the same way as symlinks. A session launched under a junctioned path matches the trust entry of the canonical target.
  • Case folding: on case-insensitive filesystems (default macOS, Windows), paths are lowercased for trust-list comparison. On Linux's case-sensitive filesystems, comparison is exact.
  • Trailing separator: stripped before comparison.

No walk-up

Project root is <cwd>/.stud/ exactly — no walk-up into parent directories on any platform. See Project Root.


Signal handling

Signal Platforms stud-cli response
SIGINT (Ctrl-C) Linux, macOS, Windows (Ctrl-C) Graceful turn cancel: stops the current turn at the next cancellation point, persists the state slot if possible, prompts the user (or exits in headless). See Concurrency and Cancellation § cancellation scopes.
SIGTERM Linux, macOS (no Windows equivalent) Persist-and-exit: final snapshot write, then exit with code 130.
SIGHUP Linux, macOS Reserved; no v1 reaction beyond the same persist-and-exit.
Console close (Windows) Windows Maps to SIGTERM-equivalent: persist-and-exit.

A second Ctrl-C during a graceful cancel escalates to a hard exit that skips further in-flight writes. The last acknowledged snapshot is still intact — see Persistence and Recovery § Crash consistency.


Exit codes

Code Meaning
0 Normal exit (session ended, or user quit cleanly).
1 Uncaught error surfaced to the user.
2 Validation failure — session did not start. See Validation Pipeline.
3 Trust refused — project not trusted, session did not start. See Project Trust.
4 No interactor available in a session that needed one. See Headless and Interactor.
5 Resume failure — manifest could not validate. See Persistence and Recovery.
130 Terminated by SIGINT / SIGTERM. Persist-and-exit completed.
137 Process killed (e.g., SIGKILL or OOM). The last acknowledged snapshot is intact; anything after it is lost.

Any code outside this list is an implementation defect — the wiki expects code to conform.


Line endings

Context Rule
File reads (e.g., a tool reading a project file) Native line endings preserved. Core does not normalize.
File writes by the Session Store Store's choice; the bundled Filesystem store writes \n (LF) on all platforms for portability of session archives.
LLM context Line-ending-agnostic; whatever the tool produced is what reaches the request.
stdin read by commands Native. \r\n on Windows is consumed as one terminator.

CRLF-sensitive tools (diff, regex with $) are the tool's problem; core does not interpose.


Terminal integration

Signal Behavior
Default interactive TTY Bundled TUI uses color. Color is part of the default product experience, not an optional enhancement.
NO_COLOR env var set to any non-empty value Explicit opt-out: bundled TUI disables ANSI colors. Bundled loggers disable ANSI colors in their sinks. See the NO_COLOR convention.
FORCE_COLOR env var Ignored in v1. If you want color off, NO_COLOR wins; if you want color on, a TTY and no NO_COLOR suffices.
TERM=dumb Bundled TUI falls back to a plain interactor (no cursor addressing).
Not a TTY (pipe, redirect) Bundled TUI degrades to line-oriented output. The interactor capability degrades accordingly — see Headless and Interactor.
Unicode rendering UTF-8 only. On Windows, stud-cli sets the console code page to 65001 (UTF-8) at startup.

CI detection

CI=true (any truthy value) in the environment implies:

  • No TTY assumed even if one is attached.
  • Bundled TUI starts in headless mode.
  • No interactive auth paths are offered in first-run; a provider that requires Auth.DeviceCode or Auth.Password fails First Run with a clear diagnostic rather than hanging.
  • Exit codes above are the primary signal; there is no "press any key to exit".

See Headless and Interactor and First Run.


File-permission expectations

File Expected permissions
~/.stud/settings.json 0600 on Linux / macOS. Windows: ACL restricted to the current user. A wider permission emits a SettingsPermissionsLoose diagnostic.
~/.stud/trust.json (user-global trust list) Same as settings.json.
~/.stud/integrity/ Same.
<cwd>/.stud/ No enforcement — the project layer is under the user's own project rules.
Session-store data (bundled filesystem store) Store's responsibility. See the reference page.

A loose permission is a warning, not a hard error, because there are legitimate shared-development setups. The diagnostic encourages the user to tighten.


Subprocess invocation

stud-cli spawns subprocesses for:

  • MCP servers with transport: stdio.
  • Tools that shell out (e.g., the bundled Bash tool).
  • CLI-wrapper providers.

Cross-platform rules:

  • Core uses the platform's native subprocess API — no shell wrapping by default, to avoid shell-injection footguns. A tool that wants shell semantics (pipes, globs) opts in and documents it.
  • Inherited env: subprocesses inherit stud-cli's resolved env — including any env entries declared for the tool / provider / MCP server. Inherited env is not filtered by core; tools and providers are trusted to not ship sensitive values.
  • Windows shell quoting differs per shell; tools that accept arguments are responsible for their own quoting. The bundled Bash tool requires bash in PATH on Windows (typically provided by Git-for-Windows or WSL).

What this page does not cover

  • Containerization strategy for yolo mode — see Sandboxing.
  • Per-provider platform quirks — see each provider page.
  • The TUI's specific terminal capability matrix — see Default TUI.

Related pages

Introduction

Reading

Core runtime

Contracts

Category contracts

Context

Security

Runtime behavior

Operations

Providers (bundled)

Integrations

Reference extensions

Tools

UI

Session Stores

Loggers

Providers

Hooks

Context Providers

Commands

Case studies

Flows

Maintainers

Clone this wiki locally