mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-31 03:12:16 +00:00
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>
127 lines
4.0 KiB
Markdown
127 lines
4.0 KiB
Markdown
# 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:
|
||
|
||
```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:
|
||
|
||
```powershell
|
||
$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`:
|
||
|
||
```powershell
|
||
$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:
|
||
|
||
```powershell
|
||
# 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:
|
||
|
||
```powershell
|
||
cd "$env:LOCALAPPDATA\OpenJarvis\src"
|
||
git pull --ff-only
|
||
uv sync --extra server
|
||
```
|
||
|
||
Or re-run the installer with `-Force`:
|
||
|
||
```powershell
|
||
irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex
|
||
# (then re-run with the file directly, passing -Force)
|
||
```
|
||
|
||
## Uninstall
|
||
|
||
```powershell
|
||
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).
|