fix: spawn cursor-agent with shell mode on Windows (model discovery falls back to static list) - #128
Merged
Conversation
On Windows, cursor-agent is a .cmd shim. Node's execFileSync cannot execute a bare .cmd file and fails with EINVAL, so model discovery silently fell back to a static 20-model list (missing newly released Cursor models) and 'open-cursor doctor' misreported cursor-agent as not installed. - discoverModelsFromCursorAgent(): use shell mode on win32 via an injectable deps object (platform/execFileSync/resolveBinary), matching the existing binary.ts contract that Windows callers pair the resolver with shell mode - checkCursorAgent()/checkCursorAgentLogin(): same win32 shell mode so doctor checks correctly resolve cursor-agent - add unit tests asserting shell mode is used on win32 and not used elsewhere
Owner
|
Thanks for tracking this down. You found the right root cause and CI is green. Every discovery path routes through One gap: I'll merge this as the foundation and wrap the three sites in a maintainer follow-up, so you don't need to touch anything here. Thanks again. cheers, RAMA |
Nomadcxx
added a commit
that referenced
this pull request
Aug 27, 2026
#128 added shell mode on win32 to the three cli spawn sites but passed the resolved binary through unquoted. Under shell mode Node joins file and args into one cmd.exe string without quoting the file, so a profile path containing a space splits at the space and discovery falls back to the static model list, which is the failure #128 set out to fix. Wrap the path in formatShellCommandForPlatform() at all three sites, matching the contract in utils/binary.ts and the existing spawn sites in plugin.ts and client/simple.ts. The win32 test fixture had no space in it, so it passed with or without the quoting. Swap in a spaced profile path and assert the quoted command.
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.
Problem
On Windows,
cursor-agentis installed as a.cmdshim(
%LOCALAPPDATA%\cursor-agent\cursor-agent.cmd). Node'sexecFileSynccannotexecute a bare
.cmdfile and throwsEINVAL:Because of this, every model-discovery path silently fell back to the static
20-model list:
open-cursor install/open-cursor sync-models-> "Models synced: 20"open-cursor doctor-> misreportscursor-agent: not found/not logged inUsers on Windows therefore never see models that exist in their Cursor
subscription (e.g. the
cursor-grok-4.5-*/cursor-grok-4.6-*families), eventhough
cursor-agent modelslists 200+ models from a normal shell.Root cause
src/utils/binary.tsdocuments the existing contract clearly:plugin.tsfollows it (spawnSync(..., shell: process.platform === "win32")),but
cli/model-discovery.tsand the doctor checks incli/opencode-cursor.tsdid not.
Fix
src/cli/model-discovery.ts:discoverModelsFromCursorAgent()now spawns withshell: platform === "win32"depsobject (platform/execFileSync/resolveBinary) so the spawn behaviour is unit-testablesrc/cli/opencode-cursor.ts:checkCursorAgent()andcheckCursorAgentLogin()use the sameshell: process.platform === "win32"so
open-cursor doctorworks on WindowsTesting
tests/unit/cli/model-discovery.test.tsassert:shell: trueand the resolved.cmdbinary is usedshell: falseandkillSignal: SIGTERM(unchanged behaviour)bun test tests/unit/cli/model-discovery.test.ts-> 4 passopen-cursor sync-models --dry-runnowdiscovers 204 models (previously 20 via fallback) and writes
cursor-grok-4.5-high/cursor-grok-4.6-*intoopencode.json; latestopen-cursor doctorreports cursor-agent installed/logged in.Notes
dist/is git-ignored and rebuilt at publish time, so no build artifacts arecommitted.
symlinkSyncEPERM intests/unit/cli/opencode-cursor.test.ts(Windowsrequires Developer Mode / admin for symlinks) -> unrelated to this change.