agent-dealer 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import fs from "node:fs";
3
- import { claudeBinExists, cursorBinExists, resolveClaudeBin, resolveCursorBin, } from "../cli-env.js";
3
+ import { claudeBinExists, cursorBinExists, resolveClaudeBin, cursorInvokeArgs, resolveCursorBin, } from "../cli-env.js";
4
4
  import { checkAgentDeckHealth, isAgentDeckMcpRegistered } from "./agent-deck.js";
5
5
  const RUNTIME_CACHE_MS = 60_000;
6
6
  const runtimeIssueCache = new Map();
@@ -41,13 +41,13 @@ async function runtimeIssuesUncached(runtime) {
41
41
  }
42
42
  return [];
43
43
  }
44
- const status = await runCommand(resolveCursorBin(), ["agent", "status"]);
44
+ const status = await runCommand(resolveCursorBin(), cursorInvokeArgs(["status"]));
45
45
  if (!status.ok && !status.output.trim() && !cursorBinExists()) {
46
- return [{ code: "cli_missing", message: "Cursor CLI not found" }];
46
+ return [{ code: "cli_missing", message: "cursor-agent not found — run: curl https://cursor.com/install -fsS | bash" }];
47
47
  }
48
48
  const out = status.output.toLowerCase();
49
49
  if (out.includes("not logged in") || out.includes("login required") || out.includes("not authenticated")) {
50
- return [{ code: "runtime_auth", message: "Run cursor agent login" }];
50
+ return [{ code: "runtime_auth", message: "Run cursor-agent login" }];
51
51
  }
52
52
  return [];
53
53
  }
@@ -40,17 +40,32 @@ export function resolveClaudeBin() {
40
40
  "/usr/local/bin/claude",
41
41
  ]) ?? "claude");
42
42
  }
43
- /** Resolve Cursor CLI binary. */
43
+ /** Resolve Cursor Agent CLI binary (`cursor-agent` from cursor.com/install). */
44
44
  export function resolveCursorBin() {
45
45
  const home = process.env.HOME ?? os.homedir();
46
46
  if (process.env.CURSOR_CLI)
47
47
  return process.env.CURSOR_CLI;
48
48
  return (firstExisting([
49
+ path.join(home, ".local/bin/cursor-agent"),
50
+ path.join(home, ".cursor/bin/cursor-agent"),
51
+ "/opt/homebrew/bin/cursor-agent",
52
+ "/usr/local/bin/cursor-agent",
53
+ // Legacy: Cursor editor `cursor` shim routes `cursor agent` → cursor-agent
49
54
  path.join(home, ".local/bin/cursor"),
50
55
  path.join(home, ".cursor/bin/cursor"),
51
56
  "/opt/homebrew/bin/cursor",
52
57
  "/usr/local/bin/cursor",
53
- ]) ?? "cursor");
58
+ ]) ?? "cursor-agent");
59
+ }
60
+ /**
61
+ * Args for Cursor agent invocations.
62
+ * `cursor-agent` is invoked directly; legacy editor `cursor` needs an `agent` subcommand.
63
+ */
64
+ export function cursorInvokeArgs(args) {
65
+ const bin = resolveCursorBin();
66
+ if (path.basename(bin) === "cursor")
67
+ return ["agent", ...args];
68
+ return args;
54
69
  }
55
70
  export function claudeBinExists() {
56
71
  const bin = resolveClaudeBin();
@@ -58,5 +73,5 @@ export function claudeBinExists() {
58
73
  }
59
74
  export function cursorBinExists() {
60
75
  const bin = resolveCursorBin();
61
- return bin !== "cursor" ? fs.existsSync(bin) : false;
76
+ return bin !== "cursor-agent" && bin !== "cursor" ? fs.existsSync(bin) : false;
62
77
  }
@@ -0,0 +1,30 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { cursorInvokeArgs } from "./cli-env.js";
4
+ test("cursorInvokeArgs passes through for cursor-agent", () => {
5
+ const prev = process.env.CURSOR_CLI;
6
+ process.env.CURSOR_CLI = "/home/user/.local/bin/cursor-agent";
7
+ try {
8
+ assert.deepEqual(cursorInvokeArgs(["status"]), ["status"]);
9
+ assert.deepEqual(cursorInvokeArgs(["-p", "--trust", "hi"]), ["-p", "--trust", "hi"]);
10
+ }
11
+ finally {
12
+ if (prev === undefined)
13
+ delete process.env.CURSOR_CLI;
14
+ else
15
+ process.env.CURSOR_CLI = prev;
16
+ }
17
+ });
18
+ test("cursorInvokeArgs prepends agent subcommand for legacy cursor shim", () => {
19
+ const prev = process.env.CURSOR_CLI;
20
+ process.env.CURSOR_CLI = "/usr/local/bin/cursor";
21
+ try {
22
+ assert.deepEqual(cursorInvokeArgs(["status"]), ["agent", "status"]);
23
+ }
24
+ finally {
25
+ if (prev === undefined)
26
+ delete process.env.CURSOR_CLI;
27
+ else
28
+ process.env.CURSOR_CLI = prev;
29
+ }
30
+ });
@@ -4,7 +4,7 @@ import path from "node:path";
4
4
  import { buildExecutionPrompt, buildExecutionContinuationPrompt, buildPlanPrompt, buildReflectPrompt, workspaceForRun } from "./prompts.js";
5
5
  import { humanFeedbackText, lineageParentExecuteSessionId } from "./run-context.js";
6
6
  import { getTemporalLogsDir } from "../paths.js";
7
- import { resolveClaudeBin, resolveCursorBin } from "../cli-env.js";
7
+ import { cursorInvokeArgs, resolveClaudeBin, resolveCursorBin } from "../cli-env.js";
8
8
  import { resolveBudgetForPhase, resolveModelForPhase, getRun } from "../repository/runs.js";
9
9
  import { budgetCliArgs, QA_PHASE_BUDGET } from "@agent-dealer/shared";
10
10
  import { buildClaudePhaseArgs } from "./claude-args.js";
@@ -67,8 +67,7 @@ export async function runCursor(run, mode = "execute", model, opts) {
67
67
  }
68
68
  const prompt = opts?.promptOverride ?? (mode === "plan" ? buildPlanPrompt(run) : buildExecutionPrompt(run));
69
69
  const logPath = logPathFor(run, mode);
70
- const args = [
71
- "agent",
70
+ const args = cursorInvokeArgs([
72
71
  "-p",
73
72
  "--trust",
74
73
  "--output-format",
@@ -78,7 +77,7 @@ export async function runCursor(run, mode = "execute", model, opts) {
78
77
  ...(opts?.resumeSessionId ? ["--resume", opts.resumeSessionId] : []),
79
78
  ...(model ? ["--model", model] : []),
80
79
  prompt,
81
- ];
80
+ ]);
82
81
  const { exitCode, transcript } = await spawnCli(resolveCursorBin(), args, workspaceForRun(run));
83
82
  if (transcript)
84
83
  fs.writeFileSync(logPath, transcript);
@@ -1,6 +1,6 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import { CURSOR_DEFAULT_MODEL, CURSOR_SUBSCRIPTION_MODEL_IDS } from "@agent-dealer/shared";
3
- import { resolveCursorBin } from "../cli-env.js";
3
+ import { cursorInvokeArgs, resolveCursorBin } from "../cli-env.js";
4
4
  const CURSOR_PINNED = [
5
5
  { id: CURSOR_DEFAULT_MODEL, label: "Auto (subscription pool)" },
6
6
  { id: "composer-2.5", label: "Composer 2.5 (subscription pool)" },
@@ -79,7 +79,7 @@ async function tryAnthropicModelsApi() {
79
79
  }
80
80
  function listCursorModels() {
81
81
  const bin = resolveCursorBin();
82
- const result = spawnSync(bin, ["agent", "--list-models"], {
82
+ const result = spawnSync(bin, cursorInvokeArgs(["--list-models"]), {
83
83
  encoding: "utf8",
84
84
  timeout: 20_000,
85
85
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-dealer/server",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "files": [