@sideboard-ai/core 0.1.111 → 0.1.115

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 +29 -20
  2. package/dist/agents/cursor-runner.js +3 -3
  3. package/dist/{agents-NN22A4G5.js → agents-3X3EFCQY.js} +7 -7
  4. package/dist/{agents-GH3FWDW2.js → agents-AHAFC6FR.js} +10 -10
  5. package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
  6. package/dist/{chunk-KVFNTWFG.js → chunk-66XTXHR3.js} +244 -36
  7. package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
  8. package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
  9. package/dist/{chunk-NC3U42ZP.js → chunk-C6OBY6IC.js} +268 -27
  10. package/dist/{chunk-DMJKOFTO.js → chunk-DCNR7NAL.js} +39 -31
  11. package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
  12. package/dist/{chunk-2GO3YKBA.js → chunk-EKIDHL2T.js} +4 -4
  13. package/dist/{chunk-C4KHDW3U.js → chunk-FZCIQYNQ.js} +1 -1
  14. package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
  15. package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
  16. package/dist/{chunk-JTQQPJAU.js → chunk-MZ6HJ7VL.js} +47 -34
  17. package/dist/{chunk-363Z34PY.js → chunk-SLU5JVKD.js} +251 -217
  18. package/dist/{chunk-VOD3HFLP.js → chunk-XOYQ7LNQ.js} +2 -2
  19. package/dist/{chunk-7YKXHBIW.js → chunk-YMRT2DU6.js} +3 -3
  20. package/dist/{chunk-YXDR43ZC.js → chunk-ZMROW673.js} +5 -5
  21. package/dist/{chunk-YFAXVUY2.js → chunk-ZRCX43LS.js} +2 -2
  22. package/dist/{chunk-AROMOP3C.js → chunk-ZYEFCSZJ.js} +2 -2
  23. package/dist/{connected-teams-M5XNXRI5.js → connected-teams-O6D4PM7A.js} +2 -2
  24. package/dist/{connected-teams-J4I5AKMR.js → connected-teams-ZCOU6KCD.js} +2 -2
  25. package/dist/{coordinator-prompt-AR66L3N4.js → coordinator-prompt-4KCALEKD.js} +3 -3
  26. package/dist/{coordinator-prompt-BHMLWL64.js → coordinator-prompt-FML4I5AR.js} +3 -3
  27. package/dist/{global-workspace-XSUFEIAQ.js → global-workspace-CSWABOG5.js} +4 -4
  28. package/dist/{global-workspace-SKFODUQQ.js → global-workspace-H4YNASM6.js} +4 -4
  29. package/dist/index.cjs +787 -427
  30. package/dist/index.d.cts +53 -1
  31. package/dist/index.d.ts +53 -1
  32. package/dist/index.js +33 -15
  33. package/dist/mcp/run-stdio.cjs +906 -625
  34. package/dist/mcp/run-stdio.js +18 -14
  35. package/dist/{orchestrator-4T2SXDZ7.js → orchestrator-GKLYKLRC.js} +8 -8
  36. package/dist/{orchestrator-EP57AB5W.js → orchestrator-TXASYNHT.js} +10 -10
  37. package/dist/{run-XKTAJRWF.js → run-USF6FRKV.js} +3 -1
  38. package/dist/{run-CFKZPY7F.js → run-XQKGHQZ2.js} +3 -1
  39. package/dist/{workspaces-XAQVKTLO.js → workspaces-HJ3EVATC.js} +5 -5
  40. package/dist/{workspaces-HV3J4TTW.js → workspaces-QG6PGFQR.js} +5 -5
  41. package/dist/{worktree-XFJED3VU.js → worktree-IW3BX26B.js} +2 -2
  42. package/dist/{worktree-N2EV24EE.js → worktree-OTFQO2W7.js} +2 -2
  43. package/package.json +1 -1
@@ -4,11 +4,12 @@ import {
4
4
  ensureCliTeamTracked,
5
5
  ensureConnectedBrightsyTeamTokens,
6
6
  loadBrightsyConfig
7
- } from "./chunk-2GO3YKBA.js";
7
+ } from "./chunk-EKIDHL2T.js";
8
8
  import {
9
9
  isOrchestratorThread
10
- } from "./chunk-4EWPKYOU.js";
10
+ } from "./chunk-4OJMZ6P2.js";
11
11
  import {
12
+ applyAgentRunnerHeapEnv,
12
13
  applyNodeLaunch,
13
14
  cursorRipgrepEnv,
14
15
  extractJsonErrorMessage,
@@ -19,13 +20,13 @@ import {
19
20
  packagedMcpStdioPath,
20
21
  parseCursorRunnerLine,
21
22
  resolveNodeLaunch
22
- } from "./chunk-363Z34PY.js";
23
+ } from "./chunk-SLU5JVKD.js";
23
24
  import {
24
25
  codexUnattendedGitConfigArgs,
25
26
  mergeAgentGitAuthEnv,
26
27
  resolveAgentGitAuthEnv,
27
28
  resolveCodexGitWritableRoots
28
- } from "./chunk-C4KHDW3U.js";
29
+ } from "./chunk-FZCIQYNQ.js";
29
30
  import {
30
31
  claudeChromeEnabled,
31
32
  loadAppSettings,
@@ -45,7 +46,7 @@ import {
45
46
  resolveCommandBinarySync,
46
47
  run,
47
48
  withExportedPath
48
- } from "./chunk-LGXBYZZA.js";
49
+ } from "./chunk-DVM4ID64.js";
49
50
 
50
51
  // src/agents/brightsy.ts
51
52
  import { existsSync } from "fs";
@@ -582,9 +583,9 @@ function toolDescription(name, input) {
582
583
  if (/connectedAgentRequest/i.test(name)) {
583
584
  return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
584
585
  }
585
- if (desc && kind) return `${kind}: ${desc}`;
586
- if (desc) return desc;
587
- return "Subagent";
586
+ if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
587
+ if (desc) return `${desc}${subagentLiveSuffix(input)}`;
588
+ return `Subagent${subagentLiveSuffix(input)}`;
588
589
  }
589
590
  if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
590
591
  return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
@@ -609,13 +610,148 @@ function toolDescription(name, input) {
609
610
  }
610
611
  if (/grep/i.test(name)) return "Search files";
611
612
  if (/glob/i.test(name)) return "Find files";
613
+ const compact = n.replace(/[_-]/g, "");
614
+ if (/^taskoutput$/i.test(compact)) {
615
+ return str(input.task_id) ? `Wait for ${str(input.task_id)}` : "Wait for background task";
616
+ }
617
+ if (/^taskstop$/i.test(compact)) {
618
+ return str(input.task_id) ? `Stop ${str(input.task_id)}` : "Stop background task";
619
+ }
620
+ if (/^monitor$/i.test(compact)) {
621
+ const command = str(input.command);
622
+ return command ? `Watch ${command.length > 48 ? `${command.slice(0, 45)}\u2026` : command}` : "Watch command";
623
+ }
612
624
  return n;
613
625
  }
626
+ function subagentLiveSuffix(input) {
627
+ if (!input) return "";
628
+ const bits = [];
629
+ const status = str(input.live_status);
630
+ if (status && !/^runn(ing)?$|^working$/i.test(status)) bits.push(status);
631
+ if (typeof input.live_tool_uses === "number") bits.push(`${input.live_tool_uses} tools`);
632
+ if (typeof input.live_duration_ms === "number") {
633
+ bits.push(`${Math.max(0, Math.round(Number(input.live_duration_ms) / 1e3))}s`);
634
+ }
635
+ const last = str(input.live_last_tool);
636
+ if (last) bits.push(last);
637
+ return bits.length ? ` \xB7 ${bits.join(" \xB7 ")}` : "";
638
+ }
614
639
  function isSubagentToolName(name) {
615
640
  const n = (name ?? "").trim();
616
641
  if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
617
642
  return /connectedAgentRequest/i.test(n);
618
643
  }
644
+ function isPollWrapperToolName(name) {
645
+ const n = (name ?? "").replace(/[_-]/g, "");
646
+ return /^(taskoutput|taskstop|sleep)$/i.test(n);
647
+ }
648
+ function lastTextPart(parts, type) {
649
+ for (let i = parts.length - 1; i >= 0; i--) {
650
+ const p = parts[i];
651
+ if (p.type === type && p.text.trim()) return p.text.trim();
652
+ }
653
+ return "";
654
+ }
655
+ function toolLabel(tool) {
656
+ return tool.description || toolDescription(tool.name, tool.input) || tool.name;
657
+ }
658
+ function fileBasename(path) {
659
+ const parts = path.replace(/\/$/, "").split(/[/\\]/);
660
+ return parts[parts.length - 1] || path;
661
+ }
662
+ function classifyTool(name) {
663
+ const compact = name.replace(/^mcp__[^_]+__/, "").replace(/[_-]/g, "");
664
+ if (/bash|shell|terminal|^zsh$|^sh$/i.test(compact)) return "shell";
665
+ if (/grep|glob|search|ripgrep|findfiles|semsearch/i.test(compact)) return "search";
666
+ if (/^(read|cat)$/i.test(compact) || /^read/i.test(compact)) return "read";
667
+ if (/edit|write|apply|strreplace|multiedit|updatefile|createfile/i.test(compact)) {
668
+ return "edit";
669
+ }
670
+ return "other";
671
+ }
672
+ function toolActivityLine(parts) {
673
+ const tools = parts.filter((p) => {
674
+ if (p.type !== "tool" || p.parentId) return false;
675
+ if (isPollWrapperToolName(p.name)) return false;
676
+ if (/present_plan$/i.test(p.name ?? "")) return false;
677
+ if (/ask_user|AskUserQuestion/i.test(p.name ?? "")) return false;
678
+ return true;
679
+ });
680
+ if (tools.length === 0) return null;
681
+ const edited = [];
682
+ let reads = 0;
683
+ let searches = 0;
684
+ let shells = 0;
685
+ let others = 0;
686
+ let additions = 0;
687
+ let deletions = 0;
688
+ for (const tool of tools) {
689
+ const kind = classifyTool(tool.name);
690
+ if (kind === "edit") {
691
+ const path = tool.filePath ?? toolFilePath(tool.input);
692
+ edited.push({
693
+ name: path ? fileBasename(path) : tool.name,
694
+ running: tool.status === "running"
695
+ });
696
+ } else if (kind === "read") reads += 1;
697
+ else if (kind === "search") searches += 1;
698
+ else if (kind === "shell") shells += 1;
699
+ else others += 1;
700
+ if (typeof tool.additions === "number") additions += tool.additions;
701
+ if (typeof tool.deletions === "number") deletions += tool.deletions;
702
+ }
703
+ const bits = [];
704
+ const editing = edited.filter((e) => e.running);
705
+ const editedDone = edited.filter((e) => !e.running);
706
+ if (editing.length === 1) bits.push(`Editing ${editing[0].name}`);
707
+ else if (editing.length > 1) bits.push(`Editing ${editing.length} files`);
708
+ if (editedDone.length === 1) bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone[0].name}`);
709
+ else if (editedDone.length > 1) {
710
+ bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone.length} files`);
711
+ }
712
+ if (reads === 1) bits.push("explored 1 file");
713
+ else if (reads > 1) bits.push(`explored ${reads} files`);
714
+ if (searches === 1) bits.push("1 search");
715
+ else if (searches > 1) bits.push(`${searches} searches`);
716
+ if (shells === 1) bits.push("ran 1 command");
717
+ else if (shells > 1) bits.push(`ran ${shells} commands`);
718
+ if (others === 1) bits.push("1 tool");
719
+ else if (others > 1) bits.push(`${others} tools`);
720
+ if (bits.length === 0) return null;
721
+ return { text: bits.join(", "), additions, deletions };
722
+ }
723
+ function liveActivitySummary(parts, opts) {
724
+ if (opts?.queued && parts.length === 0) {
725
+ return "Queued \u2014 waiting for a slot";
726
+ }
727
+ const tools = parts.filter((p) => p.type === "tool");
728
+ const runningSubs = tools.filter(
729
+ (t) => t.status === "running" && !t.parentId && isSubagentToolName(t.name)
730
+ );
731
+ const runningNested = [...tools].reverse().find((t) => t.status === "running" && t.parentId && !isPollWrapperToolName(t.name));
732
+ const runningTop = [...tools].reverse().find(
733
+ (t) => t.status === "running" && !t.parentId && !isPollWrapperToolName(t.name) && !isSubagentToolName(t.name)
734
+ );
735
+ const runningPoll = [...tools].reverse().find((t) => t.status === "running" && isPollWrapperToolName(t.name));
736
+ const thinking = lastTextPart(parts, "thinking");
737
+ const text = lastTextPart(parts, "text");
738
+ if (runningSubs.length > 0) {
739
+ const heads = runningSubs.map(toolLabel);
740
+ const head = runningSubs.length === 1 ? heads[0] : `${runningSubs.length} subagents \xB7 ${heads.slice(0, 2).join(" \xB7 ")}`;
741
+ if (runningNested) return `${head} \xB7 ${toolLabel(runningNested)}`;
742
+ return head;
743
+ }
744
+ if (runningTop) return toolLabel(runningTop);
745
+ if (runningPoll) return toolLabel(runningPoll);
746
+ if (thinking) return thinking.length > 96 ? `\u2026${thinking.slice(-96)}` : thinking;
747
+ if (text) return "Writing reply\u2026";
748
+ const last = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? tools.at(-1);
749
+ if (last) {
750
+ const label = toolLabel(last);
751
+ return last.status === "running" ? label : `Finished ${label}`;
752
+ }
753
+ return "Working\u2026";
754
+ }
619
755
  function messagePartParentId(part) {
620
756
  if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
621
757
  return part.parentId;
@@ -701,6 +837,25 @@ function applyAgentEvent(parts, event) {
701
837
  const data = event.data;
702
838
  if (!data) return parts;
703
839
  const next = [...parts];
840
+ if (event.replace) {
841
+ for (let i = next.length - 1; i >= 0; i--) {
842
+ const prev = next[i];
843
+ if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
844
+ next[i] = {
845
+ type: "thinking",
846
+ text: data,
847
+ ...event.parentId ? { parentId: event.parentId } : {}
848
+ };
849
+ return next;
850
+ }
851
+ }
852
+ next.push({
853
+ type: "thinking",
854
+ text: data,
855
+ ...event.parentId ? { parentId: event.parentId } : {}
856
+ });
857
+ return next;
858
+ }
704
859
  const last = next[next.length - 1];
705
860
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
706
861
  next[next.length - 1] = {
@@ -724,14 +879,18 @@ function applyAgentEvent(parts, event) {
724
879
  if (existing >= 0) {
725
880
  const prev = parts[existing];
726
881
  const next = [...parts];
727
- const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
882
+ const mergedInput = {
883
+ ...prev.input ?? {},
884
+ ...input ?? {}
885
+ };
886
+ const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
728
887
  next[existing] = {
729
888
  ...prev,
730
889
  name: event.name || prev.name,
731
- input: mergedInput,
732
- description: toolDescription(event.name || prev.name, mergedInput),
733
- detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
734
- filePath: toolFilePath(mergedInput) ?? prev.filePath,
890
+ input: mergedRecord,
891
+ description: toolDescription(event.name || prev.name, mergedRecord),
892
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
893
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
735
894
  additions: diff.additions ?? prev.additions,
736
895
  deletions: diff.deletions ?? prev.deletions,
737
896
  parentId: event.parentId ?? prev.parentId
@@ -1014,6 +1173,7 @@ async function buildInjectedMcpServers(opts) {
1014
1173
  );
1015
1174
  } catch {
1016
1175
  }
1176
+ applyAgentRunnerHeapEnv(sideboard.env);
1017
1177
  servers.push(sideboard);
1018
1178
  }
1019
1179
  if (opts.includeBrightsy && isBrightsyConnected()) {
@@ -1169,8 +1329,14 @@ var BASE_ALLOWED_TOOLS = [
1169
1329
  "WebSearch",
1170
1330
  // Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
1171
1331
  "Task",
1172
- "Agent"
1332
+ "Agent",
1333
+ "TaskOutput",
1334
+ "TaskStop",
1335
+ "EnterWorktree",
1336
+ "ExitWorktree",
1337
+ "Skill"
1173
1338
  ];
1339
+ var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
1174
1340
  var CLAUDE_CHROME_ALLOWED_TOOLS = [
1175
1341
  "mcp__claude-in-chrome",
1176
1342
  "mcp__claude-in-chrome__*",
@@ -1274,6 +1440,80 @@ function claudeParentToolUseId(obj) {
1274
1440
  }
1275
1441
  return void 0;
1276
1442
  }
1443
+ function claudeString(obj, key) {
1444
+ const v = obj[key];
1445
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
1446
+ }
1447
+ function eventsFromClaudeSystem(obj) {
1448
+ const subtype = claudeString(obj, "subtype") ?? "";
1449
+ const parentId = claudeParentToolUseId(obj);
1450
+ if (subtype === "init") {
1451
+ if (parentId) return null;
1452
+ const sid = claudeString(obj, "session_id");
1453
+ return sid ? { type: "session_id", data: sid } : null;
1454
+ }
1455
+ if (subtype === "task_started") {
1456
+ const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
1457
+ if (!id) return null;
1458
+ const description = claudeString(obj, "description");
1459
+ const taskType = claudeString(obj, "task_type");
1460
+ const prompt = claudeString(obj, "prompt");
1461
+ return withEventParentId(
1462
+ {
1463
+ type: "tool_use",
1464
+ id,
1465
+ name: taskType || "Agent",
1466
+ input: {
1467
+ ...description ? { description } : {},
1468
+ ...prompt ? { prompt } : {},
1469
+ ...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
1470
+ }
1471
+ },
1472
+ parentId
1473
+ );
1474
+ }
1475
+ if (subtype === "task_notification") {
1476
+ const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
1477
+ if (!id) return null;
1478
+ const status = claudeString(obj, "status") ?? "working";
1479
+ const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
1480
+ const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
1481
+ const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
1482
+ const snapshot = [
1483
+ status,
1484
+ tools != null ? `${tools} tools` : null,
1485
+ durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
1486
+ lastTool
1487
+ ].filter((bit) => Boolean(bit)).join(" \xB7 ");
1488
+ return [
1489
+ {
1490
+ type: "tool_use",
1491
+ id,
1492
+ name: claudeString(obj, "task_type") || "Agent",
1493
+ input: {
1494
+ live_status: status,
1495
+ ...tools != null ? { live_tool_uses: tools } : {},
1496
+ ...durationMs != null ? { live_duration_ms: durationMs } : {},
1497
+ ...lastTool ? { live_last_tool: lastTool } : {}
1498
+ }
1499
+ },
1500
+ withEventParentId(
1501
+ { type: "thinking", data: snapshot, replace: true },
1502
+ id
1503
+ )
1504
+ ];
1505
+ }
1506
+ if (subtype === "api_retry") {
1507
+ const attempt = obj.attempt;
1508
+ const max = obj.max_retries;
1509
+ const delay = obj.retry_delay_ms;
1510
+ return {
1511
+ type: "thinking",
1512
+ data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
1513
+ };
1514
+ }
1515
+ return null;
1516
+ }
1277
1517
  var claudeAdapter = {
1278
1518
  kind: "claude",
1279
1519
  async detect() {
@@ -1328,7 +1568,7 @@ var claudeAdapter = {
1328
1568
  );
1329
1569
  }
1330
1570
  const mode = permissionMode(thread);
1331
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-XSUFEIAQ.js");
1571
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-CSWABOG5.js");
1332
1572
  const isOrchestrator = isOrchestratorThread2(thread);
1333
1573
  const injectedServers = await buildInjectedMcpServers({
1334
1574
  includeSideboard: true,
@@ -1396,7 +1636,12 @@ var claudeAdapter = {
1396
1636
  stdin: useStdin ? `${promptText}
1397
1637
  ` : void 0,
1398
1638
  // Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
1399
- env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
1639
+ // Raise the -p background-agent wait so long TaskOutput polls are not
1640
+ // abandoned at Claude Code’s 10-minute default.
1641
+ env: {
1642
+ CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
1643
+ CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
1644
+ }
1400
1645
  };
1401
1646
  },
1402
1647
  parseEvent(line) {
@@ -1404,13 +1649,8 @@ var claudeAdapter = {
1404
1649
  if (!trimmed) return null;
1405
1650
  try {
1406
1651
  const obj = JSON.parse(trimmed);
1407
- if (obj.type === "system" && obj.subtype === "init") {
1408
- const sid = obj.session_id;
1409
- if (typeof sid === "string") return { type: "session_id", data: sid };
1410
- return null;
1411
- }
1412
- if (obj.type === "system" && typeof obj.session_id === "string") {
1413
- return { type: "session_id", data: obj.session_id };
1652
+ if (obj.type === "system") {
1653
+ return eventsFromClaudeSystem(obj);
1414
1654
  }
1415
1655
  if (obj.type === "assistant" || obj.type === "user") {
1416
1656
  const parentId = claudeParentToolUseId(obj);
@@ -1840,9 +2080,6 @@ var codexAdapter = {
1840
2080
  if (sid && (type === "thread.started" || type === "session" || !type)) {
1841
2081
  return { type: "session_id", data: sid };
1842
2082
  }
1843
- if (sid && type.endsWith(".started")) {
1844
- return { type: "session_id", data: sid };
1845
- }
1846
2083
  if (type === "turn.completed" || type === "turn_completed") {
1847
2084
  const usage = usageFromCodex(obj.usage);
1848
2085
  return usage ? { type: "usage", data: usage, scope: "turn" } : null;
@@ -2246,7 +2483,8 @@ var opencodeAdapter = {
2246
2483
  return { type: "stderr", data: detail };
2247
2484
  }
2248
2485
  const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
2249
- if (sid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
2486
+ const childSid = str2(obj.childSessionID) ?? str2(obj.childSessionId) ?? str2(obj.parentID) ?? str2(obj.parentId);
2487
+ if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
2250
2488
  return { type: "session_id", data: sid };
2251
2489
  }
2252
2490
  if (obj.type === "text") {
@@ -2868,6 +3106,9 @@ export {
2868
3106
  toolDetail,
2869
3107
  toolDescription,
2870
3108
  isSubagentToolName,
3109
+ isPollWrapperToolName,
3110
+ toolActivityLine,
3111
+ liveActivitySummary,
2871
3112
  messagePartParentId,
2872
3113
  withEventParentId,
2873
3114
  withEventsParentId,
@@ -7,7 +7,9 @@ import {
7
7
  finalizeParts,
8
8
  getAdapter,
9
9
  isBrightsyNdjsonLine,
10
+ isPollWrapperToolName,
10
11
  isSessionQuotaLimit,
12
+ liveActivitySummary,
11
13
  normalizeParseResult,
12
14
  parseBrightsyCliLine,
13
15
  parseSessionQuotaResetAt,
@@ -15,13 +17,13 @@ import {
15
17
  resolveQuotaFallbackAgent,
16
18
  stripBrightsyNdjsonNoise,
17
19
  toolDescription
18
- } from "./chunk-NC3U42ZP.js";
20
+ } from "./chunk-C6OBY6IC.js";
19
21
  import {
20
22
  addWorkspace,
21
23
  ensureWorkspace,
22
24
  removeWorkspace,
23
25
  syncWorkspacesFromThreads
24
- } from "./chunk-7KWYXGIU.js";
26
+ } from "./chunk-K3TIQXOH.js";
25
27
  import {
26
28
  assertOrchestratorCapableAgent,
27
29
  coerceOrchestratorAgent,
@@ -34,14 +36,14 @@ import {
34
36
  isOrchestratorThread,
35
37
  isSlackCoordinatorThread,
36
38
  orchestratorSessionPoisonedByBuiltins
37
- } from "./chunk-4EWPKYOU.js";
39
+ } from "./chunk-4OJMZ6P2.js";
38
40
  import {
39
41
  SLACK_REPLY_FORMATTING,
40
42
  coordinatorSystemPrompt,
41
43
  coordinatorTurnReminder,
42
44
  enrichWorkspacesWithGithub,
43
45
  ensureGlobalCoordinatorCwd
44
- } from "./chunk-KQBI5HNT.js";
46
+ } from "./chunk-7WC5UWEB.js";
45
47
  import {
46
48
  extractPresentedPlan,
47
49
  readPlanFile,
@@ -49,17 +51,19 @@ import {
49
51
  } from "./chunk-QTUESPAW.js";
50
52
  import {
51
53
  createAgentStreamCoalescer
52
- } from "./chunk-WIHKHR5R.js";
54
+ } from "./chunk-AXQ4ZWHK.js";
53
55
  import {
56
+ applyAgentRunnerHeapEnv,
54
57
  fallbackTurnFailDetail,
55
58
  formatTurnExitError,
56
59
  looksLikeAgentFailureMessage,
57
60
  looksLikeInvalidAgentSession,
61
+ looksLikeV8Oom,
58
62
  pushTurnStderr,
59
63
  shouldRetryFailedAgentTurn,
60
64
  summarizeTurnStderr,
61
65
  turnFailChatText
62
- } from "./chunk-363Z34PY.js";
66
+ } from "./chunk-SLU5JVKD.js";
63
67
  import {
64
68
  releaseCaffeinateHoldForThread
65
69
  } from "./chunk-DCOZABNT.js";
@@ -105,7 +109,7 @@ import {
105
109
  threadDisplayLabel,
106
110
  withRepoGitLock,
107
111
  worktreeNameFromPath
108
- } from "./chunk-C4KHDW3U.js";
112
+ } from "./chunk-FZCIQYNQ.js";
109
113
  import {
110
114
  ATTACHMENTS_DIR,
111
115
  LEGACY_ATTACHMENTS_DIR,
@@ -155,11 +159,13 @@ import {
155
159
  worktreesRoot
156
160
  } from "./chunk-QZQEXME2.js";
157
161
  import {
162
+ clearStaleIndexLocks,
158
163
  enrichPathWithNpmGlobalBin,
159
164
  ensureAgentPath,
160
165
  git,
166
+ resolveGitDirsForLockRecovery,
161
167
  run
162
- } from "./chunk-LGXBYZZA.js";
168
+ } from "./chunk-DVM4ID64.js";
163
169
 
164
170
  // src/orchestrator/orchestrator.ts
165
171
  import { EventEmitter } from "events";
@@ -749,9 +755,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
749
755
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
750
756
  );
751
757
  }
752
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-XSUFEIAQ.js");
758
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-CSWABOG5.js");
753
759
  if (isGlobalThread2(thread)) {
754
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-AR66L3N4.js");
760
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-4KCALEKD.js");
755
761
  ensureGlobalCoordinatorCwd2(
756
762
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
757
763
  );
@@ -768,6 +774,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
768
774
  }
769
775
  const env = childEnvWithAppSettings(cmd.env);
770
776
  applyPromptCacheTtlEnv(thread.agent, env);
777
+ applyAgentRunnerHeapEnv(env);
771
778
  try {
772
779
  if (isOrchestratorThread(thread)) {
773
780
  mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
@@ -2448,7 +2455,7 @@ async function createThread(input, _onSetupLine) {
2448
2455
  return readThread(thread.id) ?? thread;
2449
2456
  }
2450
2457
  async function listLinearIssues(agent, repoPath) {
2451
- const { getAdapter: getAdapter2 } = await import("./agents-NN22A4G5.js");
2458
+ const { getAdapter: getAdapter2 } = await import("./agents-3X3EFCQY.js");
2452
2459
  await requireAgent(agent, { requireLinear: true });
2453
2460
  const adapter = getAdapter2(agent);
2454
2461
  if (!adapter.listLinearIssues) {
@@ -2496,21 +2503,13 @@ function summarizeTurnLive(parts) {
2496
2503
  (p) => p.type === "tool"
2497
2504
  );
2498
2505
  const lastTool = tools[tools.length - 1];
2499
- const lastToolLabel = lastTool ? lastTool.description || toolDescription(lastTool.name, lastTool.input) || lastTool.name : void 0;
2500
- const running = lastTool?.status === "running";
2506
+ const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
2507
+ const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
2501
2508
  const thinking = lastText(parts, "thinking");
2502
2509
  const text = lastText(parts, "text");
2503
2510
  const excerptRaw = thinking || text;
2504
2511
  const excerpt = excerptRaw.length > 280 ? `${excerptRaw.slice(-280)}` : excerptRaw || void 0;
2505
- let summary = "Working\u2026";
2506
- if (lastToolLabel) {
2507
- const verb = running ? lastToolLabel : `Finished ${lastToolLabel}`;
2508
- summary = tools.length > 1 ? `${verb} (${tools.length} tools)` : verb;
2509
- } else if (thinking) {
2510
- summary = "Thinking\u2026";
2511
- } else if (text) {
2512
- summary = "Writing reply\u2026";
2513
- }
2512
+ const summary = liveActivitySummary(parts);
2514
2513
  return {
2515
2514
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2516
2515
  summary,
@@ -2822,7 +2821,7 @@ async function adoptThread(input) {
2822
2821
  throw new Error(`Worktree not found: ${input.worktreePath}`);
2823
2822
  }
2824
2823
  const repoPath = await resolveRepoRoot(input.worktreePath);
2825
- const { stdout: branch } = await import("./run-CFKZPY7F.js").then(
2824
+ const { stdout: branch } = await import("./run-XQKGHQZ2.js").then(
2826
2825
  ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
2827
2826
  );
2828
2827
  const thread = createEmptyThread({
@@ -2837,7 +2836,7 @@ async function adoptThread(input) {
2837
2836
  messages: input.messages ?? []
2838
2837
  });
2839
2838
  writeThread(thread);
2840
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-HV3J4TTW.js");
2839
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-QG6PGFQR.js");
2841
2840
  await ensureWorkspace2(repoPath);
2842
2841
  return thread;
2843
2842
  }
@@ -4147,7 +4146,7 @@ async function confirmLand(thread, opts) {
4147
4146
  if (preview.dirty) {
4148
4147
  committed = await commitAll(thread.worktreePath, meta.commitMessage);
4149
4148
  }
4150
- const { git: git2 } = await import("./run-CFKZPY7F.js");
4149
+ const { git: git2 } = await import("./run-XQKGHQZ2.js");
4151
4150
  const { stdout: headOut } = await git2(
4152
4151
  ["rev-parse", "--abbrev-ref", "HEAD"],
4153
4152
  thread.worktreePath,
@@ -5109,7 +5108,7 @@ function formatScheduledPrompt(name, prompt) {
5109
5108
  ${prompt}`;
5110
5109
  }
5111
5110
  async function defaultDeps() {
5112
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-EP57AB5W.js");
5111
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-TXASYNHT.js");
5113
5112
  const orch = getOrchestrator2();
5114
5113
  return {
5115
5114
  findThread: (id) => findThreadByRef(id),
@@ -5901,7 +5900,15 @@ var Orchestrator = class {
5901
5900
  hasSession: Boolean(this.requireThread(threadId).sessionId)
5902
5901
  })) {
5903
5902
  updateThread(threadId, { sessionId: null });
5904
- const retryNote = looksLikeInvalidAgentSession(detail) ? "Agent session missing \u2014 starting a fresh session" : "Agent runner crashed \u2014 restarting Node once";
5903
+ try {
5904
+ const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
5905
+ const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
5906
+ if (clearedLocks.length > 0) {
5907
+ pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
5908
+ }
5909
+ } catch {
5910
+ }
5911
+ const retryNote = looksLikeInvalidAgentSession(detail) ? "Agent session missing \u2014 starting a fresh session" : looksLikeV8Oom(detail) ? "Agent ran out of memory \u2014 starting a fresh session" : "Agent runner crashed \u2014 restarting Node once";
5905
5912
  pushTurnStderr(stderrTail, retryNote);
5906
5913
  this.emit({
5907
5914
  type: "turn_output",
@@ -6373,13 +6380,14 @@ var Orchestrator = class {
6373
6380
  const text = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
6374
6381
  const stillRunning = thread.status === "running" || thread.status === "queued";
6375
6382
  const live = stillRunning ? readTurnLive(thread.id) : null;
6383
+ const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
6376
6384
  return {
6377
6385
  text,
6378
6386
  status: thread.status,
6379
6387
  sessionId: thread.sessionId,
6380
6388
  lastError,
6381
6389
  stillRunning,
6382
- progress: live?.summary ?? null,
6390
+ progress: live?.summary ?? queuedHint,
6383
6391
  lastActivityAt: live?.updatedAt ?? null
6384
6392
  };
6385
6393
  }
@@ -6848,7 +6856,7 @@ var Orchestrator = class {
6848
6856
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
6849
6857
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
6850
6858
  try {
6851
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-HV3J4TTW.js");
6859
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-QG6PGFQR.js");
6852
6860
  await ensureWorkspace2(thread.repoPath);
6853
6861
  } catch {
6854
6862
  }
@@ -6902,7 +6910,7 @@ var Orchestrator = class {
6902
6910
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
6903
6911
  );
6904
6912
  }
6905
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-XFJED3VU.js");
6913
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-IW3BX26B.js");
6906
6914
  const slug = thread.worktreePath.split("/").pop();
6907
6915
  const dest = thread.worktreePath;
6908
6916
  await withRepoGitLock(thread.repoPath, async () => {
@@ -7010,7 +7018,7 @@ async function startOrchestration(opts) {
7010
7018
  sourceRef: "default",
7011
7019
  ...createOpts
7012
7020
  }).catch(async () => {
7013
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-XFJED3VU.js");
7021
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-IW3BX26B.js");
7014
7022
  const repo = await resolveRepoRoot2(repoPath);
7015
7023
  const def = await resolveDefaultBranch2(repo);
7016
7024
  return orch.createThread({