@sideboard-ai/core 0.1.283 → 0.1.285
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/{abletime-WLDBJJUI.js → abletime-4CH2IOX5.js} +4 -4
- package/dist/{abletime-X64E3GUJ.js → abletime-I4RODUKT.js} +4 -4
- package/dist/{abletime-oauth-AXR676W5.js → abletime-oauth-7OZZ3ABX.js} +3 -3
- package/dist/{abletime-oauth-UWOCEICP.js → abletime-oauth-C2HN2Q6F.js} +3 -3
- package/dist/{abletime-rest-S4XWEXV2.js → abletime-rest-E4LBRFLM.js} +3 -3
- package/dist/{abletime-rest-LPUDJUEP.js → abletime-rest-WFI2HWBU.js} +3 -3
- package/dist/agents/cursor-runner.cjs +54 -14
- package/dist/agents/cursor-runner.js +51 -14
- package/dist/{agents-XA2E64AW.js → agents-FKMYAKFD.js} +5 -5
- package/dist/{agents-2IE4HKHA.js → agents-ITNCZ6CA.js} +7 -7
- package/dist/chunk-2GPQZZLY.js +59 -0
- package/dist/{chunk-BYZ7F2BQ.js → chunk-2K723QZH.js} +12 -10
- package/dist/{chunk-ROPGQRPU.js → chunk-33KDPEK4.js} +1 -1
- package/dist/{chunk-W7HIK2A6.js → chunk-5QOLFOAX.js} +19 -3
- package/dist/{chunk-I6HSGKMZ.js → chunk-5T4YWFLD.js} +2 -2
- package/dist/{chunk-U7HAVAGJ.js → chunk-6CVVNAIU.js} +2 -2
- package/dist/{chunk-TQRSVE7D.js → chunk-7IAMHN2N.js} +1 -1
- package/dist/{chunk-DQZPF6WL.js → chunk-BMUVNTT4.js} +3 -3
- package/dist/{chunk-2KNO2GJQ.js → chunk-C6NVTLZK.js} +16 -14
- package/dist/{chunk-VA55JG2I.js → chunk-DEJALWKM.js} +5 -5
- package/dist/{chunk-XTPQEZZA.js → chunk-IJMUYHPT.js} +3 -3
- package/dist/chunk-JAT3JFOS.js +61 -0
- package/dist/{chunk-EIEAR62M.js → chunk-LMWPVC5L.js} +2 -2
- package/dist/{chunk-DGPROCE5.js → chunk-LS4FFCPL.js} +3 -3
- package/dist/{chunk-P2BSMNHB.js → chunk-PXMLMBMI.js} +1 -1
- package/dist/{chunk-UZUXWBXK.js → chunk-S2OOM7AU.js} +1 -1
- package/dist/{chunk-BS3QLVPL.js → chunk-TMM4FEZ5.js} +3 -3
- package/dist/{chunk-ADXVTKLC.js → chunk-TXHZJESB.js} +4 -4
- package/dist/{chunk-K2S33ZCB.js → chunk-U6QDXT4K.js} +20 -4
- package/dist/{chunk-GWFVCCJZ.js → chunk-VGNLMGBK.js} +6 -6
- package/dist/{chunk-IFURHRAR.js → chunk-VOIWX5HA.js} +1 -1
- package/dist/{chunk-PY4UCMRI.js → chunk-VQEARG5H.js} +5 -5
- package/dist/{chunk-BDAUPNHL.js → chunk-XSDCLM3F.js} +1 -1
- package/dist/{chunk-OCUIZD4Y.js → chunk-XSPOJFTV.js} +6 -6
- package/dist/{conductor-U776JSXQ.js → conductor-GBX6LSP2.js} +3 -3
- package/dist/{conductor-CNSCOC54.js → conductor-MU3TYVCD.js} +2 -2
- package/dist/{connected-teams-JIUOSZ6C.js → connected-teams-AB7ZHJVO.js} +3 -3
- package/dist/{connected-teams-RU6VATCM.js → connected-teams-BJ6PMIST.js} +3 -3
- package/dist/index.cjs +241 -120
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +176 -101
- package/dist/mcp/run-stdio.cjs +68 -25
- package/dist/mcp/run-stdio.js +10 -10
- package/dist/{oauth-S3M7B475.js → oauth-DP4ZV2M2.js} +2 -2
- package/dist/{oauth-K6CWZEQO.js → oauth-WCUZ6Z5G.js} +2 -2
- package/dist/{orchestrator-FPGVKEID.js → orchestrator-F7KXYDQW.js} +9 -9
- package/dist/{orchestrator-HWJHK5NL.js → orchestrator-VUIRO6NC.js} +7 -7
- package/package.json +1 -1
- package/dist/chunk-N7WZ6NIN.js +0 -41
- package/dist/chunk-VKQGAWHY.js +0 -40
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
toAbleTimeIssueInfo,
|
|
19
19
|
updateAbleTimeTask,
|
|
20
20
|
verifyAbleTimeConnection
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-TMM4FEZ5.js";
|
|
22
|
+
import "./chunk-5T4YWFLD.js";
|
|
23
|
+
import "./chunk-VQEARG5H.js";
|
|
24
|
+
import "./chunk-2GPQZZLY.js";
|
|
25
25
|
import "./chunk-N2WW62LF.js";
|
|
26
26
|
import "./chunk-WRIMAEF2.js";
|
|
27
27
|
import "./chunk-NSTQ6QKD.js";
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
toAbleTimeIssueInfo,
|
|
17
17
|
updateAbleTimeTask,
|
|
18
18
|
verifyAbleTimeConnection
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-LS4FFCPL.js";
|
|
20
|
+
import "./chunk-6CVVNAIU.js";
|
|
21
|
+
import "./chunk-DEJALWKM.js";
|
|
22
|
+
import "./chunk-JAT3JFOS.js";
|
|
23
23
|
import "./chunk-6K64FJDD.js";
|
|
24
24
|
import "./chunk-YNTXWFXT.js";
|
|
25
25
|
import "./chunk-77WWLBCI.js";
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import {
|
|
4
4
|
DEFAULT_ABLETIME_HOST,
|
|
5
5
|
normalizeAbleTimeHost
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VQEARG5H.js";
|
|
7
7
|
import {
|
|
8
8
|
httpFetch
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2GPQZZLY.js";
|
|
10
10
|
import {
|
|
11
11
|
disconnectAbleTimeConnection,
|
|
12
12
|
getAbleTimeHost,
|
|
@@ -288,7 +288,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
288
288
|
persistAbleTimeTokens(data, { host });
|
|
289
289
|
const token = data.access_token.trim();
|
|
290
290
|
try {
|
|
291
|
-
const { getAbleTimeOrientation } = await import("./abletime-
|
|
291
|
+
const { getAbleTimeOrientation } = await import("./abletime-4CH2IOX5.js");
|
|
292
292
|
const orientation = await getAbleTimeOrientation({ token, host });
|
|
293
293
|
return saveAbleTimeConnection({
|
|
294
294
|
accessToken: token,
|
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
parseAbleTimeOAuthCallbackUrl,
|
|
21
21
|
resolveAbleTimeOAuthHost,
|
|
22
22
|
startAbleTimeOAuth
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-IJMUYHPT.js";
|
|
24
|
+
import "./chunk-DEJALWKM.js";
|
|
25
|
+
import "./chunk-JAT3JFOS.js";
|
|
26
26
|
import "./chunk-YNTXWFXT.js";
|
|
27
27
|
import "./chunk-77WWLBCI.js";
|
|
28
28
|
import "./chunk-4TR3HZFT.js";
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
callAbleTimeRestTool,
|
|
6
6
|
looksLikeAbleTimeUlid,
|
|
7
7
|
textFromAbleTimeDoc
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-6CVVNAIU.js";
|
|
9
|
+
import "./chunk-DEJALWKM.js";
|
|
10
|
+
import "./chunk-JAT3JFOS.js";
|
|
11
11
|
import "./chunk-YNTXWFXT.js";
|
|
12
12
|
import "./chunk-77WWLBCI.js";
|
|
13
13
|
import "./chunk-4TR3HZFT.js";
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
callAbleTimeRestTool,
|
|
8
8
|
looksLikeAbleTimeUlid,
|
|
9
9
|
textFromAbleTimeDoc
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-5T4YWFLD.js";
|
|
11
|
+
import "./chunk-VQEARG5H.js";
|
|
12
|
+
import "./chunk-2GPQZZLY.js";
|
|
13
13
|
import "./chunk-WRIMAEF2.js";
|
|
14
14
|
import "./chunk-NSTQ6QKD.js";
|
|
15
15
|
import "./chunk-WWUABK6B.js";
|
|
@@ -359,6 +359,12 @@ function sanitizeCursorStoreSegment(threadId) {
|
|
|
359
359
|
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
+
// src/agents/cursor-stream-cutoff.ts
|
|
363
|
+
var CURSOR_STREAM_CUTOFF = /nghttp2|premature close|\[unavailable\]\s+error\b|http\/2 stream closed|\bcancel \(0x8\)|error code cancel\b/i;
|
|
364
|
+
function looksLikeCursorStreamCutOff(text) {
|
|
365
|
+
return CURSOR_STREAM_CUTOFF.test(text.trim());
|
|
366
|
+
}
|
|
367
|
+
|
|
362
368
|
// src/agents/error-detail.ts
|
|
363
369
|
function formatUnknownDetail(err) {
|
|
364
370
|
if (err == null) return "";
|
|
@@ -475,9 +481,6 @@ ${content.slice(-tail)}`;
|
|
|
475
481
|
}
|
|
476
482
|
var HUGE_TOOL_RESULT_SUMMARY = "Agent crashed mid-turn after a huge tool result. Write CLI/HTTP output to .context/cli/ and read a slice \u2014 never dump raw --json/--expand into the tool result.";
|
|
477
483
|
var TOOL_RESULT_STORE_MAX_CHARS = 8e3;
|
|
478
|
-
function looksLikeCursorStreamCutOff(text) {
|
|
479
|
-
return /nghttp2|premature close|\[unavailable\]\s+error\b/i.test(text.trim());
|
|
480
|
-
}
|
|
481
484
|
|
|
482
485
|
// src/agents/cursor-session.ts
|
|
483
486
|
function cursorErrorMessage(err) {
|
|
@@ -487,8 +490,10 @@ function cursorErrorMessage(err) {
|
|
|
487
490
|
function isAgentBusyError(err) {
|
|
488
491
|
const name = err instanceof Error ? err.name : "";
|
|
489
492
|
if (name === "AgentBusyError") return true;
|
|
490
|
-
|
|
493
|
+
const message = cursorErrorMessage(err);
|
|
494
|
+
return /already has active run/i.test(message) || /agent still running/i.test(message) || /\[agent_busy\]/i.test(message);
|
|
491
495
|
}
|
|
496
|
+
var CURSOR_BUSY_RETRY_DELAY_MS = 400;
|
|
492
497
|
function isUnresumableCursorSession(err) {
|
|
493
498
|
const name = err instanceof Error ? err.name : "";
|
|
494
499
|
if (name === "AgentNotFoundError") return true;
|
|
@@ -1505,14 +1510,14 @@ function localAgentStore(Store, threadId) {
|
|
|
1505
1510
|
(0, import_node_fs17.mkdirSync)(root, { recursive: true });
|
|
1506
1511
|
return new Store(root);
|
|
1507
1512
|
}
|
|
1508
|
-
async function
|
|
1513
|
+
async function cancelStaleRuns(Agent, agentId, opts) {
|
|
1514
|
+
let cancelled = 0;
|
|
1509
1515
|
const listed = await Agent.listRuns(agentId, {
|
|
1510
1516
|
runtime: "local",
|
|
1511
1517
|
cwd: opts.cwd,
|
|
1512
1518
|
store: opts.store,
|
|
1513
1519
|
limit: 20
|
|
1514
1520
|
});
|
|
1515
|
-
let cancelled = 0;
|
|
1516
1521
|
for (const run2 of listed.items) {
|
|
1517
1522
|
if (run2.status !== "running") continue;
|
|
1518
1523
|
try {
|
|
@@ -1525,6 +1530,27 @@ async function cancelStaleLocalRuns(Agent, agentId, opts) {
|
|
|
1525
1530
|
} catch {
|
|
1526
1531
|
}
|
|
1527
1532
|
}
|
|
1533
|
+
if (cancelled > 0 || !opts.apiKey) return cancelled;
|
|
1534
|
+
try {
|
|
1535
|
+
const cloud = await Agent.listRuns(agentId, {
|
|
1536
|
+
runtime: "cloud",
|
|
1537
|
+
apiKey: opts.apiKey,
|
|
1538
|
+
limit: 20
|
|
1539
|
+
});
|
|
1540
|
+
for (const run2 of cloud.items) {
|
|
1541
|
+
if (run2.status !== "running") continue;
|
|
1542
|
+
try {
|
|
1543
|
+
await Agent.cancelRun(run2.id, {
|
|
1544
|
+
runtime: "cloud",
|
|
1545
|
+
agentId,
|
|
1546
|
+
apiKey: opts.apiKey
|
|
1547
|
+
});
|
|
1548
|
+
cancelled += 1;
|
|
1549
|
+
} catch {
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
} catch {
|
|
1553
|
+
}
|
|
1528
1554
|
return cancelled;
|
|
1529
1555
|
}
|
|
1530
1556
|
async function readStdinJson() {
|
|
@@ -1640,6 +1666,20 @@ async function main() {
|
|
|
1640
1666
|
return createAgent();
|
|
1641
1667
|
}
|
|
1642
1668
|
}
|
|
1669
|
+
async function retryAfterBusy(agent) {
|
|
1670
|
+
const n = await cancelStaleRuns(Agent, agent.agentId, {
|
|
1671
|
+
cwd: req.cwd,
|
|
1672
|
+
store,
|
|
1673
|
+
...apiKey ? { apiKey } : {}
|
|
1674
|
+
});
|
|
1675
|
+
emit({
|
|
1676
|
+
type: "stderr",
|
|
1677
|
+
data: n > 0 ? `Cursor agent had ${n} stale active run(s) \u2014 cancelled and retrying` : "Cursor agent busy \u2014 retrying send"
|
|
1678
|
+
});
|
|
1679
|
+
if (CURSOR_BUSY_RETRY_DELAY_MS > 0) {
|
|
1680
|
+
await new Promise((resolve2) => setTimeout(resolve2, CURSOR_BUSY_RETRY_DELAY_MS));
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1643
1683
|
async function sendPrompt(agent, extra) {
|
|
1644
1684
|
const sendOpts = {
|
|
1645
1685
|
...cursorSendOptions(mcpServers),
|
|
@@ -1649,14 +1689,7 @@ async function main() {
|
|
|
1649
1689
|
return await retryTransport(() => agent.send(req.prompt, sendOpts));
|
|
1650
1690
|
} catch (err) {
|
|
1651
1691
|
if (!isAgentBusyError(err)) throw err;
|
|
1652
|
-
|
|
1653
|
-
cwd: req.cwd,
|
|
1654
|
-
store
|
|
1655
|
-
});
|
|
1656
|
-
emit({
|
|
1657
|
-
type: "stderr",
|
|
1658
|
-
data: n > 0 ? `Cursor agent had ${n} stale active run(s) \u2014 cancelled and retrying` : "Cursor agent busy \u2014 retrying send"
|
|
1659
|
-
});
|
|
1692
|
+
await retryAfterBusy(agent);
|
|
1660
1693
|
return retryTransport(() => agent.send(req.prompt, sendOpts));
|
|
1661
1694
|
}
|
|
1662
1695
|
}
|
|
@@ -1739,6 +1772,9 @@ async function main() {
|
|
|
1739
1772
|
]) : await run2.wait();
|
|
1740
1773
|
if (result.status === "error") {
|
|
1741
1774
|
const detail = formatUnknownDetail(result.error);
|
|
1775
|
+
if (isAgentBusyError(detail)) {
|
|
1776
|
+
throw Object.assign(new Error(detail || "agent still running"), { name: "AgentBusyError" });
|
|
1777
|
+
}
|
|
1742
1778
|
emit({
|
|
1743
1779
|
type: "stderr",
|
|
1744
1780
|
data: detail ? `Cursor run failed (${result.id}): ${detail}` : `Cursor run failed (${result.id})`
|
|
@@ -1769,6 +1805,10 @@ async function main() {
|
|
|
1769
1805
|
try {
|
|
1770
1806
|
return await runTurn(agent);
|
|
1771
1807
|
} catch (err) {
|
|
1808
|
+
if (isAgentBusyError(err)) {
|
|
1809
|
+
await retryAfterBusy(agent);
|
|
1810
|
+
return await runTurn(agent);
|
|
1811
|
+
}
|
|
1772
1812
|
if (!isUnresumableCursorSession(err)) throw err;
|
|
1773
1813
|
emit({
|
|
1774
1814
|
type: "stderr",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
clipAgentEventForEmit,
|
|
4
4
|
sideboardCursorRpcTools
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-S2OOM7AU.js";
|
|
6
6
|
import {
|
|
7
7
|
createAgentStreamCoalescer
|
|
8
8
|
} from "../chunk-AXQ4ZWHK.js";
|
|
@@ -17,12 +17,12 @@ import {
|
|
|
17
17
|
fetchCursorTurnCostUsd,
|
|
18
18
|
importCursorSdk,
|
|
19
19
|
resolveCursorSdkRoot
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-VOIWX5HA.js";
|
|
21
21
|
import {
|
|
22
22
|
TOOL_RESULT_STORE_MAX_CHARS,
|
|
23
23
|
formatUnknownDetail,
|
|
24
24
|
looksLikeCursorStreamCutOff
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-U6QDXT4K.js";
|
|
26
26
|
import "../chunk-6K64FJDD.js";
|
|
27
27
|
import {
|
|
28
28
|
cursorSdkStoreDir
|
|
@@ -46,8 +46,10 @@ function cursorErrorMessage(err) {
|
|
|
46
46
|
function isAgentBusyError(err) {
|
|
47
47
|
const name = err instanceof Error ? err.name : "";
|
|
48
48
|
if (name === "AgentBusyError") return true;
|
|
49
|
-
|
|
49
|
+
const message = cursorErrorMessage(err);
|
|
50
|
+
return /already has active run/i.test(message) || /agent still running/i.test(message) || /\[agent_busy\]/i.test(message);
|
|
50
51
|
}
|
|
52
|
+
var CURSOR_BUSY_RETRY_DELAY_MS = 400;
|
|
51
53
|
function isUnresumableCursorSession(err) {
|
|
52
54
|
const name = err instanceof Error ? err.name : "";
|
|
53
55
|
if (name === "AgentNotFoundError") return true;
|
|
@@ -307,14 +309,14 @@ function localAgentStore(Store, threadId) {
|
|
|
307
309
|
mkdirSync(root, { recursive: true });
|
|
308
310
|
return new Store(root);
|
|
309
311
|
}
|
|
310
|
-
async function
|
|
312
|
+
async function cancelStaleRuns(Agent, agentId, opts) {
|
|
313
|
+
let cancelled = 0;
|
|
311
314
|
const listed = await Agent.listRuns(agentId, {
|
|
312
315
|
runtime: "local",
|
|
313
316
|
cwd: opts.cwd,
|
|
314
317
|
store: opts.store,
|
|
315
318
|
limit: 20
|
|
316
319
|
});
|
|
317
|
-
let cancelled = 0;
|
|
318
320
|
for (const run of listed.items) {
|
|
319
321
|
if (run.status !== "running") continue;
|
|
320
322
|
try {
|
|
@@ -327,6 +329,27 @@ async function cancelStaleLocalRuns(Agent, agentId, opts) {
|
|
|
327
329
|
} catch {
|
|
328
330
|
}
|
|
329
331
|
}
|
|
332
|
+
if (cancelled > 0 || !opts.apiKey) return cancelled;
|
|
333
|
+
try {
|
|
334
|
+
const cloud = await Agent.listRuns(agentId, {
|
|
335
|
+
runtime: "cloud",
|
|
336
|
+
apiKey: opts.apiKey,
|
|
337
|
+
limit: 20
|
|
338
|
+
});
|
|
339
|
+
for (const run of cloud.items) {
|
|
340
|
+
if (run.status !== "running") continue;
|
|
341
|
+
try {
|
|
342
|
+
await Agent.cancelRun(run.id, {
|
|
343
|
+
runtime: "cloud",
|
|
344
|
+
agentId,
|
|
345
|
+
apiKey: opts.apiKey
|
|
346
|
+
});
|
|
347
|
+
cancelled += 1;
|
|
348
|
+
} catch {
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
} catch {
|
|
352
|
+
}
|
|
330
353
|
return cancelled;
|
|
331
354
|
}
|
|
332
355
|
async function readStdinJson() {
|
|
@@ -442,6 +465,20 @@ async function main() {
|
|
|
442
465
|
return createAgent();
|
|
443
466
|
}
|
|
444
467
|
}
|
|
468
|
+
async function retryAfterBusy(agent) {
|
|
469
|
+
const n = await cancelStaleRuns(Agent, agent.agentId, {
|
|
470
|
+
cwd: req.cwd,
|
|
471
|
+
store,
|
|
472
|
+
...apiKey ? { apiKey } : {}
|
|
473
|
+
});
|
|
474
|
+
emit({
|
|
475
|
+
type: "stderr",
|
|
476
|
+
data: n > 0 ? `Cursor agent had ${n} stale active run(s) \u2014 cancelled and retrying` : "Cursor agent busy \u2014 retrying send"
|
|
477
|
+
});
|
|
478
|
+
if (CURSOR_BUSY_RETRY_DELAY_MS > 0) {
|
|
479
|
+
await new Promise((resolve2) => setTimeout(resolve2, CURSOR_BUSY_RETRY_DELAY_MS));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
445
482
|
async function sendPrompt(agent, extra) {
|
|
446
483
|
const sendOpts = {
|
|
447
484
|
...cursorSendOptions(mcpServers),
|
|
@@ -451,14 +488,7 @@ async function main() {
|
|
|
451
488
|
return await retryTransport(() => agent.send(req.prompt, sendOpts));
|
|
452
489
|
} catch (err) {
|
|
453
490
|
if (!isAgentBusyError(err)) throw err;
|
|
454
|
-
|
|
455
|
-
cwd: req.cwd,
|
|
456
|
-
store
|
|
457
|
-
});
|
|
458
|
-
emit({
|
|
459
|
-
type: "stderr",
|
|
460
|
-
data: n > 0 ? `Cursor agent had ${n} stale active run(s) \u2014 cancelled and retrying` : "Cursor agent busy \u2014 retrying send"
|
|
461
|
-
});
|
|
491
|
+
await retryAfterBusy(agent);
|
|
462
492
|
return retryTransport(() => agent.send(req.prompt, sendOpts));
|
|
463
493
|
}
|
|
464
494
|
}
|
|
@@ -541,6 +571,9 @@ async function main() {
|
|
|
541
571
|
]) : await run.wait();
|
|
542
572
|
if (result.status === "error") {
|
|
543
573
|
const detail = formatUnknownDetail(result.error);
|
|
574
|
+
if (isAgentBusyError(detail)) {
|
|
575
|
+
throw Object.assign(new Error(detail || "agent still running"), { name: "AgentBusyError" });
|
|
576
|
+
}
|
|
544
577
|
emit({
|
|
545
578
|
type: "stderr",
|
|
546
579
|
data: detail ? `Cursor run failed (${result.id}): ${detail}` : `Cursor run failed (${result.id})`
|
|
@@ -571,6 +604,10 @@ async function main() {
|
|
|
571
604
|
try {
|
|
572
605
|
return await runTurn(agent);
|
|
573
606
|
} catch (err) {
|
|
607
|
+
if (isAgentBusyError(err)) {
|
|
608
|
+
await retryAfterBusy(agent);
|
|
609
|
+
return await runTurn(agent);
|
|
610
|
+
}
|
|
574
611
|
if (!isUnresumableCursorSession(err)) throw err;
|
|
575
612
|
emit({
|
|
576
613
|
type: "stderr",
|
|
@@ -56,11 +56,11 @@ import {
|
|
|
56
56
|
resolveQuotaFallbackAgent,
|
|
57
57
|
turnCostUsdFromCursorUsage,
|
|
58
58
|
whichOnPath
|
|
59
|
-
} from "./chunk-
|
|
60
|
-
import "./chunk-
|
|
61
|
-
import "./chunk-
|
|
62
|
-
import "./chunk-
|
|
63
|
-
import "./chunk-
|
|
59
|
+
} from "./chunk-TXHZJESB.js";
|
|
60
|
+
import "./chunk-7IAMHN2N.js";
|
|
61
|
+
import "./chunk-PXMLMBMI.js";
|
|
62
|
+
import "./chunk-2GPQZZLY.js";
|
|
63
|
+
import "./chunk-5QOLFOAX.js";
|
|
64
64
|
import "./chunk-2SJXQ4UX.js";
|
|
65
65
|
import "./chunk-5MGLNVNK.js";
|
|
66
66
|
import "./chunk-N2WW62LF.js";
|
|
@@ -47,15 +47,15 @@ import {
|
|
|
47
47
|
resolveLoginCommand,
|
|
48
48
|
resolveQuotaFallbackAgent,
|
|
49
49
|
whichOnPath
|
|
50
|
-
} from "./chunk-
|
|
51
|
-
import "./chunk-
|
|
52
|
-
import "./chunk-
|
|
50
|
+
} from "./chunk-XSPOJFTV.js";
|
|
51
|
+
import "./chunk-VGNLMGBK.js";
|
|
52
|
+
import "./chunk-XSDCLM3F.js";
|
|
53
53
|
import "./chunk-WY2IAB7J.js";
|
|
54
54
|
import "./chunk-K5XSTHHP.js";
|
|
55
55
|
import "./chunk-N5UGX3JL.js";
|
|
56
56
|
import "./chunk-2P4XKWV2.js";
|
|
57
|
-
import "./chunk-
|
|
58
|
-
import "./chunk-
|
|
57
|
+
import "./chunk-33KDPEK4.js";
|
|
58
|
+
import "./chunk-JAT3JFOS.js";
|
|
59
59
|
import {
|
|
60
60
|
CURSOR_SDK_INSTALL_HINT,
|
|
61
61
|
cursorSdkMessageToEvents,
|
|
@@ -64,8 +64,8 @@ import {
|
|
|
64
64
|
preferredCursorCostCents,
|
|
65
65
|
resolveCursorSdkRoot,
|
|
66
66
|
turnCostUsdFromCursorUsage
|
|
67
|
-
} from "./chunk-
|
|
68
|
-
import "./chunk-
|
|
67
|
+
} from "./chunk-VOIWX5HA.js";
|
|
68
|
+
import "./chunk-U6QDXT4K.js";
|
|
69
69
|
import "./chunk-6K64FJDD.js";
|
|
70
70
|
import "./chunk-UWQ6UCIB.js";
|
|
71
71
|
import {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// src/http/fetch.ts
|
|
5
|
+
var injected = null;
|
|
6
|
+
var TLS_ISSUER_RE = /UNABLE_TO_GET_ISSUER_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE|SELF_SIGNED_CERT_IN_CHAIN/i;
|
|
7
|
+
var TLS_ISSUER_HINT = " \u2014 Node rejected the TLS certificate (corporate VPN/proxy CA). Desktop Linear can still work; reconnecting the API key will not fix this.";
|
|
8
|
+
function isTlsIssuerFailure(code, message) {
|
|
9
|
+
return TLS_ISSUER_RE.test(`${code ?? ""} ${message}`);
|
|
10
|
+
}
|
|
11
|
+
function describeCause(cause, depth = 0) {
|
|
12
|
+
if (depth > 5 || cause == null) return null;
|
|
13
|
+
if (cause instanceof AggregateError) {
|
|
14
|
+
for (const item of cause.errors) {
|
|
15
|
+
const found = describeCause(item, depth + 1);
|
|
16
|
+
if (found && (found.code || found.message)) return found;
|
|
17
|
+
}
|
|
18
|
+
return cause.message ? { message: cause.message } : null;
|
|
19
|
+
}
|
|
20
|
+
if (cause instanceof Error) {
|
|
21
|
+
const code = typeof cause.code === "string" ? cause.code : void 0;
|
|
22
|
+
const nested = describeCause(cause.cause, depth + 1);
|
|
23
|
+
if ((!cause.message || cause.message === "fetch failed") && nested) return nested;
|
|
24
|
+
if (cause.message || code) return { code, message: cause.message };
|
|
25
|
+
return nested;
|
|
26
|
+
}
|
|
27
|
+
return { message: String(cause) };
|
|
28
|
+
}
|
|
29
|
+
function causeSuffix(detail) {
|
|
30
|
+
if (!detail) return "";
|
|
31
|
+
if (detail.code && detail.message) return ` [${detail.code}: ${detail.message}]`;
|
|
32
|
+
if (detail.code) return ` [${detail.code}]`;
|
|
33
|
+
if (detail.message) return ` [${detail.message}]`;
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
function formatFetchError(err, url, opts) {
|
|
37
|
+
if (!(err instanceof Error)) return `${String(err)} (${url})`;
|
|
38
|
+
const detail = describeCause(err.cause);
|
|
39
|
+
const hintSource = `${err.message} ${detail?.code ?? ""} ${detail?.message ?? ""}`;
|
|
40
|
+
const tls = isTlsIssuerFailure(detail?.code, hintSource);
|
|
41
|
+
const hint = tls ? opts?.tlsHint ?? TLS_ISSUER_HINT : "";
|
|
42
|
+
return `${err.message}${causeSuffix(detail)} (${url})${hint}`;
|
|
43
|
+
}
|
|
44
|
+
function currentHttpFetch() {
|
|
45
|
+
return injected ?? globalThis.fetch.bind(globalThis);
|
|
46
|
+
}
|
|
47
|
+
async function httpFetch(input, init) {
|
|
48
|
+
const url = typeof input === "string" ? input : input.href;
|
|
49
|
+
try {
|
|
50
|
+
return await currentHttpFetch()(url, init);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
throw new Error(formatFetchError(err, url));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
formatFetchError,
|
|
58
|
+
httpFetch
|
|
59
|
+
};
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
parseSessionQuotaResetAt,
|
|
24
24
|
planModeTurnInstruction,
|
|
25
25
|
resolveQuotaFallbackAgent
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-TXHZJESB.js";
|
|
27
27
|
import {
|
|
28
28
|
REVIEW_TAB_TITLE,
|
|
29
29
|
applyWorktreePkgCacheEnv,
|
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
worktreeDevProcessKey,
|
|
63
63
|
worktreeRunProcessKey,
|
|
64
64
|
worktreeSetupProcessKey
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-LMWPVC5L.js";
|
|
66
66
|
import {
|
|
67
67
|
applyAgentEvent,
|
|
68
68
|
clipAgentEventForPaint,
|
|
@@ -78,6 +78,7 @@ import {
|
|
|
78
78
|
looksLikeInvalidAgentSession,
|
|
79
79
|
looksLikeV8Oom,
|
|
80
80
|
messagePartParentId,
|
|
81
|
+
nextCrashContinueCount,
|
|
81
82
|
normalizeParseResult,
|
|
82
83
|
partsToAssistantText,
|
|
83
84
|
pushTurnStderr,
|
|
@@ -88,7 +89,7 @@ import {
|
|
|
88
89
|
summarizeTurnStderr,
|
|
89
90
|
toolDescription,
|
|
90
91
|
turnFailChatText
|
|
91
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-5QOLFOAX.js";
|
|
92
93
|
import {
|
|
93
94
|
SLACK_REPLY_FORMATTING,
|
|
94
95
|
addWorkspace,
|
|
@@ -2506,7 +2507,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2506
2507
|
let sourceIsFork = false;
|
|
2507
2508
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
2508
2509
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
2509
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
2510
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-4CH2IOX5.js");
|
|
2510
2511
|
const task = await ensureAbleTimeTask({
|
|
2511
2512
|
title: title?.trim() || "Untitled work",
|
|
2512
2513
|
description: input.prompt?.trim() || void 0
|
|
@@ -6093,7 +6094,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6093
6094
|
${prompt}`;
|
|
6094
6095
|
}
|
|
6095
6096
|
async function defaultDeps() {
|
|
6096
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6097
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-VUIRO6NC.js");
|
|
6097
6098
|
const orch = getOrchestrator2();
|
|
6098
6099
|
return {
|
|
6099
6100
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6261,10 +6262,10 @@ var Orchestrator = class {
|
|
|
6261
6262
|
/** Timers for orchestration session-quota auto-resume. */
|
|
6262
6263
|
quotaResumeTimers = /* @__PURE__ */ new Map();
|
|
6263
6264
|
/**
|
|
6264
|
-
*
|
|
6265
|
-
*
|
|
6265
|
+
* Crash-continue count per thread. Cleared on a successful finish or a user
|
|
6266
|
+
* send. Stream cutoffs may resume more than once; other crashes once.
|
|
6266
6267
|
*/
|
|
6267
|
-
crashContinued = /* @__PURE__ */ new
|
|
6268
|
+
crashContinued = /* @__PURE__ */ new Map();
|
|
6268
6269
|
/** Auto-continues after a worktree turn ended while a detached job still runs. */
|
|
6269
6270
|
jobContinueCount = /* @__PURE__ */ new Map();
|
|
6270
6271
|
jobContinueNudged = /* @__PURE__ */ new Set();
|
|
@@ -6703,7 +6704,6 @@ var Orchestrator = class {
|
|
|
6703
6704
|
* next prompt so the same agent can continue instead of sitting on lastError.
|
|
6704
6705
|
*/
|
|
6705
6706
|
maybeEnqueueCrashContinue(threadId, opts) {
|
|
6706
|
-
if (this.crashContinued.has(threadId)) return;
|
|
6707
6707
|
if (this.haltDrain.has(threadId)) return;
|
|
6708
6708
|
if (!shouldFeedErrorBackToAgent({
|
|
6709
6709
|
detail: opts.detail,
|
|
@@ -6712,9 +6712,11 @@ var Orchestrator = class {
|
|
|
6712
6712
|
})) {
|
|
6713
6713
|
return;
|
|
6714
6714
|
}
|
|
6715
|
+
const resumeCount = nextCrashContinueCount(opts.detail, this.crashContinued.get(threadId) ?? 0);
|
|
6716
|
+
if (resumeCount == null) return;
|
|
6715
6717
|
const thread = readThread(threadId);
|
|
6716
6718
|
if (!thread || thread.status === "archived") return;
|
|
6717
|
-
this.crashContinued.
|
|
6719
|
+
this.crashContinued.set(threadId, resumeCount);
|
|
6718
6720
|
const prompt = formatAgentErrorContinuePrompt(opts.detail);
|
|
6719
6721
|
const next = prependQueuedItem(thread.queue, thread.queueAttachments, prompt);
|
|
6720
6722
|
updateThread(threadId, next);
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
// src/agents/cursor-stream-cutoff.ts
|
|
5
|
+
var CURSOR_STREAM_CUTOFF = /nghttp2|premature close|\[unavailable\]\s+error\b|http\/2 stream closed|\bcancel \(0x8\)|error code cancel\b/i;
|
|
6
|
+
var CURSOR_STREAM_CUTOFF_CONTINUE_LIMIT = 3;
|
|
7
|
+
function looksLikeCursorStreamCutOff(text) {
|
|
8
|
+
return CURSOR_STREAM_CUTOFF.test(text.trim());
|
|
9
|
+
}
|
|
10
|
+
function cursorStreamCutOffContinueLimit(detail) {
|
|
11
|
+
if (looksLikeCursorStreamCutOff(detail) || /connection stalled/i.test(detail)) {
|
|
12
|
+
return CURSOR_STREAM_CUTOFF_CONTINUE_LIMIT;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function nextCrashContinueCount(detail, used) {
|
|
17
|
+
const limit = cursorStreamCutOffContinueLimit(detail) ?? 1;
|
|
18
|
+
if (used >= limit) return null;
|
|
19
|
+
return used + 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
4
22
|
// src/agents/error-detail.ts
|
|
5
23
|
function formatUnknownDetail(err) {
|
|
6
24
|
if (err == null) return "";
|
|
@@ -199,9 +217,6 @@ function looksLikeInvalidAgentSession(text) {
|
|
|
199
217
|
if (!lower) return false;
|
|
200
218
|
return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower) || /\brun\b.{0,80}\bnot found for agent\b/.test(lower);
|
|
201
219
|
}
|
|
202
|
-
function looksLikeCursorStreamCutOff(text) {
|
|
203
|
-
return /nghttp2|premature close|\[unavailable\]\s+error\b/i.test(text.trim());
|
|
204
|
-
}
|
|
205
220
|
function looksLikeBrightsyEmptyCompletion(text) {
|
|
206
221
|
const core = text.trim().replace(/^exit\s*\d+:\s*/i, "").replace(/^error:\s*/i, "").trim();
|
|
207
222
|
return /^i did not receive a valid model response\. please try again\.$/i.test(core);
|
|
@@ -1185,6 +1200,7 @@ function normalizeParseResult(parsed) {
|
|
|
1185
1200
|
}
|
|
1186
1201
|
|
|
1187
1202
|
export {
|
|
1203
|
+
nextCrashContinueCount,
|
|
1188
1204
|
formatUnknownDetail,
|
|
1189
1205
|
extractJsonErrorMessage,
|
|
1190
1206
|
pushTurnStderr,
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
normalizeAbleTimeCredential,
|
|
7
7
|
normalizeAbleTimeHost,
|
|
8
8
|
rewriteAbleTimeError
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VQEARG5H.js";
|
|
10
10
|
import {
|
|
11
11
|
httpFetch
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-2GPQZZLY.js";
|
|
13
13
|
import {
|
|
14
14
|
getAbleTimeAccessToken,
|
|
15
15
|
getAbleTimeHost
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
normalizeAbleTimeCredential,
|
|
5
5
|
normalizeAbleTimeHost,
|
|
6
6
|
rewriteAbleTimeError
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DEJALWKM.js";
|
|
8
8
|
import {
|
|
9
9
|
httpFetch
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JAT3JFOS.js";
|
|
11
11
|
import {
|
|
12
12
|
getAbleTimeAccessToken,
|
|
13
13
|
getAbleTimeHost
|