pi-cursor-bridge 0.1.3 → 0.1.5

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.
@@ -2990,7 +2990,7 @@ var require_compile = __commonJS({
2990
2990
  const schOrFunc = root.refs[ref];
2991
2991
  if (schOrFunc)
2992
2992
  return schOrFunc;
2993
- let _sch = resolve6.call(this, root, ref);
2993
+ let _sch = resolve7.call(this, root, ref);
2994
2994
  if (_sch === void 0) {
2995
2995
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2996
2996
  const { schemaId } = this.opts;
@@ -3017,7 +3017,7 @@ var require_compile = __commonJS({
3017
3017
  function sameSchemaEnv(s1, s2) {
3018
3018
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3019
3019
  }
3020
- function resolve6(root, ref) {
3020
+ function resolve7(root, ref) {
3021
3021
  let sch;
3022
3022
  while (typeof (sch = this.refs[ref]) == "string")
3023
3023
  ref = sch;
@@ -3648,7 +3648,7 @@ var require_fast_uri = __commonJS({
3648
3648
  }
3649
3649
  return uri;
3650
3650
  }
3651
- function resolve6(baseURI, relativeURI, options) {
3651
+ function resolve7(baseURI, relativeURI, options) {
3652
3652
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3653
3653
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3654
3654
  schemelessOptions.skipEscape = true;
@@ -3906,7 +3906,7 @@ var require_fast_uri = __commonJS({
3906
3906
  var fastUri = {
3907
3907
  SCHEMES,
3908
3908
  normalize,
3909
- resolve: resolve6,
3909
+ resolve: resolve7,
3910
3910
  resolveComponent,
3911
3911
  equal,
3912
3912
  serialize,
@@ -10897,20 +10897,20 @@ public static class CursorBridgeWindowControl {
10897
10897
 
10898
10898
  // lifecycle-paths.mjs
10899
10899
  import { createHash } from "node:crypto";
10900
- import { homedir as homedir2 } from "node:os";
10901
- import { join as join2 } from "node:path";
10902
- import { mkdirSync as mkdirSync2 } from "node:fs";
10900
+ import { homedir as homedir3 } from "node:os";
10901
+ import { join as join3 } from "node:path";
10902
+ import { mkdirSync as mkdirSync3 } from "node:fs";
10903
10903
  function defaultLifecycleDir() {
10904
10904
  if (process.env.CURSOR_BRIDGE_LIFECYCLE_DIR) return process.env.CURSOR_BRIDGE_LIFECYCLE_DIR;
10905
10905
  if (process.platform === "win32") {
10906
- const root2 = process.env.LOCALAPPDATA || join2(homedir2(), "AppData", "Local");
10907
- return join2(root2, "cursor-bridge", "lifecycle");
10906
+ const root2 = process.env.LOCALAPPDATA || join3(homedir3(), "AppData", "Local");
10907
+ return join3(root2, "cursor-bridge", "lifecycle");
10908
10908
  }
10909
- const root = process.env.XDG_RUNTIME_DIR || process.env.XDG_STATE_HOME || join2(homedir2(), ".local", "state");
10910
- return join2(root, "cursor-bridge", "lifecycle");
10909
+ const root = process.env.XDG_RUNTIME_DIR || process.env.XDG_STATE_HOME || join3(homedir3(), ".local", "state");
10910
+ return join3(root, "cursor-bridge", "lifecycle");
10911
10911
  }
10912
10912
  function ensureLifecycleDir(dir = defaultLifecycleDir()) {
10913
- mkdirSync2(dir, { recursive: true });
10913
+ mkdirSync3(dir, { recursive: true });
10914
10914
  return dir;
10915
10915
  }
10916
10916
  function lifecycleEndpointTag(dir) {
@@ -10921,13 +10921,13 @@ function supervisorSockPath(dir = defaultLifecycleDir()) {
10921
10921
  if (process.platform === "win32") {
10922
10922
  return `\\\\.\\pipe\\cursor-bridge-lifecycle-${lifecycleEndpointTag(dir)}`;
10923
10923
  }
10924
- return join2(dir, "supervisor.sock");
10924
+ return join3(dir, "supervisor.sock");
10925
10925
  }
10926
10926
  function supervisorPidPath(dir = defaultLifecycleDir()) {
10927
- return join2(dir, "supervisor.pid");
10927
+ return join3(dir, "supervisor.pid");
10928
10928
  }
10929
10929
  function supervisorLockPath(dir = defaultLifecycleDir()) {
10930
- return join2(dir, "supervisor.lock");
10930
+ return join3(dir, "supervisor.lock");
10931
10931
  }
10932
10932
  var init_lifecycle_paths = __esm({
10933
10933
  "lifecycle-paths.mjs"() {
@@ -10937,15 +10937,15 @@ var init_lifecycle_paths = __esm({
10937
10937
  // workspace-binding.mjs
10938
10938
  import {
10939
10939
  existsSync,
10940
- mkdirSync as mkdirSync3,
10941
- readFileSync as readFileSync2,
10942
- renameSync as renameSync2,
10943
- rmSync as rmSync2,
10940
+ mkdirSync as mkdirSync4,
10941
+ readFileSync as readFileSync3,
10942
+ renameSync as renameSync3,
10943
+ rmSync as rmSync3,
10944
10944
  statSync,
10945
- writeFileSync as writeFileSync2
10945
+ writeFileSync as writeFileSync3
10946
10946
  } from "node:fs";
10947
- import { dirname as dirname2, extname, isAbsolute, join as join3, resolve as resolve2 } from "node:path";
10948
- import { homedir as homedir3 } from "node:os";
10947
+ import { dirname as dirname3, extname, isAbsolute, join as join4, resolve as resolve3 } from "node:path";
10948
+ import { homedir as homedir4 } from "node:os";
10949
10949
  function pluginRuntimePath(candidate) {
10950
10950
  const value = String(candidate || "").replace(/\//g, "\\").toLowerCase();
10951
10951
  return value.includes("\\.codex\\.tmp\\marketplaces\\") || value.includes("\\.codex\\plugins\\cache\\") || value.includes("\\.claude\\plugins\\cache\\") || value.includes("\\appdata\\local\\npm-cache\\_npx\\");
@@ -10953,11 +10953,11 @@ function pluginRuntimePath(candidate) {
10953
10953
  function normalizeWorkspacePath(value) {
10954
10954
  let raw = String(value || "").trim().replace(/^(["'])(.*)\1$/, "$2").trim();
10955
10955
  if (!raw) return "";
10956
- if (raw === "~") raw = homedir3();
10957
- else if (raw.startsWith("~/") || raw.startsWith("~\\")) raw = join3(homedir3(), raw.slice(2));
10958
- if (/^\\\\\?\\UNC\\/i.test(raw)) return resolve2(`\\\\${raw.slice(8)}`);
10959
- if (/^\\\\\?\\[a-zA-Z]:\\/.test(raw)) return resolve2(raw.slice(4));
10960
- return resolve2(raw);
10956
+ if (raw === "~") raw = homedir4();
10957
+ else if (raw.startsWith("~/") || raw.startsWith("~\\")) raw = join4(homedir4(), raw.slice(2));
10958
+ if (/^\\\\\?\\UNC\\/i.test(raw)) return resolve3(`\\\\${raw.slice(8)}`);
10959
+ if (/^\\\\\?\\[a-zA-Z]:\\/.test(raw)) return resolve3(raw.slice(4));
10960
+ return resolve3(raw);
10961
10961
  }
10962
10962
  function isAbsoluteWorkspacePath(value) {
10963
10963
  const raw = String(value || "").trim().replace(/^(["'])(.*)\1$/, "$2").trim();
@@ -10977,7 +10977,7 @@ function isWorkspaceTarget(projectPath, options = {}) {
10977
10977
  }
10978
10978
  }
10979
10979
  function resolveWorkspaceBindingFile(env = process.env) {
10980
- return resolve2(env.CURSOR_BRIDGE_WORKSPACE_FILE || join3(defaultLifecycleDir(), "workspaces.json"));
10980
+ return resolve3(env.CURSOR_BRIDGE_WORKSPACE_FILE || join4(defaultLifecycleDir(), "workspaces.json"));
10981
10981
  }
10982
10982
  function resolveWorkspaceBindingKey(env = process.env, options = {}) {
10983
10983
  const codexThreadId = String(env.CODEX_THREAD_ID || "").trim();
@@ -11001,7 +11001,7 @@ function resolveWorkspaceBindingKey(env = process.env, options = {}) {
11001
11001
  function readWorkspaceBindings(filePath) {
11002
11002
  if (!filePath) return { version: WORKSPACE_BINDING_VERSION, bindings: {} };
11003
11003
  try {
11004
- const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
11004
+ const parsed = JSON.parse(readFileSync3(filePath, "utf8"));
11005
11005
  if (!parsed || parsed.version !== WORKSPACE_BINDING_VERSION || !parsed.bindings || typeof parsed.bindings !== "object") {
11006
11006
  return { version: WORKSPACE_BINDING_VERSION, bindings: {} };
11007
11007
  }
@@ -11038,13 +11038,13 @@ function writeWorkspaceBinding(filePath, bindingKey, projectPath, options = {})
11038
11038
  const state = readWorkspaceBindings(filePath);
11039
11039
  const updatedAt = options.updatedAt || (/* @__PURE__ */ new Date()).toISOString();
11040
11040
  state.bindings[key] = { projectPath: normalized, updatedAt };
11041
- mkdirSync3(dirname2(filePath), { recursive: true });
11041
+ mkdirSync4(dirname3(filePath), { recursive: true });
11042
11042
  const temporary = `${filePath}.${process.pid}.${Date.now()}.tmp`;
11043
11043
  try {
11044
- writeFileSync2(temporary, JSON.stringify(state, null, 2) + "\n", "utf8");
11045
- renameSync2(temporary, filePath);
11044
+ writeFileSync3(temporary, JSON.stringify(state, null, 2) + "\n", "utf8");
11045
+ renameSync3(temporary, filePath);
11046
11046
  } catch (error2) {
11047
- rmSync2(temporary, { force: true });
11047
+ rmSync3(temporary, { force: true });
11048
11048
  throw new Error(`failed to persist cursor_init at ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`);
11049
11049
  }
11050
11050
  return { projectPath: normalized, updatedAt };
@@ -11068,8 +11068,8 @@ var init_workspace_binding = __esm({
11068
11068
  import { spawn as spawn2, execFileSync as execFileSync2 } from "child_process";
11069
11069
  import { existsSync as existsSync2 } from "fs";
11070
11070
  import { createRequire as createNodeRequire } from "node:module";
11071
- import { homedir as homedir4 } from "node:os";
11072
- import { basename as basename2, extname as extname2, join as join4, resolve as resolve3, win32 as winPath, posix as posixPath } from "node:path";
11071
+ import { homedir as homedir5 } from "node:os";
11072
+ import { basename as basename3, extname as extname2, join as join5, resolve as resolve4, win32 as winPath, posix as posixPath } from "node:path";
11073
11073
  import http from "http";
11074
11074
  function resolveCursorLaunchCdpPort(port = process.env.CURSOR_BRIDGE_CDP_PORT) {
11075
11075
  const parsed = Number(port == null || String(port).trim() === "" ? 9223 : port);
@@ -11096,13 +11096,13 @@ function resolveCodexThreadProjectPath(options = {}) {
11096
11096
  try {
11097
11097
  const lookupThreadCwd = options.lookupThreadCwd || ((id) => {
11098
11098
  const { DatabaseSync } = (options.requireImpl || loadModule)("node:sqlite");
11099
- const databasePath = options.databasePath || join4(homedir4(), ".codex", "state_5.sqlite");
11099
+ const databasePath = options.databasePath || join5(homedir5(), ".codex", "state_5.sqlite");
11100
11100
  database = new DatabaseSync(databasePath, { readOnly: true });
11101
11101
  return database.prepare("SELECT cwd FROM threads WHERE id = ?").get(id)?.cwd || null;
11102
11102
  });
11103
11103
  const candidate = normalizeCodexThreadCwd(lookupThreadCwd(threadId));
11104
11104
  const existsImpl = options.existsImpl || existsSync2;
11105
- const resolved = candidate && !looksLikePluginRuntimePath(candidate) && existsImpl(candidate) ? resolve3(candidate) : null;
11105
+ const resolved = candidate && !looksLikePluginRuntimePath(candidate) && existsImpl(candidate) ? resolve4(candidate) : null;
11106
11106
  if (options.useCache !== false) CODEX_THREAD_PROJECTS.set(threadId, resolved);
11107
11107
  return resolved;
11108
11108
  } catch {
@@ -11117,14 +11117,14 @@ function resolveCodexThreadProjectPath(options = {}) {
11117
11117
  }
11118
11118
  function resolveProjectPath(value = process.env.CURSOR_PROJECT_PATH, options = {}) {
11119
11119
  const explicit = String(value || "").trim();
11120
- if (explicit) return resolve3(explicit);
11120
+ if (explicit) return resolve4(explicit);
11121
11121
  const persisted = String(options.persistedProjectPath || "").trim();
11122
- if (persisted) return resolve3(normalizeCodexThreadCwd(persisted));
11122
+ if (persisted) return resolve4(normalizeCodexThreadCwd(persisted));
11123
11123
  const threadProjectPath = options.threadProjectPath === void 0 ? resolveCodexThreadProjectPath(options) : options.threadProjectPath;
11124
- if (threadProjectPath) return resolve3(normalizeCodexThreadCwd(threadProjectPath));
11124
+ if (threadProjectPath) return resolve4(normalizeCodexThreadCwd(threadProjectPath));
11125
11125
  const cwd = options.cwd ?? process.cwd();
11126
11126
  if (!cwd || looksLikePluginRuntimePath(cwd)) return null;
11127
- return resolve3(cwd);
11127
+ return resolve4(cwd);
11128
11128
  }
11129
11129
  function cursorFromRegistry(options = {}) {
11130
11130
  const execFileSyncImpl = options.execFileSyncImpl || execFileSync2;
@@ -11189,7 +11189,7 @@ function findCursorExeDetails(options = {}) {
11189
11189
  existsImpl
11190
11190
  });
11191
11191
  if (fromReg) return { path: fromReg, source: "windows_registry", platform };
11192
- const localAppData = env.LOCALAPPDATA || join4(homedir4(), "AppData", "Local");
11192
+ const localAppData = env.LOCALAPPDATA || join5(homedir5(), "AppData", "Local");
11193
11193
  const programFiles = env.ProgramFiles || env.PROGRAMFILES || "C:\\Program Files";
11194
11194
  const programFilesX86 = env["ProgramFiles(x86)"] || env.PROGRAMFILES_X86 || "";
11195
11195
  const candidates = [
@@ -11206,7 +11206,7 @@ function findCursorExeDetails(options = {}) {
11206
11206
  return null;
11207
11207
  }
11208
11208
  if (platform === "darwin") {
11209
- const userHome = env.HOME || homedir4();
11209
+ const userHome = env.HOME || homedir5();
11210
11210
  const candidates = [
11211
11211
  "/Applications/Cursor.app/Contents/MacOS/Cursor",
11212
11212
  userHome && posixPath.join(userHome, "Applications", "Cursor.app", "Contents", "MacOS", "Cursor")
@@ -11225,42 +11225,42 @@ function findCursorExe(options = {}) {
11225
11225
  return findCursorExeDetails(options)?.path || null;
11226
11226
  }
11227
11227
  function cdpUp(timeoutMs = 1500) {
11228
- return new Promise((resolve6) => {
11228
+ return new Promise((resolve7) => {
11229
11229
  const req = http.get({ host: CDP_HOST, port: CDP_PORT, path: "/json/version" }, (res) => {
11230
11230
  res.resume();
11231
- resolve6(res.statusCode === 200);
11231
+ resolve7(res.statusCode === 200);
11232
11232
  });
11233
- req.on("error", () => resolve6(false));
11233
+ req.on("error", () => resolve7(false));
11234
11234
  req.setTimeout(timeoutMs, () => {
11235
11235
  try {
11236
11236
  req.destroy();
11237
11237
  } catch {
11238
11238
  }
11239
- resolve6(false);
11239
+ resolve7(false);
11240
11240
  });
11241
11241
  });
11242
11242
  }
11243
11243
  function cdpIsCursor(timeoutMs = 1500) {
11244
- return new Promise((resolve6) => {
11244
+ return new Promise((resolve7) => {
11245
11245
  const req = http.get({ host: CDP_HOST, port: CDP_PORT, path: "/json/list" }, (res) => {
11246
11246
  let d = "";
11247
11247
  res.on("data", (c) => d += c);
11248
11248
  res.on("end", () => {
11249
11249
  try {
11250
- if (/[\/\\](windsurf)[\/\\]/i.test(d)) return resolve6(false);
11251
- resolve6(/[\/\\]cursor[\/\\](resources|app)|cursor\.exe|vscode-app[^"]*[\/\\]cursor[\/\\]/i.test(d));
11250
+ if (/[\/\\](windsurf)[\/\\]/i.test(d)) return resolve7(false);
11251
+ resolve7(/[\/\\]cursor[\/\\](resources|app)|cursor\.exe|vscode-app[^"]*[\/\\]cursor[\/\\]/i.test(d));
11252
11252
  } catch {
11253
- resolve6(false);
11253
+ resolve7(false);
11254
11254
  }
11255
11255
  });
11256
11256
  });
11257
- req.on("error", () => resolve6(false));
11257
+ req.on("error", () => resolve7(false));
11258
11258
  req.setTimeout(timeoutMs, () => {
11259
11259
  try {
11260
11260
  req.destroy();
11261
11261
  } catch {
11262
11262
  }
11263
- resolve6(false);
11263
+ resolve7(false);
11264
11264
  });
11265
11265
  });
11266
11266
  }
@@ -11300,7 +11300,7 @@ async function ensureCursorRunningLocal(options = {}) {
11300
11300
  const cdpIsCursorImpl = options.cdpIsCursorImpl || cdpIsCursor;
11301
11301
  const cursorRunningImpl = options.cursorRunningImpl || cursorRunning;
11302
11302
  const findCursorExeDetailsImpl = options.findCursorExeDetailsImpl || findCursorExeDetails;
11303
- const projectPath = Object.hasOwn(options, "projectPath") ? options.projectPath ? resolve3(String(options.projectPath)) : null : resolveProjectPath();
11303
+ const projectPath = Object.hasOwn(options, "projectPath") ? options.projectPath ? resolve4(String(options.projectPath)) : null : resolveProjectPath();
11304
11304
  const listCdpPageTargetsImpl = options.listCdpPageTargetsImpl || listCdpPageTargets;
11305
11305
  const spawnImpl = options.spawnImpl || spawn2;
11306
11306
  if (await cdpUpImpl()) {
@@ -11517,10 +11517,10 @@ async function ensureCursorRunningLocal(options = {}) {
11517
11517
  };
11518
11518
  }
11519
11519
  function normalizeProjectKey(projectPath) {
11520
- return projectPath ? resolve3(String(projectPath)).replace(/\\/g, "/").toLowerCase() : "";
11520
+ return projectPath ? resolve4(String(projectPath)).replace(/\\/g, "/").toLowerCase() : "";
11521
11521
  }
11522
11522
  function targetTitleMatchesProject(title, projectPath) {
11523
- const name = basename2(String(projectPath || "")).trim().toLowerCase();
11523
+ const name = basename3(String(projectPath || "")).trim().toLowerCase();
11524
11524
  if (!name) return false;
11525
11525
  const extension2 = extname2(name);
11526
11526
  const candidates = [...new Set([name, extension2 ? name.slice(0, -extension2.length) : name].filter(Boolean))];
@@ -11707,66 +11707,66 @@ import net from "node:net";
11707
11707
  import { createHash as createHash2 } from "node:crypto";
11708
11708
  import {
11709
11709
  existsSync as existsSync4,
11710
- mkdirSync as mkdirSync4,
11711
- readFileSync as readFileSync3,
11710
+ mkdirSync as mkdirSync5,
11711
+ readFileSync as readFileSync4,
11712
11712
  readdirSync,
11713
- renameSync as renameSync3,
11714
- rmSync as rmSync3,
11713
+ renameSync as renameSync4,
11714
+ rmSync as rmSync4,
11715
11715
  unlinkSync,
11716
- writeFileSync as writeFileSync3
11716
+ writeFileSync as writeFileSync4
11717
11717
  } from "node:fs";
11718
11718
  import { fileURLToPath } from "node:url";
11719
- import { dirname as dirname3, join as join5, resolve as resolve4 } from "node:path";
11719
+ import { dirname as dirname4, join as join6, resolve as resolve5 } from "node:path";
11720
11720
  function sleep(ms) {
11721
11721
  return new Promise((r) => setTimeout(r, ms));
11722
11722
  }
11723
11723
  function resolveSupervisorScript() {
11724
11724
  if (process.env.CURSOR_BRIDGE_SUPERVISOR_SCRIPT && existsSync4(process.env.CURSOR_BRIDGE_SUPERVISOR_SCRIPT)) {
11725
- return resolve4(process.env.CURSOR_BRIDGE_SUPERVISOR_SCRIPT);
11725
+ return resolve5(process.env.CURSOR_BRIDGE_SUPERVISOR_SCRIPT);
11726
11726
  }
11727
- const here = dirname3(fileURLToPath(import.meta.url));
11727
+ const here = dirname4(fileURLToPath(import.meta.url));
11728
11728
  const candidates = [];
11729
11729
  if (typeof process.argv[1] === "string") {
11730
- const entryDir = dirname3(resolve4(process.argv[1]));
11731
- candidates.push(join5(entryDir, "dist", "cursor-lifecycle-supervisor.mjs"));
11732
- candidates.push(join5(entryDir, "cursor-lifecycle-supervisor.mjs"));
11730
+ const entryDir = dirname4(resolve5(process.argv[1]));
11731
+ candidates.push(join6(entryDir, "dist", "cursor-lifecycle-supervisor.mjs"));
11732
+ candidates.push(join6(entryDir, "cursor-lifecycle-supervisor.mjs"));
11733
11733
  }
11734
11734
  candidates.push(
11735
- join5(here, "dist", "cursor-lifecycle-supervisor.mjs"),
11736
- join5(here, "cursor-lifecycle-supervisor.mjs")
11735
+ join6(here, "dist", "cursor-lifecycle-supervisor.mjs"),
11736
+ join6(here, "cursor-lifecycle-supervisor.mjs")
11737
11737
  );
11738
11738
  for (const c of candidates) {
11739
11739
  if (existsSync4(c)) return c;
11740
11740
  }
11741
- return join5(here, "cursor-lifecycle-supervisor.mjs");
11741
+ return join6(here, "cursor-lifecycle-supervisor.mjs");
11742
11742
  }
11743
11743
  function writeRuntimeFile(target, content) {
11744
- if (existsSync4(target) && readFileSync3(target).equals(content)) return;
11744
+ if (existsSync4(target) && readFileSync4(target).equals(content)) return;
11745
11745
  const temporary = `${target}.${process.pid}.${Date.now()}.tmp`;
11746
- writeFileSync3(temporary, content);
11746
+ writeFileSync4(temporary, content);
11747
11747
  try {
11748
- renameSync3(temporary, target);
11748
+ renameSync4(temporary, target);
11749
11749
  } catch (error2) {
11750
11750
  if (!existsSync4(target)) {
11751
- rmSync3(temporary, { force: true });
11751
+ rmSync4(temporary, { force: true });
11752
11752
  throw error2;
11753
11753
  }
11754
- if (readFileSync3(target).equals(content)) {
11755
- rmSync3(temporary, { force: true });
11754
+ if (readFileSync4(target).equals(content)) {
11755
+ rmSync4(temporary, { force: true });
11756
11756
  return;
11757
11757
  }
11758
- rmSync3(target, { force: true });
11759
- renameSync3(temporary, target);
11758
+ rmSync4(target, { force: true });
11759
+ renameSync4(temporary, target);
11760
11760
  }
11761
11761
  }
11762
11762
  function materializeLifecycleSupervisorRuntime({ sourceScript, dir = defaultLifecycleDir() } = {}) {
11763
- const source = resolve4(sourceScript || resolveSupervisorScript());
11763
+ const source = resolve5(sourceScript || resolveSupervisorScript());
11764
11764
  if (!existsSync4(source)) throw new Error(`lifecycle supervisor script missing: ${source}`);
11765
- const content = readFileSync3(source);
11765
+ const content = readFileSync4(source);
11766
11766
  const fingerprint = createHash2("sha256").update(content).digest("hex");
11767
- const runtimeRoot = join5(ensureLifecycleDir(dir), "runtime", `supervisor-${fingerprint.slice(0, 20)}`);
11768
- mkdirSync4(runtimeRoot, { recursive: true });
11769
- const script = join5(runtimeRoot, "cursor-lifecycle-supervisor.mjs");
11767
+ const runtimeRoot = join6(ensureLifecycleDir(dir), "runtime", `supervisor-${fingerprint.slice(0, 20)}`);
11768
+ mkdirSync5(runtimeRoot, { recursive: true });
11769
+ const script = join6(runtimeRoot, "cursor-lifecycle-supervisor.mjs");
11770
11770
  writeRuntimeFile(script, content);
11771
11771
  return { sourceScript: source, script, runtimeRoot, fingerprint };
11772
11772
  }
@@ -11781,7 +11781,7 @@ function isProcessAlive(pid) {
11781
11781
  }
11782
11782
  function readPidFile(pidPath) {
11783
11783
  try {
11784
- const n = Number(String(readFileSync3(pidPath, "utf8")).trim());
11784
+ const n = Number(String(readFileSync4(pidPath, "utf8")).trim());
11785
11785
  return Number.isFinite(n) ? n : null;
11786
11786
  } catch {
11787
11787
  return null;
@@ -11874,7 +11874,7 @@ function tryUnlink(path) {
11874
11874
  }
11875
11875
  }
11876
11876
  function writeBootEnv(dir, extra = {}) {
11877
- const bootPath = join5(dir, `boot-env-${process.pid}-${Date.now()}.json`);
11877
+ const bootPath = join6(dir, `boot-env-${process.pid}-${Date.now()}.json`);
11878
11878
  const payload = { ...extra };
11879
11879
  for (const [key, value] of Object.entries(process.env)) {
11880
11880
  if (key.startsWith("CURSOR_BRIDGE_") || key === "CURSOR_PROJECT_PATH" || key === "CURSOR_EXE") {
@@ -11885,7 +11885,7 @@ function writeBootEnv(dir, extra = {}) {
11885
11885
  for (const [k, v] of Object.entries(payload)) {
11886
11886
  if (v != null && v !== "") cleaned[k] = String(v);
11887
11887
  }
11888
- writeFileSync3(bootPath, `${JSON.stringify(cleaned, null, 2)}
11888
+ writeFileSync4(bootPath, `${JSON.stringify(cleaned, null, 2)}
11889
11889
  `, { encoding: "utf8" });
11890
11890
  return bootPath;
11891
11891
  }
@@ -11897,9 +11897,9 @@ async function ensureSupervisorConnected(options = {}) {
11897
11897
  const createWaitMs = Number(options.createWaitMs || DEFAULT_CREATE_WAIT_MS);
11898
11898
  const sourceScript = options.supervisorScript || resolveSupervisorScript();
11899
11899
  const runtime = options.persistSupervisorRuntime === false ? {
11900
- sourceScript: resolve4(sourceScript),
11901
- script: resolve4(sourceScript),
11902
- runtimeRoot: dirname3(resolve4(sourceScript)),
11900
+ sourceScript: resolve5(sourceScript),
11901
+ script: resolve5(sourceScript),
11902
+ runtimeRoot: dirname4(resolve5(sourceScript)),
11903
11903
  fingerprint: null
11904
11904
  } : materializeLifecycleSupervisorRuntime({ sourceScript, dir });
11905
11905
  let socket = await tryConnect(sock);
@@ -19478,7 +19478,7 @@ var Protocol = class {
19478
19478
  return;
19479
19479
  }
19480
19480
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
19481
- await new Promise((resolve6) => setTimeout(resolve6, pollInterval));
19481
+ await new Promise((resolve7) => setTimeout(resolve7, pollInterval));
19482
19482
  options?.signal?.throwIfAborted();
19483
19483
  }
19484
19484
  } catch (error2) {
@@ -19495,7 +19495,7 @@ var Protocol = class {
19495
19495
  */
19496
19496
  request(request2, resultSchema, options) {
19497
19497
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
19498
- return new Promise((resolve6, reject) => {
19498
+ return new Promise((resolve7, reject) => {
19499
19499
  const earlyReject = (error2) => {
19500
19500
  reject(error2);
19501
19501
  };
@@ -19573,7 +19573,7 @@ var Protocol = class {
19573
19573
  if (!parseResult.success) {
19574
19574
  reject(parseResult.error);
19575
19575
  } else {
19576
- resolve6(parseResult.data);
19576
+ resolve7(parseResult.data);
19577
19577
  }
19578
19578
  } catch (error2) {
19579
19579
  reject(error2);
@@ -19834,12 +19834,12 @@ var Protocol = class {
19834
19834
  }
19835
19835
  } catch {
19836
19836
  }
19837
- return new Promise((resolve6, reject) => {
19837
+ return new Promise((resolve7, reject) => {
19838
19838
  if (signal.aborted) {
19839
19839
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
19840
19840
  return;
19841
19841
  }
19842
- const timeoutId = setTimeout(resolve6, interval);
19842
+ const timeoutId = setTimeout(resolve7, interval);
19843
19843
  signal.addEventListener("abort", () => {
19844
19844
  clearTimeout(timeoutId);
19845
19845
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -20709,19 +20709,19 @@ var StdioServerTransport = class {
20709
20709
  this.onclose?.();
20710
20710
  }
20711
20711
  send(message) {
20712
- return new Promise((resolve6) => {
20712
+ return new Promise((resolve7) => {
20713
20713
  const json = serializeMessage(message);
20714
20714
  if (this._stdout.write(json)) {
20715
- resolve6();
20715
+ resolve7();
20716
20716
  } else {
20717
- this._stdout.once("drain", resolve6);
20717
+ this._stdout.once("drain", resolve7);
20718
20718
  }
20719
20719
  });
20720
20720
  }
20721
20721
  };
20722
20722
 
20723
20723
  // server.mjs
20724
- import { basename as basename3, dirname as dirname4, join as join6, resolve as resolve5 } from "node:path";
20724
+ import { basename as basename4, dirname as dirname5, join as join7, resolve as resolve6 } from "node:path";
20725
20725
 
20726
20726
  // node_modules/ws/wrapper.mjs
20727
20727
  var import_stream = __toESM(require_stream(), 1);
@@ -20735,12 +20735,119 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
20735
20735
 
20736
20736
  // server.mjs
20737
20737
  init_cursor_runtime();
20738
+ import http2 from "http";
20739
+ import { pathToFileURL as pathToFileURL2 } from "url";
20740
+
20741
+ // cursor-model-preferences.mjs
20742
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
20743
+ import { homedir as homedir2 } from "node:os";
20744
+ import { basename as basename2, dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
20745
+ var CURSOR_MODEL_TARGETS = Object.freeze(["cce", "cursor_do"]);
20746
+ var CURSOR_MODEL_EFFORTS = Object.freeze(["low", "medium", "high", "xhigh", "max"]);
20747
+ function normalizeCursorModelTarget(value, fallback = "") {
20748
+ const normalized = String(value || "").trim().toLowerCase().replace(/-/g, "_");
20749
+ if (normalized === "context_engine" || normalized === "cursor_context_engine") return "cce";
20750
+ if (normalized === "do" || normalized === "delegate") return "cursor_do";
20751
+ return CURSOR_MODEL_TARGETS.includes(normalized) ? normalized : fallback;
20752
+ }
20753
+ function normalizeCursorModelEffort(value, fallback = "") {
20754
+ const normalized = String(value || "").trim().toLowerCase().replace(/[_\s]+/g, "-");
20755
+ if (normalized === "extra-high" || normalized === "extra-high-thinking") return "xhigh";
20756
+ return CURSOR_MODEL_EFFORTS.includes(normalized) ? normalized : fallback;
20757
+ }
20758
+ function cursorEffortUiValue(value) {
20759
+ const normalized = normalizeCursorModelEffort(value, "");
20760
+ return normalized === "xhigh" ? "extra-high" : normalized;
20761
+ }
20762
+ function normalizeCursorModelPreference(value, options = {}) {
20763
+ if (value == null) return null;
20764
+ const model = String(value.model || "").trim();
20765
+ if (!model) {
20766
+ if (options.allowEmpty) return null;
20767
+ throw new Error("model must not be empty");
20768
+ }
20769
+ if (model.length > 200) throw new Error("model exceeds the 200-character limit");
20770
+ const rawEffort = value.effort == null ? "" : String(value.effort).trim();
20771
+ const effort = rawEffort ? normalizeCursorModelEffort(rawEffort, "") : null;
20772
+ if (rawEffort && !effort) {
20773
+ throw new Error(`unsupported Cursor model effort: ${value.effort}; expected low, medium, high, xhigh, or max`);
20774
+ }
20775
+ return { model, effort };
20776
+ }
20777
+ function resolveCursorModelPreferencesFile(value = process.env.CURSOR_BRIDGE_MODEL_PREFERENCES_FILE) {
20778
+ const configured = String(value || "").trim();
20779
+ if (configured) return resolve2(configured);
20780
+ const configRoot = process.platform === "win32" && process.env.APPDATA ? process.env.APPDATA : process.env.XDG_CONFIG_HOME || join2(homedir2(), ".config");
20781
+ return join2(configRoot, "cursor-bridge", "model-preferences.json");
20782
+ }
20783
+ function emptyPreferences() {
20784
+ return { version: 1, targets: { cce: null, cursor_do: null }, updatedAt: null };
20785
+ }
20786
+ function readCursorModelPreferences(filePath) {
20787
+ const empty = emptyPreferences();
20788
+ if (!filePath) return empty;
20789
+ try {
20790
+ const parsed = JSON.parse(readFileSync2(filePath, "utf8"));
20791
+ const targets = parsed && typeof parsed.targets === "object" ? parsed.targets : {};
20792
+ return {
20793
+ version: 1,
20794
+ targets: {
20795
+ cce: normalizeCursorModelPreference(targets.cce, { allowEmpty: true }),
20796
+ cursor_do: normalizeCursorModelPreference(targets.cursor_do, { allowEmpty: true })
20797
+ },
20798
+ updatedAt: parsed && parsed.updatedAt ? String(parsed.updatedAt) : null
20799
+ };
20800
+ } catch (error2) {
20801
+ if (error2 && error2.code === "ENOENT") return empty;
20802
+ console.error(`[cursor-bridge] ignoring unreadable model preferences file ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`);
20803
+ return empty;
20804
+ }
20805
+ }
20806
+ function writeCursorModelPreferences(filePath, preferences) {
20807
+ if (!filePath) throw new Error("persistent cursor_model storage is disabled for this server");
20808
+ const target = resolve2(filePath);
20809
+ const normalized = {
20810
+ version: 1,
20811
+ targets: {
20812
+ cce: normalizeCursorModelPreference(preferences && preferences.targets && preferences.targets.cce, { allowEmpty: true }),
20813
+ cursor_do: normalizeCursorModelPreference(preferences && preferences.targets && preferences.targets.cursor_do, { allowEmpty: true })
20814
+ },
20815
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
20816
+ };
20817
+ mkdirSync2(dirname2(target), { recursive: true });
20818
+ const temporary = join2(dirname2(target), `.${basename2(target)}.${process.pid}.${Date.now()}.tmp`);
20819
+ try {
20820
+ writeFileSync2(temporary, `${JSON.stringify(normalized, null, 2)}
20821
+ `, { encoding: "utf8", mode: 384 });
20822
+ renameSync2(temporary, target);
20823
+ } catch (error2) {
20824
+ rmSync2(temporary, { force: true });
20825
+ throw new Error(`failed to persist cursor_model at ${target}: ${error2 instanceof Error ? error2.message : String(error2)}`);
20826
+ }
20827
+ return normalized;
20828
+ }
20829
+ function updateCursorModelPreferences(filePath, { action, target, model, effort } = {}) {
20830
+ const normalizedAction = String(action || "show").trim().toLowerCase();
20831
+ if (!["show", "set", "reset"].includes(normalizedAction)) {
20832
+ throw new Error(`unsupported cursor_model action: ${action}; expected show, set, or reset`);
20833
+ }
20834
+ const selectedTargets = String(target || "").trim().toLowerCase() === "both" ? [...CURSOR_MODEL_TARGETS] : [normalizeCursorModelTarget(target, "")].filter(Boolean);
20835
+ if (normalizedAction !== "show" && selectedTargets.length === 0) {
20836
+ throw new Error("cursor_model set/reset requires target=cce, cursor_do, or both");
20837
+ }
20838
+ const current = readCursorModelPreferences(filePath);
20839
+ if (normalizedAction === "show") return current;
20840
+ const next = { ...current, targets: { ...current.targets } };
20841
+ const preference = normalizedAction === "set" ? normalizeCursorModelPreference({ model, effort }) : null;
20842
+ for (const selectedTarget of selectedTargets) next.targets[selectedTarget] = preference;
20843
+ return writeCursorModelPreferences(filePath, next);
20844
+ }
20845
+
20846
+ // server.mjs
20738
20847
  init_workspace_binding();
20739
20848
  init_cursor_ensure_core();
20740
20849
  init_lifecycle_paths();
20741
- import http2 from "http";
20742
- import { pathToFileURL as pathToFileURL2 } from "url";
20743
- var PLUGIN_VERSION = "5.5.0";
20850
+ var PLUGIN_VERSION = "5.6.0";
20744
20851
  var CDP_PORT2 = Number(process.env.CURSOR_BRIDGE_CDP_PORT || 9223);
20745
20852
  var ORIGIN = `http://localhost:${CDP_PORT2}`;
20746
20853
  var QUERY_TIMEOUT = Number(process.env.CURSOR_BRIDGE_TIMEOUT || 3e5);
@@ -20797,13 +20904,13 @@ var DO_DEFAULT_CONTRACT = "\n\nCompletion requirements: Work directly in the wor
20797
20904
  var DO_LANGUAGE_CONTRACT = "\n\nResponse language: Reply in the language of the user task unless it explicitly requests another language. Never translate paths, commands, identifiers, keys, enum values, exact options, or error/status codes.";
20798
20905
  var CDP_HOST2 = "127.0.0.1";
20799
20906
  function httpJson(path) {
20800
- return new Promise((resolve6, reject) => {
20907
+ return new Promise((resolve7, reject) => {
20801
20908
  const req = http2.get({ host: CDP_HOST2, port: CDP_PORT2, path }, (res) => {
20802
20909
  let d = "";
20803
20910
  res.on("data", (c) => d += c);
20804
20911
  res.on("end", () => {
20805
20912
  try {
20806
- resolve6(JSON.parse(d));
20913
+ resolve7(JSON.parse(d));
20807
20914
  } catch {
20808
20915
  reject(new Error("CDP returned a non-JSON response"));
20809
20916
  }
@@ -21185,6 +21292,73 @@ function exprClickBoundComposerStop(agentId) {
21185
21292
  })()`;
21186
21293
  }
21187
21294
  var EXPR_FIND_NEWAGENT = `(function(){const b=[...document.querySelectorAll('button,[role=button],a.action-label,.codicon')].find(e=>{if(e.offsetParent===null||e.closest('.glass-sidebar-agent-menu-btn'))return false;const s=(e.getAttribute('aria-label')||'')+' '+(e.getAttribute('title')||'')+' '+(e.innerText||'');return /(?:^|\\s)New (?:Agent|Chat)(?:\\s|$)/i.test(s);});if(!b)return '';const r=b.getBoundingClientRect();return JSON.stringify({x:Math.round(r.x+r.width/2),y:Math.round(r.y+r.height/2)});})()`;
21295
+ var MODEL_PICKER_VISIBLE_BODY = `
21296
+ const visible=(node)=>!!(node&&(node.offsetParent!==null||(node.getClientRects&&node.getClientRects().length>0)));
21297
+ const composers=[...document.querySelectorAll('.composer-bar[data-composer-id],.composer-bar,.ui-prompt-input-root')].filter(visible);
21298
+ const composer=composers[composers.length-1]||document;
21299
+ `;
21300
+ var EXPR_MODEL_PICKER_TRIGGER = `(function(){
21301
+ ${MODEL_PICKER_VISIBLE_BODY}
21302
+ const triggerSelector='.ui-model-picker__trigger,.vscode-model-picker__trigger';
21303
+ const candidates=[...composer.querySelectorAll(triggerSelector)].filter(visible);
21304
+ const trigger=candidates[candidates.length-1]||[...document.querySelectorAll(triggerSelector)].filter(visible).pop();
21305
+ if(!trigger)return JSON.stringify({found:false,state:'trigger_missing'});
21306
+ const rect=trigger.getBoundingClientRect();
21307
+ const text=String(trigger.querySelector('.ui-model-picker__trigger-text,.vscode-model-picker__trigger-text')?.innerText||trigger.innerText||'').replace(/\\s+/g,' ').trim();
21308
+ const detail=String(trigger.querySelector('.ui-model-picker__trigger-variant-suffix,.vscode-model-picker__trigger-variant-suffix')?.innerText||'').replace(/\\s+/g,' ').trim();
21309
+ return JSON.stringify({found:true,state:'ready',text,detail,x:Math.round(rect.x+rect.width/2),y:Math.round(rect.y+rect.height/2)});
21310
+ })()`;
21311
+ var EXPR_MODEL_PICKER_ROWS = `(function(){
21312
+ ${MODEL_PICKER_VISIBLE_BODY}
21313
+ const menus=[...document.querySelectorAll('[data-testid="model-picker-menu"],[data-testid*="model-parameters"],[data-testid*="parameter-submenu"],[data-component="menu-popup"][data-submenu]')].filter(visible);
21314
+ const rows=[];
21315
+ const seen=new Set();
21316
+ for(const menu of menus){
21317
+ for(const row of menu.querySelectorAll('[data-component="menu-row"],[data-component="menu-submenu-trigger"],[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]')){
21318
+ if(!visible(row)||seen.has(row))continue;
21319
+ seen.add(row);
21320
+ const rect=row.getBoundingClientRect();
21321
+ const text=String(row.innerText||row.textContent||'').replace(/\\s+/g,' ').trim();
21322
+ if(!text)continue;
21323
+ const menuTestId=String(menu.getAttribute('data-testid')||'').toLowerCase();
21324
+ let kind='control';
21325
+ if(row.querySelector('.ui-model-picker__item-content-name,.vscode-model-picker__item-content-name'))kind='model';
21326
+ else if(/^model(?:\\s|$)/i.test(text)&&row.getAttribute('aria-haspopup')==='menu')kind='model_control';
21327
+ else if(/^effort(?:\\s|$)/i.test(text)&&row.getAttribute('aria-haspopup')==='menu')kind='effort_control';
21328
+ else if(menuTestId.includes('parameter-submenu')||row.closest('[data-submenu]'))kind='parameter';
21329
+ else if(menuTestId.includes('model-picker-menu')||menuTestId.includes('model-selection'))kind='model';
21330
+ rows.push({
21331
+ text,
21332
+ kind,
21333
+ selected:row.getAttribute('data-selected')==='true'||row.getAttribute('aria-checked')==='true'||!!row.querySelector('.ui-model-picker__item-check,.ui-model-picker__param-check'),
21334
+ disabled:row.getAttribute('data-disabled')==='true'||row.getAttribute('aria-disabled')==='true',
21335
+ hasSubmenu:row.getAttribute('aria-haspopup')==='menu',
21336
+ submenu:!!row.closest('[data-submenu]'),
21337
+ x:Math.round(rect.x+rect.width/2),
21338
+ y:Math.round(rect.y+rect.height/2),
21339
+ });
21340
+ }
21341
+ }
21342
+ return JSON.stringify({open:menus.length>0,rows});
21343
+ })()`;
21344
+ function normalizeModelPickerText(value) {
21345
+ return String(value || "").trim().toLowerCase().replace(/extra[\s_-]*high/g, "xhigh").replace(/[^a-z0-9]+/g, "");
21346
+ }
21347
+ function selectModelPickerRow(rows, requested, kind = "model") {
21348
+ const wanted = normalizeModelPickerText(requested);
21349
+ if (!wanted) return null;
21350
+ const candidates = (Array.isArray(rows) ? rows : []).filter((row) => row && row.disabled !== true && (kind === "any" || row.kind === kind)).map((row) => {
21351
+ const normalized = normalizeModelPickerText(row.text);
21352
+ let score = normalized === wanted ? 1e3 : 0;
21353
+ if (!score && normalized.startsWith(wanted)) score = 800;
21354
+ if (!score && wanted.startsWith(normalized)) score = 700;
21355
+ if (!score && normalized.includes(wanted)) score = 600;
21356
+ return { row, score, distance: Math.abs(normalized.length - wanted.length) };
21357
+ }).filter((entry) => entry.score > 0).sort((a, b) => b.score - a.score || a.distance - b.distance);
21358
+ if (candidates.length === 0) return null;
21359
+ if (candidates.length > 1 && candidates[0].score === candidates[1].score && candidates[0].distance === candidates[1].distance) return null;
21360
+ return candidates[0].row;
21361
+ }
21188
21362
  var WORKSPACE_SECTION_BODY = `
21189
21363
  const headText=(el)=>String(el&&(el.innerText||el.textContent)||'').trim();
21190
21364
  const isNewAgentButton=(node)=>{
@@ -21228,7 +21402,7 @@ var WORKSPACE_SECTION_BODY = `
21228
21402
  };
21229
21403
  `;
21230
21404
  function exprCreateAgentForWorkspace(projectPath) {
21231
- const workspaceLabel = JSON.stringify(basename3(String(projectPath || "")).trim().toLowerCase());
21405
+ const workspaceLabel = JSON.stringify(basename4(String(projectPath || "")).trim().toLowerCase());
21232
21406
  return `(function(){
21233
21407
  ${WORKSPACE_SECTION_BODY}
21234
21408
  const wanted=${workspaceLabel};
@@ -21244,7 +21418,7 @@ function exprCreateAgentForWorkspace(projectPath) {
21244
21418
  })()`;
21245
21419
  }
21246
21420
  function exprInspectWorkspaceRepository(projectPath) {
21247
- const workspaceLabel = JSON.stringify(basename3(String(projectPath || "")).trim().toLowerCase());
21421
+ const workspaceLabel = JSON.stringify(basename4(String(projectPath || "")).trim().toLowerCase());
21248
21422
  return `(function(){
21249
21423
  ${WORKSPACE_SECTION_BODY}
21250
21424
  const wanted=${workspaceLabel};
@@ -21314,6 +21488,8 @@ var REACT_ADAPTER_BODY = `
21314
21488
  };
21315
21489
  const findV2Props=()=>{
21316
21490
  const found=[]; const seen=new Set();
21491
+ let globalSelectAgent=null;
21492
+ let sectionIdByAgentId=null;
21317
21493
  for(const root of document.querySelectorAll('.glass-sidebar-agent-list-container')){
21318
21494
  const nodes=[]; let n=root;
21319
21495
  for(let i=0;n&&i<24;i++,n=n.parentElement)nodes.push(n);
@@ -21324,6 +21500,8 @@ var REACT_ADAPTER_BODY = `
21324
21500
  let f=key.startsWith('__reactFiber$')?seed:{memoizedProps:seed,return:null};
21325
21501
  for(let j=0;f&&j<80;j++,f=f.return){
21326
21502
  for(const p of [f.memoizedProps,f.pendingProps,f.stateNode&&f.stateNode.props]){
21503
+ if(p&&typeof p.onSelectAgent==='function'&&!globalSelectAgent)globalSelectAgent=p.onSelectAgent;
21504
+ if(p&&p.sectionIdByAgentId&&!sectionIdByAgentId)sectionIdByAgentId=p.sectionIdByAgentId;
21327
21505
  const selectAgent=p&&(typeof p.onSelectAgent==='function'
21328
21506
  ?p.onSelectAgent
21329
21507
  :(p.rowHandlers&&typeof p.rowHandlers.onSelect==='function'?p.rowHandlers.onSelect:null));
@@ -21339,6 +21517,8 @@ var REACT_ADAPTER_BODY = `
21339
21517
  }
21340
21518
  }
21341
21519
  }
21520
+ found.globalSelectAgent=globalSelectAgent;
21521
+ found.sectionIdByAgentId=sectionIdByAgentId;
21342
21522
  return found;
21343
21523
  };
21344
21524
  const findAdapter=()=>{
@@ -21368,10 +21548,28 @@ var REACT_ADAPTER_BODY = `
21368
21548
  else if(/needs_attention/.test(status))icon='needs-attention';
21369
21549
  else if(/failed|error/.test(status))icon='warning';
21370
21550
  else if(/cancel/.test(status))icon='circle-slash';
21551
+ seen.add(selectedId);
21371
21552
  entries.push({
21372
21553
  id:selectedId,label:'',searchText:'',timestamp:0,isSelected:true,
21373
21554
  showSpinner:/in_progress|running|generating/.test(status),icon,
21374
- workspaceId:'',workspaceLabel:'',durable:false
21555
+ workspaceId:String(v2.sectionIdByAgentId instanceof Map?v2.sectionIdByAgentId.get(selectedRaw)||'':v2.sectionIdByAgentId&&readScalar(v2.sectionIdByAgentId[selectedRaw])||''),
21556
+ workspaceLabel:'',durable:!!(v2.sectionIdByAgentId&&(v2.sectionIdByAgentId instanceof Map?v2.sectionIdByAgentId.has(selectedRaw):v2.sectionIdByAgentId[selectedRaw]!==undefined)),
21557
+ registeredBySectionMap:true
21558
+ });
21559
+ }
21560
+ }
21561
+ if(v2.sectionIdByAgentId){
21562
+ const registered=v2.sectionIdByAgentId instanceof Map?[...v2.sectionIdByAgentId.entries()]:Object.entries(v2.sectionIdByAgentId);
21563
+ for(const pair of registered){
21564
+ const raw=String(pair&&pair[0]||'').replace(/^local:/,'');
21565
+ if(!raw)continue;
21566
+ const id='local:'+raw;
21567
+ if(seen.has(id))continue;
21568
+ seen.add(id);
21569
+ entries.push({
21570
+ id,label:'',searchText:'',timestamp:0,isSelected:id===selectedId,
21571
+ showSpinner:false,icon:'registered',workspaceId:String(readScalar(pair[1])||''),workspaceLabel:'',
21572
+ durable:true,registeredBySectionMap:true
21375
21573
  });
21376
21574
  }
21377
21575
  }
@@ -21384,6 +21582,8 @@ var REACT_ADAPTER_BODY = `
21384
21582
  const header=p.section.headers.find(h=>String(readScalar(h&&h.id)||'')===raw);
21385
21583
  if(header){p.onSelectAgent(header);return true;}
21386
21584
  }
21585
+ const registered=v2.sectionIdByAgentId&&(v2.sectionIdByAgentId instanceof Map?v2.sectionIdByAgentId.has(raw):v2.sectionIdByAgentId[raw]!==undefined);
21586
+ if(registered&&typeof v2.globalSelectAgent==='function'){v2.globalSelectAgent(raw);return true;}
21387
21587
  return false;
21388
21588
  }
21389
21589
  };
@@ -21481,6 +21681,13 @@ function classifyParallelTerminalIcon(icon) {
21481
21681
  function isDurablyRegisteredParallelEntry(entry) {
21482
21682
  return !!entry && entry.durable !== false && (entry.showSpinner || classifyParallelTerminalIcon(entry.icon) !== "unknown");
21483
21683
  }
21684
+ function selectPromotedFifoEntry(beforeEntries, currentAgentId, afterEntries) {
21685
+ if (!Array.isArray(beforeEntries) || !Array.isArray(afterEntries)) return null;
21686
+ if (currentAgentId && afterEntries.some((entry) => entry && entry.id === currentAgentId)) return null;
21687
+ const candidate = selectNewAgentEntry(beforeEntries, afterEntries);
21688
+ if (!candidate || candidate.id === currentAgentId || candidate.isSelected !== true) return null;
21689
+ return isDurablyRegisteredParallelEntry(candidate) ? candidate : null;
21690
+ }
21484
21691
  function uncertainSubmissionReservationScope(job, error2) {
21485
21692
  if (error2 && error2.requiresGlobalReservation) return "global";
21486
21693
  return job && job.readOnly ? "agent" : "paths";
@@ -21527,10 +21734,10 @@ function releaseAdapterWorkingDirectory({ targetDir = defaultLifecycleDir(), chd
21527
21734
  }
21528
21735
  var CursorBridge = class {
21529
21736
  constructor(options = {}) {
21530
- this.adapterStartCwd = resolve5(options.adapterStartCwd || process.cwd());
21737
+ this.adapterStartCwd = resolve6(options.adapterStartCwd || process.cwd());
21531
21738
  this.environmentDelegationMode = normalizeDelegationMode(options.delegationMode || DELEGATION_MODE);
21532
21739
  this._syncDelegationState();
21533
- this.runtimeFile = options.runtimeFile === null ? null : resolve5(options.runtimeFile || resolveCursorRuntimeFile());
21740
+ this.runtimeFile = options.runtimeFile === null ? null : resolve6(options.runtimeFile || resolveCursorRuntimeFile());
21534
21741
  this.runtimeModeDefault = normalizeCursorRuntimeMode(
21535
21742
  options.runtimeModeDefault || process.env.CURSOR_BRIDGE_RUNTIME_MODE,
21536
21743
  "normal"
@@ -21541,12 +21748,14 @@ var CursorBridge = class {
21541
21748
  this.runtimeMode = normalizeCursorRuntimeMode(requestedRuntimeMode);
21542
21749
  this.runtimeModeSource = options.runtimeMode !== void 0 ? "constructor" : persistedRuntimeMode ? "persistent" : process.env.CURSOR_BRIDGE_RUNTIME_MODE ? "environment" : "default";
21543
21750
  this.runtimeModeScope = persistedRuntimeMode ? "persistent" : options.runtimeMode !== void 0 ? "constructor" : process.env.CURSOR_BRIDGE_RUNTIME_MODE ? "environment" : "default";
21544
- this.workspaceFile = options.workspaceFile === null ? null : resolve5(options.workspaceFile || resolveWorkspaceBindingFile());
21751
+ this.workspaceFile = options.workspaceFile === null ? null : resolve6(options.workspaceFile || resolveWorkspaceBindingFile());
21545
21752
  this.workspaceKey = options.workspaceKey || resolveWorkspaceBindingKey();
21546
21753
  const persistedWorkspace = options.projectPath === void 0 ? readWorkspaceBinding(this.workspaceFile, this.workspaceKey) : null;
21547
- this.projectPath = options.projectPath !== void 0 ? resolve5(String(options.projectPath)) : persistedWorkspace && persistedWorkspace.projectPath || null;
21754
+ this.projectPath = options.projectPath !== void 0 ? resolve6(String(options.projectPath)) : persistedWorkspace && persistedWorkspace.projectPath || null;
21548
21755
  this.workspaceSource = options.projectPath !== void 0 ? "constructor" : persistedWorkspace ? "persistent_init" : "auto_detect";
21549
21756
  this.workspaceUpdatedAt = persistedWorkspace && persistedWorkspace.updatedAt || null;
21757
+ this.modelPreferencesFile = options.modelPreferencesFile === null ? null : resolve6(options.modelPreferencesFile || resolveCursorModelPreferencesFile());
21758
+ this.modelPreferences = readCursorModelPreferences(this.modelPreferencesFile);
21550
21759
  this._lastPresentation = null;
21551
21760
  this.busy = false;
21552
21761
  this.queue = [];
@@ -21654,6 +21863,36 @@ var CursorBridge = class {
21654
21863
  environmentLockedOff: this.environmentDelegationMode === "off"
21655
21864
  };
21656
21865
  }
21866
+ _refreshModelPreferences() {
21867
+ if (!this.modelPreferencesFile) return false;
21868
+ const next = readCursorModelPreferences(this.modelPreferencesFile);
21869
+ const changed = JSON.stringify(next) !== JSON.stringify(this.modelPreferences);
21870
+ this.modelPreferences = next;
21871
+ return changed;
21872
+ }
21873
+ modelPreferencesView() {
21874
+ this._refreshModelPreferences();
21875
+ return {
21876
+ modelPreferencesFile: this.modelPreferencesFile,
21877
+ modelPreferencesPersistAcrossRestart: !!this.modelPreferencesFile,
21878
+ modelPreferenceTargets: [...CURSOR_MODEL_TARGETS],
21879
+ availableEfforts: [...CURSOR_MODEL_EFFORTS],
21880
+ modelPreferences: {
21881
+ cce: this.modelPreferences.targets.cce,
21882
+ cursor_do: this.modelPreferences.targets.cursor_do
21883
+ },
21884
+ modelPreferencesUpdatedAt: this.modelPreferences.updatedAt
21885
+ };
21886
+ }
21887
+ configureModelPreferences(options = {}) {
21888
+ this.modelPreferences = updateCursorModelPreferences(this.modelPreferencesFile, options);
21889
+ return this.modelPreferencesView();
21890
+ }
21891
+ _modelPreferenceFor(target) {
21892
+ this._refreshModelPreferences();
21893
+ const preference = this.modelPreferences.targets[target];
21894
+ return preference ? { ...preference } : null;
21895
+ }
21657
21896
  _refreshPersistedRuntimeMode() {
21658
21897
  if (!this.runtimeFile || this.runtimeModeScope === "session" || this.runtimeModeScope === "constructor") {
21659
21898
  return false;
@@ -21750,7 +21989,8 @@ var CursorBridge = class {
21750
21989
  newChat: true,
21751
21990
  execution: "fifo",
21752
21991
  readOnly: true,
21753
- allowedPaths: []
21992
+ allowedPaths: [],
21993
+ modelPreference: this._modelPreferenceFor("cce")
21754
21994
  });
21755
21995
  return normalizeCceSearchResult(await job.promise);
21756
21996
  }
@@ -21802,7 +22042,8 @@ var CursorBridge = class {
21802
22042
  execution,
21803
22043
  readOnly,
21804
22044
  allowedPaths,
21805
- preferLegacyUi: options.preferLegacyUi === true
22045
+ preferLegacyUi: options.preferLegacyUi === true,
22046
+ modelPreference: this._modelPreferenceFor("cursor_do")
21806
22047
  });
21807
22048
  if (options.background !== false) return this._taskView(job);
21808
22049
  await job.promise;
@@ -21835,8 +22076,8 @@ var CursorBridge = class {
21835
22076
  const id = `cursor-${Date.now().toString(36)}-${this.nextTaskId++}`;
21836
22077
  let resolvePromise;
21837
22078
  let rejectPromise;
21838
- const promise = new Promise((resolve6, reject) => {
21839
- resolvePromise = resolve6;
22079
+ const promise = new Promise((resolve7, reject) => {
22080
+ resolvePromise = resolve7;
21840
22081
  rejectPromise = reject;
21841
22082
  });
21842
22083
  promise.catch(() => {
@@ -21852,6 +22093,8 @@ var CursorBridge = class {
21852
22093
  effectiveExecution: options.execution || "fifo",
21853
22094
  readOnly: options.readOnly === true,
21854
22095
  allowedPaths: options.allowedPaths || [],
22096
+ modelPreference: options.modelPreference ? { ...options.modelPreference } : null,
22097
+ modelSelection: options.modelPreference ? { configured: true, applied: false, ...options.modelPreference } : null,
21855
22098
  projectPath: options.projectPath || this._lastLifecycle && this._lastLifecycle.projectPath || this.projectPath || null,
21856
22099
  status: "queued",
21857
22100
  phase: "queued",
@@ -22202,6 +22445,8 @@ var CursorBridge = class {
22202
22445
  await this._bindFifoAgentAfterComposerReady(c, options, historyBefore);
22203
22446
  await this._bindFifoComposerIdentity(c, options);
22204
22447
  this._throwIfCancelledBeforeSend(options);
22448
+ await this._applyModelPreference(c, options.modelPreference, options);
22449
+ this._throwIfCancelledBeforeSend(options);
22205
22450
  const filled = await evalJS(c, exprFill(prompt));
22206
22451
  if (filled === "NO_INPUT" || filled === "EXEC_FAIL") throw new Error("Failed to enter the query because the input state was invalid");
22207
22452
  await sleep2(450);
@@ -22218,10 +22463,8 @@ var CursorBridge = class {
22218
22463
  await this._confirmSubmission(c, baseline.messageCount || 0, providerErrorBaseline);
22219
22464
  options.sendState = "sent";
22220
22465
  options.sentAt = options.sentAt || (/* @__PURE__ */ new Date()).toISOString();
22221
- if (!options.agentId) {
22222
- await this._bindFifoAgentAfterSend(c, options, historyBefore, providerErrorBaseline);
22223
- await this._bindFifoComposerIdentity(c, options);
22224
- }
22466
+ await this._bindFifoAgentAfterSend(c, options, historyBefore, providerErrorBaseline);
22467
+ await this._bindFifoComposerIdentity(c, options);
22225
22468
  return await this._waitComplete(
22226
22469
  c,
22227
22470
  options.timeoutMs || QUERY_TIMEOUT,
@@ -22250,6 +22493,176 @@ var CursorBridge = class {
22250
22493
  error2.preSend = true;
22251
22494
  throw error2;
22252
22495
  }
22496
+ async _readModelPickerTrigger(c) {
22497
+ try {
22498
+ return JSON.parse(await evalJS(c, EXPR_MODEL_PICKER_TRIGGER) || "{}");
22499
+ } catch {
22500
+ return { found: false, state: "trigger_unreadable" };
22501
+ }
22502
+ }
22503
+ async _readModelPickerRows(c) {
22504
+ try {
22505
+ const snapshot = JSON.parse(await evalJS(c, EXPR_MODEL_PICKER_ROWS) || "{}");
22506
+ return { open: snapshot.open === true, rows: Array.isArray(snapshot.rows) ? snapshot.rows : [] };
22507
+ } catch {
22508
+ return { open: false, rows: [] };
22509
+ }
22510
+ }
22511
+ async _clickModelPickerPoint(c, point) {
22512
+ if (!point || !Number.isFinite(Number(point.x)) || !Number.isFinite(Number(point.y))) {
22513
+ throw new Error("Cursor model picker returned an invalid target");
22514
+ }
22515
+ const x = Number(point.x);
22516
+ const y = Number(point.y);
22517
+ await c.send("Input.dispatchMouseEvent", { type: "mousePressed", x, y, button: "left", clickCount: 1 });
22518
+ await c.send("Input.dispatchMouseEvent", { type: "mouseReleased", x, y, button: "left", clickCount: 1 });
22519
+ }
22520
+ async _hoverModelPickerPoint(c, point) {
22521
+ if (!point || !Number.isFinite(Number(point.x)) || !Number.isFinite(Number(point.y))) return;
22522
+ await c.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: Number(point.x), y: Number(point.y) });
22523
+ }
22524
+ async _openModelPicker(c) {
22525
+ const trigger = await this._readModelPickerTrigger(c);
22526
+ if (!trigger.found) {
22527
+ throw new Error("Cursor model picker is unavailable in the active Agent composer");
22528
+ }
22529
+ let snapshot = await this._readModelPickerRows(c);
22530
+ if (!snapshot.open) {
22531
+ await this._clickModelPickerPoint(c, trigger);
22532
+ await sleep2(450);
22533
+ snapshot = await this._readModelPickerRows(c);
22534
+ }
22535
+ if (!snapshot.open) throw new Error("Cursor model picker did not open");
22536
+ return { trigger, ...snapshot };
22537
+ }
22538
+ async _closeModelPicker(c) {
22539
+ for (let attempt = 0; attempt < 3; attempt++) {
22540
+ const snapshot = await this._readModelPickerRows(c);
22541
+ if (!snapshot.open) return;
22542
+ await c.send("Input.dispatchKeyEvent", { type: "keyDown", key: "Escape", code: "Escape", windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });
22543
+ await c.send("Input.dispatchKeyEvent", { type: "keyUp", key: "Escape", code: "Escape", windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });
22544
+ await sleep2(150);
22545
+ }
22546
+ if ((await this._readModelPickerRows(c)).open) throw new Error("Cursor model picker did not close after selection");
22547
+ }
22548
+ async _openModelPickerControl(c, snapshot, controlKind) {
22549
+ const control = (snapshot && snapshot.rows || []).find((row) => row.kind === controlKind && row.disabled !== true);
22550
+ if (!control) return snapshot;
22551
+ await this._clickModelPickerPoint(c, control);
22552
+ await sleep2(400);
22553
+ let next = await this._readModelPickerRows(c);
22554
+ const expectedKind = controlKind === "model_control" ? "model" : "parameter";
22555
+ if (!next.rows.some((row) => row.kind === expectedKind)) {
22556
+ await this._hoverModelPickerPoint(c, control);
22557
+ await sleep2(350);
22558
+ next = await this._readModelPickerRows(c);
22559
+ }
22560
+ return next;
22561
+ }
22562
+ async _findModelPickerModel(c, snapshot, requestedModel) {
22563
+ let modelRow = selectModelPickerRow(snapshot && snapshot.rows, requestedModel, "model");
22564
+ if (modelRow) return { snapshot, modelRow };
22565
+ const expanded = await this._openModelPickerControl(c, snapshot, "model_control");
22566
+ modelRow = selectModelPickerRow(expanded && expanded.rows, requestedModel, "model");
22567
+ return { snapshot: expanded, modelRow };
22568
+ }
22569
+ async _selectedEffortRow(c, modelRow, effort) {
22570
+ let snapshot = await this._readModelPickerRows(c);
22571
+ let effortRow = selectModelPickerRow(snapshot.rows, cursorEffortUiValue(effort), "parameter");
22572
+ if (!effortRow) {
22573
+ snapshot = await this._openModelPickerControl(c, snapshot, "effort_control");
22574
+ effortRow = selectModelPickerRow(snapshot.rows, cursorEffortUiValue(effort), "parameter");
22575
+ }
22576
+ if (effortRow) return effortRow;
22577
+ await this._hoverModelPickerPoint(c, modelRow);
22578
+ await sleep2(400);
22579
+ snapshot = await this._readModelPickerRows(c);
22580
+ effortRow = selectModelPickerRow(snapshot.rows, cursorEffortUiValue(effort), "parameter");
22581
+ if (!effortRow && modelRow && modelRow.hasSubmenu) {
22582
+ await this._clickModelPickerPoint(c, modelRow);
22583
+ await sleep2(350);
22584
+ snapshot = await this._readModelPickerRows(c);
22585
+ effortRow = selectModelPickerRow(snapshot.rows, cursorEffortUiValue(effort), "parameter");
22586
+ }
22587
+ return effortRow;
22588
+ }
22589
+ async _applyModelPreference(c, preference, job) {
22590
+ if (!preference) {
22591
+ if (job) job.modelSelection = null;
22592
+ return null;
22593
+ }
22594
+ const requestedModel = String(preference.model || "").trim();
22595
+ const requestedEffort = preference.effort ? normalizeCursorModelEffort(preference.effort, "") : null;
22596
+ const opened = await this._openModelPicker(c);
22597
+ let located = await this._findModelPickerModel(c, opened, requestedModel);
22598
+ let modelRow = located.modelRow;
22599
+ if (!modelRow) {
22600
+ throw new Error(`Configured Cursor model is unavailable or ambiguous: ${requestedModel}`);
22601
+ }
22602
+ let selectedEffortRow = null;
22603
+ if (requestedEffort && modelRow.hasSubmenu) {
22604
+ selectedEffortRow = await this._selectedEffortRow(c, modelRow, requestedEffort);
22605
+ if (!selectedEffortRow) {
22606
+ throw new Error(`Cursor model ${requestedModel} does not expose effort ${requestedEffort}`);
22607
+ }
22608
+ if (!selectedEffortRow.selected || !modelRow.selected) {
22609
+ await this._clickModelPickerPoint(c, selectedEffortRow);
22610
+ await sleep2(550);
22611
+ }
22612
+ } else if (!modelRow.selected) {
22613
+ await this._clickModelPickerPoint(c, modelRow);
22614
+ await sleep2(550);
22615
+ }
22616
+ let trigger = await this._readModelPickerTrigger(c);
22617
+ if (!trigger.found || !normalizeModelPickerText(trigger.text).includes(normalizeModelPickerText(requestedModel))) {
22618
+ const reopened = await this._openModelPicker(c);
22619
+ located = await this._findModelPickerModel(c, reopened, requestedModel);
22620
+ const selected = selectModelPickerRow(located.snapshot.rows.filter((row) => row.selected), requestedModel, "model");
22621
+ if (!selected) throw new Error(`Cursor did not confirm configured model ${requestedModel}`);
22622
+ modelRow = selected;
22623
+ }
22624
+ let effectiveEffort = null;
22625
+ if (requestedEffort) {
22626
+ const reopened = await this._openModelPicker(c);
22627
+ located = await this._findModelPickerModel(c, reopened, requestedModel);
22628
+ modelRow = located.modelRow;
22629
+ if (!modelRow) throw new Error(`Cursor model row disappeared while applying effort: ${requestedModel}`);
22630
+ let effortRow = await this._selectedEffortRow(c, modelRow, requestedEffort);
22631
+ if (!effortRow) {
22632
+ throw new Error(`Cursor model ${requestedModel} does not expose effort ${requestedEffort}`);
22633
+ }
22634
+ if (!effortRow.selected) {
22635
+ await this._clickModelPickerPoint(c, effortRow);
22636
+ await sleep2(450);
22637
+ }
22638
+ trigger = await this._readModelPickerTrigger(c);
22639
+ const detailMatches = normalizeModelPickerText(`${trigger.detail || ""} ${trigger.text || ""}`).includes(normalizeModelPickerText(requestedEffort));
22640
+ if (!detailMatches) {
22641
+ const verify = await this._openModelPicker(c);
22642
+ const verifiedModel = await this._findModelPickerModel(c, verify, requestedModel);
22643
+ const selectedModel = verifiedModel.modelRow;
22644
+ effortRow = await this._selectedEffortRow(c, selectedModel, requestedEffort);
22645
+ if (!effortRow || !effortRow.selected) {
22646
+ throw new Error(`Cursor did not confirm effort ${requestedEffort} for model ${requestedModel}`);
22647
+ }
22648
+ }
22649
+ effectiveEffort = requestedEffort;
22650
+ }
22651
+ await this._closeModelPicker(c);
22652
+ trigger = await this._readModelPickerTrigger(c);
22653
+ const result = {
22654
+ configured: true,
22655
+ applied: true,
22656
+ requestedModel,
22657
+ requestedEffort,
22658
+ effectiveModel: trigger.text || modelRow.text,
22659
+ effectiveEffort,
22660
+ pickerDetail: trigger.detail || null,
22661
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
22662
+ };
22663
+ if (job) job.modelSelection = result;
22664
+ return result;
22665
+ }
22253
22666
  async _ensureChatPanel(c) {
22254
22667
  let vis = await evalJS(c, EXPR_VISIBLE);
22255
22668
  if (!vis) {
@@ -22272,7 +22685,7 @@ var CursorBridge = class {
22272
22685
  const created = JSON.parse(await evalJS(c, exprCreateAgentForWorkspace(options.projectPath)) || "{}");
22273
22686
  if (!created.ok) {
22274
22687
  const available = Array.isArray(created.available) ? `; available=${created.available.join(", ")}` : "";
22275
- throw new Error(`Cursor Agents workspace binding failed: ${created.state || "unknown"}; wanted=${created.wanted || basename3(options.projectPath)}${available}`);
22688
+ throw new Error(`Cursor Agents workspace binding failed: ${created.state || "unknown"}; wanted=${created.wanted || basename4(options.projectPath)}${available}`);
22276
22689
  }
22277
22690
  await sleep2(1100);
22278
22691
  return true;
@@ -22383,12 +22796,31 @@ var CursorBridge = class {
22383
22796
  }
22384
22797
  }
22385
22798
  async _bindFifoAgentAfterSend(c, job, beforeEntries, providerErrorBaseline) {
22386
- if (!this._canBindFifoHistory(job) || !Array.isArray(beforeEntries) || job.agentId) return;
22387
- for (let i = 0; i < 24 && !job.agentId; i++) {
22799
+ if (!this._canBindFifoHistory(job) || !Array.isArray(beforeEntries)) return;
22800
+ for (let i = 0; i < 24; i++) {
22388
22801
  await sleep2(350);
22389
22802
  await this._throwIfNewProviderError(c, providerErrorBaseline);
22390
- const candidate = await this._resolveNewAgent(c, beforeEntries, { requireActive: true });
22391
- if (candidate) this._applyAgentIdentity(job, candidate);
22803
+ let entries = null;
22804
+ try {
22805
+ entries = await this._readAgentEntries(c);
22806
+ } catch {
22807
+ }
22808
+ if (!Array.isArray(entries)) continue;
22809
+ const promoted = selectPromotedFifoEntry(beforeEntries, job.agentId, entries);
22810
+ if (promoted) {
22811
+ job.provisionalAgentId = job.agentId || null;
22812
+ this._applyAgentIdentity(job, promoted);
22813
+ return;
22814
+ }
22815
+ const current = job.agentId ? entries.find((entry) => entry && entry.id === job.agentId) : null;
22816
+ if (current && isDurablyRegisteredParallelEntry(current)) return;
22817
+ if (!job.agentId) {
22818
+ const candidate = selectNewAgentEntry(beforeEntries, entries);
22819
+ if (candidate && isDurablyRegisteredParallelEntry(candidate)) {
22820
+ this._applyAgentIdentity(job, candidate);
22821
+ return;
22822
+ }
22823
+ }
22392
22824
  }
22393
22825
  }
22394
22826
  async _confirmSubmission(c, baselineCount = 0, providerErrorBaseline = "") {
@@ -22481,6 +22913,8 @@ var CursorBridge = class {
22481
22913
  await this._closeHistory(c);
22482
22914
  await this._ensureChatPanel(c);
22483
22915
  this._throwIfCancelledBeforeSend(job);
22916
+ await this._applyModelPreference(c, job.modelPreference, job);
22917
+ this._throwIfCancelledBeforeSend(job);
22484
22918
  const filled = await evalJS(c, exprFill(job.prompt));
22485
22919
  if (filled === "NO_INPUT" || filled === "EXEC_FAIL") throw new Error("Failed to enter the parallel_agent task");
22486
22920
  await sleep2(350);
@@ -22537,8 +22971,25 @@ var CursorBridge = class {
22537
22971
  const c = makeClient(page.webSocketDebuggerUrl);
22538
22972
  await c.ready;
22539
22973
  try {
22540
- const entries = await this._readAgentEntries(c);
22541
- return entries.find((e) => e.id === job.agentId) || null;
22974
+ let entries = await this._readAgentEntries(c);
22975
+ let entry = entries.find((e) => e.id === job.agentId) || null;
22976
+ if (!entry && (job.execution === "fifo" || job.effectiveExecution === "fifo")) {
22977
+ const promoted = selectPromotedFifoEntry(job.historyBeforeEntries, job.agentId, entries);
22978
+ if (promoted) {
22979
+ job.provisionalAgentId = job.agentId || null;
22980
+ this._applyAgentIdentity(job, promoted);
22981
+ entry = promoted;
22982
+ }
22983
+ }
22984
+ if (entry && entry.registeredBySectionMap && classifyParallelTerminalIcon(entry.icon) === "unknown") {
22985
+ const opened = await evalJS(c, exprOpenAgent(job.agentId));
22986
+ if (opened === "OPENED") {
22987
+ await sleep2(350);
22988
+ entries = await this._readAgentEntries(c);
22989
+ entry = entries.find((e) => e.id === job.agentId) || entry;
22990
+ }
22991
+ }
22992
+ return entry;
22542
22993
  } finally {
22543
22994
  c.close();
22544
22995
  }
@@ -23287,8 +23738,11 @@ var CursorBridge = class {
23287
23738
  effectiveExecution: job.effectiveExecution,
23288
23739
  readOnly: job.readOnly,
23289
23740
  allowedPaths: job.allowedPaths,
23741
+ modelPreference: job.modelPreference,
23742
+ modelSelection: job.modelSelection,
23290
23743
  projectPath: job.projectPath,
23291
23744
  agentId: job.agentId,
23745
+ provisionalAgentId: job.provisionalAgentId || null,
23292
23746
  agentLabel: job.agentLabel,
23293
23747
  targetId: job.targetId,
23294
23748
  targetUiFlavor: job.targetUiFlavor,
@@ -23335,8 +23789,8 @@ var CursorBridge = class {
23335
23789
  async status(taskId = "") {
23336
23790
  if (taskId) {
23337
23791
  const job = this.tasks.get(String(taskId));
23338
- if (!job) return { found: false, taskId: String(taskId), ...this.workspaceView(), ...this.delegationView(), ...this.runtimeModeView() };
23339
- return { found: true, ...this.workspaceView(), ...this.delegationView(), ...this.runtimeModeView(), ...this._taskView(job, true) };
23792
+ if (!job) return { found: false, taskId: String(taskId), ...this.workspaceView(), ...this.delegationView(), ...this.runtimeModeView(), ...this.modelPreferencesView() };
23793
+ return { found: true, ...this.workspaceView(), ...this.delegationView(), ...this.runtimeModeView(), ...this.modelPreferencesView(), ...this._taskView(job, true) };
23340
23794
  }
23341
23795
  const parallelRunning = this.activeParallel.size;
23342
23796
  const uiBusy = this.busy;
@@ -23347,6 +23801,7 @@ var CursorBridge = class {
23347
23801
  ...this.workspaceView(),
23348
23802
  ...this.delegationView(),
23349
23803
  ...this.runtimeModeView(),
23804
+ ...this.modelPreferencesView(),
23350
23805
  busy: uiBusy || parallelRunning > 0 || this.queue.length > 0,
23351
23806
  uiBusy,
23352
23807
  parallelRunning,
@@ -23451,9 +23906,23 @@ function buildToolDefinitions(bridgeInstance) {
23451
23906
  required: ["mode"]
23452
23907
  }
23453
23908
  },
23909
+ {
23910
+ name: "cursor_model",
23911
+ description: "Show, set, or reset persistent Cursor model defaults for CCE and cursor_do. Settings are independent per target and survive host tasks, MCP restarts, and Cursor Bridge restarts until the user explicitly changes or resets them. When configured, Bridge applies the model and optional effort in every newly created Cursor Agent before sending the prompt, then verifies the visible selection. An unavailable, ambiguous, unsupported, or unconfirmed selection fails before prompt submission instead of silently falling back to Auto. Use set/reset only when the user explicitly asks to change these defaults; use show for read-only inspection.",
23912
+ inputSchema: {
23913
+ type: "object",
23914
+ properties: {
23915
+ action: { type: "string", enum: ["show", "set", "reset"], description: "show reads current defaults; set persists a model and optional effort; reset restores Cursor default selection for the target." },
23916
+ target: { type: "string", enum: ["cce", "cursor_do", "both"], description: "Required for set/reset. CCE and cursor_do keep independent defaults; both changes both targets together." },
23917
+ model: { type: "string", description: "Required for set. Use a model ID or display name currently available in the signed-in Cursor account." },
23918
+ effort: { type: "string", enum: [...CURSOR_MODEL_EFFORTS], description: "Optional reasoning effort for set. Omit it to use that model's Cursor default." }
23919
+ },
23920
+ required: ["action"]
23921
+ }
23922
+ },
23454
23923
  {
23455
23924
  name: "cursor_status",
23456
- description: "Read-only snapshot of Cursor connectivity, queued/running work, reservations, execution availability, and normal/minimal runtime presentation. Pass a task ID to read its current in-memory state and any result already collected; this tool never switches Agents, reconciles, or stops work.",
23925
+ description: "Read-only snapshot of Cursor connectivity, queued/running work, reservations, execution availability, persistent model/effort defaults, and normal/minimal runtime presentation. Pass a task ID to read its configured and effective model selection plus any result already collected; this tool never switches Agents, reconciles, or stops work.",
23457
23926
  inputSchema: { type: "object", properties: { task_id: { type: "string", description: "A task ID returned by cursor_do. Omit it for an overall status view." } } }
23458
23927
  }
23459
23928
  ].filter(Boolean);
@@ -23461,7 +23930,7 @@ function buildToolDefinitions(bridgeInstance) {
23461
23930
  var ADAPTER_START_CWD = process.cwd();
23462
23931
  var bridge = new CursorBridge({ adapterStartCwd: ADAPTER_START_CWD });
23463
23932
  var server = new Server(
23464
- { name: "cursor-bridge", version: "5.5.0" },
23933
+ { name: "cursor-bridge", version: "5.6.0" },
23465
23934
  { capabilities: { tools: { listChanged: true } } }
23466
23935
  );
23467
23936
  async function ensureBridgeCursor(targetBridge, reason) {
@@ -23550,6 +24019,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request2) => {
23550
24019
  }
23551
24020
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
23552
24021
  }
24022
+ if (name === "cursor_model") {
24023
+ const result = bridge.configureModelPreferences({
24024
+ action: args && args.action,
24025
+ target: args && args.target,
24026
+ model: args && args.model,
24027
+ effort: args && args.effort
24028
+ });
24029
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
24030
+ }
23553
24031
  if (name === "cursor_status") {
23554
24032
  const statusMs = Math.max(1e3, Number(process.env.CURSOR_BRIDGE_STATUS_TIMEOUT || 8e3));
23555
24033
  let result;
@@ -23607,11 +24085,15 @@ if (isMain2) {
23607
24085
  });
23608
24086
  }
23609
24087
  export {
24088
+ CURSOR_MODEL_EFFORTS,
24089
+ CURSOR_MODEL_TARGETS,
23610
24090
  CURSOR_RUNTIME_MODES,
23611
24091
  CursorBridge,
23612
24092
  EXPR_CLICK_SEND,
23613
24093
  EXPR_FIND_NEWAGENT,
23614
24094
  EXPR_HISTORY_ENTRIES,
24095
+ EXPR_MODEL_PICKER_ROWS,
24096
+ EXPR_MODEL_PICKER_TRIGGER,
23615
24097
  EXPR_PAGE_CAPABILITIES,
23616
24098
  EXPR_PROVIDER_ERROR,
23617
24099
  EXPR_VISIBLE,
@@ -23635,16 +24117,20 @@ export {
23635
24117
  isTargetedStopConfirmed,
23636
24118
  normalizeAllowedPath,
23637
24119
  normalizeCceSearchResult,
24120
+ normalizeCursorModelEffort,
23638
24121
  normalizeCursorRuntimeMode,
23639
24122
  normalizeDelegationMode,
24123
+ normalizeModelPickerText,
23640
24124
  pathsOverlap,
23641
24125
  promoteAgentsWorkspaceLifecycle,
23642
24126
  providerErrorSignature,
23643
24127
  releaseAdapterWorkingDirectory,
23644
24128
  scoreCursorPageCandidate,
23645
24129
  selectCursorPageCandidate,
24130
+ selectModelPickerRow,
23646
24131
  selectNewAgentEntry,
23647
24132
  selectPageForUiPreference,
24133
+ selectPromotedFifoEntry,
23648
24134
  shouldAutoLaunchCursor,
23649
24135
  shouldRecoverNormalAgentsPresentation,
23650
24136
  summarizeCdpPages,