@rely-ai/caliber 1.22.0-dev.1773744838 → 1.22.0-dev.1773752996

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 +129 -89
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -114,10 +114,13 @@ function getDisplayModel(config) {
114
114
  }
115
115
  function getFastModel() {
116
116
  if (process.env.CALIBER_FAST_MODEL) return process.env.CALIBER_FAST_MODEL;
117
- if (process.env.ANTHROPIC_SMALL_FAST_MODEL) return process.env.ANTHROPIC_SMALL_FAST_MODEL;
118
117
  const config = loadConfig();
118
+ const provider = config?.provider;
119
+ if (process.env.ANTHROPIC_SMALL_FAST_MODEL && (!provider || provider === "anthropic" || provider === "vertex")) {
120
+ return process.env.ANTHROPIC_SMALL_FAST_MODEL;
121
+ }
119
122
  if (config?.fastModel) return config.fastModel;
120
- if (config?.provider) return DEFAULT_FAST_MODELS[config.provider];
123
+ if (provider) return DEFAULT_FAST_MODELS[provider];
121
124
  return void 0;
122
125
  }
123
126
  var CONFIG_DIR, CONFIG_FILE, DEFAULT_MODELS, DEFAULT_FAST_MODELS;
@@ -130,7 +133,7 @@ var init_config = __esm({
130
133
  anthropic: "claude-sonnet-4-6",
131
134
  vertex: "claude-sonnet-4-6",
132
135
  openai: "gpt-4.1",
133
- cursor: "default",
136
+ cursor: "auto",
134
137
  "claude-cli": "default"
135
138
  };
136
139
  DEFAULT_FAST_MODELS = {
@@ -1207,13 +1210,21 @@ var IS_WINDOWS = process.platform === "win32";
1207
1210
  var CursorAcpProvider = class {
1208
1211
  defaultModel;
1209
1212
  cursorApiKey;
1213
+ child = null;
1214
+ rl = null;
1215
+ pending = /* @__PURE__ */ new Map();
1216
+ nextId = 1;
1217
+ connectPromise = null;
1218
+ activeCallbacks = null;
1219
+ shutdownRequested = false;
1210
1220
  constructor(config) {
1211
- this.defaultModel = config.model || "default";
1221
+ this.defaultModel = config.model || "auto";
1212
1222
  this.cursorApiKey = process.env.CURSOR_API_KEY ?? process.env.CURSOR_AUTH_TOKEN;
1223
+ process.once("exit", () => this.shutdown());
1213
1224
  }
1214
1225
  async call(options) {
1215
1226
  const chunks = [];
1216
- await this.runAcpPrompt(options, {
1227
+ await this.runPrompt(options, {
1217
1228
  onText: (text) => chunks.push(text),
1218
1229
  onEnd: () => {
1219
1230
  },
@@ -1223,114 +1234,142 @@ var CursorAcpProvider = class {
1223
1234
  return chunks.join("");
1224
1235
  }
1225
1236
  async stream(options, callbacks) {
1226
- await this.runAcpPrompt(options, callbacks);
1237
+ await this.runPrompt(options, callbacks);
1238
+ }
1239
+ shutdown() {
1240
+ this.shutdownRequested = true;
1241
+ if (this.child) {
1242
+ this.child.stdin?.end();
1243
+ this.child.kill("SIGTERM");
1244
+ this.child = null;
1245
+ }
1246
+ this.rl = null;
1247
+ this.connectPromise = null;
1248
+ }
1249
+ // -- Connection management --------------------------------------------------
1250
+ async ensureConnection() {
1251
+ if (this.child && !this.child.killed) return;
1252
+ if (this.connectPromise) return this.connectPromise;
1253
+ this.connectPromise = this.connect();
1254
+ try {
1255
+ await this.connectPromise;
1256
+ } catch (err) {
1257
+ this.connectPromise = null;
1258
+ throw err;
1259
+ }
1227
1260
  }
1228
- async runAcpPrompt(options, callbacks) {
1229
- const combinedPrompt = this.buildCombinedPrompt(options);
1261
+ async connect() {
1230
1262
  const args = ["acp"];
1231
1263
  if (this.cursorApiKey) {
1232
1264
  args.unshift("--api-key", this.cursorApiKey);
1233
1265
  }
1234
- const agent = spawn(ACP_AGENT_BIN, args, {
1235
- stdio: ["pipe", "pipe", "inherit"],
1266
+ this.child = spawn(ACP_AGENT_BIN, args, {
1267
+ stdio: ["pipe", "pipe", "ignore"],
1236
1268
  cwd: process.cwd(),
1237
1269
  env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
1238
1270
  ...IS_WINDOWS && { shell: true }
1239
1271
  });
1240
- const pending = /* @__PURE__ */ new Map();
1241
- let nextId = 1;
1242
- let sessionId = null;
1243
- const send = (method, params) => {
1244
- return new Promise((resolve2, reject) => {
1245
- const id = nextId++;
1246
- pending.set(id, { resolve: resolve2, reject });
1247
- const msg = { jsonrpc: "2.0", id, method, params };
1248
- agent.stdin.write(JSON.stringify(msg) + "\n", (err) => {
1249
- if (err) {
1250
- pending.delete(id);
1251
- reject(err);
1252
- }
1253
- });
1254
- });
1255
- };
1256
- const rl = readline.createInterface({ input: agent.stdout, crlfDelay: Infinity });
1257
- rl.on("line", (line) => {
1258
- let msg;
1259
- try {
1260
- msg = JSON.parse(line);
1261
- } catch {
1262
- return;
1272
+ this.rl = readline.createInterface({ input: this.child.stdout, crlfDelay: Infinity });
1273
+ this.rl.on("line", (line) => this.handleLine(line));
1274
+ this.child.on("error", (err) => {
1275
+ for (const w of this.pending.values()) w.reject(err);
1276
+ this.pending.clear();
1277
+ this.activeCallbacks?.onError(err);
1278
+ });
1279
+ this.child.on("close", () => {
1280
+ if (!this.shutdownRequested) {
1281
+ const err = new Error("Cursor agent process exited unexpectedly");
1282
+ for (const w of this.pending.values()) w.reject(err);
1283
+ this.pending.clear();
1284
+ this.activeCallbacks?.onError(err);
1263
1285
  }
1264
- if (msg.id != null && (msg.result !== void 0 || msg.error !== void 0)) {
1265
- const waiter = pending.get(msg.id);
1266
- if (waiter) {
1267
- pending.delete(msg.id);
1268
- if (msg.error) {
1269
- waiter.reject(new Error(msg.error.message || "ACP error"));
1270
- } else {
1271
- waiter.resolve(msg.result);
1272
- }
1273
- }
1274
- if (msg.result && typeof msg.result === "object" && "sessionId" in msg.result) {
1275
- sessionId = msg.result.sessionId;
1276
- }
1277
- if (msg.result && typeof msg.result === "object" && "stopReason" in msg.result) {
1278
- callbacks.onEnd({
1279
- stopReason: msg.result.stopReason
1280
- });
1286
+ this.child = null;
1287
+ this.rl = null;
1288
+ this.connectPromise = null;
1289
+ });
1290
+ await this.send("initialize", {
1291
+ protocolVersion: 1,
1292
+ clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },
1293
+ clientInfo: { name: "caliber", version: "1.0.0" }
1294
+ });
1295
+ await this.send("authenticate", { methodId: "cursor_login" });
1296
+ }
1297
+ // -- JSON-RPC ---------------------------------------------------------------
1298
+ send(method, params) {
1299
+ if (!this.child?.stdin) {
1300
+ return Promise.reject(new Error("Cursor agent not connected"));
1301
+ }
1302
+ return new Promise((resolve2, reject) => {
1303
+ const id = this.nextId++;
1304
+ this.pending.set(id, { resolve: resolve2, reject });
1305
+ const msg = { jsonrpc: "2.0", id, method, params };
1306
+ this.child.stdin.write(JSON.stringify(msg) + "\n", (err) => {
1307
+ if (err) {
1308
+ this.pending.delete(id);
1309
+ reject(err);
1281
1310
  }
1282
- return;
1283
- }
1284
- if (msg.method === "session/update" && msg.params?.update) {
1285
- const update = msg.params.update;
1286
- if (update.sessionUpdate === "agent_message_chunk" && update.content?.text) {
1287
- callbacks.onText(update.content.text);
1311
+ });
1312
+ });
1313
+ }
1314
+ handleLine(line) {
1315
+ let msg;
1316
+ try {
1317
+ msg = JSON.parse(line);
1318
+ } catch {
1319
+ return;
1320
+ }
1321
+ if (msg.id != null && (msg.result !== void 0 || msg.error !== void 0)) {
1322
+ const waiter = this.pending.get(msg.id);
1323
+ if (waiter) {
1324
+ this.pending.delete(msg.id);
1325
+ if (msg.error) {
1326
+ waiter.reject(new Error(msg.error.message || "ACP error"));
1327
+ } else {
1328
+ waiter.resolve(msg.result);
1288
1329
  }
1289
- return;
1290
1330
  }
1291
- if (msg.method === "session/request_permission" && msg.id != null) {
1292
- const response = JSON.stringify({
1293
- jsonrpc: "2.0",
1294
- id: msg.id,
1295
- result: { outcome: { outcome: "selected", optionId: "allow-once" } }
1296
- }) + "\n";
1297
- agent.stdin.write(response);
1331
+ if (msg.result && typeof msg.result === "object" && "stopReason" in msg.result) {
1332
+ this.activeCallbacks?.onEnd({
1333
+ stopReason: msg.result.stopReason
1334
+ });
1298
1335
  }
1299
- });
1300
- agent.on("error", (err) => {
1301
- for (const w of pending.values()) w.reject(err);
1302
- callbacks.onError(err);
1303
- });
1304
- agent.on("close", (code) => {
1305
- if (code !== 0 && code !== null) {
1306
- const err = new Error(`Cursor agent exited with code ${code}`);
1307
- for (const w of pending.values()) w.reject(err);
1308
- callbacks.onError(err);
1336
+ return;
1337
+ }
1338
+ if (msg.method === "session/update" && msg.params?.update) {
1339
+ const update = msg.params.update;
1340
+ if (update.sessionUpdate === "agent_message_chunk" && update.content?.text) {
1341
+ this.activeCallbacks?.onText(update.content.text);
1309
1342
  }
1310
- });
1343
+ return;
1344
+ }
1345
+ if (msg.method === "session/request_permission" && msg.id != null) {
1346
+ const response = JSON.stringify({
1347
+ jsonrpc: "2.0",
1348
+ id: msg.id,
1349
+ result: { outcome: { outcome: "selected", optionId: "allow-once" } }
1350
+ }) + "\n";
1351
+ this.child?.stdin?.write(response);
1352
+ }
1353
+ }
1354
+ // -- Prompt execution -------------------------------------------------------
1355
+ async runPrompt(options, callbacks) {
1356
+ await this.ensureConnection();
1357
+ this.activeCallbacks = callbacks;
1311
1358
  try {
1312
- await send("initialize", {
1313
- protocolVersion: 1,
1314
- clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },
1315
- clientInfo: { name: "caliber", version: "1.0.0" }
1316
- });
1317
- await send("authenticate", { methodId: "cursor_login" });
1318
- const sessionResult = await send("session/new", {
1359
+ const sessionResult = await this.send("session/new", {
1319
1360
  cwd: process.cwd(),
1320
1361
  mcpServers: []
1321
1362
  });
1322
- sessionId = sessionResult.sessionId;
1323
- await send("session/prompt", {
1324
- sessionId,
1325
- prompt: [{ type: "text", text: combinedPrompt }]
1363
+ await this.send("session/prompt", {
1364
+ sessionId: sessionResult.sessionId,
1365
+ prompt: [{ type: "text", text: this.buildCombinedPrompt(options) }]
1326
1366
  });
1327
1367
  } catch (err) {
1328
1368
  const error = err instanceof Error ? err : new Error(String(err));
1329
1369
  callbacks.onError(error);
1330
1370
  throw error;
1331
1371
  } finally {
1332
- agent.stdin?.end();
1333
- agent.kill("SIGTERM");
1372
+ this.activeCallbacks = null;
1334
1373
  }
1335
1374
  }
1336
1375
  buildCombinedPrompt(options) {
@@ -1745,6 +1784,7 @@ async function validateModel(options) {
1745
1784
  const provider = getProvider();
1746
1785
  const config = cachedConfig;
1747
1786
  if (!config) return;
1787
+ if (config.provider === "cursor" || config.provider === "claude-cli") return;
1748
1788
  const modelsToCheck = [config.model];
1749
1789
  if (options?.fast) {
1750
1790
  const { getFastModel: getFastModel2 } = await Promise.resolve().then(() => (init_config(), config_exports));
@@ -4043,7 +4083,7 @@ async function runInteractiveProviderSetup(options) {
4043
4083
  break;
4044
4084
  }
4045
4085
  case "cursor": {
4046
- config.model = "default";
4086
+ config.model = DEFAULT_MODELS.cursor;
4047
4087
  if (!isCursorAgentAvailable()) {
4048
4088
  console.log(chalk5.yellow("\n Cursor Agent CLI not found."));
4049
4089
  console.log(chalk5.dim(" Install it: ") + chalk5.hex("#83D1EB")("curl https://cursor.com/install -fsS | bash"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.22.0-dev.1773744838",
3
+ "version": "1.22.0-dev.1773752996",
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": {