[Bug]: browser — harness cannot start DOMShell on Windows (bare npx, dropped npm env, REPL history dir)
Affected Software/Harness
browser
Version / Commit
cli-anything-browser 1.0.0 (repo commit 810c18b0d1ab9b234bc996c9fd999318523a3ef0, main)
Operating System
Windows
Python Version
3.12.10
Steps to Reproduce
- Windows 11, Chrome running with the DOMShell extension loaded and Connected. The DOMShell MCP server is already running on 127.0.0.1:3001: npx --yes "@apireno/[email protected]" --allow-write --no-confirm --token
- pip install -e /browser/agent-harness
- set DOMSHELL_TOKEN= & set DOMSHELL_PORT=3001
- cli-anything-browser fs ls / -> Defect A below.
- Apply the one-line fix for A, re-run the same command. -> Defect B below.
- cli-anything-browser --daemon -> Defect C below.
Expected Behavior
fs ls / lists the accessibility tree of the current tab, and --daemon drops into the REPL banner + prompt. The harness should work on a stock Windows box with Node, Chrome and the DOMShell extension installed, exactly as it does on Linux/macOS.
Actual Behavior
Three independent defects sit on the path every Windows user must walk. Each one alone is a hard stop; together they make the harness unusable on Windows.
--- Defect A. Bare npx cannot be spawned, so nobody on Windows passes the precheck.
domshell_backend.py:40 sets DEFAULT_SERVER_CMD = "npx" and hands it to subprocess.run([...]) (also at lines 102 and 140 for the version check). Windows' CreateProcess does NOT apply PATHEXT to a bare name, so this raises FileNotFoundError even though shutil.which("npx") resolves fine to npx.CMD. _check_npx_has_domshell() swallows the FileNotFoundError and returns False, so the user sees:
Error: DOMShell not found. Run `npx @apireno/domshell --version` once
Note: The first run may download the package (10-50 MB).
...on a machine where that exact command works in cmd.exe. Exit code 1.
Fix: resolve the interpreter once at import time — DEFAULT_SERVER_CMD = shutil.which("npx") or shutil.which("npx.cmd") or "npx".
--- Defect B. The MCP child process gets a whitelisted env, so npm's cache setting is dropped.
Both StdioServerParameters(...) constructions (domshell_backend.py:578 and :627) pass only command and args:
server_params = StdioServerParameters(
command=DEFAULT_SERVER_CMD,
args=_build_server_args()
)
The MCP SDK then spawns the child with a minimal environment whitelist, which drops npm_config_cache (and any other npm/networking config a locked-down or proxied machine needs). npx falls back to a cache directory the environment denies and the call dies with EPERM:
npm error code EPERM
npm error syscall mkdir
npm error path C:\Program Files\nodejs\node_cache\_cacache
Fix: pass the parent environment through — env={**os.environ} on both constructions.
--- Defect C. The REPL dies before its banner when the home directory is not writable.
repl_skin.py:161 hardcodes the history directory and immediately creates it:
hist_dir = Path.home() / f".cli-anything-{self.software}"
hist_dir.mkdir(parents=True, exist_ok=True)
On a machine whose profile directory is read-only (locked-down/managed image, sandboxed run, CI), cli-anything-browser in REPL mode raises before printing anything useful and exits:
PermissionError: [WinError 5] Access is denied: 'C:\Users\<user>\.cli-anything-browser'
The user never reaches a prompt, and there is no flag or env var to point the history file elsewhere. Because repl_skin.py is a shared template copied into every harness ("Copy this file into your CLI package at ..."), every harness inherits this.
Fix: honour an override (e.g. CLI_ANYTHING_HISTORY_DIR) and fall back to the temp directory when the mkdir fails, instead of refusing to start.
Relevant Logs / Tracebacks
# Defect C - full traceback tail
File "...\cli_anything\browser\browser_cli.py", line 384, in repl
skin = ReplSkin("browser", version="1.0.0")
File "...\cli_anything\browser\\\utils\repl_skin.py", line 162, in __init__
hist_dir.mkdir(parents=True, exist_ok=True)
File "...\pathlib.py", line 1311, in mkdir
os.mkdir(self, mode)
PermissionError: [WinError 5] Access is denied: 'C:\Users\<user>\.cli-anything-browser'
# Defect B - npx child process
npm error code EPERM
npm error syscall mkdir
npm error path C:\Program Files\nodejs\node_cache\_cacache
# Proof for Defect A (same shell, same PATH)
>>> subprocess.run(["npx", "@apireno/domshell", "--version"])
FileNotFoundError: [WinError 2] The system cannot find the file specified
>>> shutil.which("npx")
'C:\\Program Files\\nodejs\\npx.CMD'
>>> subprocess.run([shutil.which("npx"), "@apireno/domshell", "--version"])
returncode=0 stdout=2.0.10
Additional Context
Environment where this was found: Windows 11, Node 24.x, Chrome with the DOMShell extension loaded from the GitHub release zip; the harness was installed editable from this repo.
All three defects have small, local fixes and I am happy to send a PR for any or all of them. While fixing A and B I also hit two capability gaps that block real use of the harness (not part of this issue): daemon mode never keeps its session alive, and fs cannot read page text at all (cat returns element metadata only). The daemon issue is filed separately because its root cause is unrelated to Windows.
Source: HKUDS/CLI-Anything