@sideboard-ai/core 0.1.109 → 0.1.111

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/agents/cursor-runner.cjs +90 -15
  2. package/dist/agents/cursor-runner.js +37 -11
  3. package/dist/{agents-XB332VUJ.js → agents-GH3FWDW2.js} +6 -6
  4. package/dist/{agents-YIMHDI46.js → agents-NN22A4G5.js} +7 -7
  5. package/dist/{app-settings-EBCVMFF6.js → app-settings-5XAGNDX7.js} +3 -1
  6. package/dist/{app-settings-IYSSVZHH.js → app-settings-J4LUWIRN.js} +3 -1
  7. package/dist/{chunk-WD2TARQS.js → chunk-363Z34PY.js} +72 -12
  8. package/dist/{chunk-756EO4GK.js → chunk-4EWPKYOU.js} +4 -4
  9. package/dist/{chunk-4LKD3PGO.js → chunk-4NR5FL46.js} +10 -0
  10. package/dist/{chunk-FBV6NK62.js → chunk-7KWYXGIU.js} +2 -2
  11. package/dist/{chunk-KGSVLZV6.js → chunk-A4VZXJEJ.js} +2 -0
  12. package/dist/{chunk-VRTKGKUW.js → chunk-AROMOP3C.js} +2 -2
  13. package/dist/{chunk-EW7COXYE.js → chunk-C4KHDW3U.js} +2 -2
  14. package/dist/{chunk-Q6B3NRCT.js → chunk-DMJKOFTO.js} +159 -288
  15. package/dist/{chunk-LTPX5N6K.js → chunk-JTQQPJAU.js} +167 -277
  16. package/dist/{chunk-I2OJ2YSP.js → chunk-KQBI5HNT.js} +2 -2
  17. package/dist/{chunk-AY2EQI2P.js → chunk-KVFNTWFG.js} +506 -60
  18. package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
  19. package/dist/{chunk-KKHDPV45.js → chunk-NC3U42ZP.js} +473 -37
  20. package/dist/{chunk-NE4TOOKS.js → chunk-SGEVS5SY.js} +10 -0
  21. package/dist/{chunk-TROJ3PVH.js → chunk-VOD3HFLP.js} +4 -4
  22. package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
  23. package/dist/{chunk-OQDIYVDD.js → chunk-YFAXVUY2.js} +2 -2
  24. package/dist/{chunk-JVIW55KT.js → chunk-YXDR43ZC.js} +2 -2
  25. package/dist/{coordinator-prompt-JKOU6BWV.js → coordinator-prompt-AR66L3N4.js} +4 -4
  26. package/dist/{coordinator-prompt-V66BYTUV.js → coordinator-prompt-BHMLWL64.js} +4 -4
  27. package/dist/{global-workspace-WBQWQQQY.js → global-workspace-SKFODUQQ.js} +5 -5
  28. package/dist/{global-workspace-NCTBE7G7.js → global-workspace-XSUFEIAQ.js} +5 -5
  29. package/dist/index.cjs +880 -512
  30. package/dist/index.d.cts +51 -3
  31. package/dist/index.d.ts +51 -3
  32. package/dist/index.js +44 -23
  33. package/dist/mcp/run-stdio.cjs +858 -511
  34. package/dist/mcp/run-stdio.js +17 -12
  35. package/dist/{orchestrator-JVGVPKLI.js → orchestrator-4T2SXDZ7.js} +8 -8
  36. package/dist/{orchestrator-6W7EKSPO.js → orchestrator-EP57AB5W.js} +10 -10
  37. package/dist/{thread-store-DQJGDKIJ.js → thread-store-LPTBVW5C.js} +1 -1
  38. package/dist/{thread-store-4OUEQ2DB.js → thread-store-OEALWU7Y.js} +1 -1
  39. package/dist/{workspaces-SUBEDSGB.js → workspaces-HV3J4TTW.js} +6 -6
  40. package/dist/{workspaces-I3554R3F.js → workspaces-XAQVKTLO.js} +6 -6
  41. package/dist/{worktree-7H6HB6GW.js → worktree-N2EV24EE.js} +3 -3
  42. package/dist/{worktree-2UWO7VEK.js → worktree-XFJED3VU.js} +3 -3
  43. package/package.json +1 -1
@@ -58,7 +58,6 @@ function appDataDir() {
58
58
  var import_node_fs8 = require("fs");
59
59
  var import_node_module = require("module");
60
60
  var import_node_path9 = require("path");
61
- var import_node_url = require("url");
62
61
 
63
62
  // src/agents/node-launch.ts
64
63
  var import_node_fs7 = require("fs");
@@ -111,7 +110,6 @@ function nodeReadableScriptPath(scriptPath) {
111
110
  }
112
111
 
113
112
  // src/agents/cursor-ripgrep.ts
114
- var import_meta = {};
115
113
  var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
116
114
  function rgBinaryName() {
117
115
  return process.platform === "win32" ? "rg.exe" : "rg";
@@ -158,7 +156,9 @@ function resolveCursorRipgrepPath(opts) {
158
156
  packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
159
157
  );
160
158
  if (fromPackaged) return fromPackaged;
161
- const start = opts?.startFile?.trim() || process.argv[1] || (0, import_node_url.fileURLToPath)(import_meta.url);
159
+ const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
160
+ // eslint-disable-next-line camelcase
161
+ (typeof __filename !== "undefined" ? __filename : "");
162
162
  return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
163
163
  }
164
164
  function ensureCursorRipgrepPath(opts) {
@@ -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
- next.then((result) => ({ kind: "item", result })),
218
+ pending.then((result) => ({ kind: "item", result })),
215
219
  new Promise((resolve) => {
216
- idleTimer = setTimeout(() => resolve({ kind: "idle" }), idleMs);
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({ type: event.type, data: event.data });
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 = { type: event.type, data: event.data };
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 = cursorSendOptions(mcpServers);
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,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createAgentStreamCoalescer
4
- } from "../chunk-MMI4RJ5I.js";
4
+ } from "../chunk-WIHKHR5R.js";
5
5
  import {
6
+ cursorDeltaToEvents,
6
7
  cursorSdkMessageToEvents,
7
8
  ensureCursorRipgrepPath,
8
9
  formatUnknownDetail
9
- } from "../chunk-WD2TARQS.js";
10
+ } from "../chunk-363Z34PY.js";
10
11
  import {
11
12
  dropNestedElectronEnvFromProcess
12
13
  } from "../chunk-4TR3HZFT.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
- next.then((result) => ({ kind: "item", result })),
72
+ pending.then((result) => ({ kind: "item", result })),
68
73
  new Promise((resolve) => {
69
- idleTimer = setTimeout(() => resolve({ kind: "idle" }), idleMs);
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 = cursorSendOptions(mcpServers);
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-AY2EQI2P.js";
35
+ } from "./chunk-KVFNTWFG.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-TROJ3PVH.js";
43
- import "./chunk-VRTKGKUW.js";
44
- import "./chunk-JVIW55KT.js";
42
+ } from "./chunk-VOD3HFLP.js";
43
+ import "./chunk-AROMOP3C.js";
44
+ import "./chunk-YXDR43ZC.js";
45
45
  import "./chunk-B3SJXYIJ.js";
46
- import "./chunk-P3BQ5DOL.js";
47
- import "./chunk-NE4TOOKS.js";
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-KKHDPV45.js";
31
+ } from "./chunk-NC3U42ZP.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-756EO4GK.js";
39
- import "./chunk-I2OJ2YSP.js";
38
+ } from "./chunk-4EWPKYOU.js";
39
+ import "./chunk-KQBI5HNT.js";
40
40
  import {
41
41
  cursorSdkMessageToEvents,
42
42
  parseCursorRunnerLine
43
- } from "./chunk-WD2TARQS.js";
44
- import "./chunk-EW7COXYE.js";
43
+ } from "./chunk-363Z34PY.js";
44
+ import "./chunk-C4KHDW3U.js";
45
45
  import "./chunk-FKOIHGKV.js";
46
- import "./chunk-4LKD3PGO.js";
46
+ import "./chunk-4NR5FL46.js";
47
47
  import "./chunk-4TR3HZFT.js";
48
48
  import "./chunk-JT7R45JB.js";
49
- import "./chunk-KGSVLZV6.js";
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-NE4TOOKS.js";
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,7 +54,7 @@ import {
53
54
  updateDefaultsSettings,
54
55
  updateIntegrationsSettings,
55
56
  updateOpencodeSettings
56
- } from "./chunk-4LKD3PGO.js";
57
+ } from "./chunk-4NR5FL46.js";
57
58
  import "./chunk-4TR3HZFT.js";
58
59
  import "./chunk-JT7R45JB.js";
59
60
  import "./chunk-77WWLBCI.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,
@@ -52,7 +52,7 @@ function extractJsonErrorMessage(obj) {
52
52
  var NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
53
53
  function isPinnedStderrLine(line) {
54
54
  if (/^\s*at\s/.test(line)) return false;
55
- return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:/i.test(
55
+ return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:|FATAL ERROR|heap out of memory|javascript heap|OOMErrorHandler|FatalProcessOutOfMemory/i.test(
56
56
  line
57
57
  );
58
58
  }
@@ -75,15 +75,22 @@ function looksLikeMinifiedJsDump(line) {
75
75
  function looksLikeNestedElectronCrash(line) {
76
76
  return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
77
77
  }
78
- function looksLikeHomebrewLibuvCrash(line) {
79
- const uvRun = /uv_run/i.test(line);
80
- const spin = /SpinEventLoopInternal/i.test(line);
81
- const homebrewUv = /Cellar\/libuv|libuv\.\d\.dylib/i.test(line);
82
- const homebrewNode = /Cellar\/node\//i.test(line);
83
- return uvRun && (homebrewUv || spin || homebrewNode) || spin && (homebrewUv || homebrewNode);
78
+ function looksLikeNativeEventLoopCrash(text) {
79
+ return /uv_run|uv__io_poll|SpinEventLoopInternal/i.test(text);
80
+ }
81
+ function looksLikeV8Oom(text) {
82
+ return /javascript heap|reached heap limit|OOMErrorHandler|FatalProcessOutOfMemory|Allocation failed - JavaScript heap/i.test(
83
+ text
84
+ );
85
+ }
86
+ function looksLikeHomebrewLibuvCrash(text) {
87
+ if (!looksLikeNativeEventLoopCrash(text)) return false;
88
+ return /Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(text);
84
89
  }
85
90
  var NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
86
91
  var HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
92
+ var BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
93
+ var V8_OOM_SUMMARY = "Cursor runner ran out of memory (JavaScript heap). Retry; if it keeps happening, exclude large files from the project folder or start a new chat.";
87
94
  var MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
88
95
  function clipStderr(text, maxChars) {
89
96
  const trimmed = text.trim();
@@ -97,7 +104,12 @@ function summarizeTurnStderr(tail, maxChars = 500) {
97
104
  const cursorRunFailed = [...tail].reverse().find((line) => /^cursor run failed\b/i.test(line.trim()));
98
105
  if (cursorRunFailed) return clipStderr(cursorRunFailed, maxChars);
99
106
  if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
100
- if (tail.some(looksLikeHomebrewLibuvCrash)) return HOMEBREW_LIBUV_SUMMARY;
107
+ const blob = tail.join("\n");
108
+ if (looksLikeV8Oom(blob)) return V8_OOM_SUMMARY;
109
+ if (looksLikeHomebrewLibuvCrash(blob)) return HOMEBREW_LIBUV_SUMMARY;
110
+ if (looksLikeNativeEventLoopCrash(blob)) {
111
+ return BUNDLED_NODE_CRASH_SUMMARY;
112
+ }
101
113
  if (tail.some(
102
114
  (line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
103
115
  )) {
@@ -123,10 +135,11 @@ function looksLikeInvalidAgentSession(text) {
123
135
  function looksLikeRetryableRunnerCrash(text) {
124
136
  if (looksLikeAgentFailureMessage(text)) return false;
125
137
  if (looksLikeInvalidAgentSession(text)) return false;
138
+ if (looksLikeV8Oom(text)) return false;
126
139
  const lower = text.trim().toLowerCase();
127
140
  if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
128
141
  if (!lower) return true;
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(
142
+ return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|cursor runner crashed in node|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
130
143
  lower
131
144
  );
132
145
  }
@@ -178,9 +191,15 @@ function humanizeAgentFailDetail(detail) {
178
191
  if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
179
192
  return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
180
193
  }
181
- if (/homebrew node \+ shared libuv|uv_run|spineventloopinternal/i.test(lower)) {
194
+ if (looksLikeV8Oom(raw) || /javascript heap out of memory/i.test(lower)) {
195
+ return /ran out of memory/i.test(raw) ? raw : V8_OOM_SUMMARY;
196
+ }
197
+ if (/homebrew node \+ shared libuv|Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(raw)) {
182
198
  return /brew install node@22/i.test(raw) ? raw : `${raw} \u2014 install Node 22 LTS (\`brew install node@22\`) and retry.`;
183
199
  }
200
+ if (/uv_run|spineventloopinternal|uv__io_poll|cursor runner crashed in node/i.test(lower)) {
201
+ return /retry the turn/i.test(raw) ? raw : BUNDLED_NODE_CRASH_SUMMARY;
202
+ }
184
203
  if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
185
204
  return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
186
205
  }
@@ -362,6 +381,45 @@ function cursorSdkMessageToEvents(msg) {
362
381
  }
363
382
  return [];
364
383
  }
384
+ function nestedUpdateToEvents(update, parentId) {
385
+ if (update.type === "thinking-delta" && update.text) {
386
+ return [{ type: "thinking", data: update.text, parentId }];
387
+ }
388
+ if (update.type === "text-delta" && update.text) {
389
+ return [{ type: "stdout", data: update.text, parentId }];
390
+ }
391
+ if ((update.type === "tool-call-started" || update.type === "tool-call-completed") && update.callId && update.toolCall) {
392
+ const rawName = typeof update.toolCall.type === "string" ? update.toolCall.type : "tool";
393
+ const normalized = normalizeCursorToolCall(rawName, update.toolCall.args);
394
+ const events = [
395
+ {
396
+ type: "tool_use",
397
+ id: update.callId,
398
+ name: normalized.name,
399
+ input: normalized.input,
400
+ parentId
401
+ }
402
+ ];
403
+ if (update.type === "tool-call-completed") {
404
+ events.push({
405
+ type: "tool_result",
406
+ id: update.callId,
407
+ content: unwrapCursorToolResult(update.toolCall.result),
408
+ isError: cursorToolResultIsError(void 0, update.toolCall.result),
409
+ parentId
410
+ });
411
+ }
412
+ return events;
413
+ }
414
+ return [];
415
+ }
416
+ function cursorDeltaToEvents(update) {
417
+ if (!update?.type) return [];
418
+ if (update.type === "tool-call-delta" && update.callId && update.taskUpdate) {
419
+ return nestedUpdateToEvents(update.taskUpdate, update.callId);
420
+ }
421
+ return [];
422
+ }
365
423
  function parseCursorRunnerLine(line) {
366
424
  const trimmed = line.trim();
367
425
  if (!trimmed) return null;
@@ -384,7 +442,6 @@ function parseCursorRunnerLine(line) {
384
442
  import { existsSync as existsSync3 } from "fs";
385
443
  import { createRequire } from "module";
386
444
  import { dirname, isAbsolute, join as join3, parse, resolve as resolvePath } from "path";
387
- import { fileURLToPath } from "url";
388
445
 
389
446
  // src/agents/node-launch.ts
390
447
  import { existsSync as existsSync2, readdirSync, realpathSync } from "fs";
@@ -646,7 +703,9 @@ function resolveCursorRipgrepPath(opts) {
646
703
  packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
647
704
  );
648
705
  if (fromPackaged) return fromPackaged;
649
- const start = opts?.startFile?.trim() || process.argv[1] || fileURLToPath(import.meta.url);
706
+ const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
707
+ // eslint-disable-next-line camelcase
708
+ (typeof __filename !== "undefined" ? __filename : "");
650
709
  return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
651
710
  }
652
711
  function cursorRipgrepEnv(opts) {
@@ -677,6 +736,7 @@ export {
677
736
  applyNodeLaunch,
678
737
  resolveNodeLaunch,
679
738
  cursorSdkMessageToEvents,
739
+ cursorDeltaToEvents,
680
740
  parseCursorRunnerLine,
681
741
  cursorRipgrepEnv,
682
742
  ensureCursorRipgrepPath
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  ensureGlobalCoordinatorCwd
3
- } from "./chunk-I2OJ2YSP.js";
3
+ } from "./chunk-KQBI5HNT.js";
4
4
  import {
5
5
  allocateTeamName,
6
6
  takenSlugsFromThread,
7
7
  teamSlugFromName
8
- } from "./chunk-EW7COXYE.js";
8
+ } from "./chunk-C4KHDW3U.js";
9
9
  import {
10
10
  resolveNewThreadOptions,
11
11
  resolveThreadDefaults
12
- } from "./chunk-4LKD3PGO.js";
12
+ } from "./chunk-4NR5FL46.js";
13
13
  import {
14
14
  createEmptyThread,
15
15
  listThreads,
16
16
  updateThread,
17
17
  writeThread
18
- } from "./chunk-KGSVLZV6.js";
18
+ } from "./chunk-A4VZXJEJ.js";
19
19
  import {
20
20
  globalAgentCwd
21
21
  } from "./chunk-QZQEXME2.js";
@@ -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,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  isGlobalRepoPath
3
- } from "./chunk-756EO4GK.js";
3
+ } from "./chunk-4EWPKYOU.js";
4
4
  import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveRepoRoot
7
- } from "./chunk-EW7COXYE.js";
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-JVIW55KT.js";
5
+ } from "./chunk-YXDR43ZC.js";
6
6
  import {
7
7
  resolveThreadDefaults
8
- } from "./chunk-NE4TOOKS.js";
8
+ } from "./chunk-SGEVS5SY.js";
9
9
  import {
10
10
  globalAgentCwd,
11
11
  sideboardReposDir