What it does
detect is the shared detection layer that all platform and agent blocks
import from. Instead of each block duplicating environment checks, they
all import from this single file. One fix, all blocks benefit.
This block is auto-installed when you add any platform block (open-url,
copy-clipboard, notify-os) or agent block (json-mode, next-steps).
API
import {
currentPlatform, // "darwin" | "win32" | "wsl" | "linux" | "unknown"
isWindows, // process.platform === "win32"
isCi, // CI, GITHUB_ACTIONS, GITLAB_CI, etc.
isHeadlessLinux, // no DISPLAY, no WAYLAND_DISPLAY, not WSL
hasCommand, // checks if a binary exists in PATH (cross-OS)
detectMode, // "human" | "json" based on --json flag / TTY / pipe
shouldColor, // respects NO_COLOR and FORCE_COLOR
} from "@/cli/platform/detect";Why a separate block
- DRY: WSL detection, CI detection, and mode detection were duplicated across blocks. One bug fix had to land in multiple places.
- Cache: WSL detection reads
/proc/version. The result is cached per-process. Without sharing, each block reads the file independently. - Composable: your own commands can import
detecttoo. NeedisCi()in your deploy guard? Import it.
currentPlatform() vs process.platform
process.platform returns "linux" for both native Linux and WSL.
currentPlatform() distinguishes WSL as its own value because the
behavior difference (routing through Windows host binaries) is
significant enough to warrant a distinct branch in CLI code.
const os = currentPlatform();
// "darwin" | "win32" | "wsl" | "linux" | "unknown"
if (os === "wsl") {
// route through cmd.exe or wslview
}hasCommand(cmd)
Walks PATH, checks existsSync for each candidate. On Windows,
automatically appends .exe, .cmd, .bat extensions.
if (hasCommand("docker")) {
// docker is available
}detectMode(opts)
Returns "human" or "json". Precedence:
explicit --json flag > NO_JSON env > TTY detection > default human.
Used by json-mode and next-steps blocks for consistent mode resolution.