@sideboard-ai/core 0.1.324 → 0.1.325
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-5ZY3ZUUO.js → abletime-M7STTMZT.js} +6 -5
- package/dist/{abletime-CU2UPMJF.js → abletime-VL234MCP.js} +5 -4
- package/dist/{abletime-oauth-7EOSBEFM.js → abletime-oauth-LMMGMAPA.js} +3 -3
- package/dist/{abletime-oauth-4TTCR3CT.js → abletime-oauth-P4ZFBEAL.js} +3 -3
- package/dist/{abletime-rest-3TG4G7LW.js → abletime-rest-DLV7EIWS.js} +3 -3
- package/dist/{abletime-rest-KOKE7V4B.js → abletime-rest-GOI7HELR.js} +3 -3
- package/dist/agents/claude-runner.cjs +59 -22
- package/dist/agents/claude-runner.js +39 -16
- package/dist/agents/cursor-runner.cjs +96 -31
- package/dist/agents/cursor-runner.js +74 -24
- package/dist/{agents-YK65UDLT.js → agents-LDRM3BTY.js} +9 -8
- package/dist/{agents-LUSTCMDN.js → agents-MBIEAETM.js} +12 -11
- package/dist/{app-settings-I5HM5RMP.js → app-settings-E7DMMEKC.js} +1 -1
- package/dist/{app-settings-XIF4EC4K.js → app-settings-UQHUNOLV.js} +1 -1
- package/dist/{chunk-INBUV7HY.js → chunk-2UP3XD2D.js} +2 -2
- package/dist/{chunk-EQ52JR3Q.js → chunk-5MXLDDYF.js} +1 -1
- package/dist/{chunk-NCHOTN3C.js → chunk-5YCKATG6.js} +4 -3
- package/dist/{chunk-BYUCNIXK.js → chunk-7G27TB4M.js} +6 -6
- package/dist/chunk-7LUOLYFM.js +1445 -0
- package/dist/{chunk-Y3WREIPQ.js → chunk-A76MKMSF.js} +12 -210
- package/dist/{chunk-JE3JLHMO.js → chunk-APKUI4BP.js} +3 -3
- package/dist/{chunk-FR3SAYUL.js → chunk-AQEKPJWU.js} +5 -5
- package/dist/{chunk-QOS4465Y.js → chunk-BOFYI6LC.js} +1 -1
- package/dist/{chunk-FUFNMUNR.js → chunk-BTF3ATST.js} +7 -8
- package/dist/{chunk-OIHRC2ZJ.js → chunk-CI4M54LS.js} +22 -2
- package/dist/chunk-DBKHL7NC.js +214 -0
- package/dist/{chunk-ROOZDDFA.js → chunk-EO6ZFLG6.js} +7 -8
- package/dist/chunk-EZR6W4B3.js +1259 -0
- package/dist/{chunk-MZIZTSR2.js → chunk-F65JMKUR.js} +2 -2
- package/dist/chunk-F6GE7V3Q.js +216 -0
- package/dist/{chunk-7MQSYPAY.js → chunk-GNLKBS3U.js} +206 -188
- package/dist/{chunk-EKU7FQVG.js → chunk-H36GKGU2.js} +2 -2
- package/dist/{chunk-7D5QIU3N.js → chunk-HG6KS7OT.js} +294 -265
- package/dist/chunk-MBT6WDAB.js +28 -0
- package/dist/{chunk-JH5SMVM5.js → chunk-MFMDZAA6.js} +262 -233
- package/dist/{chunk-7PVT73H6.js → chunk-NWGINMEA.js} +12 -210
- package/dist/{chunk-QIC2JXHW.js → chunk-OOXRMTU6.js} +1 -1
- package/dist/{chunk-5XNT6BCG.js → chunk-OPXEJJBM.js} +1 -1
- package/dist/chunk-OYRN356W.js +80 -0
- package/dist/chunk-PPTJMBUY.js +25 -0
- package/dist/{chunk-B4CDSSRN.js → chunk-Q3FHTGIW.js} +2 -0
- package/dist/{chunk-EJ66LEKH.js → chunk-RZJTGBXY.js} +22 -2
- package/dist/{chunk-DF5BM5OY.js → chunk-SACHHTBJ.js} +207 -186
- package/dist/{chunk-5GDJSFCT.js → chunk-SK6NYGPD.js} +2 -2
- package/dist/{chunk-74OPNF7U.js → chunk-SQQBU7Z6.js} +2 -2
- package/dist/{chunk-Q3YJZPQI.js → chunk-SS6CYGLF.js} +3 -3
- package/dist/{chunk-YDUHLWI5.js → chunk-SUZOPJZC.js} +21 -7
- package/dist/{chunk-ZHGMRBSC.js → chunk-U5WO6MEB.js} +3 -3
- package/dist/{chunk-NXUN4U5P.js → chunk-VAFQS4D2.js} +2 -2
- package/dist/chunk-W3ZLE4PO.js +77 -0
- package/dist/{chunk-RR4WCGNB.js → chunk-WYEST76H.js} +7 -7
- package/dist/{chunk-ODH3XHMI.js → chunk-ZEUMWHOH.js} +5 -5
- package/dist/{chunk-ZIRQZUZY.js → chunk-ZHDXLDLA.js} +3 -3
- package/dist/{chunk-IFWGG2M2.js → chunk-ZSHS46V5.js} +2 -0
- package/dist/{conductor-JFABMXDA.js → conductor-D4KFZF54.js} +6 -6
- package/dist/{conductor-SPZOTC7W.js → conductor-KB7L7NQN.js} +7 -7
- package/dist/{coordinator-prompt-K66RGNWK.js → coordinator-prompt-OBXEC63K.js} +4 -4
- package/dist/{coordinator-prompt-Z6UFHFDH.js → coordinator-prompt-SUO4FRY3.js} +4 -4
- package/dist/{cursor-recover-TEBFKAZ4.js → cursor-recover-7F46PAJ5.js} +1 -1
- package/dist/{cursor-recover-OWPQUHFH.js → cursor-recover-BDIAZIE3.js} +1 -1
- package/dist/{global-workspace-A6UO6PJV.js → global-workspace-UHU2FXTY.js} +4 -4
- package/dist/{global-workspace-RHEO55B4.js → global-workspace-Z2SURNHA.js} +4 -4
- package/dist/index.cjs +21112 -20864
- package/dist/index.d.cts +25 -9
- package/dist/index.d.ts +25 -9
- package/dist/index.js +343 -1678
- package/dist/linear-HFUOUJ5H.js +67 -0
- package/dist/linear-SIHEBU3X.js +69 -0
- package/dist/linear-list-63I7QUC6.js +6 -0
- package/dist/linear-list-JFV3EES6.js +8 -0
- package/dist/mcp/run-stdio.cjs +15654 -15398
- package/dist/mcp/run-stdio.js +67 -1247
- package/dist/{optional-cli-RMMS5L6F.js → optional-cli-U2GUA2X6.js} +3 -3
- package/dist/{optional-cli-Y3Z3GIPZ.js → optional-cli-ULDP3O5S.js} +4 -4
- package/dist/{orchestrator-7VTAUY24.js → orchestrator-3H4KNGPN.js} +15 -13
- package/dist/{orchestrator-2O6OJQLX.js → orchestrator-6ROMEWBP.js} +14 -12
- package/dist/{thread-store-3F7GR64A.js → thread-store-4ZN3DS2W.js} +1 -1
- package/dist/{thread-store-JRSL4HQY.js → thread-store-IC4BQXDW.js} +1 -1
- package/dist/{workspaces-NRKEXOYR.js → workspaces-MG5JHRKW.js} +4 -4
- package/dist/{workspaces-42E6AGXD.js → workspaces-QJNKEGEM.js} +4 -4
- package/dist/{worktree-ZDA2UJ7C.js → worktree-KSJPTHGZ.js} +3 -3
- package/dist/{worktree-4NGXCCUO.js → worktree-MYJYUHZM.js} +3 -3
- package/package.json +1 -1
|
@@ -19,12 +19,13 @@ import {
|
|
|
19
19
|
toAbleTimeIssueInfo,
|
|
20
20
|
updateAbleTimeTask,
|
|
21
21
|
verifyAbleTimeConnection
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-A76MKMSF.js";
|
|
23
|
+
import "./chunk-VAFQS4D2.js";
|
|
24
|
+
import "./chunk-AQEKPJWU.js";
|
|
25
|
+
import "./chunk-F6GE7V3Q.js";
|
|
26
26
|
import "./chunk-N2WW62LF.js";
|
|
27
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-2GPQZZLY.js";
|
|
28
|
+
import "./chunk-CI4M54LS.js";
|
|
28
29
|
import "./chunk-NSTQ6QKD.js";
|
|
29
30
|
import "./chunk-WWUABK6B.js";
|
|
30
31
|
import "./chunk-FJZWM2ON.js";
|
|
@@ -17,12 +17,13 @@ import {
|
|
|
17
17
|
toAbleTimeIssueInfo,
|
|
18
18
|
updateAbleTimeTask,
|
|
19
19
|
verifyAbleTimeConnection
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-NWGINMEA.js";
|
|
21
|
+
import "./chunk-DBKHL7NC.js";
|
|
22
|
+
import "./chunk-H36GKGU2.js";
|
|
23
|
+
import "./chunk-ZEUMWHOH.js";
|
|
23
24
|
import "./chunk-JAT3JFOS.js";
|
|
24
25
|
import "./chunk-6K64FJDD.js";
|
|
25
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-RZJTGBXY.js";
|
|
26
27
|
import "./chunk-77WWLBCI.js";
|
|
27
28
|
import "./chunk-4TR3HZFT.js";
|
|
28
29
|
import "./chunk-WDRMZKVB.js";
|
|
@@ -20,10 +20,10 @@ import {
|
|
|
20
20
|
parseAbleTimeOAuthCallbackUrl,
|
|
21
21
|
resolveAbleTimeOAuthHost,
|
|
22
22
|
startAbleTimeOAuth
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-SS6CYGLF.js";
|
|
24
|
+
import "./chunk-ZEUMWHOH.js";
|
|
25
25
|
import "./chunk-JAT3JFOS.js";
|
|
26
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-RZJTGBXY.js";
|
|
27
27
|
import "./chunk-77WWLBCI.js";
|
|
28
28
|
import "./chunk-4TR3HZFT.js";
|
|
29
29
|
import "./chunk-WDRMZKVB.js";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
DEFAULT_ABLETIME_HOST,
|
|
5
5
|
normalizeAbleTimeHost
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AQEKPJWU.js";
|
|
7
7
|
import {
|
|
8
8
|
httpFetch
|
|
9
9
|
} from "./chunk-2GPQZZLY.js";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getAbleTimeHost,
|
|
13
13
|
loadAppSettings,
|
|
14
14
|
saveAbleTimeConnection
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-CI4M54LS.js";
|
|
16
16
|
import "./chunk-NSTQ6QKD.js";
|
|
17
17
|
import "./chunk-WWUABK6B.js";
|
|
18
18
|
import "./chunk-FJZWM2ON.js";
|
|
@@ -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-M7STTMZT.js");
|
|
292
292
|
const orientation = await getAbleTimeOrientation({ token, host });
|
|
293
293
|
return saveAbleTimeConnection({
|
|
294
294
|
accessToken: token,
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
callAbleTimeRestTool,
|
|
8
8
|
looksLikeAbleTimeUlid,
|
|
9
9
|
textFromAbleTimeDoc
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-VAFQS4D2.js";
|
|
11
|
+
import "./chunk-AQEKPJWU.js";
|
|
12
12
|
import "./chunk-2GPQZZLY.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-CI4M54LS.js";
|
|
14
14
|
import "./chunk-NSTQ6QKD.js";
|
|
15
15
|
import "./chunk-WWUABK6B.js";
|
|
16
16
|
import "./chunk-FJZWM2ON.js";
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
callAbleTimeRestTool,
|
|
6
6
|
looksLikeAbleTimeUlid,
|
|
7
7
|
textFromAbleTimeDoc
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-H36GKGU2.js";
|
|
9
|
+
import "./chunk-ZEUMWHOH.js";
|
|
10
10
|
import "./chunk-JAT3JFOS.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-RZJTGBXY.js";
|
|
12
12
|
import "./chunk-77WWLBCI.js";
|
|
13
13
|
import "./chunk-4TR3HZFT.js";
|
|
14
14
|
import "./chunk-WDRMZKVB.js";
|
|
@@ -166,6 +166,8 @@ function agentRuntimeLooksLive(meta = readAgentRuntimeMetadata()) {
|
|
|
166
166
|
// src/agent-rpc/client.ts
|
|
167
167
|
var AgentRpcClient = class {
|
|
168
168
|
ws = null;
|
|
169
|
+
/** In-flight connect. Concurrent call()s must share it or each opens a socket. */
|
|
170
|
+
connecting = null;
|
|
169
171
|
pending = /* @__PURE__ */ new Map();
|
|
170
172
|
nextId = 1;
|
|
171
173
|
url;
|
|
@@ -208,10 +210,10 @@ var AgentRpcClient = class {
|
|
|
208
210
|
url.searchParams.set(AGENT_RPC_TOKEN_QUERY, this.authToken);
|
|
209
211
|
return url.toString();
|
|
210
212
|
}
|
|
211
|
-
|
|
212
|
-
if (this.ws && this.ws.readyState === import_ws.WebSocket.OPEN) return this.ws;
|
|
213
|
+
ensureSocket() {
|
|
214
|
+
if (this.ws && this.ws.readyState === import_ws.WebSocket.OPEN) return Promise.resolve(this.ws);
|
|
215
|
+
if (this.connecting) return this.connecting;
|
|
213
216
|
const ws = new import_ws.WebSocket(this.socketUrl());
|
|
214
|
-
this.ws = ws;
|
|
215
217
|
ws.on("message", (data) => this.onFrame(data.toString()));
|
|
216
218
|
ws.on("error", (err) => this.drop(ws, err));
|
|
217
219
|
ws.on("close", () => this.drop(ws, new Error("Agent RPC socket closed")));
|
|
@@ -224,11 +226,16 @@ var AgentRpcClient = class {
|
|
|
224
226
|
)
|
|
225
227
|
);
|
|
226
228
|
});
|
|
227
|
-
|
|
229
|
+
let settled = false;
|
|
230
|
+
const pending = new Promise((resolve, reject) => {
|
|
228
231
|
const fail = (err) => {
|
|
232
|
+
if (settled) return;
|
|
233
|
+
settled = true;
|
|
234
|
+
if (this.connecting === pending) this.connecting = null;
|
|
229
235
|
const message = err.message.includes("401") ? "Unauthorized" : err.message;
|
|
230
236
|
reject(message === err.message ? err : new Error(message));
|
|
231
237
|
};
|
|
238
|
+
const failClose = () => fail(new Error("Agent RPC socket closed"));
|
|
232
239
|
ws.once("unexpected-response", (_req, res) => {
|
|
233
240
|
fail(
|
|
234
241
|
new Error(
|
|
@@ -237,15 +244,22 @@ var AgentRpcClient = class {
|
|
|
237
244
|
);
|
|
238
245
|
});
|
|
239
246
|
ws.once("error", fail);
|
|
247
|
+
ws.once("close", failClose);
|
|
240
248
|
ws.once("open", () => {
|
|
241
249
|
ws.off("error", fail);
|
|
242
|
-
|
|
250
|
+
ws.off("close", failClose);
|
|
251
|
+
settled = true;
|
|
252
|
+
this.ws = ws;
|
|
253
|
+
this.connecting = null;
|
|
254
|
+
resolve(ws);
|
|
243
255
|
});
|
|
244
256
|
});
|
|
245
|
-
|
|
257
|
+
this.connecting = pending;
|
|
258
|
+
return pending;
|
|
246
259
|
}
|
|
247
260
|
drop(ws, err) {
|
|
248
|
-
if (this.ws
|
|
261
|
+
if (this.ws !== ws) return;
|
|
262
|
+
this.ws = null;
|
|
249
263
|
if (this.pending.size === 0) return;
|
|
250
264
|
this.failAll(err);
|
|
251
265
|
}
|
|
@@ -485,6 +499,31 @@ async function claudePermissionResult(input) {
|
|
|
485
499
|
}
|
|
486
500
|
}
|
|
487
501
|
|
|
502
|
+
// src/agents/claude-query-options.ts
|
|
503
|
+
function buildClaudeSdkQueryOptions(req, mcpServers, abortController) {
|
|
504
|
+
const options = {
|
|
505
|
+
cwd: req.cwd,
|
|
506
|
+
pathToClaudeCodeExecutable: req.claudePath,
|
|
507
|
+
permissionMode: req.permissionMode,
|
|
508
|
+
...req.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
|
|
509
|
+
allowedTools: req.allowedTools,
|
|
510
|
+
mcpServers,
|
|
511
|
+
includePartialMessages: true,
|
|
512
|
+
strictMcpConfig: true,
|
|
513
|
+
systemPrompt: {
|
|
514
|
+
type: "preset",
|
|
515
|
+
preset: "claude_code",
|
|
516
|
+
...req.systemPrompt ? { append: req.systemPrompt } : {}
|
|
517
|
+
},
|
|
518
|
+
abortController
|
|
519
|
+
};
|
|
520
|
+
if (req.sessionId) options.resume = req.sessionId;
|
|
521
|
+
if (req.model) options.model = req.model;
|
|
522
|
+
if (req.effort) options.effort = req.effort;
|
|
523
|
+
if (req.chrome) options.extraArgs = { chrome: null };
|
|
524
|
+
return options;
|
|
525
|
+
}
|
|
526
|
+
|
|
488
527
|
// src/agents/claude-runner.ts
|
|
489
528
|
dropNestedElectronEnvFromProcess();
|
|
490
529
|
function emit(value) {
|
|
@@ -533,21 +572,17 @@ async function main() {
|
|
|
533
572
|
for (const [name, spec] of Object.entries(req.mcpServers ?? {})) {
|
|
534
573
|
mcpServers[name] = spec;
|
|
535
574
|
}
|
|
575
|
+
const abortController = new AbortController();
|
|
576
|
+
let stopped = false;
|
|
577
|
+
const onStop = () => {
|
|
578
|
+
stopped = true;
|
|
579
|
+
abortController.abort();
|
|
580
|
+
setTimeout(() => process.exit(130), 3e3).unref();
|
|
581
|
+
};
|
|
582
|
+
process.once("SIGTERM", onStop);
|
|
583
|
+
process.once("SIGINT", onStop);
|
|
536
584
|
try {
|
|
537
|
-
const options =
|
|
538
|
-
cwd: req.cwd,
|
|
539
|
-
pathToClaudeCodeExecutable: req.claudePath,
|
|
540
|
-
permissionMode: req.permissionMode,
|
|
541
|
-
...req.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
|
|
542
|
-
allowedTools: req.allowedTools,
|
|
543
|
-
mcpServers,
|
|
544
|
-
includePartialMessages: true
|
|
545
|
-
};
|
|
546
|
-
if (req.sessionId) options.resume = req.sessionId;
|
|
547
|
-
if (req.model) options.model = req.model;
|
|
548
|
-
if (req.systemPrompt) options.appendSystemPrompt = req.systemPrompt;
|
|
549
|
-
if (req.effort) options.effort = req.effort;
|
|
550
|
-
if (req.chrome) options.chrome = true;
|
|
585
|
+
const options = buildClaudeSdkQueryOptions(req, mcpServers, abortController);
|
|
551
586
|
options.canUseTool = (toolName, toolInput, toolOpts) => claudePermissionResult({
|
|
552
587
|
permissionMode: req.permissionMode,
|
|
553
588
|
threadId: process.env.SIDEBOARD_THREAD_ID?.trim() || "",
|
|
@@ -558,11 +593,13 @@ async function main() {
|
|
|
558
593
|
options: toolOpts,
|
|
559
594
|
rpc: req.agentRpc
|
|
560
595
|
});
|
|
561
|
-
options.settingSources = [];
|
|
562
596
|
for await (const message of sdk.query({ prompt: req.prompt, options })) {
|
|
563
597
|
emit(message);
|
|
564
598
|
}
|
|
599
|
+
if (stopped) process.exitCode = 130;
|
|
565
600
|
} finally {
|
|
601
|
+
process.off("SIGTERM", onStop);
|
|
602
|
+
process.off("SIGINT", onStop);
|
|
566
603
|
exec.close();
|
|
567
604
|
}
|
|
568
605
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
AgentRpcClient,
|
|
10
10
|
PILOT_TOOL_DESCRIPTIONS,
|
|
11
11
|
createPilotRpcExecutors
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-SUZOPJZC.js";
|
|
13
13
|
import {
|
|
14
14
|
dropNestedElectronEnvFromProcess
|
|
15
15
|
} from "../chunk-4TR3HZFT.js";
|
|
@@ -131,6 +131,31 @@ async function claudePermissionResult(input) {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// src/agents/claude-query-options.ts
|
|
135
|
+
function buildClaudeSdkQueryOptions(req, mcpServers, abortController) {
|
|
136
|
+
const options = {
|
|
137
|
+
cwd: req.cwd,
|
|
138
|
+
pathToClaudeCodeExecutable: req.claudePath,
|
|
139
|
+
permissionMode: req.permissionMode,
|
|
140
|
+
...req.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
|
|
141
|
+
allowedTools: req.allowedTools,
|
|
142
|
+
mcpServers,
|
|
143
|
+
includePartialMessages: true,
|
|
144
|
+
strictMcpConfig: true,
|
|
145
|
+
systemPrompt: {
|
|
146
|
+
type: "preset",
|
|
147
|
+
preset: "claude_code",
|
|
148
|
+
...req.systemPrompt ? { append: req.systemPrompt } : {}
|
|
149
|
+
},
|
|
150
|
+
abortController
|
|
151
|
+
};
|
|
152
|
+
if (req.sessionId) options.resume = req.sessionId;
|
|
153
|
+
if (req.model) options.model = req.model;
|
|
154
|
+
if (req.effort) options.effort = req.effort;
|
|
155
|
+
if (req.chrome) options.extraArgs = { chrome: null };
|
|
156
|
+
return options;
|
|
157
|
+
}
|
|
158
|
+
|
|
134
159
|
// src/agents/claude-runner.ts
|
|
135
160
|
dropNestedElectronEnvFromProcess();
|
|
136
161
|
function emit(value) {
|
|
@@ -179,21 +204,17 @@ async function main() {
|
|
|
179
204
|
for (const [name, spec] of Object.entries(req.mcpServers ?? {})) {
|
|
180
205
|
mcpServers[name] = spec;
|
|
181
206
|
}
|
|
207
|
+
const abortController = new AbortController();
|
|
208
|
+
let stopped = false;
|
|
209
|
+
const onStop = () => {
|
|
210
|
+
stopped = true;
|
|
211
|
+
abortController.abort();
|
|
212
|
+
setTimeout(() => process.exit(130), 3e3).unref();
|
|
213
|
+
};
|
|
214
|
+
process.once("SIGTERM", onStop);
|
|
215
|
+
process.once("SIGINT", onStop);
|
|
182
216
|
try {
|
|
183
|
-
const options =
|
|
184
|
-
cwd: req.cwd,
|
|
185
|
-
pathToClaudeCodeExecutable: req.claudePath,
|
|
186
|
-
permissionMode: req.permissionMode,
|
|
187
|
-
...req.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
|
|
188
|
-
allowedTools: req.allowedTools,
|
|
189
|
-
mcpServers,
|
|
190
|
-
includePartialMessages: true
|
|
191
|
-
};
|
|
192
|
-
if (req.sessionId) options.resume = req.sessionId;
|
|
193
|
-
if (req.model) options.model = req.model;
|
|
194
|
-
if (req.systemPrompt) options.appendSystemPrompt = req.systemPrompt;
|
|
195
|
-
if (req.effort) options.effort = req.effort;
|
|
196
|
-
if (req.chrome) options.chrome = true;
|
|
217
|
+
const options = buildClaudeSdkQueryOptions(req, mcpServers, abortController);
|
|
197
218
|
options.canUseTool = (toolName, toolInput, toolOpts) => claudePermissionResult({
|
|
198
219
|
permissionMode: req.permissionMode,
|
|
199
220
|
threadId: process.env.SIDEBOARD_THREAD_ID?.trim() || "",
|
|
@@ -204,11 +225,13 @@ async function main() {
|
|
|
204
225
|
options: toolOpts,
|
|
205
226
|
rpc: req.agentRpc
|
|
206
227
|
});
|
|
207
|
-
options.settingSources = [];
|
|
208
228
|
for await (const message of sdk.query({ prompt: req.prompt, options })) {
|
|
209
229
|
emit(message);
|
|
210
230
|
}
|
|
231
|
+
if (stopped) process.exitCode = 130;
|
|
211
232
|
} finally {
|
|
233
|
+
process.off("SIGTERM", onStop);
|
|
234
|
+
process.off("SIGINT", onStop);
|
|
212
235
|
exec.close();
|
|
213
236
|
}
|
|
214
237
|
}
|
|
@@ -359,10 +359,20 @@ async function acquireCursorCatalogLock(storeDir) {
|
|
|
359
359
|
try {
|
|
360
360
|
return await import_proper_lockfile.default.lock(lockPath, {
|
|
361
361
|
retries: { retries: 40, minTimeout: 50, maxTimeout: 500 },
|
|
362
|
-
|
|
363
|
-
|
|
362
|
+
// Repair rewrites run_events.ndjson synchronously while holding the lock.
|
|
363
|
+
// A 5s stale window treats that stall as a dead owner and throws from a
|
|
364
|
+
// timer, which kills the runner mid-turn.
|
|
365
|
+
stale: 3e4,
|
|
366
|
+
update: 1e4,
|
|
367
|
+
onCompromised: (err) => {
|
|
368
|
+
console.error(`[sideboard] cursor catalog lock compromised: ${err.message}`);
|
|
369
|
+
}
|
|
364
370
|
});
|
|
365
|
-
} catch {
|
|
371
|
+
} catch (err) {
|
|
372
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
373
|
+
console.error(
|
|
374
|
+
`[sideboard] cursor catalog lock not acquired (${message}); continuing without the lock`
|
|
375
|
+
);
|
|
366
376
|
return async () => {
|
|
367
377
|
};
|
|
368
378
|
}
|
|
@@ -695,7 +705,7 @@ function extractJsonErrorMessage(obj) {
|
|
|
695
705
|
const candidates = [
|
|
696
706
|
typeof obj.message === "string" ? obj.message : null,
|
|
697
707
|
typeof obj.error === "string" ? obj.error : null,
|
|
698
|
-
nested && typeof nested.message === "string" ? nested.message : null,
|
|
708
|
+
nested && typeof nested.message === "string" ? nested.message : typeof nested?.data?.message === "string" ? nested.data.message : null,
|
|
699
709
|
typeof obj.result === "string" ? obj.result : null,
|
|
700
710
|
typeof obj.detail === "string" ? obj.detail : null
|
|
701
711
|
];
|
|
@@ -800,8 +810,8 @@ function isUnresumableCursorSession(err) {
|
|
|
800
810
|
if (name === "AgentNotFoundError") return true;
|
|
801
811
|
const lower = cursorErrorMessage(err).toLowerCase();
|
|
802
812
|
if (!lower) return false;
|
|
803
|
-
return /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\
|
|
804
|
-
/\brun\
|
|
813
|
+
return /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\s+agent-[\w-]+\s+not found\b/.test(lower) || // Shared JSONL last-write-wins: `Run run-… not found for agent agent-…`
|
|
814
|
+
/\brun\s+run-[\w-]+\s+not found for agent\b/.test(lower) || /cannot resume/.test(lower);
|
|
805
815
|
}
|
|
806
816
|
function cursorSessionRecoveryMessage(err, agentId) {
|
|
807
817
|
const detail = cursorErrorMessage(err) || "unresumable session";
|
|
@@ -842,13 +852,20 @@ async function retryOnceOnRetryableCursorError(fn, onRetry, delayMs = CURSOR_RET
|
|
|
842
852
|
return fn();
|
|
843
853
|
}
|
|
844
854
|
}
|
|
845
|
-
function cursorSendOptions(mcpServers) {
|
|
846
|
-
const opts = {
|
|
855
|
+
function cursorSendOptions(mcpServers, mode) {
|
|
856
|
+
const opts = {
|
|
857
|
+
local: { force: true }
|
|
858
|
+
};
|
|
859
|
+
if (mode) opts.mode = mode;
|
|
847
860
|
if (mcpServers && typeof mcpServers === "object" && Object.keys(mcpServers).length > 0) {
|
|
848
861
|
opts.mcpServers = mcpServers;
|
|
849
862
|
}
|
|
850
863
|
return opts;
|
|
851
864
|
}
|
|
865
|
+
function cursorDisallowedTools(planMode) {
|
|
866
|
+
if (planMode) return ["read", "shell", "edit", "write", "delete", "task"];
|
|
867
|
+
return ["read"];
|
|
868
|
+
}
|
|
852
869
|
function withCursorLocalHangGuards(local) {
|
|
853
870
|
return { ...local, enableAgentRetries: false };
|
|
854
871
|
}
|
|
@@ -889,6 +906,30 @@ async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
|
|
|
889
906
|
throw err;
|
|
890
907
|
}
|
|
891
908
|
}
|
|
909
|
+
function exitWhenFlushed(code) {
|
|
910
|
+
let pending = 2;
|
|
911
|
+
let exited = false;
|
|
912
|
+
const finish = () => {
|
|
913
|
+
pending -= 1;
|
|
914
|
+
if (pending > 0 || exited) return;
|
|
915
|
+
exited = true;
|
|
916
|
+
process.exit(code);
|
|
917
|
+
};
|
|
918
|
+
const flush = (stream) => {
|
|
919
|
+
if (stream.writableEnded) {
|
|
920
|
+
finish();
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
stream.write("", finish);
|
|
924
|
+
};
|
|
925
|
+
flush(process.stdout);
|
|
926
|
+
flush(process.stderr);
|
|
927
|
+
setTimeout(() => {
|
|
928
|
+
if (exited) return;
|
|
929
|
+
exited = true;
|
|
930
|
+
process.exit(code);
|
|
931
|
+
}, 1e3).unref();
|
|
932
|
+
}
|
|
892
933
|
|
|
893
934
|
// src/agents/sliced-file-read.ts
|
|
894
935
|
var import_node_fs15 = require("fs");
|
|
@@ -1105,6 +1146,8 @@ function agentRuntimeLooksLive(meta = readAgentRuntimeMetadata()) {
|
|
|
1105
1146
|
// src/agent-rpc/client.ts
|
|
1106
1147
|
var AgentRpcClient = class {
|
|
1107
1148
|
ws = null;
|
|
1149
|
+
/** In-flight connect. Concurrent call()s must share it or each opens a socket. */
|
|
1150
|
+
connecting = null;
|
|
1108
1151
|
pending = /* @__PURE__ */ new Map();
|
|
1109
1152
|
nextId = 1;
|
|
1110
1153
|
url;
|
|
@@ -1147,10 +1190,10 @@ var AgentRpcClient = class {
|
|
|
1147
1190
|
url.searchParams.set(AGENT_RPC_TOKEN_QUERY, this.authToken);
|
|
1148
1191
|
return url.toString();
|
|
1149
1192
|
}
|
|
1150
|
-
|
|
1151
|
-
if (this.ws && this.ws.readyState === import_ws.WebSocket.OPEN) return this.ws;
|
|
1193
|
+
ensureSocket() {
|
|
1194
|
+
if (this.ws && this.ws.readyState === import_ws.WebSocket.OPEN) return Promise.resolve(this.ws);
|
|
1195
|
+
if (this.connecting) return this.connecting;
|
|
1152
1196
|
const ws = new import_ws.WebSocket(this.socketUrl());
|
|
1153
|
-
this.ws = ws;
|
|
1154
1197
|
ws.on("message", (data) => this.onFrame(data.toString()));
|
|
1155
1198
|
ws.on("error", (err) => this.drop(ws, err));
|
|
1156
1199
|
ws.on("close", () => this.drop(ws, new Error("Agent RPC socket closed")));
|
|
@@ -1163,11 +1206,16 @@ var AgentRpcClient = class {
|
|
|
1163
1206
|
)
|
|
1164
1207
|
);
|
|
1165
1208
|
});
|
|
1166
|
-
|
|
1209
|
+
let settled = false;
|
|
1210
|
+
const pending = new Promise((resolve2, reject) => {
|
|
1167
1211
|
const fail = (err) => {
|
|
1212
|
+
if (settled) return;
|
|
1213
|
+
settled = true;
|
|
1214
|
+
if (this.connecting === pending) this.connecting = null;
|
|
1168
1215
|
const message = err.message.includes("401") ? "Unauthorized" : err.message;
|
|
1169
1216
|
reject(message === err.message ? err : new Error(message));
|
|
1170
1217
|
};
|
|
1218
|
+
const failClose = () => fail(new Error("Agent RPC socket closed"));
|
|
1171
1219
|
ws.once("unexpected-response", (_req, res) => {
|
|
1172
1220
|
fail(
|
|
1173
1221
|
new Error(
|
|
@@ -1176,15 +1224,22 @@ var AgentRpcClient = class {
|
|
|
1176
1224
|
);
|
|
1177
1225
|
});
|
|
1178
1226
|
ws.once("error", fail);
|
|
1227
|
+
ws.once("close", failClose);
|
|
1179
1228
|
ws.once("open", () => {
|
|
1180
1229
|
ws.off("error", fail);
|
|
1181
|
-
|
|
1230
|
+
ws.off("close", failClose);
|
|
1231
|
+
settled = true;
|
|
1232
|
+
this.ws = ws;
|
|
1233
|
+
this.connecting = null;
|
|
1234
|
+
resolve2(ws);
|
|
1182
1235
|
});
|
|
1183
1236
|
});
|
|
1184
|
-
|
|
1237
|
+
this.connecting = pending;
|
|
1238
|
+
return pending;
|
|
1185
1239
|
}
|
|
1186
1240
|
drop(ws, err) {
|
|
1187
|
-
if (this.ws
|
|
1241
|
+
if (this.ws !== ws) return;
|
|
1242
|
+
this.ws = null;
|
|
1188
1243
|
if (this.pending.size === 0) return;
|
|
1189
1244
|
this.failAll(err);
|
|
1190
1245
|
}
|
|
@@ -1474,13 +1529,14 @@ function guardCursorCustomTool(tool, opts) {
|
|
|
1474
1529
|
};
|
|
1475
1530
|
}
|
|
1476
1531
|
var NON_RECOVERABLE_RUN_ERROR = /invalid (?:user )?api key|not logged in|not authenticated|unauthorized|credit balance|out of credits|insufficient.?quota|usage limit|you've hit your|too many requests|rate.?limit/;
|
|
1532
|
+
var RECOVERABLE_RUN_ERROR = /premature close|tool execution failed|stream (?:idle|cut ?off|closed)|custom tool|result too (?:large|long)|max(?:imum)? (?:tool )?result/;
|
|
1477
1533
|
function shouldReturnRunErrorToAgent(detail) {
|
|
1478
1534
|
const text = detail.trim();
|
|
1479
1535
|
if (!text) return false;
|
|
1480
1536
|
if (looksLikeHugeToolResultDump(text) || looksLikeCursorStreamCutOff(text)) return true;
|
|
1481
1537
|
const head = text.slice(0, 2e3).toLowerCase();
|
|
1482
1538
|
if (NON_RECOVERABLE_RUN_ERROR.test(head)) return false;
|
|
1483
|
-
return
|
|
1539
|
+
return RECOVERABLE_RUN_ERROR.test(head);
|
|
1484
1540
|
}
|
|
1485
1541
|
function cursorRunErrorRecoveryPrompt(detail) {
|
|
1486
1542
|
const summary = looksLikeHugeToolResultDump(detail) ? HUGE_TOOL_RESULT_SUMMARY : detail.replace(/\s+/g, " ").trim().slice(0, 400);
|
|
@@ -1561,7 +1617,8 @@ function preferredCursorCostCents(cost) {
|
|
|
1561
1617
|
}
|
|
1562
1618
|
function turnCostUsdFromCursorUsage(before, after) {
|
|
1563
1619
|
if (!after) return void 0;
|
|
1564
|
-
|
|
1620
|
+
if (before == null) return void 0;
|
|
1621
|
+
const beforeIds = new Set((before.runs ?? []).map((r) => r.runId));
|
|
1565
1622
|
const newRuns = (after.runs ?? []).filter((r) => !beforeIds.has(r.runId));
|
|
1566
1623
|
let sum = 0;
|
|
1567
1624
|
let any = false;
|
|
@@ -1573,7 +1630,6 @@ function turnCostUsdFromCursorUsage(before, after) {
|
|
|
1573
1630
|
}
|
|
1574
1631
|
}
|
|
1575
1632
|
if (any) return sum / 100;
|
|
1576
|
-
if (before == null) return void 0;
|
|
1577
1633
|
const afterCents = preferredCursorCostCents(after.cost);
|
|
1578
1634
|
if (afterCents == null) return void 0;
|
|
1579
1635
|
const beforeCents = preferredCursorCostCents(before.cost) ?? 0;
|
|
@@ -2010,7 +2066,7 @@ async function main() {
|
|
|
2010
2066
|
mode,
|
|
2011
2067
|
local,
|
|
2012
2068
|
name: "Sideboard",
|
|
2013
|
-
disallowedTools:
|
|
2069
|
+
disallowedTools: cursorDisallowedTools(req.planMode),
|
|
2014
2070
|
...mcpServers ? { mcpServers } : {}
|
|
2015
2071
|
};
|
|
2016
2072
|
const retryTransport = (fn) => retryOnceOnRetryableCursorError(fn, (err) => {
|
|
@@ -2023,14 +2079,18 @@ async function main() {
|
|
|
2023
2079
|
const { name: _name, ...opts } = createOpts;
|
|
2024
2080
|
return retryTransport(() => Agent.resume(agentId, opts));
|
|
2025
2081
|
}
|
|
2082
|
+
function promptForNewSession() {
|
|
2083
|
+
return req.freshPrompt?.trim() || req.prompt;
|
|
2084
|
+
}
|
|
2026
2085
|
async function openAgent() {
|
|
2027
2086
|
try {
|
|
2028
|
-
|
|
2087
|
+
if (!req.agentId) return { agent: await createAgent(), fresh: true };
|
|
2088
|
+
return { agent: await resumeAgent(req.agentId), fresh: false };
|
|
2029
2089
|
} catch (err) {
|
|
2030
2090
|
if (!isUnresumableCursorSession(err)) throw err;
|
|
2031
2091
|
if (repairCursorCatalogForResume(storeRoot, note) && req.agentId) {
|
|
2032
2092
|
try {
|
|
2033
|
-
return await resumeAgent(req.agentId);
|
|
2093
|
+
return { agent: await resumeAgent(req.agentId), fresh: false };
|
|
2034
2094
|
} catch (err2) {
|
|
2035
2095
|
if (!isUnresumableCursorSession(err2)) throw err2;
|
|
2036
2096
|
}
|
|
@@ -2039,7 +2099,7 @@ async function main() {
|
|
|
2039
2099
|
type: "stderr",
|
|
2040
2100
|
data: cursorSessionRecoveryMessage(err, req.agentId)
|
|
2041
2101
|
});
|
|
2042
|
-
return createAgent();
|
|
2102
|
+
return { agent: await createAgent(), fresh: true };
|
|
2043
2103
|
}
|
|
2044
2104
|
}
|
|
2045
2105
|
async function retryAfterBusy(agent) {
|
|
@@ -2058,7 +2118,7 @@ async function main() {
|
|
|
2058
2118
|
}
|
|
2059
2119
|
async function sendPrompt(agent, prompt, extra) {
|
|
2060
2120
|
const sendOpts = {
|
|
2061
|
-
...cursorSendOptions(mcpServers),
|
|
2121
|
+
...cursorSendOptions(mcpServers, mode),
|
|
2062
2122
|
...extra
|
|
2063
2123
|
};
|
|
2064
2124
|
try {
|
|
@@ -2089,7 +2149,7 @@ async function main() {
|
|
|
2089
2149
|
setTimeout(resolve2, 2e3);
|
|
2090
2150
|
})
|
|
2091
2151
|
]).finally(() => {
|
|
2092
|
-
void closeCursorCatalogTurn().finally(() =>
|
|
2152
|
+
void closeCursorCatalogTurn().finally(() => exitWhenFlushed(1));
|
|
2093
2153
|
});
|
|
2094
2154
|
};
|
|
2095
2155
|
process.once("SIGTERM", onSignal);
|
|
@@ -2175,7 +2235,10 @@ async function main() {
|
|
|
2175
2235
|
});
|
|
2176
2236
|
return 2;
|
|
2177
2237
|
}
|
|
2178
|
-
if (result.status === "cancelled")
|
|
2238
|
+
if (result.status === "cancelled") {
|
|
2239
|
+
if (streamIdle) return 1;
|
|
2240
|
+
return 0;
|
|
2241
|
+
}
|
|
2179
2242
|
try {
|
|
2180
2243
|
const costUsd = await fetchCursorTurnCostUsd(
|
|
2181
2244
|
(opts) => agent.getUsage(opts),
|
|
@@ -2194,14 +2257,16 @@ async function main() {
|
|
|
2194
2257
|
}
|
|
2195
2258
|
}
|
|
2196
2259
|
try {
|
|
2197
|
-
|
|
2260
|
+
const opened = await openAgent();
|
|
2261
|
+
let agent = opened.agent;
|
|
2262
|
+
const prompt = opened.fresh ? promptForNewSession() : req.prompt;
|
|
2198
2263
|
try {
|
|
2199
2264
|
try {
|
|
2200
|
-
return await runTurn(agent);
|
|
2265
|
+
return await runTurn(agent, prompt);
|
|
2201
2266
|
} catch (err) {
|
|
2202
2267
|
if (isAgentBusyError(err)) {
|
|
2203
2268
|
await retryAfterBusy(agent);
|
|
2204
|
-
return await runTurn(agent);
|
|
2269
|
+
return await runTurn(agent, prompt);
|
|
2205
2270
|
}
|
|
2206
2271
|
if (!isUnresumableCursorSession(err)) throw err;
|
|
2207
2272
|
const agentId = agent.agentId;
|
|
@@ -2220,7 +2285,7 @@ async function main() {
|
|
|
2220
2285
|
data: cursorSessionRecoveryMessage(err, agentId)
|
|
2221
2286
|
});
|
|
2222
2287
|
agent = await createAgent();
|
|
2223
|
-
return await runTurn(agent);
|
|
2288
|
+
return await runTurn(agent, promptForNewSession());
|
|
2224
2289
|
}
|
|
2225
2290
|
} finally {
|
|
2226
2291
|
await agent[Symbol.asyncDispose]().catch(() => void 0);
|
|
@@ -2241,9 +2306,9 @@ async function main() {
|
|
|
2241
2306
|
}
|
|
2242
2307
|
}
|
|
2243
2308
|
main().then(
|
|
2244
|
-
(code) =>
|
|
2309
|
+
(code) => exitWhenFlushed(code),
|
|
2245
2310
|
(err) => {
|
|
2246
2311
|
emit({ type: "stderr", data: err instanceof Error ? err.message : String(err) });
|
|
2247
|
-
|
|
2312
|
+
exitWhenFlushed(1);
|
|
2248
2313
|
}
|
|
2249
2314
|
);
|