@rely-ai/caliber 1.22.0-dev.1773745340 → 1.22.0-dev.1773764649

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.
Files changed (2) hide show
  1. package/dist/bin.js +136 -88
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -133,13 +133,14 @@ var init_config = __esm({
133
133
  anthropic: "claude-sonnet-4-6",
134
134
  vertex: "claude-sonnet-4-6",
135
135
  openai: "gpt-4.1",
136
- cursor: "auto",
136
+ cursor: "sonnet-4.6",
137
137
  "claude-cli": "default"
138
138
  };
139
139
  DEFAULT_FAST_MODELS = {
140
140
  anthropic: "claude-haiku-4-5-20251001",
141
141
  vertex: "claude-haiku-4-5-20251001",
142
- openai: "gpt-4.1-mini"
142
+ openai: "gpt-4.1-mini",
143
+ cursor: "gpt-5.3-codex-fast"
143
144
  };
144
145
  }
145
146
  });
@@ -1210,13 +1211,17 @@ var IS_WINDOWS = process.platform === "win32";
1210
1211
  var CursorAcpProvider = class {
1211
1212
  defaultModel;
1212
1213
  cursorApiKey;
1214
+ connections = /* @__PURE__ */ new Map();
1215
+ connectPromises = /* @__PURE__ */ new Map();
1216
+ shutdownRequested = false;
1213
1217
  constructor(config) {
1214
- this.defaultModel = config.model || "default";
1218
+ this.defaultModel = config.model || "sonnet-4.6";
1215
1219
  this.cursorApiKey = process.env.CURSOR_API_KEY ?? process.env.CURSOR_AUTH_TOKEN;
1220
+ process.once("exit", () => this.shutdown());
1216
1221
  }
1217
1222
  async call(options) {
1218
1223
  const chunks = [];
1219
- await this.runAcpPrompt(options, {
1224
+ await this.runPrompt(options, {
1220
1225
  onText: (text) => chunks.push(text),
1221
1226
  onEnd: () => {
1222
1227
  },
@@ -1226,118 +1231,161 @@ var CursorAcpProvider = class {
1226
1231
  return chunks.join("");
1227
1232
  }
1228
1233
  async stream(options, callbacks) {
1229
- await this.runAcpPrompt(options, callbacks);
1234
+ await this.runPrompt(options, callbacks);
1235
+ }
1236
+ shutdown() {
1237
+ this.shutdownRequested = true;
1238
+ for (const conn of this.connections.values()) {
1239
+ conn.child.stdin?.end();
1240
+ conn.child.kill("SIGTERM");
1241
+ }
1242
+ this.connections.clear();
1243
+ this.connectPromises.clear();
1244
+ }
1245
+ // -- Connection pool --------------------------------------------------------
1246
+ resolveModel(options) {
1247
+ return options.model || this.defaultModel;
1248
+ }
1249
+ async ensureConnection(model) {
1250
+ const existing = this.connections.get(model);
1251
+ if (existing && !existing.child.killed) return existing;
1252
+ const pending = this.connectPromises.get(model);
1253
+ if (pending) {
1254
+ await pending;
1255
+ return this.connections.get(model);
1256
+ }
1257
+ const promise = this.connect(model);
1258
+ this.connectPromises.set(model, promise);
1259
+ try {
1260
+ await promise;
1261
+ } catch (err) {
1262
+ this.connectPromises.delete(model);
1263
+ throw err;
1264
+ }
1265
+ return this.connections.get(model);
1230
1266
  }
1231
- async runAcpPrompt(options, callbacks) {
1232
- const combinedPrompt = this.buildCombinedPrompt(options);
1233
- const model = options.model || this.defaultModel;
1234
- const args = ["acp"];
1267
+ async connect(model) {
1268
+ const args = ["--mode", "ask", "acp"];
1235
1269
  if (model && model !== "auto" && model !== "default") {
1236
1270
  args.unshift("--model", model);
1237
1271
  }
1238
1272
  if (this.cursorApiKey) {
1239
1273
  args.unshift("--api-key", this.cursorApiKey);
1240
1274
  }
1241
- const agent = spawn(ACP_AGENT_BIN, args, {
1242
- stdio: ["pipe", "pipe", "inherit"],
1275
+ const child = spawn(ACP_AGENT_BIN, args, {
1276
+ stdio: ["pipe", "pipe", "ignore"],
1243
1277
  cwd: process.cwd(),
1244
1278
  env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
1245
1279
  ...IS_WINDOWS && { shell: true }
1246
1280
  });
1247
- const pending = /* @__PURE__ */ new Map();
1248
- let nextId = 1;
1249
- let sessionId = null;
1250
- const send = (method, params) => {
1251
- return new Promise((resolve2, reject) => {
1252
- const id = nextId++;
1253
- pending.set(id, { resolve: resolve2, reject });
1254
- const msg = { jsonrpc: "2.0", id, method, params };
1255
- agent.stdin.write(JSON.stringify(msg) + "\n", (err) => {
1256
- if (err) {
1257
- pending.delete(id);
1258
- reject(err);
1259
- }
1260
- });
1261
- });
1281
+ const conn = {
1282
+ child,
1283
+ rl: readline.createInterface({ input: child.stdout, crlfDelay: Infinity }),
1284
+ pending: /* @__PURE__ */ new Map(),
1285
+ nextId: 1,
1286
+ activeCallbacks: null
1262
1287
  };
1263
- const rl = readline.createInterface({ input: agent.stdout, crlfDelay: Infinity });
1264
- rl.on("line", (line) => {
1265
- let msg;
1266
- try {
1267
- msg = JSON.parse(line);
1268
- } catch {
1269
- return;
1288
+ conn.rl.on("line", (line) => this.handleLine(conn, line));
1289
+ child.on("error", (err) => {
1290
+ for (const w of conn.pending.values()) w.reject(err);
1291
+ conn.pending.clear();
1292
+ conn.activeCallbacks?.onError(err);
1293
+ });
1294
+ child.on("close", () => {
1295
+ if (!this.shutdownRequested) {
1296
+ const err = new Error("Cursor agent process exited unexpectedly");
1297
+ for (const w of conn.pending.values()) w.reject(err);
1298
+ conn.pending.clear();
1299
+ conn.activeCallbacks?.onError(err);
1270
1300
  }
1271
- if (msg.id != null && (msg.result !== void 0 || msg.error !== void 0)) {
1272
- const waiter = pending.get(msg.id);
1273
- if (waiter) {
1274
- pending.delete(msg.id);
1275
- if (msg.error) {
1276
- waiter.reject(new Error(msg.error.message || "ACP error"));
1277
- } else {
1278
- waiter.resolve(msg.result);
1279
- }
1280
- }
1281
- if (msg.result && typeof msg.result === "object" && "sessionId" in msg.result) {
1282
- sessionId = msg.result.sessionId;
1283
- }
1284
- if (msg.result && typeof msg.result === "object" && "stopReason" in msg.result) {
1285
- callbacks.onEnd({
1286
- stopReason: msg.result.stopReason
1287
- });
1301
+ this.connections.delete(model);
1302
+ this.connectPromises.delete(model);
1303
+ });
1304
+ this.connections.set(model, conn);
1305
+ await this.send(conn, "initialize", {
1306
+ protocolVersion: 1,
1307
+ clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },
1308
+ clientInfo: { name: "caliber", version: "1.0.0" }
1309
+ });
1310
+ await this.send(conn, "authenticate", { methodId: "cursor_login" });
1311
+ }
1312
+ // -- JSON-RPC ---------------------------------------------------------------
1313
+ send(conn, method, params) {
1314
+ if (!conn.child.stdin) {
1315
+ return Promise.reject(new Error("Cursor agent not connected"));
1316
+ }
1317
+ return new Promise((resolve2, reject) => {
1318
+ const id = conn.nextId++;
1319
+ conn.pending.set(id, { resolve: resolve2, reject });
1320
+ const msg = { jsonrpc: "2.0", id, method, params };
1321
+ conn.child.stdin.write(JSON.stringify(msg) + "\n", (err) => {
1322
+ if (err) {
1323
+ conn.pending.delete(id);
1324
+ reject(err);
1288
1325
  }
1289
- return;
1290
- }
1291
- if (msg.method === "session/update" && msg.params?.update) {
1292
- const update = msg.params.update;
1293
- if (update.sessionUpdate === "agent_message_chunk" && update.content?.text) {
1294
- callbacks.onText(update.content.text);
1326
+ });
1327
+ });
1328
+ }
1329
+ handleLine(conn, line) {
1330
+ let msg;
1331
+ try {
1332
+ msg = JSON.parse(line);
1333
+ } catch {
1334
+ return;
1335
+ }
1336
+ if (msg.id != null && (msg.result !== void 0 || msg.error !== void 0)) {
1337
+ const waiter = conn.pending.get(msg.id);
1338
+ if (waiter) {
1339
+ conn.pending.delete(msg.id);
1340
+ if (msg.error) {
1341
+ waiter.reject(new Error(msg.error.message || "ACP error"));
1342
+ } else {
1343
+ waiter.resolve(msg.result);
1295
1344
  }
1296
- return;
1297
1345
  }
1298
- if (msg.method === "session/request_permission" && msg.id != null) {
1299
- const response = JSON.stringify({
1300
- jsonrpc: "2.0",
1301
- id: msg.id,
1302
- result: { outcome: { outcome: "selected", optionId: "allow-once" } }
1303
- }) + "\n";
1304
- agent.stdin.write(response);
1346
+ if (msg.result && typeof msg.result === "object" && "stopReason" in msg.result) {
1347
+ conn.activeCallbacks?.onEnd({
1348
+ stopReason: msg.result.stopReason
1349
+ });
1305
1350
  }
1306
- });
1307
- agent.on("error", (err) => {
1308
- for (const w of pending.values()) w.reject(err);
1309
- callbacks.onError(err);
1310
- });
1311
- agent.on("close", (code) => {
1312
- if (code !== 0 && code !== null) {
1313
- const err = new Error(`Cursor agent exited with code ${code}`);
1314
- for (const w of pending.values()) w.reject(err);
1315
- callbacks.onError(err);
1351
+ return;
1352
+ }
1353
+ if (msg.method === "session/update" && msg.params?.update) {
1354
+ const update = msg.params.update;
1355
+ if (update.sessionUpdate === "agent_message_chunk" && update.content?.text) {
1356
+ conn.activeCallbacks?.onText(update.content.text);
1316
1357
  }
1317
- });
1358
+ return;
1359
+ }
1360
+ if (msg.method === "session/request_permission" && msg.id != null) {
1361
+ const response = JSON.stringify({
1362
+ jsonrpc: "2.0",
1363
+ id: msg.id,
1364
+ result: { outcome: { outcome: "selected", optionId: "allow-once" } }
1365
+ }) + "\n";
1366
+ conn.child.stdin?.write(response);
1367
+ }
1368
+ }
1369
+ // -- Prompt execution -------------------------------------------------------
1370
+ async runPrompt(options, callbacks) {
1371
+ const model = this.resolveModel(options);
1372
+ const conn = await this.ensureConnection(model);
1373
+ conn.activeCallbacks = callbacks;
1318
1374
  try {
1319
- await send("initialize", {
1320
- protocolVersion: 1,
1321
- clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },
1322
- clientInfo: { name: "caliber", version: "1.0.0" }
1323
- });
1324
- await send("authenticate", { methodId: "cursor_login" });
1325
- const sessionResult = await send("session/new", {
1375
+ const sessionResult = await this.send(conn, "session/new", {
1326
1376
  cwd: process.cwd(),
1327
1377
  mcpServers: []
1328
1378
  });
1329
- sessionId = sessionResult.sessionId;
1330
- await send("session/prompt", {
1331
- sessionId,
1332
- prompt: [{ type: "text", text: combinedPrompt }]
1379
+ await this.send(conn, "session/prompt", {
1380
+ sessionId: sessionResult.sessionId,
1381
+ prompt: [{ type: "text", text: this.buildCombinedPrompt(options) }]
1333
1382
  });
1334
1383
  } catch (err) {
1335
1384
  const error = err instanceof Error ? err : new Error(String(err));
1336
1385
  callbacks.onError(error);
1337
1386
  throw error;
1338
1387
  } finally {
1339
- agent.stdin?.end();
1340
- agent.kill("SIGTERM");
1388
+ conn.activeCallbacks = null;
1341
1389
  }
1342
1390
  }
1343
1391
  buildCombinedPrompt(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.22.0-dev.1773745340",
3
+ "version": "1.22.0-dev.1773764649",
4
4
  "description": "Analyze your codebase and generate optimized AI agent configs (CLAUDE.md, .cursorrules, skills) — no API key needed",
5
5
  "type": "module",
6
6
  "bin": {