@sideboard-ai/core 0.1.111 → 0.1.116

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 +51 -21
  2. package/dist/agents/cursor-runner.js +3 -3
  3. package/dist/{agents-NN22A4G5.js → agents-7NIX44RB.js} +7 -7
  4. package/dist/{agents-GH3FWDW2.js → agents-DU7DHY7A.js} +10 -10
  5. package/dist/{chunk-JTQQPJAU.js → chunk-4HOFVKPC.js} +52 -38
  6. package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
  7. package/dist/{chunk-NC3U42ZP.js → chunk-5KSLD4MU.js} +317 -33
  8. package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
  9. package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
  10. package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
  11. package/dist/{chunk-DMJKOFTO.js → chunk-DWP25N32.js} +44 -35
  12. package/dist/{chunk-2GO3YKBA.js → chunk-EKIDHL2T.js} +4 -4
  13. package/dist/{chunk-C4KHDW3U.js → chunk-FZCIQYNQ.js} +1 -1
  14. package/dist/{chunk-363Z34PY.js → chunk-GBY7OOMB.js} +273 -218
  15. package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
  16. package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
  17. package/dist/{chunk-KVFNTWFG.js → chunk-OFF5AFCR.js} +300 -43
  18. package/dist/{chunk-VOD3HFLP.js → chunk-XOYQ7LNQ.js} +2 -2
  19. package/dist/{chunk-7YKXHBIW.js → chunk-YMRT2DU6.js} +3 -3
  20. package/dist/{chunk-YXDR43ZC.js → chunk-ZMROW673.js} +5 -5
  21. package/dist/{chunk-YFAXVUY2.js → chunk-ZRCX43LS.js} +2 -2
  22. package/dist/{chunk-AROMOP3C.js → chunk-ZYEFCSZJ.js} +2 -2
  23. package/dist/{connected-teams-M5XNXRI5.js → connected-teams-O6D4PM7A.js} +2 -2
  24. package/dist/{connected-teams-J4I5AKMR.js → connected-teams-ZCOU6KCD.js} +2 -2
  25. package/dist/{coordinator-prompt-AR66L3N4.js → coordinator-prompt-4KCALEKD.js} +3 -3
  26. package/dist/{coordinator-prompt-BHMLWL64.js → coordinator-prompt-FML4I5AR.js} +3 -3
  27. package/dist/{global-workspace-XSUFEIAQ.js → global-workspace-CSWABOG5.js} +4 -4
  28. package/dist/{global-workspace-SKFODUQQ.js → global-workspace-H4YNASM6.js} +4 -4
  29. package/dist/index.cjs +855 -440
  30. package/dist/index.d.cts +59 -1
  31. package/dist/index.d.ts +59 -1
  32. package/dist/index.js +37 -17
  33. package/dist/mcp/run-stdio.cjs +966 -635
  34. package/dist/mcp/run-stdio.js +20 -16
  35. package/dist/{orchestrator-4T2SXDZ7.js → orchestrator-NXPANCZA.js} +8 -8
  36. package/dist/{orchestrator-EP57AB5W.js → orchestrator-ZY4RUJKT.js} +10 -10
  37. package/dist/{run-XKTAJRWF.js → run-USF6FRKV.js} +3 -1
  38. package/dist/{run-CFKZPY7F.js → run-XQKGHQZ2.js} +3 -1
  39. package/dist/{workspaces-XAQVKTLO.js → workspaces-HJ3EVATC.js} +5 -5
  40. package/dist/{workspaces-HV3J4TTW.js → workspaces-QG6PGFQR.js} +5 -5
  41. package/dist/{worktree-XFJED3VU.js → worktree-IW3BX26B.js} +2 -2
  42. package/dist/{worktree-N2EV24EE.js → worktree-OTFQO2W7.js} +2 -2
  43. package/package.json +1 -1
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-4TR3HZFT.js";
5
5
  import {
6
6
  run
7
- } from "./chunk-LGXBYZZA.js";
7
+ } from "./chunk-DVM4ID64.js";
8
8
 
9
9
  // src/agents/error-detail.ts
10
10
  function formatUnknownDetail(err) {
@@ -90,7 +90,7 @@ function looksLikeHomebrewLibuvCrash(text) {
90
90
  var NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
91
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
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.";
93
+ var V8_OOM_SUMMARY = "Agent ran out of memory (JavaScript heap). If it keeps happening, exclude large files from the project folder.";
94
94
  var MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
95
95
  function clipStderr(text, maxChars) {
96
96
  const trimmed = text.trim();
@@ -145,6 +145,7 @@ function looksLikeRetryableRunnerCrash(text) {
145
145
  }
146
146
  function shouldRetryFailedAgentTurn(detail, opts) {
147
147
  if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
148
+ if (looksLikeV8Oom(detail) && opts.hasSession) return true;
148
149
  return looksLikeRetryableRunnerCrash(detail);
149
150
  }
150
151
  function looksLikeAgentFailureMessage(text) {
@@ -230,219 +231,6 @@ function formatTurnExitError(exitCode, stderrSummary) {
230
231
  return `exit ${code}: ${detail}`;
231
232
  }
232
233
 
233
- // src/agents/cursor-events.ts
234
- function usageFromCursor(usage) {
235
- if (!usage) return null;
236
- const inputTokens = Number(usage.inputTokens ?? 0);
237
- const outputTokens = Number(usage.outputTokens ?? 0);
238
- if (!inputTokens && !outputTokens) return null;
239
- return {
240
- inputTokens,
241
- outputTokens,
242
- cacheReadTokens: usage.cacheReadTokens ? Number(usage.cacheReadTokens) : void 0,
243
- cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
244
- };
245
- }
246
- function asRecord(value) {
247
- if (value && typeof value === "object" && !Array.isArray(value)) {
248
- return value;
249
- }
250
- return void 0;
251
- }
252
- function normalizeCursorToolCall(name, args) {
253
- const raw = asRecord(args);
254
- const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
255
- const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord(raw?.args) != null);
256
- if (looksLikeMcp && toolName) {
257
- const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
258
- const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
259
- const nested = asRecord(raw.args);
260
- return {
261
- name: `mcp__${provider}__${toolName}`,
262
- input: nested ?? { toolName }
263
- };
264
- }
265
- return { name, input: raw };
266
- }
267
- function unwrapCursorToolResult(result) {
268
- if (result == null) return void 0;
269
- if (typeof result === "string") return result;
270
- const rec = asRecord(result);
271
- if (!rec) {
272
- try {
273
- return JSON.stringify(result);
274
- } catch {
275
- return String(result);
276
- }
277
- }
278
- const collectTexts = (items) => {
279
- const texts = [];
280
- for (const item of items) {
281
- const row = asRecord(item);
282
- if (!row) continue;
283
- if (typeof row.text === "string") {
284
- texts.push(row.text);
285
- continue;
286
- }
287
- const nested = asRecord(row.text);
288
- if (typeof nested?.text === "string") texts.push(nested.text);
289
- }
290
- return texts;
291
- };
292
- const value = asRecord(rec.value);
293
- if (value && Array.isArray(value.content)) {
294
- const texts = collectTexts(value.content);
295
- if (texts.length) return texts.join("\n");
296
- }
297
- if (Array.isArray(rec.content)) {
298
- const texts = collectTexts(rec.content);
299
- if (texts.length) return texts.join("\n");
300
- }
301
- try {
302
- return JSON.stringify(result);
303
- } catch {
304
- return String(result);
305
- }
306
- }
307
- function cursorToolResultIsError(status, result) {
308
- if (status === "error") return true;
309
- const rec = asRecord(result);
310
- if (!rec) return false;
311
- if (rec.status === "error") return true;
312
- const value = asRecord(rec.value);
313
- return value?.isError === true;
314
- }
315
- function cursorSdkMessageToEvents(msg) {
316
- if (!msg?.type) return [];
317
- if (msg.type === "system" && msg.agent_id) {
318
- return [{ type: "session_id", data: msg.agent_id }];
319
- }
320
- if (msg.type === "thinking" && msg.text) {
321
- return [{ type: "thinking", data: msg.text }];
322
- }
323
- if (msg.type === "assistant" && msg.message?.content?.length) {
324
- const out = [];
325
- for (const block of msg.message.content) {
326
- if (block?.type === "text" && block.text) {
327
- out.push({ type: "stdout", data: block.text });
328
- } else if (block?.type === "tool_use" && block.id && block.name) {
329
- const normalized = normalizeCursorToolCall(block.name, block.input);
330
- out.push({
331
- type: "tool_use",
332
- id: block.id,
333
- name: normalized.name,
334
- input: normalized.input
335
- });
336
- }
337
- }
338
- return out;
339
- }
340
- if (msg.type === "tool_call" && msg.call_id && msg.name) {
341
- const normalized = normalizeCursorToolCall(msg.name, msg.args);
342
- if (msg.status === "running") {
343
- return [
344
- {
345
- type: "tool_use",
346
- id: msg.call_id,
347
- name: normalized.name,
348
- input: normalized.input
349
- }
350
- ];
351
- }
352
- if (msg.status === "completed" || msg.status === "error") {
353
- return [
354
- {
355
- type: "tool_use",
356
- id: msg.call_id,
357
- name: normalized.name,
358
- input: normalized.input
359
- },
360
- {
361
- type: "tool_result",
362
- id: msg.call_id,
363
- content: unwrapCursorToolResult(msg.result),
364
- isError: cursorToolResultIsError(msg.status, msg.result)
365
- }
366
- ];
367
- }
368
- }
369
- if (msg.type === "usage") {
370
- const usage = usageFromCursor(msg.usage);
371
- if (usage) return [{ type: "usage", data: usage, scope: "request" }];
372
- }
373
- if (msg.type === "status" && msg.status === "ERROR") {
374
- const rawMessage = msg.message;
375
- const detail = (typeof rawMessage === "string" ? rawMessage.trim() : "") || extractJsonErrorMessage(msg) || formatUnknownDetail(msg.error) || msg.text || "Cursor run entered ERROR status";
376
- return [{ type: "stderr", data: detail }];
377
- }
378
- if (msg.type === "error") {
379
- const detail = extractJsonErrorMessage(msg) || formatUnknownDetail(msg.error) || msg.text || "Cursor run error";
380
- return [{ type: "stderr", data: detail }];
381
- }
382
- return [];
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
- }
423
- function parseCursorRunnerLine(line) {
424
- const trimmed = line.trim();
425
- if (!trimmed) return null;
426
- try {
427
- const obj = JSON.parse(trimmed);
428
- if (Array.isArray(obj)) return obj;
429
- if (obj && typeof obj === "object" && "events" in obj && Array.isArray(obj.events)) {
430
- return obj.events;
431
- }
432
- if (obj && typeof obj === "object" && "type" in obj) {
433
- return obj;
434
- }
435
- return null;
436
- } catch {
437
- return { type: "stdout", data: line };
438
- }
439
- }
440
-
441
- // src/agents/cursor-ripgrep.ts
442
- import { existsSync as existsSync3 } from "fs";
443
- import { createRequire } from "module";
444
- import { dirname, isAbsolute, join as join3, parse, resolve as resolvePath } from "path";
445
-
446
234
  // src/agents/node-launch.ts
447
235
  import { existsSync as existsSync2, readdirSync, realpathSync } from "fs";
448
236
  import { homedir } from "os";
@@ -492,6 +280,29 @@ function packagedCursorRipgrepCandidate(platformPkg, binName) {
492
280
  }
493
281
 
494
282
  // src/agents/node-launch.ts
283
+ var AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
284
+ var MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
285
+ function withMaxOldSpaceSize(nodeOptions, heapMb) {
286
+ const existing = (nodeOptions ?? "").trim();
287
+ const match = MAX_OLD_SPACE_FLAG.exec(existing);
288
+ if (match) {
289
+ const current = match[2] ? Number(match[2]) : 0;
290
+ if (Number.isFinite(current) && current >= heapMb) return existing;
291
+ return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
292
+ }
293
+ return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
294
+ }
295
+ function applyAgentRunnerHeapEnv(env) {
296
+ env.NODE_OPTIONS = withMaxOldSpaceSize(
297
+ env.NODE_OPTIONS,
298
+ AGENT_RUNNER_MAX_OLD_SPACE_MB
299
+ );
300
+ }
301
+ function envWithAgentHeap(env) {
302
+ const next = { ...env };
303
+ applyAgentRunnerHeapEnv(next);
304
+ return next;
305
+ }
495
306
  function isAsarPath(filePath) {
496
307
  if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
497
308
  return /\.asar([/\\]|$)/.test(filePath);
@@ -628,13 +439,21 @@ async function findSystemNode() {
628
439
  function applyNodeLaunch(launch, args) {
629
440
  const readableArgs = args.map(nodeReadableScriptPath);
630
441
  if (!launch.env.ELECTRON_RUN_AS_NODE) {
631
- return { file: launch.file, args: readableArgs, env: launch.env };
442
+ return {
443
+ file: launch.file,
444
+ args: readableArgs,
445
+ env: envWithAgentHeap(launch.env)
446
+ };
632
447
  }
633
448
  const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
634
449
  if (process.platform === "win32") {
635
- return { file: wrapped.file, args: wrapped.args, env: launch.env };
450
+ return {
451
+ file: wrapped.file,
452
+ args: wrapped.args,
453
+ env: envWithAgentHeap(launch.env)
454
+ };
636
455
  }
637
- const env = { ...launch.env };
456
+ const env = envWithAgentHeap(launch.env);
638
457
  delete env.ELECTRON_RUN_AS_NODE;
639
458
  return { file: wrapped.file, args: wrapped.args, env };
640
459
  }
@@ -656,7 +475,239 @@ async function resolveNodeLaunch(scriptPath) {
656
475
  };
657
476
  }
658
477
 
478
+ // src/agents/cursor-events.ts
479
+ function usageFromCursor(usage) {
480
+ if (!usage) return null;
481
+ const inputTokens = Number(usage.inputTokens ?? 0);
482
+ const outputTokens = Number(usage.outputTokens ?? 0);
483
+ if (!inputTokens && !outputTokens) return null;
484
+ return {
485
+ inputTokens,
486
+ outputTokens,
487
+ cacheReadTokens: usage.cacheReadTokens ? Number(usage.cacheReadTokens) : void 0,
488
+ cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
489
+ };
490
+ }
491
+ function asRecord(value) {
492
+ if (value && typeof value === "object" && !Array.isArray(value)) {
493
+ return value;
494
+ }
495
+ return void 0;
496
+ }
497
+ function normalizeCursorToolCall(name, args) {
498
+ const raw = asRecord(args);
499
+ const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
500
+ const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord(raw?.args) != null);
501
+ if (looksLikeMcp && toolName) {
502
+ const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
503
+ const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
504
+ const nested = asRecord(raw.args);
505
+ return {
506
+ name: `mcp__${provider}__${toolName}`,
507
+ input: nested ?? { toolName }
508
+ };
509
+ }
510
+ return { name, input: raw };
511
+ }
512
+ function unwrapCursorToolResult(result) {
513
+ if (result == null) return void 0;
514
+ if (typeof result === "string") return result;
515
+ const rec = asRecord(result);
516
+ if (!rec) {
517
+ try {
518
+ return JSON.stringify(result);
519
+ } catch {
520
+ return String(result);
521
+ }
522
+ }
523
+ const collectTexts = (items) => {
524
+ const texts = [];
525
+ for (const item of items) {
526
+ const row = asRecord(item);
527
+ if (!row) continue;
528
+ if (typeof row.text === "string") {
529
+ texts.push(row.text);
530
+ continue;
531
+ }
532
+ const nested = asRecord(row.text);
533
+ if (typeof nested?.text === "string") texts.push(nested.text);
534
+ }
535
+ return texts;
536
+ };
537
+ const value = asRecord(rec.value);
538
+ if (value && Array.isArray(value.content)) {
539
+ const texts = collectTexts(value.content);
540
+ if (texts.length) return texts.join("\n");
541
+ }
542
+ if (Array.isArray(rec.content)) {
543
+ const texts = collectTexts(rec.content);
544
+ if (texts.length) return texts.join("\n");
545
+ }
546
+ try {
547
+ return JSON.stringify(result);
548
+ } catch {
549
+ return String(result);
550
+ }
551
+ }
552
+ function cursorToolResultIsError(status, result) {
553
+ if (status === "error") return true;
554
+ const rec = asRecord(result);
555
+ if (!rec) return false;
556
+ if (rec.status === "error") return true;
557
+ const value = asRecord(rec.value);
558
+ return value?.isError === true;
559
+ }
560
+ function cursorSdkMessageToEvents(msg) {
561
+ if (!msg?.type) return [];
562
+ if (msg.type === "system" && msg.agent_id) {
563
+ return [{ type: "session_id", data: msg.agent_id }];
564
+ }
565
+ if (msg.type === "thinking" && msg.text) {
566
+ return [{ type: "thinking", data: msg.text }];
567
+ }
568
+ if (msg.type === "assistant" && msg.message?.content?.length) {
569
+ const out = [];
570
+ for (const block of msg.message.content) {
571
+ if (block?.type === "text" && block.text) {
572
+ out.push({ type: "stdout", data: block.text });
573
+ } else if (block?.type === "tool_use" && block.id && block.name) {
574
+ const normalized = normalizeCursorToolCall(block.name, block.input);
575
+ out.push({
576
+ type: "tool_use",
577
+ id: block.id,
578
+ name: normalized.name,
579
+ input: normalized.input
580
+ });
581
+ }
582
+ }
583
+ return out;
584
+ }
585
+ if (msg.type === "tool_call" && msg.call_id && msg.name) {
586
+ const normalized = normalizeCursorToolCall(msg.name, msg.args);
587
+ if (msg.status === "running") {
588
+ const events = [
589
+ {
590
+ type: "tool_use",
591
+ id: msg.call_id,
592
+ name: normalized.name,
593
+ input: normalized.input
594
+ }
595
+ ];
596
+ const live = unwrapCursorToolResult(msg.result);
597
+ if (live) {
598
+ events.push({
599
+ type: "tool_result",
600
+ id: msg.call_id,
601
+ content: live,
602
+ partial: true
603
+ });
604
+ }
605
+ return events;
606
+ }
607
+ if (msg.status === "completed" || msg.status === "error") {
608
+ return [
609
+ {
610
+ type: "tool_use",
611
+ id: msg.call_id,
612
+ name: normalized.name,
613
+ input: normalized.input
614
+ },
615
+ {
616
+ type: "tool_result",
617
+ id: msg.call_id,
618
+ content: unwrapCursorToolResult(msg.result),
619
+ isError: cursorToolResultIsError(msg.status, msg.result)
620
+ }
621
+ ];
622
+ }
623
+ }
624
+ if (msg.type === "usage") {
625
+ const usage = usageFromCursor(msg.usage);
626
+ if (usage) return [{ type: "usage", data: usage, scope: "request" }];
627
+ }
628
+ if (msg.type === "status" && msg.status === "ERROR") {
629
+ const rawMessage = msg.message;
630
+ const detail = (typeof rawMessage === "string" ? rawMessage.trim() : "") || extractJsonErrorMessage(msg) || formatUnknownDetail(msg.error) || msg.text || "Cursor run entered ERROR status";
631
+ return [{ type: "stderr", data: detail }];
632
+ }
633
+ if (msg.type === "error") {
634
+ const detail = extractJsonErrorMessage(msg) || formatUnknownDetail(msg.error) || msg.text || "Cursor run error";
635
+ return [{ type: "stderr", data: detail }];
636
+ }
637
+ return [];
638
+ }
639
+ function nestedUpdateToEvents(update, parentId) {
640
+ if (update.type === "thinking-delta" && update.text) {
641
+ return [{ type: "thinking", data: update.text, parentId }];
642
+ }
643
+ if (update.type === "text-delta" && update.text) {
644
+ return [{ type: "stdout", data: update.text, parentId }];
645
+ }
646
+ if ((update.type === "tool-call-started" || update.type === "tool-call-completed") && update.callId && update.toolCall) {
647
+ const rawName = typeof update.toolCall.type === "string" ? update.toolCall.type : "tool";
648
+ const normalized = normalizeCursorToolCall(rawName, update.toolCall.args);
649
+ const events = [
650
+ {
651
+ type: "tool_use",
652
+ id: update.callId,
653
+ name: normalized.name,
654
+ input: normalized.input,
655
+ parentId
656
+ }
657
+ ];
658
+ if (update.type === "tool-call-completed") {
659
+ events.push({
660
+ type: "tool_result",
661
+ id: update.callId,
662
+ content: unwrapCursorToolResult(update.toolCall.result),
663
+ isError: cursorToolResultIsError(void 0, update.toolCall.result),
664
+ parentId
665
+ });
666
+ } else {
667
+ const live = unwrapCursorToolResult(update.toolCall.result);
668
+ if (live) {
669
+ events.push({
670
+ type: "tool_result",
671
+ id: update.callId,
672
+ content: live,
673
+ partial: true,
674
+ parentId
675
+ });
676
+ }
677
+ }
678
+ return events;
679
+ }
680
+ return [];
681
+ }
682
+ function cursorDeltaToEvents(update) {
683
+ if (!update?.type) return [];
684
+ if (update.type === "tool-call-delta" && update.callId && update.taskUpdate) {
685
+ return nestedUpdateToEvents(update.taskUpdate, update.callId);
686
+ }
687
+ return [];
688
+ }
689
+ function parseCursorRunnerLine(line) {
690
+ const trimmed = line.trim();
691
+ if (!trimmed) return null;
692
+ try {
693
+ const obj = JSON.parse(trimmed);
694
+ if (Array.isArray(obj)) return obj;
695
+ if (obj && typeof obj === "object" && "events" in obj && Array.isArray(obj.events)) {
696
+ return obj.events;
697
+ }
698
+ if (obj && typeof obj === "object" && "type" in obj) {
699
+ return obj;
700
+ }
701
+ return null;
702
+ } catch {
703
+ return { type: "stdout", data: line };
704
+ }
705
+ }
706
+
659
707
  // src/agents/cursor-ripgrep.ts
708
+ import { existsSync as existsSync3 } from "fs";
709
+ import { createRequire } from "module";
710
+ import { dirname, isAbsolute, join as join3, parse, resolve as resolvePath } from "path";
660
711
  var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
661
712
  function rgBinaryName() {
662
713
  return process.platform === "win32" ? "rg.exe" : "rg";
@@ -723,6 +774,7 @@ export {
723
774
  formatUnknownDetail,
724
775
  extractJsonErrorMessage,
725
776
  pushTurnStderr,
777
+ looksLikeV8Oom,
726
778
  summarizeTurnStderr,
727
779
  looksLikeInvalidAgentSession,
728
780
  shouldRetryFailedAgentTurn,
@@ -732,6 +784,9 @@ export {
732
784
  formatTurnExitError,
733
785
  packagedCursorRunnerPath,
734
786
  packagedMcpStdioPath,
787
+ AGENT_RUNNER_MAX_OLD_SPACE_MB,
788
+ withMaxOldSpaceSize,
789
+ applyAgentRunnerHeapEnv,
735
790
  isAsarPath,
736
791
  applyNodeLaunch,
737
792
  resolveNodeLaunch,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  isGlobalRepoPath
3
- } from "./chunk-4EWPKYOU.js";
3
+ } from "./chunk-4OJMZ6P2.js";
4
4
  import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveRepoRoot
7
- } from "./chunk-C4KHDW3U.js";
7
+ } from "./chunk-FZCIQYNQ.js";
8
8
  import {
9
9
  appDataDir
10
10
  } from "./chunk-QZQEXME2.js";
@@ -99,6 +99,34 @@ function withExportedPath(command, pathValue) {
99
99
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
100
100
  }
101
101
 
102
+ // src/git/stale-lock.ts
103
+ import { existsSync as existsSync2, statSync, unlinkSync } from "fs";
104
+ import { join as join2 } from "path";
105
+ var STALE_INDEX_LOCK_MS = 2e4;
106
+ function isIndexLockError(text) {
107
+ return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text);
108
+ }
109
+ function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
110
+ const lockPath = join2(gitDir, "index.lock");
111
+ try {
112
+ if (!existsSync2(lockPath)) return null;
113
+ if (now - statSync(lockPath).mtimeMs < maxAgeMs) return null;
114
+ unlinkSync(lockPath);
115
+ return lockPath;
116
+ } catch {
117
+ return null;
118
+ }
119
+ }
120
+ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
121
+ const now = Date.now();
122
+ const removed = [];
123
+ for (const dir of new Set(gitDirs)) {
124
+ const cleared = clearStaleIndexLock(dir, maxAgeMs, now);
125
+ if (cleared) removed.push(cleared);
126
+ }
127
+ return removed;
128
+ }
129
+
102
130
  // src/git/run.ts
103
131
  async function run(file, args, opts) {
104
132
  ensureAgentPath();
@@ -126,6 +154,21 @@ async function run(file, args, opts) {
126
154
  throw err;
127
155
  }
128
156
  }
157
+ async function resolveGitDirsForLockRecovery(cwd, env = {}) {
158
+ const dirs = /* @__PURE__ */ new Set();
159
+ const [gitDir, commonDir] = await Promise.all([
160
+ run("git", ["rev-parse", "--absolute-git-dir"], { cwd, reject: false, env, timeoutMs: 5e3 }),
161
+ run("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
162
+ cwd,
163
+ reject: false,
164
+ env,
165
+ timeoutMs: 5e3
166
+ })
167
+ ]);
168
+ if (gitDir.exitCode === 0 && gitDir.stdout.trim()) dirs.add(gitDir.stdout.trim());
169
+ if (commonDir.exitCode === 0 && commonDir.stdout.trim()) dirs.add(commonDir.stdout.trim());
170
+ return [...dirs];
171
+ }
129
172
  async function git(args, cwd, opts) {
130
173
  const prefix = [];
131
174
  if (opts?.config) {
@@ -134,21 +177,32 @@ async function git(args, cwd, opts) {
134
177
  prefix.push("-c", `${key}=${value}`);
135
178
  }
136
179
  }
137
- return run("git", ["--no-pager", ...prefix, ...args], {
138
- cwd,
139
- reject: opts?.reject,
140
- timeoutMs: opts?.timeoutMs,
180
+ const gitArgs = ["--no-pager", ...prefix, ...args];
181
+ const env = {
141
182
  // Never block forever on a credential/SSH prompt inside MCP / Electron.
142
- env: {
143
- GIT_TERMINAL_PROMPT: "0",
144
- GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
145
- SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
146
- GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
147
- GCM_INTERACTIVE: "never",
148
- GH_PROMPT_DISABLED: "1",
149
- ...opts?.env
183
+ GIT_TERMINAL_PROMPT: "0",
184
+ GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
185
+ SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
186
+ GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
187
+ GCM_INTERACTIVE: "never",
188
+ GH_PROMPT_DISABLED: "1",
189
+ ...opts?.env
190
+ };
191
+ let result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
192
+ if (result.exitCode !== 0 && isIndexLockError(result.stderr)) {
193
+ const gitDirs = await resolveGitDirsForLockRecovery(cwd, env);
194
+ const cleared = clearStaleIndexLocks(gitDirs);
195
+ if (cleared.length > 0) {
196
+ result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
150
197
  }
151
- });
198
+ }
199
+ if ((opts?.reject ?? true) && result.exitCode !== 0) {
200
+ throw new Error(
201
+ `Command failed with exit code ${result.exitCode}: git ${gitArgs.join(" ")}
202
+ ${result.stderr}`
203
+ );
204
+ }
205
+ return result;
152
206
  }
153
207
  async function gh(args, cwd, opts) {
154
208
  return run("gh", args, {
@@ -176,7 +230,9 @@ export {
176
230
  posixShellSingleQuote,
177
231
  resolveCommandBinarySync,
178
232
  withExportedPath,
233
+ clearStaleIndexLocks,
179
234
  run,
235
+ resolveGitDirsForLockRecovery,
180
236
  git,
181
237
  gh,
182
238
  resolveGhAuthToken