@sideboard-ai/core 0.1.109 → 0.1.110

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 +87 -12
  2. package/dist/agents/cursor-runner.js +37 -11
  3. package/dist/{agents-XB332VUJ.js → agents-MQDW3YXL.js} +6 -6
  4. package/dist/{agents-YIMHDI46.js → agents-WK54VP7J.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-3UOKB6VQ.js} +40 -0
  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-EAAB4EK5.js} +154 -287
  15. package/dist/{chunk-I2OJ2YSP.js → chunk-KQBI5HNT.js} +2 -2
  16. package/dist/{chunk-P3BQ5DOL.js → chunk-KYOTBZ6S.js} +2 -0
  17. package/dist/{chunk-KKHDPV45.js → chunk-RSIWPLRG.js} +473 -37
  18. package/dist/{chunk-NE4TOOKS.js → chunk-SGEVS5SY.js} +10 -0
  19. package/dist/{chunk-TROJ3PVH.js → chunk-VOD3HFLP.js} +4 -4
  20. package/dist/{chunk-AY2EQI2P.js → chunk-VOJSO3RM.js} +472 -46
  21. package/dist/{chunk-MMI4RJ5I.js → chunk-WIHKHR5R.js} +14 -3
  22. package/dist/{chunk-LTPX5N6K.js → chunk-XOZDAVOP.js} +162 -276
  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 +835 -489
  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 +812 -487
  34. package/dist/mcp/run-stdio.js +17 -12
  35. package/dist/{orchestrator-6W7EKSPO.js → orchestrator-FCZVCKBK.js} +10 -10
  36. package/dist/{orchestrator-JVGVPKLI.js → orchestrator-SCATSB3O.js} +8 -8
  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";
@@ -668,6 +668,291 @@ function mcpAllowTools(servers) {
668
668
  return out;
669
669
  }
670
670
 
671
+ // src/agents/message-parts.ts
672
+ function asRecord(input) {
673
+ if (input && typeof input === "object" && !Array.isArray(input)) {
674
+ return input;
675
+ }
676
+ return void 0;
677
+ }
678
+ function str(v) {
679
+ return typeof v === "string" && v.trim() ? v : void 0;
680
+ }
681
+ function toolDetail(name, input) {
682
+ if (!input) return void 0;
683
+ const command = str(input.command) ?? str(input.cmd);
684
+ if (command) return command;
685
+ const path = str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
686
+ if (path) return path;
687
+ const pattern = str(input.pattern) ?? str(input.glob) ?? str(input.glob_pattern);
688
+ if (pattern) return pattern;
689
+ const query = str(input.query) ?? str(input.prompt);
690
+ if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
691
+ try {
692
+ const raw = JSON.stringify(input);
693
+ return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
694
+ } catch {
695
+ return name;
696
+ }
697
+ }
698
+ function toolDescription(name, input) {
699
+ const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
700
+ if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
701
+ if (/connectedAgentRequest/i.test(name)) {
702
+ return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
703
+ }
704
+ if (/present_artifact$/i.test(name)) {
705
+ return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
706
+ }
707
+ if (/present_plan$/i.test(name)) {
708
+ return str(input?.title) ? `Plan ${str(input?.title)}` : "Present plan";
709
+ }
710
+ if (/present_schema$/i.test(name)) {
711
+ return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
712
+ }
713
+ if (/present_files$/i.test(name)) {
714
+ return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
715
+ }
716
+ if (isSubagentToolName(name)) {
717
+ const desc = str(input?.description);
718
+ const sub = asRecord(input?.subagentType);
719
+ const kind = str(sub?.name) ?? str(sub?.kind) ?? str(input?.subagent_type) ?? str(input?.subagentType);
720
+ if (/^spawn_agent$/i.test(name)) {
721
+ return str(input?.prompt) ?? desc ?? "Subagent";
722
+ }
723
+ if (/connectedAgentRequest/i.test(name)) {
724
+ return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
725
+ }
726
+ if (desc && kind) return `${kind}: ${desc}`;
727
+ if (desc) return desc;
728
+ return "Subagent";
729
+ }
730
+ if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
731
+ return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
732
+ }
733
+ if (!input) return n;
734
+ if (/bash|shell|terminal/i.test(name) && str(input.command)) {
735
+ const cmd = str(input.command);
736
+ if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
737
+ if (/git\s+status/i.test(cmd)) return "Check git status";
738
+ if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
739
+ if (/git\s+branch/i.test(cmd)) return "List branches";
740
+ if (/grep|rg\b/i.test(cmd)) return "Search repository";
741
+ return "Run shell command";
742
+ }
743
+ if (/edit|write|apply/i.test(name)) {
744
+ const path = str(input.file_path) ?? str(input.path);
745
+ return path ? `Edit ${path.split("/").pop()}` : "Edit file";
746
+ }
747
+ if (/read/i.test(name)) {
748
+ const path = str(input.file_path) ?? str(input.path);
749
+ return path ? `Read ${path.split("/").pop()}` : "Read file";
750
+ }
751
+ if (/grep/i.test(name)) return "Search files";
752
+ if (/glob/i.test(name)) return "Find files";
753
+ return n;
754
+ }
755
+ function isSubagentToolName(name) {
756
+ const n = (name ?? "").trim();
757
+ if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
758
+ return /connectedAgentRequest/i.test(n);
759
+ }
760
+ function messagePartParentId(part) {
761
+ if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
762
+ return part.parentId;
763
+ }
764
+ return void 0;
765
+ }
766
+ function sameParentId(a, b) {
767
+ return (a ?? "") === (b ?? "");
768
+ }
769
+ function withEventParentId(event, parentId) {
770
+ if (!parentId) return event;
771
+ if (event.type === "stdout" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result") {
772
+ return { ...event, parentId: event.parentId ?? parentId };
773
+ }
774
+ return event;
775
+ }
776
+ function toolFilePath(input) {
777
+ if (!input) return void 0;
778
+ return str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
779
+ }
780
+ function countLines(text) {
781
+ if (!text) return 0;
782
+ return text.split("\n").length;
783
+ }
784
+ function diffFromInput(input) {
785
+ if (!input) return {};
786
+ const oldS = str(input.old_string) ?? str(input.oldString);
787
+ const newS = str(input.new_string) ?? str(input.newString) ?? str(input.content);
788
+ if (oldS != null || newS != null) {
789
+ return {
790
+ additions: countLines(newS),
791
+ deletions: countLines(oldS)
792
+ };
793
+ }
794
+ return {};
795
+ }
796
+ function parseDiffStat(result) {
797
+ if (!result) return {};
798
+ const paired = result.match(/\+(\d+)\s+-(\d+)/);
799
+ if (paired) {
800
+ return {
801
+ additions: Number(paired[1]),
802
+ deletions: Number(paired[2])
803
+ };
804
+ }
805
+ const verbose = result.match(
806
+ /(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
807
+ );
808
+ if (verbose) {
809
+ return {
810
+ additions: Number(verbose[1]),
811
+ deletions: verbose[2] != null ? Number(verbose[2]) : void 0
812
+ };
813
+ }
814
+ return {};
815
+ }
816
+ function applyAgentEvent(parts, event) {
817
+ if (event.type === "stdout") {
818
+ const data = event.data;
819
+ if (!data) return parts;
820
+ const next = [...parts];
821
+ const last = next[next.length - 1];
822
+ if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
823
+ next[next.length - 1] = {
824
+ type: "text",
825
+ text: last.text + data,
826
+ ...event.parentId ? { parentId: event.parentId } : {}
827
+ };
828
+ } else {
829
+ next.push({
830
+ type: "text",
831
+ text: data,
832
+ ...event.parentId ? { parentId: event.parentId } : {}
833
+ });
834
+ }
835
+ return next;
836
+ }
837
+ if (event.type === "thinking") {
838
+ const data = event.data;
839
+ if (!data) return parts;
840
+ const next = [...parts];
841
+ const last = next[next.length - 1];
842
+ if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
843
+ next[next.length - 1] = {
844
+ type: "thinking",
845
+ text: last.text + data,
846
+ ...event.parentId ? { parentId: event.parentId } : {}
847
+ };
848
+ } else {
849
+ next.push({
850
+ type: "thinking",
851
+ text: data,
852
+ ...event.parentId ? { parentId: event.parentId } : {}
853
+ });
854
+ }
855
+ return next;
856
+ }
857
+ if (event.type === "tool_use") {
858
+ const input = asRecord(event.input);
859
+ const diff = diffFromInput(input);
860
+ const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
861
+ if (existing >= 0) {
862
+ const prev = parts[existing];
863
+ const next = [...parts];
864
+ const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
865
+ next[existing] = {
866
+ ...prev,
867
+ name: event.name || prev.name,
868
+ input: mergedInput,
869
+ description: toolDescription(event.name || prev.name, mergedInput),
870
+ detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
871
+ filePath: toolFilePath(mergedInput) ?? prev.filePath,
872
+ additions: diff.additions ?? prev.additions,
873
+ deletions: diff.deletions ?? prev.deletions,
874
+ parentId: event.parentId ?? prev.parentId
875
+ };
876
+ return next;
877
+ }
878
+ return [
879
+ ...parts,
880
+ {
881
+ type: "tool",
882
+ id: event.id,
883
+ name: event.name,
884
+ input,
885
+ description: toolDescription(event.name, input),
886
+ detail: toolDetail(event.name, input),
887
+ status: "running",
888
+ filePath: toolFilePath(input),
889
+ ...event.parentId ? { parentId: event.parentId } : {},
890
+ ...diff
891
+ }
892
+ ];
893
+ }
894
+ if (event.type === "tool_result") {
895
+ const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
896
+ const fromResult = parseDiffStat(event.content);
897
+ if (existing < 0) {
898
+ return [
899
+ ...parts,
900
+ {
901
+ type: "tool",
902
+ id: event.id,
903
+ name: "tool",
904
+ description: "tool",
905
+ status: event.isError ? "error" : "done",
906
+ result: event.content,
907
+ ...event.parentId ? { parentId: event.parentId } : {},
908
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
909
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
910
+ }
911
+ ];
912
+ }
913
+ return parts.map((p, i) => {
914
+ if (i !== existing || p.type !== "tool") return p;
915
+ return {
916
+ ...p,
917
+ status: event.isError ? "error" : "done",
918
+ result: event.content,
919
+ ...fromResult.additions != null ? { additions: fromResult.additions } : {},
920
+ ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
921
+ };
922
+ });
923
+ }
924
+ return parts;
925
+ }
926
+ function partsToAssistantText(parts) {
927
+ return parts.filter(
928
+ (p) => p.type === "text" && !messagePartParentId(p)
929
+ ).map((p) => p.text).join("").trim();
930
+ }
931
+ function stripBrightsyNdjsonNoise(text) {
932
+ if (!text || !text.includes('"type"')) return text;
933
+ let out = text;
934
+ out = out.replace(
935
+ /\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
936
+ ""
937
+ );
938
+ out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
939
+ return out.trim();
940
+ }
941
+ function isBrightsyNdjsonLine(line) {
942
+ const t = line.trim();
943
+ if (!t.startsWith("{")) return false;
944
+ return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
945
+ }
946
+ function finalizeParts(parts) {
947
+ return parts.map(
948
+ (p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
949
+ );
950
+ }
951
+ function normalizeParseResult(parsed) {
952
+ if (!parsed) return [];
953
+ return Array.isArray(parsed) ? parsed : [parsed];
954
+ }
955
+
671
956
  // src/agents/injected-mcp.ts
672
957
  import { existsSync as existsSync4, mkdtempSync, writeFileSync } from "fs";
673
958
  import { createRequire } from "module";
@@ -1217,7 +1502,10 @@ var BASE_ALLOWED_TOOLS = [
1217
1502
  "Glob",
1218
1503
  "Grep",
1219
1504
  "WebFetch",
1220
- "WebSearch"
1505
+ "WebSearch",
1506
+ // Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
1507
+ "Task",
1508
+ "Agent"
1221
1509
  ];
1222
1510
  var CLAUDE_CHROME_ALLOWED_TOOLS = [
1223
1511
  "mcp__claude-in-chrome",
@@ -1269,42 +1557,59 @@ function claudeResultErrorDetail(obj) {
1269
1557
  }
1270
1558
  return "Claude turn failed";
1271
1559
  }
1272
- function eventsFromContentBlocks(blocks) {
1560
+ function eventsFromContentBlocks(blocks, parentId) {
1273
1561
  if (!blocks?.length) return [];
1274
1562
  const out = [];
1275
1563
  for (const block of blocks) {
1276
1564
  if (!block?.type) continue;
1277
1565
  if (block.type === "text" && block.text) {
1278
- out.push({ type: "stdout", data: block.text });
1566
+ out.push(withEventParentId({ type: "stdout", data: block.text }, parentId));
1279
1567
  continue;
1280
1568
  }
1281
1569
  if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
1282
- out.push({ type: "thinking", data: block.thinking });
1570
+ out.push(withEventParentId({ type: "thinking", data: block.thinking }, parentId));
1283
1571
  continue;
1284
1572
  }
1285
1573
  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
- });
1574
+ out.push(
1575
+ withEventParentId(
1576
+ {
1577
+ type: "tool_use",
1578
+ id: block.id,
1579
+ name: block.name,
1580
+ input: block.input
1581
+ },
1582
+ parentId
1583
+ )
1584
+ );
1292
1585
  continue;
1293
1586
  }
1294
1587
  if (block.type === "tool_result" && block.tool_use_id) {
1295
1588
  const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
1296
1589
  (c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
1297
1590
  ).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
- });
1591
+ out.push(
1592
+ withEventParentId(
1593
+ {
1594
+ type: "tool_result",
1595
+ id: block.tool_use_id,
1596
+ content,
1597
+ isError: Boolean(block.is_error)
1598
+ },
1599
+ parentId
1600
+ )
1601
+ );
1304
1602
  }
1305
1603
  }
1306
1604
  return out;
1307
1605
  }
1606
+ function claudeParentToolUseId(obj) {
1607
+ const nested = obj.event && typeof obj.event === "object" && !Array.isArray(obj.event) ? obj.event : void 0;
1608
+ for (const id of [obj.parent_tool_use_id, nested?.parent_tool_use_id]) {
1609
+ if (typeof id === "string" && id.trim()) return id.trim();
1610
+ }
1611
+ return void 0;
1612
+ }
1308
1613
  var claudeAdapter = {
1309
1614
  kind: "claude",
1310
1615
  async detect() {
@@ -1359,7 +1664,7 @@ var claudeAdapter = {
1359
1664
  );
1360
1665
  }
1361
1666
  const mode = permissionMode(thread);
1362
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-WBQWQQQY.js");
1667
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-SKFODUQQ.js");
1363
1668
  const isOrchestrator = isOrchestratorThread2(thread);
1364
1669
  const injectedServers = await buildInjectedMcpServers({
1365
1670
  includeSideboard: true,
@@ -1425,7 +1730,9 @@ var claudeAdapter = {
1425
1730
  args,
1426
1731
  cwd: thread.worktreePath,
1427
1732
  stdin: useStdin ? `${promptText}
1428
- ` : void 0
1733
+ ` : void 0,
1734
+ // Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
1735
+ env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
1429
1736
  };
1430
1737
  },
1431
1738
  parseEvent(line) {
@@ -1442,8 +1749,9 @@ var claudeAdapter = {
1442
1749
  return { type: "session_id", data: obj.session_id };
1443
1750
  }
1444
1751
  if (obj.type === "assistant" || obj.type === "user") {
1752
+ const parentId = claudeParentToolUseId(obj);
1445
1753
  const message = obj.message;
1446
- const events = eventsFromContentBlocks(message?.content);
1754
+ const events = eventsFromContentBlocks(message?.content, parentId);
1447
1755
  if (obj.type === "assistant") {
1448
1756
  const usage = usageFromClaude(message?.usage);
1449
1757
  if (usage) events.push({ type: "usage", data: usage, scope: "request" });
@@ -1452,34 +1760,45 @@ var claudeAdapter = {
1452
1760
  return events.length === 1 ? events[0] : events;
1453
1761
  }
1454
1762
  if (obj.type === "stream_event") {
1763
+ const parentId = claudeParentToolUseId(obj);
1455
1764
  const event = obj.event;
1456
1765
  if (!event) return null;
1457
1766
  if (event.type === "content_block_start" && event.content_block) {
1458
1767
  const block = event.content_block;
1459
1768
  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
- };
1769
+ return withEventParentId(
1770
+ {
1771
+ type: "tool_use",
1772
+ id: block.id,
1773
+ name: block.name,
1774
+ input: block.input
1775
+ },
1776
+ parentId
1777
+ );
1466
1778
  }
1467
1779
  if (block.type === "thinking" && block.thinking) {
1468
- return { type: "thinking", data: block.thinking };
1780
+ return withEventParentId({ type: "thinking", data: block.thinking }, parentId);
1469
1781
  }
1470
1782
  return null;
1471
1783
  }
1472
1784
  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 };
1785
+ if (event.delta.text) {
1786
+ return withEventParentId({ type: "stdout", data: event.delta.text }, parentId);
1787
+ }
1788
+ if (event.delta.thinking) {
1789
+ return withEventParentId({ type: "thinking", data: event.delta.thinking }, parentId);
1790
+ }
1475
1791
  return null;
1476
1792
  }
1477
1793
  return null;
1478
1794
  }
1479
1795
  if (obj.type === "content_block_delta") {
1796
+ const parentId = claudeParentToolUseId(obj);
1480
1797
  const delta = obj.delta;
1481
- if (delta?.text) return { type: "stdout", data: delta.text };
1482
- if (delta?.thinking) return { type: "thinking", data: delta.thinking };
1798
+ if (delta?.text) return withEventParentId({ type: "stdout", data: delta.text }, parentId);
1799
+ if (delta?.thinking) {
1800
+ return withEventParentId({ type: "thinking", data: delta.thinking }, parentId);
1801
+ }
1483
1802
  return null;
1484
1803
  }
1485
1804
  if (obj.type === "result") {
@@ -1648,7 +1967,7 @@ function unwrapCodexMcpResult(result) {
1648
1967
  return String(result);
1649
1968
  }
1650
1969
  }
1651
- function asRecord(value) {
1970
+ function asRecord2(value) {
1652
1971
  if (value && typeof value === "object" && !Array.isArray(value)) {
1653
1972
  return value;
1654
1973
  }
@@ -1787,7 +2106,7 @@ var codexAdapter = {
1787
2106
  }
1788
2107
  if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
1789
2108
  const name = `mcp__${item.server}__${item.tool}`;
1790
- const input = asRecord(item.arguments);
2109
+ const input = asRecord2(item.arguments);
1791
2110
  const events = [
1792
2111
  { type: "tool_use", id: item.id, name, input }
1793
2112
  ];
@@ -1818,6 +2137,36 @@ var codexAdapter = {
1818
2137
  }
1819
2138
  return events.length === 1 ? events[0] : events;
1820
2139
  }
2140
+ if (itemType === "collab_tool_call" && item.id) {
2141
+ const rawTool = typeof item.tool === "string" ? item.tool : "spawn_agent";
2142
+ const name = /spawn/i.test(rawTool) ? "spawn_agent" : rawTool;
2143
+ const input = {};
2144
+ if (item.prompt) input.prompt = item.prompt;
2145
+ if (Array.isArray(item.receiver_thread_ids)) {
2146
+ input.receiver_thread_ids = item.receiver_thread_ids;
2147
+ }
2148
+ const events = [{ type: "tool_use", id: item.id, name, input }];
2149
+ const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
2150
+ if (finished) {
2151
+ const nested = [];
2152
+ if (item.agents_states && typeof item.agents_states === "object") {
2153
+ for (const value of Object.values(item.agents_states)) {
2154
+ const msg = value && typeof value === "object" && typeof value.message === "string" ? value.message.trim() : "";
2155
+ if (msg) nested.push(msg);
2156
+ }
2157
+ }
2158
+ for (const text of nested) {
2159
+ events.push({ type: "stdout", data: text, parentId: item.id });
2160
+ }
2161
+ events.push({
2162
+ type: "tool_result",
2163
+ id: item.id,
2164
+ content: nested.join("\n") || void 0,
2165
+ isError: item.status === "failed"
2166
+ });
2167
+ }
2168
+ return events.length === 1 ? events[0] : events;
2169
+ }
1821
2170
  if (item.status === "failed") {
1822
2171
  const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
1823
2172
  return { type: "stderr", data: detail };
@@ -1911,20 +2260,20 @@ function usageFromCursor(usage) {
1911
2260
  cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
1912
2261
  };
1913
2262
  }
1914
- function asRecord2(value) {
2263
+ function asRecord3(value) {
1915
2264
  if (value && typeof value === "object" && !Array.isArray(value)) {
1916
2265
  return value;
1917
2266
  }
1918
2267
  return void 0;
1919
2268
  }
1920
2269
  function normalizeCursorToolCall(name, args) {
1921
- const raw = asRecord2(args);
2270
+ const raw = asRecord3(args);
1922
2271
  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);
2272
+ const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord3(raw?.args) != null);
1924
2273
  if (looksLikeMcp && toolName) {
1925
2274
  const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
1926
2275
  const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
1927
- const nested = asRecord2(raw.args);
2276
+ const nested = asRecord3(raw.args);
1928
2277
  return {
1929
2278
  name: `mcp__${provider}__${toolName}`,
1930
2279
  input: nested ?? { toolName }
@@ -1935,7 +2284,7 @@ function normalizeCursorToolCall(name, args) {
1935
2284
  function unwrapCursorToolResult(result) {
1936
2285
  if (result == null) return void 0;
1937
2286
  if (typeof result === "string") return result;
1938
- const rec = asRecord2(result);
2287
+ const rec = asRecord3(result);
1939
2288
  if (!rec) {
1940
2289
  try {
1941
2290
  return JSON.stringify(result);
@@ -1946,18 +2295,18 @@ function unwrapCursorToolResult(result) {
1946
2295
  const collectTexts = (items) => {
1947
2296
  const texts = [];
1948
2297
  for (const item of items) {
1949
- const row = asRecord2(item);
2298
+ const row = asRecord3(item);
1950
2299
  if (!row) continue;
1951
2300
  if (typeof row.text === "string") {
1952
2301
  texts.push(row.text);
1953
2302
  continue;
1954
2303
  }
1955
- const nested = asRecord2(row.text);
2304
+ const nested = asRecord3(row.text);
1956
2305
  if (typeof nested?.text === "string") texts.push(nested.text);
1957
2306
  }
1958
2307
  return texts;
1959
2308
  };
1960
- const value = asRecord2(rec.value);
2309
+ const value = asRecord3(rec.value);
1961
2310
  if (value && Array.isArray(value.content)) {
1962
2311
  const texts = collectTexts(value.content);
1963
2312
  if (texts.length) return texts.join("\n");
@@ -1974,10 +2323,10 @@ function unwrapCursorToolResult(result) {
1974
2323
  }
1975
2324
  function cursorToolResultIsError(status, result) {
1976
2325
  if (status === "error") return true;
1977
- const rec = asRecord2(result);
2326
+ const rec = asRecord3(result);
1978
2327
  if (!rec) return false;
1979
2328
  if (rec.status === "error") return true;
1980
- const value = asRecord2(rec.value);
2329
+ const value = asRecord3(rec.value);
1981
2330
  return value?.isError === true;
1982
2331
  }
1983
2332
  function cursorSdkMessageToEvents(msg) {
@@ -2297,6 +2646,24 @@ var FALLBACK_OPENCODE_MODELS = [
2297
2646
  ];
2298
2647
  var cachedOpencodeModels = null;
2299
2648
  var OPENCODE_MODEL_CACHE_MS = 5 * 60 * 1e3;
2649
+ function asRecord4(value) {
2650
+ if (value && typeof value === "object" && !Array.isArray(value)) {
2651
+ return value;
2652
+ }
2653
+ return void 0;
2654
+ }
2655
+ function str2(v) {
2656
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
2657
+ }
2658
+ function opencodeToolId(name, callId, metadata) {
2659
+ const sessionId = str2(metadata?.sessionId) ?? str2(metadata?.sessionID);
2660
+ if (name === "task" && sessionId) return sessionId;
2661
+ return callId || `tool-${Date.now()}`;
2662
+ }
2663
+ function withTaskParent(parentId, nested) {
2664
+ const events = Array.isArray(nested) ? nested : [nested];
2665
+ return [{ type: "tool_use", id: parentId, name: "task" }, ...events];
2666
+ }
2300
2667
  function displayNameFromOpencodeId(id) {
2301
2668
  const slash = id.indexOf("/");
2302
2669
  if (slash <= 0) return id;
@@ -2454,10 +2821,15 @@ var opencodeAdapter = {
2454
2821
  }
2455
2822
  if (obj.type === "tool_use") {
2456
2823
  const part = obj.part;
2457
- const id = part?.callID ?? part?.id ?? obj.id ?? `tool-${Date.now()}`;
2458
2824
  const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
2459
2825
  const state = part?.state;
2460
2826
  const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
2827
+ const metadata = asRecord4(state?.metadata);
2828
+ const id = opencodeToolId(
2829
+ name,
2830
+ part?.callID ?? part?.id ?? obj.id,
2831
+ metadata
2832
+ );
2461
2833
  const events = [{ type: "tool_use", id, name, input }];
2462
2834
  const output = state?.output;
2463
2835
  if (output != null || state?.status === "completed" || state?.status === "error") {
@@ -2471,6 +2843,53 @@ var opencodeAdapter = {
2471
2843
  }
2472
2844
  return events.length === 1 ? events[0] : events;
2473
2845
  }
2846
+ if (obj.type === "subtask_delta") {
2847
+ const parentId = str2(obj.childSessionID) ?? str2(obj.childSessionId);
2848
+ const delta = str2(obj.delta);
2849
+ if (parentId && delta) {
2850
+ return withTaskParent(
2851
+ parentId,
2852
+ withEventParentId({ type: "thinking", data: delta }, parentId)
2853
+ );
2854
+ }
2855
+ return null;
2856
+ }
2857
+ if (obj.type === "subtask_event") {
2858
+ const parentId = str2(obj.childSessionID) ?? str2(obj.childSessionId);
2859
+ const part = asRecord4(obj.part);
2860
+ if (!parentId || !part) return null;
2861
+ if (part.type === "text" && str2(part.text)) {
2862
+ return withTaskParent(
2863
+ parentId,
2864
+ withEventParentId({ type: "stdout", data: str2(part.text) }, parentId)
2865
+ );
2866
+ }
2867
+ if (part.type === "tool" || str2(part.tool)) {
2868
+ const name = str2(part.tool) ?? str2(part.name) ?? "tool";
2869
+ const id = str2(part.callID) ?? str2(part.id) ?? `${parentId}-${name}`;
2870
+ const state = asRecord4(part.state);
2871
+ const input = asRecord4(state?.input) ?? asRecord4(part.input);
2872
+ const nested = [
2873
+ withEventParentId({ type: "tool_use", id, name, input }, parentId)
2874
+ ];
2875
+ const output = state?.output ?? part.output;
2876
+ if (output != null || state?.status === "completed" || state?.status === "error") {
2877
+ nested.push(
2878
+ withEventParentId(
2879
+ {
2880
+ type: "tool_result",
2881
+ id,
2882
+ content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
2883
+ isError: state?.status === "error" || state?.status === "failed"
2884
+ },
2885
+ parentId
2886
+ )
2887
+ );
2888
+ }
2889
+ return withTaskParent(parentId, nested);
2890
+ }
2891
+ return null;
2892
+ }
2474
2893
  if (obj.type === "tool_result") {
2475
2894
  const part = obj.part;
2476
2895
  const id = part?.tool_use_id ?? part?.id ?? obj.tool_use_id ?? obj.id;
@@ -3004,6 +3423,13 @@ export {
3004
3423
  parseBrightsyCliLine,
3005
3424
  listBrightsyChatTargets,
3006
3425
  brightsyAdapter,
3426
+ toolDescription,
3427
+ applyAgentEvent,
3428
+ partsToAssistantText,
3429
+ stripBrightsyNdjsonNoise,
3430
+ isBrightsyNdjsonLine,
3431
+ finalizeParts,
3432
+ normalizeParseResult,
3007
3433
  sideboardMcpProfile,
3008
3434
  PLAN_MODE_INSTRUCTION,
3009
3435
  permissionMode,