@sideboard-ai/core 0.1.116 → 0.1.120

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 (42) hide show
  1. package/dist/agents/cursor-runner.cjs +74 -59
  2. package/dist/agents/cursor-runner.js +10 -9
  3. package/dist/{agents-7NIX44RB.js → agents-HOIXQEP5.js} +6 -6
  4. package/dist/{agents-DU7DHY7A.js → agents-XTABRYO5.js} +5 -5
  5. package/dist/{chunk-4HOFVKPC.js → chunk-4LRPW6QM.js} +43 -19
  6. package/dist/{chunk-XOYQ7LNQ.js → chunk-4NAW5BAQ.js} +3 -3
  7. package/dist/{chunk-4OJMZ6P2.js → chunk-4WV7C7WP.js} +3 -3
  8. package/dist/{chunk-DWP25N32.js → chunk-AFM6442E.js} +44 -20
  9. package/dist/{chunk-ZRCX43LS.js → chunk-BKVDZV7X.js} +2 -2
  10. package/dist/{chunk-A4VZXJEJ.js → chunk-HPAWHIZ3.js} +4 -1
  11. package/dist/{chunk-GBY7OOMB.js → chunk-NZBDVBCP.js} +1 -1
  12. package/dist/{chunk-5KSLD4MU.js → chunk-QI7VC4EG.js} +92 -62
  13. package/dist/{chunk-KYOTBZ6S.js → chunk-RG737OWT.js} +4 -1
  14. package/dist/{chunk-OFF5AFCR.js → chunk-TDNM7QZJ.js} +92 -62
  15. package/dist/{chunk-K3TIQXOH.js → chunk-U3IVCVLH.js} +2 -2
  16. package/dist/{chunk-FZCIQYNQ.js → chunk-VGPLXQIH.js} +1 -1
  17. package/dist/chunk-VHX673DI.js +32 -0
  18. package/dist/{chunk-ZMROW673.js → chunk-WCU3FHEI.js} +1 -1
  19. package/dist/{chunk-7WC5UWEB.js → chunk-X3NIPGQT.js} +1 -1
  20. package/dist/{chunk-ZYEFCSZJ.js → chunk-XTZQL7OU.js} +1 -1
  21. package/dist/{coordinator-prompt-4KCALEKD.js → coordinator-prompt-QMV6YEP5.js} +3 -3
  22. package/dist/{coordinator-prompt-FML4I5AR.js → coordinator-prompt-XCBHAOGE.js} +3 -3
  23. package/dist/cursor-recover-NOQYOFRF.js +76 -0
  24. package/dist/{cursor-recover-JBTIDARH.js → cursor-recover-QSLWEZNA.js} +12 -7
  25. package/dist/{global-workspace-CSWABOG5.js → global-workspace-SBKXKQFS.js} +4 -4
  26. package/dist/{global-workspace-H4YNASM6.js → global-workspace-Z37MNYU6.js} +4 -4
  27. package/dist/index.cjs +388 -285
  28. package/dist/index.d.cts +13 -2
  29. package/dist/index.d.ts +13 -2
  30. package/dist/index.js +10 -8
  31. package/dist/mcp/run-stdio.cjs +383 -282
  32. package/dist/mcp/run-stdio.js +7 -7
  33. package/dist/{orchestrator-NXPANCZA.js → orchestrator-3LJIG6XG.js} +7 -7
  34. package/dist/{orchestrator-ZY4RUJKT.js → orchestrator-NWNKWZLB.js} +8 -8
  35. package/dist/{thread-store-OEALWU7Y.js → thread-store-JR235AWK.js} +3 -1
  36. package/dist/{thread-store-LPTBVW5C.js → thread-store-PMH3BMB6.js} +3 -1
  37. package/dist/{workspaces-HJ3EVATC.js → workspaces-C3TJJFY3.js} +5 -5
  38. package/dist/{workspaces-QG6PGFQR.js → workspaces-M4OICPWF.js} +5 -5
  39. package/dist/{worktree-IW3BX26B.js → worktree-7AEKZSEX.js} +2 -2
  40. package/dist/{worktree-OTFQO2W7.js → worktree-MRSTQ32S.js} +2 -2
  41. package/package.json +1 -1
  42. package/dist/cursor-recover-ZUJG6XRQ.js +0 -42
@@ -17,13 +17,13 @@ import {
17
17
  resolveQuotaFallbackAgent,
18
18
  stripBrightsyNdjsonNoise,
19
19
  toolDescription
20
- } from "./chunk-5KSLD4MU.js";
20
+ } from "./chunk-QI7VC4EG.js";
21
21
  import {
22
22
  addWorkspace,
23
23
  ensureWorkspace,
24
24
  removeWorkspace,
25
25
  syncWorkspacesFromThreads
26
- } from "./chunk-K3TIQXOH.js";
26
+ } from "./chunk-U3IVCVLH.js";
27
27
  import {
28
28
  assertOrchestratorCapableAgent,
29
29
  coerceOrchestratorAgent,
@@ -36,14 +36,14 @@ import {
36
36
  isOrchestratorThread,
37
37
  isSlackCoordinatorThread,
38
38
  orchestratorSessionPoisonedByBuiltins
39
- } from "./chunk-4OJMZ6P2.js";
39
+ } from "./chunk-4WV7C7WP.js";
40
40
  import {
41
41
  SLACK_REPLY_FORMATTING,
42
42
  coordinatorSystemPrompt,
43
43
  coordinatorTurnReminder,
44
44
  enrichWorkspacesWithGithub,
45
45
  ensureGlobalCoordinatorCwd
46
- } from "./chunk-7WC5UWEB.js";
46
+ } from "./chunk-X3NIPGQT.js";
47
47
  import {
48
48
  extractPresentedPlan,
49
49
  readPlanFile,
@@ -63,7 +63,7 @@ import {
63
63
  shouldRetryFailedAgentTurn,
64
64
  summarizeTurnStderr,
65
65
  turnFailChatText
66
- } from "./chunk-GBY7OOMB.js";
66
+ } from "./chunk-NZBDVBCP.js";
67
67
  import {
68
68
  releaseCaffeinateHoldForThread
69
69
  } from "./chunk-DCOZABNT.js";
@@ -109,7 +109,7 @@ import {
109
109
  threadDisplayLabel,
110
110
  withRepoGitLock,
111
111
  worktreeNameFromPath
112
- } from "./chunk-FZCIQYNQ.js";
112
+ } from "./chunk-VGPLXQIH.js";
113
113
  import {
114
114
  ATTACHMENTS_DIR,
115
115
  LEGACY_ATTACHMENTS_DIR,
@@ -145,7 +145,7 @@ import {
145
145
  updateThread,
146
146
  withThreadLock,
147
147
  writeThread
148
- } from "./chunk-A4VZXJEJ.js";
148
+ } from "./chunk-HPAWHIZ3.js";
149
149
  import {
150
150
  appDataDir,
151
151
  findConventionSetup,
@@ -755,9 +755,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
755
755
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
756
756
  );
757
757
  }
758
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-CSWABOG5.js");
758
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SBKXKQFS.js");
759
759
  if (isGlobalThread2(thread)) {
760
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-4KCALEKD.js");
760
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-QMV6YEP5.js");
761
761
  ensureGlobalCoordinatorCwd2(
762
762
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
763
763
  );
@@ -2455,7 +2455,7 @@ async function createThread(input, _onSetupLine) {
2455
2455
  return readThread(thread.id) ?? thread;
2456
2456
  }
2457
2457
  async function listLinearIssues(agent, repoPath) {
2458
- const { getAdapter: getAdapter2 } = await import("./agents-7NIX44RB.js");
2458
+ const { getAdapter: getAdapter2 } = await import("./agents-HOIXQEP5.js");
2459
2459
  await requireAgent(agent, { requireLinear: true });
2460
2460
  const adapter = getAdapter2(agent);
2461
2461
  if (!adapter.listLinearIssues) {
@@ -2551,7 +2551,7 @@ function noteTurnLiveEvent(threadId, event) {
2551
2551
  buffers.delete(threadId);
2552
2552
  return;
2553
2553
  }
2554
- const immediate = event.type === "tool_use" || event.type === "tool_result";
2554
+ const immediate = event.type === "tool_use" || event.type === "tool_result" && !event.partial;
2555
2555
  if (immediate) flush(threadId);
2556
2556
  else scheduleFlush(threadId);
2557
2557
  }
@@ -2591,6 +2591,21 @@ function clearTurnLive(threadId) {
2591
2591
  }
2592
2592
  }
2593
2593
 
2594
+ // src/orchestrator/reconcile-heal.ts
2595
+ var RECONCILE_HEAL_MIN_MS = 2e3;
2596
+ var SKIP = /* @__PURE__ */ new Set([
2597
+ "stdout",
2598
+ "thinking",
2599
+ "usage",
2600
+ "stderr",
2601
+ "tool_result"
2602
+ ]);
2603
+ function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
2604
+ if (SKIP.has(eventType)) return false;
2605
+ if (lastCheckAt != null && now - lastCheckAt < RECONCILE_HEAL_MIN_MS) return false;
2606
+ return true;
2607
+ }
2608
+
2594
2609
  // src/threads/fork-worktree.ts
2595
2610
  function requireThread2(idOrRef) {
2596
2611
  const thread = findThreadByRef(idOrRef) ?? null;
@@ -2836,7 +2851,7 @@ async function adoptThread(input) {
2836
2851
  messages: input.messages ?? []
2837
2852
  });
2838
2853
  writeThread(thread);
2839
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-QG6PGFQR.js");
2854
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-M4OICPWF.js");
2840
2855
  await ensureWorkspace2(repoPath);
2841
2856
  return thread;
2842
2857
  }
@@ -5109,7 +5124,7 @@ function formatScheduledPrompt(name, prompt) {
5109
5124
  ${prompt}`;
5110
5125
  }
5111
5126
  async function defaultDeps() {
5112
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-ZY4RUJKT.js");
5127
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-NWNKWZLB.js");
5113
5128
  const orch = getOrchestrator2();
5114
5129
  return {
5115
5130
  findThread: (id) => findThreadByRef(id),
@@ -5243,6 +5258,8 @@ var Orchestrator = class {
5243
5258
  draining = /* @__PURE__ */ new Set();
5244
5259
  /** Threads past setStatus(running) but not yet in activeTurns (spawn in flight). */
5245
5260
  startingTurns = /* @__PURE__ */ new Set();
5261
+ /** Last sync thread-file read for false-stop heal (throttled per thread). */
5262
+ lastReconcileHealAt = /* @__PURE__ */ new Map();
5246
5263
  /**
5247
5264
  * Threads intentionally force-stopped. Prevents runTurn from re-asserting
5248
5265
  * `running` after spawn, and from overwriting `stopped` with idle/error when
@@ -5840,7 +5857,13 @@ var Orchestrator = class {
5840
5857
  if (event.type === "stderr" && typeof event.data === "string") {
5841
5858
  pushTurnStderr(stderrTail, event.data);
5842
5859
  }
5843
- if (event.type !== "stdout" && event.type !== "thinking") {
5860
+ const now = Date.now();
5861
+ if (shouldReadThreadToHealReconcile(
5862
+ event.type,
5863
+ this.lastReconcileHealAt.get(threadId),
5864
+ now
5865
+ )) {
5866
+ this.lastReconcileHealAt.set(threadId, now);
5844
5867
  const live = readThread(threadId);
5845
5868
  if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
5846
5869
  setStatus(threadId, "running");
@@ -5880,11 +5903,12 @@ var Orchestrator = class {
5880
5903
  if (this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
5881
5904
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
5882
5905
  if (sessionId) {
5883
- const { recoverFinishedCursorRun } = await import("./cursor-recover-ZUJG6XRQ.js");
5906
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-QSLWEZNA.js");
5884
5907
  for (let i = 0; i < 8; i++) {
5885
5908
  const recovered = recoverFinishedCursorRun({
5886
5909
  agentId: sessionId,
5887
- startedAfterMs: turnStartedAt - 5e3
5910
+ startedAfterMs: turnStartedAt - 5e3,
5911
+ threadId
5888
5912
  });
5889
5913
  if (recovered?.result) {
5890
5914
  assistantText = recovered.result;
@@ -6857,7 +6881,7 @@ var Orchestrator = class {
6857
6881
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
6858
6882
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
6859
6883
  try {
6860
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-QG6PGFQR.js");
6884
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-M4OICPWF.js");
6861
6885
  await ensureWorkspace2(thread.repoPath);
6862
6886
  } catch {
6863
6887
  }
@@ -6911,7 +6935,7 @@ var Orchestrator = class {
6911
6935
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
6912
6936
  );
6913
6937
  }
6914
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-IW3BX26B.js");
6938
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7AEKZSEX.js");
6915
6939
  const slug = thread.worktreePath.split("/").pop();
6916
6940
  const dest = thread.worktreePath;
6917
6941
  await withRepoGitLock(thread.repoPath, async () => {
@@ -7019,7 +7043,7 @@ async function startOrchestration(opts) {
7019
7043
  sourceRef: "default",
7020
7044
  ...createOpts
7021
7045
  }).catch(async () => {
7022
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-IW3BX26B.js");
7046
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7AEKZSEX.js");
7023
7047
  const repo = await resolveRepoRoot2(repoPath);
7024
7048
  const def = await resolveDefaultBranch2(repo);
7025
7049
  return orch.createThread({
@@ -7029,7 +7053,7 @@ async function startOrchestration(opts) {
7029
7053
  repoPath: repo
7030
7054
  });
7031
7055
  });
7032
- const { updateThread: upd } = await import("./thread-store-OEALWU7Y.js");
7056
+ const { updateThread: upd } = await import("./thread-store-JR235AWK.js");
7033
7057
  const updated = upd(thread.id, {
7034
7058
  sourceType: "orchestration",
7035
7059
  sourceRef: goal
@@ -2,11 +2,11 @@
2
2
 
3
3
  import {
4
4
  isGlobalRepoPath
5
- } from "./chunk-XOYQ7LNQ.js";
5
+ } from "./chunk-4NAW5BAQ.js";
6
6
  import {
7
7
  ensureGhPreferOrigin,
8
8
  resolveRepoRoot
9
- } from "./chunk-ZMROW673.js";
9
+ } from "./chunk-WCU3FHEI.js";
10
10
  import {
11
11
  appDataDir
12
12
  } from "./chunk-BD2ICC4D.js";
@@ -17,6 +17,7 @@ import {
17
17
  writeFileSync,
18
18
  readdirSync
19
19
  } from "fs";
20
+ import { basename } from "path";
20
21
  import lockfile from "proper-lockfile";
21
22
  function nowIso() {
22
23
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -119,7 +120,8 @@ function writeThread(thread) {
119
120
  function idPath(id) {
120
121
  return id;
121
122
  }
122
- function isThreadRecordFile(name) {
123
+ function isThreadRecordFile(nameOrPath) {
124
+ const name = basename(nameOrPath);
123
125
  return name.endsWith(".json") && !name.endsWith(".live.json");
124
126
  }
125
127
  function listThreads(opts) {
@@ -178,6 +180,7 @@ export {
178
180
  withThreadLock,
179
181
  readThread,
180
182
  writeThread,
183
+ isThreadRecordFile,
181
184
  listThreads,
182
185
  deleteThreadRecord,
183
186
  updateThread,
@@ -130,7 +130,7 @@ function summarizeTurnStderr(tail, maxChars = 500) {
130
130
  function looksLikeInvalidAgentSession(text) {
131
131
  const lower = text.trim().toLowerCase();
132
132
  if (!lower) return false;
133
- return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower);
133
+ return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower) || /\brun\b.{0,80}\bnot found for agent\b/.test(lower);
134
134
  }
135
135
  function looksLikeRetryableRunnerCrash(text) {
136
136
  if (looksLikeAgentFailureMessage(text)) return false;
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-EKIDHL2T.js";
8
8
  import {
9
9
  isOrchestratorThread
10
- } from "./chunk-4OJMZ6P2.js";
10
+ } from "./chunk-4WV7C7WP.js";
11
11
  import {
12
12
  applyAgentRunnerHeapEnv,
13
13
  applyNodeLaunch,
@@ -20,13 +20,13 @@ import {
20
20
  packagedMcpStdioPath,
21
21
  parseCursorRunnerLine,
22
22
  resolveNodeLaunch
23
- } from "./chunk-GBY7OOMB.js";
23
+ } from "./chunk-NZBDVBCP.js";
24
24
  import {
25
25
  codexUnattendedGitConfigArgs,
26
26
  mergeAgentGitAuthEnv,
27
27
  resolveAgentGitAuthEnv,
28
28
  resolveCodexGitWritableRoots
29
- } from "./chunk-FZCIQYNQ.js";
29
+ } from "./chunk-VGPLXQIH.js";
30
30
  import {
31
31
  claudeChromeEnabled,
32
32
  loadAppSettings,
@@ -815,6 +815,11 @@ function parseDiffStat(result) {
815
815
  }
816
816
  return {};
817
817
  }
818
+ function withPartTimes(next, prev) {
819
+ const now = Date.now();
820
+ const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
821
+ return { ...next, startedAt, updatedAt: now };
822
+ }
818
823
  function applyAgentEvent(parts, event) {
819
824
  if (event.type === "stdout") {
820
825
  const data = event.data;
@@ -822,17 +827,22 @@ function applyAgentEvent(parts, event) {
822
827
  const next = [...parts];
823
828
  const last = next[next.length - 1];
824
829
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
825
- next[next.length - 1] = {
826
- type: "text",
827
- text: last.text + data,
828
- ...event.parentId ? { parentId: event.parentId } : {}
829
- };
830
+ next[next.length - 1] = withPartTimes(
831
+ {
832
+ type: "text",
833
+ text: last.text + data,
834
+ ...event.parentId ? { parentId: event.parentId } : {}
835
+ },
836
+ last
837
+ );
830
838
  } else {
831
- next.push({
832
- type: "text",
833
- text: data,
834
- ...event.parentId ? { parentId: event.parentId } : {}
835
- });
839
+ next.push(
840
+ withPartTimes({
841
+ type: "text",
842
+ text: data,
843
+ ...event.parentId ? { parentId: event.parentId } : {}
844
+ })
845
+ );
836
846
  }
837
847
  return next;
838
848
  }
@@ -844,34 +854,44 @@ function applyAgentEvent(parts, event) {
844
854
  for (let i = next.length - 1; i >= 0; i--) {
845
855
  const prev = next[i];
846
856
  if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
847
- next[i] = {
848
- type: "thinking",
849
- text: data,
850
- ...event.parentId ? { parentId: event.parentId } : {}
851
- };
857
+ next[i] = withPartTimes(
858
+ {
859
+ type: "thinking",
860
+ text: data,
861
+ ...event.parentId ? { parentId: event.parentId } : {}
862
+ },
863
+ prev
864
+ );
852
865
  return next;
853
866
  }
854
867
  }
855
- next.push({
856
- type: "thinking",
857
- text: data,
858
- ...event.parentId ? { parentId: event.parentId } : {}
859
- });
868
+ next.push(
869
+ withPartTimes({
870
+ type: "thinking",
871
+ text: data,
872
+ ...event.parentId ? { parentId: event.parentId } : {}
873
+ })
874
+ );
860
875
  return next;
861
876
  }
862
877
  const last = next[next.length - 1];
863
878
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
864
- next[next.length - 1] = {
865
- type: "thinking",
866
- text: last.text + data,
867
- ...event.parentId ? { parentId: event.parentId } : {}
868
- };
879
+ next[next.length - 1] = withPartTimes(
880
+ {
881
+ type: "thinking",
882
+ text: last.text + data,
883
+ ...event.parentId ? { parentId: event.parentId } : {}
884
+ },
885
+ last
886
+ );
869
887
  } else {
870
- next.push({
871
- type: "thinking",
872
- text: data,
873
- ...event.parentId ? { parentId: event.parentId } : {}
874
- });
888
+ next.push(
889
+ withPartTimes({
890
+ type: "thinking",
891
+ text: data,
892
+ ...event.parentId ? { parentId: event.parentId } : {}
893
+ })
894
+ );
875
895
  }
876
896
  return next;
877
897
  }
@@ -887,22 +907,25 @@ function applyAgentEvent(parts, event) {
887
907
  ...input ?? {}
888
908
  };
889
909
  const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
890
- next[existing] = {
891
- ...prev,
892
- name: event.name || prev.name,
893
- input: mergedRecord,
894
- description: toolDescription(event.name || prev.name, mergedRecord),
895
- detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
896
- filePath: toolFilePath(mergedRecord) ?? prev.filePath,
897
- additions: diff.additions ?? prev.additions,
898
- deletions: diff.deletions ?? prev.deletions,
899
- parentId: event.parentId ?? prev.parentId
900
- };
910
+ next[existing] = withPartTimes(
911
+ {
912
+ ...prev,
913
+ name: event.name || prev.name,
914
+ input: mergedRecord,
915
+ description: toolDescription(event.name || prev.name, mergedRecord),
916
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
917
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
918
+ additions: diff.additions ?? prev.additions,
919
+ deletions: diff.deletions ?? prev.deletions,
920
+ parentId: event.parentId ?? prev.parentId
921
+ },
922
+ prev
923
+ );
901
924
  return next;
902
925
  }
903
926
  return [
904
927
  ...parts,
905
- {
928
+ withPartTimes({
906
929
  type: "tool",
907
930
  id: event.id,
908
931
  name: event.name,
@@ -913,7 +936,7 @@ function applyAgentEvent(parts, event) {
913
936
  filePath: toolFilePath(input),
914
937
  ...event.parentId ? { parentId: event.parentId } : {},
915
938
  ...diff
916
- }
939
+ })
917
940
  ];
918
941
  }
919
942
  if (event.type === "tool_result") {
@@ -923,7 +946,7 @@ function applyAgentEvent(parts, event) {
923
946
  if (existing < 0) {
924
947
  return [
925
948
  ...parts,
926
- {
949
+ withPartTimes({
927
950
  type: "tool",
928
951
  id: event.id,
929
952
  name: "tool",
@@ -931,22 +954,25 @@ function applyAgentEvent(parts, event) {
931
954
  status: event.isError ? "error" : "running",
932
955
  result: event.content,
933
956
  ...event.parentId ? { parentId: event.parentId } : {}
934
- }
957
+ })
935
958
  ];
936
959
  }
937
960
  return parts.map((p, i) => {
938
961
  if (i !== existing || p.type !== "tool") return p;
939
962
  if (p.status === "done" || p.status === "error") return p;
940
- return {
941
- ...p,
942
- result: event.content ?? p.result
943
- };
963
+ return withPartTimes(
964
+ {
965
+ ...p,
966
+ result: event.content ?? p.result
967
+ },
968
+ p
969
+ );
944
970
  });
945
971
  }
946
972
  if (existing < 0) {
947
973
  return [
948
974
  ...parts,
949
- {
975
+ withPartTimes({
950
976
  type: "tool",
951
977
  id: event.id,
952
978
  name: "tool",
@@ -956,18 +982,21 @@ function applyAgentEvent(parts, event) {
956
982
  ...event.parentId ? { parentId: event.parentId } : {},
957
983
  ...fromResult.additions != null ? { additions: fromResult.additions } : {},
958
984
  ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
959
- }
985
+ })
960
986
  ];
961
987
  }
962
988
  return parts.map((p, i) => {
963
989
  if (i !== existing || p.type !== "tool") return p;
964
- return {
965
- ...p,
966
- status: event.isError ? "error" : "done",
967
- result: event.content,
968
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
969
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
970
- };
990
+ return withPartTimes(
991
+ {
992
+ ...p,
993
+ status: event.isError ? "error" : "done",
994
+ result: event.content,
995
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
996
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
997
+ },
998
+ p
999
+ );
971
1000
  });
972
1001
  }
973
1002
  return parts;
@@ -1595,7 +1624,7 @@ var claudeAdapter = {
1595
1624
  );
1596
1625
  }
1597
1626
  const mode = permissionMode(thread);
1598
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-CSWABOG5.js");
1627
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-SBKXKQFS.js");
1599
1628
  const isOrchestrator = isOrchestratorThread2(thread);
1600
1629
  const injectedServers = await buildInjectedMcpServers({
1601
1630
  includeSideboard: true,
@@ -2295,6 +2324,7 @@ var cursorAdapter = {
2295
2324
  const req = {
2296
2325
  prompt,
2297
2326
  cwd: thread.worktreePath,
2327
+ threadId: thread.id,
2298
2328
  agentId,
2299
2329
  model: thread.model,
2300
2330
  effort: thread.effort,
@@ -19,6 +19,7 @@ import {
19
19
  writeFileSync,
20
20
  readdirSync
21
21
  } from "fs";
22
+ import { basename } from "path";
22
23
  import lockfile from "proper-lockfile";
23
24
  function nowIso() {
24
25
  return (/* @__PURE__ */ new Date()).toISOString();
@@ -121,7 +122,8 @@ function writeThread(thread) {
121
122
  function idPath(id) {
122
123
  return id;
123
124
  }
124
- function isThreadRecordFile(name) {
125
+ function isThreadRecordFile(nameOrPath) {
126
+ const name = basename(nameOrPath);
125
127
  return name.endsWith(".json") && !name.endsWith(".live.json");
126
128
  }
127
129
  function listThreads(opts) {
@@ -180,6 +182,7 @@ export {
180
182
  withThreadLock,
181
183
  readThread,
182
184
  writeThread,
185
+ isThreadRecordFile,
183
186
  listThreads,
184
187
  deleteThreadRecord,
185
188
  updateThread,