@rely-ai/caliber 1.22.0-dev.1773765954 → 1.22.0-dev.1773767049

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 +93 -165
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -1205,197 +1205,125 @@ var OpenAICompatProvider = class {
1205
1205
 
1206
1206
  // src/llm/cursor-acp.ts
1207
1207
  import { spawn, execSync as execSync3 } from "child_process";
1208
- import readline from "readline";
1209
- var ACP_AGENT_BIN = "agent";
1208
+ var AGENT_BIN = "agent";
1210
1209
  var IS_WINDOWS = process.platform === "win32";
1211
1210
  var CursorAcpProvider = class {
1212
1211
  defaultModel;
1213
1212
  cursorApiKey;
1214
- connections = /* @__PURE__ */ new Map();
1215
- connectPromises = /* @__PURE__ */ new Map();
1216
- shutdownRequested = false;
1217
1213
  constructor(config) {
1218
1214
  this.defaultModel = config.model || "sonnet-4.6";
1219
1215
  this.cursorApiKey = process.env.CURSOR_API_KEY ?? process.env.CURSOR_AUTH_TOKEN;
1220
- process.once("exit", () => this.shutdown());
1221
1216
  }
1222
1217
  async call(options) {
1223
- const chunks = [];
1224
- await this.runPrompt(options, {
1225
- onText: (text) => chunks.push(text),
1226
- onEnd: () => {
1227
- },
1228
- onError: () => {
1229
- }
1230
- });
1231
- return chunks.join("");
1218
+ const prompt = this.buildPrompt(options);
1219
+ const model = options.model || this.defaultModel;
1220
+ return this.runPrint(model, prompt);
1232
1221
  }
1233
1222
  async stream(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);
1223
+ const prompt = this.buildPrompt(options);
1224
+ const model = options.model || this.defaultModel;
1225
+ return this.runPrintStream(model, prompt, callbacks);
1266
1226
  }
1267
- async connect(model) {
1268
- const args = ["acp"];
1227
+ buildArgs(model, streaming) {
1228
+ const args = ["--print"];
1269
1229
  if (model && model !== "auto" && model !== "default") {
1270
- args.unshift("--model", model);
1230
+ args.push("--model", model);
1231
+ }
1232
+ if (streaming) {
1233
+ args.push("--output-format", "stream-json", "--stream-partial-output");
1271
1234
  }
1272
1235
  if (this.cursorApiKey) {
1273
- args.unshift("--api-key", this.cursorApiKey);
1236
+ args.push("--api-key", this.cursorApiKey);
1274
1237
  }
1275
- const child = spawn(ACP_AGENT_BIN, args, {
1276
- stdio: ["pipe", "pipe", "ignore"],
1277
- cwd: process.cwd(),
1278
- env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
1279
- ...IS_WINDOWS && { shell: true }
1280
- });
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
1287
- };
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);
1300
- }
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" });
1238
+ return args;
1311
1239
  }
1312
- // -- JSON-RPC ---------------------------------------------------------------
1313
- send(conn, method, params) {
1314
- if (!conn.child.stdin) {
1315
- return Promise.reject(new Error("Cursor agent not connected"));
1316
- }
1240
+ runPrint(model, prompt) {
1317
1241
  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);
1242
+ const args = this.buildArgs(model, false);
1243
+ const child = spawn(AGENT_BIN, args, {
1244
+ stdio: ["pipe", "pipe", "ignore"],
1245
+ env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
1246
+ ...IS_WINDOWS && { shell: true }
1247
+ });
1248
+ const chunks = [];
1249
+ child.stdout.on("data", (data) => {
1250
+ chunks.push(data);
1251
+ });
1252
+ child.on("error", reject);
1253
+ child.on("close", (code) => {
1254
+ const output = Buffer.concat(chunks).toString("utf-8").trim();
1255
+ if (code !== 0 && !output) {
1256
+ reject(new Error(`Cursor agent exited with code ${code}`));
1257
+ } else {
1258
+ resolve2(output);
1325
1259
  }
1326
1260
  });
1261
+ child.stdin.write(prompt);
1262
+ child.stdin.end();
1327
1263
  });
1328
1264
  }
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);
1265
+ runPrintStream(model, prompt, callbacks) {
1266
+ return new Promise((resolve2, reject) => {
1267
+ const args = this.buildArgs(model, true);
1268
+ const child = spawn(AGENT_BIN, args, {
1269
+ stdio: ["pipe", "pipe", "ignore"],
1270
+ env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
1271
+ ...IS_WINDOWS && { shell: true }
1272
+ });
1273
+ let buffer = "";
1274
+ child.stdout.on("data", (data) => {
1275
+ buffer += data.toString("utf-8");
1276
+ const lines = buffer.split("\n");
1277
+ buffer = lines.pop() || "";
1278
+ for (const line of lines) {
1279
+ if (!line.trim()) continue;
1280
+ try {
1281
+ const event = JSON.parse(line);
1282
+ if (event.type === "assistant") {
1283
+ const text = event.message?.content?.[0]?.text || event.content;
1284
+ if (text) callbacks.onText(text);
1285
+ } else if (event.type === "result") {
1286
+ callbacks.onEnd({ stopReason: "end_turn" });
1287
+ }
1288
+ } catch {
1289
+ callbacks.onText(line);
1290
+ }
1344
1291
  }
1345
- }
1346
- if (msg.result && typeof msg.result === "object" && "stopReason" in msg.result) {
1347
- conn.activeCallbacks?.onEnd({
1348
- stopReason: msg.result.stopReason
1349
- });
1350
- }
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);
1357
- }
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;
1374
- try {
1375
- const sessionResult = await this.send(conn, "session/new", {
1376
- cwd: process.cwd(),
1377
- mcpServers: []
1378
1292
  });
1379
- await this.send(conn, "session/prompt", {
1380
- sessionId: sessionResult.sessionId,
1381
- prompt: [{ type: "text", text: this.buildCombinedPrompt(options) }]
1293
+ child.on("error", (err) => {
1294
+ callbacks.onError(err);
1295
+ reject(err);
1296
+ });
1297
+ child.on("close", (code) => {
1298
+ if (buffer.trim()) {
1299
+ try {
1300
+ const event = JSON.parse(buffer);
1301
+ if (event.type === "assistant") {
1302
+ const text = event.message?.content?.[0]?.text || event.content;
1303
+ if (text) callbacks.onText(text);
1304
+ } else if (event.type === "result") {
1305
+ callbacks.onEnd({ stopReason: "end_turn" });
1306
+ }
1307
+ } catch {
1308
+ callbacks.onText(buffer);
1309
+ }
1310
+ }
1311
+ if (code !== 0 && code !== null) {
1312
+ const err = new Error(`Cursor agent exited with code ${code}`);
1313
+ callbacks.onError(err);
1314
+ reject(err);
1315
+ } else {
1316
+ resolve2();
1317
+ }
1382
1318
  });
1383
- } catch (err) {
1384
- const error = err instanceof Error ? err : new Error(String(err));
1385
- callbacks.onError(error);
1386
- throw error;
1387
- } finally {
1388
- conn.activeCallbacks = null;
1389
- }
1319
+ child.stdin.write(prompt);
1320
+ child.stdin.end();
1321
+ });
1390
1322
  }
1391
- buildCombinedPrompt(options) {
1323
+ buildPrompt(options) {
1392
1324
  const streamOpts = options;
1393
1325
  const hasHistory = streamOpts.messages && streamOpts.messages.length > 0;
1394
1326
  let combined = "";
1395
- combined += "IMPORTANT: You are being used as a direct LLM, not as a coding agent. ";
1396
- combined += "Do NOT use tools, do NOT read or write files, do NOT check the repository. ";
1397
- combined += "Process the prompt below and output your response directly in your message. ";
1398
- combined += "Follow the system instructions exactly.\n\n";
1399
1327
  combined += "[[System]]\n" + options.system + "\n\n";
1400
1328
  if (hasHistory) {
1401
1329
  for (const msg of streamOpts.messages) {
@@ -1411,7 +1339,7 @@ ${msg.content}
1411
1339
  };
1412
1340
  function isCursorAgentAvailable() {
1413
1341
  try {
1414
- const cmd = process.platform === "win32" ? `where ${ACP_AGENT_BIN}` : `which ${ACP_AGENT_BIN}`;
1342
+ const cmd = process.platform === "win32" ? `where ${AGENT_BIN}` : `which ${AGENT_BIN}`;
1415
1343
  execSync3(cmd, { stdio: "ignore" });
1416
1344
  return true;
1417
1345
  } catch {
@@ -4055,9 +3983,9 @@ var SpinnerMessages = class {
4055
3983
 
4056
3984
  // src/utils/prompt.ts
4057
3985
  import chalk4 from "chalk";
4058
- import readline2 from "readline";
3986
+ import readline from "readline";
4059
3987
  function promptInput(question) {
4060
- const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
3988
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
4061
3989
  return new Promise((resolve2) => {
4062
3990
  rl.question(chalk4.cyan(`${question} `), (answer) => {
4063
3991
  rl.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.22.0-dev.1773765954",
3
+ "version": "1.22.0-dev.1773767049",
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": {