Skip to content

Commit e98de58

Browse files
committed
Windows platform support:
- Justfile: [windows] recipes for build-hyperlight, resolve-hyperlight-dir, start-debug - Justfile: runtime-cflags forward-slash fix for clang cross-compilation - build-binary.js: .cmd launcher, platform-aware post-build output - plugins: O_NOFOLLOW fallback (Windows lacks O_NOFOLLOW, relies on lstat pre-check) - agent/index.ts: pathToFileURL for ESM plugin imports on Windows - build.rs: forward-slash CFLAGS for clang on Windows - code-validator/guest: win32-x64-msvc NAPI target - .gitattributes: enforce LF line endings across platforms VM resource management: - sandbox/tool.js: invalidateSandbox() now calls dispose() on LoadedJSSandbox and JSSandbox for deterministic VM cleanup instead of relying on V8 GC - Updated hyperlight-js dep to include dispose() API Error handling: - agent/event-handler.ts: suppress duplicate 'Tool execution failed' messages - sandbox/tool.js: MMIO error detection in compilation and runtime paths - agent/index.ts: surrogate pool env vars (HYPERLIGHT_INITIAL/MAX_SURROGATES) Test fixes (Windows compatibility): - tests: symlink EPERM skip for Windows (path-jail, fs-read, fs-write) - tests/dts-sync: rmSync instead of shell rm -rf - tests/pattern-loader: unique tmpdir per test to avoid Windows EBUSY locks CI: - pr-validate.yml: Windows WHP matrix - publish.yml: Windows build support Security: - npm audit fix across all workspaces (picomatch, brace-expansion) - plugin-system/manager.ts: simplified ternary Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
1 parent 1e0e754 commit e98de58

33 files changed

+542
-214
lines changed

.gitattributes

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Force LF line endings everywhere — no platform-specific CRLF nonsense.
2+
# This ensures consistent diffs across Linux, macOS, and Windows.
3+
* text=auto eol=lf
4+
5+
# Explicitly mark binary files so git doesn't try to normalize them
6+
*.node binary
7+
*.wasm binary
8+
*.png binary
9+
*.jpg binary
10+
*.jpeg binary
11+
*.gif binary
12+
*.ico binary
13+
*.pptx binary
14+
*.xlsx binary
15+
*.docx binary
16+
*.zip binary
17+
*.tar binary
18+
*.gz binary
19+
*.tgz binary
20+
*.exe binary
21+
*.dll binary
22+
*.so binary
23+
*.dylib binary

.github/workflows/pr-validate.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,8 @@ jobs:
8383
run: just test-all
8484

8585
# Build and test on all hypervisor configurations (1ES runners have Rust + just)
86-
# NOTE: Windows WHP support is temporarily disabled pending upstream
87-
# hyperlight fix for multiple SurrogateProcessManager instances.
88-
# See: https://github.com/hyperlight-dev/hyperagent/issues/1
8986
build-and-test:
90-
name: Build & Test (${{ matrix.hypervisor }}-${{ matrix.config }})
87+
name: Build & Test (${{ matrix.build }})
9188
needs: [docs-pr]
9289
if: needs.docs-pr.outputs.docs-only != 'true'
9390
strategy:
@@ -98,6 +95,8 @@ jobs:
9895
- linux-kvm-release
9996
- linux-mshv-debug
10097
- linux-mshv-release
98+
- windows-whp-debug
99+
- windows-whp-release
101100
include:
102101
- build: linux-kvm-debug
103102
os: [self-hosted, Linux, X64, "1ES.Pool=hld-kvm-amd"]
@@ -115,6 +114,14 @@ jobs:
115114
os: [self-hosted, Linux, X64, "1ES.Pool=hld-azlinux3-mshv-amd"]
116115
hypervisor: mshv
117116
config: release
117+
- build: windows-whp-debug
118+
os: [self-hosted, Windows, X64, "1ES.Pool=hld-win2022-amd"]
119+
hypervisor: whp
120+
config: debug
121+
- build: windows-whp-release
122+
os: [self-hosted, Windows, X64, "1ES.Pool=hld-win2022-amd"]
123+
hypervisor: whp
124+
config: release
118125
runs-on: ${{ matrix.os }}
119126
steps:
120127
- uses: actions/checkout@v6
@@ -142,7 +149,7 @@ jobs:
142149
if: matrix.config == 'release'
143150
uses: actions/upload-artifact@v7
144151
with:
145-
name: hyperagent-linux-x64-${{ matrix.hypervisor }}
152+
name: hyperagent-${{ matrix.build }}
146153
path: dist/
147154
retention-days: 7
148155

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
# Test on all hypervisor configurations before publishing
2525
# NOTE: Windows WHP temporarily disabled (see pr-validate.yml)
2626
test:
27-
name: Test (${{ matrix.hypervisor }})
27+
name: Test (${{ matrix.build }})
2828
strategy:
2929
fail-fast: true
3030
matrix:

Justfile

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ runtime-dir := justfile_dir() / "src" / "sandbox" / "runtime"
3737
# -D__wasi__=1 to disable pthreads. Uses cargo metadata to find the
3838
# include/ dir from the hyperlight-js-runtime dependency.
3939
# Fails loudly if resolution fails — empty CFLAGS causes cryptic build errors.
40-
runtime-cflags := `node -e "var m=JSON.parse(require('child_process').execSync('cargo +1.89 metadata --format-version 1 --manifest-path src/sandbox/runtime/Cargo.toml',{encoding:'utf8',stdio:['pipe','pipe','inherit'],maxBuffer:20*1024*1024}));var p=m.packages.find(function(p){return p.name==='hyperlight-js-runtime'});if(!p){process.stderr.write('ERROR: hyperlight-js-runtime not found in cargo metadata\n');process.exit(1)}console.log('-I'+require('path').join(require('path').dirname(p.manifest_path),'include')+' -D__wasi__=1')"`
40+
runtime-cflags := `node -e "var m=JSON.parse(require('child_process').execSync('cargo +1.89 metadata --format-version 1 --manifest-path src/sandbox/runtime/Cargo.toml',{encoding:'utf8',stdio:['pipe','pipe','inherit'],maxBuffer:20*1024*1024}));var p=m.packages.find(function(p){return p.name==='hyperlight-js-runtime'});if(!p){process.stderr.write('ERROR: hyperlight-js-runtime not found in cargo metadata\n');process.exit(1)}var inc=require('path').join(require('path').dirname(p.manifest_path),'include').split(require('path').sep).join('/');console.log('-I'+inc+' -D__wasi__=1')"`
4141

4242
# Export HYPERLIGHT_CFLAGS so cargo-hyperlight picks them up when building runtimes
4343
export HYPERLIGHT_CFLAGS := runtime-cflags
@@ -71,6 +71,12 @@ resolve-hyperlight-dir:
7171
fi
7272
echo "$dir"
7373

74+
# Resolve hyperlight-js workspace root (Windows variant).
75+
[private]
76+
[windows]
77+
resolve-hyperlight-dir:
78+
node -e "var m=JSON.parse(require('child_process').execSync('cargo +1.89 metadata --format-version 1 --manifest-path src/sandbox/runtime/Cargo.toml',{encoding:'utf8',stdio:['pipe','pipe','pipe'],maxBuffer:20*1024*1024}));var p=m.packages.find(function(p){return p.name==='hyperlight-js-runtime'});if(p)console.log(require('path').resolve(require('path').dirname(p.manifest_path),'..','..'));else{process.stderr.write('hyperlight-js-runtime not found');process.exit(1)}"
79+
7480
# Install required Rust toolchains and cargo subcommands.
7581
# Cross-platform (Linux/macOS/Windows) — no bash required.
7682
[private]
@@ -84,8 +90,7 @@ ensure-tools:
8490
# 2. Discovers the hyperlight-js workspace from Cargo's checkout
8591
# 3. Builds the NAPI addon with our custom runtime embedded
8692
# 4. Symlinks deps/js-host-api → checkout/src/js-host-api for npm file: dep
87-
# NOTE: [unix] only — Windows support is disabled pending upstream fix (issue #1).
88-
# When Windows lands, add [windows] variants using mklink /J for junctions.
93+
# NOTE: [unix] only — add [windows] variant below for Windows WHP support.
8994
[private]
9095
[unix]
9196
build-hyperlight target="debug": (build-runtime-release)
@@ -101,6 +106,13 @@ build-hyperlight target="debug": (build-runtime-release)
101106
ln -sfn "${hl_dir}/src/js-host-api" "{{hyperlight-link}}"
102107
echo "🔗 deps/js-host-api → ${hl_dir}/src/js-host-api"
103108

109+
# Build hyperlight-js NAPI addon (Windows variant — PowerShell + junction link).
110+
# All statements on one line because just runs each line as a separate pwsh -Command.
111+
[private]
112+
[windows]
113+
build-hyperlight target="debug": (build-runtime-release)
114+
$hl_dir = just resolve-hyperlight-dir; Push-Location (Join-Path $hl_dir "src" "hyperlight-js"); cargo clean -p hyperlight-js 2>$null; Pop-Location; Push-Location $hl_dir; just build {{ if target == "debug" { "" } else { target } }}; Pop-Location; $linkPath = [IO.Path]::GetFullPath("{{hyperlight-link}}"); $targetPath = Join-Path $hl_dir "src" "js-host-api"; New-Item -ItemType Directory -Path (Split-Path $linkPath) -Force | Out-Null; if (Test-Path $linkPath) { cmd /c rmdir /q $linkPath 2>$null }; cmd /c mklink /J $linkPath $targetPath; Write-Output "🔗 deps/js-host-api → $targetPath"
115+
104116
# Build the hyperlight-analysis-guest NAPI addon (debug)
105117
[private]
106118
build-analysis-guest:
@@ -165,9 +177,15 @@ start *ARGS: install
165177
npx tsx src/agent/index.ts {{ARGS}}
166178

167179
# Run with crash diagnostics (generates crash report .json files on SIGSEGV)
180+
[unix]
168181
start-debug *ARGS: install
169182
NODE_OPTIONS="--report-on-signal --report-on-fatalerror --report-directory=$HOME/.hyperagent/logs" npx tsx src/agent/index.ts {{ARGS}}
170183

184+
# Run with crash diagnostics (Windows variant)
185+
[windows]
186+
start-debug *ARGS: install
187+
$env:NODE_OPTIONS="--report-on-signal --report-on-fatalerror --report-directory=$env:USERPROFILE/.hyperagent/logs"; npx tsx src/agent/index.ts {{ARGS}}
188+
171189
# Run the agent with release-built native addon (faster sandbox execution)
172190
start-release *ARGS: install-release
173191
npx tsx src/agent/index.ts {{ARGS}}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ Ask the agent to compute things, and it writes & runs JavaScript in a hardware-i
1010

1111
### Prerequisites
1212

13-
- **Linux with KVM**, **Azure Linux with MSHV**, or **WSL2 with KVM** (hardware virtualization required)
13+
- **Linux with KVM**, **Azure Linux with MSHV**, **Windows with WHP**, or **WSL2 with KVM** (hardware virtualization required)
1414
- **GitHub authentication** (see [below](#github-authentication))
1515
- **Docker** (for containerized option)
1616
- **Node.js 22+** (for npm install / source builds only)
1717
- **Rust + just** (for source builds only — see [Contributing](#contributing))
1818

19-
**NOTE:** HyperAgent does not currently run on macOS [due to this issue](https://github.com/hyperlight-dev/hyperlight/issues/45). Native Windows support (WHP) is planned — for now, use [WSL2 with KVM](https://learn.microsoft.com/en-us/windows/wsl/install) on Windows.
19+
**NOTE:** HyperAgent does not currently run on macOS [due to this issue](https://github.com/hyperlight-dev/hyperlight/issues/45).
2020

2121
### GitHub Authentication
2222

builtin-modules/ooxml-core.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"description": "Shared OOXML infrastructure - units, colors, themes, Content_Types, relationships",
44
"author": "system",
55
"mutable": false,
6-
"sourceHash": "sha256:00cfaa1e652856b2",
7-
"dtsHash": "sha256:6aac85502082bf89",
6+
"sourceHash": "sha256:1e939013c13555bc",
7+
"dtsHash": "sha256:9f88e7c59a56854c",
88
"importStyle": "named",
99
"hints": {
1010
"overview": "Low-level OOXML infrastructure. Most users should use ha:pptx instead.",

builtin-modules/pptx-charts.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"description": "OOXML DrawingML chart generation - bar, pie, line charts for PPTX presentations",
44
"author": "system",
55
"mutable": false,
6-
"sourceHash": "sha256:27d40e5c5095ec38",
7-
"dtsHash": "sha256:4353b8263dc99405",
6+
"sourceHash": "sha256:5c521ce93ff39626",
7+
"dtsHash": "sha256:5f653830226c3554",
88
"importStyle": "named",
99
"hints": {
1010
"overview": "Chart generation for PPTX. Always used with ha:pptx.",

builtin-modules/pptx-tables.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"description": "Styled tables for PPTX presentations - headers, borders, alternating rows",
44
"author": "system",
55
"mutable": false,
6-
"sourceHash": "sha256:5940fb396a67f801",
7-
"dtsHash": "sha256:3ba75bbc44353467",
6+
"sourceHash": "sha256:0739a7db5a8ab428",
7+
"dtsHash": "sha256:82d903ffbf4dfb1e",
88
"importStyle": "named",
99
"hints": {
1010
"overview": "Table generation for PPTX. Always used with ha:pptx.",

builtin-modules/pptx.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"description": "PowerPoint PPTX presentation builder - slides, text, shapes, themes, layouts",
44
"author": "system",
55
"mutable": false,
6-
"sourceHash": "sha256:895d7188d5ba8b46",
7-
"dtsHash": "sha256:27520514e4401465",
6+
"sourceHash": "sha256:093b19522e994756",
7+
"dtsHash": "sha256:2107e369816b4bd5",
88
"importStyle": "named",
99
"hints": {
1010
"overview": "Core PPTX slide building. Charts in ha:pptx-charts, tables in ha:pptx-tables.",

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)