fix(windows): make dev:desktop and the CLI bridge work on Windows - #38
Open
elextechnico-dotcom wants to merge 1 commit into
Open
Conversation
Two independent issues, both only surfacing on win32:
1. scripts/dev-desktop.mjs spawned "npm" and node_modules/.bin binaries
directly via execFileSync/spawn without shell:true. On Windows these are
.cmd shims, so Node's ENOENT lookup fails before anything runs. Also fixed
the teardown logic, which killed process GROUPS via a negative PID
(POSIX-only) — on win32 it now just kills the PID directly. Vite's port is
now passed explicitly (--port/--strictPort) rather than relying on the
config default, and the "is this port held by our own stale vite"
detection (previously lsof/ps) now has a PowerShell equivalent
(Get-NetTCPConnection / Get-CimInstance Win32_Process) for win32.
2. The CLI <-> app handshake over the named pipe never completed on Windows.
The client wrote the handshake and called sock.end() immediately
(half-close), which is how the Unix-socket version of this protocol
expects to signal "done sending" while leaving the socket open for the
server's reply. Windows named pipes don't support that: end() on one side
tears down the whole duplex pipe, so by the time the app's cli-server
tried to write its reply, the pipe was already gone (write EPIPE) and the
CLI's JSON.parse("") failed with "Unexpected end of JSON input" on every
single command (open, context, etc).
Fixed by switching the handshake to newline-delimited framing instead of
relying on a half-close to mark the end of the message: the client keeps
its socket open, writes `<json>\n`, and only closes after reading the
server's `<json>\n` reply. The server mirrors this (parses up to the first
newline instead of waiting for the 'end' event). Verified end-to-end on
Windows 11: `dapi open <dir>` and `dapi context` both round-trip correctly
now.
Tested via `npm run dev:desktop` from a clean clone on Windows 11 (Node 24).
|
@lequesilva is attempting to deploy a commit to the Diffusion Studio Team on Vercel. A member of the Team first needs to authorize it. |
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
Two independent Windows-only issues that block
npm run dev:desktopand thedapiCLI on win32:1.
scripts/dev-desktop.mjsspawns tools withoutshell: trueexecFileSync("npm", ...)andspawn(join(BIN, bin), ...)fail withENOENTon Windows becausenpm/binaries innode_modules/.binare.cmdshims there. Also fixed the teardown logic (process.kill(-child.pid, ...), POSIX process-group only) and added a PowerShell equivalent for the "is our own stale vite still holding the port" check (previouslylsof/ps).2. The CLI ↔ app handshake over the named pipe never completes on Windows
The client writes the handshake and calls
sock.end()immediately (half-close) to signal "done sending" while leaving the pipe open for the reply — this works on Unix domain sockets but Windows named pipes don't support that half-open semantics;end()tears down the whole duplex pipe. By the timecli-server.tstries to write its reply, the pipe is already gone (write EPIPE), and the CLI'sJSON.parse("")throwsUnexpected end of JSON inputon every command (dapi open,dapi context, etc.).Fixed by switching the handshake to newline-delimited framing: the client keeps its socket open, writes
<json>\n, and only closes after reading the server's<json>\nreply back. The server mirrors this (parses up to the first\ninstead of waiting for'end').Test plan
npm run dev:desktopfrom a clean clone on Windows 11 (Node 24) — builds CLI, starts Vite, builds+launches the desktop app.write EPIPEbefore, clean{"ok":true}after.dapi contextanddapi open <dir>verified round-tripping real JSON responses end-to-end after the fix.Not touched: macOS/Linux code paths are unchanged (all new branches are gated on
process.platform === "win32", and the handshake framing change applies to both platforms identically since newline-delimited framing is a strict superset of the old half-close approach).