Add a global Cursor CLI binary path override that is validated before enabling or probing Cursor routing. - Add global settings schema/types and API support for storing a trimmed Cursor CLI binary path override. - Surface a Settings Authentication control to save, clear, and test the Cursor CLI binary path. - Probe configured Cursor binaries before PATH fallbacks and expose diagnostics for status/routes. - Cover settings, route, dashboard, and cursor runtime behavior with focused tests and documentation. Files changed: .changeset/fn-7419-cursor-cli-binary-path.md | 7 ++ docs/cursor-cli-contract.md | 33 ++++-- docs/settings-reference.md | 2 + .../core/src/__tests__/cursor-cli-settings.test.ts | 34 ++++++ packages/core/src/settings-schema.ts | 6 + packages/core/src/types.ts | 8 ++ packages/dashboard/app/api/legacy.ts | 17 ++- .../app/components/CursorCliProviderCard.css | 37 +++++- .../app/components/CursorCliProviderCard.tsx | 78 ++++++++++++- .../__tests__/ModelOnboardingModal.test.tsx | 4 + .../__tests__/SettingsModal.general.test.tsx | 2 + .../__tests__/SettingsModal.models-auth.test.tsx | 75 ++++++++++++ .../SettingsModal.remote-notifications.test.tsx | 2 + .../SettingsModal.scheduling-merge.test.tsx | 2 + .../__tests__/SettingsModal.test-harness.tsx | 3 + .../dashboard/src/__tests__/routes-auth.test.ts | 130 ++++++++++++++++++++- .../dashboard/src/routes/register-auth-routes.ts | 69 +++++++++-- .../src/__tests__/probe.test.ts | 61 +++++++++- .../src/__tests__/process-manager.test.ts | 10 ++ .../src/__tests__/provider.test.ts | 57 +++++++++ plugins/fusion-plugin-cursor-runtime/src/probe.ts | 39 +++++-- .../fusion-plugin-cursor-runtime/src/provider.ts | 15 ++- plugins/fusion-plugin-cursor-runtime/src/types.ts | 3 + 23 files changed, 655 insertions(+), 39 deletions(-) Fusion-Task-Id: FN-7419 Fusion-Task-Lineage: 2c192a37-a1db-41a9-99f5-a480ed311d9c Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
5.9 KiB
Cursor CLI Contract (FN-3396 Step 0)
Date: 2026-05-07
Research method
- Local runtime inspection in the task environment (
which, direct command execution). - Local binary wrapper inspection (
cursor,cursor-agentlaunch scripts and install layout). - Bounded
fn_research_runwas attempted but failed in this environment with:table research_runs has no column named projectId.
Confirmed invocation and binary detection
- Primary executable aliases found on PATH:
cursorcursor-agent
- Not found on PATH:
cursor-cli
cursoris a wrapper that can delegate to agent mode and emits a targeted message when IDE install is missing.cursor-agentis the direct CLI runtime entrypoint and is symlinked to a versioned install under:~/.local/share/cursor-agent/versions/<version>/cursor-agent
Detection strategy
- If the global
cursorCliBinaryPathsetting is a non-empty string, probe that configured binary first. - Probe
cursor-agentfrom PATH. - Probe
cursorfrom PATH. - Deduplicate candidates when the configured value is exactly
cursor-agentorcursor. - Persist the resolved path and executable name in probe results.
- Report explicit failure reason when neither exists.
Manual binary path override
Settings → Authentication → Cursor CLI exposes an optional binary path field. Leave it blank to use PATH auto-detection. When populated, Fusion validates the configured path by running the same --version probe used for status/enable, saves it only if that configured candidate itself succeeds, and then uses it for status, enable validation, and Cursor model discovery before falling back to PATH candidates.
If the configured path fails during ordinary status/model-discovery probes but a PATH candidate succeeds, Fusion remains usable and reports the PATH candidate as the effective binaryPath; bounded diagnostics include the configured-path failure. If saving a new non-empty override fails or only succeeds via PATH fallback, the Settings save returns a 400 diagnostic and does not persist the path.
Windows paths with spaces, for example C:\Users\A User\AppData\Roaming\npm\cursor-agent.cmd, are treated as one operator-provided string. Users should not quote or split the path in the UI.
Windows PATH shim invocation
On Windows, cursor-agent, cursor, and manual override paths can resolve to .cmd / .bat wrappers rather than native executables. Node.js direct spawn(binary, args) does not execute those wrappers reliably; Fusion's Cursor command runner therefore sets shell execution only when process.platform === "win32".
The Windows shell-backed path applies to every Cursor CLI command Fusion currently runs through the shared runner:
- Configured binary /
cursor-agent --version/cursor --versionprobe attempts. - Model discovery attempts against the effective probe-selected binary:
models --json,model list --json, andmodels.
Non-Windows probes and discovery continue to use direct spawn. Spawn errors such as ENOENT or EACCES are included in the unavailable probe reason in bounded diagnostic form so a working terminal command is distinguishable from known Cursor runtime/auth states; Fusion does not dump PATH, environment variables, or unbounded stdout/stderr.
Confirmed error/auth/runtime signals
Observed command behavior in this environment:
cursor --help(without IDE install):Error: No Cursor IDE installation found. Use 'cursor agent' or 'agent' to run the agent.
cursor-agent --helpandcursor agent --help(with locked keychain):Error: Your macOS login keychain is locked.Run security unlock-keychain and try again.
Auth/readiness implications
- Keychain-locked is a distinct, expected failure mode and must be surfaced as an auth/runtime-blocked state (not as unknown crash).
- Missing IDE install is a distinct expected failure mode from missing binary.
Structured output and model discovery
- No stable model-list command was conclusively confirmed in this preflight due CLI gating by keychain lock and inability to complete bounded remote research in this run.
- No contract evidence yet for a guaranteed
--jsonor dedicated model enumeration command.
Fallback model discovery strategy (to use in implementation)
- Attempt known structured/listing command variants with short timeouts (plugin-defined sequence).
- If structured output is unavailable but text output exists, parse tolerant line-based IDs.
- Normalize and dedupe model IDs.
- If discovery is unavailable/fails, return an empty discovered set with:
sourcemarking probe mode,fallbackUsed: true,- machine-readable reason.
- Host should only surface Cursor models when provider readiness + discovery usability conditions are met.
Provider ID decision
- Use
cursor-clias the provider ID. - Rationale: aligns with task requirement; no conflicting provider ID observed in current codebase scan.
Contract freeze for FN-3396
Implementation should treat the following as canonical for this task unless stronger evidence is found during code-level integration tests:
- Binary candidates:
cursor-agent,cursor. - Expected failure states include: missing binary, missing IDE installation, keychain locked, unauthenticated/not-ready CLI.
- Model discovery must be dynamic-first with resilient fallback and no hardcoded static catalog by default.