Skip to content

fix(windows): make dev:desktop and the CLI bridge work on Windows - #38

Open
elextechnico-dotcom wants to merge 1 commit into
diffusionstudio:mainfrom
elextechnico-dotcom:fix/windows-cli-bridge-and-dev-desktop
Open

fix(windows): make dev:desktop and the CLI bridge work on Windows#38
elextechnico-dotcom wants to merge 1 commit into
diffusionstudio:mainfrom
elextechnico-dotcom:fix/windows-cli-bridge-and-dev-desktop

Conversation

@elextechnico-dotcom

Copy link
Copy Markdown

Summary

Two independent Windows-only issues that block npm run dev:desktop and the dapi CLI on win32:

1. scripts/dev-desktop.mjs spawns tools without shell: true
execFileSync("npm", ...) and spawn(join(BIN, bin), ...) fail with ENOENT on Windows because npm/binaries in node_modules/.bin are .cmd shims 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 (previously lsof/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 time cli-server.ts tries to write its reply, the pipe is already gone (write EPIPE), and the CLI's JSON.parse("") throws Unexpected end of JSON input on 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>\n reply back. The server mirrors this (parses up to the first \n instead of waiting for 'end').

Test plan

  • npm run dev:desktop from a clean clone on Windows 11 (Node 24) — builds CLI, starts Vite, builds+launches the desktop app.
  • Isolated the named-pipe handshake with a standalone Node script before/after the fix — confirmed write EPIPE before, clean {"ok":true} after.
  • dapi context and dapi 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).

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).
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

@lequesilva is attempting to deploy a commit to the Diffusion Studio Team on Vercel.

A member of the Team first needs to authorize it.

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.

2 participants