Stem’s released installers target macOS and Linux. Windows is a terminal-first dev port: you can clone, install, and run from a user account without admin rights, using a portable Node.js zip. Packaging (NSIS/portable exe) is not included yet.
Personal data still lives outside the clone, under %APPDATA%\Stem\ (and
%APPDATA%\Stem Profiles\ for --fresh / --profile=). Reinstalling Node or
re-cloning the repo does not wipe that folder.
- Download the Windows x64 Node.js 24+ binary zip from nodejs.org (the zip, not the MSI).
- Extract somewhere you can write, e.g.
%USERPROFILE%\tools\node-v24.x.x-win-x64. - Put that folder on your PATH. Prefer a user PATH entry (no admin). You do not need a system-wide PATH.
This persists for your account in new terminals and apps. No admin prompt.
- Press Win, type
environment, open Edit environment variables for your account (not “Edit the system environment variables”). - Under User variables, select Path → Edit → New.
- Add the full folder that contains
node.exe, e.g.C:\Users\<you>\tools\node-v24.x.x-win-x64(same path as step 2; expand%USERPROFILE%yourself in the dialog). - OK out of all dialogs.
- Close and reopen any open terminals (and Cursor / VS Code if they were already running) so they pick up the new PATH.
- Verify:
where node
node -v
npm -vwhere node should list your extracted folder first.
When you upgrade Node later, edit that same user Path entry (or add a new one and remove the old) so it points at the new extract folder.
Useful for a one-off check without changing account settings.
cmd.exe (preferred when PowerShell profiles are broken):
set PATH=%USERPROFILE%\tools\node-v24.x.x-win-x64;%PATH%
node -v
npm -vPowerShell — always skip the profile if profile.ps1 errors or is blocked:
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$env:PATH = \"$env:USERPROFILE\tools\node-v24.x.x-win-x64;$env:PATH\"; node -v; npm -v"Or open a -NoProfile shell first, then set PATH for that session.
git clone https://github.com/join3r/stem.git
cd stem
npm install
npm run preflight
npm run devIf preflight says Electron’s binary is missing:
node node_modules\electron\install.jsOn Windows, approved commands run in Git Bash when Git for Windows is installed, and fall back to Command Prompt otherwise:
Git Bash (when bash.exe is on disk):
bash.exe --noprofile --norc -c "<command>"
--noprofile --norc skips .bashrc / /etc/profile (the same idea as cmd /d).
Git’s usr\bin is prepended to PATH so ls / cat / grep work. The safety
parser then follows bash quoting, not cmd’s — ls auto-runs, dir does not.
Stem looks for bash.exe on disk (usual Git for Windows paths, then PATH)
without running PowerShell. If Git is installed somewhere unusual, paste the
path to bash.exe under Settings → Chat → Command execution.
Only a Git for Windows layout is accepted — …\Git\bin\bash.exe with git.exe
beside it. C:\Windows\System32\bash.exe is WSL's launcher, and it is on PATH
before anything else on a machine with WSL enabled: commands there would run in
the Linux VM against /mnt/c/... paths, which the read-only folder guard does
not translate. A machine with WSL and no Git for Windows falls back to cmd.exe.
Command Prompt fallback (no Git Bash, or you pick it in Settings):
cmd.exe /d /s /c "<command>"
/ddisables AutoRun (registry hooks that behave like a login profile).- Stem does not load PowerShell’s
profile.ps1for this path. - The command is wrapped in quotes and spawned with
windowsVerbatimArgumentsso inner"(e.g. PowerShell-Command "...") are not turned into\".
The safety tiers are the same as on macOS, but the cmd.exe parser is not zsh’s. That changes which commands can skip the safety check:
- Read-only probes auto-run:
dir,type,where,echo,cd,git statusand friends. The POSIX names (ls,cat,grep) are not on the cmd allowlist — under cmd they are not commands. 'is not a quote character to cmd, so anything containing one goes to the safety check rather than auto-running.cmdwould readtype 'a & whoami'as two commands, and Stem will not auto-run something it cannot bound.- Same for
%VAR%(it expands before cmd parses the line) and^(cmd’s escape character). Use double quotes when you want a literal argument. C:\…,\\server\share\…and%VAR%\…paths are checked against read-only connected folders, so a command naming one is blocked the same way as on macOS.
If you need PowerShell from the agent, ask it to run something like:
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Write-Output hi"A bare | is a cmd pipe: it splits the line before PowerShell sees it. Put
PowerShell pipelines inside -Command "...":
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Get-Process | Select-Object -First 1 Name"Or avoid pipes with (...) / property access when that is enough
(e.g. (Get-Command Get-Process).Name).
-
node -v≥ 24 andnpm -vwith portable Node on PATH. -
npm install→npm run preflight→npm run devopens Stem. -
Complete onboarding / chat with a provider.
-
Ask Stem to run
echo hello,ls, orgit status— expect a normal result (or an approval card), not a spawn/zsherror. Without Git Bash,diris the Command Prompt equivalent. -
Confirm a broken
profile.ps1did not fire for those default commands. -
Optional: have Stem run the
-NoProfilePowerShell one-liner above. -
Assisted mode: ask for
cat 'a & whoami'(Git Bash) ortype 'a & whoami & rem '(cmd). It must show an approval card, never run. -
Connect a folder read-only, then ask Stem to
cat/typea file inside it. Expect the read-only refusal, not the file. -
Check that
%APPDATA%\Stem\appears and survives a restart. -
Memory / search: if hybrid embeddings fail, the reason is in
%APPDATA%\Stem\stem.log(FTS-only fallback is safe but weaker). Three scopes cover it — grep for whichever the symptom points at:findstr /C:"[retrieval]" /C:"[embed-worker]" /C:"[embed-endpoint]" "%APPDATA%\Stem\stem.log"
[retrieval]— the model's own lifecycle:downloading,loading,readywith its dimension, orerrorwith the message the Memory tab shows. One line per transition, so a repeated failure appears once.[embed-worker]— the utility process:spawned, afork failed, an unexpected exit (with code and uptime), a purged corrupt weights cache. A model that never appears asspawnedwas never asked for; one that spawns and exits with noerrorstatus aborted natively (ONNX OOM and friends), and the reason went with the child's stderr.[embed-endpoint]— the named pipe serving query embeddings to thestem-recallMCP server. Failing here costssearch_past_chatsits semantic half and nothing else.
-
Settings → Chat → Command execution → Windows shell should already be Git Bash when
bash.exewas found. Ask Stem to runls. Switch to Command Prompt anddirif you want the cmd parser.