@sideboard-ai/core 0.1.292 → 0.1.293

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 (33) hide show
  1. package/dist/agents/cursor-runner.cjs +329 -36
  2. package/dist/agents/cursor-runner.js +318 -17
  3. package/dist/{agents-4BBCKITL.js → agents-SITR5V6F.js} +3 -3
  4. package/dist/{agents-XAKSP653.js → agents-WT72O5A3.js} +3 -3
  5. package/dist/{chunk-2IXKTAIT.js → chunk-2VGLZIU6.js} +37 -13
  6. package/dist/{chunk-GBAACE3C.js → chunk-4YXXLWDI.js} +3 -3
  7. package/dist/{chunk-4VXWLY3L.js → chunk-IP5WSADC.js} +9 -9
  8. package/dist/{chunk-QOUTSISS.js → chunk-LSHGJI4S.js} +10 -10
  9. package/dist/{chunk-O4324MXE.js → chunk-PO3PDNMV.js} +1 -1
  10. package/dist/{chunk-LUQ7MIVD.js → chunk-RPCKGO3J.js} +3 -3
  11. package/dist/{chunk-5HPMKLJ7.js → chunk-UO5C2L2G.js} +37 -13
  12. package/dist/{chunk-G74TSBJ3.js → chunk-WRDKJRWF.js} +3 -3
  13. package/dist/{chunk-VNCPRMIK.js → chunk-XZW3BXZW.js} +3 -3
  14. package/dist/{chunk-V3BSO2O6.js → chunk-ZRQWV3MS.js} +1 -1
  15. package/dist/{conductor-UFJXJPTF.js → conductor-MAYZSFL6.js} +3 -3
  16. package/dist/{conductor-5MNGC25D.js → conductor-P7XPGYF4.js} +3 -3
  17. package/dist/{coordinator-prompt-5Q66Y5KW.js → coordinator-prompt-NAM5JHLT.js} +2 -2
  18. package/dist/{coordinator-prompt-BYPEW6DE.js → coordinator-prompt-OZFKNCM3.js} +2 -2
  19. package/dist/{global-workspace-BTH2YGDZ.js → global-workspace-CTFQDG7G.js} +2 -2
  20. package/dist/{global-workspace-YKOYXSB2.js → global-workspace-UGR6FQXI.js} +2 -2
  21. package/dist/index.cjs +47 -13
  22. package/dist/index.d.cts +10 -4
  23. package/dist/index.d.ts +10 -4
  24. package/dist/index.js +17 -7
  25. package/dist/mcp/run-stdio.cjs +37 -13
  26. package/dist/mcp/run-stdio.js +5 -5
  27. package/dist/{orchestrator-EQSK2RMI.js → orchestrator-4QVF6CE2.js} +5 -5
  28. package/dist/{orchestrator-GSOW3RPA.js → orchestrator-BOGVTCWI.js} +5 -5
  29. package/dist/{workspaces-ELO2YVTU.js → workspaces-QNKFBA63.js} +2 -2
  30. package/dist/{workspaces-RFD6I4FM.js → workspaces-YNZXVBSF.js} +2 -2
  31. package/dist/{worktree-ADVQ6X6C.js → worktree-EMCWDPZJ.js} +1 -1
  32. package/dist/{worktree-TN7DZDJZ.js → worktree-ERRH4TAG.js} +1 -1
  33. package/package.json +1 -1
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/agents/cursor-runner.ts
27
- var import_node_fs17 = require("fs");
27
+ var import_node_fs18 = require("fs");
28
28
  var import_node_readline2 = require("readline");
29
29
 
30
30
  // src/hook/nested-electron-env.ts
@@ -346,14 +346,288 @@ function ensureCursorRipgrepPath(opts) {
346
346
  return path;
347
347
  }
348
348
 
349
- // src/agents/cursor-store.ts
349
+ // src/agents/cursor-catalog.ts
350
+ var import_node_fs14 = require("fs");
350
351
  var import_node_path15 = require("path");
352
+ var import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
353
+ var CATALOG_FILES = ["agents.ndjson", "runs.ndjson", "run_events.ndjson", "checkpoints.ndjson"];
354
+ var INTERRUPTED_TMP = /^\.(agents|runs|run_events|checkpoints)\.ndjson\.[0-9a-f]{16}\.tmp$/;
355
+ async function acquireCursorCatalogLock(storeDir) {
356
+ (0, import_node_fs14.mkdirSync)(storeDir, { recursive: true });
357
+ const lockPath = (0, import_node_path15.join)(storeDir, ".catalog.lock");
358
+ (0, import_node_fs14.writeFileSync)(lockPath, "", { flag: "a" });
359
+ try {
360
+ return await import_proper_lockfile.default.lock(lockPath, {
361
+ retries: { retries: 40, minTimeout: 50, maxTimeout: 500 },
362
+ stale: 5e3,
363
+ update: 2e3
364
+ });
365
+ } catch {
366
+ return async () => {
367
+ };
368
+ }
369
+ }
370
+ var heldCatalogRelease;
371
+ function publishRepair(repair, note) {
372
+ for (const line of repair.notes) note(line);
373
+ }
374
+ async function openCursorCatalogTurn(storeDir, note) {
375
+ (0, import_node_fs14.mkdirSync)(storeDir, { recursive: true });
376
+ heldCatalogRelease = await acquireCursorCatalogLock(storeDir);
377
+ publishRepair(repairCursorLocalCatalog(storeDir), note);
378
+ }
379
+ function repairCursorCatalogForResume(storeDir, note) {
380
+ const repair = repairCursorLocalCatalog(storeDir);
381
+ publishRepair(repair, note);
382
+ return repair.repaired;
383
+ }
384
+ async function closeCursorCatalogTurn() {
385
+ const release = heldCatalogRelease;
386
+ heldCatalogRelease = void 0;
387
+ if (release) await release().catch(() => void 0);
388
+ }
389
+ function repairCursorLocalCatalog(storeDir) {
390
+ if (!(0, import_node_fs14.existsSync)(storeDir)) return { repaired: false, notes: [] };
391
+ const notes = [];
392
+ let repaired = false;
393
+ const loaded = /* @__PURE__ */ new Map();
394
+ for (const file of CATALOG_FILES) {
395
+ loaded.set(file, loadCatalogFile(storeDir, file));
396
+ }
397
+ const checkpoints = mergeByKey(
398
+ loaded.get("checkpoints.ndjson").main,
399
+ loaded.get("checkpoints.ndjson").tmpRows,
400
+ (row) => checkpointKey(row),
401
+ (main2) => main2
402
+ );
403
+ const blobs = checkpointBlobs(checkpoints.rows);
404
+ const agents = mergeByKey(
405
+ loaded.get("agents.ndjson").main,
406
+ loaded.get("agents.ndjson").tmpRows,
407
+ (row) => typeof row.agentId === "string" ? row.agentId : null,
408
+ (main2, extra) => preferAgent(main2, extra, blobs)
409
+ );
410
+ const runs = mergeByKey(
411
+ loaded.get("runs.ndjson").main,
412
+ loaded.get("runs.ndjson").tmpRows,
413
+ (row) => runKey(row),
414
+ (main2, extra) => num(extra.updatedAt) >= num(main2.updatedAt) ? extra : main2
415
+ );
416
+ const events = mergeByKey(
417
+ loaded.get("run_events.ndjson").main,
418
+ loaded.get("run_events.ndjson").tmpRows,
419
+ (row) => eventKey(row),
420
+ (main2) => main2
421
+ );
422
+ const merged = {
423
+ "checkpoints.ndjson": checkpoints.rows,
424
+ "agents.ndjson": agents.rows,
425
+ "runs.ndjson": runs.rows,
426
+ "run_events.ndjson": events.rows
427
+ };
428
+ for (const agent of merged["agents.ndjson"]) {
429
+ if (restoreAgentCheckpoint(agent, merged["runs.ndjson"], blobs, notes)) repaired = true;
430
+ if (clearMissingActiveRun(agent, merged["runs.ndjson"], notes)) repaired = true;
431
+ }
432
+ for (const file of CATALOG_FILES) {
433
+ const prior = loaded.get(file);
434
+ const next = merged[file];
435
+ const recovered = countNewKeys(prior.main, next, keyFor(file));
436
+ if (recovered > 0) {
437
+ notes.push(`Cursor catalog recovered ${recovered} ${file} row(s) from an interrupted write`);
438
+ repaired = true;
439
+ }
440
+ if (!sameRows(prior.main, next)) {
441
+ writeCatalogFile((0, import_node_path15.join)(storeDir, file), next);
442
+ repaired = true;
443
+ }
444
+ for (const tmp of prior.tmps) {
445
+ try {
446
+ (0, import_node_fs14.unlinkSync)(tmp);
447
+ } catch {
448
+ }
449
+ }
450
+ }
451
+ return { repaired, notes };
452
+ }
453
+ function loadCatalogFile(storeDir, file) {
454
+ const tmps = interruptedTmps(storeDir, file);
455
+ return {
456
+ main: readRows((0, import_node_path15.join)(storeDir, file)),
457
+ tmps,
458
+ tmpRows: tmps.flatMap((tmp) => readRows(tmp))
459
+ };
460
+ }
461
+ function keyFor(file) {
462
+ if (file === "checkpoints.ndjson") return checkpointKey;
463
+ if (file === "agents.ndjson") return (row) => typeof row.agentId === "string" ? row.agentId : null;
464
+ if (file === "runs.ndjson") return runKey;
465
+ return eventKey;
466
+ }
467
+ function countNewKeys(main2, next, keyOf) {
468
+ const had = new Set(main2.map(keyOf).filter((key) => Boolean(key)));
469
+ let n = 0;
470
+ for (const row of next) {
471
+ const key = keyOf(row);
472
+ if (key && !had.has(key)) n += 1;
473
+ }
474
+ return n;
475
+ }
476
+ function interruptedTmps(storeDir, file) {
477
+ let names = [];
478
+ try {
479
+ names = (0, import_node_fs14.readdirSync)(storeDir);
480
+ } catch {
481
+ return [];
482
+ }
483
+ const prefix = `.${file}.`;
484
+ return names.filter((name) => name.startsWith(prefix) && INTERRUPTED_TMP.test(name)).map((name) => (0, import_node_path15.join)(storeDir, name));
485
+ }
486
+ function readRows(file) {
487
+ if (!(0, import_node_fs14.existsSync)(file)) return [];
488
+ let raw = "";
489
+ try {
490
+ raw = (0, import_node_fs14.readFileSync)(file, "utf8");
491
+ } catch {
492
+ return [];
493
+ }
494
+ const rows = [];
495
+ for (const line of raw.split("\n")) {
496
+ const trimmed = line.trim();
497
+ if (!trimmed) continue;
498
+ try {
499
+ const parsed = JSON.parse(trimmed);
500
+ if (isRow(parsed)) rows.push(parsed);
501
+ } catch {
502
+ }
503
+ }
504
+ return rows;
505
+ }
506
+ function writeCatalogFile(file, rows) {
507
+ if (rows.length === 0 && !(0, import_node_fs14.existsSync)(file)) return;
508
+ const body = rows.map((row) => JSON.stringify(row)).join("\n");
509
+ const dir = (0, import_node_path15.dirname)(file);
510
+ (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
511
+ const tmp = (0, import_node_path15.join)(dir, `.${(0, import_node_path15.basename)(file)}.repair.tmp`);
512
+ (0, import_node_fs14.writeFileSync)(tmp, body);
513
+ (0, import_node_fs14.renameSync)(tmp, file);
514
+ }
515
+ function mergeByKey(main2, extra, keyOf, prefer) {
516
+ const out = [];
517
+ const index = /* @__PURE__ */ new Map();
518
+ for (const row of main2) {
519
+ const key = keyOf(row);
520
+ if (!key || index.has(key)) continue;
521
+ index.set(key, out.length);
522
+ out.push(structuredClone(row));
523
+ }
524
+ for (const row of extra) {
525
+ const key = keyOf(row);
526
+ if (!key) continue;
527
+ const at = index.get(key);
528
+ if (at == null) {
529
+ index.set(key, out.length);
530
+ out.push(structuredClone(row));
531
+ continue;
532
+ }
533
+ out[at] = structuredClone(prefer(out[at], row));
534
+ }
535
+ return { rows: out };
536
+ }
537
+ function restoreAgentCheckpoint(agent, runs, blobs, notes) {
538
+ const agentId = typeof agent.agentId === "string" ? agent.agentId : "";
539
+ const current = rootBlobId(agent.latestCheckpoint);
540
+ if (!agentId || !current || blobs.has(`${agentId}\0${current}`)) return false;
541
+ const fallback = fallbackCheckpoint(runs, agentId, blobs);
542
+ const fallbackId = rootBlobId(fallback);
543
+ if (!fallback || !fallbackId) return false;
544
+ agent.latestCheckpoint = fallback;
545
+ agent.updatedAt = Date.now();
546
+ notes.push(
547
+ `Cursor catalog restored agent ${agentId} to checkpoint ${fallbackId} (root blob ${current} was missing)`
548
+ );
549
+ return true;
550
+ }
551
+ function clearMissingActiveRun(agent, runs, notes) {
552
+ const agentId = typeof agent.agentId === "string" ? agent.agentId : "";
553
+ const active = typeof agent.activeRunId === "string" ? agent.activeRunId : "";
554
+ if (!agentId || !active) return false;
555
+ const live = runs.some((run2) => run2.agentId === agentId && run2.runId === active);
556
+ if (live) return false;
557
+ agent.activeRunId = null;
558
+ if (agent.status === "running") agent.status = "idle";
559
+ notes.push(`Cursor catalog cleared missing run ${active} on agent ${agentId}`);
560
+ return true;
561
+ }
562
+ function fallbackCheckpoint(runs, agentId, blobs) {
563
+ const mine = runs.filter((run2) => run2.agentId === agentId).slice().sort((a, b) => num(b.updatedAt) - num(a.updatedAt));
564
+ for (const run2 of mine) {
565
+ for (const field of ["latestCheckpointRef", "startCheckpointRef"]) {
566
+ const ref = run2[field];
567
+ const id = rootBlobId(ref);
568
+ if (id && blobs.has(`${agentId}\0${id}`) && isRow(ref)) return ref;
569
+ }
570
+ }
571
+ return null;
572
+ }
573
+ function preferAgent(main2, extra, blobs) {
574
+ const mainOk = checkpointPresent(main2, blobs);
575
+ const extraOk = checkpointPresent(extra, blobs);
576
+ if (mainOk && !extraOk) return main2;
577
+ if (extraOk && !mainOk) return extra;
578
+ return num(extra.updatedAt) >= num(main2.updatedAt) ? extra : main2;
579
+ }
580
+ function checkpointPresent(agent, blobs) {
581
+ const agentId = typeof agent.agentId === "string" ? agent.agentId : "";
582
+ const id = rootBlobId(agent.latestCheckpoint);
583
+ if (!id) return true;
584
+ return blobs.has(`${agentId}\0${id}`);
585
+ }
586
+ function checkpointBlobs(rows) {
587
+ const ids = /* @__PURE__ */ new Set();
588
+ for (const row of rows) {
589
+ if (typeof row.agentId !== "string" || typeof row.blobId !== "string") continue;
590
+ if (typeof row.dataBase64 !== "string" || !row.dataBase64) continue;
591
+ ids.add(`${row.agentId}\0${row.blobId}`);
592
+ }
593
+ return ids;
594
+ }
595
+ function checkpointKey(row) {
596
+ if (typeof row.agentId !== "string" || typeof row.blobId !== "string") return null;
597
+ return `${row.agentId}\0${row.blobId}`;
598
+ }
599
+ function runKey(row) {
600
+ if (typeof row.agentId !== "string" || typeof row.runId !== "string") return null;
601
+ return `${row.agentId}\0${row.runId}`;
602
+ }
603
+ function eventKey(row) {
604
+ if (typeof row.runId !== "string") return null;
605
+ if (typeof row.seq === "number") return `${row.runId}\0${row.seq}`;
606
+ if (typeof row.offset === "string") return `${row.runId}\0${row.offset}`;
607
+ return null;
608
+ }
609
+ function rootBlobId(ref) {
610
+ if (!isRow(ref) || typeof ref.rootBlobId !== "string" || !ref.rootBlobId) return null;
611
+ return ref.rootBlobId;
612
+ }
613
+ function num(value) {
614
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
615
+ }
616
+ function sameRows(a, b) {
617
+ return JSON.stringify(a) === JSON.stringify(b);
618
+ }
619
+ function isRow(value) {
620
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
621
+ }
622
+
623
+ // src/agents/cursor-store.ts
624
+ var import_node_path16 = require("path");
351
625
  var CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
352
626
  function cursorSdkStoreDir(threadId) {
353
- const root = (0, import_node_path15.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
627
+ const root = (0, import_node_path16.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
354
628
  const id = sanitizeCursorStoreSegment(threadId);
355
629
  if (!id) return root;
356
- return (0, import_node_path15.join)(root, "threads", id);
630
+ return (0, import_node_path16.join)(root, "threads", id);
357
631
  }
358
632
  function sanitizeCursorStoreSegment(threadId) {
359
633
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
@@ -590,8 +864,8 @@ async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
590
864
  }
591
865
 
592
866
  // src/agents/sliced-file-read.ts
593
- var import_node_fs14 = require("fs");
594
- var import_node_path16 = require("path");
867
+ var import_node_fs15 = require("fs");
868
+ var import_node_path17 = require("path");
595
869
  var SLICED_READ_DEFAULT_LIMIT = 200;
596
870
  var SLICED_READ_MAX_LINE_CHARS = 2e3;
597
871
  var SLICED_READ_DESCRIPTION = "Read a text file. Defaults to 200 lines (and a small char budget). Pass offset (1-based) + limit to continue \u2014 never request the whole file when it is large.";
@@ -615,18 +889,18 @@ var SLICED_READ_INPUT_SCHEMA = {
615
889
  };
616
890
  function realpathOrSelf(path) {
617
891
  try {
618
- return (0, import_node_fs14.realpathSync)(path);
892
+ return (0, import_node_fs15.realpathSync)(path);
619
893
  } catch {
620
- return (0, import_node_path16.resolve)(path);
894
+ return (0, import_node_path17.resolve)(path);
621
895
  }
622
896
  }
623
897
  function isOutsideWorktree(root, abs) {
624
- const rel = (0, import_node_path16.relative)(root, abs);
625
- return rel === ".." || rel.startsWith(`..${import_node_path16.sep}`) || (0, import_node_path16.isAbsolute)(rel);
898
+ const rel = (0, import_node_path17.relative)(root, abs);
899
+ return rel === ".." || rel.startsWith(`..${import_node_path17.sep}`) || (0, import_node_path17.isAbsolute)(rel);
626
900
  }
627
901
  function resolveWithinCwd(cwd, input) {
628
902
  const root = realpathOrSelf(cwd);
629
- const abs = (0, import_node_path16.isAbsolute)(input) ? (0, import_node_path16.resolve)(input) : (0, import_node_path16.resolve)(root, input);
903
+ const abs = (0, import_node_path17.isAbsolute)(input) ? (0, import_node_path17.resolve)(input) : (0, import_node_path17.resolve)(root, input);
630
904
  if (isOutsideWorktree(root, abs)) {
631
905
  throw new Error(`Path is outside the worktree: ${input}`);
632
906
  }
@@ -663,9 +937,9 @@ function executeSlicedFileRead(cwd, args) {
663
937
  }
664
938
  let buf;
665
939
  try {
666
- const st = (0, import_node_fs14.statSync)(abs);
940
+ const st = (0, import_node_fs15.statSync)(abs);
667
941
  if (!st.isFile()) return `Error: not a file: ${rawPath}`;
668
- buf = (0, import_node_fs14.readFileSync)(abs);
942
+ buf = (0, import_node_fs15.readFileSync)(abs);
669
943
  } catch (err) {
670
944
  return `Error: ${err instanceof Error ? err.message : String(err)}`;
671
945
  }
@@ -745,14 +1019,14 @@ function parseRpcFrame(raw) {
745
1019
  }
746
1020
 
747
1021
  // src/agent-rpc/metadata.ts
748
- var import_node_fs15 = require("fs");
749
- var import_node_path17 = require("path");
1022
+ var import_node_fs16 = require("fs");
1023
+ var import_node_path18 = require("path");
750
1024
  function agentRuntimeMetadataPath() {
751
- return (0, import_node_path17.join)(appDataDir(), "agent-runtime.json");
1025
+ return (0, import_node_path18.join)(appDataDir(), "agent-runtime.json");
752
1026
  }
753
1027
  function readAgentRuntimeMetadata() {
754
1028
  try {
755
- const raw = JSON.parse((0, import_node_fs15.readFileSync)(agentRuntimeMetadataPath(), "utf8"));
1029
+ const raw = JSON.parse((0, import_node_fs16.readFileSync)(agentRuntimeMetadataPath(), "utf8"));
756
1030
  if (!raw || typeof raw !== "object") return null;
757
1031
  const rec = raw;
758
1032
  if (typeof rec.runtimeId !== "string" || !rec.runtimeId.trim()) return null;
@@ -1078,8 +1352,8 @@ function sideboardCursorRpcTools(opts) {
1078
1352
  }
1079
1353
 
1080
1354
  // src/agents/tool-result-clip.ts
1081
- var import_node_fs16 = require("fs");
1082
- var import_node_path18 = require("path");
1355
+ var import_node_fs17 = require("fs");
1356
+ var import_node_path19 = require("path");
1083
1357
 
1084
1358
  // src/paths/workspace-scratch.ts
1085
1359
  var CLI_DIR = ".context/cli";
@@ -1088,15 +1362,15 @@ var CLI_DIR = ".context/cli";
1088
1362
  function spillPath(cwd, prefix) {
1089
1363
  const stamp = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
1090
1364
  const safe = prefix.replace(/[^a-zA-Z0-9_-]+/g, "-").slice(0, 40) || "tool";
1091
- return (0, import_node_path18.join)(cwd, CLI_DIR, `${safe}-${stamp}.txt`);
1365
+ return (0, import_node_path19.join)(cwd, CLI_DIR, `${safe}-${stamp}.txt`);
1092
1366
  }
1093
1367
  function spillToolResultToCli(content, opts) {
1094
1368
  const cwd = opts?.cwd?.trim();
1095
1369
  if (!cwd || !content) return null;
1096
1370
  const file = spillPath(cwd, opts?.prefix ?? "tool-result");
1097
1371
  try {
1098
- (0, import_node_fs16.mkdirSync)((0, import_node_path18.join)(cwd, CLI_DIR), { recursive: true });
1099
- (0, import_node_fs16.writeFileSync)(file, content, "utf8");
1372
+ (0, import_node_fs17.mkdirSync)((0, import_node_path19.join)(cwd, CLI_DIR), { recursive: true });
1373
+ (0, import_node_fs17.writeFileSync)(file, content, "utf8");
1100
1374
  return file;
1101
1375
  } catch {
1102
1376
  return null;
@@ -1507,7 +1781,7 @@ function emit(event) {
1507
1781
  }
1508
1782
  function localAgentStore(Store, threadId) {
1509
1783
  const root = cursorSdkStoreDir(threadId);
1510
- (0, import_node_fs17.mkdirSync)(root, { recursive: true });
1784
+ (0, import_node_fs18.mkdirSync)(root, { recursive: true });
1511
1785
  return new Store(root);
1512
1786
  }
1513
1787
  async function cancelStaleRuns(Agent, agentId, opts) {
@@ -1597,6 +1871,9 @@ async function main() {
1597
1871
  fast: Boolean(req.fast)
1598
1872
  });
1599
1873
  const mode = req.planMode ? "plan" : "agent";
1874
+ const storeRoot = cursorSdkStoreDir(req.threadId);
1875
+ const note = (line) => emit({ type: "stderr", data: line });
1876
+ await openCursorCatalogTurn(storeRoot, note);
1600
1877
  const store = localAgentStore(JsonlLocalAgentStore, req.threadId);
1601
1878
  const isolateSources = [];
1602
1879
  let onRpcProgress = () => {
@@ -1645,20 +1922,22 @@ async function main() {
1645
1922
  async function createAgent() {
1646
1923
  return retryTransport(() => Agent.create(createOpts));
1647
1924
  }
1925
+ function resumeAgent(agentId) {
1926
+ const { name: _name, ...opts } = createOpts;
1927
+ return retryTransport(() => Agent.resume(agentId, opts));
1928
+ }
1648
1929
  async function openAgent() {
1649
1930
  try {
1650
- return req.agentId ? await retryTransport(
1651
- () => Agent.resume(req.agentId, {
1652
- apiKey,
1653
- model,
1654
- mode,
1655
- local,
1656
- disallowedTools: ["read"],
1657
- ...mcpServers ? { mcpServers } : {}
1658
- })
1659
- ) : await createAgent();
1931
+ return req.agentId ? await resumeAgent(req.agentId) : await createAgent();
1660
1932
  } catch (err) {
1661
1933
  if (!isUnresumableCursorSession(err)) throw err;
1934
+ if (repairCursorCatalogForResume(storeRoot, note) && req.agentId) {
1935
+ try {
1936
+ return await resumeAgent(req.agentId);
1937
+ } catch (err2) {
1938
+ if (!isUnresumableCursorSession(err2)) throw err2;
1939
+ }
1940
+ }
1662
1941
  emit({
1663
1942
  type: "stderr",
1664
1943
  data: cursorSessionRecoveryMessage(err, req.agentId)
@@ -1712,7 +1991,9 @@ async function main() {
1712
1991
  new Promise((resolve2) => {
1713
1992
  setTimeout(resolve2, 2e3);
1714
1993
  })
1715
- ]).finally(() => process.exit(1));
1994
+ ]).finally(() => {
1995
+ void closeCursorCatalogTurn().finally(() => process.exit(1));
1996
+ });
1716
1997
  };
1717
1998
  process.once("SIGTERM", onSignal);
1718
1999
  process.once("SIGINT", onSignal);
@@ -1810,11 +2091,21 @@ async function main() {
1810
2091
  return await runTurn(agent);
1811
2092
  }
1812
2093
  if (!isUnresumableCursorSession(err)) throw err;
2094
+ const agentId = agent.agentId;
2095
+ await agent[Symbol.asyncDispose]().catch(() => void 0);
2096
+ const repaired = repairCursorCatalogForResume(storeRoot, note);
2097
+ if (repaired) {
2098
+ try {
2099
+ agent = await resumeAgent(agentId);
2100
+ return await runTurn(agent);
2101
+ } catch (err2) {
2102
+ if (!isUnresumableCursorSession(err2)) throw err2;
2103
+ }
2104
+ }
1813
2105
  emit({
1814
2106
  type: "stderr",
1815
- data: cursorSessionRecoveryMessage(err, agent.agentId)
2107
+ data: cursorSessionRecoveryMessage(err, agentId)
1816
2108
  });
1817
- await agent[Symbol.asyncDispose]().catch(() => void 0);
1818
2109
  agent = await createAgent();
1819
2110
  return await runTurn(agent);
1820
2111
  }
@@ -1832,6 +2123,8 @@ async function main() {
1832
2123
  const message = err instanceof Error ? err.message : String(err);
1833
2124
  emit({ type: "stderr", data: message });
1834
2125
  return 1;
2126
+ } finally {
2127
+ await closeCursorCatalogTurn();
1835
2128
  }
1836
2129
  }
1837
2130
  main().then(