@sideboard-ai/core 0.1.107 → 0.1.110
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/agents/cursor-runner.cjs +87 -12
- package/dist/agents/cursor-runner.js +38 -12
- package/dist/{agents-T4RHL5UX.js → agents-MQDW3YXL.js} +6 -6
- package/dist/{agents-4XQANGFO.js → agents-WK54VP7J.js} +8 -8
- package/dist/{app-settings-2WH6DVOW.js → app-settings-5XAGNDX7.js} +3 -1
- package/dist/{app-settings-6AXBWM3K.js → app-settings-J4LUWIRN.js} +4 -2
- package/dist/{chunk-HUKCGRAT.js → chunk-3UOKB6VQ.js} +47 -2
- package/dist/{chunk-SMWVSSE5.js → chunk-4EWPKYOU.js} +4 -4
- package/dist/{chunk-7ZTQHC2Q.js → chunk-4NR5FL46.js} +11 -1
- package/dist/{chunk-TLPJHLLM.js → chunk-4TR3HZFT.js} +1 -1
- package/dist/{chunk-VTTTV2LM.js → chunk-7KWYXGIU.js} +2 -2
- package/dist/{chunk-KGSVLZV6.js → chunk-A4VZXJEJ.js} +2 -0
- package/dist/{chunk-5XUKY2JY.js → chunk-AROMOP3C.js} +8 -16
- package/dist/{chunk-PZVA2VDF.js → chunk-C4KHDW3U.js} +2 -2
- package/dist/{chunk-3SIFRHJ3.js → chunk-EAAB4EK5.js} +1597 -1704
- package/dist/{chunk-GYFNFU62.js → chunk-KQBI5HNT.js} +8 -16
- package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
- package/dist/{chunk-6HRR4T4P.js → chunk-RSIWPLRG.js} +483 -46
- package/dist/{chunk-EX4NZN3O.js → chunk-SGEVS5SY.js} +11 -1
- package/dist/{chunk-THXSFETX.js → chunk-VOD3HFLP.js} +4 -4
- package/dist/{chunk-XOYH3OMI.js → chunk-VOJSO3RM.js} +484 -55
- package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
- package/dist/{chunk-XEFHG6VG.js → chunk-XOZDAVOP.js} +1449 -1518
- package/dist/{chunk-LRO7YVLJ.js → chunk-YFAXVUY2.js} +2 -2
- package/dist/{chunk-6JJTMI7G.js → chunk-YXDR43ZC.js} +2 -2
- package/dist/{coordinator-prompt-4TUQUEHY.js → coordinator-prompt-AR66L3N4.js} +5 -5
- package/dist/{coordinator-prompt-YQWRXCPX.js → coordinator-prompt-BHMLWL64.js} +4 -4
- package/dist/{global-workspace-H37LFFXI.js → global-workspace-SKFODUQQ.js} +5 -5
- package/dist/{global-workspace-V6TMECDU.js → global-workspace-XSUFEIAQ.js} +6 -6
- package/dist/index.cjs +2388 -2006
- package/dist/index.d.cts +115 -26
- package/dist/index.d.ts +115 -26
- package/dist/index.js +141 -98
- package/dist/mcp/run-stdio.cjs +2354 -1988
- package/dist/mcp/run-stdio.js +90 -82
- package/dist/{orchestrator-DEHSKERK.js → orchestrator-FCZVCKBK.js} +11 -11
- package/dist/{orchestrator-2P7DX44Q.js → orchestrator-SCATSB3O.js} +8 -8
- package/dist/{thread-store-DQJGDKIJ.js → thread-store-LPTBVW5C.js} +1 -1
- package/dist/{thread-store-4OUEQ2DB.js → thread-store-OEALWU7Y.js} +1 -1
- package/dist/{workspaces-UPEVANU4.js → workspaces-HV3J4TTW.js} +7 -7
- package/dist/{workspaces-JU3P6FHB.js → workspaces-XAQVKTLO.js} +6 -6
- package/dist/{worktree-6MFKE465.js → worktree-N2EV24EE.js} +3 -3
- package/dist/{worktree-NR5YJG2E.js → worktree-XFJED3VU.js} +4 -4
- package/package.json +1 -1
|
@@ -204,27 +204,36 @@ function withCursorLocalHangGuards(local) {
|
|
|
204
204
|
return { ...local, enableAgentRetries: false };
|
|
205
205
|
}
|
|
206
206
|
var CURSOR_STREAM_IDLE_MS = 18e4;
|
|
207
|
-
async function* iterateUntilIdle(iterable, idleMs, onIdle) {
|
|
207
|
+
async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
|
|
208
208
|
const iterator = iterable[Symbol.asyncIterator]();
|
|
209
|
+
const bump = () => {
|
|
210
|
+
if (activity) activity.at = Date.now();
|
|
211
|
+
};
|
|
209
212
|
try {
|
|
213
|
+
let pending = iterator.next();
|
|
210
214
|
while (true) {
|
|
215
|
+
const waitMs = activity ? Math.max(0, idleMs - (Date.now() - activity.at)) : idleMs;
|
|
211
216
|
let idleTimer;
|
|
212
|
-
const next = iterator.next();
|
|
213
217
|
const raced = await Promise.race([
|
|
214
|
-
|
|
218
|
+
pending.then((result) => ({ kind: "item", result })),
|
|
215
219
|
new Promise((resolve) => {
|
|
216
|
-
idleTimer = setTimeout(() => resolve({ kind: "idle" }),
|
|
220
|
+
idleTimer = setTimeout(() => resolve({ kind: "idle" }), waitMs);
|
|
217
221
|
idleTimer.unref?.();
|
|
218
222
|
})
|
|
219
223
|
]);
|
|
220
224
|
if (idleTimer) clearTimeout(idleTimer);
|
|
221
225
|
if (raced.kind === "idle") {
|
|
226
|
+
if (activity && Date.now() - activity.at < idleMs) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
222
229
|
onIdle?.();
|
|
223
230
|
void iterator.return?.();
|
|
224
231
|
return;
|
|
225
232
|
}
|
|
226
233
|
if (raced.result.done) return;
|
|
234
|
+
bump();
|
|
227
235
|
yield raced.result.value;
|
|
236
|
+
pending = iterator.next();
|
|
228
237
|
}
|
|
229
238
|
} catch (err) {
|
|
230
239
|
void iterator.return?.();
|
|
@@ -427,11 +436,53 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
427
436
|
}
|
|
428
437
|
return [];
|
|
429
438
|
}
|
|
439
|
+
function nestedUpdateToEvents(update, parentId) {
|
|
440
|
+
if (update.type === "thinking-delta" && update.text) {
|
|
441
|
+
return [{ type: "thinking", data: update.text, parentId }];
|
|
442
|
+
}
|
|
443
|
+
if (update.type === "text-delta" && update.text) {
|
|
444
|
+
return [{ type: "stdout", data: update.text, parentId }];
|
|
445
|
+
}
|
|
446
|
+
if ((update.type === "tool-call-started" || update.type === "tool-call-completed") && update.callId && update.toolCall) {
|
|
447
|
+
const rawName = typeof update.toolCall.type === "string" ? update.toolCall.type : "tool";
|
|
448
|
+
const normalized = normalizeCursorToolCall(rawName, update.toolCall.args);
|
|
449
|
+
const events = [
|
|
450
|
+
{
|
|
451
|
+
type: "tool_use",
|
|
452
|
+
id: update.callId,
|
|
453
|
+
name: normalized.name,
|
|
454
|
+
input: normalized.input,
|
|
455
|
+
parentId
|
|
456
|
+
}
|
|
457
|
+
];
|
|
458
|
+
if (update.type === "tool-call-completed") {
|
|
459
|
+
events.push({
|
|
460
|
+
type: "tool_result",
|
|
461
|
+
id: update.callId,
|
|
462
|
+
content: unwrapCursorToolResult(update.toolCall.result),
|
|
463
|
+
isError: cursorToolResultIsError(void 0, update.toolCall.result),
|
|
464
|
+
parentId
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
return events;
|
|
468
|
+
}
|
|
469
|
+
return [];
|
|
470
|
+
}
|
|
471
|
+
function cursorDeltaToEvents(update) {
|
|
472
|
+
if (!update?.type) return [];
|
|
473
|
+
if (update.type === "tool-call-delta" && update.callId && update.taskUpdate) {
|
|
474
|
+
return nestedUpdateToEvents(update.taskUpdate, update.callId);
|
|
475
|
+
}
|
|
476
|
+
return [];
|
|
477
|
+
}
|
|
430
478
|
|
|
431
479
|
// src/agents/cursor-stream-coalesce.ts
|
|
432
480
|
function isTextEvent(event) {
|
|
433
481
|
return event.type === "stdout" || event.type === "thinking";
|
|
434
482
|
}
|
|
483
|
+
function parentKey(event) {
|
|
484
|
+
return event.parentId ?? "";
|
|
485
|
+
}
|
|
435
486
|
function createAgentStreamCoalescer(emit2, opts) {
|
|
436
487
|
const intervalMs = opts?.intervalMs ?? 32;
|
|
437
488
|
let pending = null;
|
|
@@ -444,7 +495,11 @@ function createAgentStreamCoalescer(emit2, opts) {
|
|
|
444
495
|
if (!pending) return;
|
|
445
496
|
const event = pending;
|
|
446
497
|
pending = null;
|
|
447
|
-
emit2({
|
|
498
|
+
emit2({
|
|
499
|
+
type: event.type,
|
|
500
|
+
data: event.data,
|
|
501
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
502
|
+
});
|
|
448
503
|
};
|
|
449
504
|
const schedule = () => {
|
|
450
505
|
if (timer) return;
|
|
@@ -459,11 +514,15 @@ function createAgentStreamCoalescer(emit2, opts) {
|
|
|
459
514
|
return;
|
|
460
515
|
}
|
|
461
516
|
if (!event.data) return;
|
|
462
|
-
if (pending && pending.type === event.type) {
|
|
517
|
+
if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
|
|
463
518
|
pending.data += event.data;
|
|
464
519
|
} else {
|
|
465
520
|
flush();
|
|
466
|
-
pending = {
|
|
521
|
+
pending = {
|
|
522
|
+
type: event.type,
|
|
523
|
+
data: event.data,
|
|
524
|
+
...event.parentId ? { parentId: event.parentId } : {}
|
|
525
|
+
};
|
|
467
526
|
}
|
|
468
527
|
schedule();
|
|
469
528
|
},
|
|
@@ -584,8 +643,11 @@ async function main() {
|
|
|
584
643
|
return createAgent();
|
|
585
644
|
}
|
|
586
645
|
}
|
|
587
|
-
async function sendPrompt(agent) {
|
|
588
|
-
const sendOpts =
|
|
646
|
+
async function sendPrompt(agent, extra) {
|
|
647
|
+
const sendOpts = {
|
|
648
|
+
...cursorSendOptions(mcpServers),
|
|
649
|
+
...extra
|
|
650
|
+
};
|
|
589
651
|
try {
|
|
590
652
|
return await agent.send(req.prompt, sendOpts);
|
|
591
653
|
} catch (err) {
|
|
@@ -626,9 +688,20 @@ async function main() {
|
|
|
626
688
|
process.once("SIGINT", onSignal);
|
|
627
689
|
async function runTurn(agent) {
|
|
628
690
|
emit({ type: "session_id", data: agent.agentId });
|
|
629
|
-
const run2 = await sendPrompt(agent);
|
|
630
|
-
liveRun = run2;
|
|
631
691
|
const stream = createAgentStreamCoalescer(emit);
|
|
692
|
+
const activity = { at: Date.now() };
|
|
693
|
+
const bump = () => {
|
|
694
|
+
activity.at = Date.now();
|
|
695
|
+
};
|
|
696
|
+
const run2 = await sendPrompt(agent, {
|
|
697
|
+
onDelta: ({ update }) => {
|
|
698
|
+
bump();
|
|
699
|
+
for (const event of cursorDeltaToEvents(update)) {
|
|
700
|
+
stream.push(event);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
liveRun = run2;
|
|
632
705
|
let streamIdle = false;
|
|
633
706
|
try {
|
|
634
707
|
for await (const msg of iterateUntilIdle(
|
|
@@ -641,8 +714,10 @@ async function main() {
|
|
|
641
714
|
data: "Cursor stream idle \u2014 finishing the turn (SDK stream did not close)"
|
|
642
715
|
});
|
|
643
716
|
void cancelLiveRun();
|
|
644
|
-
}
|
|
717
|
+
},
|
|
718
|
+
activity
|
|
645
719
|
)) {
|
|
720
|
+
bump();
|
|
646
721
|
for (const event of cursorSdkMessageToEvents(msg)) {
|
|
647
722
|
stream.push(event);
|
|
648
723
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createAgentStreamCoalescer
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-WIHKHR5R.js";
|
|
5
5
|
import {
|
|
6
|
+
cursorDeltaToEvents,
|
|
6
7
|
cursorSdkMessageToEvents,
|
|
7
8
|
ensureCursorRipgrepPath,
|
|
8
9
|
formatUnknownDetail
|
|
9
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-3UOKB6VQ.js";
|
|
10
11
|
import {
|
|
11
12
|
dropNestedElectronEnvFromProcess
|
|
12
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-4TR3HZFT.js";
|
|
13
14
|
import {
|
|
14
15
|
appDataDir
|
|
15
16
|
} from "../chunk-QZQEXME2.js";
|
|
@@ -57,27 +58,36 @@ function withCursorLocalHangGuards(local) {
|
|
|
57
58
|
return { ...local, enableAgentRetries: false };
|
|
58
59
|
}
|
|
59
60
|
var CURSOR_STREAM_IDLE_MS = 18e4;
|
|
60
|
-
async function* iterateUntilIdle(iterable, idleMs, onIdle) {
|
|
61
|
+
async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
|
|
61
62
|
const iterator = iterable[Symbol.asyncIterator]();
|
|
63
|
+
const bump = () => {
|
|
64
|
+
if (activity) activity.at = Date.now();
|
|
65
|
+
};
|
|
62
66
|
try {
|
|
67
|
+
let pending = iterator.next();
|
|
63
68
|
while (true) {
|
|
69
|
+
const waitMs = activity ? Math.max(0, idleMs - (Date.now() - activity.at)) : idleMs;
|
|
64
70
|
let idleTimer;
|
|
65
|
-
const next = iterator.next();
|
|
66
71
|
const raced = await Promise.race([
|
|
67
|
-
|
|
72
|
+
pending.then((result) => ({ kind: "item", result })),
|
|
68
73
|
new Promise((resolve) => {
|
|
69
|
-
idleTimer = setTimeout(() => resolve({ kind: "idle" }),
|
|
74
|
+
idleTimer = setTimeout(() => resolve({ kind: "idle" }), waitMs);
|
|
70
75
|
idleTimer.unref?.();
|
|
71
76
|
})
|
|
72
77
|
]);
|
|
73
78
|
if (idleTimer) clearTimeout(idleTimer);
|
|
74
79
|
if (raced.kind === "idle") {
|
|
80
|
+
if (activity && Date.now() - activity.at < idleMs) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
75
83
|
onIdle?.();
|
|
76
84
|
void iterator.return?.();
|
|
77
85
|
return;
|
|
78
86
|
}
|
|
79
87
|
if (raced.result.done) return;
|
|
88
|
+
bump();
|
|
80
89
|
yield raced.result.value;
|
|
90
|
+
pending = iterator.next();
|
|
81
91
|
}
|
|
82
92
|
} catch (err) {
|
|
83
93
|
void iterator.return?.();
|
|
@@ -198,8 +208,11 @@ async function main() {
|
|
|
198
208
|
return createAgent();
|
|
199
209
|
}
|
|
200
210
|
}
|
|
201
|
-
async function sendPrompt(agent) {
|
|
202
|
-
const sendOpts =
|
|
211
|
+
async function sendPrompt(agent, extra) {
|
|
212
|
+
const sendOpts = {
|
|
213
|
+
...cursorSendOptions(mcpServers),
|
|
214
|
+
...extra
|
|
215
|
+
};
|
|
203
216
|
try {
|
|
204
217
|
return await agent.send(req.prompt, sendOpts);
|
|
205
218
|
} catch (err) {
|
|
@@ -240,9 +253,20 @@ async function main() {
|
|
|
240
253
|
process.once("SIGINT", onSignal);
|
|
241
254
|
async function runTurn(agent) {
|
|
242
255
|
emit({ type: "session_id", data: agent.agentId });
|
|
243
|
-
const run = await sendPrompt(agent);
|
|
244
|
-
liveRun = run;
|
|
245
256
|
const stream = createAgentStreamCoalescer(emit);
|
|
257
|
+
const activity = { at: Date.now() };
|
|
258
|
+
const bump = () => {
|
|
259
|
+
activity.at = Date.now();
|
|
260
|
+
};
|
|
261
|
+
const run = await sendPrompt(agent, {
|
|
262
|
+
onDelta: ({ update }) => {
|
|
263
|
+
bump();
|
|
264
|
+
for (const event of cursorDeltaToEvents(update)) {
|
|
265
|
+
stream.push(event);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
liveRun = run;
|
|
246
270
|
let streamIdle = false;
|
|
247
271
|
try {
|
|
248
272
|
for await (const msg of iterateUntilIdle(
|
|
@@ -255,8 +279,10 @@ async function main() {
|
|
|
255
279
|
data: "Cursor stream idle \u2014 finishing the turn (SDK stream did not close)"
|
|
256
280
|
});
|
|
257
281
|
void cancelLiveRun();
|
|
258
|
-
}
|
|
282
|
+
},
|
|
283
|
+
activity
|
|
259
284
|
)) {
|
|
285
|
+
bump();
|
|
260
286
|
for (const event of cursorSdkMessageToEvents(msg)) {
|
|
261
287
|
stream.push(event);
|
|
262
288
|
}
|
|
@@ -32,19 +32,19 @@ import {
|
|
|
32
32
|
resolveCursorModelId,
|
|
33
33
|
resolveLoginCommand,
|
|
34
34
|
resolveQuotaFallbackAgent
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-VOJSO3RM.js";
|
|
36
36
|
import "./chunk-7YKXHBIW.js";
|
|
37
37
|
import {
|
|
38
38
|
ORCHESTRATOR_AGENT_KINDS,
|
|
39
39
|
assertOrchestratorCapableAgent,
|
|
40
40
|
coerceOrchestratorAgent,
|
|
41
41
|
isOrchestratorCapableAgent
|
|
42
|
-
} from "./chunk-
|
|
43
|
-
import "./chunk-
|
|
44
|
-
import "./chunk-
|
|
42
|
+
} from "./chunk-VOD3HFLP.js";
|
|
43
|
+
import "./chunk-AROMOP3C.js";
|
|
44
|
+
import "./chunk-YXDR43ZC.js";
|
|
45
45
|
import "./chunk-B3SJXYIJ.js";
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-
|
|
46
|
+
import "./chunk-KYOTBZ6S.js";
|
|
47
|
+
import "./chunk-SGEVS5SY.js";
|
|
48
48
|
import "./chunk-NSTQ6QKD.js";
|
|
49
49
|
import "./chunk-KGZBYWZ3.js";
|
|
50
50
|
import "./chunk-BD2ICC4D.js";
|
|
@@ -28,25 +28,25 @@ import {
|
|
|
28
28
|
resolveCursorModelId,
|
|
29
29
|
resolveLoginCommand,
|
|
30
30
|
resolveQuotaFallbackAgent
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-RSIWPLRG.js";
|
|
32
32
|
import "./chunk-2GO3YKBA.js";
|
|
33
33
|
import {
|
|
34
34
|
ORCHESTRATOR_AGENT_KINDS,
|
|
35
35
|
assertOrchestratorCapableAgent,
|
|
36
36
|
coerceOrchestratorAgent,
|
|
37
37
|
isOrchestratorCapableAgent
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-4EWPKYOU.js";
|
|
39
|
+
import "./chunk-KQBI5HNT.js";
|
|
40
40
|
import {
|
|
41
41
|
cursorSdkMessageToEvents,
|
|
42
42
|
parseCursorRunnerLine
|
|
43
|
-
} from "./chunk-
|
|
44
|
-
import "./chunk-
|
|
43
|
+
} from "./chunk-3UOKB6VQ.js";
|
|
44
|
+
import "./chunk-C4KHDW3U.js";
|
|
45
45
|
import "./chunk-FKOIHGKV.js";
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-
|
|
46
|
+
import "./chunk-4NR5FL46.js";
|
|
47
|
+
import "./chunk-4TR3HZFT.js";
|
|
48
48
|
import "./chunk-JT7R45JB.js";
|
|
49
|
-
import "./chunk-
|
|
49
|
+
import "./chunk-A4VZXJEJ.js";
|
|
50
50
|
import "./chunk-77WWLBCI.js";
|
|
51
51
|
import "./chunk-QZQEXME2.js";
|
|
52
52
|
import {
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
childEnvWithAppSettings,
|
|
20
20
|
claudeChromeEnabled,
|
|
21
21
|
claudeUserSettingsPath,
|
|
22
|
+
cowboyModeEnabled,
|
|
22
23
|
deleteBranchOnPurgeEnabled,
|
|
23
24
|
disconnectLinearConnection,
|
|
24
25
|
ensureSlackDeviceIdentity,
|
|
@@ -55,7 +56,7 @@ import {
|
|
|
55
56
|
updateDefaultsSettings,
|
|
56
57
|
updateIntegrationsSettings,
|
|
57
58
|
updateOpencodeSettings
|
|
58
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-SGEVS5SY.js";
|
|
59
60
|
import "./chunk-NSTQ6QKD.js";
|
|
60
61
|
import "./chunk-KGZBYWZ3.js";
|
|
61
62
|
import "./chunk-BD2ICC4D.js";
|
|
@@ -78,6 +79,7 @@ export {
|
|
|
78
79
|
childEnvWithAppSettings,
|
|
79
80
|
claudeChromeEnabled,
|
|
80
81
|
claudeUserSettingsPath,
|
|
82
|
+
cowboyModeEnabled,
|
|
81
83
|
deleteBranchOnPurgeEnabled,
|
|
82
84
|
disconnectLinearConnection,
|
|
83
85
|
ensureSlackDeviceIdentity,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
childEnvWithAppSettings,
|
|
18
18
|
claudeChromeEnabled,
|
|
19
19
|
claudeUserSettingsPath,
|
|
20
|
+
cowboyModeEnabled,
|
|
20
21
|
deleteBranchOnPurgeEnabled,
|
|
21
22
|
disconnectLinearConnection,
|
|
22
23
|
ensureSlackDeviceIdentity,
|
|
@@ -53,8 +54,8 @@ import {
|
|
|
53
54
|
updateDefaultsSettings,
|
|
54
55
|
updateIntegrationsSettings,
|
|
55
56
|
updateOpencodeSettings
|
|
56
|
-
} from "./chunk-
|
|
57
|
-
import "./chunk-
|
|
57
|
+
} from "./chunk-4NR5FL46.js";
|
|
58
|
+
import "./chunk-4TR3HZFT.js";
|
|
58
59
|
import "./chunk-JT7R45JB.js";
|
|
59
60
|
import "./chunk-77WWLBCI.js";
|
|
60
61
|
import "./chunk-QZQEXME2.js";
|
|
@@ -77,6 +78,7 @@ export {
|
|
|
77
78
|
childEnvWithAppSettings,
|
|
78
79
|
claudeChromeEnabled,
|
|
79
80
|
claudeUserSettingsPath,
|
|
81
|
+
cowboyModeEnabled,
|
|
80
82
|
deleteBranchOnPurgeEnabled,
|
|
81
83
|
disconnectLinearConnection,
|
|
82
84
|
ensureSlackDeviceIdentity,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isElectronLikeCommand,
|
|
3
3
|
wrapElectronAsNodeLaunch
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4TR3HZFT.js";
|
|
5
5
|
import {
|
|
6
6
|
run
|
|
7
7
|
} from "./chunk-LGXBYZZA.js";
|
|
@@ -94,6 +94,8 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
94
94
|
if (tail.length === 0) return "";
|
|
95
95
|
const cursorStartup = [...tail].reverse().find((line) => /cursor startup failed:/i.test(line));
|
|
96
96
|
if (cursorStartup) return clipStderr(cursorStartup, maxChars);
|
|
97
|
+
const cursorRunFailed = [...tail].reverse().find((line) => /^cursor run failed\b/i.test(line.trim()));
|
|
98
|
+
if (cursorRunFailed) return clipStderr(cursorRunFailed, maxChars);
|
|
97
99
|
if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
|
|
98
100
|
if (tail.some(looksLikeHomebrewLibuvCrash)) return HOMEBREW_LIBUV_SUMMARY;
|
|
99
101
|
if (tail.some(
|
|
@@ -124,7 +126,7 @@ function looksLikeRetryableRunnerCrash(text) {
|
|
|
124
126
|
const lower = text.trim().toLowerCase();
|
|
125
127
|
if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
|
|
126
128
|
if (!lower) return true;
|
|
127
|
-
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
129
|
+
return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
|
|
128
130
|
lower
|
|
129
131
|
);
|
|
130
132
|
}
|
|
@@ -182,6 +184,9 @@ function humanizeAgentFailDetail(detail) {
|
|
|
182
184
|
if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
|
|
183
185
|
return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
184
186
|
}
|
|
187
|
+
if (/connection stalled/.test(lower)) {
|
|
188
|
+
return /retry the turn/i.test(raw) ? raw : `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
189
|
+
}
|
|
185
190
|
return raw;
|
|
186
191
|
}
|
|
187
192
|
function turnFailChatText(opts) {
|
|
@@ -357,6 +362,45 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
357
362
|
}
|
|
358
363
|
return [];
|
|
359
364
|
}
|
|
365
|
+
function nestedUpdateToEvents(update, parentId) {
|
|
366
|
+
if (update.type === "thinking-delta" && update.text) {
|
|
367
|
+
return [{ type: "thinking", data: update.text, parentId }];
|
|
368
|
+
}
|
|
369
|
+
if (update.type === "text-delta" && update.text) {
|
|
370
|
+
return [{ type: "stdout", data: update.text, parentId }];
|
|
371
|
+
}
|
|
372
|
+
if ((update.type === "tool-call-started" || update.type === "tool-call-completed") && update.callId && update.toolCall) {
|
|
373
|
+
const rawName = typeof update.toolCall.type === "string" ? update.toolCall.type : "tool";
|
|
374
|
+
const normalized = normalizeCursorToolCall(rawName, update.toolCall.args);
|
|
375
|
+
const events = [
|
|
376
|
+
{
|
|
377
|
+
type: "tool_use",
|
|
378
|
+
id: update.callId,
|
|
379
|
+
name: normalized.name,
|
|
380
|
+
input: normalized.input,
|
|
381
|
+
parentId
|
|
382
|
+
}
|
|
383
|
+
];
|
|
384
|
+
if (update.type === "tool-call-completed") {
|
|
385
|
+
events.push({
|
|
386
|
+
type: "tool_result",
|
|
387
|
+
id: update.callId,
|
|
388
|
+
content: unwrapCursorToolResult(update.toolCall.result),
|
|
389
|
+
isError: cursorToolResultIsError(void 0, update.toolCall.result),
|
|
390
|
+
parentId
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
return events;
|
|
394
|
+
}
|
|
395
|
+
return [];
|
|
396
|
+
}
|
|
397
|
+
function cursorDeltaToEvents(update) {
|
|
398
|
+
if (!update?.type) return [];
|
|
399
|
+
if (update.type === "tool-call-delta" && update.callId && update.taskUpdate) {
|
|
400
|
+
return nestedUpdateToEvents(update.taskUpdate, update.callId);
|
|
401
|
+
}
|
|
402
|
+
return [];
|
|
403
|
+
}
|
|
360
404
|
function parseCursorRunnerLine(line) {
|
|
361
405
|
const trimmed = line.trim();
|
|
362
406
|
if (!trimmed) return null;
|
|
@@ -672,6 +716,7 @@ export {
|
|
|
672
716
|
applyNodeLaunch,
|
|
673
717
|
resolveNodeLaunch,
|
|
674
718
|
cursorSdkMessageToEvents,
|
|
719
|
+
cursorDeltaToEvents,
|
|
675
720
|
parseCursorRunnerLine,
|
|
676
721
|
cursorRipgrepEnv,
|
|
677
722
|
ensureCursorRipgrepPath
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureGlobalCoordinatorCwd
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KQBI5HNT.js";
|
|
4
4
|
import {
|
|
5
5
|
allocateTeamName,
|
|
6
6
|
takenSlugsFromThread,
|
|
7
7
|
teamSlugFromName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-C4KHDW3U.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveNewThreadOptions,
|
|
11
11
|
resolveThreadDefaults
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-4NR5FL46.js";
|
|
13
13
|
import {
|
|
14
14
|
createEmptyThread,
|
|
15
15
|
listThreads,
|
|
16
16
|
updateThread,
|
|
17
17
|
writeThread
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-A4VZXJEJ.js";
|
|
19
19
|
import {
|
|
20
20
|
globalAgentCwd
|
|
21
21
|
} from "./chunk-QZQEXME2.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
stripNestedElectronEnv
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4TR3HZFT.js";
|
|
4
4
|
import {
|
|
5
5
|
chmodOwnerOnly,
|
|
6
6
|
writePrivateFile
|
|
@@ -430,6 +430,9 @@ function normalizeAdvanced(raw) {
|
|
|
430
430
|
if (typeof source.deleteBranchOnPurge === "boolean") {
|
|
431
431
|
out.deleteBranchOnPurge = source.deleteBranchOnPurge;
|
|
432
432
|
}
|
|
433
|
+
if (typeof source.cowboyMode === "boolean") {
|
|
434
|
+
out.cowboyMode = source.cowboyMode;
|
|
435
|
+
}
|
|
433
436
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
434
437
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
435
438
|
}
|
|
@@ -964,6 +967,9 @@ function updateAdvancedSettings(patch) {
|
|
|
964
967
|
if (typeof patch.deleteBranchOnPurge === "boolean") {
|
|
965
968
|
advanced.deleteBranchOnPurge = patch.deleteBranchOnPurge;
|
|
966
969
|
}
|
|
970
|
+
if (typeof patch.cowboyMode === "boolean") {
|
|
971
|
+
advanced.cowboyMode = patch.cowboyMode;
|
|
972
|
+
}
|
|
967
973
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
968
974
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
969
975
|
}
|
|
@@ -1014,6 +1020,9 @@ function caffeinateWhileCloudConnectEnabled(settings = loadAppSettings()) {
|
|
|
1014
1020
|
function deleteBranchOnPurgeEnabled(settings = loadAppSettings()) {
|
|
1015
1021
|
return Boolean(settings.advanced.deleteBranchOnPurge);
|
|
1016
1022
|
}
|
|
1023
|
+
function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
1024
|
+
return Boolean(settings.advanced.cowboyMode);
|
|
1025
|
+
}
|
|
1017
1026
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
1018
1027
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
1019
1028
|
}
|
|
@@ -1153,6 +1162,7 @@ export {
|
|
|
1153
1162
|
caffeinateWhileSchedulesEnabled,
|
|
1154
1163
|
caffeinateWhileCloudConnectEnabled,
|
|
1155
1164
|
deleteBranchOnPurgeEnabled,
|
|
1165
|
+
cowboyModeEnabled,
|
|
1156
1166
|
autoArchiveOnMergeEnabled,
|
|
1157
1167
|
autoCleanupOrphansEnabled,
|
|
1158
1168
|
orchestrationQuotaOnLimit,
|
|
@@ -35,7 +35,7 @@ function isElectronLikeCommand(command) {
|
|
|
35
35
|
const name = command.trim();
|
|
36
36
|
if (!name) return false;
|
|
37
37
|
if (process.versions.electron && name === process.execPath) return true;
|
|
38
|
-
return /(?:^|[/\\])Electron(?:\.exe)?$/i.test(name) || /
|
|
38
|
+
return /(?:^|[/\\])Electron(?:\.exe)?$/i.test(name) || /(?:^|[/\\])Sideboard(?:\.exe)?$/i.test(name) || /(?:Sideboard|Electron)\.app[/\\]Contents[/\\]MacOS[/\\]/i.test(name);
|
|
39
39
|
}
|
|
40
40
|
function unwrapStrippedElectronLaunch(command, args) {
|
|
41
41
|
if (!isStrippedElectronLaunch(command, args) || !args || args.length < 4) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isGlobalRepoPath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4EWPKYOU.js";
|
|
4
4
|
import {
|
|
5
5
|
ensureGhPreferOrigin,
|
|
6
6
|
resolveRepoRoot
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-C4KHDW3U.js";
|
|
8
8
|
import {
|
|
9
9
|
appDataDir
|
|
10
10
|
} from "./chunk-QZQEXME2.js";
|
|
@@ -41,6 +41,7 @@ function normalizeThread(raw) {
|
|
|
41
41
|
prTitle: raw.prTitle ?? null,
|
|
42
42
|
prState: raw.prState ?? null,
|
|
43
43
|
skipAutoArchiveOnMerge: Boolean(raw.skipAutoArchiveOnMerge),
|
|
44
|
+
cowboy: Boolean(raw.cowboy),
|
|
44
45
|
stackId: raw.stackId ?? null,
|
|
45
46
|
stackLayer: raw.stackLayer ?? null,
|
|
46
47
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
@@ -69,6 +70,7 @@ function createEmptyThread(partial) {
|
|
|
69
70
|
prTitle: partial.prTitle ?? null,
|
|
70
71
|
prState: partial.prState ?? null,
|
|
71
72
|
skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
|
|
73
|
+
cowboy: Boolean(partial.cowboy),
|
|
72
74
|
stackId: partial.stackId ?? null,
|
|
73
75
|
stackLayer: partial.stackLayer ?? null,
|
|
74
76
|
userSetTitle: partial.userSetTitle ?? false,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
resolveGithubRepoSlug
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YXDR43ZC.js";
|
|
6
6
|
import {
|
|
7
7
|
resolveThreadDefaults
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SGEVS5SY.js";
|
|
9
9
|
import {
|
|
10
10
|
globalAgentCwd,
|
|
11
11
|
sideboardReposDir
|
|
@@ -71,14 +71,14 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
71
71
|
"- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
|
|
72
72
|
"Inspect / review / PRs:",
|
|
73
73
|
"- get_diff \u2014 compact diff summary",
|
|
74
|
-
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .
|
|
74
|
+
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else seeds that skill / local guidelines; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id',
|
|
75
75
|
"- ask_git \u2014 commit & push, open a draft PR, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing.",
|
|
76
76
|
'- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
|
|
77
77
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
78
78
|
"Process guides:",
|
|
79
79
|
"- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
|
|
80
|
-
"- Recurring shapes: have the worktree agent write `.claude/skills/<kebab-name>/SKILL.md` (commit it) so later threads and native Claude Code / attach see it. Do not use `.sideboard/skills
|
|
81
|
-
"- One-offs: no guide. Same miss across threads: edit the skill or `.
|
|
80
|
+
"- Recurring shapes: have the worktree agent write `.claude/skills/<kebab-name>/SKILL.md` (commit it) so later threads and native Claude Code / attach see it. Merge-review sentences go in `.claude/skills/review/SKILL.md` (create it \u2014 that is allowed). Do not use `.sideboard/skills/` (that folder only). Codex/OpenCode: one line in AGENTS.md pointing at that file.",
|
|
81
|
+
"- One-offs: no guide. Same miss across threads: edit the skill or `.claude/skills/review/SKILL.md`, then rerun the batch \u2014 do not patch three threads.",
|
|
82
82
|
"Human-only (do not attempt): ready-for-review land (confirm_land), purge_thread.",
|
|
83
83
|
"Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
|
|
84
84
|
"Bash / Read / etc: allowed for (1) inspecting target worktrees / registered repo paths from MCP, and (2) greenfield setup under ~/sideboard/repos (git clone, gh repo create, git init+remote). Never git init/clone *inside* this synthetic home cwd \u2014 emptiness here is expected, not a bug."
|
|
@@ -99,19 +99,11 @@ function coordinatorTurnReminder(opts) {
|
|
|
99
99
|
const goal = opts.goal?.trim();
|
|
100
100
|
return [
|
|
101
101
|
"Sideboard Orchestration (mandatory):",
|
|
102
|
-
"- You oversee
|
|
103
|
-
|
|
104
|
-
"- Registered workspaces / child threads are the fleet you manage via Sideboard MCP.",
|
|
105
|
-
`- YOUR orchestration thread id is ${opts.parentId}`,
|
|
106
|
-
`- Always pass parentThreadId="${opts.parentId}" on create_thread (never invent or reuse another uuid).`,
|
|
107
|
-
`- Or omit parentThreadId \u2014 Sideboard MCP already binds children to ${opts.parentId}.`,
|
|
102
|
+
"- You oversee worktree agents from a synthetic empty cwd (not a git repo). Follow AGENTS.md / CLAUDE.md.",
|
|
103
|
+
`- YOUR orchestration thread id is ${opts.parentId} \u2014 pass parentThreadId="${opts.parentId}" on create_thread, or omit it.`,
|
|
108
104
|
goal ? `- Goal / title: ${goal}` : null,
|
|
109
105
|
accountDefaultsPlaybookLine(),
|
|
110
|
-
|
|
111
|
-
"- Existing repo: create_thread on a repoPath \u2192 send_to_thread \u2192 wait_for_turn. If stillRunning, the child is working (progress is tools/thinking) \u2014 wait_for_turn again; do not ping it. If status is error, lastError/text is the failure \u2014 adapt (switch agent, tell the user). Commit/push/draft PR with ask_git on the child, then wait_for_turn \u2014 never git/gh from this cwd. Call ask_git merge only if the user explicitly asked to merge.",
|
|
112
|
-
"- New repo: Bash (clone or gh repo create under ~/sideboard/repos/<name>) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
113
|
-
"- When naming threads for the user, link them as `[Title](sideboard://thread/<id>)`.",
|
|
114
|
-
"- If they will wait on Slack, leave the Mac, or rely on overnight schedules, call set_caffeinate enabled=true (or they can enable Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled). When they say they are done / wrapping up / going to sleep, call set_caffeinate enabled=false. Closing this chat also turns it off."
|
|
106
|
+
"- Status: list_threads. Link chats as `[Title](sideboard://thread/<id>)`. Merge only if the user asked."
|
|
115
107
|
].filter(Boolean).join("\n");
|
|
116
108
|
}
|
|
117
109
|
function ensureGlobalCoordinatorCwd(opts) {
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
getGithubGitAuthMode,
|
|
6
6
|
getGithubPat
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4NR5FL46.js";
|
|
8
8
|
import {
|
|
9
9
|
listThreads
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-A4VZXJEJ.js";
|
|
11
11
|
import {
|
|
12
12
|
worktreesRoot
|
|
13
13
|
} from "./chunk-QZQEXME2.js";
|