@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
@@ -9,13 +9,13 @@ import {
9
9
  } from "./chunk-7YKXHBIW.js";
10
10
  import {
11
11
  isOrchestratorThread
12
- } from "./chunk-TROJ3PVH.js";
12
+ } from "./chunk-VOD3HFLP.js";
13
13
  import {
14
14
  codexUnattendedGitConfigArgs,
15
15
  mergeAgentGitAuthEnv,
16
16
  resolveAgentGitAuthEnv,
17
17
  resolveCodexGitWritableRoots
18
- } from "./chunk-JVIW55KT.js";
18
+ } from "./chunk-YXDR43ZC.js";
19
19
  import {
20
20
  claudeChromeEnabled,
21
21
  isElectronLikeCommand,
@@ -24,7 +24,7 @@ import {
24
24
  resolveClaudeExecutable,
25
25
  unwrapStrippedElectronLaunch,
26
26
  wrapElectronAsNodeLaunch
27
- } from "./chunk-NE4TOOKS.js";
27
+ } from "./chunk-SGEVS5SY.js";
28
28
  import {
29
29
  appDataDir
30
30
  } from "./chunk-BD2ICC4D.js";
@@ -159,7 +159,7 @@ function extractJsonErrorMessage(obj) {
159
159
  var NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
160
160
  function isPinnedStderrLine(line) {
161
161
  if (/^\s*at\s/.test(line)) return false;
162
- return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:/i.test(
162
+ return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:|FATAL ERROR|heap out of memory|javascript heap|OOMErrorHandler|FatalProcessOutOfMemory/i.test(
163
163
  line
164
164
  );
165
165
  }
@@ -182,15 +182,22 @@ function looksLikeMinifiedJsDump(line) {
182
182
  function looksLikeNestedElectronCrash(line) {
183
183
  return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
184
184
  }
185
- function looksLikeHomebrewLibuvCrash(line) {
186
- const uvRun = /uv_run/i.test(line);
187
- const spin = /SpinEventLoopInternal/i.test(line);
188
- const homebrewUv = /Cellar\/libuv|libuv\.\d\.dylib/i.test(line);
189
- const homebrewNode = /Cellar\/node\//i.test(line);
190
- return uvRun && (homebrewUv || spin || homebrewNode) || spin && (homebrewUv || homebrewNode);
185
+ function looksLikeNativeEventLoopCrash(text) {
186
+ return /uv_run|uv__io_poll|SpinEventLoopInternal/i.test(text);
187
+ }
188
+ function looksLikeV8Oom(text) {
189
+ return /javascript heap|reached heap limit|OOMErrorHandler|FatalProcessOutOfMemory|Allocation failed - JavaScript heap/i.test(
190
+ text
191
+ );
192
+ }
193
+ function looksLikeHomebrewLibuvCrash(text) {
194
+ if (!looksLikeNativeEventLoopCrash(text)) return false;
195
+ return /Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(text);
191
196
  }
192
197
  var NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
193
198
  var HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
199
+ var BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
200
+ 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.";
194
201
  var MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
195
202
  function clipStderr(text, maxChars) {
196
203
  const trimmed = text.trim();
@@ -204,7 +211,12 @@ function summarizeTurnStderr(tail, maxChars = 500) {
204
211
  const cursorRunFailed = [...tail].reverse().find((line) => /^cursor run failed\b/i.test(line.trim()));
205
212
  if (cursorRunFailed) return clipStderr(cursorRunFailed, maxChars);
206
213
  if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
207
- if (tail.some(looksLikeHomebrewLibuvCrash)) return HOMEBREW_LIBUV_SUMMARY;
214
+ const blob = tail.join("\n");
215
+ if (looksLikeV8Oom(blob)) return V8_OOM_SUMMARY;
216
+ if (looksLikeHomebrewLibuvCrash(blob)) return HOMEBREW_LIBUV_SUMMARY;
217
+ if (looksLikeNativeEventLoopCrash(blob)) {
218
+ return BUNDLED_NODE_CRASH_SUMMARY;
219
+ }
208
220
  if (tail.some(
209
221
  (line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
210
222
  )) {
@@ -230,10 +242,11 @@ function looksLikeInvalidAgentSession(text) {
230
242
  function looksLikeRetryableRunnerCrash(text) {
231
243
  if (looksLikeAgentFailureMessage(text)) return false;
232
244
  if (looksLikeInvalidAgentSession(text)) return false;
245
+ if (looksLikeV8Oom(text)) return false;
233
246
  const lower = text.trim().toLowerCase();
234
247
  if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
235
248
  if (!lower) return true;
236
- 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(
249
+ 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(
237
250
  lower
238
251
  );
239
252
  }
@@ -285,9 +298,15 @@ function humanizeAgentFailDetail(detail) {
285
298
  if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
286
299
  return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
287
300
  }
288
- if (/homebrew node \+ shared libuv|uv_run|spineventloopinternal/i.test(lower)) {
301
+ if (looksLikeV8Oom(raw) || /javascript heap out of memory/i.test(lower)) {
302
+ return /ran out of memory/i.test(raw) ? raw : V8_OOM_SUMMARY;
303
+ }
304
+ if (/homebrew node \+ shared libuv|Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(raw)) {
289
305
  return /brew install node@22/i.test(raw) ? raw : `${raw} \u2014 install Node 22 LTS (\`brew install node@22\`) and retry.`;
290
306
  }
307
+ if (/uv_run|spineventloopinternal|uv__io_poll|cursor runner crashed in node/i.test(lower)) {
308
+ return /retry the turn/i.test(raw) ? raw : BUNDLED_NODE_CRASH_SUMMARY;
309
+ }
291
310
  if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
292
311
  return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
293
312
  }
@@ -668,6 +687,291 @@ function mcpAllowTools(servers) {
668
687
  return out;
669
688
  }
670
689
 
690
+ // src/agents/message-parts.ts
691
+ function asRecord(input) {
692
+ if (input && typeof input === "object" && !Array.isArray(input)) {
693
+ return input;
694
+ }
695
+ return void 0;
696
+ }
697
+ function str(v) {
698
+ return typeof v === "string" && v.trim() ? v : void 0;
699
+ }
700
+ function toolDetail(name, input) {
701
+ if (!input) return void 0;
702
+ const command = str(input.command) ?? str(input.cmd);
703
+ if (command) return command;
704
+ const path = str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
705
+ if (path) return path;
706
+ const pattern = str(input.pattern) ?? str(input.glob) ?? str(input.glob_pattern);
707
+ if (pattern) return pattern;
708
+ const query = str(input.query) ?? str(input.prompt);
709
+ if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
710
+ try {
711
+ const raw = JSON.stringify(input);
712
+ return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
713
+ } catch {
714
+ return name;
715
+ }
716
+ }
717
+ function toolDescription(name, input) {
718
+ const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
719
+ if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
720
+ if (/connectedAgentRequest/i.test(name)) {
721
+ return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
722
+ }
723
+ if (/present_artifact$/i.test(name)) {
724
+ return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
725
+ }
726
+ if (/present_plan$/i.test(name)) {
727
+ return str(input?.title) ? `Plan ${str(input?.title)}` : "Present plan";
728
+ }
729
+ if (/present_schema$/i.test(name)) {
730
+ return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
731
+ }
732
+ if (/present_files$/i.test(name)) {
733
+ return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
734
+ }
735
+ if (isSubagentToolName(name)) {
736
+ const desc = str(input?.description);
737
+ const sub = asRecord(input?.subagentType);
738
+ const kind = str(sub?.name) ?? str(sub?.kind) ?? str(input?.subagent_type) ?? str(input?.subagentType);
739
+ if (/^spawn_agent$/i.test(name)) {
740
+ return str(input?.prompt) ?? desc ?? "Subagent";
741
+ }
742
+ if (/connectedAgentRequest/i.test(name)) {
743
+ return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
744
+ }
745
+ if (desc && kind) return `${kind}: ${desc}`;
746
+ if (desc) return desc;
747
+ return "Subagent";
748
+ }
749
+ if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
750
+ return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
751
+ }
752
+ if (!input) return n;
753
+ if (/bash|shell|terminal/i.test(name) && str(input.command)) {
754
+ const cmd = str(input.command);
755
+ if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
756
+ if (/git\s+status/i.test(cmd)) return "Check git status";
757
+ if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
758
+ if (/git\s+branch/i.test(cmd)) return "List branches";
759
+ if (/grep|rg\b/i.test(cmd)) return "Search repository";
760
+ return "Run shell command";
761
+ }
762
+ if (/edit|write|apply/i.test(name)) {
763
+ const path = str(input.file_path) ?? str(input.path);
764
+ return path ? `Edit ${path.split("/").pop()}` : "Edit file";
765
+ }
766
+ if (/read/i.test(name)) {
767
+ const path = str(input.file_path) ?? str(input.path);
768
+ return path ? `Read ${path.split("/").pop()}` : "Read file";
769
+ }
770
+ if (/grep/i.test(name)) return "Search files";
771
+ if (/glob/i.test(name)) return "Find files";
772
+ return n;
773
+ }
774
+ function isSubagentToolName(name) {
775
+ const n = (name ?? "").trim();
776
+ if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
777
+ return /connectedAgentRequest/i.test(n);
778
+ }
779
+ function messagePartParentId(part) {
780
+ if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
781
+ return part.parentId;
782
+ }
783
+ return void 0;
784
+ }
785
+ function sameParentId(a, b) {
786
+ return (a ?? "") === (b ?? "");
787
+ }
788
+ function withEventParentId(event, parentId) {
789
+ if (!parentId) return event;
790
+ if (event.type === "stdout" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result") {
791
+ return { ...event, parentId: event.parentId ?? parentId };
792
+ }
793
+ return event;
794
+ }
795
+ function toolFilePath(input) {
796
+ if (!input) return void 0;
797
+ return str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
798
+ }
799
+ function countLines(text) {
800
+ if (!text) return 0;
801
+ return text.split("\n").length;
802
+ }
803
+ function diffFromInput(input) {
804
+ if (!input) return {};
805
+ const oldS = str(input.old_string) ?? str(input.oldString);
806
+ const newS = str(input.new_string) ?? str(input.newString) ?? str(input.content);
807
+ if (oldS != null || newS != null) {
808
+ return {
809
+ additions: countLines(newS),
810
+ deletions: countLines(oldS)
811
+ };
812
+ }
813
+ return {};
814
+ }
815
+ function parseDiffStat(result) {
816
+ if (!result) return {};
817
+ const paired = result.match(/\+(\d+)\s+-(\d+)/);
818
+ if (paired) {
819
+ return {
820
+ additions: Number(paired[1]),
821
+ deletions: Number(paired[2])
822
+ };
823
+ }
824
+ const verbose = result.match(
825
+ /(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
826
+ );
827
+ if (verbose) {
828
+ return {
829
+ additions: Number(verbose[1]),
830
+ deletions: verbose[2] != null ? Number(verbose[2]) : void 0
831
+ };
832
+ }
833
+ return {};
834
+ }
835
+ function applyAgentEvent(parts, event) {
836
+ if (event.type === "stdout") {
837
+ const data = event.data;
838
+ if (!data) return parts;
839
+ const next = [...parts];
840
+ const last = next[next.length - 1];
841
+ if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
842
+ next[next.length - 1] = {
843
+ type: "text",
844
+ text: last.text + data,
845
+ ...event.parentId ? { parentId: event.parentId } : {}
846
+ };
847
+ } else {
848
+ next.push({
849
+ type: "text",
850
+ text: data,
851
+ ...event.parentId ? { parentId: event.parentId } : {}
852
+ });
853
+ }
854
+ return next;
855
+ }
856
+ if (event.type === "thinking") {
857
+ const data = event.data;
858
+ if (!data) return parts;
859
+ const next = [...parts];
860
+ const last = next[next.length - 1];
861
+ if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
862
+ next[next.length - 1] = {
863
+ type: "thinking",
864
+ text: last.text + data,
865
+ ...event.parentId ? { parentId: event.parentId } : {}
866
+ };
867
+ } else {
868
+ next.push({
869
+ type: "thinking",
870
+ text: data,
871
+ ...event.parentId ? { parentId: event.parentId } : {}
872
+ });
873
+ }
874
+ return next;
875
+ }
876
+ if (event.type === "tool_use") {
877
+ const input = asRecord(event.input);
878
+ const diff = diffFromInput(input);
879
+ const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
880
+ if (existing >= 0) {
881
+ const prev = parts[existing];
882
+ const next = [...parts];
883
+ const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
884
+ next[existing] = {
885
+ ...prev,
886
+ name: event.name || prev.name,
887
+ input: mergedInput,
888
+ description: toolDescription(event.name || prev.name, mergedInput),
889
+ detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
890
+ filePath: toolFilePath(mergedInput) ?? prev.filePath,
891
+ additions: diff.additions ?? prev.additions,
892
+ deletions: diff.deletions ?? prev.deletions,
893
+ parentId: event.parentId ?? prev.parentId
894
+ };
895
+ return next;
896
+ }
897
+ return [
898
+ ...parts,
899
+ {
900
+ type: "tool",
901
+ id: event.id,
902
+ name: event.name,
903
+ input,
904
+ description: toolDescription(event.name, input),
905
+ detail: toolDetail(event.name, input),
906
+ status: "running",
907
+ filePath: toolFilePath(input),
908
+ ...event.parentId ? { parentId: event.parentId } : {},
909
+ ...diff
910
+ }
911
+ ];
912
+ }
913
+ if (event.type === "tool_result") {
914
+ const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
915
+ const fromResult = parseDiffStat(event.content);
916
+ if (existing < 0) {
917
+ return [
918
+ ...parts,
919
+ {
920
+ type: "tool",
921
+ id: event.id,
922
+ name: "tool",
923
+ description: "tool",
924
+ status: event.isError ? "error" : "done",
925
+ result: event.content,
926
+ ...event.parentId ? { parentId: event.parentId } : {},
927
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
928
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
929
+ }
930
+ ];
931
+ }
932
+ return parts.map((p, i) => {
933
+ if (i !== existing || p.type !== "tool") return p;
934
+ return {
935
+ ...p,
936
+ status: event.isError ? "error" : "done",
937
+ result: event.content,
938
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
939
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
940
+ };
941
+ });
942
+ }
943
+ return parts;
944
+ }
945
+ function partsToAssistantText(parts) {
946
+ return parts.filter(
947
+ (p) => p.type === "text" && !messagePartParentId(p)
948
+ ).map((p) => p.text).join("").trim();
949
+ }
950
+ function stripBrightsyNdjsonNoise(text) {
951
+ if (!text || !text.includes('"type"')) return text;
952
+ let out = text;
953
+ out = out.replace(
954
+ /\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
955
+ ""
956
+ );
957
+ out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
958
+ return out.trim();
959
+ }
960
+ function isBrightsyNdjsonLine(line) {
961
+ const t = line.trim();
962
+ if (!t.startsWith("{")) return false;
963
+ return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
964
+ }
965
+ function finalizeParts(parts) {
966
+ return parts.map(
967
+ (p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
968
+ );
969
+ }
970
+ function normalizeParseResult(parsed) {
971
+ if (!parsed) return [];
972
+ return Array.isArray(parsed) ? parsed : [parsed];
973
+ }
974
+
671
975
  // src/agents/injected-mcp.ts
672
976
  import { existsSync as existsSync4, mkdtempSync, writeFileSync } from "fs";
673
977
  import { createRequire } from "module";
@@ -1217,7 +1521,10 @@ var BASE_ALLOWED_TOOLS = [
1217
1521
  "Glob",
1218
1522
  "Grep",
1219
1523
  "WebFetch",
1220
- "WebSearch"
1524
+ "WebSearch",
1525
+ // Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
1526
+ "Task",
1527
+ "Agent"
1221
1528
  ];
1222
1529
  var CLAUDE_CHROME_ALLOWED_TOOLS = [
1223
1530
  "mcp__claude-in-chrome",
@@ -1269,42 +1576,59 @@ function claudeResultErrorDetail(obj) {
1269
1576
  }
1270
1577
  return "Claude turn failed";
1271
1578
  }
1272
- function eventsFromContentBlocks(blocks) {
1579
+ function eventsFromContentBlocks(blocks, parentId) {
1273
1580
  if (!blocks?.length) return [];
1274
1581
  const out = [];
1275
1582
  for (const block of blocks) {
1276
1583
  if (!block?.type) continue;
1277
1584
  if (block.type === "text" && block.text) {
1278
- out.push({ type: "stdout", data: block.text });
1585
+ out.push(withEventParentId({ type: "stdout", data: block.text }, parentId));
1279
1586
  continue;
1280
1587
  }
1281
1588
  if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
1282
- out.push({ type: "thinking", data: block.thinking });
1589
+ out.push(withEventParentId({ type: "thinking", data: block.thinking }, parentId));
1283
1590
  continue;
1284
1591
  }
1285
1592
  if (block.type === "tool_use" && block.id && block.name) {
1286
- out.push({
1287
- type: "tool_use",
1288
- id: block.id,
1289
- name: block.name,
1290
- input: block.input
1291
- });
1593
+ out.push(
1594
+ withEventParentId(
1595
+ {
1596
+ type: "tool_use",
1597
+ id: block.id,
1598
+ name: block.name,
1599
+ input: block.input
1600
+ },
1601
+ parentId
1602
+ )
1603
+ );
1292
1604
  continue;
1293
1605
  }
1294
1606
  if (block.type === "tool_result" && block.tool_use_id) {
1295
1607
  const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
1296
1608
  (c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
1297
1609
  ).join("") : block.content != null ? JSON.stringify(block.content) : void 0;
1298
- out.push({
1299
- type: "tool_result",
1300
- id: block.tool_use_id,
1301
- content,
1302
- isError: Boolean(block.is_error)
1303
- });
1610
+ out.push(
1611
+ withEventParentId(
1612
+ {
1613
+ type: "tool_result",
1614
+ id: block.tool_use_id,
1615
+ content,
1616
+ isError: Boolean(block.is_error)
1617
+ },
1618
+ parentId
1619
+ )
1620
+ );
1304
1621
  }
1305
1622
  }
1306
1623
  return out;
1307
1624
  }
1625
+ function claudeParentToolUseId(obj) {
1626
+ const nested = obj.event && typeof obj.event === "object" && !Array.isArray(obj.event) ? obj.event : void 0;
1627
+ for (const id of [obj.parent_tool_use_id, nested?.parent_tool_use_id]) {
1628
+ if (typeof id === "string" && id.trim()) return id.trim();
1629
+ }
1630
+ return void 0;
1631
+ }
1308
1632
  var claudeAdapter = {
1309
1633
  kind: "claude",
1310
1634
  async detect() {
@@ -1359,7 +1683,7 @@ var claudeAdapter = {
1359
1683
  );
1360
1684
  }
1361
1685
  const mode = permissionMode(thread);
1362
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-WBQWQQQY.js");
1686
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-SKFODUQQ.js");
1363
1687
  const isOrchestrator = isOrchestratorThread2(thread);
1364
1688
  const injectedServers = await buildInjectedMcpServers({
1365
1689
  includeSideboard: true,
@@ -1425,7 +1749,9 @@ var claudeAdapter = {
1425
1749
  args,
1426
1750
  cwd: thread.worktreePath,
1427
1751
  stdin: useStdin ? `${promptText}
1428
- ` : void 0
1752
+ ` : void 0,
1753
+ // Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
1754
+ env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
1429
1755
  };
1430
1756
  },
1431
1757
  parseEvent(line) {
@@ -1442,8 +1768,9 @@ var claudeAdapter = {
1442
1768
  return { type: "session_id", data: obj.session_id };
1443
1769
  }
1444
1770
  if (obj.type === "assistant" || obj.type === "user") {
1771
+ const parentId = claudeParentToolUseId(obj);
1445
1772
  const message = obj.message;
1446
- const events = eventsFromContentBlocks(message?.content);
1773
+ const events = eventsFromContentBlocks(message?.content, parentId);
1447
1774
  if (obj.type === "assistant") {
1448
1775
  const usage = usageFromClaude(message?.usage);
1449
1776
  if (usage) events.push({ type: "usage", data: usage, scope: "request" });
@@ -1452,34 +1779,45 @@ var claudeAdapter = {
1452
1779
  return events.length === 1 ? events[0] : events;
1453
1780
  }
1454
1781
  if (obj.type === "stream_event") {
1782
+ const parentId = claudeParentToolUseId(obj);
1455
1783
  const event = obj.event;
1456
1784
  if (!event) return null;
1457
1785
  if (event.type === "content_block_start" && event.content_block) {
1458
1786
  const block = event.content_block;
1459
1787
  if (block.type === "tool_use" && block.id && block.name) {
1460
- return {
1461
- type: "tool_use",
1462
- id: block.id,
1463
- name: block.name,
1464
- input: block.input
1465
- };
1788
+ return withEventParentId(
1789
+ {
1790
+ type: "tool_use",
1791
+ id: block.id,
1792
+ name: block.name,
1793
+ input: block.input
1794
+ },
1795
+ parentId
1796
+ );
1466
1797
  }
1467
1798
  if (block.type === "thinking" && block.thinking) {
1468
- return { type: "thinking", data: block.thinking };
1799
+ return withEventParentId({ type: "thinking", data: block.thinking }, parentId);
1469
1800
  }
1470
1801
  return null;
1471
1802
  }
1472
1803
  if (event.type === "content_block_delta" && event.delta) {
1473
- if (event.delta.text) return { type: "stdout", data: event.delta.text };
1474
- if (event.delta.thinking) return { type: "thinking", data: event.delta.thinking };
1804
+ if (event.delta.text) {
1805
+ return withEventParentId({ type: "stdout", data: event.delta.text }, parentId);
1806
+ }
1807
+ if (event.delta.thinking) {
1808
+ return withEventParentId({ type: "thinking", data: event.delta.thinking }, parentId);
1809
+ }
1475
1810
  return null;
1476
1811
  }
1477
1812
  return null;
1478
1813
  }
1479
1814
  if (obj.type === "content_block_delta") {
1815
+ const parentId = claudeParentToolUseId(obj);
1480
1816
  const delta = obj.delta;
1481
- if (delta?.text) return { type: "stdout", data: delta.text };
1482
- if (delta?.thinking) return { type: "thinking", data: delta.thinking };
1817
+ if (delta?.text) return withEventParentId({ type: "stdout", data: delta.text }, parentId);
1818
+ if (delta?.thinking) {
1819
+ return withEventParentId({ type: "thinking", data: delta.thinking }, parentId);
1820
+ }
1483
1821
  return null;
1484
1822
  }
1485
1823
  if (obj.type === "result") {
@@ -1648,7 +1986,7 @@ function unwrapCodexMcpResult(result) {
1648
1986
  return String(result);
1649
1987
  }
1650
1988
  }
1651
- function asRecord(value) {
1989
+ function asRecord2(value) {
1652
1990
  if (value && typeof value === "object" && !Array.isArray(value)) {
1653
1991
  return value;
1654
1992
  }
@@ -1787,7 +2125,7 @@ var codexAdapter = {
1787
2125
  }
1788
2126
  if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
1789
2127
  const name = `mcp__${item.server}__${item.tool}`;
1790
- const input = asRecord(item.arguments);
2128
+ const input = asRecord2(item.arguments);
1791
2129
  const events = [
1792
2130
  { type: "tool_use", id: item.id, name, input }
1793
2131
  ];
@@ -1818,6 +2156,36 @@ var codexAdapter = {
1818
2156
  }
1819
2157
  return events.length === 1 ? events[0] : events;
1820
2158
  }
2159
+ if (itemType === "collab_tool_call" && item.id) {
2160
+ const rawTool = typeof item.tool === "string" ? item.tool : "spawn_agent";
2161
+ const name = /spawn/i.test(rawTool) ? "spawn_agent" : rawTool;
2162
+ const input = {};
2163
+ if (item.prompt) input.prompt = item.prompt;
2164
+ if (Array.isArray(item.receiver_thread_ids)) {
2165
+ input.receiver_thread_ids = item.receiver_thread_ids;
2166
+ }
2167
+ const events = [{ type: "tool_use", id: item.id, name, input }];
2168
+ const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
2169
+ if (finished) {
2170
+ const nested = [];
2171
+ if (item.agents_states && typeof item.agents_states === "object") {
2172
+ for (const value of Object.values(item.agents_states)) {
2173
+ const msg = value && typeof value === "object" && typeof value.message === "string" ? value.message.trim() : "";
2174
+ if (msg) nested.push(msg);
2175
+ }
2176
+ }
2177
+ for (const text of nested) {
2178
+ events.push({ type: "stdout", data: text, parentId: item.id });
2179
+ }
2180
+ events.push({
2181
+ type: "tool_result",
2182
+ id: item.id,
2183
+ content: nested.join("\n") || void 0,
2184
+ isError: item.status === "failed"
2185
+ });
2186
+ }
2187
+ return events.length === 1 ? events[0] : events;
2188
+ }
1821
2189
  if (item.status === "failed") {
1822
2190
  const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
1823
2191
  return { type: "stderr", data: detail };
@@ -1895,7 +2263,7 @@ var codexAdapter = {
1895
2263
  import { existsSync as existsSync8 } from "fs";
1896
2264
  import { createRequire as createRequire3 } from "module";
1897
2265
  import { dirname as dirname3, join as join6 } from "path";
1898
- import { fileURLToPath as fileURLToPath3 } from "url";
2266
+ import { fileURLToPath as fileURLToPath2 } from "url";
1899
2267
  import { Cursor } from "@cursor/sdk";
1900
2268
 
1901
2269
  // src/agents/cursor-events.ts
@@ -1911,20 +2279,20 @@ function usageFromCursor(usage) {
1911
2279
  cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
1912
2280
  };
1913
2281
  }
1914
- function asRecord2(value) {
2282
+ function asRecord3(value) {
1915
2283
  if (value && typeof value === "object" && !Array.isArray(value)) {
1916
2284
  return value;
1917
2285
  }
1918
2286
  return void 0;
1919
2287
  }
1920
2288
  function normalizeCursorToolCall(name, args) {
1921
- const raw = asRecord2(args);
2289
+ const raw = asRecord3(args);
1922
2290
  const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
1923
- const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord2(raw?.args) != null);
2291
+ const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord3(raw?.args) != null);
1924
2292
  if (looksLikeMcp && toolName) {
1925
2293
  const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
1926
2294
  const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
1927
- const nested = asRecord2(raw.args);
2295
+ const nested = asRecord3(raw.args);
1928
2296
  return {
1929
2297
  name: `mcp__${provider}__${toolName}`,
1930
2298
  input: nested ?? { toolName }
@@ -1935,7 +2303,7 @@ function normalizeCursorToolCall(name, args) {
1935
2303
  function unwrapCursorToolResult(result) {
1936
2304
  if (result == null) return void 0;
1937
2305
  if (typeof result === "string") return result;
1938
- const rec = asRecord2(result);
2306
+ const rec = asRecord3(result);
1939
2307
  if (!rec) {
1940
2308
  try {
1941
2309
  return JSON.stringify(result);
@@ -1946,18 +2314,18 @@ function unwrapCursorToolResult(result) {
1946
2314
  const collectTexts = (items) => {
1947
2315
  const texts = [];
1948
2316
  for (const item of items) {
1949
- const row = asRecord2(item);
2317
+ const row = asRecord3(item);
1950
2318
  if (!row) continue;
1951
2319
  if (typeof row.text === "string") {
1952
2320
  texts.push(row.text);
1953
2321
  continue;
1954
2322
  }
1955
- const nested = asRecord2(row.text);
2323
+ const nested = asRecord3(row.text);
1956
2324
  if (typeof nested?.text === "string") texts.push(nested.text);
1957
2325
  }
1958
2326
  return texts;
1959
2327
  };
1960
- const value = asRecord2(rec.value);
2328
+ const value = asRecord3(rec.value);
1961
2329
  if (value && Array.isArray(value.content)) {
1962
2330
  const texts = collectTexts(value.content);
1963
2331
  if (texts.length) return texts.join("\n");
@@ -1974,10 +2342,10 @@ function unwrapCursorToolResult(result) {
1974
2342
  }
1975
2343
  function cursorToolResultIsError(status, result) {
1976
2344
  if (status === "error") return true;
1977
- const rec = asRecord2(result);
2345
+ const rec = asRecord3(result);
1978
2346
  if (!rec) return false;
1979
2347
  if (rec.status === "error") return true;
1980
- const value = asRecord2(rec.value);
2348
+ const value = asRecord3(rec.value);
1981
2349
  return value?.isError === true;
1982
2350
  }
1983
2351
  function cursorSdkMessageToEvents(msg) {
@@ -2071,7 +2439,6 @@ function parseCursorRunnerLine(line) {
2071
2439
  import { existsSync as existsSync7 } from "fs";
2072
2440
  import { createRequire as createRequire2 } from "module";
2073
2441
  import { dirname as dirname2, isAbsolute, join as join5, parse, resolve as resolvePath } from "path";
2074
- import { fileURLToPath as fileURLToPath2 } from "url";
2075
2442
  var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
2076
2443
  function rgBinaryName() {
2077
2444
  return process.platform === "win32" ? "rg.exe" : "rg";
@@ -2118,7 +2485,9 @@ function resolveCursorRipgrepPath(opts) {
2118
2485
  packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
2119
2486
  );
2120
2487
  if (fromPackaged) return fromPackaged;
2121
- const start = opts?.startFile?.trim() || process.argv[1] || fileURLToPath2(import.meta.url);
2488
+ const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
2489
+ // eslint-disable-next-line camelcase
2490
+ (typeof __filename !== "undefined" ? __filename : "");
2122
2491
  return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
2123
2492
  }
2124
2493
  function cursorRipgrepEnv(opts) {
@@ -2172,7 +2541,7 @@ function entryDir() {
2172
2541
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
2173
2542
  if (cjsDir) return cjsDir;
2174
2543
  try {
2175
- return dirname3(fileURLToPath3(import.meta.url));
2544
+ return dirname3(fileURLToPath2(import.meta.url));
2176
2545
  } catch {
2177
2546
  try {
2178
2547
  const req = createRequire3(process.cwd() + "/");
@@ -2297,6 +2666,24 @@ var FALLBACK_OPENCODE_MODELS = [
2297
2666
  ];
2298
2667
  var cachedOpencodeModels = null;
2299
2668
  var OPENCODE_MODEL_CACHE_MS = 5 * 60 * 1e3;
2669
+ function asRecord4(value) {
2670
+ if (value && typeof value === "object" && !Array.isArray(value)) {
2671
+ return value;
2672
+ }
2673
+ return void 0;
2674
+ }
2675
+ function str2(v) {
2676
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
2677
+ }
2678
+ function opencodeToolId(name, callId, metadata) {
2679
+ const sessionId = str2(metadata?.sessionId) ?? str2(metadata?.sessionID);
2680
+ if (name === "task" && sessionId) return sessionId;
2681
+ return callId || `tool-${Date.now()}`;
2682
+ }
2683
+ function withTaskParent(parentId, nested) {
2684
+ const events = Array.isArray(nested) ? nested : [nested];
2685
+ return [{ type: "tool_use", id: parentId, name: "task" }, ...events];
2686
+ }
2300
2687
  function displayNameFromOpencodeId(id) {
2301
2688
  const slash = id.indexOf("/");
2302
2689
  if (slash <= 0) return id;
@@ -2454,10 +2841,15 @@ var opencodeAdapter = {
2454
2841
  }
2455
2842
  if (obj.type === "tool_use") {
2456
2843
  const part = obj.part;
2457
- const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
2458
2844
  const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
2459
2845
  const state = part?.state;
2460
2846
  const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
2847
+ const metadata = asRecord4(state?.metadata);
2848
+ const id = opencodeToolId(
2849
+ name,
2850
+ part?.callID ?? part?.id ?? obj.id,
2851
+ metadata
2852
+ );
2461
2853
  const events = [{ type: "tool_use", id, name, input }];
2462
2854
  const output = state?.output;
2463
2855
  if (output != null || state?.status === "completed" || state?.status === "error") {
@@ -2471,6 +2863,53 @@ var opencodeAdapter = {
2471
2863
  }
2472
2864
  return events.length === 1 ? events[0] : events;
2473
2865
  }
2866
+ if (obj.type === "subtask_delta") {
2867
+ const parentId = str2(obj.childSessionID) ?? str2(obj.childSessionId);
2868
+ const delta = str2(obj.delta);
2869
+ if (parentId && delta) {
2870
+ return withTaskParent(
2871
+ parentId,
2872
+ withEventParentId({ type: "thinking", data: delta }, parentId)
2873
+ );
2874
+ }
2875
+ return null;
2876
+ }
2877
+ if (obj.type === "subtask_event") {
2878
+ const parentId = str2(obj.childSessionID) ?? str2(obj.childSessionId);
2879
+ const part = asRecord4(obj.part);
2880
+ if (!parentId || !part) return null;
2881
+ if (part.type === "text" && str2(part.text)) {
2882
+ return withTaskParent(
2883
+ parentId,
2884
+ withEventParentId({ type: "stdout", data: str2(part.text) }, parentId)
2885
+ );
2886
+ }
2887
+ if (part.type === "tool" || str2(part.tool)) {
2888
+ const name = str2(part.tool) ?? str2(part.name) ?? "tool";
2889
+ const id = str2(part.callID) ?? str2(part.id) ?? `${parentId}-${name}`;
2890
+ const state = asRecord4(part.state);
2891
+ const input = asRecord4(state?.input) ?? asRecord4(part.input);
2892
+ const nested = [
2893
+ withEventParentId({ type: "tool_use", id, name, input }, parentId)
2894
+ ];
2895
+ const output = state?.output ?? part.output;
2896
+ if (output != null || state?.status === "completed" || state?.status === "error") {
2897
+ nested.push(
2898
+ withEventParentId(
2899
+ {
2900
+ type: "tool_result",
2901
+ id,
2902
+ content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
2903
+ isError: state?.status === "error" || state?.status === "failed"
2904
+ },
2905
+ parentId
2906
+ )
2907
+ );
2908
+ }
2909
+ return withTaskParent(parentId, nested);
2910
+ }
2911
+ return null;
2912
+ }
2474
2913
  if (obj.type === "tool_result") {
2475
2914
  const part = obj.part;
2476
2915
  const id = part?.tool_use_id ?? part?.id ?? obj.tool_use_id ?? obj.id;
@@ -3004,6 +3443,13 @@ export {
3004
3443
  parseBrightsyCliLine,
3005
3444
  listBrightsyChatTargets,
3006
3445
  brightsyAdapter,
3446
+ toolDescription,
3447
+ applyAgentEvent,
3448
+ partsToAssistantText,
3449
+ stripBrightsyNdjsonNoise,
3450
+ isBrightsyNdjsonLine,
3451
+ finalizeParts,
3452
+ normalizeParseResult,
3007
3453
  sideboardMcpProfile,
3008
3454
  PLAN_MODE_INSTRUCTION,
3009
3455
  permissionMode,