Description
On Windows, npm installs language servers (typescript-language-server, pyright, vscode-*-language-server) as .cmd shims. Nanocoder finds them with where (which understands .cmd) and reports them as available. But it then checks and starts them with execFileSync and spawn without a shell, and those cannot run a .cmd file. So no server starts and LSP features stay off. Only servers that ship as real .exe files (like gopls, rust-analyzer, clangd) should work.
Environment
- OS: Windows 11 (10.0.26300)
- Node version: 22.22.3
- Nanocoder version: 1.31.0 (main at 6eaff7a)
- typescript-language-server: 6.0.2, installed with
npm install typescript-language-server typescript
- Provider / Model: not relevant
Steps to Reproduce
- On Windows, run
npm install typescript-language-server typescript and put node_modules\.bin on PATH.
- Make a project with
tsconfig.json and a.ts.
- In that folder, call
getKnownServersStatus() and discoverLanguageServers() from source/lsp/server-discovery.ts.
- Compare with
cmd /c typescript-language-server --version and with spawn('typescript-language-server', ['--stdio']).
Expected Behavior
The server is discovered and started, like it is on Linux and macOS.
Actual Behavior
where typescript-language-server -> node_modules/.bin/typescript-language-server | .../typescript-language-server.cmd
cmd /c typescript-language-server --version -> 6.0.2 (Windows can run it)
execFileSync('typescript-language-server', ...) -> FAILS: ENOENT
getKnownServersStatus() ... {"name":"typescript-language-server","available":true}
discoverLanguageServers() []
spawn('typescript-language-server', ['--stdio']) -> error event: ENOENT
Suggested Fix
source/lsp/server-discovery.ts: findCommand (about lines 249-266) uses where, so it succeeds. verifyServer (about lines 274-290, execFileSync) and verifyLSPServerWithCommunication (about line 302, spawn) cannot run the shim. source/lsp/lsp-client.ts:69 has the same spawn.
- Use
cross-spawn for all three. I checked that cross-spawn.sync('typescript-language-server', ['--version']) returns 6.0.2 here. Note that cross-spawn is only a transitive dependency today and is not imported anywhere in the repo, so add it to package.json (and keep knip happy).
- Or resolve
<name>.cmd and run it through cmd.exe /d /s /c on win32. The node_modules/.bin fallback in findCommand finds the extensionless POSIX shim, which also can't be spawned on Windows.
- Add a Windows-only test: put a fake
typescript-language-server.cmd on PATH and expect discoverLanguageServers() to return it. That exact test fails today.
Additional Context
Description
On Windows, npm installs language servers (
typescript-language-server,pyright,vscode-*-language-server) as.cmdshims. Nanocoder finds them withwhere(which understands.cmd) and reports them as available. But it then checks and starts them withexecFileSyncandspawnwithout a shell, and those cannot run a.cmdfile. So no server starts and LSP features stay off. Only servers that ship as real.exefiles (likegopls,rust-analyzer,clangd) should work.Environment
npm install typescript-language-server typescriptSteps to Reproduce
npm install typescript-language-server typescriptand putnode_modules\.binonPATH.tsconfig.jsonanda.ts.getKnownServersStatus()anddiscoverLanguageServers()fromsource/lsp/server-discovery.ts.cmd /c typescript-language-server --versionand withspawn('typescript-language-server', ['--stdio']).Expected Behavior
The server is discovered and started, like it is on Linux and macOS.
Actual Behavior
Suggested Fix
source/lsp/server-discovery.ts:findCommand(about lines 249-266) useswhere, so it succeeds.verifyServer(about lines 274-290,execFileSync) andverifyLSPServerWithCommunication(about line 302,spawn) cannot run the shim.source/lsp/lsp-client.ts:69has the samespawn.cross-spawnfor all three. I checked thatcross-spawn.sync('typescript-language-server', ['--version'])returns6.0.2here. Note thatcross-spawnis only a transitive dependency today and is not imported anywhere in the repo, so add it topackage.json(and keepkniphappy).<name>.cmdand run it throughcmd.exe /d /s /conwin32. Thenode_modules/.binfallback infindCommandfinds the extensionless POSIX shim, which also can't be spawned on Windows.typescript-language-server.cmdonPATHand expectdiscoverLanguageServers()to return it. That exact test fails today.Additional Context
file://URI parsing on Windows), [Bug] Command not in Path #605 (closed, debug log noise).