Skip to content

fix(plan): forward LOCALAPPDATA so Node's compile cache stays outside the workspace#389

Merged
branchseer merged 2 commits into
mainfrom
localappdata-env-passthrough
May 19, 2026
Merged

fix(plan): forward LOCALAPPDATA so Node's compile cache stays outside the workspace#389
branchseer merged 2 commits into
mainfrom
localappdata-env-passthrough

Conversation

@branchseer
Copy link
Copy Markdown
Member

@branchseer branchseer commented May 19, 2026

What's wrong

On Windows, any Node ≥ 22 task that uses the built-in compile cache (which Vite, esbuild's CJS loader, Storybook, and anything that touches node:module opts into) is currently uncacheable under vt run --cache. Node picks the cache directory from LOCALAPPDATA, but the planner doesn't forward that variable to cached tasks, so Node falls back to a workspace-relative path. The cache files end up next to the source, the runner sees the same paths both written and read in one run, and refuses to cache it with not cached because it modified its input.

What this PR does

Adds LOCALAPPDATA to the planner's default env-passthrough list. With LOCALAPPDATA populated, Node finds the real C:\Users\<user>\AppData\Local and the compile cache lands outside the workspace, where the runner ignores it — so cached runs work the way they're supposed to.

The PR has two commits to make the bug easy to see:

  1. First commit — Adds a small e2e fixture (node_compile_cache_outside_workspace) that runs a Node script with the compile cache turned on. On Linux and macOS the test passes. On Windows CI it fails with the exact "modified its input" symptom. (Windows-only failure run)

  2. Second commit — Adds LOCALAPPDATA to the planner's default list and mirrors it in the e2e harness (which clears env for snapshot determinism, so it has to be told which vars to forward). All platforms green. (Final green run)

Test plan

  • All e2e tests green on Linux and macOS
  • Windows CI green on the second commit
  • Windows CI red on the first commit alone, with the exact failure mode the fix addresses

Copy link
Copy Markdown
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9818095e25

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@branchseer branchseer force-pushed the localappdata-env-passthrough branch from 6f74c19 to 914d2e7 Compare May 19, 2026 08:08
@branchseer branchseer changed the title test(e2e): add node compile-cache fixture (fails on Windows) fix(plan): propagate Windows-essential envs to cached tasks May 19, 2026
branchseer and others added 2 commits May 19, 2026 16:18
A small Node script turns on Node's compile cache and imports a few
sibling modules so the cache directory gets some files. Two
`vt run --cache build` calls expect a cache miss followed by a cache
hit — that's how it should look when the cache lives outside the
workspace.

The test passes on Linux and macOS but is expected to fail on Windows
CI. The e2e harness clears the spawned process env for snapshot
determinism, so on Windows the task ends up without `LOCALAPPDATA`,
Node falls back to a workspace-relative cache path, and the runner
refuses to cache the run. The next commit makes both this fixture and
real-world Windows tasks pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… the workspace

`DEFAULT_UNTRACKED_ENV` already forwards most Windows env vars to
cached tasks, but `LOCALAPPDATA` was missing. Node's compile cache
uses it to decide where to put cache files on Windows. Without it,
the cache lands inside the workspace, the runner sees the same files
both written and read in one run, and refuses to cache anything with
`not cached because it modified its input`.

Add `LOCALAPPDATA` to the list, and mirror it in the e2e harness so
the previous commit's Node compile-cache fixture goes from failing on
Windows to passing on every platform.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@branchseer branchseer force-pushed the localappdata-env-passthrough branch from 914d2e7 to c96a35c Compare May 19, 2026 08:19
@branchseer branchseer changed the title fix(plan): propagate Windows-essential envs to cached tasks fix(plan): forward LOCALAPPDATA so Node's compile cache stays outside the workspace May 19, 2026
@branchseer branchseer merged commit 165ca76 into main May 19, 2026
13 checks passed
@branchseer branchseer deleted the localappdata-env-passthrough branch May 19, 2026 08:31
fengmk2 added a commit to voidzero-dev/vite-plus that referenced this pull request May 19, 2026
Release vite-plus v0.1.22: Security Patch, Parallel Global Install & Scaffold Polish

A critical Vitest browser-mode security fix, parallel `vp add -g`
installs, a built-in oxlint rule to prefer `vite-plus` imports, and a
new `--git` switch for `vp create`.

### Highlights

- **Security**: bundled `vitest` bumped to `4.1.6` to address
[GHSA-2h32-95rg-cppp](GHSA-2h32-95rg-cppp)
(Critical, CVSS 9.6), an XSS to RCE chain via the `otelCarrier` query
parameter in Vitest browser mode
([#1633](#1633))
- **Parallel global install**: `vp add/install/update -g` now installs
packages concurrently with a progress bar and a `--concurrency` flag
(default 5)
([#1597](#1597))
- **Prefer vite-plus imports**: new bundled oxlint rule rewrites
`vite`/`vitest` imports to `vite-plus`, enabled by default in generated
and migrated `lint` configs
([#1408](#1408))
- **Git init on scaffold**: `vp create` learns `--git`/`--no-git`
(interactive prompt; auto-commits "Initial commit from Vite+")
([#1484](#1484))

### Features

- Spawn npm for global installation in parallel with a progress bar and
a `--concurrency` option
([#1597](#1597)), by
@liangmiQwQ
- Add bundled oxlint rule to prefer `vite-plus` imports over
`vite`/`vitest`
([#1408](#1408)), by
@Han5991
- `vp create`: initialize a git repository and create an initial commit
on scaffold
([#1484](#1484)), by
@ryohidaka
- `vp create`: rename underscore-prefixed files (`_gitignore`, `_npmrc`,
`_yarnrc.yml`) to dotfiles for `@org/create` bundled templates
([#1574](#1574)), by
@jong-kyung
- Add `VP_PR_VERSION` env var to install unreleased PR builds via
pkg.pr.new
([#1578](#1578)), by
@fengmk2

### Fixes & Enhancements

- Skip merging standalone `.oxfmtrc`/`.oxlintrc` config when the
`fmt:`/`lint:` key is already declared in `vite.config.ts` (fixes
duplicate-block regression in `vp create fate`)
([#1601](#1601)), by
@fengmk2
- Suppress the `VITE+ - The Unified Toolchain for the Web` banner for
`vp lint --lsp`, `vp fmt --lsp`, and `vp fmt --stdin-filepath` so stdout
stays a pure LSP / formatter stream
([#1619](#1619)), by
@fengmk2
- `vp create`: detect output directory when running in the current
directory
([#1606](#1606)), by
@jong-kyung
- `vp update -g`: skip installs when the recorded global package version
already matches the npm-resolved version, and tolerate string/array
outputs from `npm view ... version --json`
([#1596](#1596)), by
@leno23
- `vp create`: preserve single-segment project path in
`updateWorkspaceConfig`
([#1582](#1582)), by
@jong-kyung
- `vp env use`: keep the change session-scoped on Windows
([#1577](#1577)), by
@fengmk2
- `vp rebuild`: accept positional package names
([#1564](#1564)), by
@fengmk2
- Adopt the new vite-task error formatter; errors now print as `error:
<top-level>` plus `* <source>` chain lines, with bold-red highlight on a
TTY
([vite-task#390](voidzero-dev/vite-task#390)),
by @branchseer
- vite-task: forward `LOCALAPPDATA` so Node's compile cache stays
outside the workspace on Windows
([vite-task#389](voidzero-dev/vite-task#389)),
by @branchseer
- Bump vite-task to `c945cc0`
([#1628](#1628)), by
@branchseer

### Refactor

- Revert `vp pm plugin` command (per discussion in #1038)
([#1623](#1623)), by
@jong-kyung

### Docs

- Add `vitepress-plugin-llms` to the docs site so the published docs
include LLM-friendly outputs (`/llms.txt`)
([#1625](#1625)), by
@jong-kyung
- Refresh home stats for oxlint, vite, and vitest
([#1512](#1512)), by
@nozomee
- Mention `vp env doctor` in agent instructions
([#1603](#1603)), by
@leno23

### Chore

- Consolidate the upstream build chain into a single `pnpm build` script
(justfile recipe now just calls `pnpm build`)
([#1626](#1626)), by
@fengmk2
- Fix bootstrap-cli on Windows
([#1583](#1583)), by
@fengmk2
- Refresh trusted stack stats
([#1573](#1573),
[#1616](#1616)), by
@voidzero-guard[bot]
- Update GitHub Actions
([#1611](#1611),
[#1612](#1612)), by
@renovate[bot]
- Address zizmor findings in composite actions and the release workflow;
drop unused `actions-cool/issues-helper`
([#1630](#1630)), by
@Boshen
- Switch plain checkouts to `taiki-e/checkout-action`
([#1620](#1620)), by
@Boshen
- Switch release to a version-bump PR + push trigger flow
([#1575](#1575)), by
@Boshen
- Gate release publish on environment approval with a Discord notice
([#1571](#1571)), by
@Boshen
- Enable `cargo clippy` with `-D warnings`
([#1579](#1579)), by
@Boshen
- Drop unused `setup-node` from the version-check job
([#1600](#1600)), by
@fengmk2
- Add Void deploy workflows for the docs site
([#1590](#1590)), by
@fengmk2
- Add `--help` case to config snap tests for npm10/yarn1/yarn4
([#1585](#1585)), by
@jong-kyung
- Add `--help` case to publish snap tests for npm10/yarn1/yarn4
([#1584](#1584)), by
@jong-kyung
- Verify `.gitignore` and `.yarnrc.yml` in the new-vite-monorepo snap
([#1576](#1576)), by
@jong-kyung
- vite-task: bump pnpm to `11.1.2`
([vite-task#383](voidzero-dev/vite-task#383)),
by @branchseer
- vite-task: update lint-staged to v17
([vite-task#385](voidzero-dev/vite-task#385)),
by @renovate[bot]

### Bundled Versions

| Tool | Version | Source |
| --- | --- | --- |
| vite | `8.0.11` |
[`66f3194`](vitejs/vite@66f3194)
|
| rolldown | `1.0.0` |
[`ac5c710`](rolldown/rolldown@ac5c710)
|
| tsdown | `0.22.0` | [npm](https://npmx.dev/package/tsdown/v/0.22.0) |
| vitest | `4.1.6` | [npm](https://npmx.dev/package/vitest/v/4.1.6) |
| oxlint | `1.63.0` | [npm](https://npmx.dev/package/oxlint/v/1.63.0) |
| oxlint-tsgolint | `0.22.1` |
[npm](https://npmx.dev/package/oxlint-tsgolint/v/0.22.1) |
| oxfmt | `0.48.0` | [npm](https://npmx.dev/package/oxfmt/v/0.48.0) |

### New Contributors

Welcome to all new contributors! 🎉

@nozomee, @ryohidaka, @leno23

**Full Changelog**:
v0.1.21...v0.1.22

---

Merging this PR will trigger the release workflow.

---------

Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com>
Co-authored-by: MK <fengmk2@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant