@sideboard-ai/core 0.1.324 → 0.1.325

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 (83) hide show
  1. package/dist/{abletime-5ZY3ZUUO.js → abletime-M7STTMZT.js} +6 -5
  2. package/dist/{abletime-CU2UPMJF.js → abletime-VL234MCP.js} +5 -4
  3. package/dist/{abletime-oauth-7EOSBEFM.js → abletime-oauth-LMMGMAPA.js} +3 -3
  4. package/dist/{abletime-oauth-4TTCR3CT.js → abletime-oauth-P4ZFBEAL.js} +3 -3
  5. package/dist/{abletime-rest-3TG4G7LW.js → abletime-rest-DLV7EIWS.js} +3 -3
  6. package/dist/{abletime-rest-KOKE7V4B.js → abletime-rest-GOI7HELR.js} +3 -3
  7. package/dist/agents/claude-runner.cjs +59 -22
  8. package/dist/agents/claude-runner.js +39 -16
  9. package/dist/agents/cursor-runner.cjs +96 -31
  10. package/dist/agents/cursor-runner.js +74 -24
  11. package/dist/{agents-YK65UDLT.js → agents-LDRM3BTY.js} +9 -8
  12. package/dist/{agents-LUSTCMDN.js → agents-MBIEAETM.js} +12 -11
  13. package/dist/{app-settings-I5HM5RMP.js → app-settings-E7DMMEKC.js} +1 -1
  14. package/dist/{app-settings-XIF4EC4K.js → app-settings-UQHUNOLV.js} +1 -1
  15. package/dist/{chunk-INBUV7HY.js → chunk-2UP3XD2D.js} +2 -2
  16. package/dist/{chunk-EQ52JR3Q.js → chunk-5MXLDDYF.js} +1 -1
  17. package/dist/{chunk-NCHOTN3C.js → chunk-5YCKATG6.js} +4 -3
  18. package/dist/{chunk-BYUCNIXK.js → chunk-7G27TB4M.js} +6 -6
  19. package/dist/chunk-7LUOLYFM.js +1445 -0
  20. package/dist/{chunk-Y3WREIPQ.js → chunk-A76MKMSF.js} +12 -210
  21. package/dist/{chunk-JE3JLHMO.js → chunk-APKUI4BP.js} +3 -3
  22. package/dist/{chunk-FR3SAYUL.js → chunk-AQEKPJWU.js} +5 -5
  23. package/dist/{chunk-QOS4465Y.js → chunk-BOFYI6LC.js} +1 -1
  24. package/dist/{chunk-FUFNMUNR.js → chunk-BTF3ATST.js} +7 -8
  25. package/dist/{chunk-OIHRC2ZJ.js → chunk-CI4M54LS.js} +22 -2
  26. package/dist/chunk-DBKHL7NC.js +214 -0
  27. package/dist/{chunk-ROOZDDFA.js → chunk-EO6ZFLG6.js} +7 -8
  28. package/dist/chunk-EZR6W4B3.js +1259 -0
  29. package/dist/{chunk-MZIZTSR2.js → chunk-F65JMKUR.js} +2 -2
  30. package/dist/chunk-F6GE7V3Q.js +216 -0
  31. package/dist/{chunk-7MQSYPAY.js → chunk-GNLKBS3U.js} +206 -188
  32. package/dist/{chunk-EKU7FQVG.js → chunk-H36GKGU2.js} +2 -2
  33. package/dist/{chunk-7D5QIU3N.js → chunk-HG6KS7OT.js} +294 -265
  34. package/dist/chunk-MBT6WDAB.js +28 -0
  35. package/dist/{chunk-JH5SMVM5.js → chunk-MFMDZAA6.js} +262 -233
  36. package/dist/{chunk-7PVT73H6.js → chunk-NWGINMEA.js} +12 -210
  37. package/dist/{chunk-QIC2JXHW.js → chunk-OOXRMTU6.js} +1 -1
  38. package/dist/{chunk-5XNT6BCG.js → chunk-OPXEJJBM.js} +1 -1
  39. package/dist/chunk-OYRN356W.js +80 -0
  40. package/dist/chunk-PPTJMBUY.js +25 -0
  41. package/dist/{chunk-B4CDSSRN.js → chunk-Q3FHTGIW.js} +2 -0
  42. package/dist/{chunk-EJ66LEKH.js → chunk-RZJTGBXY.js} +22 -2
  43. package/dist/{chunk-DF5BM5OY.js → chunk-SACHHTBJ.js} +207 -186
  44. package/dist/{chunk-5GDJSFCT.js → chunk-SK6NYGPD.js} +2 -2
  45. package/dist/{chunk-74OPNF7U.js → chunk-SQQBU7Z6.js} +2 -2
  46. package/dist/{chunk-Q3YJZPQI.js → chunk-SS6CYGLF.js} +3 -3
  47. package/dist/{chunk-YDUHLWI5.js → chunk-SUZOPJZC.js} +21 -7
  48. package/dist/{chunk-ZHGMRBSC.js → chunk-U5WO6MEB.js} +3 -3
  49. package/dist/{chunk-NXUN4U5P.js → chunk-VAFQS4D2.js} +2 -2
  50. package/dist/chunk-W3ZLE4PO.js +77 -0
  51. package/dist/{chunk-RR4WCGNB.js → chunk-WYEST76H.js} +7 -7
  52. package/dist/{chunk-ODH3XHMI.js → chunk-ZEUMWHOH.js} +5 -5
  53. package/dist/{chunk-ZIRQZUZY.js → chunk-ZHDXLDLA.js} +3 -3
  54. package/dist/{chunk-IFWGG2M2.js → chunk-ZSHS46V5.js} +2 -0
  55. package/dist/{conductor-JFABMXDA.js → conductor-D4KFZF54.js} +6 -6
  56. package/dist/{conductor-SPZOTC7W.js → conductor-KB7L7NQN.js} +7 -7
  57. package/dist/{coordinator-prompt-K66RGNWK.js → coordinator-prompt-OBXEC63K.js} +4 -4
  58. package/dist/{coordinator-prompt-Z6UFHFDH.js → coordinator-prompt-SUO4FRY3.js} +4 -4
  59. package/dist/{cursor-recover-TEBFKAZ4.js → cursor-recover-7F46PAJ5.js} +1 -1
  60. package/dist/{cursor-recover-OWPQUHFH.js → cursor-recover-BDIAZIE3.js} +1 -1
  61. package/dist/{global-workspace-A6UO6PJV.js → global-workspace-UHU2FXTY.js} +4 -4
  62. package/dist/{global-workspace-RHEO55B4.js → global-workspace-Z2SURNHA.js} +4 -4
  63. package/dist/index.cjs +21112 -20864
  64. package/dist/index.d.cts +25 -9
  65. package/dist/index.d.ts +25 -9
  66. package/dist/index.js +343 -1678
  67. package/dist/linear-HFUOUJ5H.js +67 -0
  68. package/dist/linear-SIHEBU3X.js +69 -0
  69. package/dist/linear-list-63I7QUC6.js +6 -0
  70. package/dist/linear-list-JFV3EES6.js +8 -0
  71. package/dist/mcp/run-stdio.cjs +15654 -15398
  72. package/dist/mcp/run-stdio.js +67 -1247
  73. package/dist/{optional-cli-RMMS5L6F.js → optional-cli-U2GUA2X6.js} +3 -3
  74. package/dist/{optional-cli-Y3Z3GIPZ.js → optional-cli-ULDP3O5S.js} +4 -4
  75. package/dist/{orchestrator-7VTAUY24.js → orchestrator-3H4KNGPN.js} +15 -13
  76. package/dist/{orchestrator-2O6OJQLX.js → orchestrator-6ROMEWBP.js} +14 -12
  77. package/dist/{thread-store-3F7GR64A.js → thread-store-4ZN3DS2W.js} +1 -1
  78. package/dist/{thread-store-JRSL4HQY.js → thread-store-IC4BQXDW.js} +1 -1
  79. package/dist/{workspaces-NRKEXOYR.js → workspaces-MG5JHRKW.js} +4 -4
  80. package/dist/{workspaces-42E6AGXD.js → workspaces-QJNKEGEM.js} +4 -4
  81. package/dist/{worktree-ZDA2UJ7C.js → worktree-KSJPTHGZ.js} +3 -3
  82. package/dist/{worktree-4NGXCCUO.js → worktree-MYJYUHZM.js} +3 -3
  83. package/package.json +1 -1
@@ -1,9 +1,16 @@
1
+ import {
2
+ formatOptionalServicesDirectiveForTurn,
3
+ formatOptionalServicesReminderForTurn
4
+ } from "./chunk-2UP3XD2D.js";
1
5
  import {
2
6
  extractPresentedPlan,
3
7
  isPresentPlanToolName,
4
8
  readPlanFile,
5
9
  writePlanFile
6
10
  } from "./chunk-PGPSIEMW.js";
11
+ import {
12
+ issueActivityKind
13
+ } from "./chunk-W3ZLE4PO.js";
7
14
  import {
8
15
  SIDEBOARD_THREAD_ID_ENV,
9
16
  adjustBrightsyTurnExit,
@@ -14,7 +21,7 @@ import {
14
21
  parseSessionQuotaResetAt,
15
22
  planModeTurnInstruction,
16
23
  resolveQuotaFallbackAgent
17
- } from "./chunk-JH5SMVM5.js";
24
+ } from "./chunk-MFMDZAA6.js";
18
25
  import {
19
26
  applyWorktreePkgCacheEnv,
20
27
  askBlockStillWaiting,
@@ -52,7 +59,7 @@ import {
52
59
  worktreeDevProcessKey,
53
60
  worktreeRunProcessKey,
54
61
  worktreeSetupProcessKey
55
- } from "./chunk-RR4WCGNB.js";
62
+ } from "./chunk-WYEST76H.js";
56
63
  import {
57
64
  applyAgentEvent,
58
65
  clipAgentEventForPaint,
@@ -67,14 +74,10 @@ import {
67
74
  partsToAssistantText,
68
75
  stripBrightsyNdjsonNoise,
69
76
  toolDescription
70
- } from "./chunk-QIC2JXHW.js";
77
+ } from "./chunk-OOXRMTU6.js";
71
78
  import {
72
79
  titleFromPrompt
73
80
  } from "./chunk-7H655NEW.js";
74
- import {
75
- formatOptionalServicesDirectiveForTurn,
76
- formatOptionalServicesReminderForTurn
77
- } from "./chunk-INBUV7HY.js";
78
81
  import {
79
82
  SLACK_REPLY_FORMATTING,
80
83
  addWorkspace,
@@ -99,7 +102,7 @@ import {
99
102
  stageAbsolutePathsAsAttachments,
100
103
  stageBuffersAsAttachments,
101
104
  syncWorkspacesFromThreads
102
- } from "./chunk-JE3JLHMO.js";
105
+ } from "./chunk-APKUI4BP.js";
103
106
  import {
104
107
  addPrStackLayer,
105
108
  allocateTeamSlug,
@@ -150,7 +153,7 @@ import {
150
153
  resolveRepoRoot,
151
154
  switchWorktreeBranch,
152
155
  withRepoGitLock
153
- } from "./chunk-FUFNMUNR.js";
156
+ } from "./chunk-BTF3ATST.js";
154
157
  import {
155
158
  REVIEW_TAB_TITLE,
156
159
  agentNicknameFromWorktreePath,
@@ -178,7 +181,7 @@ import {
178
181
  worktreeNameFromPath,
179
182
  worktreeSlugForTicket,
180
183
  writeThread
181
- } from "./chunk-IFWGG2M2.js";
184
+ } from "./chunk-ZSHS46V5.js";
182
185
  import {
183
186
  mcpServerIdForPermission,
184
187
  mcpServerPermissionUpdate
@@ -189,7 +192,7 @@ import {
189
192
  import {
190
193
  applyAgentRunnerHeapEnv,
191
194
  packagedMcpDir
192
- } from "./chunk-ZHGMRBSC.js";
195
+ } from "./chunk-U5WO6MEB.js";
193
196
  import {
194
197
  fallbackTurnFailDetail,
195
198
  formatAgentErrorContinuePrompt,
@@ -204,7 +207,7 @@ import {
204
207
  shouldRetryFailedAgentTurn,
205
208
  summarizeTurnStderr,
206
209
  turnFailChatText
207
- } from "./chunk-5XNT6BCG.js";
210
+ } from "./chunk-OPXEJJBM.js";
208
211
  import {
209
212
  clearStaleIndexLocks,
210
213
  enrichPathWithNpmGlobalBin,
@@ -242,13 +245,14 @@ import {
242
245
  resolveNewThreadOptions,
243
246
  resolveOrchestratorDefaults,
244
247
  resolveViewerProfileForRepo,
248
+ subtractUsage,
245
249
  sumUsageList,
246
250
  updateAdvancedSettings,
247
251
  updateAppEnvironment,
248
252
  usageOnLimit,
249
253
  withTurnScopedCost,
250
254
  writeViewerContext
251
- } from "./chunk-EJ66LEKH.js";
255
+ } from "./chunk-RZJTGBXY.js";
252
256
  import {
253
257
  normalizeThinkingEffort
254
258
  } from "./chunk-77WWLBCI.js";
@@ -325,9 +329,50 @@ import { randomUUID as randomUUID5 } from "crypto";
325
329
  import { existsSync as existsSync14 } from "fs";
326
330
 
327
331
  // src/agents/spawn.ts
332
+ import { rmSync } from "fs";
328
333
  import { createInterface } from "readline";
329
334
  import { execa } from "execa";
330
335
 
336
+ // src/orchestrator/agent-pid.ts
337
+ import { execFileSync } from "child_process";
338
+ function pidStartedAt(pid) {
339
+ if (!Number.isFinite(pid) || pid <= 0 || process.platform === "win32") return null;
340
+ try {
341
+ const out = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], {
342
+ encoding: "utf8",
343
+ timeout: 1e3,
344
+ stdio: ["ignore", "pipe", "ignore"]
345
+ }).trim();
346
+ return out || null;
347
+ } catch {
348
+ return null;
349
+ }
350
+ }
351
+ function isSameAgentProcess(pid, startedAt, alive) {
352
+ if (!alive) return false;
353
+ if (!startedAt) return true;
354
+ const now = pidStartedAt(pid);
355
+ if (!now) return true;
356
+ return now === startedAt;
357
+ }
358
+ function isPidAlive(pid) {
359
+ if (!Number.isFinite(pid) || pid <= 0) return false;
360
+ try {
361
+ process.kill(pid, 0);
362
+ return true;
363
+ } catch {
364
+ return false;
365
+ }
366
+ }
367
+ async function waitForPidExit(pid, timeoutMs) {
368
+ const start = Date.now();
369
+ while (isPidAlive(pid)) {
370
+ if (Date.now() - start >= timeoutMs) return false;
371
+ await new Promise((r) => setTimeout(r, 80));
372
+ }
373
+ return true;
374
+ }
375
+
331
376
  // src/agents/turn-trace.ts
332
377
  import { appendFileSync } from "fs";
333
378
  import { join } from "path";
@@ -473,9 +518,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
473
518
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
474
519
  );
475
520
  }
476
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-RHEO55B4.js");
521
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-Z2SURNHA.js");
477
522
  if (isGlobalThread2(thread)) {
478
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-K66RGNWK.js");
523
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-OBXEC63K.js");
479
524
  ensureGlobalCoordinatorCwd2(
480
525
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
481
526
  );
@@ -550,8 +595,13 @@ async function spawnAgentTurn(thread, input, onEvent) {
550
595
  cwd: cmd.cwd,
551
596
  env,
552
597
  reject: false,
598
+ // readline consumes both streams. The default buffer (100 MB) keeps a
599
+ // second copy and SIGTERMs the agent when a long stream-json turn exceeds it.
600
+ buffer: false,
553
601
  stdout: "pipe",
554
602
  stderr: "pipe",
603
+ // Own process group so Stop can signal MCP servers and shells the CLI spawned.
604
+ detached: process.platform !== "win32",
555
605
  // Claude stream-json turns write a user message to stdin; otherwise ignore
556
606
  // so Claude doesn't wait ~3s for an empty pipe.
557
607
  stdin: cmd.stdin != null ? "pipe" : "ignore"
@@ -565,50 +615,66 @@ async function spawnAgentTurn(thread, input, onEvent) {
565
615
  let assistantText = "";
566
616
  let parts = [];
567
617
  let usage = null;
618
+ const usageByMessageId = /* @__PURE__ */ new Map();
568
619
  const outbound = createAgentStreamCoalescer(onEvent);
569
620
  const consume = (stream, kind) => {
570
621
  if (!stream) return;
571
622
  const rl = createInterface({ input: stream, crlfDelay: Infinity });
572
623
  rl.on("line", (line) => {
573
- if (kind === "stderr") {
574
- outbound.push({ type: "stderr", data: line });
575
- return;
576
- }
577
- let events = normalizeParseResult(adapter.parseEvent(line));
578
- if (thread.agent === "brightsy" && kind === "stdout" && isBrightsyNdjsonLine(line)) {
579
- const dumped = events.some(
580
- (e) => e.type === "stdout" && isBrightsyNdjsonLine(e.data)
581
- );
582
- if (events.length === 0 || dumped) {
583
- events = normalizeParseResult(parseBrightsyCliLine(line));
584
- }
585
- }
586
- for (const event of events) {
587
- let parsed = event;
588
- if (parsed.type === "session_id") {
589
- sessionId = parsed.data;
590
- outbound.push(parsed);
591
- continue;
624
+ try {
625
+ if (kind === "stderr") {
626
+ outbound.push({ type: "stderr", data: line });
627
+ return;
592
628
  }
593
- if (parsed.type === "usage") {
594
- const data = parsed.scope === "turn" ? withTurnScopedCost(parsed.data, thread.messages) : parsed.data;
595
- usage = applyTurnUsage(usage, data, parsed.scope ?? "request");
596
- outbound.push({ ...parsed, data });
597
- continue;
629
+ let events = normalizeParseResult(adapter.parseEvent(line));
630
+ if (thread.agent === "brightsy" && kind === "stdout" && isBrightsyNdjsonLine(line)) {
631
+ const dumped = events.some(
632
+ (e) => e.type === "stdout" && isBrightsyNdjsonLine(e.data)
633
+ );
634
+ if (events.length === 0 || dumped) {
635
+ events = normalizeParseResult(parseBrightsyCliLine(line));
636
+ }
598
637
  }
599
- if (parsed.type === "stdout") {
600
- if (thread.agent === "brightsy" && isBrightsyNdjsonLine(parsed.data)) {
638
+ for (const event of events) {
639
+ let parsed = event;
640
+ if (parsed.type === "session_id") {
641
+ sessionId = parsed.data;
642
+ outbound.push(parsed);
601
643
  continue;
602
644
  }
603
- const folded = foldDuplicateStdout(textSoFar(parts, parsed.parentId), parsed.data);
604
- if (folded == null) continue;
605
- if (folded !== parsed.data) parsed = { ...parsed, data: folded };
606
- }
607
- parts = applyAgentEvent(parts, parsed);
608
- if (parsed.type === "stdout") {
609
- assistantText = partsToAssistantText(parts);
645
+ if (parsed.type === "usage") {
646
+ const data = parsed.scope === "turn" ? withTurnScopedCost(parsed.data, thread.messages) : parsed.data;
647
+ let base = usage;
648
+ const messageId = parsed.messageId;
649
+ if (messageId && parsed.scope !== "turn") {
650
+ const prev = usageByMessageId.get(messageId);
651
+ if (prev) base = subtractUsage(base, prev);
652
+ usageByMessageId.set(messageId, data);
653
+ }
654
+ usage = applyTurnUsage(base, data, parsed.scope ?? "request");
655
+ outbound.push({ ...parsed, data });
656
+ continue;
657
+ }
658
+ if (parsed.type === "stdout") {
659
+ if (thread.agent === "brightsy" && isBrightsyNdjsonLine(parsed.data)) {
660
+ continue;
661
+ }
662
+ const folded = foldDuplicateStdout(textSoFar(parts, parsed.parentId), parsed.data);
663
+ if (folded == null) continue;
664
+ if (folded !== parsed.data) parsed = { ...parsed, data: folded };
665
+ }
666
+ parts = applyAgentEvent(parts, parsed);
667
+ if (parsed.type === "stdout") {
668
+ assistantText = partsToAssistantText(parts);
669
+ }
670
+ outbound.push(parsed);
610
671
  }
611
- outbound.push(parsed);
672
+ } catch (err) {
673
+ const detail = err instanceof Error ? err.message : String(err);
674
+ outbound.push({
675
+ type: "stderr",
676
+ data: `sideboard: failed to parse agent output: ${detail}`
677
+ });
612
678
  }
613
679
  });
614
680
  };
@@ -622,14 +688,39 @@ async function spawnAgentTurn(thread, input, onEvent) {
622
688
  const exitCode = thread.agent === "brightsy" ? adjustBrightsyTurnExit(result.exitCode ?? null, text3) : result.exitCode ?? null;
623
689
  onEvent({ type: "exit", data: exitCode });
624
690
  return { exitCode, sessionId, assistantText: text3, parts: finalized, usage };
691
+ }).finally(() => {
692
+ for (const dir of cmd.cleanupDirs ?? []) {
693
+ try {
694
+ rmSync(dir, { recursive: true, force: true });
695
+ } catch {
696
+ }
697
+ }
625
698
  });
626
699
  return {
627
700
  pid: child.pid,
628
701
  kill: () => {
629
- try {
630
- child.kill("SIGTERM");
631
- } catch {
632
- }
702
+ const pid = child.pid;
703
+ const startedAt = typeof pid === "number" && pid > 0 ? pidStartedAt(pid) : null;
704
+ const signal = (sig) => {
705
+ if (sig === "SIGKILL" && typeof pid === "number" && pid > 0 && !isSameAgentProcess(pid, startedAt, isPidAlive(pid))) {
706
+ return;
707
+ }
708
+ if (pid && process.platform !== "win32") {
709
+ try {
710
+ process.kill(-pid, sig);
711
+ return;
712
+ } catch {
713
+ }
714
+ }
715
+ try {
716
+ child.kill(sig);
717
+ } catch {
718
+ }
719
+ };
720
+ signal("SIGTERM");
721
+ const timer = setTimeout(() => signal("SIGKILL"), 5e3);
722
+ timer.unref?.();
723
+ child.once("exit", () => clearTimeout(timer));
633
724
  },
634
725
  done
635
726
  };
@@ -1602,14 +1693,15 @@ function sessionGrants(item) {
1602
1693
  if (!dir) return void 0;
1603
1694
  return [{ type: "addDirectories", directories: [dir], destination: "session" }];
1604
1695
  }
1605
- function directoryGrant(item) {
1606
- const stored = item.prompt;
1607
- const path = stored.path ?? "";
1696
+ function directoryGrantPath(path) {
1608
1697
  if (!path) return "";
1609
1698
  if (path.endsWith("/") || path.endsWith("\\")) return path;
1610
1699
  const dir = dirname(path);
1611
1700
  return dir && dir !== "." ? dir : path;
1612
1701
  }
1702
+ function directoryGrant(item) {
1703
+ return directoryGrantPath(item.prompt.path ?? "");
1704
+ }
1613
1705
  function toAnswer(item, decision) {
1614
1706
  if (decision === "deny") {
1615
1707
  return denied("The user denied this action.");
@@ -1654,10 +1746,12 @@ function askToolPermission(ask) {
1654
1746
  if (!threadId || !toolName) return Promise.resolve(denied("Missing chat or tool."));
1655
1747
  const described = describeToolPermission({ ...ask, threadId, toolName });
1656
1748
  const mcpServerId = mcpServerIdForPermission(toolName, ask.mcpServer) ?? void 0;
1749
+ const grantDir = described.path ? directoryGrantPath(described.path) : "";
1750
+ const sessionNote = grantDir && described.path && grantDir !== described.path ? `Allow for this session applies to ${grantDir}, not only this file.` : "";
1657
1751
  const prompt = {
1658
1752
  id: randomUUID(),
1659
1753
  title: described.title,
1660
- detail: described.detail,
1754
+ detail: [described.detail, sessionNote].filter(Boolean).join("\n"),
1661
1755
  path: described.path || void 0,
1662
1756
  // Claude hides "always allow" when the saved rule would be broader than
1663
1757
  // this call. For MCP that broader rule is what we want: the whole server.
@@ -3069,7 +3163,7 @@ async function createThread(input, _onSetupLine) {
3069
3163
  });
3070
3164
  await requireAgent(resolved.agent);
3071
3165
  if (input.cowboy) {
3072
- const { cowboyModeEnabled } = await import("./app-settings-XIF4EC4K.js");
3166
+ const { cowboyModeEnabled } = await import("./app-settings-UQHUNOLV.js");
3073
3167
  if (!cowboyModeEnabled()) {
3074
3168
  throw new Error(
3075
3169
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3128,7 +3222,7 @@ async function createThread(input, _onSetupLine) {
3128
3222
  let sourceIsFork = false;
3129
3223
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3130
3224
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3131
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-CU2UPMJF.js");
3225
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-VL234MCP.js");
3132
3226
  const task = await ensureAbleTimeTask({
3133
3227
  title: title?.trim() || "Untitled work",
3134
3228
  description: input.prompt?.trim() || void 0
@@ -3239,7 +3333,7 @@ async function createThread(input, _onSetupLine) {
3239
3333
  return readThread(thread.id) ?? thread;
3240
3334
  }
3241
3335
  async function listLinearIssues(agent, repoPath) {
3242
- const { getAdapter: getAdapter2 } = await import("./agents-LUSTCMDN.js");
3336
+ const { getAdapter: getAdapter2 } = await import("./agents-MBIEAETM.js");
3243
3337
  await requireAgent(agent, { requireLinear: true });
3244
3338
  const adapter = getAdapter2(agent);
3245
3339
  if (!adapter.listLinearIssues) {
@@ -3925,14 +4019,14 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText, opts) {
3925
4019
  }
3926
4020
 
3927
4021
  // src/threads/adopt.ts
3928
- import { execFileSync } from "child_process";
4022
+ import { execFileSync as execFileSync2 } from "child_process";
3929
4023
  import {
3930
4024
  copyFileSync,
3931
4025
  existsSync as existsSync7,
3932
4026
  mkdtempSync,
3933
4027
  readdirSync as readdirSync2,
3934
4028
  readFileSync as readFileSync5,
3935
- rmSync
4029
+ rmSync as rmSync2
3936
4030
  } from "fs";
3937
4031
  import { tmpdir } from "os";
3938
4032
  import { join as join7 } from "path";
@@ -4022,7 +4116,7 @@ async function adoptThread(input) {
4022
4116
  messages: input.messages ?? []
4023
4117
  });
4024
4118
  writeThread(thread);
4025
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-42E6AGXD.js");
4119
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-QJNKEGEM.js");
4026
4120
  await addWorkspace2(repoPath);
4027
4121
  const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-INRDQFWV.js");
4028
4122
  await ensureWorktreeSideboardIgnored(input.worktreePath);
@@ -4119,7 +4213,7 @@ function listConductorWorkspaces() {
4119
4213
  db.close();
4120
4214
  }
4121
4215
  } finally {
4122
- rmSync(tmp, { recursive: true, force: true });
4216
+ rmSync2(tmp, { recursive: true, force: true });
4123
4217
  }
4124
4218
  }
4125
4219
  function importConductorWorkspace(workspaceId) {
@@ -4192,7 +4286,7 @@ function importConductorWorkspace(workspaceId) {
4192
4286
  }
4193
4287
  let repoPath = worktreePath;
4194
4288
  try {
4195
- repoPath = execFileSync("git", ["rev-parse", "--show-toplevel"], {
4289
+ repoPath = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
4196
4290
  cwd: worktreePath,
4197
4291
  encoding: "utf8"
4198
4292
  }).trim();
@@ -4215,7 +4309,7 @@ function importConductorWorkspace(workspaceId) {
4215
4309
  db.close();
4216
4310
  }
4217
4311
  } finally {
4218
- rmSync(tmp, { recursive: true, force: true });
4312
+ rmSync2(tmp, { recursive: true, force: true });
4219
4313
  }
4220
4314
  }
4221
4315
  async function importConductorWorkspaceAsync(workspaceId) {
@@ -6604,78 +6698,6 @@ import { z as z2 } from "zod";
6604
6698
 
6605
6699
  // src/mcp/issue-list.ts
6606
6700
  import { z } from "zod";
6607
-
6608
- // src/integrations/issue-since.ts
6609
- var ISSUE_SINCE_ERROR = "updatedSince must be an ISO datetime, YYYY-MM-DD, or relative time (yesterday, 2d, 3 hours ago)";
6610
- var DATE_ONLY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
6611
- var DATE_TIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
6612
- var RELATIVE_RE = /^(\d+)\s*(hours?|hrs?|h|days?|d|weeks?|wks?|w)(?:\s+ago)?$/i;
6613
- function startOfLocalDay(date) {
6614
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
6615
- }
6616
- function addLocalDays(date, days) {
6617
- return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
6618
- }
6619
- function parseIssueSince(input, now = /* @__PURE__ */ new Date()) {
6620
- const raw = input.trim();
6621
- if (!raw) throw new Error(ISSUE_SINCE_ERROR);
6622
- const dateOnly = raw.match(DATE_ONLY_RE);
6623
- if (dateOnly) {
6624
- const year = Number(dateOnly[1]);
6625
- const month = Number(dateOnly[2]);
6626
- const day = Number(dateOnly[3]);
6627
- const local = new Date(year, month - 1, day);
6628
- if (local.getFullYear() !== year || local.getMonth() !== month - 1 || local.getDate() !== day) {
6629
- throw new Error(ISSUE_SINCE_ERROR);
6630
- }
6631
- return startOfLocalDay(local).toISOString();
6632
- }
6633
- if (DATE_TIME_RE.test(raw)) {
6634
- const ms = Date.parse(raw);
6635
- if (!Number.isFinite(ms)) throw new Error(ISSUE_SINCE_ERROR);
6636
- return new Date(ms).toISOString();
6637
- }
6638
- const lower = raw.toLowerCase();
6639
- if (lower === "today") return startOfLocalDay(now).toISOString();
6640
- if (lower === "yesterday") return addLocalDays(startOfLocalDay(now), -1).toISOString();
6641
- if (lower === "last week" || lower === "lastweek") {
6642
- return addLocalDays(startOfLocalDay(now), -7).toISOString();
6643
- }
6644
- const relative = lower.match(RELATIVE_RE);
6645
- if (relative) {
6646
- const n = Number(relative[1]);
6647
- if (!Number.isInteger(n) || n < 1) throw new Error(ISSUE_SINCE_ERROR);
6648
- const unit = relative[2];
6649
- if (unit.startsWith("h")) return new Date(now.getTime() - n * 36e5).toISOString();
6650
- if (unit.startsWith("w")) return addLocalDays(startOfLocalDay(now), -7 * n).toISOString();
6651
- return addLocalDays(startOfLocalDay(now), -n).toISOString();
6652
- }
6653
- throw new Error(ISSUE_SINCE_ERROR);
6654
- }
6655
- function formatGitHubSearchUpdatedSince(iso) {
6656
- return iso.replace(/\.\d{3}Z$/, "Z");
6657
- }
6658
- function issueMatchesUpdatedSince(issue, sinceIso) {
6659
- const ts = issue.updatedAt || issue.createdAt;
6660
- if (!ts) return false;
6661
- const value = Date.parse(ts);
6662
- const since = Date.parse(sinceIso);
6663
- return Number.isFinite(value) && Number.isFinite(since) && value >= since;
6664
- }
6665
- var ISSUE_COMMENT_PREVIEW_CHARS = 240;
6666
- function previewIssueCommentBody(body) {
6667
- const flat = body.replace(/\s+/g, " ").trim();
6668
- if (flat.length <= ISSUE_COMMENT_PREVIEW_CHARS) return flat;
6669
- return `${flat.slice(0, ISSUE_COMMENT_PREVIEW_CHARS - 1).trimEnd()}\u2026`;
6670
- }
6671
- function issueActivityKind(issue, sinceIso) {
6672
- const created = issue.createdAt ? Date.parse(issue.createdAt) : Number.NaN;
6673
- const since = Date.parse(sinceIso);
6674
- if (Number.isFinite(created) && Number.isFinite(since) && created >= since) return "created";
6675
- return "updated";
6676
- }
6677
-
6678
- // src/mcp/issue-list.ts
6679
6701
  var MCP_ISSUE_LIST_DEFAULT_LIMIT = 40;
6680
6702
  var MCP_ISSUE_LIST_MAX_LIMIT = 250;
6681
6703
  function clampMcpIssueLimit(limit) {
@@ -7489,7 +7511,7 @@ function formatScheduledPrompt(name, prompt) {
7489
7511
  ${prompt}`;
7490
7512
  }
7491
7513
  async function defaultDeps() {
7492
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-7VTAUY24.js");
7514
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-3H4KNGPN.js");
7493
7515
  const orch = getOrchestrator2();
7494
7516
  return {
7495
7517
  findThread: (id) => findThreadByRef(id),
@@ -7635,23 +7657,6 @@ function armSchedules() {
7635
7657
  // src/orchestrator/orchestrator.ts
7636
7658
  var LIVE_TURN_SPAWN_GRACE_MS = 15e3;
7637
7659
  var RUN_SCRIPT_DESKTOP_ADOPT_MS = 2e4;
7638
- function isPidAlive(pid) {
7639
- if (!Number.isFinite(pid) || pid <= 0) return false;
7640
- try {
7641
- process.kill(pid, 0);
7642
- return true;
7643
- } catch {
7644
- return false;
7645
- }
7646
- }
7647
- async function waitForPidExit(pid, timeoutMs) {
7648
- const start = Date.now();
7649
- while (isPidAlive(pid)) {
7650
- if (Date.now() - start >= timeoutMs) return false;
7651
- await new Promise((r) => setTimeout(r, 80));
7652
- }
7653
- return true;
7654
- }
7655
7660
  function resolveOrchChildFollowUp(requested) {
7656
7661
  if (requested === "steer" || requested === "queue") return requested;
7657
7662
  return followUpBehavior();
@@ -7857,7 +7862,7 @@ var Orchestrator = class {
7857
7862
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7858
7863
  });
7859
7864
  }
7860
- const { autoCleanupOrphansEnabled } = await import("./app-settings-XIF4EC4K.js");
7865
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-UQHUNOLV.js");
7861
7866
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7862
7867
  await cleanupOrphanWorktrees({ repoPaths });
7863
7868
  }
@@ -7878,7 +7883,7 @@ var Orchestrator = class {
7878
7883
  const pid = thread.agentPid;
7879
7884
  const deadPid = typeof pid === "number" && pid > 0 && !isPidAlive(pid) ? true : false;
7880
7885
  if (deadPid) {
7881
- updateThread(thread.id, { agentPid: null });
7886
+ updateThread(thread.id, { agentPid: null, agentPidStartedAt: null });
7882
7887
  }
7883
7888
  if (thread.status === "queued" && thread.queue.length === 0) {
7884
7889
  if (!this.activeTurns.has(thread.id) && !this.startingTurns.has(thread.id)) {
@@ -8251,7 +8256,7 @@ var Orchestrator = class {
8251
8256
  }
8252
8257
  await setup;
8253
8258
  if (skipSetup) return;
8254
- const { autoRunAfterSetupEnabled } = await import("./app-settings-XIF4EC4K.js");
8259
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-UQHUNOLV.js");
8255
8260
  if (autoRunAfterSetupEnabled()) {
8256
8261
  try {
8257
8262
  await this.startDev(threadId);
@@ -8431,19 +8436,26 @@ var Orchestrator = class {
8431
8436
  }
8432
8437
  const livePid = thread.agentPid;
8433
8438
  if (typeof livePid === "number" && livePid > 0 && isPidAlive(livePid)) {
8434
- const exited = await waitForPidExit(livePid, STALE_AGENT_PID_WAIT_MS);
8435
- if (!exited && isPidAlive(livePid)) {
8439
+ if (!isSameAgentProcess(livePid, thread.agentPidStartedAt, true)) {
8436
8440
  try {
8437
- process.kill(livePid, "SIGKILL");
8441
+ updateThread(threadId, { agentPid: null, agentPidStartedAt: null });
8438
8442
  } catch {
8439
8443
  }
8440
- await waitForPidExit(livePid, 400);
8441
- try {
8442
- updateThread(threadId, { agentPid: null });
8443
- } catch {
8444
+ } else {
8445
+ const exited = await waitForPidExit(livePid, STALE_AGENT_PID_WAIT_MS);
8446
+ if (!exited && isPidAlive(livePid)) {
8447
+ try {
8448
+ process.kill(livePid, "SIGKILL");
8449
+ } catch {
8450
+ }
8451
+ await waitForPidExit(livePid, 400);
8452
+ try {
8453
+ updateThread(threadId, { agentPid: null, agentPidStartedAt: null });
8454
+ } catch {
8455
+ }
8444
8456
  }
8457
+ continue;
8445
8458
  }
8446
- continue;
8447
8459
  }
8448
8460
  const shifted = shiftQueuedItem(thread.queue, thread.queueAttachments);
8449
8461
  if (!shifted) break;
@@ -8618,7 +8630,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8618
8630
  }
8619
8631
  const adapter = getAdapter(thread.agent);
8620
8632
  const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
8621
- if (resolved && resolved !== thread.sessionId) {
8633
+ if (resolved !== thread.sessionId) {
8622
8634
  updateThread(threadId, { sessionId: resolved });
8623
8635
  }
8624
8636
  const fresh = this.requireThread(threadId);
@@ -8629,7 +8641,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8629
8641
  }
8630
8642
  const isBrightsy = fresh.agent === "brightsy";
8631
8643
  const isOrchestration = isOrchestratorThread(fresh);
8632
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-XIF4EC4K.js");
8644
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-UQHUNOLV.js");
8633
8645
  const gitAuthMode = getGithubGitAuthMode();
8634
8646
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
8635
8647
  githubSlug: turnOrigin?.forge === "github" ? turnOrigin.slug : await withTimeout(resolveGithubRepoSlug(fresh.worktreePath), 8e3, "resolveGithubRepoSlug").catch(() => null),
@@ -8766,7 +8778,10 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8766
8778
  this.activeTurns.set(threadId, handle);
8767
8779
  this.startingTurns.delete(threadId);
8768
8780
  if (typeof handle.pid === "number" && handle.pid > 0) {
8769
- updateThread(threadId, { agentPid: handle.pid });
8781
+ updateThread(threadId, {
8782
+ agentPid: handle.pid,
8783
+ agentPidStartedAt: pidStartedAt(handle.pid)
8784
+ });
8770
8785
  }
8771
8786
  if (this.stoppedTurns.has(threadId)) {
8772
8787
  handle.kill();
@@ -8794,7 +8809,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8794
8809
  if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
8795
8810
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
8796
8811
  if (sessionId) {
8797
- const { recoverFinishedCursorRun } = await import("./cursor-recover-OWPQUHFH.js");
8812
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-BDIAZIE3.js");
8798
8813
  for (let i = 0; i < 8; i++) {
8799
8814
  const recovered = recoverFinishedCursorRun({
8800
8815
  agentId: sessionId,
@@ -8879,7 +8894,10 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8879
8894
  );
8880
8895
  this.activeTurns.set(threadId, retryHandle);
8881
8896
  if (typeof retryHandle.pid === "number" && retryHandle.pid > 0) {
8882
- updateThread(threadId, { agentPid: retryHandle.pid });
8897
+ updateThread(threadId, {
8898
+ agentPid: retryHandle.pid,
8899
+ agentPidStartedAt: pidStartedAt(retryHandle.pid)
8900
+ });
8883
8901
  }
8884
8902
  this.processes.set(`${threadId}:agent`, {
8885
8903
  kind: "agent",
@@ -9028,7 +9046,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9028
9046
  this.runningCount = Math.max(0, this.runningCount - 1);
9029
9047
  clearTurnLive(threadId);
9030
9048
  try {
9031
- updateThread(threadId, { agentPid: null });
9049
+ updateThread(threadId, { agentPid: null, agentPidStartedAt: null });
9032
9050
  } catch {
9033
9051
  }
9034
9052
  }
@@ -9066,9 +9084,16 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9066
9084
  if (proc) proc.kill();
9067
9085
  const pid = thread.agentPid;
9068
9086
  if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) {
9069
- try {
9070
- process.kill(pid, "SIGTERM");
9071
- } catch {
9087
+ if (!isSameAgentProcess(pid, thread.agentPidStartedAt, true)) {
9088
+ try {
9089
+ updateThread(thread.id, { agentPid: null, agentPidStartedAt: null });
9090
+ } catch {
9091
+ }
9092
+ } else {
9093
+ try {
9094
+ process.kill(pid, "SIGTERM");
9095
+ } catch {
9096
+ }
9072
9097
  }
9073
9098
  }
9074
9099
  const stopped = writeStoppedStatus(thread.id, resolveStopReason(opts)) ?? readThread(thread.id) ?? thread;
@@ -9956,7 +9981,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9956
9981
  if (Object.keys(patch).length === 0) continue;
9957
9982
  updateThread(t.id, patch);
9958
9983
  }
9959
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-XIF4EC4K.js");
9984
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-UQHUNOLV.js");
9960
9985
  const latest = this.requireThread(thread.id);
9961
9986
  if (!shouldAutoArchiveOnPrMerge({
9962
9987
  previousPrState: prevState || null,
@@ -10280,7 +10305,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
10280
10305
  await runArchiveScript(thread.repoPath, thread.worktreePath);
10281
10306
  } catch {
10282
10307
  }
10283
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-XIF4EC4K.js");
10308
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-UQHUNOLV.js");
10284
10309
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
10285
10310
  await removeWorktree(thread.repoPath, thread.worktreePath, {
10286
10311
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -10418,7 +10443,7 @@ async function startOrchestration(opts) {
10418
10443
  sourceRef: "default",
10419
10444
  ...createOpts
10420
10445
  }).catch(async () => {
10421
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-ZDA2UJ7C.js");
10446
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-KSJPTHGZ.js");
10422
10447
  const repo = await resolveRepoRoot2(repoPath);
10423
10448
  const def = await resolveDefaultBranch2(repo);
10424
10449
  return orch.createThread({
@@ -10428,7 +10453,7 @@ async function startOrchestration(opts) {
10428
10453
  repoPath: repo
10429
10454
  });
10430
10455
  });
10431
- const { updateThread: upd } = await import("./thread-store-JRSL4HQY.js");
10456
+ const { updateThread: upd } = await import("./thread-store-IC4BQXDW.js");
10432
10457
  const updated = upd(thread.id, {
10433
10458
  sourceType: "orchestration",
10434
10459
  sourceRef: goal
@@ -10515,6 +10540,8 @@ export {
10515
10540
  pendingInjectedNotices,
10516
10541
  lastAgentReply,
10517
10542
  formatInjectedNoticesForTurn,
10543
+ isPidAlive,
10544
+ waitForPidExit,
10518
10545
  applyPromptCacheTtlEnv,
10519
10546
  spawnAgentTurn,
10520
10547
  AGENT_GIT_ACTIONS,
@@ -10636,10 +10663,6 @@ export {
10636
10663
  formatLongRunningReminder,
10637
10664
  formatArtifactDirective,
10638
10665
  formatUiReminder,
10639
- parseIssueSince,
10640
- formatGitHubSearchUpdatedSince,
10641
- issueMatchesUpdatedSince,
10642
- previewIssueCommentBody,
10643
10666
  clampMcpIssueLimit,
10644
10667
  applyIssueListWindow,
10645
10668
  mcpIssueUpdatedSinceSchema,
@@ -10648,8 +10671,6 @@ export {
10648
10671
  registerViewerContextTools,
10649
10672
  LIVE_TURN_SPAWN_GRACE_MS,
10650
10673
  RUN_SCRIPT_DESKTOP_ADOPT_MS,
10651
- isPidAlive,
10652
- waitForPidExit,
10653
10674
  resolveOrchChildFollowUp,
10654
10675
  LIGHT_RECONCILE_THROTTLE_MS,
10655
10676
  Orchestrator,