@sideboard-ai/core 0.1.110 → 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 +32 -23
  2. package/dist/agents/cursor-runner.js +3 -3
  3. package/dist/{agents-WK54VP7J.js → agents-3X3EFCQY.js} +7 -7
  4. package/dist/{agents-MQDW3YXL.js → agents-AHAFC6FR.js} +10 -10
  5. package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
  6. package/dist/{chunk-VOJSO3RM.js → chunk-66XTXHR3.js} +277 -49
  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-RSIWPLRG.js → chunk-C6OBY6IC.js} +268 -27
  10. package/dist/{chunk-EAAB4EK5.js → chunk-DCNR7NAL.js} +44 -32
  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-XOZDAVOP.js → chunk-MZ6HJ7VL.js} +52 -35
  17. package/dist/{chunk-3UOKB6VQ.js → chunk-SLU5JVKD.js} +282 -228
  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 +825 -443
  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 +947 -644
  34. package/dist/mcp/run-stdio.js +18 -14
  35. package/dist/{orchestrator-SCATSB3O.js → orchestrator-GKLYKLRC.js} +8 -8
  36. package/dist/{orchestrator-FCZVCKBK.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
@@ -1419,7 +1419,7 @@ function extractJsonErrorMessage(obj) {
1419
1419
  }
1420
1420
  function isPinnedStderrLine(line) {
1421
1421
  if (/^\s*at\s/.test(line)) return false;
1422
- return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:/i.test(
1422
+ return /cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|cursor startup failed:|FATAL ERROR|heap out of memory|javascript heap|OOMErrorHandler|FatalProcessOutOfMemory/i.test(
1423
1423
  line
1424
1424
  );
1425
1425
  }
@@ -1442,12 +1442,17 @@ function looksLikeMinifiedJsDump(line) {
1442
1442
  function looksLikeNestedElectronCrash(line) {
1443
1443
  return /HasCustomHostObject|ElectronInitializeICUandStartNode/i.test(line);
1444
1444
  }
1445
- function looksLikeHomebrewLibuvCrash(line) {
1446
- const uvRun = /uv_run/i.test(line);
1447
- const spin = /SpinEventLoopInternal/i.test(line);
1448
- const homebrewUv = /Cellar\/libuv|libuv\.\d\.dylib/i.test(line);
1449
- const homebrewNode = /Cellar\/node\//i.test(line);
1450
- return uvRun && (homebrewUv || spin || homebrewNode) || spin && (homebrewUv || homebrewNode);
1445
+ function looksLikeNativeEventLoopCrash(text4) {
1446
+ return /uv_run|uv__io_poll|SpinEventLoopInternal/i.test(text4);
1447
+ }
1448
+ function looksLikeV8Oom(text4) {
1449
+ return /javascript heap|reached heap limit|OOMErrorHandler|FatalProcessOutOfMemory|Allocation failed - JavaScript heap/i.test(
1450
+ text4
1451
+ );
1452
+ }
1453
+ function looksLikeHomebrewLibuvCrash(text4) {
1454
+ if (!looksLikeNativeEventLoopCrash(text4)) return false;
1455
+ return /Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(text4);
1451
1456
  }
1452
1457
  function clipStderr(text4, maxChars) {
1453
1458
  const trimmed = text4.trim();
@@ -1461,7 +1466,12 @@ function summarizeTurnStderr(tail, maxChars = 500) {
1461
1466
  const cursorRunFailed = [...tail].reverse().find((line) => /^cursor run failed\b/i.test(line.trim()));
1462
1467
  if (cursorRunFailed) return clipStderr(cursorRunFailed, maxChars);
1463
1468
  if (tail.some(looksLikeNestedElectronCrash)) return NESTED_ELECTRON_SUMMARY;
1464
- if (tail.some(looksLikeHomebrewLibuvCrash)) return HOMEBREW_LIBUV_SUMMARY;
1469
+ const blob = tail.join("\n");
1470
+ if (looksLikeV8Oom(blob)) return V8_OOM_SUMMARY;
1471
+ if (looksLikeHomebrewLibuvCrash(blob)) return HOMEBREW_LIBUV_SUMMARY;
1472
+ if (looksLikeNativeEventLoopCrash(blob)) {
1473
+ return BUNDLED_NODE_CRASH_SUMMARY;
1474
+ }
1465
1475
  if (tail.some(
1466
1476
  (line) => /\[resource_exhausted\]|resource_exhausted/i.test(line) || /findFilesWithRipgrep/.test(line)
1467
1477
  )) {
@@ -1487,15 +1497,17 @@ function looksLikeInvalidAgentSession(text4) {
1487
1497
  function looksLikeRetryableRunnerCrash(text4) {
1488
1498
  if (looksLikeAgentFailureMessage(text4)) return false;
1489
1499
  if (looksLikeInvalidAgentSession(text4)) return false;
1500
+ if (looksLikeV8Oom(text4)) return false;
1490
1501
  const lower = text4.trim().toLowerCase();
1491
1502
  if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
1492
1503
  if (!lower) return true;
1493
- return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
1504
+ return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|cursor runner crashed in node|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
1494
1505
  lower
1495
1506
  );
1496
1507
  }
1497
1508
  function shouldRetryFailedAgentTurn(detail, opts) {
1498
1509
  if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
1510
+ if (looksLikeV8Oom(detail) && opts.hasSession) return true;
1499
1511
  return looksLikeRetryableRunnerCrash(detail);
1500
1512
  }
1501
1513
  function looksLikeAgentFailureMessage(text4) {
@@ -1542,9 +1554,15 @@ function humanizeAgentFailDetail(detail) {
1542
1554
  if (/hascustomhostobject|electroninitializeicuandstartnode|nested chromium/i.test(lower)) {
1543
1555
  return `${raw} \u2014 retry the turn; if it keeps failing, pick another agent.`;
1544
1556
  }
1545
- if (/homebrew node \+ shared libuv|uv_run|spineventloopinternal/i.test(lower)) {
1557
+ if (looksLikeV8Oom(raw) || /javascript heap out of memory/i.test(lower)) {
1558
+ return /ran out of memory/i.test(raw) ? raw : V8_OOM_SUMMARY;
1559
+ }
1560
+ if (/homebrew node \+ shared libuv|Cellar\/(?:libuv|node)|libuv\.\d+\.dylib/i.test(raw)) {
1546
1561
  return /brew install node@22/i.test(raw) ? raw : `${raw} \u2014 install Node 22 LTS (\`brew install node@22\`) and retry.`;
1547
1562
  }
1563
+ if (/uv_run|spineventloopinternal|uv__io_poll|cursor runner crashed in node/i.test(lower)) {
1564
+ return /retry the turn/i.test(raw) ? raw : BUNDLED_NODE_CRASH_SUMMARY;
1565
+ }
1548
1566
  if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
1549
1567
  return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
1550
1568
  }
@@ -1574,17 +1592,266 @@ function formatTurnExitError(exitCode, stderrSummary) {
1574
1592
  if (looksLikeAgentFailureMessage(raw)) return detail;
1575
1593
  return `exit ${code}: ${detail}`;
1576
1594
  }
1577
- var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, MINIFIED_DUMP_SUMMARY;
1595
+ var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, BUNDLED_NODE_CRASH_SUMMARY, V8_OOM_SUMMARY, MINIFIED_DUMP_SUMMARY;
1578
1596
  var init_error_detail = __esm({
1579
1597
  "src/agents/error-detail.ts"() {
1580
1598
  "use strict";
1581
1599
  NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
1582
1600
  NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
1583
1601
  HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
1602
+ BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
1603
+ V8_OOM_SUMMARY = "Agent ran out of memory (JavaScript heap). If it keeps happening, exclude large files from the project folder.";
1584
1604
  MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
1585
1605
  }
1586
1606
  });
1587
1607
 
1608
+ // src/agents/path.ts
1609
+ function prependPathDir(env, dir) {
1610
+ if (!dir || !(0, import_node_fs10.existsSync)(dir)) return;
1611
+ const current = env.PATH ?? "";
1612
+ const parts = current.split(import_node_path10.delimiter).filter(Boolean);
1613
+ if (parts.includes(dir)) {
1614
+ env.PATH = current;
1615
+ return;
1616
+ }
1617
+ env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
1618
+ }
1619
+ function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os3.homedir)()) {
1620
+ return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
1621
+ }
1622
+ function isConductorBundledCli(filePath) {
1623
+ const p = (filePath ?? "").replace(/\\/g, "/");
1624
+ return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
1625
+ }
1626
+ function ensureAgentPath(env = process.env) {
1627
+ const home = env.HOME || env.USERPROFILE || (0, import_node_os3.homedir)();
1628
+ const current = env.PATH ?? "";
1629
+ const parts = current.split(import_node_path10.delimiter).filter(Boolean);
1630
+ const seen = new Set(parts);
1631
+ const extras = [
1632
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
1633
+ "/opt/homebrew/bin",
1634
+ "/usr/local/bin",
1635
+ // Keep after Homebrew/npm so a user-installed CLI still wins.
1636
+ conductorBundledBinDir(home)
1637
+ ];
1638
+ for (const dir of extras.reverse()) {
1639
+ if (!dir || seen.has(dir) || !(0, import_node_fs10.existsSync)(dir)) continue;
1640
+ parts.unshift(dir);
1641
+ seen.add(dir);
1642
+ }
1643
+ const next = parts.join(import_node_path10.delimiter);
1644
+ env.PATH = next;
1645
+ return next;
1646
+ }
1647
+ function enrichPathWithNpmGlobalBin(env = process.env) {
1648
+ ensureAgentPath(env);
1649
+ try {
1650
+ const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
1651
+ encoding: "utf8",
1652
+ env: { ...process.env, ...env },
1653
+ timeout: 8e3,
1654
+ stdio: ["ignore", "pipe", "ignore"]
1655
+ }).trim().split(/\r?\n/).find(Boolean);
1656
+ if (prefix) {
1657
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
1658
+ prependPathDir(env, binDir);
1659
+ }
1660
+ } catch {
1661
+ }
1662
+ return env.PATH ?? "";
1663
+ }
1664
+ function posixShellSingleQuote(value) {
1665
+ return `'${value.replace(/'/g, `'\\''`)}'`;
1666
+ }
1667
+ function resolveCommandBinarySync(command, whichPath) {
1668
+ const trimmed = command.trim();
1669
+ if (!trimmed) return trimmed;
1670
+ const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
1671
+ if (!match) return trimmed;
1672
+ const bin = match[1];
1673
+ const rest = match[2] ?? "";
1674
+ if (bin.includes("/") || bin.includes("\\")) return trimmed;
1675
+ const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
1676
+ if (!abs) return trimmed;
1677
+ return `${abs}${rest}`;
1678
+ }
1679
+ function withExportedPath(command, pathValue) {
1680
+ const trimmed = command.trim();
1681
+ if (!trimmed) return trimmed;
1682
+ if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
1683
+ return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
1684
+ }
1685
+ var import_node_fs10, import_node_child_process2, import_node_os3, import_node_path10, EXTRA_BIN_DIRS;
1686
+ var init_path = __esm({
1687
+ "src/agents/path.ts"() {
1688
+ "use strict";
1689
+ import_node_fs10 = require("fs");
1690
+ import_node_child_process2 = require("child_process");
1691
+ import_node_os3 = require("os");
1692
+ import_node_path10 = require("path");
1693
+ EXTRA_BIN_DIRS = [
1694
+ ".local/bin",
1695
+ ".cargo/bin",
1696
+ ".nvm/current/bin",
1697
+ ".asdf/shims",
1698
+ ".volta/bin",
1699
+ ".npm-global/bin",
1700
+ // fnm default alias (common when shell init is skipped)
1701
+ ".local/share/fnm/aliases/default/bin",
1702
+ // pnpm / npm global bins (where `@brightsy/cli` typically lands)
1703
+ "Library/pnpm",
1704
+ ".pnpm"
1705
+ ];
1706
+ }
1707
+ });
1708
+
1709
+ // src/git/stale-lock.ts
1710
+ function isIndexLockError(text4) {
1711
+ return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text4);
1712
+ }
1713
+ function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
1714
+ const lockPath = (0, import_node_path11.join)(gitDir, "index.lock");
1715
+ try {
1716
+ if (!(0, import_node_fs11.existsSync)(lockPath)) return null;
1717
+ if (now - (0, import_node_fs11.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
1718
+ (0, import_node_fs11.unlinkSync)(lockPath);
1719
+ return lockPath;
1720
+ } catch {
1721
+ return null;
1722
+ }
1723
+ }
1724
+ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
1725
+ const now = Date.now();
1726
+ const removed = [];
1727
+ for (const dir of new Set(gitDirs)) {
1728
+ const cleared = clearStaleIndexLock(dir, maxAgeMs, now);
1729
+ if (cleared) removed.push(cleared);
1730
+ }
1731
+ return removed;
1732
+ }
1733
+ var import_node_fs11, import_node_path11, STALE_INDEX_LOCK_MS;
1734
+ var init_stale_lock = __esm({
1735
+ "src/git/stale-lock.ts"() {
1736
+ "use strict";
1737
+ import_node_fs11 = require("fs");
1738
+ import_node_path11 = require("path");
1739
+ STALE_INDEX_LOCK_MS = 2e4;
1740
+ }
1741
+ });
1742
+
1743
+ // src/git/run.ts
1744
+ var run_exports = {};
1745
+ __export(run_exports, {
1746
+ gh: () => gh,
1747
+ git: () => git,
1748
+ resolveGhAuthToken: () => resolveGhAuthToken,
1749
+ resolveGitDirsForLockRecovery: () => resolveGitDirsForLockRecovery,
1750
+ run: () => run
1751
+ });
1752
+ async function run(file, args, opts) {
1753
+ ensureAgentPath();
1754
+ try {
1755
+ const result = await (0, import_execa2.execa)(file, args, {
1756
+ cwd: opts?.cwd,
1757
+ env: { ...process.env, ...opts?.env },
1758
+ reject: opts?.reject ?? true,
1759
+ ...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
1760
+ });
1761
+ return {
1762
+ stdout: result.stdout ?? "",
1763
+ stderr: result.stderr ?? "",
1764
+ exitCode: result.exitCode ?? 0
1765
+ };
1766
+ } catch (err) {
1767
+ const e = err;
1768
+ if (opts?.reject === false) {
1769
+ return {
1770
+ stdout: String(e.stdout ?? ""),
1771
+ stderr: String(e.stderr ?? ""),
1772
+ exitCode: e.exitCode ?? 1
1773
+ };
1774
+ }
1775
+ throw err;
1776
+ }
1777
+ }
1778
+ async function resolveGitDirsForLockRecovery(cwd, env = {}) {
1779
+ const dirs = /* @__PURE__ */ new Set();
1780
+ const [gitDir, commonDir] = await Promise.all([
1781
+ run("git", ["rev-parse", "--absolute-git-dir"], { cwd, reject: false, env, timeoutMs: 5e3 }),
1782
+ run("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], {
1783
+ cwd,
1784
+ reject: false,
1785
+ env,
1786
+ timeoutMs: 5e3
1787
+ })
1788
+ ]);
1789
+ if (gitDir.exitCode === 0 && gitDir.stdout.trim()) dirs.add(gitDir.stdout.trim());
1790
+ if (commonDir.exitCode === 0 && commonDir.stdout.trim()) dirs.add(commonDir.stdout.trim());
1791
+ return [...dirs];
1792
+ }
1793
+ async function git(args, cwd, opts) {
1794
+ const prefix = [];
1795
+ if (opts?.config) {
1796
+ for (const [key, value] of Object.entries(opts.config)) {
1797
+ if (!key) continue;
1798
+ prefix.push("-c", `${key}=${value}`);
1799
+ }
1800
+ }
1801
+ const gitArgs = ["--no-pager", ...prefix, ...args];
1802
+ const env = {
1803
+ // Never block forever on a credential/SSH prompt inside MCP / Electron.
1804
+ GIT_TERMINAL_PROMPT: "0",
1805
+ GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
1806
+ SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
1807
+ GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
1808
+ GCM_INTERACTIVE: "never",
1809
+ GH_PROMPT_DISABLED: "1",
1810
+ ...opts?.env
1811
+ };
1812
+ let result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
1813
+ if (result.exitCode !== 0 && isIndexLockError(result.stderr)) {
1814
+ const gitDirs = await resolveGitDirsForLockRecovery(cwd, env);
1815
+ const cleared = clearStaleIndexLocks(gitDirs);
1816
+ if (cleared.length > 0) {
1817
+ result = await run("git", gitArgs, { cwd, reject: false, timeoutMs: opts?.timeoutMs, env });
1818
+ }
1819
+ }
1820
+ if ((opts?.reject ?? true) && result.exitCode !== 0) {
1821
+ throw new Error(
1822
+ `Command failed with exit code ${result.exitCode}: git ${gitArgs.join(" ")}
1823
+ ${result.stderr}`
1824
+ );
1825
+ }
1826
+ return result;
1827
+ }
1828
+ async function gh(args, cwd, opts) {
1829
+ return run("gh", args, {
1830
+ cwd,
1831
+ reject: opts?.reject,
1832
+ timeoutMs: opts?.timeoutMs,
1833
+ env: {
1834
+ GH_PROMPT_DISABLED: "1",
1835
+ GIT_TERMINAL_PROMPT: "0"
1836
+ }
1837
+ });
1838
+ }
1839
+ async function resolveGhAuthToken(cwd) {
1840
+ const result = await gh(["auth", "token"], cwd, { reject: false, timeoutMs: 8e3 });
1841
+ if (result.exitCode !== 0) return null;
1842
+ const token = result.stdout.trim();
1843
+ return token || null;
1844
+ }
1845
+ var import_execa2;
1846
+ var init_run = __esm({
1847
+ "src/git/run.ts"() {
1848
+ "use strict";
1849
+ import_execa2 = require("execa");
1850
+ init_path();
1851
+ init_stale_lock();
1852
+ }
1853
+ });
1854
+
1588
1855
  // src/git/team-meta.ts
1589
1856
  var SOCCER_TEAM_META;
1590
1857
  var init_team_meta = __esm({
@@ -2486,7 +2753,7 @@ var init_gh_errors = __esm({
2486
2753
 
2487
2754
  // src/store/secret-vault.ts
2488
2755
  function secretVaultPath() {
2489
- return (0, import_node_path10.join)(appDataDir(), "secrets.json");
2756
+ return (0, import_node_path12.join)(appDataDir(), "secrets.json");
2490
2757
  }
2491
2758
  function loadSecretVault() {
2492
2759
  const parsed = readSecureJson(secretVaultPath());
@@ -2530,11 +2797,11 @@ function normalizeVault(raw) {
2530
2797
  }
2531
2798
  return out;
2532
2799
  }
2533
- var import_node_path10;
2800
+ var import_node_path12;
2534
2801
  var init_secret_vault = __esm({
2535
2802
  "src/store/secret-vault.ts"() {
2536
2803
  "use strict";
2537
- import_node_path10 = require("path");
2804
+ import_node_path12 = require("path");
2538
2805
  init_paths();
2539
2806
  init_secure_file();
2540
2807
  }
@@ -2637,10 +2904,10 @@ function toPublicAppSettings(settings) {
2637
2904
  };
2638
2905
  }
2639
2906
  function appSettingsPath() {
2640
- return (0, import_node_path11.join)(appDataDir(), "settings.json");
2907
+ return (0, import_node_path13.join)(appDataDir(), "settings.json");
2641
2908
  }
2642
2909
  function claudeUserSettingsPath() {
2643
- return (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
2910
+ return (0, import_node_path13.join)((0, import_node_os4.homedir)(), ".claude", "settings.json");
2644
2911
  }
2645
2912
  function normalizeClaude(raw) {
2646
2913
  if (!raw || typeof raw !== "object") return {};
@@ -2889,10 +3156,10 @@ function normalizeSettings(raw) {
2889
3156
  }
2890
3157
  function readSettingsFile() {
2891
3158
  const path = appSettingsPath();
2892
- if (!(0, import_node_fs10.existsSync)(path)) return { ...EMPTY_SETTINGS };
3159
+ if (!(0, import_node_fs12.existsSync)(path)) return { ...EMPTY_SETTINGS };
2893
3160
  try {
2894
3161
  chmodOwnerOnly(path);
2895
- const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf8"));
3162
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
2896
3163
  return normalizeSettings(parsed);
2897
3164
  } catch {
2898
3165
  return { ...EMPTY_SETTINGS };
@@ -3277,7 +3544,7 @@ function ensureSlackDeviceIdentity(settings = loadAppSettings()) {
3277
3544
  }
3278
3545
  if (!deviceLabel) {
3279
3546
  try {
3280
- deviceLabel = (0, import_node_os3.hostname)().split(".")[0]?.trim() || "This Mac";
3547
+ deviceLabel = (0, import_node_os4.hostname)().split(".")[0]?.trim() || "This Mac";
3281
3548
  } catch {
3282
3549
  deviceLabel = "This Mac";
3283
3550
  }
@@ -3464,14 +3731,14 @@ function childEnvWithAppSettings(extra) {
3464
3731
  function harnessEnvKey(harness) {
3465
3732
  return HARNESS_ENV_KEYS[harness];
3466
3733
  }
3467
- var import_node_crypto3, import_node_fs10, import_node_os3, import_node_path11, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
3734
+ var import_node_crypto3, import_node_fs12, import_node_os4, import_node_path13, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
3468
3735
  var init_app_settings = __esm({
3469
3736
  "src/store/app-settings.ts"() {
3470
3737
  "use strict";
3471
3738
  import_node_crypto3 = require("crypto");
3472
- import_node_fs10 = require("fs");
3473
- import_node_os3 = require("os");
3474
- import_node_path11 = require("path");
3739
+ import_node_fs12 = require("fs");
3740
+ import_node_os4 = require("os");
3741
+ import_node_path13 = require("path");
3475
3742
  init_thinking_effort();
3476
3743
  init_nested_electron_env();
3477
3744
  init_paths();
@@ -3523,23 +3790,23 @@ var init_app_settings = __esm({
3523
3790
  function githubAgentAuthDir() {
3524
3791
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
3525
3792
  if (override) return override;
3526
- return (0, import_node_path12.join)((0, import_node_os4.homedir)(), ".sideboard-git-auth");
3793
+ return (0, import_node_path14.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
3527
3794
  }
3528
3795
  function githubCredentialStorePath() {
3529
- return (0, import_node_path12.join)(githubAgentAuthDir(), "git-credentials");
3796
+ return (0, import_node_path14.join)(githubAgentAuthDir(), "git-credentials");
3530
3797
  }
3531
3798
  function githubGhConfigDir() {
3532
- return (0, import_node_path12.join)(githubAgentAuthDir(), "gh");
3799
+ return (0, import_node_path14.join)(githubAgentAuthDir(), "gh");
3533
3800
  }
3534
3801
  function writePrivateFile2(file, body) {
3535
- (0, import_node_fs11.mkdirSync)((0, import_node_path12.dirname)(file), { recursive: true, mode: 448 });
3802
+ (0, import_node_fs13.mkdirSync)((0, import_node_path14.dirname)(file), { recursive: true, mode: 448 });
3536
3803
  try {
3537
- (0, import_node_fs11.chmodSync)((0, import_node_path12.dirname)(file), 448);
3804
+ (0, import_node_fs13.chmodSync)((0, import_node_path14.dirname)(file), 448);
3538
3805
  } catch {
3539
3806
  }
3540
- (0, import_node_fs11.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
3807
+ (0, import_node_fs13.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
3541
3808
  try {
3542
- (0, import_node_fs11.chmodSync)(file, 384);
3809
+ (0, import_node_fs13.chmodSync)(file, 384);
3543
3810
  } catch {
3544
3811
  }
3545
3812
  }
@@ -3561,228 +3828,43 @@ function ghHostsYml(token, user = "x-access-token") {
3561
3828
  ].join("\n");
3562
3829
  }
3563
3830
  function materializeGithubAgentAuth(token, user) {
3564
- const trimmed = token.trim();
3565
- if (!trimmed) return;
3566
- const root = githubAgentAuthDir();
3567
- (0, import_node_fs11.mkdirSync)(root, { recursive: true, mode: 448 });
3568
- try {
3569
- (0, import_node_fs11.chmodSync)(root, 448);
3570
- } catch {
3571
- }
3572
- writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
3573
- const ghDir = githubGhConfigDir();
3574
- (0, import_node_fs11.mkdirSync)(ghDir, { recursive: true, mode: 448 });
3575
- writePrivateFile2((0, import_node_path12.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
3576
- writePrivateFile2((0, import_node_path12.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
3577
- }
3578
- function githubAgentAuthReady() {
3579
- return (0, import_node_fs11.existsSync)(githubCredentialStorePath()) && (0, import_node_fs11.existsSync)((0, import_node_path12.join)(githubGhConfigDir(), "hosts.yml"));
3580
- }
3581
- function githubCredentialHelperGitConfig() {
3582
- const file = githubCredentialStorePath();
3583
- return [
3584
- { key: "credential.helper", value: "" },
3585
- { key: "credential.helper", value: `store --file=${file}` }
3586
- ];
3587
- }
3588
- function githubGhConfigEnv() {
3589
- return {
3590
- GH_CONFIG_DIR: githubGhConfigDir(),
3591
- GH_PROMPT_DISABLED: "1"
3592
- };
3593
- }
3594
- var import_node_fs11, import_node_os4, import_node_path12;
3595
- var init_github_agent_auth = __esm({
3596
- "src/git/github-agent-auth.ts"() {
3597
- "use strict";
3598
- import_node_fs11 = require("fs");
3599
- import_node_os4 = require("os");
3600
- import_node_path12 = require("path");
3601
- }
3602
- });
3603
-
3604
- // src/agents/path.ts
3605
- function prependPathDir(env, dir) {
3606
- if (!dir || !(0, import_node_fs12.existsSync)(dir)) return;
3607
- const current = env.PATH ?? "";
3608
- const parts = current.split(import_node_path13.delimiter).filter(Boolean);
3609
- if (parts.includes(dir)) {
3610
- env.PATH = current;
3611
- return;
3612
- }
3613
- env.PATH = [dir, ...parts].join(import_node_path13.delimiter);
3614
- }
3615
- function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
3616
- return (0, import_node_path13.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
3617
- }
3618
- function isConductorBundledCli(filePath) {
3619
- const p = (filePath ?? "").replace(/\\/g, "/");
3620
- return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
3621
- }
3622
- function ensureAgentPath(env = process.env) {
3623
- const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
3624
- const current = env.PATH ?? "";
3625
- const parts = current.split(import_node_path13.delimiter).filter(Boolean);
3626
- const seen = new Set(parts);
3627
- const extras = [
3628
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path13.join)(home, rel)),
3629
- "/opt/homebrew/bin",
3630
- "/usr/local/bin",
3631
- // Keep after Homebrew/npm so a user-installed CLI still wins.
3632
- conductorBundledBinDir(home)
3633
- ];
3634
- for (const dir of extras.reverse()) {
3635
- if (!dir || seen.has(dir) || !(0, import_node_fs12.existsSync)(dir)) continue;
3636
- parts.unshift(dir);
3637
- seen.add(dir);
3638
- }
3639
- const next = parts.join(import_node_path13.delimiter);
3640
- env.PATH = next;
3641
- return next;
3642
- }
3643
- function enrichPathWithNpmGlobalBin(env = process.env) {
3644
- ensureAgentPath(env);
3645
- try {
3646
- const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
3647
- encoding: "utf8",
3648
- env: { ...process.env, ...env },
3649
- timeout: 8e3,
3650
- stdio: ["ignore", "pipe", "ignore"]
3651
- }).trim().split(/\r?\n/).find(Boolean);
3652
- if (prefix) {
3653
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
3654
- prependPathDir(env, binDir);
3655
- }
3656
- } catch {
3657
- }
3658
- return env.PATH ?? "";
3659
- }
3660
- function posixShellSingleQuote(value) {
3661
- return `'${value.replace(/'/g, `'\\''`)}'`;
3662
- }
3663
- function resolveCommandBinarySync(command, whichPath) {
3664
- const trimmed = command.trim();
3665
- if (!trimmed) return trimmed;
3666
- const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
3667
- if (!match) return trimmed;
3668
- const bin = match[1];
3669
- const rest = match[2] ?? "";
3670
- if (bin.includes("/") || bin.includes("\\")) return trimmed;
3671
- const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
3672
- if (!abs) return trimmed;
3673
- return `${abs}${rest}`;
3674
- }
3675
- function withExportedPath(command, pathValue) {
3676
- const trimmed = command.trim();
3677
- if (!trimmed) return trimmed;
3678
- if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
3679
- return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
3680
- }
3681
- var import_node_fs12, import_node_child_process2, import_node_os5, import_node_path13, EXTRA_BIN_DIRS;
3682
- var init_path = __esm({
3683
- "src/agents/path.ts"() {
3684
- "use strict";
3685
- import_node_fs12 = require("fs");
3686
- import_node_child_process2 = require("child_process");
3687
- import_node_os5 = require("os");
3688
- import_node_path13 = require("path");
3689
- EXTRA_BIN_DIRS = [
3690
- ".local/bin",
3691
- ".cargo/bin",
3692
- ".nvm/current/bin",
3693
- ".asdf/shims",
3694
- ".volta/bin",
3695
- ".npm-global/bin",
3696
- // fnm default alias (common when shell init is skipped)
3697
- ".local/share/fnm/aliases/default/bin",
3698
- // pnpm / npm global bins (where `@brightsy/cli` typically lands)
3699
- "Library/pnpm",
3700
- ".pnpm"
3701
- ];
3702
- }
3703
- });
3704
-
3705
- // src/git/run.ts
3706
- var run_exports = {};
3707
- __export(run_exports, {
3708
- gh: () => gh,
3709
- git: () => git,
3710
- resolveGhAuthToken: () => resolveGhAuthToken,
3711
- run: () => run
3712
- });
3713
- async function run(file, args, opts) {
3714
- ensureAgentPath();
3715
- try {
3716
- const result = await (0, import_execa2.execa)(file, args, {
3717
- cwd: opts?.cwd,
3718
- env: { ...process.env, ...opts?.env },
3719
- reject: opts?.reject ?? true,
3720
- ...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
3721
- });
3722
- return {
3723
- stdout: result.stdout ?? "",
3724
- stderr: result.stderr ?? "",
3725
- exitCode: result.exitCode ?? 0
3726
- };
3727
- } catch (err) {
3728
- const e = err;
3729
- if (opts?.reject === false) {
3730
- return {
3731
- stdout: String(e.stdout ?? ""),
3732
- stderr: String(e.stderr ?? ""),
3733
- exitCode: e.exitCode ?? 1
3734
- };
3735
- }
3736
- throw err;
3737
- }
3738
- }
3739
- async function git(args, cwd, opts) {
3740
- const prefix = [];
3741
- if (opts?.config) {
3742
- for (const [key, value] of Object.entries(opts.config)) {
3743
- if (!key) continue;
3744
- prefix.push("-c", `${key}=${value}`);
3745
- }
3831
+ const trimmed = token.trim();
3832
+ if (!trimmed) return;
3833
+ const root = githubAgentAuthDir();
3834
+ (0, import_node_fs13.mkdirSync)(root, { recursive: true, mode: 448 });
3835
+ try {
3836
+ (0, import_node_fs13.chmodSync)(root, 448);
3837
+ } catch {
3746
3838
  }
3747
- return run("git", ["--no-pager", ...prefix, ...args], {
3748
- cwd,
3749
- reject: opts?.reject,
3750
- timeoutMs: opts?.timeoutMs,
3751
- // Never block forever on a credential/SSH prompt inside MCP / Electron.
3752
- env: {
3753
- GIT_TERMINAL_PROMPT: "0",
3754
- GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
3755
- SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
3756
- GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
3757
- GCM_INTERACTIVE: "never",
3758
- GH_PROMPT_DISABLED: "1",
3759
- ...opts?.env
3760
- }
3761
- });
3839
+ writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
3840
+ const ghDir = githubGhConfigDir();
3841
+ (0, import_node_fs13.mkdirSync)(ghDir, { recursive: true, mode: 448 });
3842
+ writePrivateFile2((0, import_node_path14.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
3843
+ writePrivateFile2((0, import_node_path14.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
3762
3844
  }
3763
- async function gh(args, cwd, opts) {
3764
- return run("gh", args, {
3765
- cwd,
3766
- reject: opts?.reject,
3767
- timeoutMs: opts?.timeoutMs,
3768
- env: {
3769
- GH_PROMPT_DISABLED: "1",
3770
- GIT_TERMINAL_PROMPT: "0"
3771
- }
3772
- });
3845
+ function githubAgentAuthReady() {
3846
+ return (0, import_node_fs13.existsSync)(githubCredentialStorePath()) && (0, import_node_fs13.existsSync)((0, import_node_path14.join)(githubGhConfigDir(), "hosts.yml"));
3773
3847
  }
3774
- async function resolveGhAuthToken(cwd) {
3775
- const result = await gh(["auth", "token"], cwd, { reject: false, timeoutMs: 8e3 });
3776
- if (result.exitCode !== 0) return null;
3777
- const token = result.stdout.trim();
3778
- return token || null;
3848
+ function githubCredentialHelperGitConfig() {
3849
+ const file = githubCredentialStorePath();
3850
+ return [
3851
+ { key: "credential.helper", value: "" },
3852
+ { key: "credential.helper", value: `store --file=${file}` }
3853
+ ];
3779
3854
  }
3780
- var import_execa2;
3781
- var init_run = __esm({
3782
- "src/git/run.ts"() {
3855
+ function githubGhConfigEnv() {
3856
+ return {
3857
+ GH_CONFIG_DIR: githubGhConfigDir(),
3858
+ GH_PROMPT_DISABLED: "1"
3859
+ };
3860
+ }
3861
+ var import_node_fs13, import_node_os5, import_node_path14;
3862
+ var init_github_agent_auth = __esm({
3863
+ "src/git/github-agent-auth.ts"() {
3783
3864
  "use strict";
3784
- import_execa2 = require("execa");
3785
- init_path();
3865
+ import_node_fs13 = require("fs");
3866
+ import_node_os5 = require("os");
3867
+ import_node_path14 = require("path");
3786
3868
  }
3787
3869
  });
3788
3870
 
@@ -3874,7 +3956,7 @@ async function warmGithubAgentAuth(opts) {
3874
3956
  }
3875
3957
  function normalizeWritableRoot(raw) {
3876
3958
  const trimmed = raw.trim().replace(/\/+$/, "");
3877
- return trimmed && (0, import_node_path14.isAbsolute)(trimmed) ? trimmed : null;
3959
+ return trimmed && (0, import_node_path15.isAbsolute)(trimmed) ? trimmed : null;
3878
3960
  }
3879
3961
  async function resolveCodexGitWritableRoots(cwd) {
3880
3962
  const roots = /* @__PURE__ */ new Set();
@@ -3951,11 +4033,11 @@ function formatGitAuthModeDirective(mode) {
3951
4033
  ].join("\n");
3952
4034
  }
3953
4035
  }
3954
- var import_node_path14, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
4036
+ var import_node_path15, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
3955
4037
  var init_git_auth_mode = __esm({
3956
4038
  "src/git/git-auth-mode.ts"() {
3957
4039
  "use strict";
3958
- import_node_path14 = require("path");
4040
+ import_node_path15 = require("path");
3959
4041
  init_app_settings();
3960
4042
  init_github_agent_auth();
3961
4043
  init_run();
@@ -5125,8 +5207,8 @@ function isLocalPrFetchBranch(ref) {
5125
5207
  }
5126
5208
  async function createThreadWorktree(opts) {
5127
5209
  let branchName = `thread/${opts.slug}`;
5128
- const worktreePath = (0, import_node_path15.join)(worktreesRoot(opts.repoPath), opts.slug);
5129
- if ((0, import_node_fs13.existsSync)(worktreePath)) {
5210
+ const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
5211
+ if ((0, import_node_fs14.existsSync)(worktreePath)) {
5130
5212
  throw new Error(`Worktree already exists at ${worktreePath}`);
5131
5213
  }
5132
5214
  await ensureGhPreferOrigin(opts.repoPath);
@@ -5193,8 +5275,8 @@ ${add.stdout}`;
5193
5275
  async function createExistingBranchWorktree(opts) {
5194
5276
  const branchName = opts.branchName.trim();
5195
5277
  if (!branchName) throw new Error("branch name required");
5196
- const worktreePath = (0, import_node_path15.join)(worktreesRoot(opts.repoPath), opts.slug);
5197
- if ((0, import_node_fs13.existsSync)(worktreePath)) {
5278
+ const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
5279
+ if ((0, import_node_fs14.existsSync)(worktreePath)) {
5198
5280
  throw new Error(`Worktree already exists at ${worktreePath}`);
5199
5281
  }
5200
5282
  await ensureGhPreferOrigin(opts.repoPath);
@@ -5485,10 +5567,10 @@ function sameRepoPath(a, b) {
5485
5567
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
5486
5568
  }
5487
5569
  function listLocalThreadBranchSlugs(repoPath) {
5488
- const refsDir = (0, import_node_path15.join)(repoPath, ".git", "refs", "heads", "thread");
5489
- if (!(0, import_node_fs13.existsSync)(refsDir)) return [];
5570
+ const refsDir = (0, import_node_path16.join)(repoPath, ".git", "refs", "heads", "thread");
5571
+ if (!(0, import_node_fs14.existsSync)(refsDir)) return [];
5490
5572
  try {
5491
- return (0, import_node_fs13.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
5573
+ return (0, import_node_fs14.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
5492
5574
  } catch {
5493
5575
  return [];
5494
5576
  }
@@ -5496,8 +5578,8 @@ function listLocalThreadBranchSlugs(repoPath) {
5496
5578
  function collectTakenTeamSlugs(repoPath) {
5497
5579
  const taken = /* @__PURE__ */ new Set();
5498
5580
  const root = worktreesRoot(repoPath);
5499
- if ((0, import_node_fs13.existsSync)(root)) {
5500
- for (const entry of (0, import_node_fs13.readdirSync)(root, { withFileTypes: true })) {
5581
+ if ((0, import_node_fs14.existsSync)(root)) {
5582
+ for (const entry of (0, import_node_fs14.readdirSync)(root, { withFileTypes: true })) {
5501
5583
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
5502
5584
  taken.add(normalizeTakenSlug(entry.name));
5503
5585
  }
@@ -5518,18 +5600,18 @@ function allocateTeamSlug(repoPath) {
5518
5600
  const taken = collectTakenTeamSlugs(repoPath);
5519
5601
  for (let attempt = 0; attempt < 32; attempt++) {
5520
5602
  const team = allocateTeamName(taken);
5521
- const path = (0, import_node_path15.join)(worktreesRoot(repoPath), team.slug);
5522
- if (!(0, import_node_fs13.existsSync)(path)) return team;
5603
+ const path = (0, import_node_path16.join)(worktreesRoot(repoPath), team.slug);
5604
+ if (!(0, import_node_fs14.existsSync)(path)) return team;
5523
5605
  taken.add(team.slug);
5524
5606
  }
5525
5607
  throw new Error("No available soccer team worktree directories left");
5526
5608
  }
5527
- var import_node_fs13, import_node_path15;
5609
+ var import_node_fs14, import_node_path16;
5528
5610
  var init_worktree = __esm({
5529
5611
  "src/git/worktree.ts"() {
5530
5612
  "use strict";
5531
- import_node_fs13 = require("fs");
5532
- import_node_path15 = require("path");
5613
+ import_node_fs14 = require("fs");
5614
+ import_node_path16 = require("path");
5533
5615
  init_paths();
5534
5616
  init_thread_store();
5535
5617
  init_teams();
@@ -5664,7 +5746,7 @@ function coordinatorTurnReminder(opts) {
5664
5746
  function ensureGlobalCoordinatorCwd(opts) {
5665
5747
  const dir = globalAgentCwd();
5666
5748
  try {
5667
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
5749
+ (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
5668
5750
  } catch {
5669
5751
  return dir;
5670
5752
  }
@@ -5672,7 +5754,7 @@ function ensureGlobalCoordinatorCwd(opts) {
5672
5754
  let orchId = opts?.orchestratorThreadId?.trim() || "";
5673
5755
  if (!orchId) {
5674
5756
  try {
5675
- const existing = (0, import_node_fs14.readFileSync)((0, import_node_path16.join)(dir, "AGENTS.md"), "utf8");
5757
+ const existing = (0, import_node_fs15.readFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), "utf8");
5676
5758
  const m = existing.match(
5677
5759
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
5678
5760
  );
@@ -5714,9 +5796,9 @@ function ensureGlobalCoordinatorCwd(opts) {
5714
5796
  "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
5715
5797
  ].join("\n");
5716
5798
  try {
5717
- (0, import_node_fs14.writeFileSync)((0, import_node_path16.join)(dir, "CLAUDE.md"), `${body}
5799
+ (0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "CLAUDE.md"), `${body}
5718
5800
  `, "utf8");
5719
- (0, import_node_fs14.writeFileSync)((0, import_node_path16.join)(dir, "AGENTS.md"), `${body}
5801
+ (0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), `${body}
5720
5802
  `, "utf8");
5721
5803
  } catch {
5722
5804
  }
@@ -5748,12 +5830,12 @@ function coordinatorSystemPrompt(opts) {
5748
5830
  formatWorkspaceInventory(opts.workspaces)
5749
5831
  ].join("\n");
5750
5832
  }
5751
- var import_node_fs14, import_node_path16, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5833
+ var import_node_fs15, import_node_path17, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5752
5834
  var init_coordinator_prompt = __esm({
5753
5835
  "src/orchestrator/coordinator-prompt.ts"() {
5754
5836
  "use strict";
5755
- import_node_fs14 = require("fs");
5756
- import_node_path16 = require("path");
5837
+ import_node_fs15 = require("fs");
5838
+ import_node_path17 = require("path");
5757
5839
  init_worktree();
5758
5840
  init_app_settings();
5759
5841
  init_paths();
@@ -5779,7 +5861,7 @@ var init_coordinator_prompt = __esm({
5779
5861
  "- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
5780
5862
  "- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
5781
5863
  "- send_to_thread \u2014 queue a prompt (start/continue a chat turn); pass force_stop: true to interrupt mid-turn / clear stale queued prompts before replacing with a new request",
5782
- "- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply. wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success.",
5864
+ "- wait_for_turn / get_turn_result \u2014 wait for and read the agent reply. wait_for_turn returns within ~45s even if the child is still working (MCP clients kill longer tool calls). If stillRunning is true, progress is a live snapshot of tools/thinking \u2014 call wait_for_turn again. status=queued with no lastActivityAt means the child has not started yet (concurrency cap) \u2014 keep waiting; do not force_stop or send a check-in. Do not send \u201Care you stuck?\u201D or assume a hang while lastActivityAt is recent. On status error, lastError (and text) is the failure \u2014 switch agent, tell the user, or retry; do not treat empty text as success.",
5783
5865
  "- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
5784
5866
  "- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
5785
5867
  "Setup / run:",
@@ -6051,32 +6133,32 @@ var init_global_workspace = __esm({
6051
6133
 
6052
6134
  // src/brightsy/config.ts
6053
6135
  function brightsyConfigPath() {
6054
- return (0, import_node_path17.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
6136
+ return (0, import_node_path18.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
6055
6137
  }
6056
6138
  function loadBrightsyConfig() {
6057
6139
  const path = brightsyConfigPath();
6058
- if (!(0, import_node_fs15.existsSync)(path)) {
6140
+ if (!(0, import_node_fs16.existsSync)(path)) {
6059
6141
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
6060
6142
  }
6061
- const raw = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
6143
+ const raw = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
6062
6144
  if (!raw.access_token || !raw.account_id) {
6063
6145
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
6064
6146
  }
6065
6147
  return raw;
6066
6148
  }
6067
6149
  function saveBrightsyConfig(cfg) {
6068
- (0, import_node_fs15.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
6150
+ (0, import_node_fs16.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
6069
6151
  `, {
6070
6152
  mode: 384
6071
6153
  });
6072
6154
  }
6073
- var import_node_fs15, import_node_os6, import_node_path17;
6155
+ var import_node_fs16, import_node_os6, import_node_path18;
6074
6156
  var init_config = __esm({
6075
6157
  "src/brightsy/config.ts"() {
6076
6158
  "use strict";
6077
- import_node_fs15 = require("fs");
6159
+ import_node_fs16 = require("fs");
6078
6160
  import_node_os6 = require("os");
6079
- import_node_path17 = require("path");
6161
+ import_node_path18 = require("path");
6080
6162
  }
6081
6163
  });
6082
6164
 
@@ -6091,22 +6173,22 @@ var init_accounts = __esm({
6091
6173
 
6092
6174
  // src/brightsy/connected-teams.ts
6093
6175
  function storePath4() {
6094
- return (0, import_node_path18.join)(appDataDir(), "brightsy-teams.json");
6176
+ return (0, import_node_path19.join)(appDataDir(), "brightsy-teams.json");
6095
6177
  }
6096
6178
  function readStore4() {
6097
6179
  const path = storePath4();
6098
- if (!(0, import_node_fs16.existsSync)(path)) return [];
6180
+ if (!(0, import_node_fs17.existsSync)(path)) return [];
6099
6181
  try {
6100
- const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
6182
+ const parsed = JSON.parse((0, import_node_fs17.readFileSync)(path, "utf8"));
6101
6183
  return Array.isArray(parsed.teams) ? parsed.teams : [];
6102
6184
  } catch {
6103
6185
  return [];
6104
6186
  }
6105
6187
  }
6106
6188
  function writeStore2(teams) {
6107
- (0, import_node_fs16.mkdirSync)(appDataDir(), { recursive: true });
6189
+ (0, import_node_fs17.mkdirSync)(appDataDir(), { recursive: true });
6108
6190
  const path = storePath4();
6109
- (0, import_node_fs16.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
6191
+ (0, import_node_fs17.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
6110
6192
  `, {
6111
6193
  mode: 384
6112
6194
  });
@@ -6218,12 +6300,12 @@ function brightsyMcpServerName(slug) {
6218
6300
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
6219
6301
  return `brightsy_${cleaned || "team"}`;
6220
6302
  }
6221
- var import_node_fs16, import_node_path18;
6303
+ var import_node_fs17, import_node_path19;
6222
6304
  var init_connected_teams = __esm({
6223
6305
  "src/brightsy/connected-teams.ts"() {
6224
6306
  "use strict";
6225
- import_node_fs16 = require("fs");
6226
- import_node_path18 = require("path");
6307
+ import_node_fs17 = require("fs");
6308
+ import_node_path19 = require("path");
6227
6309
  init_paths();
6228
6310
  init_accounts();
6229
6311
  init_config();
@@ -6554,11 +6636,11 @@ async function syncCliForTarget(accountId) {
6554
6636
  }
6555
6637
  applyConnectedTeamToCli(team);
6556
6638
  }
6557
- var import_node_fs17, brightsyAdapter;
6639
+ var import_node_fs18, brightsyAdapter;
6558
6640
  var init_brightsy = __esm({
6559
6641
  "src/agents/brightsy.ts"() {
6560
6642
  "use strict";
6561
- import_node_fs17 = require("fs");
6643
+ import_node_fs18 = require("fs");
6562
6644
  init_run();
6563
6645
  init_connected_teams();
6564
6646
  init_config();
@@ -6573,7 +6655,7 @@ var init_brightsy = __esm({
6573
6655
  async detect() {
6574
6656
  const brightsy = resolveAgentExecutable("brightsy");
6575
6657
  if (brightsy !== "brightsy") {
6576
- if (!(0, import_node_fs17.existsSync)(brightsy)) {
6658
+ if (!(0, import_node_fs18.existsSync)(brightsy)) {
6577
6659
  return {
6578
6660
  agent: "brightsy",
6579
6661
  installed: false,
@@ -6742,9 +6824,9 @@ function toolDescription(name, input) {
6742
6824
  if (/connectedAgentRequest/i.test(name)) {
6743
6825
  return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
6744
6826
  }
6745
- if (desc && kind) return `${kind}: ${desc}`;
6746
- if (desc) return desc;
6747
- return "Subagent";
6827
+ if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
6828
+ if (desc) return `${desc}${subagentLiveSuffix(input)}`;
6829
+ return `Subagent${subagentLiveSuffix(input)}`;
6748
6830
  }
6749
6831
  if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
6750
6832
  return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
@@ -6769,13 +6851,83 @@ function toolDescription(name, input) {
6769
6851
  }
6770
6852
  if (/grep/i.test(name)) return "Search files";
6771
6853
  if (/glob/i.test(name)) return "Find files";
6854
+ const compact = n.replace(/[_-]/g, "");
6855
+ if (/^taskoutput$/i.test(compact)) {
6856
+ return str2(input.task_id) ? `Wait for ${str2(input.task_id)}` : "Wait for background task";
6857
+ }
6858
+ if (/^taskstop$/i.test(compact)) {
6859
+ return str2(input.task_id) ? `Stop ${str2(input.task_id)}` : "Stop background task";
6860
+ }
6861
+ if (/^monitor$/i.test(compact)) {
6862
+ const command = str2(input.command);
6863
+ return command ? `Watch ${command.length > 48 ? `${command.slice(0, 45)}\u2026` : command}` : "Watch command";
6864
+ }
6772
6865
  return n;
6773
6866
  }
6867
+ function subagentLiveSuffix(input) {
6868
+ if (!input) return "";
6869
+ const bits = [];
6870
+ const status = str2(input.live_status);
6871
+ if (status && !/^runn(ing)?$|^working$/i.test(status)) bits.push(status);
6872
+ if (typeof input.live_tool_uses === "number") bits.push(`${input.live_tool_uses} tools`);
6873
+ if (typeof input.live_duration_ms === "number") {
6874
+ bits.push(`${Math.max(0, Math.round(Number(input.live_duration_ms) / 1e3))}s`);
6875
+ }
6876
+ const last = str2(input.live_last_tool);
6877
+ if (last) bits.push(last);
6878
+ return bits.length ? ` \xB7 ${bits.join(" \xB7 ")}` : "";
6879
+ }
6774
6880
  function isSubagentToolName(name) {
6775
6881
  const n = (name ?? "").trim();
6776
6882
  if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
6777
6883
  return /connectedAgentRequest/i.test(n);
6778
6884
  }
6885
+ function isPollWrapperToolName(name) {
6886
+ const n = (name ?? "").replace(/[_-]/g, "");
6887
+ return /^(taskoutput|taskstop|sleep)$/i.test(n);
6888
+ }
6889
+ function lastTextPart(parts, type) {
6890
+ for (let i = parts.length - 1; i >= 0; i--) {
6891
+ const p = parts[i];
6892
+ if (p.type === type && p.text.trim()) return p.text.trim();
6893
+ }
6894
+ return "";
6895
+ }
6896
+ function toolLabel(tool) {
6897
+ return tool.description || toolDescription(tool.name, tool.input) || tool.name;
6898
+ }
6899
+ function liveActivitySummary(parts, opts) {
6900
+ if (opts?.queued && parts.length === 0) {
6901
+ return "Queued \u2014 waiting for a slot";
6902
+ }
6903
+ const tools = parts.filter((p) => p.type === "tool");
6904
+ const runningSubs = tools.filter(
6905
+ (t) => t.status === "running" && !t.parentId && isSubagentToolName(t.name)
6906
+ );
6907
+ const runningNested = [...tools].reverse().find((t) => t.status === "running" && t.parentId && !isPollWrapperToolName(t.name));
6908
+ const runningTop = [...tools].reverse().find(
6909
+ (t) => t.status === "running" && !t.parentId && !isPollWrapperToolName(t.name) && !isSubagentToolName(t.name)
6910
+ );
6911
+ const runningPoll = [...tools].reverse().find((t) => t.status === "running" && isPollWrapperToolName(t.name));
6912
+ const thinking = lastTextPart(parts, "thinking");
6913
+ const text4 = lastTextPart(parts, "text");
6914
+ if (runningSubs.length > 0) {
6915
+ const heads = runningSubs.map(toolLabel);
6916
+ const head = runningSubs.length === 1 ? heads[0] : `${runningSubs.length} subagents \xB7 ${heads.slice(0, 2).join(" \xB7 ")}`;
6917
+ if (runningNested) return `${head} \xB7 ${toolLabel(runningNested)}`;
6918
+ return head;
6919
+ }
6920
+ if (runningTop) return toolLabel(runningTop);
6921
+ if (runningPoll) return toolLabel(runningPoll);
6922
+ if (thinking) return thinking.length > 96 ? `\u2026${thinking.slice(-96)}` : thinking;
6923
+ if (text4) return "Writing reply\u2026";
6924
+ const last = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? tools.at(-1);
6925
+ if (last) {
6926
+ const label = toolLabel(last);
6927
+ return last.status === "running" ? label : `Finished ${label}`;
6928
+ }
6929
+ return "Working\u2026";
6930
+ }
6779
6931
  function messagePartParentId(part) {
6780
6932
  if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
6781
6933
  return part.parentId;
@@ -6857,6 +7009,25 @@ function applyAgentEvent(parts, event) {
6857
7009
  const data = event.data;
6858
7010
  if (!data) return parts;
6859
7011
  const next = [...parts];
7012
+ if (event.replace) {
7013
+ for (let i = next.length - 1; i >= 0; i--) {
7014
+ const prev = next[i];
7015
+ if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
7016
+ next[i] = {
7017
+ type: "thinking",
7018
+ text: data,
7019
+ ...event.parentId ? { parentId: event.parentId } : {}
7020
+ };
7021
+ return next;
7022
+ }
7023
+ }
7024
+ next.push({
7025
+ type: "thinking",
7026
+ text: data,
7027
+ ...event.parentId ? { parentId: event.parentId } : {}
7028
+ });
7029
+ return next;
7030
+ }
6860
7031
  const last = next[next.length - 1];
6861
7032
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
6862
7033
  next[next.length - 1] = {
@@ -6880,14 +7051,18 @@ function applyAgentEvent(parts, event) {
6880
7051
  if (existing >= 0) {
6881
7052
  const prev = parts[existing];
6882
7053
  const next = [...parts];
6883
- const mergedInput = input && Object.keys(input).length > 0 ? input : prev.input ?? input;
7054
+ const mergedInput = {
7055
+ ...prev.input ?? {},
7056
+ ...input ?? {}
7057
+ };
7058
+ const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
6884
7059
  next[existing] = {
6885
7060
  ...prev,
6886
7061
  name: event.name || prev.name,
6887
- input: mergedInput,
6888
- description: toolDescription(event.name || prev.name, mergedInput),
6889
- detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
6890
- filePath: toolFilePath(mergedInput) ?? prev.filePath,
7062
+ input: mergedRecord,
7063
+ description: toolDescription(event.name || prev.name, mergedRecord),
7064
+ detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
7065
+ filePath: toolFilePath(mergedRecord) ?? prev.filePath,
6891
7066
  additions: diff.additions ?? prev.additions,
6892
7067
  deletions: diff.deletions ?? prev.deletions,
6893
7068
  parentId: event.parentId ?? prev.parentId
@@ -6998,47 +7173,68 @@ function electronResourcesPath() {
6998
7173
  function packagedCursorRuntimeDir() {
6999
7174
  const resources = electronResourcesPath();
7000
7175
  if (!resources) return null;
7001
- const dir = (0, import_node_path19.join)(resources, "cursor-runtime");
7002
- if (!(0, import_node_fs18.existsSync)((0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
7176
+ const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
7177
+ if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
7003
7178
  return dir;
7004
7179
  }
7005
7180
  function packagedCursorRunnerPath() {
7006
7181
  const dir = packagedCursorRuntimeDir();
7007
- return dir ? (0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
7182
+ return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
7008
7183
  }
7009
7184
  function packagedMcpDir() {
7010
7185
  const resources = electronResourcesPath();
7011
7186
  if (!resources) return null;
7012
- const dir = (0, import_node_path19.join)(resources, "sideboard-mcp");
7013
- if (!(0, import_node_fs18.existsSync)((0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
7187
+ const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
7188
+ if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
7014
7189
  return dir;
7015
7190
  }
7016
7191
  function packagedMcpStdioPath() {
7017
7192
  const dir = packagedMcpDir();
7018
- return dir ? (0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
7193
+ return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
7019
7194
  }
7020
7195
  function packagedBundledNodePath() {
7021
7196
  const resources = electronResourcesPath();
7022
7197
  if (!resources) return null;
7023
- const bin = (0, import_node_path19.join)(resources, "node", "bin", "node");
7024
- if (!(0, import_node_fs18.existsSync)(bin)) return null;
7198
+ const bin = (0, import_node_path20.join)(resources, "node", "bin", "node");
7199
+ if (!(0, import_node_fs19.existsSync)(bin)) return null;
7025
7200
  return bin;
7026
7201
  }
7027
7202
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
7028
7203
  const dir = packagedCursorRuntimeDir();
7029
7204
  if (!dir) return null;
7030
- return (0, import_node_path19.join)(dir, "node_modules", platformPkg, "bin", binName);
7205
+ return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
7031
7206
  }
7032
- var import_node_fs18, import_node_path19;
7207
+ var import_node_fs19, import_node_path20;
7033
7208
  var init_packaged_runtime = __esm({
7034
7209
  "src/agents/packaged-runtime.ts"() {
7035
7210
  "use strict";
7036
- import_node_fs18 = require("fs");
7037
- import_node_path19 = require("path");
7211
+ import_node_fs19 = require("fs");
7212
+ import_node_path20 = require("path");
7038
7213
  }
7039
7214
  });
7040
7215
 
7041
7216
  // src/agents/node-launch.ts
7217
+ function withMaxOldSpaceSize(nodeOptions, heapMb) {
7218
+ const existing = (nodeOptions ?? "").trim();
7219
+ const match = MAX_OLD_SPACE_FLAG.exec(existing);
7220
+ if (match) {
7221
+ const current = match[2] ? Number(match[2]) : 0;
7222
+ if (Number.isFinite(current) && current >= heapMb) return existing;
7223
+ return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
7224
+ }
7225
+ return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
7226
+ }
7227
+ function applyAgentRunnerHeapEnv(env) {
7228
+ env.NODE_OPTIONS = withMaxOldSpaceSize(
7229
+ env.NODE_OPTIONS,
7230
+ AGENT_RUNNER_MAX_OLD_SPACE_MB
7231
+ );
7232
+ }
7233
+ function envWithAgentHeap(env) {
7234
+ const next = { ...env };
7235
+ applyAgentRunnerHeapEnv(next);
7236
+ return next;
7237
+ }
7042
7238
  function isAsarPath(filePath) {
7043
7239
  if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
7044
7240
  return /\.asar([/\\]|$)/.test(filePath);
@@ -7047,7 +7243,7 @@ function unpackedAsarPath(filePath) {
7047
7243
  if (!isAsarPath(filePath)) return null;
7048
7244
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
7049
7245
  if (unpacked === filePath) return null;
7050
- return (0, import_node_fs19.existsSync)(unpacked) ? unpacked : null;
7246
+ return (0, import_node_fs20.existsSync)(unpacked) ? unpacked : null;
7051
7247
  }
7052
7248
  function nodeReadableScriptPath(scriptPath) {
7053
7249
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -7087,37 +7283,37 @@ function pickPreferredNode(candidates) {
7087
7283
  return best;
7088
7284
  }
7089
7285
  function versionDirNodeBins(root, toBin) {
7090
- if (!(0, import_node_fs19.existsSync)(root)) return [];
7286
+ if (!(0, import_node_fs20.existsSync)(root)) return [];
7091
7287
  try {
7092
- return (0, import_node_fs19.readdirSync)(root).map(toBin);
7288
+ return (0, import_node_fs20.readdirSync)(root).map(toBin);
7093
7289
  } catch {
7094
7290
  return [];
7095
7291
  }
7096
7292
  }
7097
7293
  function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
7098
7294
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
7099
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path20.join)(prefix, "opt", `node@${major}`, "bin", "node"))
7295
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path21.join)(prefix, "opt", `node@${major}`, "bin", "node"))
7100
7296
  );
7101
7297
  return [
7102
7298
  ...kegs,
7103
7299
  "/opt/homebrew/bin/node",
7104
7300
  "/usr/local/bin/node",
7105
- (0, import_node_path20.join)(home, ".local/share/fnm/aliases/default/bin/node"),
7106
- (0, import_node_path20.join)(home, ".nvm/current/bin/node"),
7107
- (0, import_node_path20.join)(home, ".volta/bin/node"),
7108
- (0, import_node_path20.join)(home, ".asdf/shims/node"),
7109
- (0, import_node_path20.join)(home, ".local/share/mise/shims/node"),
7301
+ (0, import_node_path21.join)(home, ".local/share/fnm/aliases/default/bin/node"),
7302
+ (0, import_node_path21.join)(home, ".nvm/current/bin/node"),
7303
+ (0, import_node_path21.join)(home, ".volta/bin/node"),
7304
+ (0, import_node_path21.join)(home, ".asdf/shims/node"),
7305
+ (0, import_node_path21.join)(home, ".local/share/mise/shims/node"),
7110
7306
  ...versionDirNodeBins(
7111
- (0, import_node_path20.join)(home, ".nvm", "versions", "node"),
7112
- (name) => (0, import_node_path20.join)(home, ".nvm", "versions", "node", name, "bin", "node")
7307
+ (0, import_node_path21.join)(home, ".nvm", "versions", "node"),
7308
+ (name) => (0, import_node_path21.join)(home, ".nvm", "versions", "node", name, "bin", "node")
7113
7309
  ),
7114
7310
  ...versionDirNodeBins(
7115
- (0, import_node_path20.join)(home, ".local/share/fnm", "node-versions"),
7116
- (name) => (0, import_node_path20.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
7311
+ (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions"),
7312
+ (name) => (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
7117
7313
  ),
7118
7314
  ...versionDirNodeBins(
7119
- (0, import_node_path20.join)(home, ".volta", "tools", "image", "node"),
7120
- (name) => (0, import_node_path20.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
7315
+ (0, import_node_path21.join)(home, ".volta", "tools", "image", "node"),
7316
+ (name) => (0, import_node_path21.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
7121
7317
  )
7122
7318
  ];
7123
7319
  }
@@ -7126,10 +7322,10 @@ function uniqueExistingNodeBins(paths) {
7126
7322
  const out = [];
7127
7323
  for (const raw of paths) {
7128
7324
  const p = raw.trim();
7129
- if (!p || !(0, import_node_fs19.existsSync)(p) || isElectronLikeCommand(p)) continue;
7325
+ if (!p || !(0, import_node_fs20.existsSync)(p) || isElectronLikeCommand(p)) continue;
7130
7326
  let key = p;
7131
7327
  try {
7132
- key = (0, import_node_fs19.realpathSync)(p);
7328
+ key = (0, import_node_fs20.realpathSync)(p);
7133
7329
  } catch {
7134
7330
  continue;
7135
7331
  }
@@ -7174,13 +7370,21 @@ async function findSystemNode() {
7174
7370
  function applyNodeLaunch(launch, args) {
7175
7371
  const readableArgs = args.map(nodeReadableScriptPath);
7176
7372
  if (!launch.env.ELECTRON_RUN_AS_NODE) {
7177
- return { file: launch.file, args: readableArgs, env: launch.env };
7373
+ return {
7374
+ file: launch.file,
7375
+ args: readableArgs,
7376
+ env: envWithAgentHeap(launch.env)
7377
+ };
7178
7378
  }
7179
7379
  const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
7180
7380
  if (process.platform === "win32") {
7181
- return { file: wrapped.file, args: wrapped.args, env: launch.env };
7381
+ return {
7382
+ file: wrapped.file,
7383
+ args: wrapped.args,
7384
+ env: envWithAgentHeap(launch.env)
7385
+ };
7182
7386
  }
7183
- const env = { ...launch.env };
7387
+ const env = envWithAgentHeap(launch.env);
7184
7388
  delete env.ELECTRON_RUN_AS_NODE;
7185
7389
  return { file: wrapped.file, args: wrapped.args, env };
7186
7390
  }
@@ -7201,16 +7405,18 @@ async function resolveNodeLaunch(scriptPath) {
7201
7405
  env: { ELECTRON_RUN_AS_NODE: "1" }
7202
7406
  };
7203
7407
  }
7204
- var import_node_fs19, import_node_os7, import_node_path20, PREFERRED_LTS_MAJORS;
7408
+ var import_node_fs20, import_node_os7, import_node_path21, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
7205
7409
  var init_node_launch = __esm({
7206
7410
  "src/agents/node-launch.ts"() {
7207
7411
  "use strict";
7208
- import_node_fs19 = require("fs");
7412
+ import_node_fs20 = require("fs");
7209
7413
  import_node_os7 = require("os");
7210
- import_node_path20 = require("path");
7414
+ import_node_path21 = require("path");
7211
7415
  init_nested_electron_env();
7212
7416
  init_run();
7213
7417
  init_packaged_runtime();
7418
+ AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
7419
+ MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
7214
7420
  PREFERRED_LTS_MAJORS = [24, 22, 20];
7215
7421
  }
7216
7422
  });
@@ -7298,37 +7504,37 @@ function corePackageDir() {
7298
7504
  try {
7299
7505
  const url = import_meta.url;
7300
7506
  if (typeof url === "string" && url.length > 0) {
7301
- return (0, import_node_path21.dirname)((0, import_node_url.fileURLToPath)(url));
7507
+ return (0, import_node_path22.dirname)((0, import_node_url.fileURLToPath)(url));
7302
7508
  }
7303
7509
  } catch {
7304
7510
  }
7305
7511
  try {
7306
- const req = (0, import_node_module.createRequire)((0, import_node_path21.join)(process.cwd(), "package.json"));
7307
- return (0, import_node_path21.dirname)(req.resolve("@sideboard-ai/core"));
7512
+ const req = (0, import_node_module.createRequire)((0, import_node_path22.join)(process.cwd(), "package.json"));
7513
+ return (0, import_node_path22.dirname)(req.resolve("@sideboard-ai/core"));
7308
7514
  } catch {
7309
7515
  return process.cwd();
7310
7516
  }
7311
7517
  }
7312
7518
  function findSideboardMcpJsEntry() {
7313
7519
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
7314
- if (override && (0, import_node_fs20.existsSync)(override)) return override;
7520
+ if (override && (0, import_node_fs21.existsSync)(override)) return override;
7315
7521
  const packaged = packagedMcpStdioPath();
7316
7522
  if (packaged) return packaged;
7317
7523
  let dir = corePackageDir();
7318
7524
  for (let i = 0; i < 10; i++) {
7319
7525
  const candidates = [
7320
- (0, import_node_path21.join)(dir, "mcp/run-stdio.js"),
7321
- (0, import_node_path21.join)(dir, "mcp/run-stdio.cjs"),
7322
- (0, import_node_path21.join)(dir, "dist/mcp/run-stdio.js"),
7323
- (0, import_node_path21.join)(dir, "dist/mcp/run-stdio.cjs"),
7324
- (0, import_node_path21.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
7325
- (0, import_node_path21.join)(dir, "packages/cli/dist/index.js"),
7326
- (0, import_node_path21.join)(dir, "cli/dist/index.js")
7526
+ (0, import_node_path22.join)(dir, "mcp/run-stdio.js"),
7527
+ (0, import_node_path22.join)(dir, "mcp/run-stdio.cjs"),
7528
+ (0, import_node_path22.join)(dir, "dist/mcp/run-stdio.js"),
7529
+ (0, import_node_path22.join)(dir, "dist/mcp/run-stdio.cjs"),
7530
+ (0, import_node_path22.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
7531
+ (0, import_node_path22.join)(dir, "packages/cli/dist/index.js"),
7532
+ (0, import_node_path22.join)(dir, "cli/dist/index.js")
7327
7533
  ];
7328
7534
  for (const p of candidates) {
7329
- if ((0, import_node_fs20.existsSync)(p) && !isAsarPath(p)) return p;
7535
+ if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
7330
7536
  }
7331
- const parent = (0, import_node_path21.dirname)(dir);
7537
+ const parent = (0, import_node_path22.dirname)(dir);
7332
7538
  if (parent === dir) break;
7333
7539
  dir = parent;
7334
7540
  }
@@ -7376,6 +7582,7 @@ async function buildInjectedMcpServers(opts) {
7376
7582
  );
7377
7583
  } catch {
7378
7584
  }
7585
+ applyAgentRunnerHeapEnv(sideboard.env);
7379
7586
  servers.push(sideboard);
7380
7587
  }
7381
7588
  if (opts.includeBrightsy && isBrightsyConnected()) {
@@ -7469,19 +7676,19 @@ function writeMcpServersConfig(servers) {
7469
7676
  ...env ? { env } : {}
7470
7677
  };
7471
7678
  }
7472
- const dir = (0, import_node_fs20.mkdtempSync)((0, import_node_path21.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7473
- const cfgPath = (0, import_node_path21.join)(dir, "mcp.json");
7474
- (0, import_node_fs20.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7679
+ const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path22.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7680
+ const cfgPath = (0, import_node_path22.join)(dir, "mcp.json");
7681
+ (0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7475
7682
  return cfgPath;
7476
7683
  }
7477
- var import_node_fs20, import_node_module, import_node_os8, import_node_path21, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
7684
+ var import_node_fs21, import_node_module, import_node_os8, import_node_path22, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
7478
7685
  var init_injected_mcp = __esm({
7479
7686
  "src/agents/injected-mcp.ts"() {
7480
7687
  "use strict";
7481
- import_node_fs20 = require("fs");
7688
+ import_node_fs21 = require("fs");
7482
7689
  import_node_module = require("module");
7483
7690
  import_node_os8 = require("os");
7484
- import_node_path21 = require("path");
7691
+ import_node_path22 = require("path");
7485
7692
  import_node_url = require("url");
7486
7693
  init_run();
7487
7694
  init_config();
@@ -7655,6 +7862,80 @@ function claudeParentToolUseId(obj) {
7655
7862
  }
7656
7863
  return void 0;
7657
7864
  }
7865
+ function claudeString(obj, key) {
7866
+ const v = obj[key];
7867
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
7868
+ }
7869
+ function eventsFromClaudeSystem(obj) {
7870
+ const subtype = claudeString(obj, "subtype") ?? "";
7871
+ const parentId = claudeParentToolUseId(obj);
7872
+ if (subtype === "init") {
7873
+ if (parentId) return null;
7874
+ const sid = claudeString(obj, "session_id");
7875
+ return sid ? { type: "session_id", data: sid } : null;
7876
+ }
7877
+ if (subtype === "task_started") {
7878
+ const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
7879
+ if (!id) return null;
7880
+ const description = claudeString(obj, "description");
7881
+ const taskType = claudeString(obj, "task_type");
7882
+ const prompt = claudeString(obj, "prompt");
7883
+ return withEventParentId(
7884
+ {
7885
+ type: "tool_use",
7886
+ id,
7887
+ name: taskType || "Agent",
7888
+ input: {
7889
+ ...description ? { description } : {},
7890
+ ...prompt ? { prompt } : {},
7891
+ ...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
7892
+ }
7893
+ },
7894
+ parentId
7895
+ );
7896
+ }
7897
+ if (subtype === "task_notification") {
7898
+ const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
7899
+ if (!id) return null;
7900
+ const status = claudeString(obj, "status") ?? "working";
7901
+ const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
7902
+ const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
7903
+ const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
7904
+ const snapshot = [
7905
+ status,
7906
+ tools != null ? `${tools} tools` : null,
7907
+ durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
7908
+ lastTool
7909
+ ].filter((bit) => Boolean(bit)).join(" \xB7 ");
7910
+ return [
7911
+ {
7912
+ type: "tool_use",
7913
+ id,
7914
+ name: claudeString(obj, "task_type") || "Agent",
7915
+ input: {
7916
+ live_status: status,
7917
+ ...tools != null ? { live_tool_uses: tools } : {},
7918
+ ...durationMs != null ? { live_duration_ms: durationMs } : {},
7919
+ ...lastTool ? { live_last_tool: lastTool } : {}
7920
+ }
7921
+ },
7922
+ withEventParentId(
7923
+ { type: "thinking", data: snapshot, replace: true },
7924
+ id
7925
+ )
7926
+ ];
7927
+ }
7928
+ if (subtype === "api_retry") {
7929
+ const attempt = obj.attempt;
7930
+ const max = obj.max_retries;
7931
+ const delay = obj.retry_delay_ms;
7932
+ return {
7933
+ type: "thinking",
7934
+ data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
7935
+ };
7936
+ }
7937
+ return null;
7938
+ }
7658
7939
  function parseIssuesJson(raw) {
7659
7940
  const text4 = raw.trim();
7660
7941
  const candidates = [text4];
@@ -7680,11 +7961,11 @@ function parseIssuesJson(raw) {
7680
7961
  }
7681
7962
  return [];
7682
7963
  }
7683
- var import_node_fs21, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
7964
+ var import_node_fs22, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
7684
7965
  var init_claude = __esm({
7685
7966
  "src/agents/claude.ts"() {
7686
7967
  "use strict";
7687
- import_node_fs21 = require("fs");
7968
+ import_node_fs22 = require("fs");
7688
7969
  init_run();
7689
7970
  init_app_settings();
7690
7971
  init_claude_mcp();
@@ -7704,8 +7985,14 @@ var init_claude = __esm({
7704
7985
  "WebSearch",
7705
7986
  // Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
7706
7987
  "Task",
7707
- "Agent"
7988
+ "Agent",
7989
+ "TaskOutput",
7990
+ "TaskStop",
7991
+ "EnterWorktree",
7992
+ "ExitWorktree",
7993
+ "Skill"
7708
7994
  ];
7995
+ CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
7709
7996
  CLAUDE_CHROME_ALLOWED_TOOLS = [
7710
7997
  "mcp__claude-in-chrome",
7711
7998
  "mcp__claude-in-chrome__*",
@@ -7717,7 +8004,7 @@ var init_claude = __esm({
7717
8004
  async detect() {
7718
8005
  const claude = resolveClaudeExecutable();
7719
8006
  if (claude !== "claude") {
7720
- if (!(0, import_node_fs21.existsSync)(claude)) {
8007
+ if (!(0, import_node_fs22.existsSync)(claude)) {
7721
8008
  return {
7722
8009
  agent: "claude",
7723
8010
  installed: false,
@@ -7834,7 +8121,12 @@ var init_claude = __esm({
7834
8121
  stdin: useStdin ? `${promptText}
7835
8122
  ` : void 0,
7836
8123
  // Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
7837
- env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
8124
+ // Raise the -p background-agent wait so long TaskOutput polls are not
8125
+ // abandoned at Claude Code’s 10-minute default.
8126
+ env: {
8127
+ CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
8128
+ CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
8129
+ }
7838
8130
  };
7839
8131
  },
7840
8132
  parseEvent(line) {
@@ -7842,13 +8134,8 @@ var init_claude = __esm({
7842
8134
  if (!trimmed) return null;
7843
8135
  try {
7844
8136
  const obj = JSON.parse(trimmed);
7845
- if (obj.type === "system" && obj.subtype === "init") {
7846
- const sid = obj.session_id;
7847
- if (typeof sid === "string") return { type: "session_id", data: sid };
7848
- return null;
7849
- }
7850
- if (obj.type === "system" && typeof obj.session_id === "string") {
7851
- return { type: "session_id", data: obj.session_id };
8137
+ if (obj.type === "system") {
8138
+ return eventsFromClaudeSystem(obj);
7852
8139
  }
7853
8140
  if (obj.type === "assistant" || obj.type === "user") {
7854
8141
  const parentId = claudeParentToolUseId(obj);
@@ -7968,7 +8255,7 @@ async function listCodexModels() {
7968
8255
  if (codex === "codex") {
7969
8256
  const which = await run("which", ["codex"], { reject: false });
7970
8257
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
7971
- } else if (!(0, import_node_fs22.existsSync)(codex)) {
8258
+ } else if (!(0, import_node_fs23.existsSync)(codex)) {
7972
8259
  return FALLBACK_CODEX_MODELS;
7973
8260
  }
7974
8261
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -8003,12 +8290,12 @@ function usageFromCodex(usage) {
8003
8290
  }
8004
8291
  function codexConfigHasNetworkAccess() {
8005
8292
  const candidates = [
8006
- (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
8007
- (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
8293
+ (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
8294
+ (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
8008
8295
  ];
8009
8296
  for (const path of candidates) {
8010
- if (!(0, import_node_fs22.existsSync)(path)) continue;
8011
- const text4 = (0, import_node_fs22.readFileSync)(path, "utf8");
8297
+ if (!(0, import_node_fs23.existsSync)(path)) continue;
8298
+ const text4 = (0, import_node_fs23.readFileSync)(path, "utf8");
8012
8299
  if (/network_access\s*=\s*true/.test(text4)) return true;
8013
8300
  }
8014
8301
  return false;
@@ -8040,21 +8327,21 @@ function asRecord2(value) {
8040
8327
  return void 0;
8041
8328
  }
8042
8329
  function codexLooksAuthenticated() {
8043
- const authPath = (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
8044
- if (!(0, import_node_fs22.existsSync)(authPath)) return false;
8330
+ const authPath = (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
8331
+ if (!(0, import_node_fs23.existsSync)(authPath)) return false;
8045
8332
  try {
8046
- return (0, import_node_fs22.statSync)(authPath).size > 2;
8333
+ return (0, import_node_fs23.statSync)(authPath).size > 2;
8047
8334
  } catch {
8048
8335
  return false;
8049
8336
  }
8050
8337
  }
8051
- var import_node_fs22, import_node_os9, import_node_path22, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
8338
+ var import_node_fs23, import_node_os9, import_node_path23, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
8052
8339
  var init_codex = __esm({
8053
8340
  "src/agents/codex.ts"() {
8054
8341
  "use strict";
8055
- import_node_fs22 = require("fs");
8342
+ import_node_fs23 = require("fs");
8056
8343
  import_node_os9 = require("os");
8057
- import_node_path22 = require("path");
8344
+ import_node_path23 = require("path");
8058
8345
  init_run();
8059
8346
  init_app_settings();
8060
8347
  init_global_workspace();
@@ -8079,7 +8366,7 @@ var init_codex = __esm({
8079
8366
  async detect() {
8080
8367
  const codex = resolveAgentExecutable("codex");
8081
8368
  if (codex !== "codex") {
8082
- if (!(0, import_node_fs22.existsSync)(codex)) {
8369
+ if (!(0, import_node_fs23.existsSync)(codex)) {
8083
8370
  return {
8084
8371
  agent: "codex",
8085
8372
  installed: false,
@@ -8268,9 +8555,6 @@ var init_codex = __esm({
8268
8555
  if (sid && (type === "thread.started" || type === "session" || !type)) {
8269
8556
  return { type: "session_id", data: sid };
8270
8557
  }
8271
- if (sid && type.endsWith(".started")) {
8272
- return { type: "session_id", data: sid };
8273
- }
8274
8558
  if (type === "turn.completed" || type === "turn_completed") {
8275
8559
  const usage = usageFromCodex(obj.usage);
8276
8560
  return usage ? { type: "usage", data: usage, scope: "turn" } : null;
@@ -8518,21 +8802,21 @@ function platformRipgrepPackage() {
8518
8802
  }
8519
8803
  function usableRipgrepPath(candidate) {
8520
8804
  const raw = candidate?.trim();
8521
- if (!raw || !(0, import_node_path23.isAbsolute)(raw)) return null;
8805
+ if (!raw || !(0, import_node_path24.isAbsolute)(raw)) return null;
8522
8806
  const readable = nodeReadableScriptPath(raw);
8523
- if (!(0, import_node_fs23.existsSync)(readable) || isAsarPath(readable)) return null;
8807
+ if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
8524
8808
  return readable;
8525
8809
  }
8526
8810
  function walkForBundledRipgrep(startFile) {
8527
8811
  if (!startFile) return null;
8528
8812
  const pkg = platformRipgrepPackage();
8529
8813
  const name = rgBinaryName();
8530
- let dir = (0, import_node_path23.dirname)((0, import_node_path23.resolve)(startFile));
8531
- const root = (0, import_node_path23.parse)(dir).root;
8814
+ let dir = (0, import_node_path24.dirname)((0, import_node_path24.resolve)(startFile));
8815
+ const root = (0, import_node_path24.parse)(dir).root;
8532
8816
  while (dir !== root) {
8533
- const hit = usableRipgrepPath((0, import_node_path23.join)(dir, "node_modules", pkg, "bin", name));
8817
+ const hit = usableRipgrepPath((0, import_node_path24.join)(dir, "node_modules", pkg, "bin", name));
8534
8818
  if (hit) return hit;
8535
- const next = (0, import_node_path23.dirname)(dir);
8819
+ const next = (0, import_node_path24.dirname)(dir);
8536
8820
  if (next === dir) break;
8537
8821
  dir = next;
8538
8822
  }
@@ -8542,7 +8826,7 @@ function requireResolveBundledRipgrep(fromFile) {
8542
8826
  try {
8543
8827
  const req = (0, import_node_module2.createRequire)(fromFile);
8544
8828
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
8545
- return usableRipgrepPath((0, import_node_path23.join)((0, import_node_path23.dirname)(pkgJson), "bin", rgBinaryName()));
8829
+ return usableRipgrepPath((0, import_node_path24.join)((0, import_node_path24.dirname)(pkgJson), "bin", rgBinaryName()));
8546
8830
  } catch {
8547
8831
  return null;
8548
8832
  }
@@ -8555,24 +8839,24 @@ function resolveCursorRipgrepPath(opts) {
8555
8839
  packagedCursorRipgrepCandidate(platformRipgrepPackage(), rgBinaryName())
8556
8840
  );
8557
8841
  if (fromPackaged) return fromPackaged;
8558
- const start = opts?.startFile?.trim() || process.argv[1] || (0, import_node_url2.fileURLToPath)(import_meta2.url);
8842
+ const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
8843
+ // eslint-disable-next-line camelcase
8844
+ (typeof __filename !== "undefined" ? __filename : "");
8559
8845
  return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
8560
8846
  }
8561
8847
  function cursorRipgrepEnv(opts) {
8562
8848
  const path = resolveCursorRipgrepPath(opts);
8563
8849
  return path ? { [RIPGREP_ENV]: path } : {};
8564
8850
  }
8565
- var import_node_fs23, import_node_module2, import_node_path23, import_node_url2, import_meta2, RIPGREP_ENV;
8851
+ var import_node_fs24, import_node_module2, import_node_path24, RIPGREP_ENV;
8566
8852
  var init_cursor_ripgrep = __esm({
8567
8853
  "src/agents/cursor-ripgrep.ts"() {
8568
8854
  "use strict";
8569
- import_node_fs23 = require("fs");
8855
+ import_node_fs24 = require("fs");
8570
8856
  import_node_module2 = require("module");
8571
- import_node_path23 = require("path");
8572
- import_node_url2 = require("url");
8857
+ import_node_path24 = require("path");
8573
8858
  init_node_launch();
8574
8859
  init_packaged_runtime();
8575
- import_meta2 = {};
8576
8860
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
8577
8861
  }
8578
8862
  });
@@ -8616,11 +8900,11 @@ function entryDir() {
8616
8900
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
8617
8901
  if (cjsDir) return cjsDir;
8618
8902
  try {
8619
- return (0, import_node_path24.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
8903
+ return (0, import_node_path25.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
8620
8904
  } catch {
8621
8905
  try {
8622
8906
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
8623
- return (0, import_node_path24.dirname)(req.resolve("@sideboard-ai/core"));
8907
+ return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
8624
8908
  } catch {
8625
8909
  return process.cwd();
8626
8910
  }
@@ -8631,28 +8915,28 @@ function cursorRunnerPath() {
8631
8915
  if (packaged) return packaged;
8632
8916
  const root = entryDir();
8633
8917
  const candidates = [
8634
- (0, import_node_path24.join)(root, "agents", "cursor-runner.js"),
8635
- (0, import_node_path24.join)(root, "agents", "cursor-runner.cjs"),
8918
+ (0, import_node_path25.join)(root, "agents", "cursor-runner.js"),
8919
+ (0, import_node_path25.join)(root, "agents", "cursor-runner.cjs"),
8636
8920
  // If somehow resolved from package root instead of dist/
8637
- (0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.js"),
8638
- (0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.cjs"),
8921
+ (0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.js"),
8922
+ (0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.cjs"),
8639
8923
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
8640
- (0, import_node_path24.join)(root, "cursor-runner.ts"),
8641
- (0, import_node_path24.join)(root, "src", "agents", "cursor-runner.ts")
8924
+ (0, import_node_path25.join)(root, "cursor-runner.ts"),
8925
+ (0, import_node_path25.join)(root, "src", "agents", "cursor-runner.ts")
8642
8926
  ];
8643
8927
  for (const candidate of candidates) {
8644
- if ((0, import_node_fs24.existsSync)(candidate)) return candidate;
8928
+ if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
8645
8929
  }
8646
8930
  return candidates[0];
8647
8931
  }
8648
- var import_node_fs24, import_node_module3, import_node_path24, import_node_url3, import_sdk, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8932
+ var import_node_fs25, import_node_module3, import_node_path25, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8649
8933
  var init_cursor = __esm({
8650
8934
  "src/agents/cursor.ts"() {
8651
8935
  "use strict";
8652
- import_node_fs24 = require("fs");
8936
+ import_node_fs25 = require("fs");
8653
8937
  import_node_module3 = require("module");
8654
- import_node_path24 = require("path");
8655
- import_node_url3 = require("url");
8938
+ import_node_path25 = require("path");
8939
+ import_node_url2 = require("url");
8656
8940
  import_sdk = require("@cursor/sdk");
8657
8941
  init_run();
8658
8942
  init_app_settings();
@@ -8664,7 +8948,7 @@ var init_cursor = __esm({
8664
8948
  init_packaged_runtime();
8665
8949
  init_turn_input();
8666
8950
  init_cursor_events();
8667
- import_meta3 = {};
8951
+ import_meta2 = {};
8668
8952
  FALLBACK_CURSOR_MODELS = [
8669
8953
  { id: "default", displayName: "Auto" },
8670
8954
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -8801,7 +9085,7 @@ async function listOpencodeModels() {
8801
9085
  if (opencode === "opencode") {
8802
9086
  const which = await run("which", ["opencode"], { reject: false });
8803
9087
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
8804
- } else if (!(0, import_node_fs25.existsSync)(opencode)) {
9088
+ } else if (!(0, import_node_fs26.existsSync)(opencode)) {
8805
9089
  return FALLBACK_OPENCODE_MODELS;
8806
9090
  }
8807
9091
  const listed = await run(opencode, ["models"], { reject: false });
@@ -8831,11 +9115,11 @@ function usageFromOpencode(tokens) {
8831
9115
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
8832
9116
  };
8833
9117
  }
8834
- var import_node_fs25, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
9118
+ var import_node_fs26, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
8835
9119
  var init_opencode = __esm({
8836
9120
  "src/agents/opencode.ts"() {
8837
9121
  "use strict";
8838
- import_node_fs25 = require("fs");
9122
+ import_node_fs26 = require("fs");
8839
9123
  init_run();
8840
9124
  init_app_settings();
8841
9125
  init_global_workspace();
@@ -8862,7 +9146,7 @@ var init_opencode = __esm({
8862
9146
  async detect() {
8863
9147
  const opencode = resolveAgentExecutable("opencode");
8864
9148
  if (opencode !== "opencode") {
8865
- if (!(0, import_node_fs25.existsSync)(opencode)) {
9149
+ if (!(0, import_node_fs26.existsSync)(opencode)) {
8866
9150
  return {
8867
9151
  agent: "opencode",
8868
9152
  installed: false,
@@ -8948,7 +9232,8 @@ var init_opencode = __esm({
8948
9232
  return { type: "stderr", data: detail };
8949
9233
  }
8950
9234
  const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
8951
- if (sid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
9235
+ const childSid = str3(obj.childSessionID) ?? str3(obj.childSessionId) ?? str3(obj.parentID) ?? str3(obj.parentId);
9236
+ if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
8952
9237
  return { type: "session_id", data: sid };
8953
9238
  }
8954
9239
  if (obj.type === "text") {
@@ -9679,6 +9964,11 @@ function createAgentStreamCoalescer(emit, opts) {
9679
9964
  return;
9680
9965
  }
9681
9966
  if (!event.data) return;
9967
+ if (event.type === "thinking" && event.replace) {
9968
+ flush2();
9969
+ emit(event);
9970
+ return;
9971
+ }
9682
9972
  if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
9683
9973
  pending.data += event.data;
9684
9974
  } else {
@@ -9735,6 +10025,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
9735
10025
  }
9736
10026
  const env = childEnvWithAppSettings(cmd.env);
9737
10027
  applyPromptCacheTtlEnv(thread.agent, env);
10028
+ applyAgentRunnerHeapEnv(env);
9738
10029
  try {
9739
10030
  if (isOrchestratorThread(thread)) {
9740
10031
  mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
@@ -9842,9 +10133,11 @@ var init_spawn = __esm({
9842
10133
  init_agents();
9843
10134
  init_orchestrator_capable();
9844
10135
  init_message_parts();
10136
+ init_node_launch();
9845
10137
  init_path();
9846
10138
  init_usage();
9847
10139
  init_cursor_stream_coalesce();
10140
+ init_node_launch();
9848
10141
  }
9849
10142
  });
9850
10143
 
@@ -10570,21 +10863,21 @@ function shouldRefreshReviewRequestTemplate(content) {
10570
10863
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
10571
10864
  }
10572
10865
  function readTextIfPresent(abs) {
10573
- if (!(0, import_node_fs26.existsSync)(abs)) return null;
10866
+ if (!(0, import_node_fs27.existsSync)(abs)) return null;
10574
10867
  try {
10575
- const content = (0, import_node_fs26.readFileSync)(abs, "utf8");
10868
+ const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
10576
10869
  return content.trim() ? content : null;
10577
10870
  } catch {
10578
10871
  return null;
10579
10872
  }
10580
10873
  }
10581
10874
  function readLocalGuidelines(worktreePath) {
10582
- const localAbs = (0, import_node_path25.join)(worktreePath, REVIEW_REQUEST_PATH);
10875
+ const localAbs = (0, import_node_path26.join)(worktreePath, REVIEW_REQUEST_PATH);
10583
10876
  const localContent = readTextIfPresent(localAbs);
10584
10877
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
10585
10878
  return { path: REVIEW_REQUEST_PATH, content: localContent };
10586
10879
  }
10587
- const legacyAbs = (0, import_node_path25.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10880
+ const legacyAbs = (0, import_node_path26.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10588
10881
  const legacyContent = readTextIfPresent(legacyAbs);
10589
10882
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
10590
10883
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -10600,20 +10893,20 @@ function skillGuidelines(content, source) {
10600
10893
  };
10601
10894
  }
10602
10895
  function ensureReviewSkillFile(worktreePath) {
10603
- const abs = (0, import_node_path25.join)(worktreePath, REVIEW_SKILL_PATH);
10896
+ const abs = (0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH);
10604
10897
  const existing = readTextIfPresent(abs);
10605
10898
  if (existing) {
10606
10899
  return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
10607
10900
  }
10608
- const fromRepo = readTextIfPresent((0, import_node_path25.join)(worktreePath, REPO_REVIEW_PATH));
10901
+ const fromRepo = readTextIfPresent((0, import_node_path26.join)(worktreePath, REPO_REVIEW_PATH));
10609
10902
  const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
10610
10903
  const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
10611
- (0, import_node_fs26.mkdirSync)((0, import_node_path25.dirname)(abs), { recursive: true });
10612
- (0, import_node_fs26.writeFileSync)(abs, content, "utf8");
10904
+ (0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
10905
+ (0, import_node_fs27.writeFileSync)(abs, content, "utf8");
10613
10906
  return { path: REVIEW_SKILL_PATH, content, wrote: true };
10614
10907
  }
10615
10908
  function resolveReviewGuidelines(worktreePath) {
10616
- const skillContent = readTextIfPresent((0, import_node_path25.join)(worktreePath, REVIEW_SKILL_PATH));
10909
+ const skillContent = readTextIfPresent((0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH));
10617
10910
  if (skillContent) return skillGuidelines(skillContent, "skill");
10618
10911
  const local = readLocalGuidelines(worktreePath);
10619
10912
  if (local) {
@@ -10663,13 +10956,13 @@ async function requestReview(threadRef, send) {
10663
10956
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
10664
10957
  return { tab: started, from };
10665
10958
  }
10666
- var import_node_crypto5, import_node_fs26, import_node_path25, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
10959
+ var import_node_crypto5, import_node_fs27, import_node_path26, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
10667
10960
  var init_request_review = __esm({
10668
10961
  "src/review/request-review.ts"() {
10669
10962
  "use strict";
10670
10963
  import_node_crypto5 = require("crypto");
10671
- import_node_fs26 = require("fs");
10672
- import_node_path25 = require("path");
10964
+ import_node_fs27 = require("fs");
10965
+ import_node_path26 = require("path");
10673
10966
  init_global_workspace();
10674
10967
  init_chat_tabs();
10675
10968
  init_thread_store();
@@ -10694,9 +10987,9 @@ function matchSimpleGlob(pattern, name) {
10694
10987
  return new RegExp(`^${escaped}$`).test(name);
10695
10988
  }
10696
10989
  function readWorktreeInclude(repoPath) {
10697
- const path = (0, import_node_path26.join)(repoPath, ".worktreeinclude");
10698
- if (!(0, import_node_fs27.existsSync)(path)) return [];
10699
- return (0, import_node_fs27.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
10990
+ const path = (0, import_node_path27.join)(repoPath, ".worktreeinclude");
10991
+ if (!(0, import_node_fs28.existsSync)(path)) return [];
10992
+ return (0, import_node_fs28.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
10700
10993
  }
10701
10994
  function resolveFilesToCopy(repoPath) {
10702
10995
  const fromInclude = readWorktreeInclude(repoPath);
@@ -10706,10 +10999,10 @@ function resolveFilesToCopy(repoPath) {
10706
10999
  if (settings?.fileIncludeGlobs?.length) {
10707
11000
  const matched = [];
10708
11001
  try {
10709
- for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
11002
+ for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
10710
11003
  if (!entry.isFile()) continue;
10711
11004
  for (const glob of settings.fileIncludeGlobs) {
10712
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path26.basename)(glob), entry.name)) {
11005
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path27.basename)(glob), entry.name)) {
10713
11006
  matched.push(entry.name);
10714
11007
  break;
10715
11008
  }
@@ -10721,7 +11014,7 @@ function resolveFilesToCopy(repoPath) {
10721
11014
  }
10722
11015
  const defaults = [];
10723
11016
  try {
10724
- for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
11017
+ for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
10725
11018
  if (entry.isFile() && entry.name.startsWith(".env")) {
10726
11019
  defaults.push(entry.name);
10727
11020
  }
@@ -10735,11 +11028,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
10735
11028
  const patterns = resolveFilesToCopy(repoPath);
10736
11029
  const copied = [];
10737
11030
  for (const rel of patterns) {
10738
- const src = (0, import_node_path26.join)(repoPath, rel);
10739
- if (!(0, import_node_fs27.existsSync)(src)) continue;
10740
- const dest = (0, import_node_path26.join)(worktreePath, rel);
10741
- (0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(dest), { recursive: true });
10742
- (0, import_node_fs27.copyFileSync)(src, dest);
11031
+ const src = (0, import_node_path27.join)(repoPath, rel);
11032
+ if (!(0, import_node_fs28.existsSync)(src)) continue;
11033
+ const dest = (0, import_node_path27.join)(worktreePath, rel);
11034
+ (0, import_node_fs28.mkdirSync)((0, import_node_path27.dirname)(dest), { recursive: true });
11035
+ (0, import_node_fs28.copyFileSync)(src, dest);
10743
11036
  copied.push(rel);
10744
11037
  }
10745
11038
  return copied;
@@ -10774,7 +11067,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
10774
11067
  const env = stripNestedElectronEnv({
10775
11068
  ...baseEnv ?? process.env
10776
11069
  });
10777
- const name = opts.workspaceName ?? (0, import_node_path26.basename)(opts.worktreePath);
11070
+ const name = opts.workspaceName ?? (0, import_node_path27.basename)(opts.worktreePath);
10778
11071
  const ports = opts.ports ?? [];
10779
11072
  const primary = ports[0];
10780
11073
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -11035,13 +11328,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
11035
11328
  done: handle.done
11036
11329
  };
11037
11330
  }
11038
- var import_node_fs27, import_node_net, import_node_path26, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
11331
+ var import_node_fs28, import_node_net, import_node_path27, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
11039
11332
  var init_conductor = __esm({
11040
11333
  "src/hook/conductor.ts"() {
11041
11334
  "use strict";
11042
- import_node_fs27 = require("fs");
11335
+ import_node_fs28 = require("fs");
11043
11336
  import_node_net = require("net");
11044
- import_node_path26 = require("path");
11337
+ import_node_path27 = require("path");
11045
11338
  import_execa4 = require("execa");
11046
11339
  import_node_readline3 = require("readline");
11047
11340
  init_settings();
@@ -11067,9 +11360,9 @@ async function findOrphanWorktrees(repoPaths) {
11067
11360
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
11068
11361
  );
11069
11362
  const homeRoot = sideboardWorkspacesDir();
11070
- if ((0, import_node_fs28.existsSync)(homeRoot)) {
11363
+ if ((0, import_node_fs29.existsSync)(homeRoot)) {
11071
11364
  try {
11072
- for (const entry of (0, import_node_fs28.readdirSync)(homeRoot, { withFileTypes: true })) {
11365
+ for (const entry of (0, import_node_fs29.readdirSync)(homeRoot, { withFileTypes: true })) {
11073
11366
  if (!entry.isDirectory()) continue;
11074
11367
  void entry;
11075
11368
  }
@@ -11079,7 +11372,7 @@ async function findOrphanWorktrees(repoPaths) {
11079
11372
  const orphans = [];
11080
11373
  const seen = /* @__PURE__ */ new Set();
11081
11374
  for (const repoPath of repos) {
11082
- if (!repoPath || !(0, import_node_fs28.existsSync)(repoPath)) continue;
11375
+ if (!repoPath || !(0, import_node_fs29.existsSync)(repoPath)) continue;
11083
11376
  try {
11084
11377
  const wts = await listWorktrees(repoPath);
11085
11378
  for (const wt of wts) {
@@ -11090,7 +11383,7 @@ async function findOrphanWorktrees(repoPaths) {
11090
11383
  seen.add(path);
11091
11384
  let mtimeMs = 0;
11092
11385
  try {
11093
- mtimeMs = (0, import_node_fs28.statSync)(path).mtimeMs;
11386
+ mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
11094
11387
  } catch {
11095
11388
  mtimeMs = 0;
11096
11389
  }
@@ -11100,16 +11393,16 @@ async function findOrphanWorktrees(repoPaths) {
11100
11393
  }
11101
11394
  try {
11102
11395
  const root = worktreesRoot(repoPath);
11103
- if ((0, import_node_fs28.existsSync)(root)) {
11104
- for (const entry of (0, import_node_fs28.readdirSync)(root, { withFileTypes: true })) {
11396
+ if ((0, import_node_fs29.existsSync)(root)) {
11397
+ for (const entry of (0, import_node_fs29.readdirSync)(root, { withFileTypes: true })) {
11105
11398
  if (!entry.isDirectory()) continue;
11106
- const path = (0, import_node_path27.join)(root, entry.name).replace(/\/$/, "");
11399
+ const path = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
11107
11400
  if (known.has(path) || seen.has(path)) continue;
11108
- if (!(0, import_node_fs28.existsSync)((0, import_node_path27.join)(path, ".git"))) continue;
11401
+ if (!(0, import_node_fs29.existsSync)((0, import_node_path28.join)(path, ".git"))) continue;
11109
11402
  seen.add(path);
11110
11403
  let mtimeMs = 0;
11111
11404
  try {
11112
- mtimeMs = (0, import_node_fs28.statSync)(path).mtimeMs;
11405
+ mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
11113
11406
  } catch {
11114
11407
  mtimeMs = Date.now();
11115
11408
  }
@@ -11161,12 +11454,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
11161
11454
  const elapsed = Date.now() - Date.parse(last);
11162
11455
  return elapsed >= intervalHours * 36e5;
11163
11456
  }
11164
- var import_node_fs28, import_node_path27;
11457
+ var import_node_fs29, import_node_path28;
11165
11458
  var init_orphan_cleanup = __esm({
11166
11459
  "src/git/orphan-cleanup.ts"() {
11167
11460
  "use strict";
11168
- import_node_fs28 = require("fs");
11169
- import_node_path27 = require("path");
11461
+ import_node_fs29 = require("fs");
11462
+ import_node_path28 = require("path");
11170
11463
  init_worktree();
11171
11464
  init_thread_store();
11172
11465
  init_paths();
@@ -11273,38 +11566,38 @@ __export(workspaces_exports, {
11273
11566
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
11274
11567
  });
11275
11568
  function workspacesFile() {
11276
- return (0, import_node_path28.join)(appDataDir(), "workspaces.json");
11569
+ return (0, import_node_path29.join)(appDataDir(), "workspaces.json");
11277
11570
  }
11278
11571
  function removedWorkspacesFile() {
11279
- return (0, import_node_path28.join)(appDataDir(), "removed-workspaces.json");
11572
+ return (0, import_node_path29.join)(appDataDir(), "removed-workspaces.json");
11280
11573
  }
11281
11574
  function readAll() {
11282
11575
  const path = workspacesFile();
11283
- if (!(0, import_node_fs29.existsSync)(path)) return [];
11576
+ if (!(0, import_node_fs30.existsSync)(path)) return [];
11284
11577
  try {
11285
- const raw = JSON.parse((0, import_node_fs29.readFileSync)(path, "utf8"));
11578
+ const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
11286
11579
  return Array.isArray(raw) ? raw : [];
11287
11580
  } catch {
11288
11581
  return [];
11289
11582
  }
11290
11583
  }
11291
11584
  function writeAll(list) {
11292
- (0, import_node_fs29.mkdirSync)(appDataDir(), { recursive: true });
11293
- (0, import_node_fs29.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
11585
+ (0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
11586
+ (0, import_node_fs30.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
11294
11587
  }
11295
11588
  function readRemoved() {
11296
11589
  const path = removedWorkspacesFile();
11297
- if (!(0, import_node_fs29.existsSync)(path)) return /* @__PURE__ */ new Set();
11590
+ if (!(0, import_node_fs30.existsSync)(path)) return /* @__PURE__ */ new Set();
11298
11591
  try {
11299
- const raw = JSON.parse((0, import_node_fs29.readFileSync)(path, "utf8"));
11592
+ const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
11300
11593
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
11301
11594
  } catch {
11302
11595
  return /* @__PURE__ */ new Set();
11303
11596
  }
11304
11597
  }
11305
11598
  function writeRemoved(paths) {
11306
- (0, import_node_fs29.mkdirSync)(appDataDir(), { recursive: true });
11307
- (0, import_node_fs29.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
11599
+ (0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
11600
+ (0, import_node_fs30.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
11308
11601
  }
11309
11602
  function rememberRemoved(repoPath) {
11310
11603
  const next = readRemoved();
@@ -11327,7 +11620,7 @@ function listWorkspaces() {
11327
11620
  async function addWorkspace(repoPath) {
11328
11621
  const root = await resolveRepoRoot(repoPath);
11329
11622
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
11330
- if (!(0, import_node_fs29.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
11623
+ if (!(0, import_node_fs30.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
11331
11624
  forgetRemoved(root);
11332
11625
  await ensureGhPreferOrigin(root);
11333
11626
  const current = readAll();
@@ -11335,7 +11628,7 @@ async function addWorkspace(repoPath) {
11335
11628
  if (existing) return existing;
11336
11629
  const next = {
11337
11630
  path: root,
11338
- name: (0, import_node_path28.basename)(root),
11631
+ name: (0, import_node_path29.basename)(root),
11339
11632
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
11340
11633
  };
11341
11634
  writeAll([...current, next]);
@@ -11357,10 +11650,10 @@ function syncWorkspacesFromThreads(repoPaths) {
11357
11650
  if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
11358
11651
  continue;
11359
11652
  }
11360
- if (!(0, import_node_fs29.existsSync)(path)) continue;
11653
+ if (!(0, import_node_fs30.existsSync)(path)) continue;
11361
11654
  const ws = {
11362
11655
  path,
11363
- name: (0, import_node_path28.basename)(path),
11656
+ name: (0, import_node_path29.basename)(path),
11364
11657
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
11365
11658
  };
11366
11659
  byPath.set(path, ws);
@@ -11370,12 +11663,12 @@ function syncWorkspacesFromThreads(repoPaths) {
11370
11663
  if (dirty) writeAll(next);
11371
11664
  return next.sort((a, b) => a.name.localeCompare(b.name));
11372
11665
  }
11373
- var import_node_fs29, import_node_path28;
11666
+ var import_node_fs30, import_node_path29;
11374
11667
  var init_workspaces2 = __esm({
11375
11668
  "src/store/workspaces.ts"() {
11376
11669
  "use strict";
11377
- import_node_fs29 = require("fs");
11378
- import_node_path28 = require("path");
11670
+ import_node_fs30 = require("fs");
11671
+ import_node_path29 = require("path");
11379
11672
  init_paths();
11380
11673
  init_global_workspace();
11381
11674
  init_worktree();
@@ -11388,12 +11681,12 @@ async function cloneRepoIntoSideboard(opts) {
11388
11681
  if (!url) throw new Error("Clone URL is required");
11389
11682
  let name = opts.name?.trim();
11390
11683
  if (!name) {
11391
- const leaf = (0, import_node_path29.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
11684
+ const leaf = (0, import_node_path30.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
11392
11685
  name = leaf || "repo";
11393
11686
  }
11394
11687
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
11395
- const dest = (0, import_node_path29.join)(sideboardReposDir(), name);
11396
- if ((0, import_node_fs30.existsSync)(dest)) {
11688
+ const dest = (0, import_node_path30.join)(sideboardReposDir(), name);
11689
+ if ((0, import_node_fs31.existsSync)(dest)) {
11397
11690
  const repoPath2 = await resolveRepoRoot(dest);
11398
11691
  const workspace2 = await ensureWorkspace(repoPath2);
11399
11692
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -11408,12 +11701,12 @@ async function cloneRepoIntoSideboard(opts) {
11408
11701
  const workspace = await ensureWorkspace(repoPath);
11409
11702
  return { repoPath, workspace };
11410
11703
  }
11411
- var import_node_fs30, import_node_path29, import_execa6;
11704
+ var import_node_fs31, import_node_path30, import_execa6;
11412
11705
  var init_clone_repo = __esm({
11413
11706
  "src/git/clone-repo.ts"() {
11414
11707
  "use strict";
11415
- import_node_fs30 = require("fs");
11416
- import_node_path29 = require("path");
11708
+ import_node_fs31 = require("fs");
11709
+ import_node_path30 = require("path");
11417
11710
  import_execa6 = require("execa");
11418
11711
  init_paths();
11419
11712
  init_workspaces2();
@@ -11423,11 +11716,11 @@ var init_clone_repo = __esm({
11423
11716
 
11424
11717
  // src/store/desktop-host.ts
11425
11718
  function desktopHostPidPath() {
11426
- return (0, import_node_path30.join)(appDataDir(), "desktop-host.pid");
11719
+ return (0, import_node_path31.join)(appDataDir(), "desktop-host.pid");
11427
11720
  }
11428
11721
  function readDesktopHostPid() {
11429
11722
  try {
11430
- const pid = Number.parseInt((0, import_node_fs31.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
11723
+ const pid = Number.parseInt((0, import_node_fs32.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
11431
11724
  if (!Number.isFinite(pid) || pid <= 0) return null;
11432
11725
  return pid;
11433
11726
  } catch {
@@ -11453,12 +11746,12 @@ function thisProcessShouldDrainAgentQueues() {
11453
11746
  if (isThisProcessDesktopHost()) return true;
11454
11747
  return !isDesktopHostAlive();
11455
11748
  }
11456
- var import_node_fs31, import_node_path30;
11749
+ var import_node_fs32, import_node_path31;
11457
11750
  var init_desktop_host = __esm({
11458
11751
  "src/store/desktop-host.ts"() {
11459
11752
  "use strict";
11460
- import_node_fs31 = require("fs");
11461
- import_node_path30 = require("path");
11753
+ import_node_fs32 = require("fs");
11754
+ import_node_path31 = require("path");
11462
11755
  init_paths();
11463
11756
  }
11464
11757
  });
@@ -11508,7 +11801,7 @@ async function createThread(input, _onSetupLine) {
11508
11801
  });
11509
11802
  await requireAgent(resolved.agent);
11510
11803
  const repoPath = await resolveRepoRoot(input.repoPath);
11511
- if (!(0, import_node_fs32.existsSync)(repoPath)) {
11804
+ if (!(0, import_node_fs33.existsSync)(repoPath)) {
11512
11805
  throw new Error(`Repo not found: ${repoPath}`);
11513
11806
  }
11514
11807
  if (input.cowboy) {
@@ -11631,11 +11924,11 @@ async function listLinearIssues(agent, repoPath) {
11631
11924
  }
11632
11925
  return adapter.listLinearIssues(repoPath);
11633
11926
  }
11634
- var import_node_fs32;
11927
+ var import_node_fs33;
11635
11928
  var init_create = __esm({
11636
11929
  "src/threads/create.ts"() {
11637
11930
  "use strict";
11638
- import_node_fs32 = require("fs");
11931
+ import_node_fs33 = require("fs");
11639
11932
  init_detect();
11640
11933
  init_worktree();
11641
11934
  init_conductor();
@@ -11680,21 +11973,13 @@ function summarizeTurnLive(parts) {
11680
11973
  (p) => p.type === "tool"
11681
11974
  );
11682
11975
  const lastTool = tools[tools.length - 1];
11683
- const lastToolLabel = lastTool ? lastTool.description || toolDescription(lastTool.name, lastTool.input) || lastTool.name : void 0;
11684
- const running = lastTool?.status === "running";
11976
+ const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
11977
+ const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
11685
11978
  const thinking = lastText(parts, "thinking");
11686
11979
  const text4 = lastText(parts, "text");
11687
11980
  const excerptRaw = thinking || text4;
11688
11981
  const excerpt = excerptRaw.length > 280 ? `${excerptRaw.slice(-280)}` : excerptRaw || void 0;
11689
- let summary = "Working\u2026";
11690
- if (lastToolLabel) {
11691
- const verb = running ? lastToolLabel : `Finished ${lastToolLabel}`;
11692
- summary = tools.length > 1 ? `${verb} (${tools.length} tools)` : verb;
11693
- } else if (thinking) {
11694
- summary = "Thinking\u2026";
11695
- } else if (text4) {
11696
- summary = "Writing reply\u2026";
11697
- }
11982
+ const summary = liveActivitySummary(parts);
11698
11983
  return {
11699
11984
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11700
11985
  summary,
@@ -11744,20 +12029,20 @@ function writeTurnLive(threadId, progress) {
11744
12029
  const path = threadLivePath(threadId);
11745
12030
  const tmp = `${path}.${process.pid}.tmp`;
11746
12031
  try {
11747
- (0, import_node_fs33.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
11748
- (0, import_node_fs33.renameSync)(tmp, path);
12032
+ (0, import_node_fs34.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
12033
+ (0, import_node_fs34.renameSync)(tmp, path);
11749
12034
  } catch {
11750
12035
  try {
11751
- (0, import_node_fs33.unlinkSync)(tmp);
12036
+ (0, import_node_fs34.unlinkSync)(tmp);
11752
12037
  } catch {
11753
12038
  }
11754
12039
  }
11755
12040
  }
11756
12041
  function readTurnLive(threadId) {
11757
12042
  const path = threadLivePath(threadId);
11758
- if (!(0, import_node_fs33.existsSync)(path)) return null;
12043
+ if (!(0, import_node_fs34.existsSync)(path)) return null;
11759
12044
  try {
11760
- const raw = JSON.parse((0, import_node_fs33.readFileSync)(path, "utf8"));
12045
+ const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
11761
12046
  if (!raw || typeof raw.summary !== "string") return null;
11762
12047
  return raw;
11763
12048
  } catch {
@@ -11769,17 +12054,17 @@ function clearTurnLive(threadId) {
11769
12054
  if (buf?.timer) clearTimeout(buf.timer);
11770
12055
  buffers.delete(threadId);
11771
12056
  const path = threadLivePath(threadId);
11772
- if (!(0, import_node_fs33.existsSync)(path)) return;
12057
+ if (!(0, import_node_fs34.existsSync)(path)) return;
11773
12058
  try {
11774
- (0, import_node_fs33.unlinkSync)(path);
12059
+ (0, import_node_fs34.unlinkSync)(path);
11775
12060
  } catch {
11776
12061
  }
11777
12062
  }
11778
- var import_node_fs33, buffers, FLUSH_MS, MAX_PARTS;
12063
+ var import_node_fs34, buffers, FLUSH_MS, MAX_PARTS;
11779
12064
  var init_turn_live = __esm({
11780
12065
  "src/store/turn-live.ts"() {
11781
12066
  "use strict";
11782
- import_node_fs33 = require("fs");
12067
+ import_node_fs34 = require("fs");
11783
12068
  init_message_parts();
11784
12069
  init_paths();
11785
12070
  buffers = /* @__PURE__ */ new Map();
@@ -11956,8 +12241,12 @@ var init_quota_failover = __esm({
11956
12241
  });
11957
12242
 
11958
12243
  // src/threads/adopt.ts
12244
+ function thisModuleFile() {
12245
+ const cjsFile = typeof __filename !== "undefined" ? __filename : "";
12246
+ return cjsFile || process.argv[1] || (0, import_node_path32.join)(process.cwd(), "package.json");
12247
+ }
11959
12248
  function openReadonlySqlite(file) {
11960
- const req = (0, import_node_module4.createRequire)(import_meta4.url);
12249
+ const req = (0, import_node_module4.createRequire)(thisModuleFile());
11961
12250
  const Database = req("better-sqlite3");
11962
12251
  return new Database(file, { readonly: true, fileMustExist: true });
11963
12252
  }
@@ -11972,21 +12261,21 @@ function mapAgentType(raw) {
11972
12261
  return null;
11973
12262
  }
11974
12263
  function resolveConductorCursorAgentId(workspacePath) {
11975
- if (!workspacePath || !(0, import_node_fs34.existsSync)(CURSOR_SDK_STORE)) return null;
12264
+ if (!workspacePath || !(0, import_node_fs35.existsSync)(CURSOR_SDK_STORE)) return null;
11976
12265
  const normalized = workspacePath.replace(/\/$/, "");
11977
12266
  let best = null;
11978
12267
  let hashes;
11979
12268
  try {
11980
- hashes = (0, import_node_fs34.readdirSync)(CURSOR_SDK_STORE);
12269
+ hashes = (0, import_node_fs35.readdirSync)(CURSOR_SDK_STORE);
11981
12270
  } catch {
11982
12271
  return null;
11983
12272
  }
11984
12273
  for (const hash of hashes) {
11985
- const agentsFile = (0, import_node_path31.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
11986
- if (!(0, import_node_fs34.existsSync)(agentsFile)) continue;
12274
+ const agentsFile = (0, import_node_path32.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
12275
+ if (!(0, import_node_fs35.existsSync)(agentsFile)) continue;
11987
12276
  let text4;
11988
12277
  try {
11989
- text4 = (0, import_node_fs34.readFileSync)(agentsFile, "utf8");
12278
+ text4 = (0, import_node_fs35.readFileSync)(agentsFile, "utf8");
11990
12279
  } catch {
11991
12280
  continue;
11992
12281
  }
@@ -12010,7 +12299,7 @@ function resolveConductorCursorAgentId(workspacePath) {
12010
12299
  return best?.agentId ?? null;
12011
12300
  }
12012
12301
  async function adoptThread(input) {
12013
- if (!(0, import_node_fs34.existsSync)(input.worktreePath)) {
12302
+ if (!(0, import_node_fs35.existsSync)(input.worktreePath)) {
12014
12303
  throw new Error(`Worktree not found: ${input.worktreePath}`);
12015
12304
  }
12016
12305
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -12034,18 +12323,18 @@ async function adoptThread(input) {
12034
12323
  return thread;
12035
12324
  }
12036
12325
  function listConductorWorkspaces() {
12037
- if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
12326
+ if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
12038
12327
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
12039
12328
  }
12040
- const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path31.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12041
- const snapshot = (0, import_node_path31.join)(tmp, "conductor.db");
12329
+ const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12330
+ const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
12042
12331
  try {
12043
- (0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
12332
+ (0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
12044
12333
  for (const suffix of ["-wal", "-shm"]) {
12045
12334
  const src = `${CONDUCTOR_DB}${suffix}`;
12046
- if ((0, import_node_fs34.existsSync)(src)) {
12335
+ if ((0, import_node_fs35.existsSync)(src)) {
12047
12336
  try {
12048
- (0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
12337
+ (0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
12049
12338
  } catch {
12050
12339
  }
12051
12340
  }
@@ -12121,22 +12410,22 @@ function listConductorWorkspaces() {
12121
12410
  db.close();
12122
12411
  }
12123
12412
  } finally {
12124
- (0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
12413
+ (0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
12125
12414
  }
12126
12415
  }
12127
12416
  function importConductorWorkspace(workspaceId) {
12128
- if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
12417
+ if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
12129
12418
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
12130
12419
  }
12131
- const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path31.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12132
- const snapshot = (0, import_node_path31.join)(tmp, "conductor.db");
12420
+ const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12421
+ const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
12133
12422
  try {
12134
- (0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
12423
+ (0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
12135
12424
  for (const suffix of ["-wal", "-shm"]) {
12136
12425
  const src = `${CONDUCTOR_DB}${suffix}`;
12137
- if ((0, import_node_fs34.existsSync)(src)) {
12426
+ if ((0, import_node_fs35.existsSync)(src)) {
12138
12427
  try {
12139
- (0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
12428
+ (0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
12140
12429
  } catch {
12141
12430
  }
12142
12431
  }
@@ -12154,7 +12443,7 @@ function importConductorWorkspace(workspaceId) {
12154
12443
  ).get(workspaceId);
12155
12444
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
12156
12445
  const worktreePath = String(row.workspacePath);
12157
- if (!(0, import_node_fs34.existsSync)(worktreePath)) {
12446
+ if (!(0, import_node_fs35.existsSync)(worktreePath)) {
12158
12447
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
12159
12448
  }
12160
12449
  let sessionId = null;
@@ -12217,32 +12506,31 @@ function importConductorWorkspace(workspaceId) {
12217
12506
  db.close();
12218
12507
  }
12219
12508
  } finally {
12220
- (0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
12509
+ (0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
12221
12510
  }
12222
12511
  }
12223
12512
  async function importConductorWorkspaceAsync(workspaceId) {
12224
12513
  return importConductorWorkspace(workspaceId);
12225
12514
  }
12226
- var import_node_child_process3, import_node_fs34, import_node_os10, import_node_path31, import_node_module4, import_meta4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
12515
+ var import_node_child_process3, import_node_fs35, import_node_os10, import_node_path32, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
12227
12516
  var init_adopt = __esm({
12228
12517
  "src/threads/adopt.ts"() {
12229
12518
  "use strict";
12230
12519
  import_node_child_process3 = require("child_process");
12231
- import_node_fs34 = require("fs");
12520
+ import_node_fs35 = require("fs");
12232
12521
  import_node_os10 = require("os");
12233
- import_node_path31 = require("path");
12522
+ import_node_path32 = require("path");
12234
12523
  import_node_module4 = require("module");
12235
12524
  init_worktree();
12236
12525
  init_thread_store();
12237
- import_meta4 = {};
12238
- CONDUCTOR_APP_SUPPORT = (0, import_node_path31.join)(
12526
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path32.join)(
12239
12527
  process.env.HOME ?? "",
12240
12528
  "Library",
12241
12529
  "Application Support",
12242
12530
  "com.conductor.app"
12243
12531
  );
12244
- CONDUCTOR_DB = (0, import_node_path31.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
12245
- CURSOR_SDK_STORE = (0, import_node_path31.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
12532
+ CONDUCTOR_DB = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
12533
+ CURSOR_SDK_STORE = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
12246
12534
  }
12247
12535
  });
12248
12536
 
@@ -12309,7 +12597,7 @@ async function openStackLayer(input, _onSetupLine) {
12309
12597
  let createdWorktree = false;
12310
12598
  const trees = await listWorktrees(repoPath);
12311
12599
  const checkedOut = trees.find((w) => w.branch === branchName);
12312
- if (checkedOut?.path && (0, import_node_fs35.existsSync)(checkedOut.path)) {
12600
+ if (checkedOut?.path && (0, import_node_fs36.existsSync)(checkedOut.path)) {
12313
12601
  if (input.reuseExistingWorktree !== false) {
12314
12602
  worktreePath = checkedOut.path;
12315
12603
  } else {
@@ -12451,7 +12739,7 @@ async function initStackFromThread(input, onSetupLine) {
12451
12739
  async function createPrStack(input, onSetupLine) {
12452
12740
  await requireAgent(input.agent);
12453
12741
  const repoPath = await resolveRepoRoot(input.repoPath);
12454
- if (!(0, import_node_fs35.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
12742
+ if (!(0, import_node_fs36.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
12455
12743
  if (!input.branches.length) throw new Error("At least one branch name required");
12456
12744
  const status = await detectGhStack(repoPath);
12457
12745
  if (!status.available) throw new Error(status.reason);
@@ -12518,7 +12806,7 @@ async function createPrStack(input, onSetupLine) {
12518
12806
  }
12519
12807
  }
12520
12808
  const claimed = new Set(threads.map((t) => t.worktreePath));
12521
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs35.existsSync)(bootstrap.worktreePath)) {
12809
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs36.existsSync)(bootstrap.worktreePath)) {
12522
12810
  try {
12523
12811
  await removeWorktree(repoPath, bootstrap.worktreePath, {
12524
12812
  deleteBranch: bootstrap.branchName
@@ -12528,11 +12816,11 @@ async function createPrStack(input, onSetupLine) {
12528
12816
  }
12529
12817
  return { stack, threads, createdThreadIds };
12530
12818
  }
12531
- var import_node_fs35;
12819
+ var import_node_fs36;
12532
12820
  var init_stack_layers = __esm({
12533
12821
  "src/threads/stack-layers.ts"() {
12534
12822
  "use strict";
12535
- import_node_fs35 = require("fs");
12823
+ import_node_fs36 = require("fs");
12536
12824
  init_detect();
12537
12825
  init_run();
12538
12826
  init_stack();
@@ -12545,7 +12833,7 @@ var init_stack_layers = __esm({
12545
12833
 
12546
12834
  // src/diff/diff.ts
12547
12835
  async function inspectGitWorktree(worktreePath) {
12548
- if (!worktreePath || !(0, import_node_fs36.existsSync)(worktreePath)) return "missing_worktree";
12836
+ if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) return "missing_worktree";
12549
12837
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
12550
12838
  reject: false
12551
12839
  });
@@ -12553,7 +12841,7 @@ async function inspectGitWorktree(worktreePath) {
12553
12841
  return "ok";
12554
12842
  }
12555
12843
  async function initializeGitRepository(worktreePath) {
12556
- if (!worktreePath || !(0, import_node_fs36.existsSync)(worktreePath)) {
12844
+ if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) {
12557
12845
  throw new Error("Worktree not found");
12558
12846
  }
12559
12847
  const status = await inspectGitWorktree(worktreePath);
@@ -12687,11 +12975,11 @@ new file mode 100644
12687
12975
  };
12688
12976
  }
12689
12977
  async function untrackedPatch(worktreePath, path, maxHunk) {
12690
- const abs = (0, import_node_path32.join)(worktreePath, path);
12978
+ const abs = (0, import_node_path33.join)(worktreePath, path);
12691
12979
  try {
12692
- const st = (0, import_node_fs36.statSync)(abs);
12980
+ const st = (0, import_node_fs37.statSync)(abs);
12693
12981
  if (st.isFile() && st.size > maxHunk) {
12694
- const buf = (0, import_node_fs36.readFileSync)(abs).subarray(0, maxHunk);
12982
+ const buf = (0, import_node_fs37.readFileSync)(abs).subarray(0, maxHunk);
12695
12983
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
12696
12984
  }
12697
12985
  } catch {
@@ -13180,8 +13468,8 @@ function isImageRelativePath(relativePath) {
13180
13468
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13181
13469
  assertSafeRelativePath(relativePath);
13182
13470
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
13183
- const abs = (0, import_node_path32.join)(worktreePath, relativePath);
13184
- const st = (0, import_node_fs36.statSync)(abs);
13471
+ const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13472
+ const st = (0, import_node_fs37.statSync)(abs);
13185
13473
  if (!st.isFile()) {
13186
13474
  throw new Error(`Not a file: ${relativePath}`);
13187
13475
  }
@@ -13190,7 +13478,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13190
13478
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
13191
13479
  );
13192
13480
  }
13193
- const buf = (0, import_node_fs36.readFileSync)(abs);
13481
+ const buf = (0, import_node_fs37.readFileSync)(abs);
13194
13482
  return {
13195
13483
  path: relativePath,
13196
13484
  contentBase64: buf.toString("base64"),
@@ -13200,12 +13488,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13200
13488
  function readWorktreeFile(worktreePath, relativePath, opts) {
13201
13489
  assertSafeRelativePath(relativePath);
13202
13490
  const maxBytes = opts?.maxBytes ?? 2e5;
13203
- const abs = (0, import_node_path32.join)(worktreePath, relativePath);
13204
- const st = (0, import_node_fs36.statSync)(abs);
13491
+ const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13492
+ const st = (0, import_node_fs37.statSync)(abs);
13205
13493
  if (!st.isFile()) {
13206
13494
  throw new Error(`Not a file: ${relativePath}`);
13207
13495
  }
13208
- const buf = (0, import_node_fs36.readFileSync)(abs);
13496
+ const buf = (0, import_node_fs37.readFileSync)(abs);
13209
13497
  if (isImageRelativePath(relativePath)) {
13210
13498
  const maxImageBytes = Math.max(maxBytes, 15e6);
13211
13499
  const truncated2 = buf.length > maxImageBytes;
@@ -13248,9 +13536,9 @@ function assertSafeRelativePath(relativePath) {
13248
13536
  }
13249
13537
  function writeWorktreeFile(worktreePath, relativePath, content) {
13250
13538
  assertSafeRelativePath(relativePath);
13251
- const abs = (0, import_node_path32.join)(worktreePath, relativePath);
13252
- (0, import_node_fs36.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
13253
- (0, import_node_fs36.writeFileSync)(abs, content, "utf8");
13539
+ const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13540
+ (0, import_node_fs37.mkdirSync)((0, import_node_path33.dirname)(abs), { recursive: true });
13541
+ (0, import_node_fs37.writeFileSync)(abs, content, "utf8");
13254
13542
  return { path: relativePath };
13255
13543
  }
13256
13544
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -13267,12 +13555,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
13267
13555
  truncated: full.files.length > maxFiles
13268
13556
  };
13269
13557
  }
13270
- var import_node_fs36, import_node_path32, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
13558
+ var import_node_fs37, import_node_path33, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
13271
13559
  var init_diff = __esm({
13272
13560
  "src/diff/diff.ts"() {
13273
13561
  "use strict";
13274
- import_node_fs36 = require("fs");
13275
- import_node_path32 = require("path");
13562
+ import_node_fs37 = require("fs");
13563
+ import_node_path33 = require("path");
13276
13564
  init_run();
13277
13565
  init_worktree();
13278
13566
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -13440,7 +13728,7 @@ function parseFrontmatter(content) {
13440
13728
  }
13441
13729
  function readSkill(skillMd, source) {
13442
13730
  try {
13443
- const content = (0, import_node_fs37.readFileSync)(skillMd, "utf8");
13731
+ const content = (0, import_node_fs38.readFileSync)(skillMd, "utf8");
13444
13732
  const { name: fmName, description } = parseFrontmatter(content);
13445
13733
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
13446
13734
  const name = fmName || dirName;
@@ -13459,19 +13747,19 @@ function readSkill(skillMd, source) {
13459
13747
  }
13460
13748
  }
13461
13749
  function scanSkillsDir(dir, source, out) {
13462
- if (!(0, import_node_fs37.existsSync)(dir)) return;
13750
+ if (!(0, import_node_fs38.existsSync)(dir)) return;
13463
13751
  let entries;
13464
13752
  try {
13465
- entries = (0, import_node_fs37.readdirSync)(dir);
13753
+ entries = (0, import_node_fs38.readdirSync)(dir);
13466
13754
  } catch {
13467
13755
  return;
13468
13756
  }
13469
13757
  for (const entry of entries) {
13470
13758
  if (entry.startsWith(".")) continue;
13471
- const skillMd = (0, import_node_path33.join)(dir, entry, "SKILL.md");
13472
- if (!(0, import_node_fs37.existsSync)(skillMd)) continue;
13759
+ const skillMd = (0, import_node_path34.join)(dir, entry, "SKILL.md");
13760
+ if (!(0, import_node_fs38.existsSync)(skillMd)) continue;
13473
13761
  try {
13474
- if (!(0, import_node_fs37.statSync)(skillMd).isFile()) continue;
13762
+ if (!(0, import_node_fs38.statSync)(skillMd).isFile()) continue;
13475
13763
  } catch {
13476
13764
  continue;
13477
13765
  }
@@ -13480,24 +13768,24 @@ function scanSkillsDir(dir, source, out) {
13480
13768
  }
13481
13769
  }
13482
13770
  function scanClaudePluginSkills(pluginsRoot, out) {
13483
- if (!(0, import_node_fs37.existsSync)(pluginsRoot)) return;
13771
+ if (!(0, import_node_fs38.existsSync)(pluginsRoot)) return;
13484
13772
  const walk = (dir, depth, lookingForSkillsDir) => {
13485
13773
  if (depth > 7) return;
13486
13774
  let entries;
13487
13775
  try {
13488
- entries = (0, import_node_fs37.readdirSync)(dir);
13776
+ entries = (0, import_node_fs38.readdirSync)(dir);
13489
13777
  } catch {
13490
13778
  return;
13491
13779
  }
13492
13780
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
13493
- const skill = readSkill((0, import_node_path33.join)(dir, "SKILL.md"), "cli");
13781
+ const skill = readSkill((0, import_node_path34.join)(dir, "SKILL.md"), "cli");
13494
13782
  if (skill) out.push(skill);
13495
13783
  }
13496
13784
  for (const entry of entries) {
13497
13785
  if (entry === "node_modules" || entry === ".git") continue;
13498
- const full = (0, import_node_path33.join)(dir, entry);
13786
+ const full = (0, import_node_path34.join)(dir, entry);
13499
13787
  try {
13500
- if (!(0, import_node_fs37.statSync)(full).isDirectory()) continue;
13788
+ if (!(0, import_node_fs38.statSync)(full).isDirectory()) continue;
13501
13789
  } catch {
13502
13790
  continue;
13503
13791
  }
@@ -13515,17 +13803,17 @@ function discoverSkills(worktreePath) {
13515
13803
  const home = (0, import_node_os11.homedir)();
13516
13804
  const collected = [];
13517
13805
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
13518
- scanSkillsDir((0, import_node_path33.join)(worktreePath, rel), "workspace", collected);
13806
+ scanSkillsDir((0, import_node_path34.join)(worktreePath, rel), "workspace", collected);
13519
13807
  }
13520
13808
  for (const abs of [
13521
- (0, import_node_path33.join)(home, ".claude/skills"),
13522
- (0, import_node_path33.join)(home, ".cursor/skills"),
13523
- (0, import_node_path33.join)(home, ".sideboard/skills"),
13524
- (0, import_node_path33.join)(home, ".brightsy/skills")
13809
+ (0, import_node_path34.join)(home, ".claude/skills"),
13810
+ (0, import_node_path34.join)(home, ".cursor/skills"),
13811
+ (0, import_node_path34.join)(home, ".sideboard/skills"),
13812
+ (0, import_node_path34.join)(home, ".brightsy/skills")
13525
13813
  ]) {
13526
13814
  scanSkillsDir(abs, "user", collected);
13527
13815
  }
13528
- scanClaudePluginSkills((0, import_node_path33.join)(home, ".claude/plugins"), collected);
13816
+ scanClaudePluginSkills((0, import_node_path34.join)(home, ".claude/plugins"), collected);
13529
13817
  const rank = { workspace: 0, user: 1, cli: 2 };
13530
13818
  const byCommand = /* @__PURE__ */ new Map();
13531
13819
  for (const skill of collected) {
@@ -13537,7 +13825,7 @@ function discoverSkills(worktreePath) {
13537
13825
  return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
13538
13826
  }
13539
13827
  function readSkillBody(skillPath, maxChars = 12e3) {
13540
- const raw = (0, import_node_fs37.readFileSync)(skillPath, "utf8");
13828
+ const raw = (0, import_node_fs38.readFileSync)(skillPath, "utf8");
13541
13829
  if (raw.startsWith("---")) {
13542
13830
  const end = raw.indexOf("\n---", 3);
13543
13831
  if (end >= 0) {
@@ -13551,13 +13839,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
13551
13839
 
13552
13840
  \u2026(truncated)` : raw;
13553
13841
  }
13554
- var import_node_fs37, import_node_os11, import_node_path33;
13842
+ var import_node_fs38, import_node_os11, import_node_path34;
13555
13843
  var init_discover = __esm({
13556
13844
  "src/skills/discover.ts"() {
13557
13845
  "use strict";
13558
- import_node_fs37 = require("fs");
13846
+ import_node_fs38 = require("fs");
13559
13847
  import_node_os11 = require("os");
13560
- import_node_path33 = require("path");
13848
+ import_node_path34 = require("path");
13561
13849
  }
13562
13850
  });
13563
13851
 
@@ -13648,7 +13936,7 @@ var init_expand = __esm({
13648
13936
 
13649
13937
  // src/composer/stage-files.ts
13650
13938
  function fileExtension(filePath) {
13651
- const base = (0, import_node_path34.basename)(filePath).toLowerCase();
13939
+ const base = (0, import_node_path35.basename)(filePath).toLowerCase();
13652
13940
  return base.includes(".") ? base.split(".").pop() || "" : "";
13653
13941
  }
13654
13942
  function isImageFilePath(filePath) {
@@ -13658,22 +13946,22 @@ function imageMimeType(filePath) {
13658
13946
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
13659
13947
  }
13660
13948
  function ensureAttachmentsDir(worktreePath) {
13661
- const dir = (0, import_node_path34.join)(worktreePath, ATTACHMENTS_DIR);
13662
- (0, import_node_fs38.mkdirSync)(dir, { recursive: true });
13663
- const gi = (0, import_node_path34.join)(dir, ".gitignore");
13664
- if (!(0, import_node_fs38.existsSync)(gi)) {
13665
- (0, import_node_fs38.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
13949
+ const dir = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR);
13950
+ (0, import_node_fs39.mkdirSync)(dir, { recursive: true });
13951
+ const gi = (0, import_node_path35.join)(dir, ".gitignore");
13952
+ if (!(0, import_node_fs39.existsSync)(gi)) {
13953
+ (0, import_node_fs39.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
13666
13954
  }
13667
13955
  return dir;
13668
13956
  }
13669
13957
  function uniqueAttachmentName(dir, originalName) {
13670
13958
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
13671
- if (!(0, import_node_fs38.existsSync)((0, import_node_path34.join)(dir, safe))) return safe;
13672
- const ext = (0, import_node_path34.extname)(safe);
13959
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, safe))) return safe;
13960
+ const ext = (0, import_node_path35.extname)(safe);
13673
13961
  const stem = ext ? safe.slice(0, -ext.length) : safe;
13674
13962
  for (let i = 1; i < 1e4; i++) {
13675
13963
  const candidate = `${stem}-${i}${ext}`;
13676
- if (!(0, import_node_fs38.existsSync)((0, import_node_path34.join)(dir, candidate))) return candidate;
13964
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, candidate))) return candidate;
13677
13965
  }
13678
13966
  return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
13679
13967
  }
@@ -13729,15 +14017,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
13729
14017
  const dir = ensureAttachmentsDir(worktreePath);
13730
14018
  const out = [];
13731
14019
  for (const abs of absolutePaths) {
13732
- const originalName = (0, import_node_path34.basename)(abs);
14020
+ const originalName = (0, import_node_path35.basename)(abs);
13733
14021
  try {
13734
- const st = (0, import_node_fs38.statSync)(abs);
14022
+ const st = (0, import_node_fs39.statSync)(abs);
13735
14023
  if (!st.isFile()) continue;
13736
14024
  const name = uniqueAttachmentName(dir, originalName);
13737
- const destAbs = (0, import_node_path34.join)(dir, name);
13738
- (0, import_node_fs38.copyFileSync)(abs, destAbs);
14025
+ const destAbs = (0, import_node_path35.join)(dir, name);
14026
+ (0, import_node_fs39.copyFileSync)(abs, destAbs);
13739
14027
  const rel = `${ATTACHMENTS_DIR}/${name}`;
13740
- const buf = (0, import_node_fs38.readFileSync)(destAbs);
14028
+ const buf = (0, import_node_fs39.readFileSync)(destAbs);
13741
14029
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
13742
14030
  } catch (err) {
13743
14031
  out.push({
@@ -13759,8 +14047,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
13759
14047
  try {
13760
14048
  const buf = Buffer.from(item.dataBase64, "base64");
13761
14049
  const name = uniqueAttachmentName(dir, originalName);
13762
- const destAbs = (0, import_node_path34.join)(dir, name);
13763
- (0, import_node_fs38.writeFileSync)(destAbs, buf);
14050
+ const destAbs = (0, import_node_path35.join)(dir, name);
14051
+ (0, import_node_fs39.writeFileSync)(destAbs, buf);
13764
14052
  const rel = `${ATTACHMENTS_DIR}/${name}`;
13765
14053
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
13766
14054
  } catch (err) {
@@ -13780,18 +14068,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
13780
14068
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
13781
14069
  out.push({
13782
14070
  id: (0, import_node_crypto7.randomUUID)(),
13783
- name: (0, import_node_path34.basename)(rel) || "file",
14071
+ name: (0, import_node_path35.basename)(rel) || "file",
13784
14072
  kind: "file",
13785
14073
  content: `(invalid path: ${rel})`
13786
14074
  });
13787
14075
  continue;
13788
14076
  }
13789
- const name = (0, import_node_path34.basename)(rel);
14077
+ const name = (0, import_node_path35.basename)(rel);
13790
14078
  try {
13791
- const abs = (0, import_node_path34.join)(worktreePath, rel);
13792
- const st = (0, import_node_fs38.statSync)(abs);
14079
+ const abs = (0, import_node_path35.join)(worktreePath, rel);
14080
+ const st = (0, import_node_fs39.statSync)(abs);
13793
14081
  if (!st.isFile()) continue;
13794
- const buf = (0, import_node_fs38.readFileSync)(abs);
14082
+ const buf = (0, import_node_fs39.readFileSync)(abs);
13795
14083
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
13796
14084
  } catch (err) {
13797
14085
  out.push({
@@ -13804,12 +14092,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
13804
14092
  }
13805
14093
  return out;
13806
14094
  }
13807
- var import_node_fs38, import_node_path34, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
14095
+ var import_node_fs39, import_node_path35, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
13808
14096
  var init_stage_files = __esm({
13809
14097
  "src/composer/stage-files.ts"() {
13810
14098
  "use strict";
13811
- import_node_fs38 = require("fs");
13812
- import_node_path34 = require("path");
14099
+ import_node_fs39 = require("fs");
14100
+ import_node_path35 = require("path");
13813
14101
  import_node_crypto7 = require("crypto");
13814
14102
  init_workspace_scratch();
13815
14103
  IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -13978,12 +14266,12 @@ function formatArtifactDirective() {
13978
14266
  function formatUiReminder() {
13979
14267
  return "Sideboard UI: html fence or present_artifact / present_schema / present_files; ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
13980
14268
  }
13981
- var import_node_fs39, import_node_path35;
14269
+ var import_node_fs40, import_node_path36;
13982
14270
  var init_instructions = __esm({
13983
14271
  "src/agents/instructions.ts"() {
13984
14272
  "use strict";
13985
- import_node_fs39 = require("fs");
13986
- import_node_path35 = require("path");
14273
+ import_node_fs40 = require("fs");
14274
+ import_node_path36 = require("path");
13987
14275
  init_git_auth_mode();
13988
14276
  init_worktree_labels();
13989
14277
  }
@@ -14059,40 +14347,40 @@ __export(plan_file_exports, {
14059
14347
  writePlanFile: () => writePlanFile
14060
14348
  });
14061
14349
  function ensureAttachmentsGitignore(worktreePath) {
14062
- const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14063
- if ((0, import_node_fs40.existsSync)(gitignoreAbs)) return;
14064
- (0, import_node_fs40.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
14065
- (0, import_node_fs40.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14350
+ const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14351
+ if ((0, import_node_fs41.existsSync)(gitignoreAbs)) return;
14352
+ (0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
14353
+ (0, import_node_fs41.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14066
14354
  }
14067
14355
  function planFileAbs(worktreePath) {
14068
- return (0, import_node_path36.join)(worktreePath, PLAN_FILE_REL);
14356
+ return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
14069
14357
  }
14070
14358
  function readTextIfPresent2(abs) {
14071
- if (!(0, import_node_fs40.existsSync)(abs)) return null;
14359
+ if (!(0, import_node_fs41.existsSync)(abs)) return null;
14072
14360
  try {
14073
- const content = (0, import_node_fs40.readFileSync)(abs, "utf8");
14361
+ const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
14074
14362
  return content.trim() ? content : null;
14075
14363
  } catch {
14076
14364
  return null;
14077
14365
  }
14078
14366
  }
14079
14367
  function readPlanFile(worktreePath) {
14080
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, LEGACY_PLAN_FILE_REL));
14368
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, LEGACY_PLAN_FILE_REL));
14081
14369
  }
14082
14370
  function writePlanFile(worktreePath, content) {
14083
14371
  ensureAttachmentsGitignore(worktreePath);
14084
14372
  const abs = planFileAbs(worktreePath);
14085
- (0, import_node_fs40.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
14373
+ (0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
14086
14374
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
14087
- (0, import_node_fs40.writeFileSync)(abs, body, "utf8");
14375
+ (0, import_node_fs41.writeFileSync)(abs, body, "utf8");
14088
14376
  return PLAN_FILE_REL;
14089
14377
  }
14090
- var import_node_fs40, import_node_path36;
14378
+ var import_node_fs41, import_node_path37;
14091
14379
  var init_plan_file = __esm({
14092
14380
  "src/plan/plan-file.ts"() {
14093
14381
  "use strict";
14094
- import_node_fs40 = require("fs");
14095
- import_node_path36 = require("path");
14382
+ import_node_fs41 = require("fs");
14383
+ import_node_path37 = require("path");
14096
14384
  init_workspace_scratch();
14097
14385
  init_plan_present();
14098
14386
  init_plan_present();
@@ -14152,7 +14440,7 @@ function setCaffeinateHoldHooks(next) {
14152
14440
  hooks = next;
14153
14441
  }
14154
14442
  function caffeinateHoldPath() {
14155
- return (0, import_node_path37.join)(appDataDir(), "caffeinate-hold.json");
14443
+ return (0, import_node_path38.join)(appDataDir(), "caffeinate-hold.json");
14156
14444
  }
14157
14445
  function processAlive(pid) {
14158
14446
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -14186,9 +14474,9 @@ function uniqueIds(ids) {
14186
14474
  }
14187
14475
  function readHold() {
14188
14476
  const path = caffeinateHoldPath();
14189
- if (!(0, import_node_fs41.existsSync)(path)) return null;
14477
+ if (!(0, import_node_fs42.existsSync)(path)) return null;
14190
14478
  try {
14191
- const parsed = JSON.parse((0, import_node_fs41.readFileSync)(path, "utf8"));
14479
+ const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
14192
14480
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
14193
14481
  return {
14194
14482
  pid: parsed.pid,
@@ -14210,7 +14498,7 @@ function writeHold(pid, threadIds) {
14210
14498
  }
14211
14499
  function clearHold() {
14212
14500
  try {
14213
- (0, import_node_fs41.unlinkSync)(caffeinateHoldPath());
14501
+ (0, import_node_fs42.unlinkSync)(caffeinateHoldPath());
14214
14502
  } catch {
14215
14503
  }
14216
14504
  }
@@ -14295,13 +14583,13 @@ function releaseCaffeinateHoldForThread(threadId) {
14295
14583
  }
14296
14584
  return setCaffeinateHold(false, { threadId: id });
14297
14585
  }
14298
- var import_node_child_process4, import_node_fs41, import_node_path37, hooks;
14586
+ var import_node_child_process4, import_node_fs42, import_node_path38, hooks;
14299
14587
  var init_caffeinate_hold = __esm({
14300
14588
  "src/store/caffeinate-hold.ts"() {
14301
14589
  "use strict";
14302
14590
  import_node_child_process4 = require("child_process");
14303
- import_node_fs41 = require("fs");
14304
- import_node_path37 = require("path");
14591
+ import_node_fs42 = require("fs");
14592
+ import_node_path38 = require("path");
14305
14593
  init_paths();
14306
14594
  init_private_file();
14307
14595
  hooks = {};
@@ -14310,7 +14598,7 @@ var init_caffeinate_hold = __esm({
14310
14598
 
14311
14599
  // src/store/schedules.ts
14312
14600
  function schedulesPath() {
14313
- return (0, import_node_path38.join)(appDataDir(), "schedules.json");
14601
+ return (0, import_node_path39.join)(appDataDir(), "schedules.json");
14314
14602
  }
14315
14603
  function parseDurationMs(every) {
14316
14604
  const m = every.trim().match(DURATION_RE);
@@ -14410,9 +14698,9 @@ function normalizeTask(raw) {
14410
14698
  }
14411
14699
  function readAll2() {
14412
14700
  const path = schedulesPath();
14413
- if (!(0, import_node_fs42.existsSync)(path)) return [];
14701
+ if (!(0, import_node_fs43.existsSync)(path)) return [];
14414
14702
  try {
14415
- const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
14703
+ const parsed = JSON.parse((0, import_node_fs43.readFileSync)(path, "utf8"));
14416
14704
  if (!Array.isArray(parsed)) return [];
14417
14705
  return parsed.map((row) => {
14418
14706
  try {
@@ -14524,13 +14812,13 @@ function recordScheduleRun(id, result) {
14524
14812
  writeAll2(rows);
14525
14813
  return next;
14526
14814
  }
14527
- var import_node_crypto8, import_node_fs42, import_node_path38, import_croner, DURATION_RE, UNIT_MS;
14815
+ var import_node_crypto8, import_node_fs43, import_node_path39, import_croner, DURATION_RE, UNIT_MS;
14528
14816
  var init_schedules = __esm({
14529
14817
  "src/store/schedules.ts"() {
14530
14818
  "use strict";
14531
14819
  import_node_crypto8 = require("crypto");
14532
- import_node_fs42 = require("fs");
14533
- import_node_path38 = require("path");
14820
+ import_node_fs43 = require("fs");
14821
+ import_node_path39 = require("path");
14534
14822
  import_croner = require("croner");
14535
14823
  init_orchestrator_capable();
14536
14824
  init_paths();
@@ -14678,10 +14966,10 @@ __export(cursor_recover_exports, {
14678
14966
  function recoverFinishedCursorRun(opts) {
14679
14967
  const agentId = opts.agentId.trim();
14680
14968
  if (!agentId) return null;
14681
- const runsPath = (0, import_node_path39.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
14682
- if (!(0, import_node_fs43.existsSync)(runsPath)) return null;
14969
+ const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
14970
+ if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
14683
14971
  try {
14684
- const lines = (0, import_node_fs43.readFileSync)(runsPath, "utf8").split("\n");
14972
+ const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
14685
14973
  let best = null;
14686
14974
  for (const line of lines) {
14687
14975
  const trimmed = line.trim();
@@ -14707,12 +14995,12 @@ function recoverFinishedCursorRun(opts) {
14707
14995
  return null;
14708
14996
  }
14709
14997
  }
14710
- var import_node_fs43, import_node_path39;
14998
+ var import_node_fs44, import_node_path40;
14711
14999
  var init_cursor_recover = __esm({
14712
15000
  "src/agents/cursor-recover.ts"() {
14713
15001
  "use strict";
14714
- import_node_fs43 = require("fs");
14715
- import_node_path39 = require("path");
15002
+ import_node_fs44 = require("fs");
15003
+ import_node_path40 = require("path");
14716
15004
  init_paths();
14717
15005
  }
14718
15006
  });
@@ -14843,14 +15131,16 @@ async function startOrchestration(opts) {
14843
15131
  }
14844
15132
  return updated;
14845
15133
  }
14846
- var import_node_events, import_node_fs44, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
15134
+ var import_node_events, import_node_fs45, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
14847
15135
  var init_orchestrator = __esm({
14848
15136
  "src/orchestrator/orchestrator.ts"() {
14849
15137
  "use strict";
14850
15138
  import_node_events = require("events");
14851
15139
  init_outbound_watch();
14852
- import_node_fs44 = require("fs");
15140
+ import_node_fs45 = require("fs");
14853
15141
  init_error_detail();
15142
+ init_run();
15143
+ init_stale_lock();
14854
15144
  init_spawn();
14855
15145
  init_agents();
14856
15146
  init_worktree();
@@ -14966,7 +15256,7 @@ var init_orchestrator = __esm({
14966
15256
  }
14967
15257
  continue;
14968
15258
  }
14969
- if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
15259
+ if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
14970
15260
  setStatus(thread.id, "broken", "Worktree missing on disk");
14971
15261
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
14972
15262
  continue;
@@ -15559,7 +15849,15 @@ var init_orchestrator = __esm({
15559
15849
  hasSession: Boolean(this.requireThread(threadId).sessionId)
15560
15850
  })) {
15561
15851
  updateThread(threadId, { sessionId: null });
15562
- const retryNote = looksLikeInvalidAgentSession(detail) ? "Agent session missing \u2014 starting a fresh session" : "Agent runner crashed \u2014 restarting Node once";
15852
+ try {
15853
+ const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
15854
+ const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
15855
+ if (clearedLocks.length > 0) {
15856
+ pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
15857
+ }
15858
+ } catch {
15859
+ }
15860
+ 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";
15563
15861
  pushTurnStderr(stderrTail, retryNote);
15564
15862
  this.emit({
15565
15863
  type: "turn_output",
@@ -16031,13 +16329,14 @@ var init_orchestrator = __esm({
16031
16329
  const text4 = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
16032
16330
  const stillRunning = thread.status === "running" || thread.status === "queued";
16033
16331
  const live = stillRunning ? readTurnLive(thread.id) : null;
16332
+ const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
16034
16333
  return {
16035
16334
  text: text4,
16036
16335
  status: thread.status,
16037
16336
  sessionId: thread.sessionId,
16038
16337
  lastError,
16039
16338
  stillRunning,
16040
- progress: live?.summary ?? null,
16339
+ progress: live?.summary ?? queuedHint,
16041
16340
  lastActivityAt: live?.updatedAt ?? null
16042
16341
  };
16043
16342
  }
@@ -16554,7 +16853,7 @@ var init_orchestrator = __esm({
16554
16853
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
16555
16854
  return restored2;
16556
16855
  }
16557
- if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
16856
+ if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
16558
16857
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
16559
16858
  throw new Error(
16560
16859
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -16634,7 +16933,7 @@ init_nested_electron_env();
16634
16933
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
16635
16934
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
16636
16935
  var import_zod4 = require("zod");
16637
- var import_node_path40 = require("path");
16936
+ var import_node_path41 = require("path");
16638
16937
  init_orchestrator();
16639
16938
  init_worktree();
16640
16939
 
@@ -17141,6 +17440,10 @@ function mcpWaitForTurnTimeoutMs(requested) {
17141
17440
  return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
17142
17441
  }
17143
17442
  var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send a check-in prompt or assume a hang while progress is updating.";
17443
+ var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send a check-in prompt, force_stop, or assume it failed to start.";
17444
+ function mcpWaitStillRunningHint(status) {
17445
+ return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
17446
+ }
17144
17447
 
17145
17448
  // src/mcp/server.ts
17146
17449
  init_turn_live();
@@ -17987,7 +18290,7 @@ async function startMcpServer() {
17987
18290
  async () => {
17988
18291
  const threads = orch.getThreads(true);
17989
18292
  const lines = threads.map((t) => {
17990
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path40.basename)(t.repoPath) || t.repoPath;
18293
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
17991
18294
  const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
17992
18295
  const progress = live?.summary ? ` ${live.summary}` : "";
17993
18296
  return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}${progress}`;
@@ -18023,7 +18326,7 @@ async function startMcpServer() {
18023
18326
  prUrl: t.prUrl,
18024
18327
  lastError: t.lastError ?? null,
18025
18328
  stillRunning: t.status === "running" || t.status === "queued",
18026
- progress: live?.summary ?? null,
18329
+ progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
18027
18330
  lastActivityAt: live?.updatedAt ?? null
18028
18331
  };
18029
18332
  return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
@@ -18357,7 +18660,7 @@ async function startMcpServer() {
18357
18660
  );
18358
18661
  server.tool(
18359
18662
  "wait_for_turn",
18360
- "Wait until the thread finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. If stillRunning is true, progress is tools/thinking \u2014 call wait_for_turn again. Do not send a check-in prompt or assume a hang. On status error, lastError/text is the failure.",
18663
+ "Wait until the thread finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. If stillRunning is true, progress is tools/thinking (or \u201Cqueued, waiting for a concurrency slot\u201D if it has not started). Call wait_for_turn again. Do not send a check-in prompt, force_stop, or assume a hang. On status error, lastError/text is the failure.",
18361
18664
  {
18362
18665
  ref: import_zod4.z.string(),
18363
18666
  timeoutMs: import_zod4.z.number().optional()
@@ -18379,7 +18682,7 @@ async function startMcpServer() {
18379
18682
  stillRunning: result.stillRunning,
18380
18683
  progress: result.progress,
18381
18684
  lastActivityAt: result.lastActivityAt,
18382
- hint: result.stillRunning ? MCP_WAIT_STILL_RUNNING_HINT : void 0
18685
+ hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
18383
18686
  })
18384
18687
  }
18385
18688
  ]
@@ -18398,7 +18701,7 @@ async function startMcpServer() {
18398
18701
  type: "text",
18399
18702
  text: JSON.stringify({
18400
18703
  ...result,
18401
- hint: result.stillRunning ? MCP_WAIT_STILL_RUNNING_HINT : void 0
18704
+ hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
18402
18705
  })
18403
18706
  }
18404
18707
  ]