Make the repo work on Windows without WSL (and fix a <total_tokens> cache invalidation bug) - #152
Open
SiNaPsEr0x wants to merge 5 commits into
Open
Make the repo work on Windows without WSL (and fix a <total_tokens> cache invalidation bug)#152SiNaPsEr0x wants to merge 5 commits into
SiNaPsEr0x wants to merge 5 commits into
Conversation
Cloning on Windows with core.autocrlf=true rewrote every shell script with
CRLF, so bash refused to run them:
scripts/restart.sh: line 27: $'\r': command not found
Pin *.sh and *.bash to LF, let the rest use text=auto, and mark the binary
asset types so they are never converted. No tracked file is renormalized
here — the attributes take effect on the next checkout.
scripts/restart.sh only worked on macOS/Linux and broke on Windows: it relied on pgrep/lsof/kill and on `exec node`, which are unavailable or behave differently under Git Bash / PowerShell. - Rewrite it as scripts/restart.mjs, a plain Node ESM script with no external shell dependencies. - Process discovery: `ps` + pgrep-style matching on POSIX, and Get-CimInstance Win32_Process on Windows (its ConvertTo-Json output is normalized by hand, since PowerShell emits a bare object for a single match and nothing at all for none), matching the proxy by its actual command line so unrelated `node` processes are never touched. - Termination: SIGTERM then SIGKILL escalation on POSIX, taskkill /T then taskkill /T /F on Windows, both with the same 5s grace period as before. - Port ownership diagnostics use lsof on POSIX and Get-NetTCPConnection on Windows. - Port the shell test suite to tests/restart.test.ts (vitest), so it runs on every platform instead of requiring bash. - package.json: `restart` now runs `node scripts/restart.mjs`, and the `test:restart` entry is dropped because the ported suite is picked up by the regular vitest run.
NTFS has no POSIX mode bits: fs.statSync().mode reports 0o666 for every file and directory, and chmodSync() only toggles the read-only flag, so node-security.test.ts failed on Windows even though the hardening code in src/node.ts is correct and still runs there. Route the mode checks through an expectMode() helper that asserts the exact 0o600/0o700 bits only on platforms that can express them. The rest of each test — the request outcome, the file being created at all — keeps running everywhere.
`total_tokens` changes on every single turn, but it was listed in neither DYNAMIC_BLOCK_TAGS nor the known-static set, so it stayed in the static slab. That rewrote the cached image on each turn and reduced the prefix cache hit rate to zero for long sessions (it also showed up as a recurring "unknown static tag" churn warning at runtime). Add it to DYNAMIC_BLOCK_TAGS and add a cache-stability e2e case that fails if a changing token counter ever leaks back into the static slab.
The previous .gitattributes only pinned *.sh/*.bash to LF. With core.autocrlf=true a Windows clone still checked out bin/cli.js and scripts/*.mjs with CRLF, so the '#!/usr/bin/env node' line kept a trailing \r: Vite's shebang strip missed it and importing scripts/restart.mjs from a test failed with 'Invalid or unexpected token'. Pin *.js/*.mjs/*.cjs/*.py to LF too.
SiNaPsEr0x
force-pushed
the
fix/windows-cross-platform
branch
from
July 26, 2026 21:01
2ab90e5 to
c6189b1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the repo usable on Windows without WSL, and fixes one platform-independent
cache bug found along the way.
On a clean Windows clone,
pnpm run restartfailed immediately:Two separate causes: the repo had no
.gitattributes, so shell scripts werechecked out with CRLF; and
restart.shrelied onpgrep/kill/execplus aPOSIX-only PATH lookup.
Changes
.gitattributes(new) — normalizes line endings so checkouts are consistentacross platforms, and forces LF on files carrying a shebang so they stay
executable when cloned from Windows. Binary assets (
.png,.ico,.woff2, …)are marked explicitly to avoid corruption.
scripts/restart.sh→scripts/restart.mjs— reimplemented in Node, noshell dependency. Process discovery and termination now go through
platform-appropriate paths (
ps/killon POSIX,Get-CimInstance+Get-NetTCPConnectionon Windows), with the same graceful-then-forcefulshutdown sequence and the same port-holder diagnostics as before. Behaviour on
Linux/macOS is unchanged.
tests/restart.test.sh→tests/restart.test.ts— the restart suite nowruns under vitest on every platform instead of requiring bash. This also drops
the separate
test:restartscript, sincepnpm testcovers it.tests/node-security.test.ts— POSIX permission-bit assertions are skippedon Windows, where the filesystem has no equivalent concept. The assertions still
run everywhere else.
src/core/transform.ts—<total_tokens>added toDYNAMIC_BLOCK_TAGS.The cache bug (not Windows-specific)
<total_tokens>was being treated as static content. It changes on every singleturn, so it was landing in the static slab and rewriting the cached image each
turn — dropping the cache hit rate to zero for any conversation long enough to
reach the image path. It also surfaced as recurring
unknownStaticTagsnoise inthe logs, which is what led me to it.
This one is worth reviewing independently of the Windows work: it affects every
platform.
Testing
Full suite green on Windows: 923 tests across 51 files. The restart suite is
included in
pnpm testnow, so it runs in CI on all platforms rather than onlywhere bash is available.
I don't have a macOS or Linux box to verify on, so a second pair of eyes on the
POSIX branch of
restart.mjswould be welcome — the logic is a direct port, butit is the part I could not exercise myself.