authorgravatar for 146652788+BunnyGamezsc@users.noreply.github.comBunnyGamezsc <146652788+BunnyGamezsc@users.noreply.github.com> 2026-07-17 11:01:02-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-17 18:01:02+00:00
log7f1cb61031184030653c10d1cb357ba226db90e4
tree31c07c542bbe114f18469b1be78811b54222544f
parentc49d424e3aa2f5993e756a2b8f19b9b5da6f0cc5
signature Signed by PGP key B5690EEEBB952194

fix(cursor): default binary path to cursor-agent (avoid path conflict w/ grok) (#4094)


10 files changed, 27 insertions(+), 26 deletions(-)

apps/server/scripts/cursor-acp-model-mismatch-probe.ts+1-1
...@@ -62,7 +62,7 @@ const promptText = NodeProcess.argv[4] ?? "helo";...@@ -62,7 +62,7 @@ const promptText = NodeProcess.argv[4] ?? "helo";
62const targetReasoning = NodeProcess.env.CURSOR_REASONING ?? "";62const targetReasoning = NodeProcess.env.CURSOR_REASONING ?? "";
63const targetContext = NodeProcess.env.CURSOR_CONTEXT ?? "";63const targetContext = NodeProcess.env.CURSOR_CONTEXT ?? "";
64const targetFast = NodeProcess.env.CURSOR_FAST ?? "";64const targetFast = NodeProcess.env.CURSOR_FAST ?? "";
65const agentBin = NodeProcess.env.CURSOR_AGENT_BIN ?? "agent";65const agentBin = NodeProcess.env.CURSOR_AGENT_BIN ?? "cursor-agent";
66const promptWaitMs = Number(NodeProcess.env.CURSOR_PROMPT_WAIT_MS ?? "4000");66const promptWaitMs = Number(NodeProcess.env.CURSOR_PROMPT_WAIT_MS ?? "4000");
67const requestTimeoutMs = Number(NodeProcess.env.CURSOR_REQUEST_TIMEOUT_MS ?? "20000");67const requestTimeoutMs = Number(NodeProcess.env.CURSOR_REQUEST_TIMEOUT_MS ?? "20000");
6868
apps/server/src/provider/Drivers/CursorDriver.ts+12-11
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1/**1/**
2 * CursorDriver — `ProviderDriver` for the Cursor Agent (`agent`) runtime.2 * CursorDriver — `ProviderDriver` for the Cursor Agent (`cursor-agent`) runtime.
3 *3 *
4 * Cursor exposes an ACP-based CLI. Model catalog and capability refreshes4 * Cursor exposes an ACP-based CLI. Model catalog and capability refreshes
5 * happen during the managed provider status check via Cursor's5 * happen during the managed provider status check via Cursor's
...@@ -42,7 +42,7 @@ import type { ServerProviderDraft } from "../providerSnapshot.ts";...@@ -42,7 +42,7 @@ import type { ServerProviderDraft } from "../providerSnapshot.ts";
42import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts";42import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts";
43import {43import {
44 makeProviderMaintenanceCapabilities,44 makeProviderMaintenanceCapabilities,
45 makeStaticProviderMaintenanceResolver,45 type ProviderMaintenanceCapabilitiesResolver,
46 resolveProviderMaintenanceCapabilitiesEffect,46 resolveProviderMaintenanceCapabilitiesEffect,
47} from "../providerMaintenance.ts";47} from "../providerMaintenance.ts";
48import {48import {
...@@ -54,15 +54,16 @@ const decodeCursorSettings = Schema.decodeSync(CursorSettings);...@@ -54,15 +54,16 @@ const decodeCursorSettings = Schema.decodeSync(CursorSettings);
5454
55const DRIVER_KIND = ProviderDriverKind.make("cursor");55const DRIVER_KIND = ProviderDriverKind.make("cursor");
56const SNAPSHOT_REFRESH_INTERVAL = Duration.minutes(5);56const SNAPSHOT_REFRESH_INTERVAL = Duration.minutes(5);
57const UPDATE = makeStaticProviderMaintenanceResolver(57const UPDATE: ProviderMaintenanceCapabilitiesResolver = {
58 makeProviderMaintenanceCapabilities({58 resolve: (options) =>
59 provider: DRIVER_KIND,59 makeProviderMaintenanceCapabilities({
60 packageName: null,60 provider: DRIVER_KIND,
61 updateExecutable: "agent",61 packageName: null,
62 updateArgs: ["update"],62 updateExecutable: options?.binaryPath?.trim() || "cursor-agent",
63 updateLockKey: "cursor-agent",63 updateArgs: ["update"],
64 }),64 updateLockKey: "cursor-agent",
65);65 }),
66};
6667
67export type CursorDriverEnv =68export type CursorDriverEnv =
68 | ChildProcessSpawner.ChildProcessSpawner69 | ChildProcessSpawner.ChildProcessSpawner
apps/server/src/provider/Layers/CursorProvider.test.ts+1-1
...@@ -294,7 +294,7 @@ const parameterizedClaudeModelOptionConfigOptions = [...@@ -294,7 +294,7 @@ const parameterizedClaudeModelOptionConfigOptions = [
294294
295const baseCursorSettings: CursorSettings = {295const baseCursorSettings: CursorSettings = {
296 enabled: true,296 enabled: true,
297 binaryPath: "agent",297 binaryPath: "cursor-agent",
298 apiEndpoint: "",298 apiEndpoint: "",
299 customModels: [],299 customModels: [],
300};300};
apps/server/src/provider/Layers/ProviderInstanceRegistryLive.test.ts+1-1
...@@ -76,7 +76,7 @@ const makeClaudeConfig = (overrides: Partial<ClaudeSettings>): ClaudeSettings =>...@@ -76,7 +76,7 @@ const makeClaudeConfig = (overrides: Partial<ClaudeSettings>): ClaudeSettings =>
7676
77const makeCursorConfig = (overrides: Partial<CursorSettings>): CursorSettings => ({77const makeCursorConfig = (overrides: Partial<CursorSettings>): CursorSettings => ({
78 enabled: false,78 enabled: false,
79 binaryPath: "agent",79 binaryPath: "cursor-agent",
80 apiEndpoint: "",80 apiEndpoint: "",
81 customModels: [],81 customModels: [],
82 ...overrides,82 ...overrides,
apps/server/src/provider/Layers/ProviderRegistry.test.ts+1-1
...@@ -1396,7 +1396,7 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te...@@ -1396,7 +1396,7 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te
1396 Layer.provideMerge(OpenCodeRuntime.OpenCodeRuntimeLive),1396 Layer.provideMerge(OpenCodeRuntime.OpenCodeRuntimeLive),
1397 Layer.provideMerge(1397 Layer.provideMerge(
1398 mockCommandSpawnerLayer((command, args) => {1398 mockCommandSpawnerLayer((command, args) => {
1399 if (command === "agent") {1399 if (command === "cursor-agent") {
1400 cursorSpawned = true;1400 cursorSpawned = true;
1401 }1401 }
1402 const joined = args.join(" ");1402 const joined = args.join(" ");
apps/server/src/provider/acp/CursorAcpCliProbe.test.ts+5-5
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1/**1/**
2 * Optional integration check against a real `agent acp` install.2 * Optional integration check against a real `cursor-agent acp` install.
3 * Enable with: T3_CURSOR_ACP_PROBE=1 bun run test --filter CursorAcpCliProbe3 * Enable with: T3_CURSOR_ACP_PROBE=1 bun run test --filter CursorAcpCliProbe
4 */4 */
5import * as NodeServices from "@effect/platform-node/NodeServices";5import * as NodeServices from "@effect/platform-node/NodeServices";
...@@ -12,7 +12,7 @@ import type * as EffectAcpSchema from "effect-acp/schema";...@@ -12,7 +12,7 @@ import type * as EffectAcpSchema from "effect-acp/schema";
12import * as AcpSessionRuntime from "./AcpSessionRuntime.ts";12import * as AcpSessionRuntime from "./AcpSessionRuntime.ts";
1313
14describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe", () => {14describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe", () => {
15 it.effect("initialize and authenticate against real agent acp", () =>15 it.effect("initialize and authenticate against real cursor-agent acp", () =>
16 Effect.gen(function* () {16 Effect.gen(function* () {
17 const runtime = yield* AcpSessionRuntime.AcpSessionRuntime;17 const runtime = yield* AcpSessionRuntime.AcpSessionRuntime;
18 const started = yield* runtime.start();18 const started = yield* runtime.start();
...@@ -21,7 +21,7 @@ describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe",...@@ -21,7 +21,7 @@ describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe",
21 Effect.provide(21 Effect.provide(
22 AcpSessionRuntime.layer({22 AcpSessionRuntime.layer({
23 spawn: {23 spawn: {
24 command: "agent",24 command: "cursor-agent",
25 args: ["acp"],25 args: ["acp"],
26 cwd: process.cwd(),26 cwd: process.cwd(),
27 },27 },
...@@ -77,7 +77,7 @@ describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe",...@@ -77,7 +77,7 @@ describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe",
77 AcpSessionRuntime.layer({77 AcpSessionRuntime.layer({
78 authMethodId: "cursor_login",78 authMethodId: "cursor_login",
79 spawn: {79 spawn: {
80 command: "agent",80 command: "cursor-agent",
81 args: ["acp"],81 args: ["acp"],
82 cwd: process.cwd(),82 cwd: process.cwd(),
83 },83 },
...@@ -133,7 +133,7 @@ describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe",...@@ -133,7 +133,7 @@ describe.runIf(process.env.T3_CURSOR_ACP_PROBE === "1")("Cursor ACP CLI probe",
133 AcpSessionRuntime.layer({133 AcpSessionRuntime.layer({
134 authMethodId: "cursor_login",134 authMethodId: "cursor_login",
135 spawn: {135 spawn: {
136 command: "agent",136 command: "cursor-agent",
137 args: ["acp"],137 args: ["acp"],
138 cwd: process.cwd(),138 cwd: process.cwd(),
139 },139 },
apps/server/src/provider/acp/CursorAcpSupport.test.ts+1-1
...@@ -53,7 +53,7 @@ const parameterizedGpt54ConfigOptions: ReadonlyArray<EffectAcpSchema.SessionConf...@@ -53,7 +53,7 @@ const parameterizedGpt54ConfigOptions: ReadonlyArray<EffectAcpSchema.SessionConf
53describe("buildCursorAcpSpawnInput", () => {53describe("buildCursorAcpSpawnInput", () => {
54 it("builds the default Cursor ACP command", () => {54 it("builds the default Cursor ACP command", () => {
55 expect(buildCursorAcpSpawnInput(undefined, "/tmp/project")).toEqual({55 expect(buildCursorAcpSpawnInput(undefined, "/tmp/project")).toEqual({
56 command: "agent",56 command: "cursor-agent",
57 args: ["acp"],57 args: ["acp"],
58 cwd: "/tmp/project",58 cwd: "/tmp/project",
59 });59 });
apps/server/src/provider/acp/CursorAcpSupport.ts+1-1
...@@ -35,7 +35,7 @@ export function buildCursorAcpSpawnInput(...@@ -35,7 +35,7 @@ export function buildCursorAcpSpawnInput(
35 environment?: NodeJS.ProcessEnv,35 environment?: NodeJS.ProcessEnv,
36): AcpSessionRuntime.AcpSpawnInput {36): AcpSessionRuntime.AcpSpawnInput {
37 return {37 return {
38 command: cursorSettings?.binaryPath || "agent",38 command: cursorSettings?.binaryPath || "cursor-agent",
39 args: [39 args: [
40 ...(cursorSettings?.apiEndpoint ? (["-e", cursorSettings.apiEndpoint] as const) : []),40 ...(cursorSettings?.apiEndpoint ? (["-e", cursorSettings.apiEndpoint] as const) : []),
41 "acp",41 "acp",
apps/server/src/provider/providerMaintenanceRunner.test.ts+2-2
...@@ -48,7 +48,7 @@ function lifecycleFor(provider: ProviderDriverKind): ProviderMaintenanceCapabili...@@ -48,7 +48,7 @@ function lifecycleFor(provider: ProviderDriverKind): ProviderMaintenanceCapabili
48 return makeProviderMaintenanceCapabilities({48 return makeProviderMaintenanceCapabilities({
49 provider,49 provider,
50 packageName: null,50 packageName: null,
51 updateExecutable: "agent",51 updateExecutable: "cursor-agent",
52 updateArgs: ["update"],52 updateArgs: ["update"],
53 updateLockKey: "cursor-agent",53 updateLockKey: "cursor-agent",
54 });54 });
...@@ -226,7 +226,7 @@ describe("providerMaintenanceRunner", () => {...@@ -226,7 +226,7 @@ describe("providerMaintenanceRunner", () => {
226 const result = yield* updater.updateProvider(CURSOR_DRIVER);226 const result = yield* updater.updateProvider(CURSOR_DRIVER);
227 assert.deepStrictEqual(calls, [227 assert.deepStrictEqual(calls, [
228 {228 {
229 command: "agent",229 command: "cursor-agent",
230 args: ["update"],230 args: ["update"],
231 },231 },
232 ]);232 ]);
packages/contracts/src/settings.ts+2-2
...@@ -252,11 +252,11 @@ export const CursorSettings = makeProviderSettingsSchema(...@@ -252,11 +252,11 @@ export const CursorSettings = makeProviderSettingsSchema(
252 Schema.withDecodingDefault(Effect.succeed(false)),252 Schema.withDecodingDefault(Effect.succeed(false)),
253 Schema.annotateKey({ providerSettingsForm: { hidden: true } }),253 Schema.annotateKey({ providerSettingsForm: { hidden: true } }),
254 ),254 ),
255 binaryPath: makeBinaryPathSetting("agent").pipe(255 binaryPath: makeBinaryPathSetting("cursor-agent").pipe(
256 Schema.annotateKey({256 Schema.annotateKey({
257 title: "Binary path",257 title: "Binary path",
258 description: "Path to the Cursor agent binary.",258 description: "Path to the Cursor agent binary.",
259 providerSettingsForm: { placeholder: "agent", clearWhenEmpty: "omit" },259 providerSettingsForm: { placeholder: "cursor-agent", clearWhenEmpty: "omit" },
260 }),260 }),
261 ),261 ),
262 apiEndpoint: TrimmedString.pipe(262 apiEndpoint: TrimmedString.pipe(