@sideboard-ai/core 0.1.111 → 0.1.116

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 +51 -21
  2. package/dist/agents/cursor-runner.js +3 -3
  3. package/dist/{agents-NN22A4G5.js → agents-7NIX44RB.js} +7 -7
  4. package/dist/{agents-GH3FWDW2.js → agents-DU7DHY7A.js} +10 -10
  5. package/dist/{chunk-JTQQPJAU.js → chunk-4HOFVKPC.js} +52 -38
  6. package/dist/{chunk-4EWPKYOU.js → chunk-4OJMZ6P2.js} +2 -2
  7. package/dist/{chunk-NC3U42ZP.js → chunk-5KSLD4MU.js} +317 -33
  8. package/dist/{chunk-KQBI5HNT.js → chunk-7WC5UWEB.js} +2 -2
  9. package/dist/{chunk-WIHKHR5R.js → chunk-AXQ4ZWHK.js} +5 -0
  10. package/dist/{chunk-LGXBYZZA.js → chunk-DVM4ID64.js} +69 -13
  11. package/dist/{chunk-DMJKOFTO.js → chunk-DWP25N32.js} +44 -35
  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-363Z34PY.js → chunk-GBY7OOMB.js} +273 -218
  15. package/dist/{chunk-7KWYXGIU.js → chunk-K3TIQXOH.js} +2 -2
  16. package/dist/{chunk-3KETJKYA.js → chunk-KPIYENTF.js} +69 -13
  17. package/dist/{chunk-KVFNTWFG.js → chunk-OFF5AFCR.js} +300 -43
  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 +855 -440
  30. package/dist/index.d.cts +59 -1
  31. package/dist/index.d.ts +59 -1
  32. package/dist/index.js +37 -17
  33. package/dist/mcp/run-stdio.cjs +966 -635
  34. package/dist/mcp/run-stdio.js +20 -16
  35. package/dist/{orchestrator-4T2SXDZ7.js → orchestrator-NXPANCZA.js} +8 -8
  36. package/dist/{orchestrator-EP57AB5W.js → orchestrator-ZY4RUJKT.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
@@ -1507,6 +1507,7 @@ function looksLikeRetryableRunnerCrash(text4) {
1507
1507
  }
1508
1508
  function shouldRetryFailedAgentTurn(detail, opts) {
1509
1509
  if (looksLikeInvalidAgentSession(detail) && opts.hasSession) return true;
1510
+ if (looksLikeV8Oom(detail) && opts.hasSession) return true;
1510
1511
  return looksLikeRetryableRunnerCrash(detail);
1511
1512
  }
1512
1513
  function looksLikeAgentFailureMessage(text4) {
@@ -1599,11 +1600,258 @@ var init_error_detail = __esm({
1599
1600
  NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
1600
1601
  HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 22 LTS (`brew install node@22`) and retry.";
1601
1602
  BUNDLED_NODE_CRASH_SUMMARY = "Cursor runner crashed in Node. Retry the turn.";
1602
- V8_OOM_SUMMARY = "Cursor runner ran out of memory (JavaScript heap). Retry; if it keeps happening, exclude large files from the project folder or start a new chat.";
1603
+ V8_OOM_SUMMARY = "Agent ran out of memory (JavaScript heap). If it keeps happening, exclude large files from the project folder.";
1603
1604
  MINIFIED_DUMP_SUMMARY = "Cursor local agent crashed during startup (truncated crash dump)";
1604
1605
  }
1605
1606
  });
1606
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
+
1607
1855
  // src/git/team-meta.ts
1608
1856
  var SOCCER_TEAM_META;
1609
1857
  var init_team_meta = __esm({
@@ -2505,7 +2753,7 @@ var init_gh_errors = __esm({
2505
2753
 
2506
2754
  // src/store/secret-vault.ts
2507
2755
  function secretVaultPath() {
2508
- return (0, import_node_path10.join)(appDataDir(), "secrets.json");
2756
+ return (0, import_node_path12.join)(appDataDir(), "secrets.json");
2509
2757
  }
2510
2758
  function loadSecretVault() {
2511
2759
  const parsed = readSecureJson(secretVaultPath());
@@ -2549,11 +2797,11 @@ function normalizeVault(raw) {
2549
2797
  }
2550
2798
  return out;
2551
2799
  }
2552
- var import_node_path10;
2800
+ var import_node_path12;
2553
2801
  var init_secret_vault = __esm({
2554
2802
  "src/store/secret-vault.ts"() {
2555
2803
  "use strict";
2556
- import_node_path10 = require("path");
2804
+ import_node_path12 = require("path");
2557
2805
  init_paths();
2558
2806
  init_secure_file();
2559
2807
  }
@@ -2656,10 +2904,10 @@ function toPublicAppSettings(settings) {
2656
2904
  };
2657
2905
  }
2658
2906
  function appSettingsPath() {
2659
- return (0, import_node_path11.join)(appDataDir(), "settings.json");
2907
+ return (0, import_node_path13.join)(appDataDir(), "settings.json");
2660
2908
  }
2661
2909
  function claudeUserSettingsPath() {
2662
- 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");
2663
2911
  }
2664
2912
  function normalizeClaude(raw) {
2665
2913
  if (!raw || typeof raw !== "object") return {};
@@ -2908,10 +3156,10 @@ function normalizeSettings(raw) {
2908
3156
  }
2909
3157
  function readSettingsFile() {
2910
3158
  const path = appSettingsPath();
2911
- if (!(0, import_node_fs10.existsSync)(path)) return { ...EMPTY_SETTINGS };
3159
+ if (!(0, import_node_fs12.existsSync)(path)) return { ...EMPTY_SETTINGS };
2912
3160
  try {
2913
3161
  chmodOwnerOnly(path);
2914
- const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf8"));
3162
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
2915
3163
  return normalizeSettings(parsed);
2916
3164
  } catch {
2917
3165
  return { ...EMPTY_SETTINGS };
@@ -3296,7 +3544,7 @@ function ensureSlackDeviceIdentity(settings = loadAppSettings()) {
3296
3544
  }
3297
3545
  if (!deviceLabel) {
3298
3546
  try {
3299
- deviceLabel = (0, import_node_os3.hostname)().split(".")[0]?.trim() || "This Mac";
3547
+ deviceLabel = (0, import_node_os4.hostname)().split(".")[0]?.trim() || "This Mac";
3300
3548
  } catch {
3301
3549
  deviceLabel = "This Mac";
3302
3550
  }
@@ -3483,14 +3731,14 @@ function childEnvWithAppSettings(extra) {
3483
3731
  function harnessEnvKey(harness) {
3484
3732
  return HARNESS_ENV_KEYS[harness];
3485
3733
  }
3486
- 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;
3487
3735
  var init_app_settings = __esm({
3488
3736
  "src/store/app-settings.ts"() {
3489
3737
  "use strict";
3490
3738
  import_node_crypto3 = require("crypto");
3491
- import_node_fs10 = require("fs");
3492
- import_node_os3 = require("os");
3493
- import_node_path11 = require("path");
3739
+ import_node_fs12 = require("fs");
3740
+ import_node_os4 = require("os");
3741
+ import_node_path13 = require("path");
3494
3742
  init_thinking_effort();
3495
3743
  init_nested_electron_env();
3496
3744
  init_paths();
@@ -3542,23 +3790,23 @@ var init_app_settings = __esm({
3542
3790
  function githubAgentAuthDir() {
3543
3791
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
3544
3792
  if (override) return override;
3545
- 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");
3546
3794
  }
3547
3795
  function githubCredentialStorePath() {
3548
- return (0, import_node_path12.join)(githubAgentAuthDir(), "git-credentials");
3796
+ return (0, import_node_path14.join)(githubAgentAuthDir(), "git-credentials");
3549
3797
  }
3550
3798
  function githubGhConfigDir() {
3551
- return (0, import_node_path12.join)(githubAgentAuthDir(), "gh");
3799
+ return (0, import_node_path14.join)(githubAgentAuthDir(), "gh");
3552
3800
  }
3553
3801
  function writePrivateFile2(file, body) {
3554
- (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 });
3555
3803
  try {
3556
- (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);
3557
3805
  } catch {
3558
3806
  }
3559
- (0, import_node_fs11.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
3807
+ (0, import_node_fs13.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
3560
3808
  try {
3561
- (0, import_node_fs11.chmodSync)(file, 384);
3809
+ (0, import_node_fs13.chmodSync)(file, 384);
3562
3810
  } catch {
3563
3811
  }
3564
3812
  }
@@ -3583,225 +3831,40 @@ function materializeGithubAgentAuth(token, user) {
3583
3831
  const trimmed = token.trim();
3584
3832
  if (!trimmed) return;
3585
3833
  const root = githubAgentAuthDir();
3586
- (0, import_node_fs11.mkdirSync)(root, { recursive: true, mode: 448 });
3834
+ (0, import_node_fs13.mkdirSync)(root, { recursive: true, mode: 448 });
3587
3835
  try {
3588
- (0, import_node_fs11.chmodSync)(root, 448);
3836
+ (0, import_node_fs13.chmodSync)(root, 448);
3589
3837
  } catch {
3590
3838
  }
3591
3839
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
3592
- const ghDir = githubGhConfigDir();
3593
- (0, import_node_fs11.mkdirSync)(ghDir, { recursive: true, mode: 448 });
3594
- writePrivateFile2((0, import_node_path12.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
3595
- writePrivateFile2((0, import_node_path12.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
3596
- }
3597
- function githubAgentAuthReady() {
3598
- return (0, import_node_fs11.existsSync)(githubCredentialStorePath()) && (0, import_node_fs11.existsSync)((0, import_node_path12.join)(githubGhConfigDir(), "hosts.yml"));
3599
- }
3600
- function githubCredentialHelperGitConfig() {
3601
- const file = githubCredentialStorePath();
3602
- return [
3603
- { key: "credential.helper", value: "" },
3604
- { key: "credential.helper", value: `store --file=${file}` }
3605
- ];
3606
- }
3607
- function githubGhConfigEnv() {
3608
- return {
3609
- GH_CONFIG_DIR: githubGhConfigDir(),
3610
- GH_PROMPT_DISABLED: "1"
3611
- };
3612
- }
3613
- var import_node_fs11, import_node_os4, import_node_path12;
3614
- var init_github_agent_auth = __esm({
3615
- "src/git/github-agent-auth.ts"() {
3616
- "use strict";
3617
- import_node_fs11 = require("fs");
3618
- import_node_os4 = require("os");
3619
- import_node_path12 = require("path");
3620
- }
3621
- });
3622
-
3623
- // src/agents/path.ts
3624
- function prependPathDir(env, dir) {
3625
- if (!dir || !(0, import_node_fs12.existsSync)(dir)) return;
3626
- const current = env.PATH ?? "";
3627
- const parts = current.split(import_node_path13.delimiter).filter(Boolean);
3628
- if (parts.includes(dir)) {
3629
- env.PATH = current;
3630
- return;
3631
- }
3632
- env.PATH = [dir, ...parts].join(import_node_path13.delimiter);
3633
- }
3634
- function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
3635
- return (0, import_node_path13.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
3636
- }
3637
- function isConductorBundledCli(filePath) {
3638
- const p = (filePath ?? "").replace(/\\/g, "/");
3639
- return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
3640
- }
3641
- function ensureAgentPath(env = process.env) {
3642
- const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
3643
- const current = env.PATH ?? "";
3644
- const parts = current.split(import_node_path13.delimiter).filter(Boolean);
3645
- const seen = new Set(parts);
3646
- const extras = [
3647
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path13.join)(home, rel)),
3648
- "/opt/homebrew/bin",
3649
- "/usr/local/bin",
3650
- // Keep after Homebrew/npm so a user-installed CLI still wins.
3651
- conductorBundledBinDir(home)
3652
- ];
3653
- for (const dir of extras.reverse()) {
3654
- if (!dir || seen.has(dir) || !(0, import_node_fs12.existsSync)(dir)) continue;
3655
- parts.unshift(dir);
3656
- seen.add(dir);
3657
- }
3658
- const next = parts.join(import_node_path13.delimiter);
3659
- env.PATH = next;
3660
- return next;
3661
- }
3662
- function enrichPathWithNpmGlobalBin(env = process.env) {
3663
- ensureAgentPath(env);
3664
- try {
3665
- const prefix = (0, import_node_child_process2.execFileSync)("npm", ["prefix", "-g"], {
3666
- encoding: "utf8",
3667
- env: { ...process.env, ...env },
3668
- timeout: 8e3,
3669
- stdio: ["ignore", "pipe", "ignore"]
3670
- }).trim().split(/\r?\n/).find(Boolean);
3671
- if (prefix) {
3672
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
3673
- prependPathDir(env, binDir);
3674
- }
3675
- } catch {
3676
- }
3677
- return env.PATH ?? "";
3678
- }
3679
- function posixShellSingleQuote(value) {
3680
- return `'${value.replace(/'/g, `'\\''`)}'`;
3681
- }
3682
- function resolveCommandBinarySync(command, whichPath) {
3683
- const trimmed = command.trim();
3684
- if (!trimmed) return trimmed;
3685
- const match = /^(\S+)(\s[\s\S]*)?$/.exec(trimmed);
3686
- if (!match) return trimmed;
3687
- const bin = match[1];
3688
- const rest = match[2] ?? "";
3689
- if (bin.includes("/") || bin.includes("\\")) return trimmed;
3690
- const abs = whichPath?.trim().split(/\r?\n/).find(Boolean);
3691
- if (!abs) return trimmed;
3692
- return `${abs}${rest}`;
3693
- }
3694
- function withExportedPath(command, pathValue) {
3695
- const trimmed = command.trim();
3696
- if (!trimmed) return trimmed;
3697
- if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
3698
- return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
3699
- }
3700
- var import_node_fs12, import_node_child_process2, import_node_os5, import_node_path13, EXTRA_BIN_DIRS;
3701
- var init_path = __esm({
3702
- "src/agents/path.ts"() {
3703
- "use strict";
3704
- import_node_fs12 = require("fs");
3705
- import_node_child_process2 = require("child_process");
3706
- import_node_os5 = require("os");
3707
- import_node_path13 = require("path");
3708
- EXTRA_BIN_DIRS = [
3709
- ".local/bin",
3710
- ".cargo/bin",
3711
- ".nvm/current/bin",
3712
- ".asdf/shims",
3713
- ".volta/bin",
3714
- ".npm-global/bin",
3715
- // fnm default alias (common when shell init is skipped)
3716
- ".local/share/fnm/aliases/default/bin",
3717
- // pnpm / npm global bins (where `@brightsy/cli` typically lands)
3718
- "Library/pnpm",
3719
- ".pnpm"
3720
- ];
3721
- }
3722
- });
3723
-
3724
- // src/git/run.ts
3725
- var run_exports = {};
3726
- __export(run_exports, {
3727
- gh: () => gh,
3728
- git: () => git,
3729
- resolveGhAuthToken: () => resolveGhAuthToken,
3730
- run: () => run
3731
- });
3732
- async function run(file, args, opts) {
3733
- ensureAgentPath();
3734
- try {
3735
- const result = await (0, import_execa2.execa)(file, args, {
3736
- cwd: opts?.cwd,
3737
- env: { ...process.env, ...opts?.env },
3738
- reject: opts?.reject ?? true,
3739
- ...opts?.timeoutMs != null ? { timeout: opts.timeoutMs } : {}
3740
- });
3741
- return {
3742
- stdout: result.stdout ?? "",
3743
- stderr: result.stderr ?? "",
3744
- exitCode: result.exitCode ?? 0
3745
- };
3746
- } catch (err) {
3747
- const e = err;
3748
- if (opts?.reject === false) {
3749
- return {
3750
- stdout: String(e.stdout ?? ""),
3751
- stderr: String(e.stderr ?? ""),
3752
- exitCode: e.exitCode ?? 1
3753
- };
3754
- }
3755
- throw err;
3756
- }
3757
- }
3758
- async function git(args, cwd, opts) {
3759
- const prefix = [];
3760
- if (opts?.config) {
3761
- for (const [key, value] of Object.entries(opts.config)) {
3762
- if (!key) continue;
3763
- prefix.push("-c", `${key}=${value}`);
3764
- }
3765
- }
3766
- return run("git", ["--no-pager", ...prefix, ...args], {
3767
- cwd,
3768
- reject: opts?.reject,
3769
- timeoutMs: opts?.timeoutMs,
3770
- // Never block forever on a credential/SSH prompt inside MCP / Electron.
3771
- env: {
3772
- GIT_TERMINAL_PROMPT: "0",
3773
- GIT_ASKPASS: process.env.GIT_ASKPASS || "echo",
3774
- SSH_ASKPASS: process.env.SSH_ASKPASS || "echo",
3775
- GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND || "ssh -o BatchMode=yes -o ConnectTimeout=15",
3776
- GCM_INTERACTIVE: "never",
3777
- GH_PROMPT_DISABLED: "1",
3778
- ...opts?.env
3779
- }
3780
- });
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");
3781
3844
  }
3782
- async function gh(args, cwd, opts) {
3783
- return run("gh", args, {
3784
- cwd,
3785
- reject: opts?.reject,
3786
- timeoutMs: opts?.timeoutMs,
3787
- env: {
3788
- GH_PROMPT_DISABLED: "1",
3789
- GIT_TERMINAL_PROMPT: "0"
3790
- }
3791
- });
3845
+ function githubAgentAuthReady() {
3846
+ return (0, import_node_fs13.existsSync)(githubCredentialStorePath()) && (0, import_node_fs13.existsSync)((0, import_node_path14.join)(githubGhConfigDir(), "hosts.yml"));
3792
3847
  }
3793
- async function resolveGhAuthToken(cwd) {
3794
- const result = await gh(["auth", "token"], cwd, { reject: false, timeoutMs: 8e3 });
3795
- if (result.exitCode !== 0) return null;
3796
- const token = result.stdout.trim();
3797
- 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
+ ];
3798
3854
  }
3799
- var import_execa2;
3800
- var init_run = __esm({
3801
- "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"() {
3802
3864
  "use strict";
3803
- import_execa2 = require("execa");
3804
- init_path();
3865
+ import_node_fs13 = require("fs");
3866
+ import_node_os5 = require("os");
3867
+ import_node_path14 = require("path");
3805
3868
  }
3806
3869
  });
3807
3870
 
@@ -3893,7 +3956,7 @@ async function warmGithubAgentAuth(opts) {
3893
3956
  }
3894
3957
  function normalizeWritableRoot(raw) {
3895
3958
  const trimmed = raw.trim().replace(/\/+$/, "");
3896
- return trimmed && (0, import_node_path14.isAbsolute)(trimmed) ? trimmed : null;
3959
+ return trimmed && (0, import_node_path15.isAbsolute)(trimmed) ? trimmed : null;
3897
3960
  }
3898
3961
  async function resolveCodexGitWritableRoots(cwd) {
3899
3962
  const roots = /* @__PURE__ */ new Set();
@@ -3970,11 +4033,11 @@ function formatGitAuthModeDirective(mode) {
3970
4033
  ].join("\n");
3971
4034
  }
3972
4035
  }
3973
- 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;
3974
4037
  var init_git_auth_mode = __esm({
3975
4038
  "src/git/git-auth-mode.ts"() {
3976
4039
  "use strict";
3977
- import_node_path14 = require("path");
4040
+ import_node_path15 = require("path");
3978
4041
  init_app_settings();
3979
4042
  init_github_agent_auth();
3980
4043
  init_run();
@@ -5144,8 +5207,8 @@ function isLocalPrFetchBranch(ref) {
5144
5207
  }
5145
5208
  async function createThreadWorktree(opts) {
5146
5209
  let branchName = `thread/${opts.slug}`;
5147
- const worktreePath = (0, import_node_path15.join)(worktreesRoot(opts.repoPath), opts.slug);
5148
- 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)) {
5149
5212
  throw new Error(`Worktree already exists at ${worktreePath}`);
5150
5213
  }
5151
5214
  await ensureGhPreferOrigin(opts.repoPath);
@@ -5212,8 +5275,8 @@ ${add.stdout}`;
5212
5275
  async function createExistingBranchWorktree(opts) {
5213
5276
  const branchName = opts.branchName.trim();
5214
5277
  if (!branchName) throw new Error("branch name required");
5215
- const worktreePath = (0, import_node_path15.join)(worktreesRoot(opts.repoPath), opts.slug);
5216
- 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)) {
5217
5280
  throw new Error(`Worktree already exists at ${worktreePath}`);
5218
5281
  }
5219
5282
  await ensureGhPreferOrigin(opts.repoPath);
@@ -5504,10 +5567,10 @@ function sameRepoPath(a, b) {
5504
5567
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
5505
5568
  }
5506
5569
  function listLocalThreadBranchSlugs(repoPath) {
5507
- const refsDir = (0, import_node_path15.join)(repoPath, ".git", "refs", "heads", "thread");
5508
- 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 [];
5509
5572
  try {
5510
- 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));
5511
5574
  } catch {
5512
5575
  return [];
5513
5576
  }
@@ -5515,8 +5578,8 @@ function listLocalThreadBranchSlugs(repoPath) {
5515
5578
  function collectTakenTeamSlugs(repoPath) {
5516
5579
  const taken = /* @__PURE__ */ new Set();
5517
5580
  const root = worktreesRoot(repoPath);
5518
- if ((0, import_node_fs13.existsSync)(root)) {
5519
- 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 })) {
5520
5583
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
5521
5584
  taken.add(normalizeTakenSlug(entry.name));
5522
5585
  }
@@ -5537,18 +5600,18 @@ function allocateTeamSlug(repoPath) {
5537
5600
  const taken = collectTakenTeamSlugs(repoPath);
5538
5601
  for (let attempt = 0; attempt < 32; attempt++) {
5539
5602
  const team = allocateTeamName(taken);
5540
- const path = (0, import_node_path15.join)(worktreesRoot(repoPath), team.slug);
5541
- 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;
5542
5605
  taken.add(team.slug);
5543
5606
  }
5544
5607
  throw new Error("No available soccer team worktree directories left");
5545
5608
  }
5546
- var import_node_fs13, import_node_path15;
5609
+ var import_node_fs14, import_node_path16;
5547
5610
  var init_worktree = __esm({
5548
5611
  "src/git/worktree.ts"() {
5549
5612
  "use strict";
5550
- import_node_fs13 = require("fs");
5551
- import_node_path15 = require("path");
5613
+ import_node_fs14 = require("fs");
5614
+ import_node_path16 = require("path");
5552
5615
  init_paths();
5553
5616
  init_thread_store();
5554
5617
  init_teams();
@@ -5683,7 +5746,7 @@ function coordinatorTurnReminder(opts) {
5683
5746
  function ensureGlobalCoordinatorCwd(opts) {
5684
5747
  const dir = globalAgentCwd();
5685
5748
  try {
5686
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
5749
+ (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
5687
5750
  } catch {
5688
5751
  return dir;
5689
5752
  }
@@ -5691,7 +5754,7 @@ function ensureGlobalCoordinatorCwd(opts) {
5691
5754
  let orchId = opts?.orchestratorThreadId?.trim() || "";
5692
5755
  if (!orchId) {
5693
5756
  try {
5694
- 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");
5695
5758
  const m = existing.match(
5696
5759
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
5697
5760
  );
@@ -5733,9 +5796,9 @@ function ensureGlobalCoordinatorCwd(opts) {
5733
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."
5734
5797
  ].join("\n");
5735
5798
  try {
5736
- (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}
5737
5800
  `, "utf8");
5738
- (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}
5739
5802
  `, "utf8");
5740
5803
  } catch {
5741
5804
  }
@@ -5767,12 +5830,12 @@ function coordinatorSystemPrompt(opts) {
5767
5830
  formatWorkspaceInventory(opts.workspaces)
5768
5831
  ].join("\n");
5769
5832
  }
5770
- 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;
5771
5834
  var init_coordinator_prompt = __esm({
5772
5835
  "src/orchestrator/coordinator-prompt.ts"() {
5773
5836
  "use strict";
5774
- import_node_fs14 = require("fs");
5775
- import_node_path16 = require("path");
5837
+ import_node_fs15 = require("fs");
5838
+ import_node_path17 = require("path");
5776
5839
  init_worktree();
5777
5840
  init_app_settings();
5778
5841
  init_paths();
@@ -5798,7 +5861,7 @@ var init_coordinator_prompt = __esm({
5798
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.",
5799
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.",
5800
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",
5801
- "- 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.",
5802
5865
  "- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
5803
5866
  "- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
5804
5867
  "Setup / run:",
@@ -6070,32 +6133,32 @@ var init_global_workspace = __esm({
6070
6133
 
6071
6134
  // src/brightsy/config.ts
6072
6135
  function brightsyConfigPath() {
6073
- 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");
6074
6137
  }
6075
6138
  function loadBrightsyConfig() {
6076
6139
  const path = brightsyConfigPath();
6077
- if (!(0, import_node_fs15.existsSync)(path)) {
6140
+ if (!(0, import_node_fs16.existsSync)(path)) {
6078
6141
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
6079
6142
  }
6080
- const raw = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
6143
+ const raw = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
6081
6144
  if (!raw.access_token || !raw.account_id) {
6082
6145
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
6083
6146
  }
6084
6147
  return raw;
6085
6148
  }
6086
6149
  function saveBrightsyConfig(cfg) {
6087
- (0, import_node_fs15.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
6150
+ (0, import_node_fs16.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
6088
6151
  `, {
6089
6152
  mode: 384
6090
6153
  });
6091
6154
  }
6092
- var import_node_fs15, import_node_os6, import_node_path17;
6155
+ var import_node_fs16, import_node_os6, import_node_path18;
6093
6156
  var init_config = __esm({
6094
6157
  "src/brightsy/config.ts"() {
6095
6158
  "use strict";
6096
- import_node_fs15 = require("fs");
6159
+ import_node_fs16 = require("fs");
6097
6160
  import_node_os6 = require("os");
6098
- import_node_path17 = require("path");
6161
+ import_node_path18 = require("path");
6099
6162
  }
6100
6163
  });
6101
6164
 
@@ -6110,22 +6173,22 @@ var init_accounts = __esm({
6110
6173
 
6111
6174
  // src/brightsy/connected-teams.ts
6112
6175
  function storePath4() {
6113
- return (0, import_node_path18.join)(appDataDir(), "brightsy-teams.json");
6176
+ return (0, import_node_path19.join)(appDataDir(), "brightsy-teams.json");
6114
6177
  }
6115
6178
  function readStore4() {
6116
6179
  const path = storePath4();
6117
- if (!(0, import_node_fs16.existsSync)(path)) return [];
6180
+ if (!(0, import_node_fs17.existsSync)(path)) return [];
6118
6181
  try {
6119
- const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
6182
+ const parsed = JSON.parse((0, import_node_fs17.readFileSync)(path, "utf8"));
6120
6183
  return Array.isArray(parsed.teams) ? parsed.teams : [];
6121
6184
  } catch {
6122
6185
  return [];
6123
6186
  }
6124
6187
  }
6125
6188
  function writeStore2(teams) {
6126
- (0, import_node_fs16.mkdirSync)(appDataDir(), { recursive: true });
6189
+ (0, import_node_fs17.mkdirSync)(appDataDir(), { recursive: true });
6127
6190
  const path = storePath4();
6128
- (0, import_node_fs16.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
6191
+ (0, import_node_fs17.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
6129
6192
  `, {
6130
6193
  mode: 384
6131
6194
  });
@@ -6237,12 +6300,12 @@ function brightsyMcpServerName(slug) {
6237
6300
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
6238
6301
  return `brightsy_${cleaned || "team"}`;
6239
6302
  }
6240
- var import_node_fs16, import_node_path18;
6303
+ var import_node_fs17, import_node_path19;
6241
6304
  var init_connected_teams = __esm({
6242
6305
  "src/brightsy/connected-teams.ts"() {
6243
6306
  "use strict";
6244
- import_node_fs16 = require("fs");
6245
- import_node_path18 = require("path");
6307
+ import_node_fs17 = require("fs");
6308
+ import_node_path19 = require("path");
6246
6309
  init_paths();
6247
6310
  init_accounts();
6248
6311
  init_config();
@@ -6573,11 +6636,11 @@ async function syncCliForTarget(accountId) {
6573
6636
  }
6574
6637
  applyConnectedTeamToCli(team);
6575
6638
  }
6576
- var import_node_fs17, brightsyAdapter;
6639
+ var import_node_fs18, brightsyAdapter;
6577
6640
  var init_brightsy = __esm({
6578
6641
  "src/agents/brightsy.ts"() {
6579
6642
  "use strict";
6580
- import_node_fs17 = require("fs");
6643
+ import_node_fs18 = require("fs");
6581
6644
  init_run();
6582
6645
  init_connected_teams();
6583
6646
  init_config();
@@ -6592,7 +6655,7 @@ var init_brightsy = __esm({
6592
6655
  async detect() {
6593
6656
  const brightsy = resolveAgentExecutable("brightsy");
6594
6657
  if (brightsy !== "brightsy") {
6595
- if (!(0, import_node_fs17.existsSync)(brightsy)) {
6658
+ if (!(0, import_node_fs18.existsSync)(brightsy)) {
6596
6659
  return {
6597
6660
  agent: "brightsy",
6598
6661
  installed: false,
@@ -6761,9 +6824,9 @@ function toolDescription(name, input) {
6761
6824
  if (/connectedAgentRequest/i.test(name)) {
6762
6825
  return str2(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
6763
6826
  }
6764
- if (desc && kind) return `${kind}: ${desc}`;
6765
- if (desc) return desc;
6766
- return "Subagent";
6827
+ if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
6828
+ if (desc) return `${desc}${subagentLiveSuffix(input)}`;
6829
+ return `Subagent${subagentLiveSuffix(input)}`;
6767
6830
  }
6768
6831
  if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
6769
6832
  return str2(input?.title) ? `Artifact ${str2(input?.title)}` : "Artifact";
@@ -6788,13 +6851,83 @@ function toolDescription(name, input) {
6788
6851
  }
6789
6852
  if (/grep/i.test(name)) return "Search files";
6790
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
+ }
6791
6865
  return n;
6792
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
+ }
6793
6880
  function isSubagentToolName(name) {
6794
6881
  const n = (name ?? "").trim();
6795
6882
  if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
6796
6883
  return /connectedAgentRequest/i.test(n);
6797
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
+ }
6798
6931
  function messagePartParentId(part) {
6799
6932
  if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
6800
6933
  return part.parentId;
@@ -6876,6 +7009,25 @@ function applyAgentEvent(parts, event) {
6876
7009
  const data = event.data;
6877
7010
  if (!data) return parts;
6878
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
+ }
6879
7031
  const last = next[next.length - 1];
6880
7032
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
6881
7033
  next[next.length - 1] = {
@@ -6899,14 +7051,18 @@ function applyAgentEvent(parts, event) {
6899
7051
  if (existing >= 0) {
6900
7052
  const prev = parts[existing];
6901
7053
  const next = [...parts];
6902
- 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;
6903
7059
  next[existing] = {
6904
7060
  ...prev,
6905
7061
  name: event.name || prev.name,
6906
- input: mergedInput,
6907
- description: toolDescription(event.name || prev.name, mergedInput),
6908
- detail: toolDetail(event.name || prev.name, mergedInput) ?? prev.detail,
6909
- 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,
6910
7066
  additions: diff.additions ?? prev.additions,
6911
7067
  deletions: diff.deletions ?? prev.deletions,
6912
7068
  parentId: event.parentId ?? prev.parentId
@@ -6932,6 +7088,30 @@ function applyAgentEvent(parts, event) {
6932
7088
  if (event.type === "tool_result") {
6933
7089
  const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
6934
7090
  const fromResult = parseDiffStat(event.content);
7091
+ if (event.partial) {
7092
+ if (existing < 0) {
7093
+ return [
7094
+ ...parts,
7095
+ {
7096
+ type: "tool",
7097
+ id: event.id,
7098
+ name: "tool",
7099
+ description: "tool",
7100
+ status: event.isError ? "error" : "running",
7101
+ result: event.content,
7102
+ ...event.parentId ? { parentId: event.parentId } : {}
7103
+ }
7104
+ ];
7105
+ }
7106
+ return parts.map((p, i) => {
7107
+ if (i !== existing || p.type !== "tool") return p;
7108
+ if (p.status === "done" || p.status === "error") return p;
7109
+ return {
7110
+ ...p,
7111
+ result: event.content ?? p.result
7112
+ };
7113
+ });
7114
+ }
6935
7115
  if (existing < 0) {
6936
7116
  return [
6937
7117
  ...parts,
@@ -7017,47 +7197,68 @@ function electronResourcesPath() {
7017
7197
  function packagedCursorRuntimeDir() {
7018
7198
  const resources = electronResourcesPath();
7019
7199
  if (!resources) return null;
7020
- const dir = (0, import_node_path19.join)(resources, "cursor-runtime");
7021
- if (!(0, import_node_fs18.existsSync)((0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
7200
+ const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
7201
+ if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
7022
7202
  return dir;
7023
7203
  }
7024
7204
  function packagedCursorRunnerPath() {
7025
7205
  const dir = packagedCursorRuntimeDir();
7026
- return dir ? (0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
7206
+ return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
7027
7207
  }
7028
7208
  function packagedMcpDir() {
7029
7209
  const resources = electronResourcesPath();
7030
7210
  if (!resources) return null;
7031
- const dir = (0, import_node_path19.join)(resources, "sideboard-mcp");
7032
- if (!(0, import_node_fs18.existsSync)((0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
7211
+ const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
7212
+ if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
7033
7213
  return dir;
7034
7214
  }
7035
7215
  function packagedMcpStdioPath() {
7036
7216
  const dir = packagedMcpDir();
7037
- return dir ? (0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
7217
+ return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
7038
7218
  }
7039
7219
  function packagedBundledNodePath() {
7040
7220
  const resources = electronResourcesPath();
7041
7221
  if (!resources) return null;
7042
- const bin = (0, import_node_path19.join)(resources, "node", "bin", "node");
7043
- if (!(0, import_node_fs18.existsSync)(bin)) return null;
7222
+ const bin = (0, import_node_path20.join)(resources, "node", "bin", "node");
7223
+ if (!(0, import_node_fs19.existsSync)(bin)) return null;
7044
7224
  return bin;
7045
7225
  }
7046
7226
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
7047
7227
  const dir = packagedCursorRuntimeDir();
7048
7228
  if (!dir) return null;
7049
- return (0, import_node_path19.join)(dir, "node_modules", platformPkg, "bin", binName);
7229
+ return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
7050
7230
  }
7051
- var import_node_fs18, import_node_path19;
7231
+ var import_node_fs19, import_node_path20;
7052
7232
  var init_packaged_runtime = __esm({
7053
7233
  "src/agents/packaged-runtime.ts"() {
7054
7234
  "use strict";
7055
- import_node_fs18 = require("fs");
7056
- import_node_path19 = require("path");
7235
+ import_node_fs19 = require("fs");
7236
+ import_node_path20 = require("path");
7057
7237
  }
7058
7238
  });
7059
7239
 
7060
7240
  // src/agents/node-launch.ts
7241
+ function withMaxOldSpaceSize(nodeOptions, heapMb) {
7242
+ const existing = (nodeOptions ?? "").trim();
7243
+ const match = MAX_OLD_SPACE_FLAG.exec(existing);
7244
+ if (match) {
7245
+ const current = match[2] ? Number(match[2]) : 0;
7246
+ if (Number.isFinite(current) && current >= heapMb) return existing;
7247
+ return existing.replace(MAX_OLD_SPACE_FLAG, ` --max-old-space-size=${heapMb}`).trim();
7248
+ }
7249
+ return existing ? `${existing} --max-old-space-size=${heapMb}` : `--max-old-space-size=${heapMb}`;
7250
+ }
7251
+ function applyAgentRunnerHeapEnv(env) {
7252
+ env.NODE_OPTIONS = withMaxOldSpaceSize(
7253
+ env.NODE_OPTIONS,
7254
+ AGENT_RUNNER_MAX_OLD_SPACE_MB
7255
+ );
7256
+ }
7257
+ function envWithAgentHeap(env) {
7258
+ const next = { ...env };
7259
+ applyAgentRunnerHeapEnv(next);
7260
+ return next;
7261
+ }
7061
7262
  function isAsarPath(filePath) {
7062
7263
  if (/\.asar\.unpacked([/\\]|$)/.test(filePath)) return false;
7063
7264
  return /\.asar([/\\]|$)/.test(filePath);
@@ -7066,7 +7267,7 @@ function unpackedAsarPath(filePath) {
7066
7267
  if (!isAsarPath(filePath)) return null;
7067
7268
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
7068
7269
  if (unpacked === filePath) return null;
7069
- return (0, import_node_fs19.existsSync)(unpacked) ? unpacked : null;
7270
+ return (0, import_node_fs20.existsSync)(unpacked) ? unpacked : null;
7070
7271
  }
7071
7272
  function nodeReadableScriptPath(scriptPath) {
7072
7273
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -7106,37 +7307,37 @@ function pickPreferredNode(candidates) {
7106
7307
  return best;
7107
7308
  }
7108
7309
  function versionDirNodeBins(root, toBin) {
7109
- if (!(0, import_node_fs19.existsSync)(root)) return [];
7310
+ if (!(0, import_node_fs20.existsSync)(root)) return [];
7110
7311
  try {
7111
- return (0, import_node_fs19.readdirSync)(root).map(toBin);
7312
+ return (0, import_node_fs20.readdirSync)(root).map(toBin);
7112
7313
  } catch {
7113
7314
  return [];
7114
7315
  }
7115
7316
  }
7116
7317
  function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
7117
7318
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
7118
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path20.join)(prefix, "opt", `node@${major}`, "bin", "node"))
7319
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path21.join)(prefix, "opt", `node@${major}`, "bin", "node"))
7119
7320
  );
7120
7321
  return [
7121
7322
  ...kegs,
7122
7323
  "/opt/homebrew/bin/node",
7123
7324
  "/usr/local/bin/node",
7124
- (0, import_node_path20.join)(home, ".local/share/fnm/aliases/default/bin/node"),
7125
- (0, import_node_path20.join)(home, ".nvm/current/bin/node"),
7126
- (0, import_node_path20.join)(home, ".volta/bin/node"),
7127
- (0, import_node_path20.join)(home, ".asdf/shims/node"),
7128
- (0, import_node_path20.join)(home, ".local/share/mise/shims/node"),
7325
+ (0, import_node_path21.join)(home, ".local/share/fnm/aliases/default/bin/node"),
7326
+ (0, import_node_path21.join)(home, ".nvm/current/bin/node"),
7327
+ (0, import_node_path21.join)(home, ".volta/bin/node"),
7328
+ (0, import_node_path21.join)(home, ".asdf/shims/node"),
7329
+ (0, import_node_path21.join)(home, ".local/share/mise/shims/node"),
7129
7330
  ...versionDirNodeBins(
7130
- (0, import_node_path20.join)(home, ".nvm", "versions", "node"),
7131
- (name) => (0, import_node_path20.join)(home, ".nvm", "versions", "node", name, "bin", "node")
7331
+ (0, import_node_path21.join)(home, ".nvm", "versions", "node"),
7332
+ (name) => (0, import_node_path21.join)(home, ".nvm", "versions", "node", name, "bin", "node")
7132
7333
  ),
7133
7334
  ...versionDirNodeBins(
7134
- (0, import_node_path20.join)(home, ".local/share/fnm", "node-versions"),
7135
- (name) => (0, import_node_path20.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
7335
+ (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions"),
7336
+ (name) => (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
7136
7337
  ),
7137
7338
  ...versionDirNodeBins(
7138
- (0, import_node_path20.join)(home, ".volta", "tools", "image", "node"),
7139
- (name) => (0, import_node_path20.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
7339
+ (0, import_node_path21.join)(home, ".volta", "tools", "image", "node"),
7340
+ (name) => (0, import_node_path21.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
7140
7341
  )
7141
7342
  ];
7142
7343
  }
@@ -7145,10 +7346,10 @@ function uniqueExistingNodeBins(paths) {
7145
7346
  const out = [];
7146
7347
  for (const raw of paths) {
7147
7348
  const p = raw.trim();
7148
- if (!p || !(0, import_node_fs19.existsSync)(p) || isElectronLikeCommand(p)) continue;
7349
+ if (!p || !(0, import_node_fs20.existsSync)(p) || isElectronLikeCommand(p)) continue;
7149
7350
  let key = p;
7150
7351
  try {
7151
- key = (0, import_node_fs19.realpathSync)(p);
7352
+ key = (0, import_node_fs20.realpathSync)(p);
7152
7353
  } catch {
7153
7354
  continue;
7154
7355
  }
@@ -7193,13 +7394,21 @@ async function findSystemNode() {
7193
7394
  function applyNodeLaunch(launch, args) {
7194
7395
  const readableArgs = args.map(nodeReadableScriptPath);
7195
7396
  if (!launch.env.ELECTRON_RUN_AS_NODE) {
7196
- return { file: launch.file, args: readableArgs, env: launch.env };
7397
+ return {
7398
+ file: launch.file,
7399
+ args: readableArgs,
7400
+ env: envWithAgentHeap(launch.env)
7401
+ };
7197
7402
  }
7198
7403
  const wrapped = wrapElectronAsNodeLaunch(launch.file, readableArgs);
7199
7404
  if (process.platform === "win32") {
7200
- return { file: wrapped.file, args: wrapped.args, env: launch.env };
7405
+ return {
7406
+ file: wrapped.file,
7407
+ args: wrapped.args,
7408
+ env: envWithAgentHeap(launch.env)
7409
+ };
7201
7410
  }
7202
- const env = { ...launch.env };
7411
+ const env = envWithAgentHeap(launch.env);
7203
7412
  delete env.ELECTRON_RUN_AS_NODE;
7204
7413
  return { file: wrapped.file, args: wrapped.args, env };
7205
7414
  }
@@ -7220,16 +7429,18 @@ async function resolveNodeLaunch(scriptPath) {
7220
7429
  env: { ELECTRON_RUN_AS_NODE: "1" }
7221
7430
  };
7222
7431
  }
7223
- var import_node_fs19, import_node_os7, import_node_path20, PREFERRED_LTS_MAJORS;
7432
+ var import_node_fs20, import_node_os7, import_node_path21, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
7224
7433
  var init_node_launch = __esm({
7225
7434
  "src/agents/node-launch.ts"() {
7226
7435
  "use strict";
7227
- import_node_fs19 = require("fs");
7436
+ import_node_fs20 = require("fs");
7228
7437
  import_node_os7 = require("os");
7229
- import_node_path20 = require("path");
7438
+ import_node_path21 = require("path");
7230
7439
  init_nested_electron_env();
7231
7440
  init_run();
7232
7441
  init_packaged_runtime();
7442
+ AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
7443
+ MAX_OLD_SPACE_FLAG = /(?:^|\s)(--max[-_]old[-_]space[-_]size)(?:[= ](\d+))?(?=\s|$)/;
7233
7444
  PREFERRED_LTS_MAJORS = [24, 22, 20];
7234
7445
  }
7235
7446
  });
@@ -7317,37 +7528,37 @@ function corePackageDir() {
7317
7528
  try {
7318
7529
  const url = import_meta.url;
7319
7530
  if (typeof url === "string" && url.length > 0) {
7320
- return (0, import_node_path21.dirname)((0, import_node_url.fileURLToPath)(url));
7531
+ return (0, import_node_path22.dirname)((0, import_node_url.fileURLToPath)(url));
7321
7532
  }
7322
7533
  } catch {
7323
7534
  }
7324
7535
  try {
7325
- const req = (0, import_node_module.createRequire)((0, import_node_path21.join)(process.cwd(), "package.json"));
7326
- return (0, import_node_path21.dirname)(req.resolve("@sideboard-ai/core"));
7536
+ const req = (0, import_node_module.createRequire)((0, import_node_path22.join)(process.cwd(), "package.json"));
7537
+ return (0, import_node_path22.dirname)(req.resolve("@sideboard-ai/core"));
7327
7538
  } catch {
7328
7539
  return process.cwd();
7329
7540
  }
7330
7541
  }
7331
7542
  function findSideboardMcpJsEntry() {
7332
7543
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
7333
- if (override && (0, import_node_fs20.existsSync)(override)) return override;
7544
+ if (override && (0, import_node_fs21.existsSync)(override)) return override;
7334
7545
  const packaged = packagedMcpStdioPath();
7335
7546
  if (packaged) return packaged;
7336
7547
  let dir = corePackageDir();
7337
7548
  for (let i = 0; i < 10; i++) {
7338
7549
  const candidates = [
7339
- (0, import_node_path21.join)(dir, "mcp/run-stdio.js"),
7340
- (0, import_node_path21.join)(dir, "mcp/run-stdio.cjs"),
7341
- (0, import_node_path21.join)(dir, "dist/mcp/run-stdio.js"),
7342
- (0, import_node_path21.join)(dir, "dist/mcp/run-stdio.cjs"),
7343
- (0, import_node_path21.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
7344
- (0, import_node_path21.join)(dir, "packages/cli/dist/index.js"),
7345
- (0, import_node_path21.join)(dir, "cli/dist/index.js")
7550
+ (0, import_node_path22.join)(dir, "mcp/run-stdio.js"),
7551
+ (0, import_node_path22.join)(dir, "mcp/run-stdio.cjs"),
7552
+ (0, import_node_path22.join)(dir, "dist/mcp/run-stdio.js"),
7553
+ (0, import_node_path22.join)(dir, "dist/mcp/run-stdio.cjs"),
7554
+ (0, import_node_path22.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
7555
+ (0, import_node_path22.join)(dir, "packages/cli/dist/index.js"),
7556
+ (0, import_node_path22.join)(dir, "cli/dist/index.js")
7346
7557
  ];
7347
7558
  for (const p of candidates) {
7348
- if ((0, import_node_fs20.existsSync)(p) && !isAsarPath(p)) return p;
7559
+ if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
7349
7560
  }
7350
- const parent = (0, import_node_path21.dirname)(dir);
7561
+ const parent = (0, import_node_path22.dirname)(dir);
7351
7562
  if (parent === dir) break;
7352
7563
  dir = parent;
7353
7564
  }
@@ -7395,6 +7606,7 @@ async function buildInjectedMcpServers(opts) {
7395
7606
  );
7396
7607
  } catch {
7397
7608
  }
7609
+ applyAgentRunnerHeapEnv(sideboard.env);
7398
7610
  servers.push(sideboard);
7399
7611
  }
7400
7612
  if (opts.includeBrightsy && isBrightsyConnected()) {
@@ -7488,19 +7700,19 @@ function writeMcpServersConfig(servers) {
7488
7700
  ...env ? { env } : {}
7489
7701
  };
7490
7702
  }
7491
- const dir = (0, import_node_fs20.mkdtempSync)((0, import_node_path21.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7492
- const cfgPath = (0, import_node_path21.join)(dir, "mcp.json");
7493
- (0, import_node_fs20.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7703
+ const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path22.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7704
+ const cfgPath = (0, import_node_path22.join)(dir, "mcp.json");
7705
+ (0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7494
7706
  return cfgPath;
7495
7707
  }
7496
- 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;
7708
+ 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;
7497
7709
  var init_injected_mcp = __esm({
7498
7710
  "src/agents/injected-mcp.ts"() {
7499
7711
  "use strict";
7500
- import_node_fs20 = require("fs");
7712
+ import_node_fs21 = require("fs");
7501
7713
  import_node_module = require("module");
7502
7714
  import_node_os8 = require("os");
7503
- import_node_path21 = require("path");
7715
+ import_node_path22 = require("path");
7504
7716
  import_node_url = require("url");
7505
7717
  init_run();
7506
7718
  init_config();
@@ -7674,6 +7886,80 @@ function claudeParentToolUseId(obj) {
7674
7886
  }
7675
7887
  return void 0;
7676
7888
  }
7889
+ function claudeString(obj, key) {
7890
+ const v = obj[key];
7891
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
7892
+ }
7893
+ function eventsFromClaudeSystem(obj) {
7894
+ const subtype = claudeString(obj, "subtype") ?? "";
7895
+ const parentId = claudeParentToolUseId(obj);
7896
+ if (subtype === "init") {
7897
+ if (parentId) return null;
7898
+ const sid = claudeString(obj, "session_id");
7899
+ return sid ? { type: "session_id", data: sid } : null;
7900
+ }
7901
+ if (subtype === "task_started") {
7902
+ const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
7903
+ if (!id) return null;
7904
+ const description = claudeString(obj, "description");
7905
+ const taskType = claudeString(obj, "task_type");
7906
+ const prompt = claudeString(obj, "prompt");
7907
+ return withEventParentId(
7908
+ {
7909
+ type: "tool_use",
7910
+ id,
7911
+ name: taskType || "Agent",
7912
+ input: {
7913
+ ...description ? { description } : {},
7914
+ ...prompt ? { prompt } : {},
7915
+ ...claudeString(obj, "task_id") ? { task_id: claudeString(obj, "task_id") } : {}
7916
+ }
7917
+ },
7918
+ parentId
7919
+ );
7920
+ }
7921
+ if (subtype === "task_notification") {
7922
+ const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id") ?? parentId;
7923
+ if (!id) return null;
7924
+ const status = claudeString(obj, "status") ?? "working";
7925
+ const tools = typeof obj.tool_uses === "number" ? obj.tool_uses : void 0;
7926
+ const durationMs = typeof obj.duration_ms === "number" ? obj.duration_ms : void 0;
7927
+ const lastTool = claudeString(obj, "last_tool") ?? claudeString(obj, "current_tool") ?? claudeString(obj, "tool");
7928
+ const snapshot = [
7929
+ status,
7930
+ tools != null ? `${tools} tools` : null,
7931
+ durationMs != null ? `${Math.round(durationMs / 1e3)}s` : null,
7932
+ lastTool
7933
+ ].filter((bit) => Boolean(bit)).join(" \xB7 ");
7934
+ return [
7935
+ {
7936
+ type: "tool_use",
7937
+ id,
7938
+ name: claudeString(obj, "task_type") || "Agent",
7939
+ input: {
7940
+ live_status: status,
7941
+ ...tools != null ? { live_tool_uses: tools } : {},
7942
+ ...durationMs != null ? { live_duration_ms: durationMs } : {},
7943
+ ...lastTool ? { live_last_tool: lastTool } : {}
7944
+ }
7945
+ },
7946
+ withEventParentId(
7947
+ { type: "thinking", data: snapshot, replace: true },
7948
+ id
7949
+ )
7950
+ ];
7951
+ }
7952
+ if (subtype === "api_retry") {
7953
+ const attempt = obj.attempt;
7954
+ const max = obj.max_retries;
7955
+ const delay = obj.retry_delay_ms;
7956
+ return {
7957
+ type: "thinking",
7958
+ data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay === "number" ? ` (wait ${delay}ms)` : ""}`
7959
+ };
7960
+ }
7961
+ return null;
7962
+ }
7677
7963
  function parseIssuesJson(raw) {
7678
7964
  const text4 = raw.trim();
7679
7965
  const candidates = [text4];
@@ -7699,11 +7985,11 @@ function parseIssuesJson(raw) {
7699
7985
  }
7700
7986
  return [];
7701
7987
  }
7702
- var import_node_fs21, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
7988
+ var import_node_fs22, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
7703
7989
  var init_claude = __esm({
7704
7990
  "src/agents/claude.ts"() {
7705
7991
  "use strict";
7706
- import_node_fs21 = require("fs");
7992
+ import_node_fs22 = require("fs");
7707
7993
  init_run();
7708
7994
  init_app_settings();
7709
7995
  init_claude_mcp();
@@ -7723,8 +8009,14 @@ var init_claude = __esm({
7723
8009
  "WebSearch",
7724
8010
  // Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
7725
8011
  "Task",
7726
- "Agent"
8012
+ "Agent",
8013
+ "TaskOutput",
8014
+ "TaskStop",
8015
+ "EnterWorktree",
8016
+ "ExitWorktree",
8017
+ "Skill"
7727
8018
  ];
8019
+ CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
7728
8020
  CLAUDE_CHROME_ALLOWED_TOOLS = [
7729
8021
  "mcp__claude-in-chrome",
7730
8022
  "mcp__claude-in-chrome__*",
@@ -7736,7 +8028,7 @@ var init_claude = __esm({
7736
8028
  async detect() {
7737
8029
  const claude = resolveClaudeExecutable();
7738
8030
  if (claude !== "claude") {
7739
- if (!(0, import_node_fs21.existsSync)(claude)) {
8031
+ if (!(0, import_node_fs22.existsSync)(claude)) {
7740
8032
  return {
7741
8033
  agent: "claude",
7742
8034
  installed: false,
@@ -7853,7 +8145,12 @@ var init_claude = __esm({
7853
8145
  stdin: useStdin ? `${promptText}
7854
8146
  ` : void 0,
7855
8147
  // Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
7856
- env: { CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1" }
8148
+ // Raise the -p background-agent wait so long TaskOutput polls are not
8149
+ // abandoned at Claude Code’s 10-minute default.
8150
+ env: {
8151
+ CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
8152
+ CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
8153
+ }
7857
8154
  };
7858
8155
  },
7859
8156
  parseEvent(line) {
@@ -7861,13 +8158,8 @@ var init_claude = __esm({
7861
8158
  if (!trimmed) return null;
7862
8159
  try {
7863
8160
  const obj = JSON.parse(trimmed);
7864
- if (obj.type === "system" && obj.subtype === "init") {
7865
- const sid = obj.session_id;
7866
- if (typeof sid === "string") return { type: "session_id", data: sid };
7867
- return null;
7868
- }
7869
- if (obj.type === "system" && typeof obj.session_id === "string") {
7870
- return { type: "session_id", data: obj.session_id };
8161
+ if (obj.type === "system") {
8162
+ return eventsFromClaudeSystem(obj);
7871
8163
  }
7872
8164
  if (obj.type === "assistant" || obj.type === "user") {
7873
8165
  const parentId = claudeParentToolUseId(obj);
@@ -7987,7 +8279,7 @@ async function listCodexModels() {
7987
8279
  if (codex === "codex") {
7988
8280
  const which = await run("which", ["codex"], { reject: false });
7989
8281
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
7990
- } else if (!(0, import_node_fs22.existsSync)(codex)) {
8282
+ } else if (!(0, import_node_fs23.existsSync)(codex)) {
7991
8283
  return FALLBACK_CODEX_MODELS;
7992
8284
  }
7993
8285
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -8022,12 +8314,12 @@ function usageFromCodex(usage) {
8022
8314
  }
8023
8315
  function codexConfigHasNetworkAccess() {
8024
8316
  const candidates = [
8025
- (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
8026
- (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
8317
+ (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
8318
+ (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
8027
8319
  ];
8028
8320
  for (const path of candidates) {
8029
- if (!(0, import_node_fs22.existsSync)(path)) continue;
8030
- const text4 = (0, import_node_fs22.readFileSync)(path, "utf8");
8321
+ if (!(0, import_node_fs23.existsSync)(path)) continue;
8322
+ const text4 = (0, import_node_fs23.readFileSync)(path, "utf8");
8031
8323
  if (/network_access\s*=\s*true/.test(text4)) return true;
8032
8324
  }
8033
8325
  return false;
@@ -8059,21 +8351,21 @@ function asRecord2(value) {
8059
8351
  return void 0;
8060
8352
  }
8061
8353
  function codexLooksAuthenticated() {
8062
- const authPath = (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
8063
- if (!(0, import_node_fs22.existsSync)(authPath)) return false;
8354
+ const authPath = (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
8355
+ if (!(0, import_node_fs23.existsSync)(authPath)) return false;
8064
8356
  try {
8065
- return (0, import_node_fs22.statSync)(authPath).size > 2;
8357
+ return (0, import_node_fs23.statSync)(authPath).size > 2;
8066
8358
  } catch {
8067
8359
  return false;
8068
8360
  }
8069
8361
  }
8070
- var import_node_fs22, import_node_os9, import_node_path22, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
8362
+ var import_node_fs23, import_node_os9, import_node_path23, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
8071
8363
  var init_codex = __esm({
8072
8364
  "src/agents/codex.ts"() {
8073
8365
  "use strict";
8074
- import_node_fs22 = require("fs");
8366
+ import_node_fs23 = require("fs");
8075
8367
  import_node_os9 = require("os");
8076
- import_node_path22 = require("path");
8368
+ import_node_path23 = require("path");
8077
8369
  init_run();
8078
8370
  init_app_settings();
8079
8371
  init_global_workspace();
@@ -8098,7 +8390,7 @@ var init_codex = __esm({
8098
8390
  async detect() {
8099
8391
  const codex = resolveAgentExecutable("codex");
8100
8392
  if (codex !== "codex") {
8101
- if (!(0, import_node_fs22.existsSync)(codex)) {
8393
+ if (!(0, import_node_fs23.existsSync)(codex)) {
8102
8394
  return {
8103
8395
  agent: "codex",
8104
8396
  installed: false,
@@ -8238,13 +8530,22 @@ var init_codex = __esm({
8238
8530
  const events = [
8239
8531
  { type: "tool_use", id: item.id, name: "Bash", input }
8240
8532
  ];
8241
- if (type === "item.completed" || item.status === "completed" || item.status === "failed") {
8533
+ const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
8534
+ const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
8535
+ if (finished) {
8242
8536
  events.push({
8243
8537
  type: "tool_result",
8244
8538
  id: item.id,
8245
- content: item.aggregated_output,
8539
+ content: output,
8246
8540
  isError: item.status === "failed"
8247
8541
  });
8542
+ } else if (output) {
8543
+ events.push({
8544
+ type: "tool_result",
8545
+ id: item.id,
8546
+ content: output,
8547
+ partial: true
8548
+ });
8248
8549
  }
8249
8550
  return events.length === 1 ? events[0] : events;
8250
8551
  }
@@ -8287,9 +8588,6 @@ var init_codex = __esm({
8287
8588
  if (sid && (type === "thread.started" || type === "session" || !type)) {
8288
8589
  return { type: "session_id", data: sid };
8289
8590
  }
8290
- if (sid && type.endsWith(".started")) {
8291
- return { type: "session_id", data: sid };
8292
- }
8293
8591
  if (type === "turn.completed" || type === "turn_completed") {
8294
8592
  const usage = usageFromCodex(obj.usage);
8295
8593
  return usage ? { type: "usage", data: usage, scope: "turn" } : null;
@@ -8463,7 +8761,7 @@ function cursorSdkMessageToEvents(msg) {
8463
8761
  if (msg.type === "tool_call" && msg.call_id && msg.name) {
8464
8762
  const normalized = normalizeCursorToolCall(msg.name, msg.args);
8465
8763
  if (msg.status === "running") {
8466
- return [
8764
+ const events = [
8467
8765
  {
8468
8766
  type: "tool_use",
8469
8767
  id: msg.call_id,
@@ -8471,6 +8769,16 @@ function cursorSdkMessageToEvents(msg) {
8471
8769
  input: normalized.input
8472
8770
  }
8473
8771
  ];
8772
+ const live = unwrapCursorToolResult(msg.result);
8773
+ if (live) {
8774
+ events.push({
8775
+ type: "tool_result",
8776
+ id: msg.call_id,
8777
+ content: live,
8778
+ partial: true
8779
+ });
8780
+ }
8781
+ return events;
8474
8782
  }
8475
8783
  if (msg.status === "completed" || msg.status === "error") {
8476
8784
  return [
@@ -8537,21 +8845,21 @@ function platformRipgrepPackage() {
8537
8845
  }
8538
8846
  function usableRipgrepPath(candidate) {
8539
8847
  const raw = candidate?.trim();
8540
- if (!raw || !(0, import_node_path23.isAbsolute)(raw)) return null;
8848
+ if (!raw || !(0, import_node_path24.isAbsolute)(raw)) return null;
8541
8849
  const readable = nodeReadableScriptPath(raw);
8542
- if (!(0, import_node_fs23.existsSync)(readable) || isAsarPath(readable)) return null;
8850
+ if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
8543
8851
  return readable;
8544
8852
  }
8545
8853
  function walkForBundledRipgrep(startFile) {
8546
8854
  if (!startFile) return null;
8547
8855
  const pkg = platformRipgrepPackage();
8548
8856
  const name = rgBinaryName();
8549
- let dir = (0, import_node_path23.dirname)((0, import_node_path23.resolve)(startFile));
8550
- const root = (0, import_node_path23.parse)(dir).root;
8857
+ let dir = (0, import_node_path24.dirname)((0, import_node_path24.resolve)(startFile));
8858
+ const root = (0, import_node_path24.parse)(dir).root;
8551
8859
  while (dir !== root) {
8552
- const hit = usableRipgrepPath((0, import_node_path23.join)(dir, "node_modules", pkg, "bin", name));
8860
+ const hit = usableRipgrepPath((0, import_node_path24.join)(dir, "node_modules", pkg, "bin", name));
8553
8861
  if (hit) return hit;
8554
- const next = (0, import_node_path23.dirname)(dir);
8862
+ const next = (0, import_node_path24.dirname)(dir);
8555
8863
  if (next === dir) break;
8556
8864
  dir = next;
8557
8865
  }
@@ -8561,7 +8869,7 @@ function requireResolveBundledRipgrep(fromFile) {
8561
8869
  try {
8562
8870
  const req = (0, import_node_module2.createRequire)(fromFile);
8563
8871
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
8564
- return usableRipgrepPath((0, import_node_path23.join)((0, import_node_path23.dirname)(pkgJson), "bin", rgBinaryName()));
8872
+ return usableRipgrepPath((0, import_node_path24.join)((0, import_node_path24.dirname)(pkgJson), "bin", rgBinaryName()));
8565
8873
  } catch {
8566
8874
  return null;
8567
8875
  }
@@ -8583,13 +8891,13 @@ function cursorRipgrepEnv(opts) {
8583
8891
  const path = resolveCursorRipgrepPath(opts);
8584
8892
  return path ? { [RIPGREP_ENV]: path } : {};
8585
8893
  }
8586
- var import_node_fs23, import_node_module2, import_node_path23, RIPGREP_ENV;
8894
+ var import_node_fs24, import_node_module2, import_node_path24, RIPGREP_ENV;
8587
8895
  var init_cursor_ripgrep = __esm({
8588
8896
  "src/agents/cursor-ripgrep.ts"() {
8589
8897
  "use strict";
8590
- import_node_fs23 = require("fs");
8898
+ import_node_fs24 = require("fs");
8591
8899
  import_node_module2 = require("module");
8592
- import_node_path23 = require("path");
8900
+ import_node_path24 = require("path");
8593
8901
  init_node_launch();
8594
8902
  init_packaged_runtime();
8595
8903
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -8635,11 +8943,11 @@ function entryDir() {
8635
8943
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
8636
8944
  if (cjsDir) return cjsDir;
8637
8945
  try {
8638
- return (0, import_node_path24.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
8946
+ return (0, import_node_path25.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
8639
8947
  } catch {
8640
8948
  try {
8641
8949
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
8642
- return (0, import_node_path24.dirname)(req.resolve("@sideboard-ai/core"));
8950
+ return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
8643
8951
  } catch {
8644
8952
  return process.cwd();
8645
8953
  }
@@ -8650,27 +8958,27 @@ function cursorRunnerPath() {
8650
8958
  if (packaged) return packaged;
8651
8959
  const root = entryDir();
8652
8960
  const candidates = [
8653
- (0, import_node_path24.join)(root, "agents", "cursor-runner.js"),
8654
- (0, import_node_path24.join)(root, "agents", "cursor-runner.cjs"),
8961
+ (0, import_node_path25.join)(root, "agents", "cursor-runner.js"),
8962
+ (0, import_node_path25.join)(root, "agents", "cursor-runner.cjs"),
8655
8963
  // If somehow resolved from package root instead of dist/
8656
- (0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.js"),
8657
- (0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.cjs"),
8964
+ (0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.js"),
8965
+ (0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.cjs"),
8658
8966
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
8659
- (0, import_node_path24.join)(root, "cursor-runner.ts"),
8660
- (0, import_node_path24.join)(root, "src", "agents", "cursor-runner.ts")
8967
+ (0, import_node_path25.join)(root, "cursor-runner.ts"),
8968
+ (0, import_node_path25.join)(root, "src", "agents", "cursor-runner.ts")
8661
8969
  ];
8662
8970
  for (const candidate of candidates) {
8663
- if ((0, import_node_fs24.existsSync)(candidate)) return candidate;
8971
+ if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
8664
8972
  }
8665
8973
  return candidates[0];
8666
8974
  }
8667
- var import_node_fs24, import_node_module3, import_node_path24, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8975
+ 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;
8668
8976
  var init_cursor = __esm({
8669
8977
  "src/agents/cursor.ts"() {
8670
8978
  "use strict";
8671
- import_node_fs24 = require("fs");
8979
+ import_node_fs25 = require("fs");
8672
8980
  import_node_module3 = require("module");
8673
- import_node_path24 = require("path");
8981
+ import_node_path25 = require("path");
8674
8982
  import_node_url2 = require("url");
8675
8983
  import_sdk = require("@cursor/sdk");
8676
8984
  init_run();
@@ -8820,7 +9128,7 @@ async function listOpencodeModels() {
8820
9128
  if (opencode === "opencode") {
8821
9129
  const which = await run("which", ["opencode"], { reject: false });
8822
9130
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
8823
- } else if (!(0, import_node_fs25.existsSync)(opencode)) {
9131
+ } else if (!(0, import_node_fs26.existsSync)(opencode)) {
8824
9132
  return FALLBACK_OPENCODE_MODELS;
8825
9133
  }
8826
9134
  const listed = await run(opencode, ["models"], { reject: false });
@@ -8850,11 +9158,11 @@ function usageFromOpencode(tokens) {
8850
9158
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
8851
9159
  };
8852
9160
  }
8853
- var import_node_fs25, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
9161
+ var import_node_fs26, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
8854
9162
  var init_opencode = __esm({
8855
9163
  "src/agents/opencode.ts"() {
8856
9164
  "use strict";
8857
- import_node_fs25 = require("fs");
9165
+ import_node_fs26 = require("fs");
8858
9166
  init_run();
8859
9167
  init_app_settings();
8860
9168
  init_global_workspace();
@@ -8881,7 +9189,7 @@ var init_opencode = __esm({
8881
9189
  async detect() {
8882
9190
  const opencode = resolveAgentExecutable("opencode");
8883
9191
  if (opencode !== "opencode") {
8884
- if (!(0, import_node_fs25.existsSync)(opencode)) {
9192
+ if (!(0, import_node_fs26.existsSync)(opencode)) {
8885
9193
  return {
8886
9194
  agent: "opencode",
8887
9195
  installed: false,
@@ -8967,7 +9275,8 @@ var init_opencode = __esm({
8967
9275
  return { type: "stderr", data: detail };
8968
9276
  }
8969
9277
  const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
8970
- if (sid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
9278
+ const childSid = str3(obj.childSessionID) ?? str3(obj.childSessionId) ?? str3(obj.parentID) ?? str3(obj.parentId);
9279
+ if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
8971
9280
  return { type: "session_id", data: sid };
8972
9281
  }
8973
9282
  if (obj.type === "text") {
@@ -8987,13 +9296,16 @@ var init_opencode = __esm({
8987
9296
  );
8988
9297
  const events = [{ type: "tool_use", id, name, input }];
8989
9298
  const output = state?.output;
8990
- if (output != null || state?.status === "completed" || state?.status === "error") {
9299
+ const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
9300
+ const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
9301
+ if (output != null || finished) {
8991
9302
  const content = typeof output === "string" ? output : output != null ? JSON.stringify(output) : formatUnknownDetail(state?.error) || void 0;
8992
9303
  events.push({
8993
9304
  type: "tool_result",
8994
9305
  id,
8995
9306
  content,
8996
- isError: state?.status === "error" || state?.status === "failed"
9307
+ isError: state?.status === "error" || state?.status === "failed",
9308
+ ...running && !finished ? { partial: true } : {}
8997
9309
  });
8998
9310
  }
8999
9311
  return events.length === 1 ? events[0] : events;
@@ -9028,14 +9340,17 @@ var init_opencode = __esm({
9028
9340
  withEventParentId({ type: "tool_use", id, name, input }, parentId)
9029
9341
  ];
9030
9342
  const output = state?.output ?? part.output;
9031
- if (output != null || state?.status === "completed" || state?.status === "error") {
9343
+ const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
9344
+ const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
9345
+ if (output != null || finished) {
9032
9346
  nested.push(
9033
9347
  withEventParentId(
9034
9348
  {
9035
9349
  type: "tool_result",
9036
9350
  id,
9037
9351
  content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
9038
- isError: state?.status === "error" || state?.status === "failed"
9352
+ isError: state?.status === "error" || state?.status === "failed",
9353
+ ...running && !finished ? { partial: true } : {}
9039
9354
  },
9040
9355
  parentId
9041
9356
  )
@@ -9698,6 +10013,11 @@ function createAgentStreamCoalescer(emit, opts) {
9698
10013
  return;
9699
10014
  }
9700
10015
  if (!event.data) return;
10016
+ if (event.type === "thinking" && event.replace) {
10017
+ flush2();
10018
+ emit(event);
10019
+ return;
10020
+ }
9701
10021
  if (pending && pending.type === event.type && parentKey(pending) === parentKey(event)) {
9702
10022
  pending.data += event.data;
9703
10023
  } else {
@@ -9754,6 +10074,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
9754
10074
  }
9755
10075
  const env = childEnvWithAppSettings(cmd.env);
9756
10076
  applyPromptCacheTtlEnv(thread.agent, env);
10077
+ applyAgentRunnerHeapEnv(env);
9757
10078
  try {
9758
10079
  if (isOrchestratorThread(thread)) {
9759
10080
  mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
@@ -9861,9 +10182,11 @@ var init_spawn = __esm({
9861
10182
  init_agents();
9862
10183
  init_orchestrator_capable();
9863
10184
  init_message_parts();
10185
+ init_node_launch();
9864
10186
  init_path();
9865
10187
  init_usage();
9866
10188
  init_cursor_stream_coalesce();
10189
+ init_node_launch();
9867
10190
  }
9868
10191
  });
9869
10192
 
@@ -10589,21 +10912,21 @@ function shouldRefreshReviewRequestTemplate(content) {
10589
10912
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
10590
10913
  }
10591
10914
  function readTextIfPresent(abs) {
10592
- if (!(0, import_node_fs26.existsSync)(abs)) return null;
10915
+ if (!(0, import_node_fs27.existsSync)(abs)) return null;
10593
10916
  try {
10594
- const content = (0, import_node_fs26.readFileSync)(abs, "utf8");
10917
+ const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
10595
10918
  return content.trim() ? content : null;
10596
10919
  } catch {
10597
10920
  return null;
10598
10921
  }
10599
10922
  }
10600
10923
  function readLocalGuidelines(worktreePath) {
10601
- const localAbs = (0, import_node_path25.join)(worktreePath, REVIEW_REQUEST_PATH);
10924
+ const localAbs = (0, import_node_path26.join)(worktreePath, REVIEW_REQUEST_PATH);
10602
10925
  const localContent = readTextIfPresent(localAbs);
10603
10926
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
10604
10927
  return { path: REVIEW_REQUEST_PATH, content: localContent };
10605
10928
  }
10606
- const legacyAbs = (0, import_node_path25.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10929
+ const legacyAbs = (0, import_node_path26.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10607
10930
  const legacyContent = readTextIfPresent(legacyAbs);
10608
10931
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
10609
10932
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -10619,20 +10942,20 @@ function skillGuidelines(content, source) {
10619
10942
  };
10620
10943
  }
10621
10944
  function ensureReviewSkillFile(worktreePath) {
10622
- const abs = (0, import_node_path25.join)(worktreePath, REVIEW_SKILL_PATH);
10945
+ const abs = (0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH);
10623
10946
  const existing = readTextIfPresent(abs);
10624
10947
  if (existing) {
10625
10948
  return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
10626
10949
  }
10627
- const fromRepo = readTextIfPresent((0, import_node_path25.join)(worktreePath, REPO_REVIEW_PATH));
10950
+ const fromRepo = readTextIfPresent((0, import_node_path26.join)(worktreePath, REPO_REVIEW_PATH));
10628
10951
  const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
10629
10952
  const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
10630
- (0, import_node_fs26.mkdirSync)((0, import_node_path25.dirname)(abs), { recursive: true });
10631
- (0, import_node_fs26.writeFileSync)(abs, content, "utf8");
10953
+ (0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
10954
+ (0, import_node_fs27.writeFileSync)(abs, content, "utf8");
10632
10955
  return { path: REVIEW_SKILL_PATH, content, wrote: true };
10633
10956
  }
10634
10957
  function resolveReviewGuidelines(worktreePath) {
10635
- const skillContent = readTextIfPresent((0, import_node_path25.join)(worktreePath, REVIEW_SKILL_PATH));
10958
+ const skillContent = readTextIfPresent((0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH));
10636
10959
  if (skillContent) return skillGuidelines(skillContent, "skill");
10637
10960
  const local = readLocalGuidelines(worktreePath);
10638
10961
  if (local) {
@@ -10682,13 +11005,13 @@ async function requestReview(threadRef, send) {
10682
11005
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
10683
11006
  return { tab: started, from };
10684
11007
  }
10685
- 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;
11008
+ 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;
10686
11009
  var init_request_review = __esm({
10687
11010
  "src/review/request-review.ts"() {
10688
11011
  "use strict";
10689
11012
  import_node_crypto5 = require("crypto");
10690
- import_node_fs26 = require("fs");
10691
- import_node_path25 = require("path");
11013
+ import_node_fs27 = require("fs");
11014
+ import_node_path26 = require("path");
10692
11015
  init_global_workspace();
10693
11016
  init_chat_tabs();
10694
11017
  init_thread_store();
@@ -10713,9 +11036,9 @@ function matchSimpleGlob(pattern, name) {
10713
11036
  return new RegExp(`^${escaped}$`).test(name);
10714
11037
  }
10715
11038
  function readWorktreeInclude(repoPath) {
10716
- const path = (0, import_node_path26.join)(repoPath, ".worktreeinclude");
10717
- if (!(0, import_node_fs27.existsSync)(path)) return [];
10718
- return (0, import_node_fs27.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
11039
+ const path = (0, import_node_path27.join)(repoPath, ".worktreeinclude");
11040
+ if (!(0, import_node_fs28.existsSync)(path)) return [];
11041
+ return (0, import_node_fs28.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
10719
11042
  }
10720
11043
  function resolveFilesToCopy(repoPath) {
10721
11044
  const fromInclude = readWorktreeInclude(repoPath);
@@ -10725,10 +11048,10 @@ function resolveFilesToCopy(repoPath) {
10725
11048
  if (settings?.fileIncludeGlobs?.length) {
10726
11049
  const matched = [];
10727
11050
  try {
10728
- for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
11051
+ for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
10729
11052
  if (!entry.isFile()) continue;
10730
11053
  for (const glob of settings.fileIncludeGlobs) {
10731
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path26.basename)(glob), entry.name)) {
11054
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path27.basename)(glob), entry.name)) {
10732
11055
  matched.push(entry.name);
10733
11056
  break;
10734
11057
  }
@@ -10740,7 +11063,7 @@ function resolveFilesToCopy(repoPath) {
10740
11063
  }
10741
11064
  const defaults = [];
10742
11065
  try {
10743
- for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
11066
+ for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
10744
11067
  if (entry.isFile() && entry.name.startsWith(".env")) {
10745
11068
  defaults.push(entry.name);
10746
11069
  }
@@ -10754,11 +11077,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
10754
11077
  const patterns = resolveFilesToCopy(repoPath);
10755
11078
  const copied = [];
10756
11079
  for (const rel of patterns) {
10757
- const src = (0, import_node_path26.join)(repoPath, rel);
10758
- if (!(0, import_node_fs27.existsSync)(src)) continue;
10759
- const dest = (0, import_node_path26.join)(worktreePath, rel);
10760
- (0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(dest), { recursive: true });
10761
- (0, import_node_fs27.copyFileSync)(src, dest);
11080
+ const src = (0, import_node_path27.join)(repoPath, rel);
11081
+ if (!(0, import_node_fs28.existsSync)(src)) continue;
11082
+ const dest = (0, import_node_path27.join)(worktreePath, rel);
11083
+ (0, import_node_fs28.mkdirSync)((0, import_node_path27.dirname)(dest), { recursive: true });
11084
+ (0, import_node_fs28.copyFileSync)(src, dest);
10762
11085
  copied.push(rel);
10763
11086
  }
10764
11087
  return copied;
@@ -10793,7 +11116,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
10793
11116
  const env = stripNestedElectronEnv({
10794
11117
  ...baseEnv ?? process.env
10795
11118
  });
10796
- const name = opts.workspaceName ?? (0, import_node_path26.basename)(opts.worktreePath);
11119
+ const name = opts.workspaceName ?? (0, import_node_path27.basename)(opts.worktreePath);
10797
11120
  const ports = opts.ports ?? [];
10798
11121
  const primary = ports[0];
10799
11122
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -11054,13 +11377,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
11054
11377
  done: handle.done
11055
11378
  };
11056
11379
  }
11057
- var import_node_fs27, import_node_net, import_node_path26, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
11380
+ var import_node_fs28, import_node_net, import_node_path27, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
11058
11381
  var init_conductor = __esm({
11059
11382
  "src/hook/conductor.ts"() {
11060
11383
  "use strict";
11061
- import_node_fs27 = require("fs");
11384
+ import_node_fs28 = require("fs");
11062
11385
  import_node_net = require("net");
11063
- import_node_path26 = require("path");
11386
+ import_node_path27 = require("path");
11064
11387
  import_execa4 = require("execa");
11065
11388
  import_node_readline3 = require("readline");
11066
11389
  init_settings();
@@ -11086,9 +11409,9 @@ async function findOrphanWorktrees(repoPaths) {
11086
11409
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
11087
11410
  );
11088
11411
  const homeRoot = sideboardWorkspacesDir();
11089
- if ((0, import_node_fs28.existsSync)(homeRoot)) {
11412
+ if ((0, import_node_fs29.existsSync)(homeRoot)) {
11090
11413
  try {
11091
- for (const entry of (0, import_node_fs28.readdirSync)(homeRoot, { withFileTypes: true })) {
11414
+ for (const entry of (0, import_node_fs29.readdirSync)(homeRoot, { withFileTypes: true })) {
11092
11415
  if (!entry.isDirectory()) continue;
11093
11416
  void entry;
11094
11417
  }
@@ -11098,7 +11421,7 @@ async function findOrphanWorktrees(repoPaths) {
11098
11421
  const orphans = [];
11099
11422
  const seen = /* @__PURE__ */ new Set();
11100
11423
  for (const repoPath of repos) {
11101
- if (!repoPath || !(0, import_node_fs28.existsSync)(repoPath)) continue;
11424
+ if (!repoPath || !(0, import_node_fs29.existsSync)(repoPath)) continue;
11102
11425
  try {
11103
11426
  const wts = await listWorktrees(repoPath);
11104
11427
  for (const wt of wts) {
@@ -11109,7 +11432,7 @@ async function findOrphanWorktrees(repoPaths) {
11109
11432
  seen.add(path);
11110
11433
  let mtimeMs = 0;
11111
11434
  try {
11112
- mtimeMs = (0, import_node_fs28.statSync)(path).mtimeMs;
11435
+ mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
11113
11436
  } catch {
11114
11437
  mtimeMs = 0;
11115
11438
  }
@@ -11119,16 +11442,16 @@ async function findOrphanWorktrees(repoPaths) {
11119
11442
  }
11120
11443
  try {
11121
11444
  const root = worktreesRoot(repoPath);
11122
- if ((0, import_node_fs28.existsSync)(root)) {
11123
- for (const entry of (0, import_node_fs28.readdirSync)(root, { withFileTypes: true })) {
11445
+ if ((0, import_node_fs29.existsSync)(root)) {
11446
+ for (const entry of (0, import_node_fs29.readdirSync)(root, { withFileTypes: true })) {
11124
11447
  if (!entry.isDirectory()) continue;
11125
- const path = (0, import_node_path27.join)(root, entry.name).replace(/\/$/, "");
11448
+ const path = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
11126
11449
  if (known.has(path) || seen.has(path)) continue;
11127
- if (!(0, import_node_fs28.existsSync)((0, import_node_path27.join)(path, ".git"))) continue;
11450
+ if (!(0, import_node_fs29.existsSync)((0, import_node_path28.join)(path, ".git"))) continue;
11128
11451
  seen.add(path);
11129
11452
  let mtimeMs = 0;
11130
11453
  try {
11131
- mtimeMs = (0, import_node_fs28.statSync)(path).mtimeMs;
11454
+ mtimeMs = (0, import_node_fs29.statSync)(path).mtimeMs;
11132
11455
  } catch {
11133
11456
  mtimeMs = Date.now();
11134
11457
  }
@@ -11180,12 +11503,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
11180
11503
  const elapsed = Date.now() - Date.parse(last);
11181
11504
  return elapsed >= intervalHours * 36e5;
11182
11505
  }
11183
- var import_node_fs28, import_node_path27;
11506
+ var import_node_fs29, import_node_path28;
11184
11507
  var init_orphan_cleanup = __esm({
11185
11508
  "src/git/orphan-cleanup.ts"() {
11186
11509
  "use strict";
11187
- import_node_fs28 = require("fs");
11188
- import_node_path27 = require("path");
11510
+ import_node_fs29 = require("fs");
11511
+ import_node_path28 = require("path");
11189
11512
  init_worktree();
11190
11513
  init_thread_store();
11191
11514
  init_paths();
@@ -11292,38 +11615,38 @@ __export(workspaces_exports, {
11292
11615
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
11293
11616
  });
11294
11617
  function workspacesFile() {
11295
- return (0, import_node_path28.join)(appDataDir(), "workspaces.json");
11618
+ return (0, import_node_path29.join)(appDataDir(), "workspaces.json");
11296
11619
  }
11297
11620
  function removedWorkspacesFile() {
11298
- return (0, import_node_path28.join)(appDataDir(), "removed-workspaces.json");
11621
+ return (0, import_node_path29.join)(appDataDir(), "removed-workspaces.json");
11299
11622
  }
11300
11623
  function readAll() {
11301
11624
  const path = workspacesFile();
11302
- if (!(0, import_node_fs29.existsSync)(path)) return [];
11625
+ if (!(0, import_node_fs30.existsSync)(path)) return [];
11303
11626
  try {
11304
- const raw = JSON.parse((0, import_node_fs29.readFileSync)(path, "utf8"));
11627
+ const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
11305
11628
  return Array.isArray(raw) ? raw : [];
11306
11629
  } catch {
11307
11630
  return [];
11308
11631
  }
11309
11632
  }
11310
11633
  function writeAll(list) {
11311
- (0, import_node_fs29.mkdirSync)(appDataDir(), { recursive: true });
11312
- (0, import_node_fs29.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
11634
+ (0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
11635
+ (0, import_node_fs30.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
11313
11636
  }
11314
11637
  function readRemoved() {
11315
11638
  const path = removedWorkspacesFile();
11316
- if (!(0, import_node_fs29.existsSync)(path)) return /* @__PURE__ */ new Set();
11639
+ if (!(0, import_node_fs30.existsSync)(path)) return /* @__PURE__ */ new Set();
11317
11640
  try {
11318
- const raw = JSON.parse((0, import_node_fs29.readFileSync)(path, "utf8"));
11641
+ const raw = JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
11319
11642
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
11320
11643
  } catch {
11321
11644
  return /* @__PURE__ */ new Set();
11322
11645
  }
11323
11646
  }
11324
11647
  function writeRemoved(paths) {
11325
- (0, import_node_fs29.mkdirSync)(appDataDir(), { recursive: true });
11326
- (0, import_node_fs29.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
11648
+ (0, import_node_fs30.mkdirSync)(appDataDir(), { recursive: true });
11649
+ (0, import_node_fs30.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
11327
11650
  }
11328
11651
  function rememberRemoved(repoPath) {
11329
11652
  const next = readRemoved();
@@ -11346,7 +11669,7 @@ function listWorkspaces() {
11346
11669
  async function addWorkspace(repoPath) {
11347
11670
  const root = await resolveRepoRoot(repoPath);
11348
11671
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
11349
- if (!(0, import_node_fs29.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
11672
+ if (!(0, import_node_fs30.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
11350
11673
  forgetRemoved(root);
11351
11674
  await ensureGhPreferOrigin(root);
11352
11675
  const current = readAll();
@@ -11354,7 +11677,7 @@ async function addWorkspace(repoPath) {
11354
11677
  if (existing) return existing;
11355
11678
  const next = {
11356
11679
  path: root,
11357
- name: (0, import_node_path28.basename)(root),
11680
+ name: (0, import_node_path29.basename)(root),
11358
11681
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
11359
11682
  };
11360
11683
  writeAll([...current, next]);
@@ -11376,10 +11699,10 @@ function syncWorkspacesFromThreads(repoPaths) {
11376
11699
  if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
11377
11700
  continue;
11378
11701
  }
11379
- if (!(0, import_node_fs29.existsSync)(path)) continue;
11702
+ if (!(0, import_node_fs30.existsSync)(path)) continue;
11380
11703
  const ws = {
11381
11704
  path,
11382
- name: (0, import_node_path28.basename)(path),
11705
+ name: (0, import_node_path29.basename)(path),
11383
11706
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
11384
11707
  };
11385
11708
  byPath.set(path, ws);
@@ -11389,12 +11712,12 @@ function syncWorkspacesFromThreads(repoPaths) {
11389
11712
  if (dirty) writeAll(next);
11390
11713
  return next.sort((a, b) => a.name.localeCompare(b.name));
11391
11714
  }
11392
- var import_node_fs29, import_node_path28;
11715
+ var import_node_fs30, import_node_path29;
11393
11716
  var init_workspaces2 = __esm({
11394
11717
  "src/store/workspaces.ts"() {
11395
11718
  "use strict";
11396
- import_node_fs29 = require("fs");
11397
- import_node_path28 = require("path");
11719
+ import_node_fs30 = require("fs");
11720
+ import_node_path29 = require("path");
11398
11721
  init_paths();
11399
11722
  init_global_workspace();
11400
11723
  init_worktree();
@@ -11407,12 +11730,12 @@ async function cloneRepoIntoSideboard(opts) {
11407
11730
  if (!url) throw new Error("Clone URL is required");
11408
11731
  let name = opts.name?.trim();
11409
11732
  if (!name) {
11410
- const leaf = (0, import_node_path29.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
11733
+ const leaf = (0, import_node_path30.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
11411
11734
  name = leaf || "repo";
11412
11735
  }
11413
11736
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
11414
- const dest = (0, import_node_path29.join)(sideboardReposDir(), name);
11415
- if ((0, import_node_fs30.existsSync)(dest)) {
11737
+ const dest = (0, import_node_path30.join)(sideboardReposDir(), name);
11738
+ if ((0, import_node_fs31.existsSync)(dest)) {
11416
11739
  const repoPath2 = await resolveRepoRoot(dest);
11417
11740
  const workspace2 = await ensureWorkspace(repoPath2);
11418
11741
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -11427,12 +11750,12 @@ async function cloneRepoIntoSideboard(opts) {
11427
11750
  const workspace = await ensureWorkspace(repoPath);
11428
11751
  return { repoPath, workspace };
11429
11752
  }
11430
- var import_node_fs30, import_node_path29, import_execa6;
11753
+ var import_node_fs31, import_node_path30, import_execa6;
11431
11754
  var init_clone_repo = __esm({
11432
11755
  "src/git/clone-repo.ts"() {
11433
11756
  "use strict";
11434
- import_node_fs30 = require("fs");
11435
- import_node_path29 = require("path");
11757
+ import_node_fs31 = require("fs");
11758
+ import_node_path30 = require("path");
11436
11759
  import_execa6 = require("execa");
11437
11760
  init_paths();
11438
11761
  init_workspaces2();
@@ -11442,11 +11765,11 @@ var init_clone_repo = __esm({
11442
11765
 
11443
11766
  // src/store/desktop-host.ts
11444
11767
  function desktopHostPidPath() {
11445
- return (0, import_node_path30.join)(appDataDir(), "desktop-host.pid");
11768
+ return (0, import_node_path31.join)(appDataDir(), "desktop-host.pid");
11446
11769
  }
11447
11770
  function readDesktopHostPid() {
11448
11771
  try {
11449
- const pid = Number.parseInt((0, import_node_fs31.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
11772
+ const pid = Number.parseInt((0, import_node_fs32.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
11450
11773
  if (!Number.isFinite(pid) || pid <= 0) return null;
11451
11774
  return pid;
11452
11775
  } catch {
@@ -11472,12 +11795,12 @@ function thisProcessShouldDrainAgentQueues() {
11472
11795
  if (isThisProcessDesktopHost()) return true;
11473
11796
  return !isDesktopHostAlive();
11474
11797
  }
11475
- var import_node_fs31, import_node_path30;
11798
+ var import_node_fs32, import_node_path31;
11476
11799
  var init_desktop_host = __esm({
11477
11800
  "src/store/desktop-host.ts"() {
11478
11801
  "use strict";
11479
- import_node_fs31 = require("fs");
11480
- import_node_path30 = require("path");
11802
+ import_node_fs32 = require("fs");
11803
+ import_node_path31 = require("path");
11481
11804
  init_paths();
11482
11805
  }
11483
11806
  });
@@ -11527,7 +11850,7 @@ async function createThread(input, _onSetupLine) {
11527
11850
  });
11528
11851
  await requireAgent(resolved.agent);
11529
11852
  const repoPath = await resolveRepoRoot(input.repoPath);
11530
- if (!(0, import_node_fs32.existsSync)(repoPath)) {
11853
+ if (!(0, import_node_fs33.existsSync)(repoPath)) {
11531
11854
  throw new Error(`Repo not found: ${repoPath}`);
11532
11855
  }
11533
11856
  if (input.cowboy) {
@@ -11650,11 +11973,11 @@ async function listLinearIssues(agent, repoPath) {
11650
11973
  }
11651
11974
  return adapter.listLinearIssues(repoPath);
11652
11975
  }
11653
- var import_node_fs32;
11976
+ var import_node_fs33;
11654
11977
  var init_create = __esm({
11655
11978
  "src/threads/create.ts"() {
11656
11979
  "use strict";
11657
- import_node_fs32 = require("fs");
11980
+ import_node_fs33 = require("fs");
11658
11981
  init_detect();
11659
11982
  init_worktree();
11660
11983
  init_conductor();
@@ -11699,21 +12022,13 @@ function summarizeTurnLive(parts) {
11699
12022
  (p) => p.type === "tool"
11700
12023
  );
11701
12024
  const lastTool = tools[tools.length - 1];
11702
- const lastToolLabel = lastTool ? lastTool.description || toolDescription(lastTool.name, lastTool.input) || lastTool.name : void 0;
11703
- const running = lastTool?.status === "running";
12025
+ const interesting = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? lastTool;
12026
+ const lastToolLabel = interesting ? interesting.description || toolDescription(interesting.name, interesting.input) || interesting.name : void 0;
11704
12027
  const thinking = lastText(parts, "thinking");
11705
12028
  const text4 = lastText(parts, "text");
11706
12029
  const excerptRaw = thinking || text4;
11707
12030
  const excerpt = excerptRaw.length > 280 ? `${excerptRaw.slice(-280)}` : excerptRaw || void 0;
11708
- let summary = "Working\u2026";
11709
- if (lastToolLabel) {
11710
- const verb = running ? lastToolLabel : `Finished ${lastToolLabel}`;
11711
- summary = tools.length > 1 ? `${verb} (${tools.length} tools)` : verb;
11712
- } else if (thinking) {
11713
- summary = "Thinking\u2026";
11714
- } else if (text4) {
11715
- summary = "Writing reply\u2026";
11716
- }
12031
+ const summary = liveActivitySummary(parts);
11717
12032
  return {
11718
12033
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11719
12034
  summary,
@@ -11763,20 +12078,20 @@ function writeTurnLive(threadId, progress) {
11763
12078
  const path = threadLivePath(threadId);
11764
12079
  const tmp = `${path}.${process.pid}.tmp`;
11765
12080
  try {
11766
- (0, import_node_fs33.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
11767
- (0, import_node_fs33.renameSync)(tmp, path);
12081
+ (0, import_node_fs34.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
12082
+ (0, import_node_fs34.renameSync)(tmp, path);
11768
12083
  } catch {
11769
12084
  try {
11770
- (0, import_node_fs33.unlinkSync)(tmp);
12085
+ (0, import_node_fs34.unlinkSync)(tmp);
11771
12086
  } catch {
11772
12087
  }
11773
12088
  }
11774
12089
  }
11775
12090
  function readTurnLive(threadId) {
11776
12091
  const path = threadLivePath(threadId);
11777
- if (!(0, import_node_fs33.existsSync)(path)) return null;
12092
+ if (!(0, import_node_fs34.existsSync)(path)) return null;
11778
12093
  try {
11779
- const raw = JSON.parse((0, import_node_fs33.readFileSync)(path, "utf8"));
12094
+ const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
11780
12095
  if (!raw || typeof raw.summary !== "string") return null;
11781
12096
  return raw;
11782
12097
  } catch {
@@ -11788,17 +12103,17 @@ function clearTurnLive(threadId) {
11788
12103
  if (buf?.timer) clearTimeout(buf.timer);
11789
12104
  buffers.delete(threadId);
11790
12105
  const path = threadLivePath(threadId);
11791
- if (!(0, import_node_fs33.existsSync)(path)) return;
12106
+ if (!(0, import_node_fs34.existsSync)(path)) return;
11792
12107
  try {
11793
- (0, import_node_fs33.unlinkSync)(path);
12108
+ (0, import_node_fs34.unlinkSync)(path);
11794
12109
  } catch {
11795
12110
  }
11796
12111
  }
11797
- var import_node_fs33, buffers, FLUSH_MS, MAX_PARTS;
12112
+ var import_node_fs34, buffers, FLUSH_MS, MAX_PARTS;
11798
12113
  var init_turn_live = __esm({
11799
12114
  "src/store/turn-live.ts"() {
11800
12115
  "use strict";
11801
- import_node_fs33 = require("fs");
12116
+ import_node_fs34 = require("fs");
11802
12117
  init_message_parts();
11803
12118
  init_paths();
11804
12119
  buffers = /* @__PURE__ */ new Map();
@@ -11977,7 +12292,7 @@ var init_quota_failover = __esm({
11977
12292
  // src/threads/adopt.ts
11978
12293
  function thisModuleFile() {
11979
12294
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
11980
- return cjsFile || process.argv[1] || (0, import_node_path31.join)(process.cwd(), "package.json");
12295
+ return cjsFile || process.argv[1] || (0, import_node_path32.join)(process.cwd(), "package.json");
11981
12296
  }
11982
12297
  function openReadonlySqlite(file) {
11983
12298
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -11995,21 +12310,21 @@ function mapAgentType(raw) {
11995
12310
  return null;
11996
12311
  }
11997
12312
  function resolveConductorCursorAgentId(workspacePath) {
11998
- if (!workspacePath || !(0, import_node_fs34.existsSync)(CURSOR_SDK_STORE)) return null;
12313
+ if (!workspacePath || !(0, import_node_fs35.existsSync)(CURSOR_SDK_STORE)) return null;
11999
12314
  const normalized = workspacePath.replace(/\/$/, "");
12000
12315
  let best = null;
12001
12316
  let hashes;
12002
12317
  try {
12003
- hashes = (0, import_node_fs34.readdirSync)(CURSOR_SDK_STORE);
12318
+ hashes = (0, import_node_fs35.readdirSync)(CURSOR_SDK_STORE);
12004
12319
  } catch {
12005
12320
  return null;
12006
12321
  }
12007
12322
  for (const hash of hashes) {
12008
- const agentsFile = (0, import_node_path31.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
12009
- if (!(0, import_node_fs34.existsSync)(agentsFile)) continue;
12323
+ const agentsFile = (0, import_node_path32.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
12324
+ if (!(0, import_node_fs35.existsSync)(agentsFile)) continue;
12010
12325
  let text4;
12011
12326
  try {
12012
- text4 = (0, import_node_fs34.readFileSync)(agentsFile, "utf8");
12327
+ text4 = (0, import_node_fs35.readFileSync)(agentsFile, "utf8");
12013
12328
  } catch {
12014
12329
  continue;
12015
12330
  }
@@ -12033,7 +12348,7 @@ function resolveConductorCursorAgentId(workspacePath) {
12033
12348
  return best?.agentId ?? null;
12034
12349
  }
12035
12350
  async function adoptThread(input) {
12036
- if (!(0, import_node_fs34.existsSync)(input.worktreePath)) {
12351
+ if (!(0, import_node_fs35.existsSync)(input.worktreePath)) {
12037
12352
  throw new Error(`Worktree not found: ${input.worktreePath}`);
12038
12353
  }
12039
12354
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -12057,18 +12372,18 @@ async function adoptThread(input) {
12057
12372
  return thread;
12058
12373
  }
12059
12374
  function listConductorWorkspaces() {
12060
- if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
12375
+ if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
12061
12376
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
12062
12377
  }
12063
- const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path31.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12064
- const snapshot = (0, import_node_path31.join)(tmp, "conductor.db");
12378
+ const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12379
+ const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
12065
12380
  try {
12066
- (0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
12381
+ (0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
12067
12382
  for (const suffix of ["-wal", "-shm"]) {
12068
12383
  const src = `${CONDUCTOR_DB}${suffix}`;
12069
- if ((0, import_node_fs34.existsSync)(src)) {
12384
+ if ((0, import_node_fs35.existsSync)(src)) {
12070
12385
  try {
12071
- (0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
12386
+ (0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
12072
12387
  } catch {
12073
12388
  }
12074
12389
  }
@@ -12144,22 +12459,22 @@ function listConductorWorkspaces() {
12144
12459
  db.close();
12145
12460
  }
12146
12461
  } finally {
12147
- (0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
12462
+ (0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
12148
12463
  }
12149
12464
  }
12150
12465
  function importConductorWorkspace(workspaceId) {
12151
- if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
12466
+ if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
12152
12467
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
12153
12468
  }
12154
- const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path31.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12155
- const snapshot = (0, import_node_path31.join)(tmp, "conductor.db");
12469
+ const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12470
+ const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
12156
12471
  try {
12157
- (0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
12472
+ (0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
12158
12473
  for (const suffix of ["-wal", "-shm"]) {
12159
12474
  const src = `${CONDUCTOR_DB}${suffix}`;
12160
- if ((0, import_node_fs34.existsSync)(src)) {
12475
+ if ((0, import_node_fs35.existsSync)(src)) {
12161
12476
  try {
12162
- (0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
12477
+ (0, import_node_fs35.copyFileSync)(src, `${snapshot}${suffix}`);
12163
12478
  } catch {
12164
12479
  }
12165
12480
  }
@@ -12177,7 +12492,7 @@ function importConductorWorkspace(workspaceId) {
12177
12492
  ).get(workspaceId);
12178
12493
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
12179
12494
  const worktreePath = String(row.workspacePath);
12180
- if (!(0, import_node_fs34.existsSync)(worktreePath)) {
12495
+ if (!(0, import_node_fs35.existsSync)(worktreePath)) {
12181
12496
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
12182
12497
  }
12183
12498
  let sessionId = null;
@@ -12240,31 +12555,31 @@ function importConductorWorkspace(workspaceId) {
12240
12555
  db.close();
12241
12556
  }
12242
12557
  } finally {
12243
- (0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
12558
+ (0, import_node_fs35.rmSync)(tmp, { recursive: true, force: true });
12244
12559
  }
12245
12560
  }
12246
12561
  async function importConductorWorkspaceAsync(workspaceId) {
12247
12562
  return importConductorWorkspace(workspaceId);
12248
12563
  }
12249
- var import_node_child_process3, import_node_fs34, import_node_os10, import_node_path31, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
12564
+ 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;
12250
12565
  var init_adopt = __esm({
12251
12566
  "src/threads/adopt.ts"() {
12252
12567
  "use strict";
12253
12568
  import_node_child_process3 = require("child_process");
12254
- import_node_fs34 = require("fs");
12569
+ import_node_fs35 = require("fs");
12255
12570
  import_node_os10 = require("os");
12256
- import_node_path31 = require("path");
12571
+ import_node_path32 = require("path");
12257
12572
  import_node_module4 = require("module");
12258
12573
  init_worktree();
12259
12574
  init_thread_store();
12260
- CONDUCTOR_APP_SUPPORT = (0, import_node_path31.join)(
12575
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path32.join)(
12261
12576
  process.env.HOME ?? "",
12262
12577
  "Library",
12263
12578
  "Application Support",
12264
12579
  "com.conductor.app"
12265
12580
  );
12266
- CONDUCTOR_DB = (0, import_node_path31.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
12267
- CURSOR_SDK_STORE = (0, import_node_path31.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
12581
+ CONDUCTOR_DB = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
12582
+ CURSOR_SDK_STORE = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
12268
12583
  }
12269
12584
  });
12270
12585
 
@@ -12331,7 +12646,7 @@ async function openStackLayer(input, _onSetupLine) {
12331
12646
  let createdWorktree = false;
12332
12647
  const trees = await listWorktrees(repoPath);
12333
12648
  const checkedOut = trees.find((w) => w.branch === branchName);
12334
- if (checkedOut?.path && (0, import_node_fs35.existsSync)(checkedOut.path)) {
12649
+ if (checkedOut?.path && (0, import_node_fs36.existsSync)(checkedOut.path)) {
12335
12650
  if (input.reuseExistingWorktree !== false) {
12336
12651
  worktreePath = checkedOut.path;
12337
12652
  } else {
@@ -12473,7 +12788,7 @@ async function initStackFromThread(input, onSetupLine) {
12473
12788
  async function createPrStack(input, onSetupLine) {
12474
12789
  await requireAgent(input.agent);
12475
12790
  const repoPath = await resolveRepoRoot(input.repoPath);
12476
- if (!(0, import_node_fs35.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
12791
+ if (!(0, import_node_fs36.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
12477
12792
  if (!input.branches.length) throw new Error("At least one branch name required");
12478
12793
  const status = await detectGhStack(repoPath);
12479
12794
  if (!status.available) throw new Error(status.reason);
@@ -12540,7 +12855,7 @@ async function createPrStack(input, onSetupLine) {
12540
12855
  }
12541
12856
  }
12542
12857
  const claimed = new Set(threads.map((t) => t.worktreePath));
12543
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs35.existsSync)(bootstrap.worktreePath)) {
12858
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs36.existsSync)(bootstrap.worktreePath)) {
12544
12859
  try {
12545
12860
  await removeWorktree(repoPath, bootstrap.worktreePath, {
12546
12861
  deleteBranch: bootstrap.branchName
@@ -12550,11 +12865,11 @@ async function createPrStack(input, onSetupLine) {
12550
12865
  }
12551
12866
  return { stack, threads, createdThreadIds };
12552
12867
  }
12553
- var import_node_fs35;
12868
+ var import_node_fs36;
12554
12869
  var init_stack_layers = __esm({
12555
12870
  "src/threads/stack-layers.ts"() {
12556
12871
  "use strict";
12557
- import_node_fs35 = require("fs");
12872
+ import_node_fs36 = require("fs");
12558
12873
  init_detect();
12559
12874
  init_run();
12560
12875
  init_stack();
@@ -12567,7 +12882,7 @@ var init_stack_layers = __esm({
12567
12882
 
12568
12883
  // src/diff/diff.ts
12569
12884
  async function inspectGitWorktree(worktreePath) {
12570
- if (!worktreePath || !(0, import_node_fs36.existsSync)(worktreePath)) return "missing_worktree";
12885
+ if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) return "missing_worktree";
12571
12886
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
12572
12887
  reject: false
12573
12888
  });
@@ -12575,7 +12890,7 @@ async function inspectGitWorktree(worktreePath) {
12575
12890
  return "ok";
12576
12891
  }
12577
12892
  async function initializeGitRepository(worktreePath) {
12578
- if (!worktreePath || !(0, import_node_fs36.existsSync)(worktreePath)) {
12893
+ if (!worktreePath || !(0, import_node_fs37.existsSync)(worktreePath)) {
12579
12894
  throw new Error("Worktree not found");
12580
12895
  }
12581
12896
  const status = await inspectGitWorktree(worktreePath);
@@ -12709,11 +13024,11 @@ new file mode 100644
12709
13024
  };
12710
13025
  }
12711
13026
  async function untrackedPatch(worktreePath, path, maxHunk) {
12712
- const abs = (0, import_node_path32.join)(worktreePath, path);
13027
+ const abs = (0, import_node_path33.join)(worktreePath, path);
12713
13028
  try {
12714
- const st = (0, import_node_fs36.statSync)(abs);
13029
+ const st = (0, import_node_fs37.statSync)(abs);
12715
13030
  if (st.isFile() && st.size > maxHunk) {
12716
- const buf = (0, import_node_fs36.readFileSync)(abs).subarray(0, maxHunk);
13031
+ const buf = (0, import_node_fs37.readFileSync)(abs).subarray(0, maxHunk);
12717
13032
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
12718
13033
  }
12719
13034
  } catch {
@@ -13202,8 +13517,8 @@ function isImageRelativePath(relativePath) {
13202
13517
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13203
13518
  assertSafeRelativePath(relativePath);
13204
13519
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
13205
- const abs = (0, import_node_path32.join)(worktreePath, relativePath);
13206
- const st = (0, import_node_fs36.statSync)(abs);
13520
+ const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13521
+ const st = (0, import_node_fs37.statSync)(abs);
13207
13522
  if (!st.isFile()) {
13208
13523
  throw new Error(`Not a file: ${relativePath}`);
13209
13524
  }
@@ -13212,7 +13527,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13212
13527
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
13213
13528
  );
13214
13529
  }
13215
- const buf = (0, import_node_fs36.readFileSync)(abs);
13530
+ const buf = (0, import_node_fs37.readFileSync)(abs);
13216
13531
  return {
13217
13532
  path: relativePath,
13218
13533
  contentBase64: buf.toString("base64"),
@@ -13222,12 +13537,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13222
13537
  function readWorktreeFile(worktreePath, relativePath, opts) {
13223
13538
  assertSafeRelativePath(relativePath);
13224
13539
  const maxBytes = opts?.maxBytes ?? 2e5;
13225
- const abs = (0, import_node_path32.join)(worktreePath, relativePath);
13226
- const st = (0, import_node_fs36.statSync)(abs);
13540
+ const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13541
+ const st = (0, import_node_fs37.statSync)(abs);
13227
13542
  if (!st.isFile()) {
13228
13543
  throw new Error(`Not a file: ${relativePath}`);
13229
13544
  }
13230
- const buf = (0, import_node_fs36.readFileSync)(abs);
13545
+ const buf = (0, import_node_fs37.readFileSync)(abs);
13231
13546
  if (isImageRelativePath(relativePath)) {
13232
13547
  const maxImageBytes = Math.max(maxBytes, 15e6);
13233
13548
  const truncated2 = buf.length > maxImageBytes;
@@ -13270,9 +13585,9 @@ function assertSafeRelativePath(relativePath) {
13270
13585
  }
13271
13586
  function writeWorktreeFile(worktreePath, relativePath, content) {
13272
13587
  assertSafeRelativePath(relativePath);
13273
- const abs = (0, import_node_path32.join)(worktreePath, relativePath);
13274
- (0, import_node_fs36.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
13275
- (0, import_node_fs36.writeFileSync)(abs, content, "utf8");
13588
+ const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13589
+ (0, import_node_fs37.mkdirSync)((0, import_node_path33.dirname)(abs), { recursive: true });
13590
+ (0, import_node_fs37.writeFileSync)(abs, content, "utf8");
13276
13591
  return { path: relativePath };
13277
13592
  }
13278
13593
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -13289,12 +13604,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
13289
13604
  truncated: full.files.length > maxFiles
13290
13605
  };
13291
13606
  }
13292
- var import_node_fs36, import_node_path32, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
13607
+ var import_node_fs37, import_node_path33, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
13293
13608
  var init_diff = __esm({
13294
13609
  "src/diff/diff.ts"() {
13295
13610
  "use strict";
13296
- import_node_fs36 = require("fs");
13297
- import_node_path32 = require("path");
13611
+ import_node_fs37 = require("fs");
13612
+ import_node_path33 = require("path");
13298
13613
  init_run();
13299
13614
  init_worktree();
13300
13615
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -13462,7 +13777,7 @@ function parseFrontmatter(content) {
13462
13777
  }
13463
13778
  function readSkill(skillMd, source) {
13464
13779
  try {
13465
- const content = (0, import_node_fs37.readFileSync)(skillMd, "utf8");
13780
+ const content = (0, import_node_fs38.readFileSync)(skillMd, "utf8");
13466
13781
  const { name: fmName, description } = parseFrontmatter(content);
13467
13782
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
13468
13783
  const name = fmName || dirName;
@@ -13481,19 +13796,19 @@ function readSkill(skillMd, source) {
13481
13796
  }
13482
13797
  }
13483
13798
  function scanSkillsDir(dir, source, out) {
13484
- if (!(0, import_node_fs37.existsSync)(dir)) return;
13799
+ if (!(0, import_node_fs38.existsSync)(dir)) return;
13485
13800
  let entries;
13486
13801
  try {
13487
- entries = (0, import_node_fs37.readdirSync)(dir);
13802
+ entries = (0, import_node_fs38.readdirSync)(dir);
13488
13803
  } catch {
13489
13804
  return;
13490
13805
  }
13491
13806
  for (const entry of entries) {
13492
13807
  if (entry.startsWith(".")) continue;
13493
- const skillMd = (0, import_node_path33.join)(dir, entry, "SKILL.md");
13494
- if (!(0, import_node_fs37.existsSync)(skillMd)) continue;
13808
+ const skillMd = (0, import_node_path34.join)(dir, entry, "SKILL.md");
13809
+ if (!(0, import_node_fs38.existsSync)(skillMd)) continue;
13495
13810
  try {
13496
- if (!(0, import_node_fs37.statSync)(skillMd).isFile()) continue;
13811
+ if (!(0, import_node_fs38.statSync)(skillMd).isFile()) continue;
13497
13812
  } catch {
13498
13813
  continue;
13499
13814
  }
@@ -13502,24 +13817,24 @@ function scanSkillsDir(dir, source, out) {
13502
13817
  }
13503
13818
  }
13504
13819
  function scanClaudePluginSkills(pluginsRoot, out) {
13505
- if (!(0, import_node_fs37.existsSync)(pluginsRoot)) return;
13820
+ if (!(0, import_node_fs38.existsSync)(pluginsRoot)) return;
13506
13821
  const walk = (dir, depth, lookingForSkillsDir) => {
13507
13822
  if (depth > 7) return;
13508
13823
  let entries;
13509
13824
  try {
13510
- entries = (0, import_node_fs37.readdirSync)(dir);
13825
+ entries = (0, import_node_fs38.readdirSync)(dir);
13511
13826
  } catch {
13512
13827
  return;
13513
13828
  }
13514
13829
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
13515
- const skill = readSkill((0, import_node_path33.join)(dir, "SKILL.md"), "cli");
13830
+ const skill = readSkill((0, import_node_path34.join)(dir, "SKILL.md"), "cli");
13516
13831
  if (skill) out.push(skill);
13517
13832
  }
13518
13833
  for (const entry of entries) {
13519
13834
  if (entry === "node_modules" || entry === ".git") continue;
13520
- const full = (0, import_node_path33.join)(dir, entry);
13835
+ const full = (0, import_node_path34.join)(dir, entry);
13521
13836
  try {
13522
- if (!(0, import_node_fs37.statSync)(full).isDirectory()) continue;
13837
+ if (!(0, import_node_fs38.statSync)(full).isDirectory()) continue;
13523
13838
  } catch {
13524
13839
  continue;
13525
13840
  }
@@ -13537,17 +13852,17 @@ function discoverSkills(worktreePath) {
13537
13852
  const home = (0, import_node_os11.homedir)();
13538
13853
  const collected = [];
13539
13854
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
13540
- scanSkillsDir((0, import_node_path33.join)(worktreePath, rel), "workspace", collected);
13855
+ scanSkillsDir((0, import_node_path34.join)(worktreePath, rel), "workspace", collected);
13541
13856
  }
13542
13857
  for (const abs of [
13543
- (0, import_node_path33.join)(home, ".claude/skills"),
13544
- (0, import_node_path33.join)(home, ".cursor/skills"),
13545
- (0, import_node_path33.join)(home, ".sideboard/skills"),
13546
- (0, import_node_path33.join)(home, ".brightsy/skills")
13858
+ (0, import_node_path34.join)(home, ".claude/skills"),
13859
+ (0, import_node_path34.join)(home, ".cursor/skills"),
13860
+ (0, import_node_path34.join)(home, ".sideboard/skills"),
13861
+ (0, import_node_path34.join)(home, ".brightsy/skills")
13547
13862
  ]) {
13548
13863
  scanSkillsDir(abs, "user", collected);
13549
13864
  }
13550
- scanClaudePluginSkills((0, import_node_path33.join)(home, ".claude/plugins"), collected);
13865
+ scanClaudePluginSkills((0, import_node_path34.join)(home, ".claude/plugins"), collected);
13551
13866
  const rank = { workspace: 0, user: 1, cli: 2 };
13552
13867
  const byCommand = /* @__PURE__ */ new Map();
13553
13868
  for (const skill of collected) {
@@ -13559,7 +13874,7 @@ function discoverSkills(worktreePath) {
13559
13874
  return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
13560
13875
  }
13561
13876
  function readSkillBody(skillPath, maxChars = 12e3) {
13562
- const raw = (0, import_node_fs37.readFileSync)(skillPath, "utf8");
13877
+ const raw = (0, import_node_fs38.readFileSync)(skillPath, "utf8");
13563
13878
  if (raw.startsWith("---")) {
13564
13879
  const end = raw.indexOf("\n---", 3);
13565
13880
  if (end >= 0) {
@@ -13573,13 +13888,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
13573
13888
 
13574
13889
  \u2026(truncated)` : raw;
13575
13890
  }
13576
- var import_node_fs37, import_node_os11, import_node_path33;
13891
+ var import_node_fs38, import_node_os11, import_node_path34;
13577
13892
  var init_discover = __esm({
13578
13893
  "src/skills/discover.ts"() {
13579
13894
  "use strict";
13580
- import_node_fs37 = require("fs");
13895
+ import_node_fs38 = require("fs");
13581
13896
  import_node_os11 = require("os");
13582
- import_node_path33 = require("path");
13897
+ import_node_path34 = require("path");
13583
13898
  }
13584
13899
  });
13585
13900
 
@@ -13670,7 +13985,7 @@ var init_expand = __esm({
13670
13985
 
13671
13986
  // src/composer/stage-files.ts
13672
13987
  function fileExtension(filePath) {
13673
- const base = (0, import_node_path34.basename)(filePath).toLowerCase();
13988
+ const base = (0, import_node_path35.basename)(filePath).toLowerCase();
13674
13989
  return base.includes(".") ? base.split(".").pop() || "" : "";
13675
13990
  }
13676
13991
  function isImageFilePath(filePath) {
@@ -13680,22 +13995,22 @@ function imageMimeType(filePath) {
13680
13995
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
13681
13996
  }
13682
13997
  function ensureAttachmentsDir(worktreePath) {
13683
- const dir = (0, import_node_path34.join)(worktreePath, ATTACHMENTS_DIR);
13684
- (0, import_node_fs38.mkdirSync)(dir, { recursive: true });
13685
- const gi = (0, import_node_path34.join)(dir, ".gitignore");
13686
- if (!(0, import_node_fs38.existsSync)(gi)) {
13687
- (0, import_node_fs38.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
13998
+ const dir = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR);
13999
+ (0, import_node_fs39.mkdirSync)(dir, { recursive: true });
14000
+ const gi = (0, import_node_path35.join)(dir, ".gitignore");
14001
+ if (!(0, import_node_fs39.existsSync)(gi)) {
14002
+ (0, import_node_fs39.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
13688
14003
  }
13689
14004
  return dir;
13690
14005
  }
13691
14006
  function uniqueAttachmentName(dir, originalName) {
13692
14007
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
13693
- if (!(0, import_node_fs38.existsSync)((0, import_node_path34.join)(dir, safe))) return safe;
13694
- const ext = (0, import_node_path34.extname)(safe);
14008
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, safe))) return safe;
14009
+ const ext = (0, import_node_path35.extname)(safe);
13695
14010
  const stem = ext ? safe.slice(0, -ext.length) : safe;
13696
14011
  for (let i = 1; i < 1e4; i++) {
13697
14012
  const candidate = `${stem}-${i}${ext}`;
13698
- if (!(0, import_node_fs38.existsSync)((0, import_node_path34.join)(dir, candidate))) return candidate;
14013
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, candidate))) return candidate;
13699
14014
  }
13700
14015
  return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
13701
14016
  }
@@ -13751,15 +14066,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
13751
14066
  const dir = ensureAttachmentsDir(worktreePath);
13752
14067
  const out = [];
13753
14068
  for (const abs of absolutePaths) {
13754
- const originalName = (0, import_node_path34.basename)(abs);
14069
+ const originalName = (0, import_node_path35.basename)(abs);
13755
14070
  try {
13756
- const st = (0, import_node_fs38.statSync)(abs);
14071
+ const st = (0, import_node_fs39.statSync)(abs);
13757
14072
  if (!st.isFile()) continue;
13758
14073
  const name = uniqueAttachmentName(dir, originalName);
13759
- const destAbs = (0, import_node_path34.join)(dir, name);
13760
- (0, import_node_fs38.copyFileSync)(abs, destAbs);
14074
+ const destAbs = (0, import_node_path35.join)(dir, name);
14075
+ (0, import_node_fs39.copyFileSync)(abs, destAbs);
13761
14076
  const rel = `${ATTACHMENTS_DIR}/${name}`;
13762
- const buf = (0, import_node_fs38.readFileSync)(destAbs);
14077
+ const buf = (0, import_node_fs39.readFileSync)(destAbs);
13763
14078
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
13764
14079
  } catch (err) {
13765
14080
  out.push({
@@ -13781,8 +14096,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
13781
14096
  try {
13782
14097
  const buf = Buffer.from(item.dataBase64, "base64");
13783
14098
  const name = uniqueAttachmentName(dir, originalName);
13784
- const destAbs = (0, import_node_path34.join)(dir, name);
13785
- (0, import_node_fs38.writeFileSync)(destAbs, buf);
14099
+ const destAbs = (0, import_node_path35.join)(dir, name);
14100
+ (0, import_node_fs39.writeFileSync)(destAbs, buf);
13786
14101
  const rel = `${ATTACHMENTS_DIR}/${name}`;
13787
14102
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
13788
14103
  } catch (err) {
@@ -13802,18 +14117,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
13802
14117
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
13803
14118
  out.push({
13804
14119
  id: (0, import_node_crypto7.randomUUID)(),
13805
- name: (0, import_node_path34.basename)(rel) || "file",
14120
+ name: (0, import_node_path35.basename)(rel) || "file",
13806
14121
  kind: "file",
13807
14122
  content: `(invalid path: ${rel})`
13808
14123
  });
13809
14124
  continue;
13810
14125
  }
13811
- const name = (0, import_node_path34.basename)(rel);
14126
+ const name = (0, import_node_path35.basename)(rel);
13812
14127
  try {
13813
- const abs = (0, import_node_path34.join)(worktreePath, rel);
13814
- const st = (0, import_node_fs38.statSync)(abs);
14128
+ const abs = (0, import_node_path35.join)(worktreePath, rel);
14129
+ const st = (0, import_node_fs39.statSync)(abs);
13815
14130
  if (!st.isFile()) continue;
13816
- const buf = (0, import_node_fs38.readFileSync)(abs);
14131
+ const buf = (0, import_node_fs39.readFileSync)(abs);
13817
14132
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
13818
14133
  } catch (err) {
13819
14134
  out.push({
@@ -13826,12 +14141,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
13826
14141
  }
13827
14142
  return out;
13828
14143
  }
13829
- var import_node_fs38, import_node_path34, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
14144
+ var import_node_fs39, import_node_path35, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
13830
14145
  var init_stage_files = __esm({
13831
14146
  "src/composer/stage-files.ts"() {
13832
14147
  "use strict";
13833
- import_node_fs38 = require("fs");
13834
- import_node_path34 = require("path");
14148
+ import_node_fs39 = require("fs");
14149
+ import_node_path35 = require("path");
13835
14150
  import_node_crypto7 = require("crypto");
13836
14151
  init_workspace_scratch();
13837
14152
  IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -13978,14 +14293,15 @@ function formatArtifactDirective() {
13978
14293
  return [
13979
14294
  "Sideboard side column (desktop UI):",
13980
14295
  "claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
14296
+ "Do not unprompted-duplicate a payload. Chat markdown (including tables) already renders in the transcript \u2014 do not also call present_schema with those same rows just to display them. If the user asks for an editable / interactive table, call present_schema even if markdown already showed the data. Do not also call present_artifact for a document you already fenced in chat.",
13981
14297
  "Documents (HTML/SVG/markdown):",
13982
14298
  "1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
13983
14299
  "```html",
13984
14300
  "<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
13985
14301
  "```",
13986
- "2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
14302
+ "2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content \u2014 not both a fence and this tool for the same body.",
13987
14303
  "CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
13988
- "3) Call Sideboard MCP `present_schema` with title, mode (table|form), and either:",
14304
+ "3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
13989
14305
  " - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
13990
14306
  " - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
13991
14307
  "Files / media browser (CMS file manager column):",
@@ -13994,18 +14310,18 @@ function formatArtifactDirective() {
13994
14310
  "Multiple-choice questions:",
13995
14311
  "5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
13996
14312
  "Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
13997
- "Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
14313
+ "Never say artifacts, CMS UI, or the Files column are unavailable. present_schema is for interactive list/edit/publish (use it when they ask to edit, even if chat already had a markdown table); present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
13998
14314
  ].join("\n");
13999
14315
  }
14000
14316
  function formatUiReminder() {
14001
- 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.";
14317
+ return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. 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.";
14002
14318
  }
14003
- var import_node_fs39, import_node_path35;
14319
+ var import_node_fs40, import_node_path36;
14004
14320
  var init_instructions = __esm({
14005
14321
  "src/agents/instructions.ts"() {
14006
14322
  "use strict";
14007
- import_node_fs39 = require("fs");
14008
- import_node_path35 = require("path");
14323
+ import_node_fs40 = require("fs");
14324
+ import_node_path36 = require("path");
14009
14325
  init_git_auth_mode();
14010
14326
  init_worktree_labels();
14011
14327
  }
@@ -14081,40 +14397,40 @@ __export(plan_file_exports, {
14081
14397
  writePlanFile: () => writePlanFile
14082
14398
  });
14083
14399
  function ensureAttachmentsGitignore(worktreePath) {
14084
- const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14085
- if ((0, import_node_fs40.existsSync)(gitignoreAbs)) return;
14086
- (0, import_node_fs40.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
14087
- (0, import_node_fs40.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14400
+ const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14401
+ if ((0, import_node_fs41.existsSync)(gitignoreAbs)) return;
14402
+ (0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
14403
+ (0, import_node_fs41.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14088
14404
  }
14089
14405
  function planFileAbs(worktreePath) {
14090
- return (0, import_node_path36.join)(worktreePath, PLAN_FILE_REL);
14406
+ return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
14091
14407
  }
14092
14408
  function readTextIfPresent2(abs) {
14093
- if (!(0, import_node_fs40.existsSync)(abs)) return null;
14409
+ if (!(0, import_node_fs41.existsSync)(abs)) return null;
14094
14410
  try {
14095
- const content = (0, import_node_fs40.readFileSync)(abs, "utf8");
14411
+ const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
14096
14412
  return content.trim() ? content : null;
14097
14413
  } catch {
14098
14414
  return null;
14099
14415
  }
14100
14416
  }
14101
14417
  function readPlanFile(worktreePath) {
14102
- 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));
14418
+ 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));
14103
14419
  }
14104
14420
  function writePlanFile(worktreePath, content) {
14105
14421
  ensureAttachmentsGitignore(worktreePath);
14106
14422
  const abs = planFileAbs(worktreePath);
14107
- (0, import_node_fs40.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
14423
+ (0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
14108
14424
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
14109
- (0, import_node_fs40.writeFileSync)(abs, body, "utf8");
14425
+ (0, import_node_fs41.writeFileSync)(abs, body, "utf8");
14110
14426
  return PLAN_FILE_REL;
14111
14427
  }
14112
- var import_node_fs40, import_node_path36;
14428
+ var import_node_fs41, import_node_path37;
14113
14429
  var init_plan_file = __esm({
14114
14430
  "src/plan/plan-file.ts"() {
14115
14431
  "use strict";
14116
- import_node_fs40 = require("fs");
14117
- import_node_path36 = require("path");
14432
+ import_node_fs41 = require("fs");
14433
+ import_node_path37 = require("path");
14118
14434
  init_workspace_scratch();
14119
14435
  init_plan_present();
14120
14436
  init_plan_present();
@@ -14174,7 +14490,7 @@ function setCaffeinateHoldHooks(next) {
14174
14490
  hooks = next;
14175
14491
  }
14176
14492
  function caffeinateHoldPath() {
14177
- return (0, import_node_path37.join)(appDataDir(), "caffeinate-hold.json");
14493
+ return (0, import_node_path38.join)(appDataDir(), "caffeinate-hold.json");
14178
14494
  }
14179
14495
  function processAlive(pid) {
14180
14496
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -14208,9 +14524,9 @@ function uniqueIds(ids) {
14208
14524
  }
14209
14525
  function readHold() {
14210
14526
  const path = caffeinateHoldPath();
14211
- if (!(0, import_node_fs41.existsSync)(path)) return null;
14527
+ if (!(0, import_node_fs42.existsSync)(path)) return null;
14212
14528
  try {
14213
- const parsed = JSON.parse((0, import_node_fs41.readFileSync)(path, "utf8"));
14529
+ const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
14214
14530
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
14215
14531
  return {
14216
14532
  pid: parsed.pid,
@@ -14232,7 +14548,7 @@ function writeHold(pid, threadIds) {
14232
14548
  }
14233
14549
  function clearHold() {
14234
14550
  try {
14235
- (0, import_node_fs41.unlinkSync)(caffeinateHoldPath());
14551
+ (0, import_node_fs42.unlinkSync)(caffeinateHoldPath());
14236
14552
  } catch {
14237
14553
  }
14238
14554
  }
@@ -14317,13 +14633,13 @@ function releaseCaffeinateHoldForThread(threadId) {
14317
14633
  }
14318
14634
  return setCaffeinateHold(false, { threadId: id });
14319
14635
  }
14320
- var import_node_child_process4, import_node_fs41, import_node_path37, hooks;
14636
+ var import_node_child_process4, import_node_fs42, import_node_path38, hooks;
14321
14637
  var init_caffeinate_hold = __esm({
14322
14638
  "src/store/caffeinate-hold.ts"() {
14323
14639
  "use strict";
14324
14640
  import_node_child_process4 = require("child_process");
14325
- import_node_fs41 = require("fs");
14326
- import_node_path37 = require("path");
14641
+ import_node_fs42 = require("fs");
14642
+ import_node_path38 = require("path");
14327
14643
  init_paths();
14328
14644
  init_private_file();
14329
14645
  hooks = {};
@@ -14332,7 +14648,7 @@ var init_caffeinate_hold = __esm({
14332
14648
 
14333
14649
  // src/store/schedules.ts
14334
14650
  function schedulesPath() {
14335
- return (0, import_node_path38.join)(appDataDir(), "schedules.json");
14651
+ return (0, import_node_path39.join)(appDataDir(), "schedules.json");
14336
14652
  }
14337
14653
  function parseDurationMs(every) {
14338
14654
  const m = every.trim().match(DURATION_RE);
@@ -14432,9 +14748,9 @@ function normalizeTask(raw) {
14432
14748
  }
14433
14749
  function readAll2() {
14434
14750
  const path = schedulesPath();
14435
- if (!(0, import_node_fs42.existsSync)(path)) return [];
14751
+ if (!(0, import_node_fs43.existsSync)(path)) return [];
14436
14752
  try {
14437
- const parsed = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
14753
+ const parsed = JSON.parse((0, import_node_fs43.readFileSync)(path, "utf8"));
14438
14754
  if (!Array.isArray(parsed)) return [];
14439
14755
  return parsed.map((row) => {
14440
14756
  try {
@@ -14546,13 +14862,13 @@ function recordScheduleRun(id, result) {
14546
14862
  writeAll2(rows);
14547
14863
  return next;
14548
14864
  }
14549
- var import_node_crypto8, import_node_fs42, import_node_path38, import_croner, DURATION_RE, UNIT_MS;
14865
+ var import_node_crypto8, import_node_fs43, import_node_path39, import_croner, DURATION_RE, UNIT_MS;
14550
14866
  var init_schedules = __esm({
14551
14867
  "src/store/schedules.ts"() {
14552
14868
  "use strict";
14553
14869
  import_node_crypto8 = require("crypto");
14554
- import_node_fs42 = require("fs");
14555
- import_node_path38 = require("path");
14870
+ import_node_fs43 = require("fs");
14871
+ import_node_path39 = require("path");
14556
14872
  import_croner = require("croner");
14557
14873
  init_orchestrator_capable();
14558
14874
  init_paths();
@@ -14700,10 +15016,10 @@ __export(cursor_recover_exports, {
14700
15016
  function recoverFinishedCursorRun(opts) {
14701
15017
  const agentId = opts.agentId.trim();
14702
15018
  if (!agentId) return null;
14703
- const runsPath = (0, import_node_path39.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
14704
- if (!(0, import_node_fs43.existsSync)(runsPath)) return null;
15019
+ const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
15020
+ if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
14705
15021
  try {
14706
- const lines = (0, import_node_fs43.readFileSync)(runsPath, "utf8").split("\n");
15022
+ const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
14707
15023
  let best = null;
14708
15024
  for (const line of lines) {
14709
15025
  const trimmed = line.trim();
@@ -14729,12 +15045,12 @@ function recoverFinishedCursorRun(opts) {
14729
15045
  return null;
14730
15046
  }
14731
15047
  }
14732
- var import_node_fs43, import_node_path39;
15048
+ var import_node_fs44, import_node_path40;
14733
15049
  var init_cursor_recover = __esm({
14734
15050
  "src/agents/cursor-recover.ts"() {
14735
15051
  "use strict";
14736
- import_node_fs43 = require("fs");
14737
- import_node_path39 = require("path");
15052
+ import_node_fs44 = require("fs");
15053
+ import_node_path40 = require("path");
14738
15054
  init_paths();
14739
15055
  }
14740
15056
  });
@@ -14865,14 +15181,16 @@ async function startOrchestration(opts) {
14865
15181
  }
14866
15182
  return updated;
14867
15183
  }
14868
- var import_node_events, import_node_fs44, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
15184
+ var import_node_events, import_node_fs45, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
14869
15185
  var init_orchestrator = __esm({
14870
15186
  "src/orchestrator/orchestrator.ts"() {
14871
15187
  "use strict";
14872
15188
  import_node_events = require("events");
14873
15189
  init_outbound_watch();
14874
- import_node_fs44 = require("fs");
15190
+ import_node_fs45 = require("fs");
14875
15191
  init_error_detail();
15192
+ init_run();
15193
+ init_stale_lock();
14876
15194
  init_spawn();
14877
15195
  init_agents();
14878
15196
  init_worktree();
@@ -14988,7 +15306,7 @@ var init_orchestrator = __esm({
14988
15306
  }
14989
15307
  continue;
14990
15308
  }
14991
- if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
15309
+ if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
14992
15310
  setStatus(thread.id, "broken", "Worktree missing on disk");
14993
15311
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
14994
15312
  continue;
@@ -15581,7 +15899,15 @@ var init_orchestrator = __esm({
15581
15899
  hasSession: Boolean(this.requireThread(threadId).sessionId)
15582
15900
  })) {
15583
15901
  updateThread(threadId, { sessionId: null });
15584
- const retryNote = looksLikeInvalidAgentSession(detail) ? "Agent session missing \u2014 starting a fresh session" : "Agent runner crashed \u2014 restarting Node once";
15902
+ try {
15903
+ const gitDirs = await resolveGitDirsForLockRecovery(thread.worktreePath);
15904
+ const clearedLocks = clearStaleIndexLocks(gitDirs, 2e3);
15905
+ if (clearedLocks.length > 0) {
15906
+ pushTurnStderr(stderrTail, "Cleared a stale git lock left by the crashed agent process");
15907
+ }
15908
+ } catch {
15909
+ }
15910
+ 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";
15585
15911
  pushTurnStderr(stderrTail, retryNote);
15586
15912
  this.emit({
15587
15913
  type: "turn_output",
@@ -16053,13 +16379,14 @@ var init_orchestrator = __esm({
16053
16379
  const text4 = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
16054
16380
  const stillRunning = thread.status === "running" || thread.status === "queued";
16055
16381
  const live = stillRunning ? readTurnLive(thread.id) : null;
16382
+ const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
16056
16383
  return {
16057
16384
  text: text4,
16058
16385
  status: thread.status,
16059
16386
  sessionId: thread.sessionId,
16060
16387
  lastError,
16061
16388
  stillRunning,
16062
- progress: live?.summary ?? null,
16389
+ progress: live?.summary ?? queuedHint,
16063
16390
  lastActivityAt: live?.updatedAt ?? null
16064
16391
  };
16065
16392
  }
@@ -16576,7 +16903,7 @@ var init_orchestrator = __esm({
16576
16903
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
16577
16904
  return restored2;
16578
16905
  }
16579
- if (!(0, import_node_fs44.existsSync)(thread.worktreePath)) {
16906
+ if (!(0, import_node_fs45.existsSync)(thread.worktreePath)) {
16580
16907
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
16581
16908
  throw new Error(
16582
16909
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -16656,7 +16983,7 @@ init_nested_electron_env();
16656
16983
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
16657
16984
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
16658
16985
  var import_zod4 = require("zod");
16659
- var import_node_path40 = require("path");
16986
+ var import_node_path41 = require("path");
16660
16987
  init_orchestrator();
16661
16988
  init_worktree();
16662
16989
 
@@ -17163,6 +17490,10 @@ function mcpWaitForTurnTimeoutMs(requested) {
17163
17490
  return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
17164
17491
  }
17165
17492
  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.";
17493
+ 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.";
17494
+ function mcpWaitStillRunningHint(status) {
17495
+ return status === "queued" ? MCP_WAIT_QUEUED_HINT : MCP_WAIT_STILL_RUNNING_HINT;
17496
+ }
17166
17497
 
17167
17498
  // src/mcp/server.ts
17168
17499
  init_turn_live();
@@ -18009,7 +18340,7 @@ async function startMcpServer() {
18009
18340
  async () => {
18010
18341
  const threads = orch.getThreads(true);
18011
18342
  const lines = threads.map((t) => {
18012
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path40.basename)(t.repoPath) || t.repoPath;
18343
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
18013
18344
  const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
18014
18345
  const progress = live?.summary ? ` ${live.summary}` : "";
18015
18346
  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}`;
@@ -18045,7 +18376,7 @@ async function startMcpServer() {
18045
18376
  prUrl: t.prUrl,
18046
18377
  lastError: t.lastError ?? null,
18047
18378
  stillRunning: t.status === "running" || t.status === "queued",
18048
- progress: live?.summary ?? null,
18379
+ progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
18049
18380
  lastActivityAt: live?.updatedAt ?? null
18050
18381
  };
18051
18382
  return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
@@ -18054,7 +18385,7 @@ async function startMcpServer() {
18054
18385
  }
18055
18386
  server.tool(
18056
18387
  "present_artifact",
18057
- "Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
18388
+ "Show an HTML, SVG, markdown, or React document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Do not also emit the same document as a chat html/markdown fence. Prefer type=html for interactive pages. For type=react, pass a single component module that `export default`s a component (JSX/TSX ok) \u2014 Sideboard bootstraps React/ReactDOM/Babel and renders it; only `react`/`react-dom` imports are available, no other npm packages.",
18058
18389
  {
18059
18390
  title: import_zod4.z.string().describe("Short title shown in the artifact pane header"),
18060
18391
  type: import_zod4.z.enum(["html", "svg", "markdown", "react"]).describe(
@@ -18131,7 +18462,7 @@ async function startMcpServer() {
18131
18462
  );
18132
18463
  server.tool(
18133
18464
  "present_schema",
18134
- "Open Sideboard\u2019s schema-driven side column (filterable table and/or form). Pass JSON Schema + optional schemaUi. Prefer datasource=inline with embedded resource/records. Use datasource=brightsy with resource_id only when the user is logged into Brightsy.",
18465
+ "Open Sideboard\u2019s schema-driven side column (filterable table and/or form) when the user needs to filter, edit, publish, or persist records. Do not call this just to re-display rows you already wrote as a markdown table. If the user asks for an editable / interactive table, call this even if chat already showed those rows. Pass JSON Schema + optional schemaUi. Prefer datasource=inline with embedded resource/records. Use datasource=brightsy with resource_id only when the user is logged into Brightsy.",
18135
18466
  {
18136
18467
  title: import_zod4.z.string().describe("Pane title"),
18137
18468
  mode: import_zod4.z.enum(["table", "form"]).optional().describe("table = list/filter records; form = edit one record"),
@@ -18379,7 +18710,7 @@ async function startMcpServer() {
18379
18710
  );
18380
18711
  server.tool(
18381
18712
  "wait_for_turn",
18382
- "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.",
18713
+ "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.",
18383
18714
  {
18384
18715
  ref: import_zod4.z.string(),
18385
18716
  timeoutMs: import_zod4.z.number().optional()
@@ -18401,7 +18732,7 @@ async function startMcpServer() {
18401
18732
  stillRunning: result.stillRunning,
18402
18733
  progress: result.progress,
18403
18734
  lastActivityAt: result.lastActivityAt,
18404
- hint: result.stillRunning ? MCP_WAIT_STILL_RUNNING_HINT : void 0
18735
+ hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
18405
18736
  })
18406
18737
  }
18407
18738
  ]
@@ -18420,7 +18751,7 @@ async function startMcpServer() {
18420
18751
  type: "text",
18421
18752
  text: JSON.stringify({
18422
18753
  ...result,
18423
- hint: result.stillRunning ? MCP_WAIT_STILL_RUNNING_HINT : void 0
18754
+ hint: result.stillRunning ? mcpWaitStillRunningHint(result.status) : void 0
18424
18755
  })
18425
18756
  }
18426
18757
  ]