{"slug": "fauxnix-bash-for-ai-agents-on-windows-no-wsl-we-measured-the-ps-tax", "title": "Fauxnix – bash for AI agents on Windows, no WSL (we measured the PS tax)", "summary": "Fauxnix, a bash-to-PowerShell translation layer for AI agents on Windows, claims to eliminate the need for WSL or a VM by deterministically converting Linux-style commands into native PowerShell, with benchmarks showing up to 3.1x faster task completion and zero errors versus PowerShell across 7 models on the Volcano Ark Coding Plan. The tool, installable via npm as fauxnix-cli, targets the growing trend of computer-use agents trained on macOS, aiming to make Windows environments respond like the bash environments agents are trained on.", "body_md": "**Run Linux-style commands on Windows — natively, deterministically, with no VM and no WSL.**\n\nfauxnix is a bash→PowerShell translation layer built for AI agents. Your agent keeps writing the\nbash it already knows (`ls -la | grep foo`, `find . -name '*.ts' | wc -l`, `kill -9 1234`), and\nfauxnix deterministically translates each command into PowerShell, executes it natively, and hands\nback output that looks like GNU/Linux: `ls -l` columns, bash-style error messages, coreutils exit\ncodes, UTF-8/GBK handled automatically.\n\n```\nnpm install -g fauxnix-cli    # then point any MCP harness at `fauxnix mcp`\nbash\n$ fauxnix \"ls -la src | head -2\"\n-rw-r--r-- 1 me me 1204 Aug 16 09:12 ast.ts\n-rw-r--r-- 1 me me 8192 Aug 16 09:12 cli.ts\n\n$ fauxnix \"cat nope.txt\"\ncat: nope.txt: No such file or directory        # not a PowerShell stack trace\n```\n\nSame model (DeepSeek-V4-Pro), same 5 tasks, three execution modes on one Windows machine —\nfull data in [`docs/benchmark-deepseek-v4-pro.md`](/20000419/fauxnix/blob/main/docs/benchmark-deepseek-v4-pro.md) and\n[`docs/benchmark-ark-models.md](/20000419/fauxnix/blob/main/docs/benchmark-ark-models.md):\n\n|  | PowerShell | **fauxnix** | Git Bash | \n|---|---|---|---|\n| tool calls / unexpected errors | 14 / 9 | **7 / 0** | 4 / 0 | \n| time (T1–T4) | 163s | **66s** | 57s | \n\nAcross 7 models on the Volcano Ark Coding Plan, the PowerShell-vs-fauxnix gap held for every\nmodel tested — worst case (kimi-k2-thinking): **3.1× slower with 24 error events** writing\nPowerShell vs zero errors through fauxnix. fauxnix lands within ~15% of the real-bash ceiling\nwith no bash toolchain installed.\n\nLLM agents are dramatically better at bash than at PowerShell — bash dominates training data, so\nmodels on Windows often produce \"looks right, doesn't run\" commands (wrong quoting, `curl` that\nisn't curl, mojibake from codepage mismatches, inscrutable `CategoryInfo` error dumps). Existing\nsolutions are either a full VM (WSL — heavy, wrong filesystem, separate environment) or plain\nshell wrappers (still PowerShell underneath).\n\nfauxnix takes the third road: **translate, don't emulate**. A large, high-value subset of the\nLinux command line — file ops, text processing, process management, archives, networking basics —\nmaps cleanly onto PowerShell + .NET. fauxnix implements that subset faithfully and *fails loudly\nand helpfully* on what it can't translate, so the agent never gets silently-wrong results.\n\nLabs now train computer-use agents on fleets of real desktops. Reporting in 2026 (*The\nInformation*, widely repeated) has OpenAI buying tens of thousands of Mac mini / Mac Studio\nboxes — no screen, no keyboard — to reinforcement-learn agents that click, edit, test, and\nrun bash workflows, and Anthropic renting Mac minis through AWS for the same class of work.\nThat scoring environment is macOS. Windows users should not have to install a guest Unix to\nkeep up: the agent keeps writing bash; fauxnix makes the Windows box answer like the box the\nagent was trained on. See [`docs/rfc-computer-use-windows.md`](/20000419/fauxnix/blob/main/docs/rfc-computer-use-windows.md).\n\n```\nnpm install -g fauxnix-cli\n```\n\nOr from source:\n\n```\ngit clone https://github.com/20000419/fauxnix && cd fauxnix\nnpm ci\nnpm install -g .\n```\n\nnpm package name is `fauxnix-cli` (the `fauxnix` name on npm belongs to an\nunrelated 2015 websocket library); the installed command is still `fauxnix`.\n\nRequires: Windows with PowerShell 5.1+ (built-in) and Node.js ≥ 18.\n\nPowerShell 7 is an opt-in, CI-tested tier:\n\n```\n$env:FAUXNIX_PS = 'pwsh'\nfauxnix check                 # edition: Core\n```\n\nSet the variable before starting `fauxnix` or its MCP harness; restart the\nharness after changing it. Windows PowerShell 5.1 remains the default. Invalid\nvalues and a missing selected executable fail loudly rather than falling back.\nThe default is pinned below `SystemRoot`; `pwsh.exe` is resolved once from\nabsolute `PATH` directories, excluding the current working directory.\nSee [PowerShell 7 support](/20000419/fauxnix/blob/main/docs/powershell-7.md).\n\n```\n# one-off commands\nfauxnix \"ls -la\"\nfauxnix \"grep -rn TODO src | wc -l\"\nfauxnix \"cat log.txt | grep -i error | sort | uniq -c\"\n\n# see what a command becomes (great for debugging / learning PS)\nfauxnix translate \"find . -name '*.log' -mtime +7 -delete\"\n\n# check your environment\nfauxnix check\nfauxnix doctor                   # check + encoding, harness config, MCP\n\n# write user-level MCP config (idempotent; also --codex/--opencode/--kimi/--qwen)\nfauxnix install --claude\n\n# run the MCP stdio server (what agent harnesses connect to)\nfauxnix mcp\n```\n\n`translate` only renders a script and does not read command operands. Because\n`sed -f` needs a script file, translate-only mode asks you to use `-e` with\ninline script text; normal command execution continues to support `sed -f`.\n\nUnknown commands (git, node, npm, python, cargo, gh, docker, ...) are **passed through natively**\nwith argv-style quoting. Windows `.cmd`/`.bat` shims necessarily pass through `cmd.exe`; fauxnix\npreserves its supported punctuation and fails loudly for `%`, embedded double quotes, NUL, and\nline breaks rather than passing a different argument.\n\nfauxnix ships an MCP stdio server exposing a `bash` tool (plus `fauxnix_translate` and\n`fauxnix_session`). Point any MCP-capable harness at it with\n`fauxnix install --claude` (or `--codex` / `--opencode` / `--kimi` / `--qwen`).\nIdempotent; prints what changed. Manual configs below.\n\n- **Quickstarts** — copy-paste config + a 10-command smoke:[`docs/examples/`](/20000419/fauxnix/blob/main/docs/examples)\n\n**Claude Code**\n\n```\nclaude mcp add fauxnix -- fauxnix mcp\n```\n\n**Codex** (`~/.codex/config.toml` or `codex mcp add fauxnix -- fauxnix mcp`)\n\n```\n[mcp_servers.fauxnix]\ncommand = \"fauxnix\"\nargs = [\"mcp\"]\n```\n\nNote: in non-interactive `codex exec` mode, MCP tool calls are auto-denied by\nthe approval layer; pass `--dangerously-bypass-approvals-and-sandbox` (or run\ninteractively and approve once).\n\n**OpenCode** (`opencode.json`)\n\n```\n{\n  \"mcp\": {\n    \"fauxnix\": { \"type\": \"local\", \"command\": [\"fauxnix\", \"mcp\"] }\n  }\n}\n```\n\n**Kimi Code** — unlike the others, MCP servers live in a JSON file, not the\nTOML config: `~/.kimi-code/mcp.json`\n\n```\n{\n  \"mcpServers\": {\n    \"fauxnix\": { \"command\": \"fauxnix\", \"args\": [\"mcp\"] }\n  }\n}\n```\n\n**Qwen Code** (`~/.qwen/settings.json`)\n\n```\nfauxnix install --qwen\n```\n\nThe installer preserves the rest of `settings.json` and writes an absolute\nNode + package-entry launcher so Qwen startup does not depend on its working\ndirectory or `PATH` order. See [the Qwen example](/20000419/fauxnix/blob/main/docs/examples/qwen.md) for\nthe generated JSON shape.\n\n**Any MCP client** — stdio server: `fauxnix mcp`. The tool name is `bash` (override with\n`FAUXNIX_TOOL_NAME`). Tool description already teaches the model the supported subset, so no\nsystem-prompt changes are required.\n\nThe MCP session persists `cwd`, environment variables, `export`/` unset`, `cd -`/OLDPWD, and\npositional parameters (`set --` / `$1` / `\"$@\"`) across tool calls — it behaves like a logged-in\nshell, not a stateless `exec`. `$0` is the MCP tool name (`bash` / `FAUXNIX_TOOL_NAME`), not a\nWindows path.\n\n~105 commands, all output-matched against real GNU coreutils on Windows (Git Bash) during development:\n\n- **files** :`ls cp mv rm mkdir rmdir touch mktemp ln readlink realpath basename dirname stat file du df find chmod chown diff`\n- **text filters** :`grep egrep sed awk sort uniq cut tr` — sed/awk scripts are parsed while\npreparing an executable plan (unsupported constructs throw named errors, never silently\nmisbehave); inspect-only`translate` keeps`sed -f` file reads out of that path\n- **text I/O** :`echo printf cat head tail wc tee nl tac md5sum sha1sum sha256sum base64 seq yes xargs`\n\nThe curated **agent-daily 60** carry a `CommandSpec`: unknown options fail with a GNU-style\nusage error instead of being ignored. The generated [`docs/command-specs.md`](/20000419/fauxnix/blob/main/docs/command-specs.md)\nis the exact list, coverage count, option table, and exclusion rationale; `fauxnix list --json`\nexposes the same per-command metadata. `find` stays unspec'd so predicates like `-name` still\ncompile; `sed`/` awk`/` egrep` keep their command-specific parsers; `tar` remains native to\n`tar.exe` so supported bsdtar options reach the executable. Implemented GNU holes include\n`cp -n` / `mv -n` / `touch -c` / `tee --append` / `grep -m` / `head --lines` /\n`du --max-depth` / `env -u` / `ps -f` / `command -V` / `date --date=@SECONDS`.\n\n- **shell/system** :`cd pwd export unset env printenv ps kill pkill pgrep sleep which type whoami id groups date uname hostname uptime free nproc clear true false test [ [[ : pushd popd dirs sudo timeout man history less more source . eval exit alias set shift`\n- **network** :`curl wget ping netstat ss ip ifconfig nslookup dig host`\n- **archives** :`tar gzip gunzip zcat zip unzip`\n\nPlus shell syntax: pipes, `&&` / `||` / `;`, redirections (`> >> 2> 2>&1 < &>`, `/dev/null`),\nquoting, `$VAR` `$1` `$#` `\"$@\"` `set --` `shift`, `${name:-word}` `${name//pat/str}`\n`${name:off:len}` `${name[n]}` `${#name[@]}`, `A=(x y z)` array assignment, `$(...)` command\nsubstitution, `VAR=x cmd` prefixes, `~` expansion, and POSIX-style path normalization\n(`/tmp`, `/d/foo` → `D:\\foo`).\n\nExit codes follow bash conventions: 0 ok, 1 fail, 2 usage/serious, 127 command not found, 124 timeout.\n\n```\nbash command ──parser──▶ AST ──translator──▶ PowerShell script ──executor──▶ selected PowerShell\n                                                                              │\nagent ◀── GNU-style output, bash-style errors ◀── UTF-8 framed host protocol ◀┘\n```\n\n- **Deterministic translation, zero LLM calls** at runtime.\n- Each command maps to a generator that emits a self-contained PowerShell block honoring the\n\"Fauxnix contract\": string-per-line stdout, `[Console]::Error.WriteLine` for bash-style\nstderr,`$script:fx_exit` for exit codes,`$input` for stdin.\n- The executor wraps every script with UTF-8 enforcement (`[Console]::OutputEncoding` ,`$OutputEncoding` ,`chcp 65001` ), decodes native output at the process boundary (UTF-8 by\ndefault or GBK(936) in`ansi` mode), keeps host frames UTF-8, strips CLIXML serialization and\nPowerShell noise from stderr, and rewrites common PowerShell errors (including zh-CN locale\nmessages) into bash phrasing.\n- Scripts run via `-EncodedCommand` (UTF-16LE) and transparently fall back to a temp`.ps1` file\nwhen the 32 KB command-line limit would be exceeded.\n\nfauxnix optimizes for the commands agents actually run. Documented deviations:\n\n- `X=1` standalone assignments follow`export` semantics (one session-wide environment; bash's\nshell-var vs exported-var distinction does not exist), and a same-segment prefix is visible to`$VAR` inside the command's own words (`Z=in [[ $Z == in ]]` is true here, false in bash where\nword expansion precedes the temporary environment).\n- `yes` is capped at 65,536 lines — PS 5.1 pipelines cannot signal upstream producers to stop, so\nan unbounded`yes | head` would hang.\n- `tail -f` ,`eval` ,`alias` , heredocs,`env -i` /`--ignore-environment` ,\nbackground`&` , and output/fd redirects (`>``>>`` 2>``2>>``&>``&>>`` 2>&1``1>&2` ) on a non-last pipeline stage (`echo hi >f | cat` ) are\nrejected with operation-specific, actionable error messages instead of\nmisbehaving. Per-stage`<` remains supported; fully routed per-stage output\nfds are still tracked by #157.\n(`if/then/elif/else/fi` ,`for x in ...` ,`while` /`until` ,`case ... esac` (`;;` only;`;&` /`;;&` fail loud),\nbacktick substitution,`command -v` , pipeline`read` ,\ndotenv-style`source` , word-level`$((...))` arithmetic expansion,`A=(x y z)` arrays, and`${name//pat/str}` /`${name:off:len}` are supported.)\n- `command -v <builtin>` prints`/usr/bin/<name>` where bash prints the bare builtin name;\nexit codes and empty-result semantics match.\n- `chmod` maps only the read-only bit; exec bits are no-ops on Windows.`chown` is a silent no-op\n(as in Git Bash).\n- `ps aux` columns are approximations (no per-process CPU% accounting, USER shows`?` ).\n- `gzip -c` /pipeline stdin is text-faithful, not byte-faithful; file-mode`gzip f` is byte-exact.\n- A pipeline producing exactly one line, piped into `wc -l` , counts that line (bash would count 0\nif the producer omitted the trailing newline).`printf 'x' | md5sum` stays byte-exact.\n- `sed` /`awk` support the common subset; hold-space, labels, arrays, loops throw named\n\"not supported\" errors at translate time.\n- `curl` /`wget` refuse loopback/private/reserved addresses (localhost, 127.x, ::1, 10.x,\n172.16–31.x, 192.168.x, 169.254.x) as a safety default for agent-driven HTTP.\n- **Native-tool pipelines vs encoding** : PS 5.1 has a single console-encoding knob, so\npiping localized admin tools (ipconfig, tasklist — GBK on zh-CN) and UTF-8-native dev\ntools (node, curl) cannot both decode cleanly mid-pipeline. Default favors UTF-8 dev\ntools; set`FAUXNIX_NATIVE_ENCODING=ansi` when your agents grep Chinese output of\nnative Windows admin tools.**File reads are always sniffed per file** (UTF-8 strict →\nGBK fallback), so grep/sed/awk over GBK*files* works in either mode — unlike Git Bash,\nwhich only matches the encoding its locale assumes.\n\n```\nnpm install\nnpm test          # unit + real-PowerShell integration suite (Windows only, auto-skipped elsewhere)\n$env:FAUXNIX_PS = 'pwsh'; npm test   # same suite through PowerShell 7\nnpm run build\nnpx tsx scratch/run.mjs \"any bash command\"   # quick live check\n```\n\nDifferential vs Git Bash is opt-in (`FAUXNIX_DIFF_ORACLE=1`; skips if unset or `bash.exe` is missing — Git Bash is not required). See [`test/differential/README.md`](/20000419/fauxnix/blob/main/test/differential/README.md). The 253-case corpus enforces the RFC C-7 minimum of 200 cases and a 95% identity gate. The weekly oracle runs from `.github/workflows/differential.yml`; two consecutive green **scheduled** runs are still required release evidence after this gate lands.\n\nArchitecture map: `src/parser.ts` (bash subset → AST) · `src/translator.ts` (AST → PowerShell +\nexecutor wrapper) · `src/executor.ts` (spawn, redirects, session persistence) ·\n`src/commands/*.ts` (per-command generators) · `src/mcp.ts` (MCP server) · `src/cli.ts`.\n\nRoadmap: [docs/rfc-roadmap-to-1.0.md](/20000419/fauxnix/blob/main/docs/rfc-roadmap-to-1.0.md) — tracks, milestones,\nand the RFC process for proposing waves.\n\nTrust model, host protocol, kill semantics, network guard, and reporting:\n[SECURITY.md](/20000419/fauxnix/blob/main/SECURITY.md).\n\nMIT © 20000419", "url": "https://wpnews.pro/news/fauxnix-bash-for-ai-agents-on-windows-no-wsl-we-measured-the-ps-tax", "canonical_source": "https://github.com/20000419/fauxnix", "published_at": "2026-09-07 01:43:53+00:00", "updated_at": "2026-09-07 02:14:15.889461+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "artificial-intelligence"], "entities": ["fauxnix", "PowerShell", "WSL", "Git Bash", "DeepSeek-V4-Pro", "Volcano Ark", "OpenAI", "Anthropic"], "alternates": {"html": "https://wpnews.pro/news/fauxnix-bash-for-ai-agents-on-windows-no-wsl-we-measured-the-ps-tax", "markdown": "https://wpnews.pro/news/fauxnix-bash-for-ai-agents-on-windows-no-wsl-we-measured-the-ps-tax.md", "text": "https://wpnews.pro/news/fauxnix-bash-for-ai-agents-on-windows-no-wsl-we-measured-the-ps-tax.txt", "jsonld": "https://wpnews.pro/news/fauxnix-bash-for-ai-agents-on-windows-no-wsl-we-measured-the-ps-tax.jsonld"}}