Files
OpenJarvis/deploy/windows/README.md
T
a79cd6f5e9 feat(windows): Phase-1 native install + scheduled-task service (#438)
Closes Phase-1 of #298 (Native Windows Support RFC).

Reverses the long-standing "native Windows is not supported" stance. PowerShell installer at `deploy/windows/install.ps1` (published to https://open-jarvis.github.io/OpenJarvis/install.ps1) plus a `jarvis-service.ps1` scheduled-task helper that mirrors `deploy/systemd/openjarvis.service` and `deploy/launchd/com.openjarvis.plist`. Loopback default (127.0.0.1, no API key) — same as launchd.

One-liner install:
    irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex

Adversarial review caught and fixed two real bugs pre-commit:
1. `irm | iex` drops `param()` flags — added env-var fallbacks (OPENJARVIS_SKIP_SERVICE / OPENJARVIS_SERVICE / OPENJARVIS_FORCE).
2. Scheduled tasks don't inherit the registering session's env — the LAN-exposed `OPENJARVIS_API_KEY` path now persists the key to User scope so the task's logon environment can read it.

Supersedes #434 (the guidance-only "use WSL2" install.ps1).

Massive thanks to @SeCuReDmE-main-dev for the careful RFC #298 — the three-phase decomposition (install / service / shared-memory bridge) is exactly the right framing. This PR ships Phase-1 and Phase-2 of the RFC fused into one release; Phase-3 (shared memory bridge) remains future work.

Thanks also to @KadenBordeaux for raising #334 ("'bash' is not recognized as the name of a cmdlet"). That report is what made this whole Windows-support cluster a priority — without your bug report the unsupported stance would still be in the README. The friction you hit motivated #432 (numpy/python cap), #433 (CLI startup resilience), #436 (python discovery helpers), #437 (desktop launcher fix), and this PR.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 16:44:10 -07:00

4.0 KiB
Raw Blame History

OpenJarvis on native Windows

Phase-1 of the native-Windows-support RFC (#298). Mirrors the Linux (deploy/systemd/) and macOS (deploy/launchd/) deployments — but for PowerShell, without WSL2 or Docker.

One-liner install

In an elevated-or-regular PowerShell:

irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex

What it does:

  1. Refuses non-Windows hosts and Windows < 10 1809.
  2. Checks Python 3.10 3.13 (3.14 has no numpy wheels yet — see #432).
  3. Checks git on PATH.
  4. Installs uv (https://astral.sh/uv) if absent.
  5. Clones the OpenJarvis repository to %LOCALAPPDATA%\OpenJarvis (override with $env:OPENJARVIS_HOME).
  6. Runs uv sync --extra server so the FastAPI server entry point is importable.
  7. Optionally prompts to register a scheduled task that auto-starts the server at logon.

Flags (when invoked directly rather than via irm | iex):

Flag Effect
-Service Register the scheduled task without prompting
-SkipService Don't prompt; don't register
-Force Re-run all steps even if already done

irm | iex can't pass param() args into a piped script string, so the same knobs are honored via env vars when the corresponding flag is absent:

$env:OPENJARVIS_SKIP_SERVICE = '1'
irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex

The available env vars: OPENJARVIS_SKIP_SERVICE, OPENJARVIS_SERVICE, OPENJARVIS_FORCE. If you need richer control, save the script first (irm ... -OutFile install.ps1; .\install.ps1 -Force).

Manual scheduled-task setup

If you skipped the prompt during install, you can register / inspect / remove the task with jarvis-service.ps1:

$srv = "$env:LOCALAPPDATA\OpenJarvis\src\deploy\windows\jarvis-service.ps1"

# install (idempotent — replaces existing)
powershell -ExecutionPolicy Bypass -File $srv install

# status
powershell -ExecutionPolicy Bypass -File $srv status

# remove
powershell -ExecutionPolicy Bypass -File $srv uninstall

The task runs as the current user with LogonType=Interactive and RunLevel=Limited. It restarts up to 3 times on failure (1-minute gap), has no execution-time limit, and starts when available (catches up if missed).

Loopback vs LAN-exposed

By default the scheduled task binds 127.0.0.1 — reachable only from this machine, no API key required. This matches launchd parity (see deploy/launchd/com.openjarvis.plist).

To expose on your LAN:

# 1. Generate an API key. The server REFUSES to bind 0.0.0.0 without one.
$env:OPENJARVIS_API_KEY = (uv run jarvis auth generate-key)

# 2. Re-register the task with -ListenHost 0.0.0.0.
powershell -ExecutionPolicy Bypass -File $srv install -ListenHost 0.0.0.0

jarvis-service.ps1 install refuses -ListenHost 0.0.0.0 if $env:OPENJARVIS_API_KEY is unset — same guard as the systemd unit's EnvironmentFile=/etc/openjarvis/env.

Parity table

Concern systemd launchd Windows
Service definition deploy/systemd/openjarvis.service deploy/launchd/com.openjarvis.plist deploy/windows/jarvis-service.ps1 (cmdlet-driven)
Default bind 0.0.0.0 (with API key) 127.0.0.1 (no API key) 127.0.0.1 (no API key)
Restart on failure Restart=on-failure RestartSec=5 KeepAlive=true RestartCount=3 RestartInterval=PT1M
Auto-start multi-user.target RunAtLoad=true AtLogOn trigger

Updating

To pull the latest:

cd "$env:LOCALAPPDATA\OpenJarvis\src"
git pull --ff-only
uv sync --extra server

Or re-run the installer with -Force:

irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex
# (then re-run with the file directly, passing -Force)

Uninstall

powershell -ExecutionPolicy Bypass -File "$env:LOCALAPPDATA\OpenJarvis\src\deploy\windows\jarvis-service.ps1" uninstall
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\OpenJarvis"

Uninstalling does NOT remove uv (it's a separate tool — you may have other Python projects using it).