@rely-ai/caliber 1.23.0-dev.1773793983 → 1.23.0
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.
- package/dist/bin.js +228 -65
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -169,6 +169,22 @@ var init_config = __esm({
|
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
+
// src/llm/types.ts
|
|
173
|
+
var types_exports = {};
|
|
174
|
+
__export(types_exports, {
|
|
175
|
+
isSeatBased: () => isSeatBased
|
|
176
|
+
});
|
|
177
|
+
function isSeatBased(provider) {
|
|
178
|
+
return SEAT_BASED_PROVIDERS.has(provider);
|
|
179
|
+
}
|
|
180
|
+
var SEAT_BASED_PROVIDERS;
|
|
181
|
+
var init_types = __esm({
|
|
182
|
+
"src/llm/types.ts"() {
|
|
183
|
+
"use strict";
|
|
184
|
+
SEAT_BASED_PROVIDERS = /* @__PURE__ */ new Set(["cursor", "claude-cli"]);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
172
188
|
// src/constants.ts
|
|
173
189
|
var constants_exports = {};
|
|
174
190
|
__export(constants_exports, {
|
|
@@ -1036,8 +1052,8 @@ var AnthropicProvider = class {
|
|
|
1036
1052
|
cacheWriteTokens: u.cache_creation_input_tokens
|
|
1037
1053
|
});
|
|
1038
1054
|
}
|
|
1039
|
-
const block = response.content[0];
|
|
1040
|
-
return block
|
|
1055
|
+
const block = response.content?.[0];
|
|
1056
|
+
return block?.type === "text" ? block.text : "";
|
|
1041
1057
|
}
|
|
1042
1058
|
async listModels() {
|
|
1043
1059
|
const models = [];
|
|
@@ -1140,8 +1156,8 @@ var VertexProvider = class {
|
|
|
1140
1156
|
cacheWriteTokens: u.cache_creation_input_tokens
|
|
1141
1157
|
});
|
|
1142
1158
|
}
|
|
1143
|
-
const block = response.content[0];
|
|
1144
|
-
return block
|
|
1159
|
+
const block = response.content?.[0];
|
|
1160
|
+
return block?.type === "text" ? block.text : "";
|
|
1145
1161
|
}
|
|
1146
1162
|
async stream(options, callbacks) {
|
|
1147
1163
|
const messages = options.messages ? [
|
|
@@ -1261,14 +1277,44 @@ var OpenAICompatProvider = class {
|
|
|
1261
1277
|
// src/llm/cursor-acp.ts
|
|
1262
1278
|
import { spawn, execSync as execSync3 } from "child_process";
|
|
1263
1279
|
import os2 from "os";
|
|
1280
|
+
|
|
1281
|
+
// src/llm/seat-based-errors.ts
|
|
1282
|
+
var ERROR_PATTERNS = [
|
|
1283
|
+
{ pattern: /not logged in|not authenticated|login required|unauthorized/i, message: "Authentication required. Run the login command for your provider to re-authenticate." },
|
|
1284
|
+
{ pattern: /rate limit|too many requests|429/i, message: "Rate limit exceeded. Retrying..." },
|
|
1285
|
+
{ pattern: /model.*not found|invalid model|model.*unavailable/i, message: "The requested model is not available. Run `caliber config` to select a different model." }
|
|
1286
|
+
];
|
|
1287
|
+
function parseSeatBasedError(stderr, exitCode) {
|
|
1288
|
+
if (!stderr && exitCode === 0) return null;
|
|
1289
|
+
for (const { pattern, message } of ERROR_PATTERNS) {
|
|
1290
|
+
if (pattern.test(stderr)) return message;
|
|
1291
|
+
}
|
|
1292
|
+
return null;
|
|
1293
|
+
}
|
|
1294
|
+
function isRateLimitError(stderr) {
|
|
1295
|
+
return /rate limit|too many requests|429/i.test(stderr);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// src/llm/cursor-acp.ts
|
|
1264
1299
|
var AGENT_BIN = "agent";
|
|
1265
1300
|
var IS_WINDOWS = process.platform === "win32";
|
|
1301
|
+
var DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1302
|
+
var SIGKILL_DELAY_MS = 5e3;
|
|
1303
|
+
var STDERR_MAX_BYTES = 10 * 1024;
|
|
1266
1304
|
var CursorAcpProvider = class {
|
|
1267
1305
|
defaultModel;
|
|
1268
1306
|
cursorApiKey;
|
|
1307
|
+
timeoutMs;
|
|
1308
|
+
warmProcess = null;
|
|
1309
|
+
warmModel = null;
|
|
1269
1310
|
constructor(config) {
|
|
1270
1311
|
this.defaultModel = config.model || "sonnet-4.6";
|
|
1271
1312
|
this.cursorApiKey = process.env.CURSOR_API_KEY ?? process.env.CURSOR_AUTH_TOKEN;
|
|
1313
|
+
const envTimeout = process.env.CALIBER_CURSOR_TIMEOUT_MS;
|
|
1314
|
+
this.timeoutMs = envTimeout ? parseInt(envTimeout, 10) : DEFAULT_TIMEOUT_MS;
|
|
1315
|
+
if (!Number.isFinite(this.timeoutMs) || this.timeoutMs < 1e3) {
|
|
1316
|
+
this.timeoutMs = DEFAULT_TIMEOUT_MS;
|
|
1317
|
+
}
|
|
1272
1318
|
}
|
|
1273
1319
|
async call(options) {
|
|
1274
1320
|
const prompt = this.buildPrompt(options);
|
|
@@ -1280,6 +1326,29 @@ var CursorAcpProvider = class {
|
|
|
1280
1326
|
const model = options.model || this.defaultModel;
|
|
1281
1327
|
return this.runPrintStream(model, prompt, callbacks);
|
|
1282
1328
|
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Pre-spawn an agent process so it's ready when the first call comes.
|
|
1331
|
+
* Call this during fingerprint collection to hide spawn latency.
|
|
1332
|
+
*/
|
|
1333
|
+
prewarm(model) {
|
|
1334
|
+
const targetModel = model || this.defaultModel;
|
|
1335
|
+
if (this.warmProcess && !this.warmProcess.killed && this.warmModel === targetModel) return;
|
|
1336
|
+
const args = this.buildArgs(targetModel, false);
|
|
1337
|
+
this.warmProcess = spawn(AGENT_BIN, args, {
|
|
1338
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1339
|
+
env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
|
|
1340
|
+
...IS_WINDOWS && { shell: true }
|
|
1341
|
+
});
|
|
1342
|
+
this.warmModel = targetModel;
|
|
1343
|
+
this.warmProcess.on("error", () => {
|
|
1344
|
+
this.warmProcess = null;
|
|
1345
|
+
this.warmModel = null;
|
|
1346
|
+
});
|
|
1347
|
+
this.warmProcess.on("close", () => {
|
|
1348
|
+
this.warmProcess = null;
|
|
1349
|
+
this.warmModel = null;
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1283
1352
|
buildArgs(model, streaming) {
|
|
1284
1353
|
const args = ["--print", "--trust", "--workspace", os2.tmpdir()];
|
|
1285
1354
|
if (model && model !== "auto" && model !== "default") {
|
|
@@ -1293,23 +1362,78 @@ var CursorAcpProvider = class {
|
|
|
1293
1362
|
}
|
|
1294
1363
|
return args;
|
|
1295
1364
|
}
|
|
1365
|
+
takeWarmProcess(model, streaming) {
|
|
1366
|
+
if (!streaming && this.warmProcess && !this.warmProcess.killed && this.warmModel === model) {
|
|
1367
|
+
const proc = this.warmProcess;
|
|
1368
|
+
this.warmProcess = null;
|
|
1369
|
+
this.warmModel = null;
|
|
1370
|
+
return proc;
|
|
1371
|
+
}
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
spawnAgent(model, streaming) {
|
|
1375
|
+
const warm = this.takeWarmProcess(model, streaming);
|
|
1376
|
+
if (warm) {
|
|
1377
|
+
const stderrChunks2 = [];
|
|
1378
|
+
warm.stderr?.on("data", (chunk) => {
|
|
1379
|
+
if (Buffer.concat(stderrChunks2).length < STDERR_MAX_BYTES) stderrChunks2.push(chunk);
|
|
1380
|
+
});
|
|
1381
|
+
return { child: warm, stderrChunks: stderrChunks2 };
|
|
1382
|
+
}
|
|
1383
|
+
const args = this.buildArgs(model, streaming);
|
|
1384
|
+
const child = spawn(AGENT_BIN, args, {
|
|
1385
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1386
|
+
env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
|
|
1387
|
+
...IS_WINDOWS && { shell: true }
|
|
1388
|
+
});
|
|
1389
|
+
const stderrChunks = [];
|
|
1390
|
+
child.stderr.on("data", (chunk) => {
|
|
1391
|
+
if (Buffer.concat(stderrChunks).length < STDERR_MAX_BYTES) stderrChunks.push(chunk);
|
|
1392
|
+
});
|
|
1393
|
+
return { child, stderrChunks };
|
|
1394
|
+
}
|
|
1395
|
+
killWithEscalation(child) {
|
|
1396
|
+
child.kill("SIGTERM");
|
|
1397
|
+
const killTimer = setTimeout(() => {
|
|
1398
|
+
if (!child.killed) child.kill("SIGKILL");
|
|
1399
|
+
}, SIGKILL_DELAY_MS);
|
|
1400
|
+
killTimer.unref();
|
|
1401
|
+
}
|
|
1402
|
+
buildErrorMessage(code, stderrChunks) {
|
|
1403
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
|
|
1404
|
+
const parsed = parseSeatBasedError(stderr, code);
|
|
1405
|
+
if (parsed) return parsed;
|
|
1406
|
+
const base = `Cursor agent exited with code ${code}`;
|
|
1407
|
+
return stderr ? `${base}: ${stderr.slice(0, 200)}` : base;
|
|
1408
|
+
}
|
|
1296
1409
|
runPrint(model, prompt) {
|
|
1297
1410
|
return new Promise((resolve2, reject) => {
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
stdio: ["pipe", "pipe", "ignore"],
|
|
1301
|
-
env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
|
|
1302
|
-
...IS_WINDOWS && { shell: true }
|
|
1303
|
-
});
|
|
1411
|
+
const { child, stderrChunks } = this.spawnAgent(model, false);
|
|
1412
|
+
let settled = false;
|
|
1304
1413
|
const chunks = [];
|
|
1305
|
-
child.stdout.on("data", (data) =>
|
|
1306
|
-
|
|
1414
|
+
child.stdout.on("data", (data) => chunks.push(data));
|
|
1415
|
+
const timer = setTimeout(() => {
|
|
1416
|
+
this.killWithEscalation(child);
|
|
1417
|
+
if (!settled) {
|
|
1418
|
+
settled = true;
|
|
1419
|
+
reject(new Error(`Cursor agent timed out after ${this.timeoutMs / 1e3}s. Set CALIBER_CURSOR_TIMEOUT_MS to increase.`));
|
|
1420
|
+
}
|
|
1421
|
+
}, this.timeoutMs);
|
|
1422
|
+
timer.unref();
|
|
1423
|
+
child.on("error", (err) => {
|
|
1424
|
+
clearTimeout(timer);
|
|
1425
|
+
if (!settled) {
|
|
1426
|
+
settled = true;
|
|
1427
|
+
reject(err);
|
|
1428
|
+
}
|
|
1307
1429
|
});
|
|
1308
|
-
child.on("error", reject);
|
|
1309
1430
|
child.on("close", (code) => {
|
|
1431
|
+
clearTimeout(timer);
|
|
1432
|
+
if (settled) return;
|
|
1433
|
+
settled = true;
|
|
1310
1434
|
const output = Buffer.concat(chunks).toString("utf-8").trim();
|
|
1311
1435
|
if (code !== 0 && !output) {
|
|
1312
|
-
reject(new Error(
|
|
1436
|
+
reject(new Error(this.buildErrorMessage(code, stderrChunks)));
|
|
1313
1437
|
} else {
|
|
1314
1438
|
resolve2(output);
|
|
1315
1439
|
}
|
|
@@ -1320,14 +1444,20 @@ var CursorAcpProvider = class {
|
|
|
1320
1444
|
}
|
|
1321
1445
|
runPrintStream(model, prompt, callbacks) {
|
|
1322
1446
|
return new Promise((resolve2, reject) => {
|
|
1323
|
-
const
|
|
1324
|
-
const child = spawn(AGENT_BIN, args, {
|
|
1325
|
-
stdio: ["pipe", "pipe", "ignore"],
|
|
1326
|
-
env: { ...process.env, ...this.cursorApiKey && { CURSOR_API_KEY: this.cursorApiKey } },
|
|
1327
|
-
...IS_WINDOWS && { shell: true }
|
|
1328
|
-
});
|
|
1447
|
+
const { child, stderrChunks } = this.spawnAgent(model, true);
|
|
1329
1448
|
let buffer = "";
|
|
1330
1449
|
let endCalled = false;
|
|
1450
|
+
let settled = false;
|
|
1451
|
+
const timer = setTimeout(() => {
|
|
1452
|
+
this.killWithEscalation(child);
|
|
1453
|
+
if (!settled) {
|
|
1454
|
+
settled = true;
|
|
1455
|
+
const err = new Error(`Cursor agent timed out after ${this.timeoutMs / 1e3}s. Set CALIBER_CURSOR_TIMEOUT_MS to increase.`);
|
|
1456
|
+
callbacks.onError(err);
|
|
1457
|
+
reject(err);
|
|
1458
|
+
}
|
|
1459
|
+
}, this.timeoutMs);
|
|
1460
|
+
timer.unref();
|
|
1331
1461
|
child.stdout.on("data", (data) => {
|
|
1332
1462
|
buffer += data.toString("utf-8");
|
|
1333
1463
|
const lines = buffer.split("\n");
|
|
@@ -1352,16 +1482,26 @@ var CursorAcpProvider = class {
|
|
|
1352
1482
|
}
|
|
1353
1483
|
});
|
|
1354
1484
|
child.on("error", (err) => {
|
|
1355
|
-
|
|
1356
|
-
|
|
1485
|
+
clearTimeout(timer);
|
|
1486
|
+
if (!settled) {
|
|
1487
|
+
settled = true;
|
|
1488
|
+
callbacks.onError(err);
|
|
1489
|
+
reject(err);
|
|
1490
|
+
}
|
|
1357
1491
|
});
|
|
1358
1492
|
child.on("close", (code) => {
|
|
1493
|
+
clearTimeout(timer);
|
|
1494
|
+
if (settled) return;
|
|
1495
|
+
settled = true;
|
|
1359
1496
|
if (buffer.trim()) {
|
|
1360
1497
|
try {
|
|
1361
1498
|
const event = JSON.parse(buffer);
|
|
1362
1499
|
if (event.type === "assistant") {
|
|
1363
|
-
const
|
|
1364
|
-
if (
|
|
1500
|
+
const isDelta = "timestamp_ms" in event;
|
|
1501
|
+
if (isDelta) {
|
|
1502
|
+
const text = event.message?.content?.[0]?.text || event.content;
|
|
1503
|
+
if (text) callbacks.onText(text);
|
|
1504
|
+
}
|
|
1365
1505
|
} else if (event.type === "result") {
|
|
1366
1506
|
endCalled = true;
|
|
1367
1507
|
callbacks.onEnd({ stopReason: event.is_error ? "error" : "end_turn" });
|
|
@@ -1374,9 +1514,16 @@ var CursorAcpProvider = class {
|
|
|
1374
1514
|
callbacks.onEnd({ stopReason: code === 0 ? "end_turn" : "error" });
|
|
1375
1515
|
}
|
|
1376
1516
|
if (code !== 0 && code !== null) {
|
|
1377
|
-
const
|
|
1378
|
-
|
|
1379
|
-
|
|
1517
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
|
|
1518
|
+
if (isRateLimitError(stderr)) {
|
|
1519
|
+
const err = new Error("Rate limit exceeded");
|
|
1520
|
+
callbacks.onError(err);
|
|
1521
|
+
reject(err);
|
|
1522
|
+
} else {
|
|
1523
|
+
const err = new Error(this.buildErrorMessage(code, stderrChunks));
|
|
1524
|
+
callbacks.onError(err);
|
|
1525
|
+
reject(err);
|
|
1526
|
+
}
|
|
1380
1527
|
} else {
|
|
1381
1528
|
resolve2();
|
|
1382
1529
|
}
|
|
@@ -1403,28 +1550,48 @@ var CursorAcpProvider = class {
|
|
|
1403
1550
|
};
|
|
1404
1551
|
function isCursorAgentAvailable() {
|
|
1405
1552
|
try {
|
|
1406
|
-
const cmd =
|
|
1553
|
+
const cmd = IS_WINDOWS ? `where ${AGENT_BIN}` : `which ${AGENT_BIN}`;
|
|
1407
1554
|
execSync3(cmd, { stdio: "ignore" });
|
|
1408
1555
|
return true;
|
|
1409
1556
|
} catch {
|
|
1410
1557
|
return false;
|
|
1411
1558
|
}
|
|
1412
1559
|
}
|
|
1560
|
+
function isCursorLoggedIn() {
|
|
1561
|
+
try {
|
|
1562
|
+
const result = execSync3(`${AGENT_BIN} status`, { stdio: ["ignore", "pipe", "ignore"], timeout: 5e3 });
|
|
1563
|
+
return !result.toString().includes("not logged in");
|
|
1564
|
+
} catch {
|
|
1565
|
+
return false;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1413
1568
|
|
|
1414
1569
|
// src/llm/claude-cli.ts
|
|
1415
1570
|
import { spawn as spawn2, execSync as execSync4 } from "child_process";
|
|
1416
1571
|
var CLAUDE_CLI_BIN = "claude";
|
|
1417
|
-
var
|
|
1572
|
+
var DEFAULT_TIMEOUT_MS2 = 10 * 60 * 1e3;
|
|
1418
1573
|
var IS_WINDOWS2 = process.platform === "win32";
|
|
1574
|
+
function spawnClaude(args) {
|
|
1575
|
+
return IS_WINDOWS2 ? spawn2([CLAUDE_CLI_BIN, ...args].join(" "), {
|
|
1576
|
+
cwd: process.cwd(),
|
|
1577
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1578
|
+
env: process.env,
|
|
1579
|
+
shell: true
|
|
1580
|
+
}) : spawn2(CLAUDE_CLI_BIN, args, {
|
|
1581
|
+
cwd: process.cwd(),
|
|
1582
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1583
|
+
env: process.env
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1419
1586
|
var ClaudeCliProvider = class {
|
|
1420
1587
|
defaultModel;
|
|
1421
1588
|
timeoutMs;
|
|
1422
1589
|
constructor(config) {
|
|
1423
1590
|
this.defaultModel = config.model || "default";
|
|
1424
1591
|
const envTimeout = process.env.CALIBER_CLAUDE_CLI_TIMEOUT_MS;
|
|
1425
|
-
this.timeoutMs = envTimeout ? parseInt(envTimeout, 10) :
|
|
1592
|
+
this.timeoutMs = envTimeout ? parseInt(envTimeout, 10) : DEFAULT_TIMEOUT_MS2;
|
|
1426
1593
|
if (!Number.isFinite(this.timeoutMs) || this.timeoutMs < 1e3) {
|
|
1427
|
-
this.timeoutMs =
|
|
1594
|
+
this.timeoutMs = DEFAULT_TIMEOUT_MS2;
|
|
1428
1595
|
}
|
|
1429
1596
|
}
|
|
1430
1597
|
async call(options) {
|
|
@@ -1435,23 +1602,16 @@ var ClaudeCliProvider = class {
|
|
|
1435
1602
|
const combined = this.buildCombinedPrompt(options);
|
|
1436
1603
|
const args = ["-p"];
|
|
1437
1604
|
if (options.model) args.push("--model", options.model);
|
|
1438
|
-
const child =
|
|
1439
|
-
cwd: process.cwd(),
|
|
1440
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
1441
|
-
env: process.env,
|
|
1442
|
-
shell: true
|
|
1443
|
-
}) : spawn2(CLAUDE_CLI_BIN, args, {
|
|
1444
|
-
cwd: process.cwd(),
|
|
1445
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
1446
|
-
env: process.env
|
|
1447
|
-
});
|
|
1605
|
+
const child = spawnClaude(args);
|
|
1448
1606
|
child.stdin.end(combined);
|
|
1449
1607
|
let settled = false;
|
|
1450
1608
|
const chunks = [];
|
|
1609
|
+
const stderrChunks = [];
|
|
1451
1610
|
child.stdout.on("data", (chunk) => {
|
|
1452
1611
|
chunks.push(chunk);
|
|
1453
1612
|
callbacks.onText(chunk.toString("utf-8"));
|
|
1454
1613
|
});
|
|
1614
|
+
child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
1455
1615
|
const timer = setTimeout(() => {
|
|
1456
1616
|
child.kill("SIGTERM");
|
|
1457
1617
|
if (!settled) {
|
|
@@ -1477,45 +1637,40 @@ var ClaudeCliProvider = class {
|
|
|
1477
1637
|
if (code === 0) {
|
|
1478
1638
|
callbacks.onEnd({ stopReason: "end_turn" });
|
|
1479
1639
|
} else {
|
|
1640
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
|
|
1641
|
+
const friendly = parseSeatBasedError(stderr, code);
|
|
1480
1642
|
const stdout = Buffer.concat(chunks).toString("utf-8").trim();
|
|
1481
|
-
const
|
|
1482
|
-
|
|
1643
|
+
const base = signal ? `Claude CLI killed (${signal})` : code != null ? `Claude CLI exited with code ${code}` : "Claude CLI exited";
|
|
1644
|
+
const detail = friendly || stderr || (stdout ? stdout.slice(0, 200) : "");
|
|
1645
|
+
callbacks.onError(new Error(detail ? `${base}. ${detail}` : base));
|
|
1483
1646
|
}
|
|
1484
1647
|
});
|
|
1485
1648
|
}
|
|
1486
1649
|
buildCombinedPrompt(options) {
|
|
1487
1650
|
const streamOpts = options;
|
|
1488
1651
|
const hasHistory = streamOpts.messages && streamOpts.messages.length > 0;
|
|
1489
|
-
let combined = "";
|
|
1490
|
-
combined += "[[System]]\n" + options.system + "\n\n";
|
|
1652
|
+
let combined = options.system + "\n\n";
|
|
1491
1653
|
if (hasHistory) {
|
|
1492
1654
|
for (const msg of streamOpts.messages) {
|
|
1493
|
-
|
|
1494
|
-
${msg.content}
|
|
1655
|
+
const label = msg.role === "user" ? "User" : "Assistant";
|
|
1656
|
+
combined += `${label}: ${msg.content}
|
|
1495
1657
|
|
|
1496
1658
|
`;
|
|
1497
1659
|
}
|
|
1498
1660
|
}
|
|
1499
|
-
combined +=
|
|
1661
|
+
combined += options.prompt;
|
|
1500
1662
|
return combined;
|
|
1501
1663
|
}
|
|
1502
1664
|
runClaudePrint(combinedPrompt, model) {
|
|
1503
1665
|
return new Promise((resolve2, reject) => {
|
|
1504
1666
|
const args = ["-p"];
|
|
1505
1667
|
if (model) args.push("--model", model);
|
|
1506
|
-
const child =
|
|
1507
|
-
cwd: process.cwd(),
|
|
1508
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
1509
|
-
env: process.env,
|
|
1510
|
-
shell: true
|
|
1511
|
-
}) : spawn2(CLAUDE_CLI_BIN, args, {
|
|
1512
|
-
cwd: process.cwd(),
|
|
1513
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
1514
|
-
env: process.env
|
|
1515
|
-
});
|
|
1668
|
+
const child = spawnClaude(args);
|
|
1516
1669
|
child.stdin.end(combinedPrompt);
|
|
1517
1670
|
const chunks = [];
|
|
1671
|
+
const stderrChunks = [];
|
|
1518
1672
|
child.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
1673
|
+
child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
1519
1674
|
child.on("error", (err) => {
|
|
1520
1675
|
clearTimeout(timer);
|
|
1521
1676
|
reject(err);
|
|
@@ -1526,8 +1681,11 @@ ${msg.content}
|
|
|
1526
1681
|
if (code === 0) {
|
|
1527
1682
|
resolve2(stdout);
|
|
1528
1683
|
} else {
|
|
1529
|
-
const
|
|
1530
|
-
|
|
1684
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
|
|
1685
|
+
const friendly = parseSeatBasedError(stderr, code);
|
|
1686
|
+
const base = signal ? `Claude CLI killed (${signal})` : code != null ? `Claude CLI exited with code ${code}` : "Claude CLI exited";
|
|
1687
|
+
const detail = friendly || stderr || (stdout ? stdout.slice(0, 200) : "");
|
|
1688
|
+
reject(new Error(detail ? `${base}. ${detail}` : base));
|
|
1531
1689
|
}
|
|
1532
1690
|
});
|
|
1533
1691
|
const timer = setTimeout(() => {
|
|
@@ -1701,6 +1859,7 @@ async function handleModelNotAvailable(failedModel, provider, config) {
|
|
|
1701
1859
|
}
|
|
1702
1860
|
|
|
1703
1861
|
// src/llm/index.ts
|
|
1862
|
+
init_types();
|
|
1704
1863
|
init_config();
|
|
1705
1864
|
var cachedProvider = null;
|
|
1706
1865
|
var cachedConfig = null;
|
|
@@ -1776,11 +1935,11 @@ async function llmCall(options) {
|
|
|
1776
1935
|
throw error;
|
|
1777
1936
|
}
|
|
1778
1937
|
if (isOverloaded(error) && attempt < MAX_RETRIES) {
|
|
1779
|
-
await new Promise((r) => setTimeout(r,
|
|
1938
|
+
await new Promise((r) => setTimeout(r, 1e3 * Math.pow(2, attempt - 1)));
|
|
1780
1939
|
continue;
|
|
1781
1940
|
}
|
|
1782
1941
|
if (isTransientError(error) && attempt < MAX_RETRIES) {
|
|
1783
|
-
await new Promise((r) => setTimeout(r,
|
|
1942
|
+
await new Promise((r) => setTimeout(r, 1e3 * Math.pow(2, attempt - 1)));
|
|
1784
1943
|
continue;
|
|
1785
1944
|
}
|
|
1786
1945
|
throw error;
|
|
@@ -1796,7 +1955,8 @@ async function validateModel(options) {
|
|
|
1796
1955
|
const provider = getProvider();
|
|
1797
1956
|
const config = cachedConfig;
|
|
1798
1957
|
if (!config) return;
|
|
1799
|
-
|
|
1958
|
+
const { isSeatBased: isSeatBased2 } = await Promise.resolve().then(() => (init_types(), types_exports));
|
|
1959
|
+
if (isSeatBased2(config.provider)) return;
|
|
1800
1960
|
const modelsToCheck = [config.model];
|
|
1801
1961
|
if (options?.fast) {
|
|
1802
1962
|
const { getFastModel: getFastModel2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -4196,8 +4356,11 @@ async function runInteractiveProviderSetup(options) {
|
|
|
4196
4356
|
console.log(chalk5.dim(" Then run ") + chalk5.hex("#83D1EB")("agent login") + chalk5.dim(" to authenticate.\n"));
|
|
4197
4357
|
const proceed = await confirm({ message: "Continue anyway?" });
|
|
4198
4358
|
if (!proceed) throw new Error("__exit__");
|
|
4199
|
-
} else {
|
|
4200
|
-
console.log(chalk5.
|
|
4359
|
+
} else if (!isCursorLoggedIn()) {
|
|
4360
|
+
console.log(chalk5.yellow("\n Cursor Agent CLI found but not logged in."));
|
|
4361
|
+
console.log(chalk5.dim(" Run ") + chalk5.hex("#83D1EB")("agent login") + chalk5.dim(" to authenticate.\n"));
|
|
4362
|
+
const proceed = await confirm({ message: "Continue anyway?" });
|
|
4363
|
+
if (!proceed) throw new Error("__exit__");
|
|
4201
4364
|
}
|
|
4202
4365
|
break;
|
|
4203
4366
|
}
|
package/package.json
CHANGED