[PR #2136] feat(packaging): prepare a Windows portable runtime #5052

Open
opened 2026-10-31 01:01:06 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2136
Author: @Zhong-fan
Created: 10/12/2026
Status: 🔄 Open

Base: main ← Head: feat/1316-portable-windows


📝 Commits (10+)

  • 7a784c5 feat(packaging): prepare a Windows portable runtime
  • a90e1b3 fix(packaging): preserve path arguments and verify complete inventories
  • e580508 fix(ci): allow Wakaru downloads to recover from transient outages
  • 8e775c5 fix(test): select host package verifier and resolve Windows file URLs
  • 5dc4d97 chore: merge main and preserve Windows CI path handling
  • 44db48c fix(packaging): preserve percent signs in portable verification paths
  • 8bfd521 chore: merge main and retain platform verification documentation
  • 35ed015 fix(packaging): preserve delayed-expansion paths and optional providers
  • 3b90561 fix(packaging): honor npm platform selector semantics
  • cca7640 fix(packaging): merge main and verify portable doctor offline

📊 Changes

23 files changed (+1730 additions, -30 deletions)

View changed files

📝 .github/workflows/ci.yml (+25 -1)
📝 docs/installation.md (+6 -0)
➕ docs/portable-windows.md (+94 -0)
📝 knip.json (+2 -0)
📝 package.json (+2 -0)
📝 scripts/ci/plan.mjs (+5 -0)
📝 scripts/ci/scopes.mjs (+6 -0)
➕ scripts/lib/portable-command.d.mts (+16 -0)
➕ scripts/lib/portable-command.mjs (+84 -0)
➕ scripts/lib/portable-dependencies.d.mts (+16 -0)
➕ scripts/lib/portable-dependencies.mjs (+93 -0)
➕ scripts/lib/portable-inventory.d.mts (+19 -0)
➕ scripts/lib/portable-inventory.mjs (+166 -0)
➕ scripts/lib/portable-launcher.ps1 (+44 -0)
➕ scripts/lib/portable-node-bootstrap.mjs (+8 -0)
➕ scripts/package-portable-windows.mjs (+178 -0)
➕ scripts/verify-portable-windows.mjs (+371 -0)
📝 tests/boundary/cli/cutterCommands.test.ts (+15 -20)
📝 tests/boundary/filesystem/ciChangeScope.test.ts (+62 -0)
➕ tests/evaluation/package/portableDependencies.test.ts (+176 -0)

...and 3 more files

📄 Description

Summary

Refs #1316. Add an experimental Windows x64 portable directory containing REA, an official Node runtime, locked production dependencies, and the Windows native module. The prepared directory starts without npm or dependency downloads on the destination machine.

Problem and expected behavior

Archival and air-gapped installations need a complete, relocatable REA directory. Preparation uses the existing build toolchain; destination users can launch REA and configure a client with the bundled runtime offline.

Change and scope

  • Assemble the published application files, production dependencies, Node executable, and license notices into a new directory.
  • Provide PowerShell and Command Prompt launchers, including literal-path handling and live stdio MCP support.
  • Record a SHA-256 file inventory and verify exact contents with bounded reads before exercising the package.
  • Add portable preparation documentation, focused regressions, and Windows CI verification under PowerShell 5.1 and 7.

Contract and boundary impact

Use the existing CLI, MCP, setup, and analysis implementations. Setup writes the selected client's configuration and installs the skill using absolute bundled paths; rerun setup after relocation. External engines remain separately prepared prerequisites. No new analysis provider or target-execution capability is introduced.

Evidence and regression coverage

Cover dependency platform selection, missing dependencies, altered or unlisted artifact contents, bounded inventory traversal, and literal Windows paths and arguments. Artifact verification checks offline setup/doctor, repeated setup without additional writes, CLI/MCP static JavaScript analysis parity, source preservation, and uninstall in an isolated user directory. It removes system Node/npm from PATH and denies Node socket connections; this is not an OS-level network sandbox.

Validation performed

Current head: 5a2e3875. The prior 9d3cfecf validation below covers the unchanged portable implementation. Merged upstream 6f28b363 (REA 6.7.0), retaining both upstream and portable knip entrypoints and using upstream's existing runner-cancellation CI ownership entry. The final committed tree matches the tree checked below. A merge preview against subsequently advanced main 4a4bbab3 was clean; GitHub now reports the PR mergeable.

Windows, Node 24.18.0 / npm 11.16.0: seven focused files passed 351 tests with 6 platform skips, covering portable dependencies/inventory, batch paths, launcher timeout cleanup, Windows process ownership, the public runner, and CI routing. The JS/TS static tasks, architecture guards and discovery checks passed. docs:check passed, including all 5 README consistency tests.

The full check:ci command on Windows reached the Python phase but cannot import POSIX resource. The same Python suites ran unchanged under WSL: 41 bridge tests and 91 experiment tests passed. Their FIFO fixtures used Linux RAM-backed temporary storage because the E: WSL mount does not support FIFOs; sources, dependencies, logs and packaged outputs remained on E:.

A fresh 8,619-file 6.7.0 portable directory passed the actual verifier under Windows PowerShell 5.1 and PowerShell 7, including literal paths containing spaces, Unicode, &, %PATH%, and !NAME!. This covers inventory hashes, offline setup/doctor, repeated setup, CLI/MCP analysis parity, source preservation and uninstall. The matching Windows native artifact was built by upstream CI run 39715971038 at the exact included 6f28b363 source and passed the artifact verifier before use.

Actual packaged CLI help also passed through an existing SMB share with the same literal path markers. This is a targeted UNC batch-entry check, not a complete UNC portable-suite result. Optional external engines were not exercised by these portable checks.

Upstream run 39719522258 on 9d3cfecf caught a module-isolation violation: the portable inventory test mocked fs/promises inside the shared evaluation project. Move that test to the existing isolated process-global project and explicitly include it in Windows CI and package-lane routing. Before the move, the repository isolation regression failed locally with the same test path; afterward, all three focused files passed (301 tests, 2 platform skips), typecheck/lint passed, and discovery assigned all 1,968 files exactly once. These tests ran on Windows with junction creation permitted. No portable production code changed. That CI passed the isolation regression but shard 5 later aborted with JavaScript heap exhaustion while loading the Cutter CLI test; the portable report and required gate failed as consequences of that worker error.

Follow-up at 5a2e3875: use the existing Babel parser/types to inspect the JavaScript Cutter verifier, preserving the AST checks and public CLI assertions while removing the additional TypeScript compiler import. The CLI worker heap limit remains 384 MiB. Windows typecheck/lint and the normal pre-push gate passed. In a separate E:-backed Linux checkout with Node 24.18.0 and a fresh runtime build, three related CLI files produced 31 passed tests and one failed cancellation test: both original and patched versions failed to observe the child connections within 5 seconds on this local host. POSIX-sensitive fixtures used RAM-backed temporary storage. The verifier-output test passed in both versions; local single-file execution did not reproduce the CI OOM. The patched test reported 239 MiB heap at file completion, versus 280 MiB in the original focused run; these focused observations do not establish full-shard memory behavior. Current-commit CI is pending and must confirm the complete shard outcome. No production code or dependencies changed.

Compatibility, safety, and release

Windows x64 only. Ghidra, Java, Hopper, browsers, and other optional tools are not bundled or verified by this portable check. The inventory is not a signature. A failed preparation retains its partial output without a completion manifest. Offline updates require a separately prepared replacement directory; automatic release uploads are outside this PR.

Author readiness

Human owner: @Zhong-fan

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • Scope and documentation describe the portable-installation outcome.
  • Relevant regression coverage and package-lane routing are included.
  • Generated binaries and local verification reports are excluded from the diff.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/2136 **Author:** [@Zhong-fan](https://github.com/Zhong-fan) **Created:** 10/12/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/1316-portable-windows` --- ### 📝 Commits (10+) - [`7a784c5`](https://github.com/morluto/rea/commit/7a784c5d9f5c022be999736ec7dfcfc7a9043550) feat(packaging): prepare a Windows portable runtime - [`a90e1b3`](https://github.com/morluto/rea/commit/a90e1b3cbaf80541f91e0c595c323b7141d607ef) fix(packaging): preserve path arguments and verify complete inventories - [`e580508`](https://github.com/morluto/rea/commit/e58050836c9e56b6a5e3a475115167d8a46779b8) fix(ci): allow Wakaru downloads to recover from transient outages - [`8e775c5`](https://github.com/morluto/rea/commit/8e775c57ededbfe45f6f298a49819f8a658cf12c) fix(test): select host package verifier and resolve Windows file URLs - [`5dc4d97`](https://github.com/morluto/rea/commit/5dc4d979aaf88728e978ad597a0619ca9c8f4ef8) chore: merge main and preserve Windows CI path handling - [`44db48c`](https://github.com/morluto/rea/commit/44db48c0e87e7a6823fb041ddcfb663274404dd1) fix(packaging): preserve percent signs in portable verification paths - [`8bfd521`](https://github.com/morluto/rea/commit/8bfd521dd9923497c5beb3d295b44862124d2ef2) chore: merge main and retain platform verification documentation - [`35ed015`](https://github.com/morluto/rea/commit/35ed015d6ef1f03332056eb9df2f1edfd03de36a) fix(packaging): preserve delayed-expansion paths and optional providers - [`3b90561`](https://github.com/morluto/rea/commit/3b90561297f76fccf036e1272c5a9d91481f8069) fix(packaging): honor npm platform selector semantics - [`cca7640`](https://github.com/morluto/rea/commit/cca76401e5eb6b4c58c6068e8792ae45f34d7c32) fix(packaging): merge main and verify portable doctor offline ### 📊 Changes **23 files changed** (+1730 additions, -30 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/ci.yml` (+25 -1) 📝 `docs/installation.md` (+6 -0) ➕ `docs/portable-windows.md` (+94 -0) 📝 `knip.json` (+2 -0) 📝 `package.json` (+2 -0) 📝 `scripts/ci/plan.mjs` (+5 -0) 📝 `scripts/ci/scopes.mjs` (+6 -0) ➕ `scripts/lib/portable-command.d.mts` (+16 -0) ➕ `scripts/lib/portable-command.mjs` (+84 -0) ➕ `scripts/lib/portable-dependencies.d.mts` (+16 -0) ➕ `scripts/lib/portable-dependencies.mjs` (+93 -0) ➕ `scripts/lib/portable-inventory.d.mts` (+19 -0) ➕ `scripts/lib/portable-inventory.mjs` (+166 -0) ➕ `scripts/lib/portable-launcher.ps1` (+44 -0) ➕ `scripts/lib/portable-node-bootstrap.mjs` (+8 -0) ➕ `scripts/package-portable-windows.mjs` (+178 -0) ➕ `scripts/verify-portable-windows.mjs` (+371 -0) 📝 `tests/boundary/cli/cutterCommands.test.ts` (+15 -20) 📝 `tests/boundary/filesystem/ciChangeScope.test.ts` (+62 -0) ➕ `tests/evaluation/package/portableDependencies.test.ts` (+176 -0) _...and 3 more files_ </details> ### 📄 Description ## Summary Refs #1316. Add an experimental Windows x64 portable directory containing REA, an official Node runtime, locked production dependencies, and the Windows native module. The prepared directory starts without npm or dependency downloads on the destination machine. ## Problem and expected behavior Archival and air-gapped installations need a complete, relocatable REA directory. Preparation uses the existing build toolchain; destination users can launch REA and configure a client with the bundled runtime offline. ## Change and scope - Assemble the published application files, production dependencies, Node executable, and license notices into a new directory. - Provide PowerShell and Command Prompt launchers, including literal-path handling and live stdio MCP support. - Record a SHA-256 file inventory and verify exact contents with bounded reads before exercising the package. - Add portable preparation documentation, focused regressions, and Windows CI verification under PowerShell 5.1 and 7. ## Contract and boundary impact Use the existing CLI, MCP, setup, and analysis implementations. Setup writes the selected client's configuration and installs the skill using absolute bundled paths; rerun setup after relocation. External engines remain separately prepared prerequisites. No new analysis provider or target-execution capability is introduced. ## Evidence and regression coverage Cover dependency platform selection, missing dependencies, altered or unlisted artifact contents, bounded inventory traversal, and literal Windows paths and arguments. Artifact verification checks offline setup/doctor, repeated setup without additional writes, CLI/MCP static JavaScript analysis parity, source preservation, and uninstall in an isolated user directory. It removes system Node/npm from PATH and denies Node socket connections; this is not an OS-level network sandbox. ## Validation performed Current head: `5a2e3875`. The prior `9d3cfecf` validation below covers the unchanged portable implementation. Merged upstream `6f28b363` (REA 6.7.0), retaining both upstream and portable knip entrypoints and using upstream's existing runner-cancellation CI ownership entry. The final committed tree matches the tree checked below. A merge preview against subsequently advanced main `4a4bbab3` was clean; GitHub now reports the PR mergeable. Windows, Node 24.18.0 / npm 11.16.0: seven focused files passed 351 tests with 6 platform skips, covering portable dependencies/inventory, batch paths, launcher timeout cleanup, Windows process ownership, the public runner, and CI routing. The JS/TS static tasks, architecture guards and discovery checks passed. `docs:check` passed, including all 5 README consistency tests. The full `check:ci` command on Windows reached the Python phase but cannot import POSIX `resource`. The same Python suites ran unchanged under WSL: 41 bridge tests and 91 experiment tests passed. Their FIFO fixtures used Linux RAM-backed temporary storage because the E: WSL mount does not support FIFOs; sources, dependencies, logs and packaged outputs remained on E:. A fresh 8,619-file 6.7.0 portable directory passed the actual verifier under Windows PowerShell 5.1 and PowerShell 7, including literal paths containing spaces, Unicode, `&`, `%PATH%`, and `!NAME!`. This covers inventory hashes, offline setup/doctor, repeated setup, CLI/MCP analysis parity, source preservation and uninstall. The matching Windows native artifact was built by upstream CI run `39715971038` at the exact included `6f28b363` source and passed the artifact verifier before use. Actual packaged CLI help also passed through an existing SMB share with the same literal path markers. This is a targeted UNC batch-entry check, not a complete UNC portable-suite result. Optional external engines were not exercised by these portable checks. Upstream run `39719522258` on `9d3cfecf` caught a module-isolation violation: the portable inventory test mocked fs/promises inside the shared evaluation project. Move that test to the existing isolated process-global project and explicitly include it in Windows CI and package-lane routing. Before the move, the repository isolation regression failed locally with the same test path; afterward, all three focused files passed (301 tests, 2 platform skips), typecheck/lint passed, and discovery assigned all 1,968 files exactly once. These tests ran on Windows with junction creation permitted. No portable production code changed. That CI passed the isolation regression but shard 5 later aborted with JavaScript heap exhaustion while loading the Cutter CLI test; the portable report and required gate failed as consequences of that worker error. Follow-up at `5a2e3875`: use the existing Babel parser/types to inspect the JavaScript Cutter verifier, preserving the AST checks and public CLI assertions while removing the additional TypeScript compiler import. The CLI worker heap limit remains 384 MiB. Windows typecheck/lint and the normal pre-push gate passed. In a separate E:-backed Linux checkout with Node 24.18.0 and a fresh runtime build, three related CLI files produced 31 passed tests and one failed cancellation test: both original and patched versions failed to observe the child connections within 5 seconds on this local host. POSIX-sensitive fixtures used RAM-backed temporary storage. The verifier-output test passed in both versions; local single-file execution did not reproduce the CI OOM. The patched test reported 239 MiB heap at file completion, versus 280 MiB in the original focused run; these focused observations do not establish full-shard memory behavior. Current-commit CI is pending and must confirm the complete shard outcome. No production code or dependencies changed. ## Compatibility, safety, and release Windows x64 only. Ghidra, Java, Hopper, browsers, and other optional tools are not bundled or verified by this portable check. The inventory is not a signature. A failed preparation retains its partial output without a completion manifest. Offline updates require a separately prepared replacement directory; automatic release uploads are outside this PR. ## Author readiness Human owner: @Zhong-fan - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] Scope and documentation describe the portable-installation outcome. - [x] Relevant regression coverage and package-lane routing are included. - [x] Generated binaries and local verification reports are excluded from the diff. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5052
No description provided.