@sideboard-ai/core 0.1.115 → 0.1.117

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 (42) hide show
  1. package/dist/agents/cursor-runner.cjs +96 -60
  2. package/dist/agents/cursor-runner.js +10 -9
  3. package/dist/{agents-3X3EFCQY.js → agents-GUEKGV7V.js} +6 -6
  4. package/dist/{agents-AHAFC6FR.js → agents-OCGAZCKT.js} +5 -5
  5. package/dist/{chunk-66XTXHR3.js → chunk-4CDCTYTM.js} +61 -11
  6. package/dist/{chunk-XOYQ7LNQ.js → chunk-4NAW5BAQ.js} +3 -3
  7. package/dist/{chunk-4OJMZ6P2.js → chunk-4WV7C7WP.js} +3 -3
  8. package/dist/{chunk-DCNR7NAL.js → chunk-5X7GRP5W.js} +49 -24
  9. package/dist/{chunk-MZ6HJ7VL.js → chunk-74YJHND6.js} +48 -23
  10. package/dist/{chunk-ZRCX43LS.js → chunk-BKVDZV7X.js} +2 -2
  11. package/dist/{chunk-A4VZXJEJ.js → chunk-HPAWHIZ3.js} +4 -1
  12. package/dist/{chunk-SLU5JVKD.js → chunk-NZBDVBCP.js} +23 -2
  13. package/dist/{chunk-KYOTBZ6S.js → chunk-RG737OWT.js} +4 -1
  14. package/dist/{chunk-K3TIQXOH.js → chunk-U3IVCVLH.js} +2 -2
  15. package/dist/{chunk-FZCIQYNQ.js → chunk-VGPLXQIH.js} +1 -1
  16. package/dist/chunk-VHX673DI.js +32 -0
  17. package/dist/{chunk-ZMROW673.js → chunk-WCU3FHEI.js} +1 -1
  18. package/dist/{chunk-7WC5UWEB.js → chunk-X3NIPGQT.js} +1 -1
  19. package/dist/{chunk-ZYEFCSZJ.js → chunk-XTZQL7OU.js} +1 -1
  20. package/dist/{chunk-C6OBY6IC.js → chunk-YJ2WV5TZ.js} +54 -10
  21. package/dist/{coordinator-prompt-4KCALEKD.js → coordinator-prompt-QMV6YEP5.js} +3 -3
  22. package/dist/{coordinator-prompt-FML4I5AR.js → coordinator-prompt-XCBHAOGE.js} +3 -3
  23. package/dist/cursor-recover-NOQYOFRF.js +76 -0
  24. package/dist/{cursor-recover-JBTIDARH.js → cursor-recover-QSLWEZNA.js} +12 -7
  25. package/dist/{global-workspace-CSWABOG5.js → global-workspace-SBKXKQFS.js} +4 -4
  26. package/dist/{global-workspace-H4YNASM6.js → global-workspace-Z37MNYU6.js} +4 -4
  27. package/dist/index.cjs +369 -240
  28. package/dist/index.d.cts +13 -1
  29. package/dist/index.d.ts +13 -1
  30. package/dist/index.js +14 -10
  31. package/dist/mcp/run-stdio.cjs +359 -237
  32. package/dist/mcp/run-stdio.js +9 -9
  33. package/dist/{orchestrator-GKLYKLRC.js → orchestrator-4PKR6AZJ.js} +7 -7
  34. package/dist/{orchestrator-TXASYNHT.js → orchestrator-MKTZYWTI.js} +8 -8
  35. package/dist/{thread-store-OEALWU7Y.js → thread-store-JR235AWK.js} +3 -1
  36. package/dist/{thread-store-LPTBVW5C.js → thread-store-PMH3BMB6.js} +3 -1
  37. package/dist/{workspaces-HJ3EVATC.js → workspaces-C3TJJFY3.js} +5 -5
  38. package/dist/{workspaces-QG6PGFQR.js → workspaces-M4OICPWF.js} +5 -5
  39. package/dist/{worktree-IW3BX26B.js → worktree-7AEKZSEX.js} +2 -2
  40. package/dist/{worktree-OTFQO2W7.js → worktree-MRSTQ32S.js} +2 -2
  41. package/package.json +1 -1
  42. package/dist/cursor-recover-ZUJG6XRQ.js +0 -42
@@ -670,6 +670,7 @@ __export(thread_store_exports, {
670
670
  createEmptyThread: () => createEmptyThread,
671
671
  deleteThreadRecord: () => deleteThreadRecord,
672
672
  findThreadByRef: () => findThreadByRef,
673
+ isThreadRecordFile: () => isThreadRecordFile,
673
674
  listThreads: () => listThreads,
674
675
  normalizeThread: () => normalizeThread,
675
676
  readThread: () => readThread,
@@ -780,7 +781,8 @@ function writeThread(thread) {
780
781
  function idPath(id) {
781
782
  return id;
782
783
  }
783
- function isThreadRecordFile(name) {
784
+ function isThreadRecordFile(nameOrPath) {
785
+ const name = (0, import_node_path7.basename)(nameOrPath);
784
786
  return name.endsWith(".json") && !name.endsWith(".live.json");
785
787
  }
786
788
  function listThreads(opts) {
@@ -831,12 +833,13 @@ function findThreadByRef(ref) {
831
833
  (t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
832
834
  ) ?? null;
833
835
  }
834
- var import_node_crypto2, import_node_fs7, import_proper_lockfile;
836
+ var import_node_crypto2, import_node_fs7, import_node_path7, import_proper_lockfile;
835
837
  var init_thread_store = __esm({
836
838
  "src/store/thread-store.ts"() {
837
839
  "use strict";
838
840
  import_node_crypto2 = require("crypto");
839
841
  import_node_fs7 = require("fs");
842
+ import_node_path7 = require("path");
840
843
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
841
844
  init_thinking_effort();
842
845
  init_paths();
@@ -887,7 +890,7 @@ var init_api = __esm({
887
890
 
888
891
  // src/slack/reply-target.ts
889
892
  function storePath() {
890
- return (0, import_node_path7.join)(appDataDir(), "slack-reply-to.json");
893
+ return (0, import_node_path8.join)(appDataDir(), "slack-reply-to.json");
891
894
  }
892
895
  function readStore() {
893
896
  const path = storePath();
@@ -902,12 +905,12 @@ function readStore() {
902
905
  function getSlackReplyTarget(threadId) {
903
906
  return readStore()[threadId] ?? null;
904
907
  }
905
- var import_node_fs8, import_node_path7;
908
+ var import_node_fs8, import_node_path8;
906
909
  var init_reply_target = __esm({
907
910
  "src/slack/reply-target.ts"() {
908
911
  "use strict";
909
912
  import_node_fs8 = require("fs");
910
- import_node_path7 = require("path");
913
+ import_node_path8 = require("path");
911
914
  init_paths();
912
915
  init_private_file();
913
916
  init_secure_file();
@@ -916,7 +919,7 @@ var init_reply_target = __esm({
916
919
 
917
920
  // src/slack/workspaces.ts
918
921
  function storePath2() {
919
- return (0, import_node_path8.join)(appDataDir(), "slack-workspaces.json");
922
+ return (0, import_node_path9.join)(appDataDir(), "slack-workspaces.json");
920
923
  }
921
924
  function readStore2() {
922
925
  try {
@@ -977,11 +980,11 @@ function requireSlackWorkspace(teamId) {
977
980
  }
978
981
  return ws;
979
982
  }
980
- var import_node_path8;
983
+ var import_node_path9;
981
984
  var init_workspaces = __esm({
982
985
  "src/slack/workspaces.ts"() {
983
986
  "use strict";
984
- import_node_path8 = require("path");
987
+ import_node_path9 = require("path");
985
988
  init_paths();
986
989
  init_secure_file();
987
990
  init_api();
@@ -990,7 +993,7 @@ var init_workspaces = __esm({
990
993
 
991
994
  // src/slack/outbound-watch.ts
992
995
  function storePath3() {
993
- return (0, import_node_path9.join)(appDataDir(), "slack-outbound-watch.json");
996
+ return (0, import_node_path10.join)(appDataDir(), "slack-outbound-watch.json");
994
997
  }
995
998
  function watchId(teamId, channelId, ts) {
996
999
  return `${teamId}:${channelId}:${ts}`;
@@ -1352,12 +1355,12 @@ async function refreshSlackReplyBadges(opts) {
1352
1355
  if (changed) writeStore(watches);
1353
1356
  return listSlackReplyBadges();
1354
1357
  }
1355
- var import_node_fs9, import_node_path9, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache;
1358
+ var import_node_fs9, import_node_path10, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache;
1356
1359
  var init_outbound_watch = __esm({
1357
1360
  "src/slack/outbound-watch.ts"() {
1358
1361
  "use strict";
1359
1362
  import_node_fs9 = require("fs");
1360
- import_node_path9 = require("path");
1363
+ import_node_path10 = require("path");
1361
1364
  init_paths();
1362
1365
  init_private_file();
1363
1366
  init_secure_file();
@@ -1492,7 +1495,7 @@ function summarizeTurnStderr(tail, maxChars = 500) {
1492
1495
  function looksLikeInvalidAgentSession(text4) {
1493
1496
  const lower = text4.trim().toLowerCase();
1494
1497
  if (!lower) return false;
1495
- return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower);
1498
+ return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower) || /\brun\b.{0,80}\bnot found for agent\b/.test(lower);
1496
1499
  }
1497
1500
  function looksLikeRetryableRunnerCrash(text4) {
1498
1501
  if (looksLikeAgentFailureMessage(text4)) return false;
@@ -1609,15 +1612,15 @@ var init_error_detail = __esm({
1609
1612
  function prependPathDir(env, dir) {
1610
1613
  if (!dir || !(0, import_node_fs10.existsSync)(dir)) return;
1611
1614
  const current = env.PATH ?? "";
1612
- const parts = current.split(import_node_path10.delimiter).filter(Boolean);
1615
+ const parts = current.split(import_node_path11.delimiter).filter(Boolean);
1613
1616
  if (parts.includes(dir)) {
1614
1617
  env.PATH = current;
1615
1618
  return;
1616
1619
  }
1617
- env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
1620
+ env.PATH = [dir, ...parts].join(import_node_path11.delimiter);
1618
1621
  }
1619
1622
  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");
1623
+ return (0, import_node_path11.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
1621
1624
  }
1622
1625
  function isConductorBundledCli(filePath) {
1623
1626
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -1626,10 +1629,10 @@ function isConductorBundledCli(filePath) {
1626
1629
  function ensureAgentPath(env = process.env) {
1627
1630
  const home = env.HOME || env.USERPROFILE || (0, import_node_os3.homedir)();
1628
1631
  const current = env.PATH ?? "";
1629
- const parts = current.split(import_node_path10.delimiter).filter(Boolean);
1632
+ const parts = current.split(import_node_path11.delimiter).filter(Boolean);
1630
1633
  const seen = new Set(parts);
1631
1634
  const extras = [
1632
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
1635
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path11.join)(home, rel)),
1633
1636
  "/opt/homebrew/bin",
1634
1637
  "/usr/local/bin",
1635
1638
  // Keep after Homebrew/npm so a user-installed CLI still wins.
@@ -1640,7 +1643,7 @@ function ensureAgentPath(env = process.env) {
1640
1643
  parts.unshift(dir);
1641
1644
  seen.add(dir);
1642
1645
  }
1643
- const next = parts.join(import_node_path10.delimiter);
1646
+ const next = parts.join(import_node_path11.delimiter);
1644
1647
  env.PATH = next;
1645
1648
  return next;
1646
1649
  }
@@ -1654,7 +1657,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
1654
1657
  stdio: ["ignore", "pipe", "ignore"]
1655
1658
  }).trim().split(/\r?\n/).find(Boolean);
1656
1659
  if (prefix) {
1657
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
1660
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path11.join)(prefix, "bin");
1658
1661
  prependPathDir(env, binDir);
1659
1662
  }
1660
1663
  } catch {
@@ -1682,14 +1685,14 @@ function withExportedPath(command, pathValue) {
1682
1685
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
1683
1686
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
1684
1687
  }
1685
- var import_node_fs10, import_node_child_process2, import_node_os3, import_node_path10, EXTRA_BIN_DIRS;
1688
+ var import_node_fs10, import_node_child_process2, import_node_os3, import_node_path11, EXTRA_BIN_DIRS;
1686
1689
  var init_path = __esm({
1687
1690
  "src/agents/path.ts"() {
1688
1691
  "use strict";
1689
1692
  import_node_fs10 = require("fs");
1690
1693
  import_node_child_process2 = require("child_process");
1691
1694
  import_node_os3 = require("os");
1692
- import_node_path10 = require("path");
1695
+ import_node_path11 = require("path");
1693
1696
  EXTRA_BIN_DIRS = [
1694
1697
  ".local/bin",
1695
1698
  ".cargo/bin",
@@ -1711,7 +1714,7 @@ function isIndexLockError(text4) {
1711
1714
  return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text4);
1712
1715
  }
1713
1716
  function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
1714
- const lockPath = (0, import_node_path11.join)(gitDir, "index.lock");
1717
+ const lockPath = (0, import_node_path12.join)(gitDir, "index.lock");
1715
1718
  try {
1716
1719
  if (!(0, import_node_fs11.existsSync)(lockPath)) return null;
1717
1720
  if (now - (0, import_node_fs11.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
@@ -1730,12 +1733,12 @@ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
1730
1733
  }
1731
1734
  return removed;
1732
1735
  }
1733
- var import_node_fs11, import_node_path11, STALE_INDEX_LOCK_MS;
1736
+ var import_node_fs11, import_node_path12, STALE_INDEX_LOCK_MS;
1734
1737
  var init_stale_lock = __esm({
1735
1738
  "src/git/stale-lock.ts"() {
1736
1739
  "use strict";
1737
1740
  import_node_fs11 = require("fs");
1738
- import_node_path11 = require("path");
1741
+ import_node_path12 = require("path");
1739
1742
  STALE_INDEX_LOCK_MS = 2e4;
1740
1743
  }
1741
1744
  });
@@ -2753,7 +2756,7 @@ var init_gh_errors = __esm({
2753
2756
 
2754
2757
  // src/store/secret-vault.ts
2755
2758
  function secretVaultPath() {
2756
- return (0, import_node_path12.join)(appDataDir(), "secrets.json");
2759
+ return (0, import_node_path13.join)(appDataDir(), "secrets.json");
2757
2760
  }
2758
2761
  function loadSecretVault() {
2759
2762
  const parsed = readSecureJson(secretVaultPath());
@@ -2797,11 +2800,11 @@ function normalizeVault(raw) {
2797
2800
  }
2798
2801
  return out;
2799
2802
  }
2800
- var import_node_path12;
2803
+ var import_node_path13;
2801
2804
  var init_secret_vault = __esm({
2802
2805
  "src/store/secret-vault.ts"() {
2803
2806
  "use strict";
2804
- import_node_path12 = require("path");
2807
+ import_node_path13 = require("path");
2805
2808
  init_paths();
2806
2809
  init_secure_file();
2807
2810
  }
@@ -2904,10 +2907,10 @@ function toPublicAppSettings(settings) {
2904
2907
  };
2905
2908
  }
2906
2909
  function appSettingsPath() {
2907
- return (0, import_node_path13.join)(appDataDir(), "settings.json");
2910
+ return (0, import_node_path14.join)(appDataDir(), "settings.json");
2908
2911
  }
2909
2912
  function claudeUserSettingsPath() {
2910
- return (0, import_node_path13.join)((0, import_node_os4.homedir)(), ".claude", "settings.json");
2913
+ return (0, import_node_path14.join)((0, import_node_os4.homedir)(), ".claude", "settings.json");
2911
2914
  }
2912
2915
  function normalizeClaude(raw) {
2913
2916
  if (!raw || typeof raw !== "object") return {};
@@ -3731,14 +3734,14 @@ function childEnvWithAppSettings(extra) {
3731
3734
  function harnessEnvKey(harness) {
3732
3735
  return HARNESS_ENV_KEYS[harness];
3733
3736
  }
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;
3737
+ var import_node_crypto3, import_node_fs12, import_node_os4, import_node_path14, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
3735
3738
  var init_app_settings = __esm({
3736
3739
  "src/store/app-settings.ts"() {
3737
3740
  "use strict";
3738
3741
  import_node_crypto3 = require("crypto");
3739
3742
  import_node_fs12 = require("fs");
3740
3743
  import_node_os4 = require("os");
3741
- import_node_path13 = require("path");
3744
+ import_node_path14 = require("path");
3742
3745
  init_thinking_effort();
3743
3746
  init_nested_electron_env();
3744
3747
  init_paths();
@@ -3790,18 +3793,18 @@ var init_app_settings = __esm({
3790
3793
  function githubAgentAuthDir() {
3791
3794
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
3792
3795
  if (override) return override;
3793
- return (0, import_node_path14.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
3796
+ return (0, import_node_path15.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
3794
3797
  }
3795
3798
  function githubCredentialStorePath() {
3796
- return (0, import_node_path14.join)(githubAgentAuthDir(), "git-credentials");
3799
+ return (0, import_node_path15.join)(githubAgentAuthDir(), "git-credentials");
3797
3800
  }
3798
3801
  function githubGhConfigDir() {
3799
- return (0, import_node_path14.join)(githubAgentAuthDir(), "gh");
3802
+ return (0, import_node_path15.join)(githubAgentAuthDir(), "gh");
3800
3803
  }
3801
3804
  function writePrivateFile2(file, body) {
3802
- (0, import_node_fs13.mkdirSync)((0, import_node_path14.dirname)(file), { recursive: true, mode: 448 });
3805
+ (0, import_node_fs13.mkdirSync)((0, import_node_path15.dirname)(file), { recursive: true, mode: 448 });
3803
3806
  try {
3804
- (0, import_node_fs13.chmodSync)((0, import_node_path14.dirname)(file), 448);
3807
+ (0, import_node_fs13.chmodSync)((0, import_node_path15.dirname)(file), 448);
3805
3808
  } catch {
3806
3809
  }
3807
3810
  (0, import_node_fs13.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
@@ -3839,11 +3842,11 @@ function materializeGithubAgentAuth(token, user) {
3839
3842
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
3840
3843
  const ghDir = githubGhConfigDir();
3841
3844
  (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");
3845
+ writePrivateFile2((0, import_node_path15.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
3846
+ writePrivateFile2((0, import_node_path15.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
3844
3847
  }
3845
3848
  function githubAgentAuthReady() {
3846
- return (0, import_node_fs13.existsSync)(githubCredentialStorePath()) && (0, import_node_fs13.existsSync)((0, import_node_path14.join)(githubGhConfigDir(), "hosts.yml"));
3849
+ return (0, import_node_fs13.existsSync)(githubCredentialStorePath()) && (0, import_node_fs13.existsSync)((0, import_node_path15.join)(githubGhConfigDir(), "hosts.yml"));
3847
3850
  }
3848
3851
  function githubCredentialHelperGitConfig() {
3849
3852
  const file = githubCredentialStorePath();
@@ -3858,13 +3861,13 @@ function githubGhConfigEnv() {
3858
3861
  GH_PROMPT_DISABLED: "1"
3859
3862
  };
3860
3863
  }
3861
- var import_node_fs13, import_node_os5, import_node_path14;
3864
+ var import_node_fs13, import_node_os5, import_node_path15;
3862
3865
  var init_github_agent_auth = __esm({
3863
3866
  "src/git/github-agent-auth.ts"() {
3864
3867
  "use strict";
3865
3868
  import_node_fs13 = require("fs");
3866
3869
  import_node_os5 = require("os");
3867
- import_node_path14 = require("path");
3870
+ import_node_path15 = require("path");
3868
3871
  }
3869
3872
  });
3870
3873
 
@@ -3956,7 +3959,7 @@ async function warmGithubAgentAuth(opts) {
3956
3959
  }
3957
3960
  function normalizeWritableRoot(raw) {
3958
3961
  const trimmed = raw.trim().replace(/\/+$/, "");
3959
- return trimmed && (0, import_node_path15.isAbsolute)(trimmed) ? trimmed : null;
3962
+ return trimmed && (0, import_node_path16.isAbsolute)(trimmed) ? trimmed : null;
3960
3963
  }
3961
3964
  async function resolveCodexGitWritableRoots(cwd) {
3962
3965
  const roots = /* @__PURE__ */ new Set();
@@ -4033,11 +4036,11 @@ function formatGitAuthModeDirective(mode) {
4033
4036
  ].join("\n");
4034
4037
  }
4035
4038
  }
4036
- var import_node_path15, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
4039
+ var import_node_path16, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
4037
4040
  var init_git_auth_mode = __esm({
4038
4041
  "src/git/git-auth-mode.ts"() {
4039
4042
  "use strict";
4040
- import_node_path15 = require("path");
4043
+ import_node_path16 = require("path");
4041
4044
  init_app_settings();
4042
4045
  init_github_agent_auth();
4043
4046
  init_run();
@@ -5207,7 +5210,7 @@ function isLocalPrFetchBranch(ref) {
5207
5210
  }
5208
5211
  async function createThreadWorktree(opts) {
5209
5212
  let branchName = `thread/${opts.slug}`;
5210
- const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
5213
+ const worktreePath = (0, import_node_path17.join)(worktreesRoot(opts.repoPath), opts.slug);
5211
5214
  if ((0, import_node_fs14.existsSync)(worktreePath)) {
5212
5215
  throw new Error(`Worktree already exists at ${worktreePath}`);
5213
5216
  }
@@ -5275,7 +5278,7 @@ ${add.stdout}`;
5275
5278
  async function createExistingBranchWorktree(opts) {
5276
5279
  const branchName = opts.branchName.trim();
5277
5280
  if (!branchName) throw new Error("branch name required");
5278
- const worktreePath = (0, import_node_path16.join)(worktreesRoot(opts.repoPath), opts.slug);
5281
+ const worktreePath = (0, import_node_path17.join)(worktreesRoot(opts.repoPath), opts.slug);
5279
5282
  if ((0, import_node_fs14.existsSync)(worktreePath)) {
5280
5283
  throw new Error(`Worktree already exists at ${worktreePath}`);
5281
5284
  }
@@ -5567,7 +5570,7 @@ function sameRepoPath(a, b) {
5567
5570
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
5568
5571
  }
5569
5572
  function listLocalThreadBranchSlugs(repoPath) {
5570
- const refsDir = (0, import_node_path16.join)(repoPath, ".git", "refs", "heads", "thread");
5573
+ const refsDir = (0, import_node_path17.join)(repoPath, ".git", "refs", "heads", "thread");
5571
5574
  if (!(0, import_node_fs14.existsSync)(refsDir)) return [];
5572
5575
  try {
5573
5576
  return (0, import_node_fs14.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
@@ -5600,18 +5603,18 @@ function allocateTeamSlug(repoPath) {
5600
5603
  const taken = collectTakenTeamSlugs(repoPath);
5601
5604
  for (let attempt = 0; attempt < 32; attempt++) {
5602
5605
  const team = allocateTeamName(taken);
5603
- const path = (0, import_node_path16.join)(worktreesRoot(repoPath), team.slug);
5606
+ const path = (0, import_node_path17.join)(worktreesRoot(repoPath), team.slug);
5604
5607
  if (!(0, import_node_fs14.existsSync)(path)) return team;
5605
5608
  taken.add(team.slug);
5606
5609
  }
5607
5610
  throw new Error("No available soccer team worktree directories left");
5608
5611
  }
5609
- var import_node_fs14, import_node_path16;
5612
+ var import_node_fs14, import_node_path17;
5610
5613
  var init_worktree = __esm({
5611
5614
  "src/git/worktree.ts"() {
5612
5615
  "use strict";
5613
5616
  import_node_fs14 = require("fs");
5614
- import_node_path16 = require("path");
5617
+ import_node_path17 = require("path");
5615
5618
  init_paths();
5616
5619
  init_thread_store();
5617
5620
  init_teams();
@@ -5754,7 +5757,7 @@ function ensureGlobalCoordinatorCwd(opts) {
5754
5757
  let orchId = opts?.orchestratorThreadId?.trim() || "";
5755
5758
  if (!orchId) {
5756
5759
  try {
5757
- const existing = (0, import_node_fs15.readFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), "utf8");
5760
+ const existing = (0, import_node_fs15.readFileSync)((0, import_node_path18.join)(dir, "AGENTS.md"), "utf8");
5758
5761
  const m = existing.match(
5759
5762
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
5760
5763
  );
@@ -5796,9 +5799,9 @@ function ensureGlobalCoordinatorCwd(opts) {
5796
5799
  "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."
5797
5800
  ].join("\n");
5798
5801
  try {
5799
- (0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "CLAUDE.md"), `${body}
5802
+ (0, import_node_fs15.writeFileSync)((0, import_node_path18.join)(dir, "CLAUDE.md"), `${body}
5800
5803
  `, "utf8");
5801
- (0, import_node_fs15.writeFileSync)((0, import_node_path17.join)(dir, "AGENTS.md"), `${body}
5804
+ (0, import_node_fs15.writeFileSync)((0, import_node_path18.join)(dir, "AGENTS.md"), `${body}
5802
5805
  `, "utf8");
5803
5806
  } catch {
5804
5807
  }
@@ -5830,12 +5833,12 @@ function coordinatorSystemPrompt(opts) {
5830
5833
  formatWorkspaceInventory(opts.workspaces)
5831
5834
  ].join("\n");
5832
5835
  }
5833
- var import_node_fs15, import_node_path17, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5836
+ var import_node_fs15, import_node_path18, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5834
5837
  var init_coordinator_prompt = __esm({
5835
5838
  "src/orchestrator/coordinator-prompt.ts"() {
5836
5839
  "use strict";
5837
5840
  import_node_fs15 = require("fs");
5838
- import_node_path17 = require("path");
5841
+ import_node_path18 = require("path");
5839
5842
  init_worktree();
5840
5843
  init_app_settings();
5841
5844
  init_paths();
@@ -6133,7 +6136,7 @@ var init_global_workspace = __esm({
6133
6136
 
6134
6137
  // src/brightsy/config.ts
6135
6138
  function brightsyConfigPath() {
6136
- return (0, import_node_path18.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
6139
+ return (0, import_node_path19.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
6137
6140
  }
6138
6141
  function loadBrightsyConfig() {
6139
6142
  const path = brightsyConfigPath();
@@ -6152,13 +6155,13 @@ function saveBrightsyConfig(cfg) {
6152
6155
  mode: 384
6153
6156
  });
6154
6157
  }
6155
- var import_node_fs16, import_node_os6, import_node_path18;
6158
+ var import_node_fs16, import_node_os6, import_node_path19;
6156
6159
  var init_config = __esm({
6157
6160
  "src/brightsy/config.ts"() {
6158
6161
  "use strict";
6159
6162
  import_node_fs16 = require("fs");
6160
6163
  import_node_os6 = require("os");
6161
- import_node_path18 = require("path");
6164
+ import_node_path19 = require("path");
6162
6165
  }
6163
6166
  });
6164
6167
 
@@ -6173,7 +6176,7 @@ var init_accounts = __esm({
6173
6176
 
6174
6177
  // src/brightsy/connected-teams.ts
6175
6178
  function storePath4() {
6176
- return (0, import_node_path19.join)(appDataDir(), "brightsy-teams.json");
6179
+ return (0, import_node_path20.join)(appDataDir(), "brightsy-teams.json");
6177
6180
  }
6178
6181
  function readStore4() {
6179
6182
  const path = storePath4();
@@ -6300,12 +6303,12 @@ function brightsyMcpServerName(slug) {
6300
6303
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
6301
6304
  return `brightsy_${cleaned || "team"}`;
6302
6305
  }
6303
- var import_node_fs17, import_node_path19;
6306
+ var import_node_fs17, import_node_path20;
6304
6307
  var init_connected_teams = __esm({
6305
6308
  "src/brightsy/connected-teams.ts"() {
6306
6309
  "use strict";
6307
6310
  import_node_fs17 = require("fs");
6308
- import_node_path19 = require("path");
6311
+ import_node_path20 = require("path");
6309
6312
  init_paths();
6310
6313
  init_accounts();
6311
6314
  init_config();
@@ -7088,6 +7091,30 @@ function applyAgentEvent(parts, event) {
7088
7091
  if (event.type === "tool_result") {
7089
7092
  const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
7090
7093
  const fromResult = parseDiffStat(event.content);
7094
+ if (event.partial) {
7095
+ if (existing < 0) {
7096
+ return [
7097
+ ...parts,
7098
+ {
7099
+ type: "tool",
7100
+ id: event.id,
7101
+ name: "tool",
7102
+ description: "tool",
7103
+ status: event.isError ? "error" : "running",
7104
+ result: event.content,
7105
+ ...event.parentId ? { parentId: event.parentId } : {}
7106
+ }
7107
+ ];
7108
+ }
7109
+ return parts.map((p, i) => {
7110
+ if (i !== existing || p.type !== "tool") return p;
7111
+ if (p.status === "done" || p.status === "error") return p;
7112
+ return {
7113
+ ...p,
7114
+ result: event.content ?? p.result
7115
+ };
7116
+ });
7117
+ }
7091
7118
  if (existing < 0) {
7092
7119
  return [
7093
7120
  ...parts,
@@ -7173,43 +7200,43 @@ function electronResourcesPath() {
7173
7200
  function packagedCursorRuntimeDir() {
7174
7201
  const resources = electronResourcesPath();
7175
7202
  if (!resources) return null;
7176
- const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
7177
- if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
7203
+ const dir = (0, import_node_path21.join)(resources, "cursor-runtime");
7204
+ if (!(0, import_node_fs19.existsSync)((0, import_node_path21.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
7178
7205
  return dir;
7179
7206
  }
7180
7207
  function packagedCursorRunnerPath() {
7181
7208
  const dir = packagedCursorRuntimeDir();
7182
- return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
7209
+ return dir ? (0, import_node_path21.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
7183
7210
  }
7184
7211
  function packagedMcpDir() {
7185
7212
  const resources = electronResourcesPath();
7186
7213
  if (!resources) return null;
7187
- const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
7188
- if (!(0, import_node_fs19.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
7214
+ const dir = (0, import_node_path21.join)(resources, "sideboard-mcp");
7215
+ if (!(0, import_node_fs19.existsSync)((0, import_node_path21.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
7189
7216
  return dir;
7190
7217
  }
7191
7218
  function packagedMcpStdioPath() {
7192
7219
  const dir = packagedMcpDir();
7193
- return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
7220
+ return dir ? (0, import_node_path21.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
7194
7221
  }
7195
7222
  function packagedBundledNodePath() {
7196
7223
  const resources = electronResourcesPath();
7197
7224
  if (!resources) return null;
7198
- const bin = (0, import_node_path20.join)(resources, "node", "bin", "node");
7225
+ const bin = (0, import_node_path21.join)(resources, "node", "bin", "node");
7199
7226
  if (!(0, import_node_fs19.existsSync)(bin)) return null;
7200
7227
  return bin;
7201
7228
  }
7202
7229
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
7203
7230
  const dir = packagedCursorRuntimeDir();
7204
7231
  if (!dir) return null;
7205
- return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
7232
+ return (0, import_node_path21.join)(dir, "node_modules", platformPkg, "bin", binName);
7206
7233
  }
7207
- var import_node_fs19, import_node_path20;
7234
+ var import_node_fs19, import_node_path21;
7208
7235
  var init_packaged_runtime = __esm({
7209
7236
  "src/agents/packaged-runtime.ts"() {
7210
7237
  "use strict";
7211
7238
  import_node_fs19 = require("fs");
7212
- import_node_path20 = require("path");
7239
+ import_node_path21 = require("path");
7213
7240
  }
7214
7241
  });
7215
7242
 
@@ -7292,28 +7319,28 @@ function versionDirNodeBins(root, toBin) {
7292
7319
  }
7293
7320
  function defaultNodeBinCandidates(home = (0, import_node_os7.homedir)()) {
7294
7321
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
7295
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path21.join)(prefix, "opt", `node@${major}`, "bin", "node"))
7322
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path22.join)(prefix, "opt", `node@${major}`, "bin", "node"))
7296
7323
  );
7297
7324
  return [
7298
7325
  ...kegs,
7299
7326
  "/opt/homebrew/bin/node",
7300
7327
  "/usr/local/bin/node",
7301
- (0, import_node_path21.join)(home, ".local/share/fnm/aliases/default/bin/node"),
7302
- (0, import_node_path21.join)(home, ".nvm/current/bin/node"),
7303
- (0, import_node_path21.join)(home, ".volta/bin/node"),
7304
- (0, import_node_path21.join)(home, ".asdf/shims/node"),
7305
- (0, import_node_path21.join)(home, ".local/share/mise/shims/node"),
7328
+ (0, import_node_path22.join)(home, ".local/share/fnm/aliases/default/bin/node"),
7329
+ (0, import_node_path22.join)(home, ".nvm/current/bin/node"),
7330
+ (0, import_node_path22.join)(home, ".volta/bin/node"),
7331
+ (0, import_node_path22.join)(home, ".asdf/shims/node"),
7332
+ (0, import_node_path22.join)(home, ".local/share/mise/shims/node"),
7306
7333
  ...versionDirNodeBins(
7307
- (0, import_node_path21.join)(home, ".nvm", "versions", "node"),
7308
- (name) => (0, import_node_path21.join)(home, ".nvm", "versions", "node", name, "bin", "node")
7334
+ (0, import_node_path22.join)(home, ".nvm", "versions", "node"),
7335
+ (name) => (0, import_node_path22.join)(home, ".nvm", "versions", "node", name, "bin", "node")
7309
7336
  ),
7310
7337
  ...versionDirNodeBins(
7311
- (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions"),
7312
- (name) => (0, import_node_path21.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
7338
+ (0, import_node_path22.join)(home, ".local/share/fnm", "node-versions"),
7339
+ (name) => (0, import_node_path22.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
7313
7340
  ),
7314
7341
  ...versionDirNodeBins(
7315
- (0, import_node_path21.join)(home, ".volta", "tools", "image", "node"),
7316
- (name) => (0, import_node_path21.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
7342
+ (0, import_node_path22.join)(home, ".volta", "tools", "image", "node"),
7343
+ (name) => (0, import_node_path22.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
7317
7344
  )
7318
7345
  ];
7319
7346
  }
@@ -7405,13 +7432,13 @@ async function resolveNodeLaunch(scriptPath) {
7405
7432
  env: { ELECTRON_RUN_AS_NODE: "1" }
7406
7433
  };
7407
7434
  }
7408
- var import_node_fs20, import_node_os7, import_node_path21, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
7435
+ var import_node_fs20, import_node_os7, import_node_path22, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
7409
7436
  var init_node_launch = __esm({
7410
7437
  "src/agents/node-launch.ts"() {
7411
7438
  "use strict";
7412
7439
  import_node_fs20 = require("fs");
7413
7440
  import_node_os7 = require("os");
7414
- import_node_path21 = require("path");
7441
+ import_node_path22 = require("path");
7415
7442
  init_nested_electron_env();
7416
7443
  init_run();
7417
7444
  init_packaged_runtime();
@@ -7504,13 +7531,13 @@ function corePackageDir() {
7504
7531
  try {
7505
7532
  const url = import_meta.url;
7506
7533
  if (typeof url === "string" && url.length > 0) {
7507
- return (0, import_node_path22.dirname)((0, import_node_url.fileURLToPath)(url));
7534
+ return (0, import_node_path23.dirname)((0, import_node_url.fileURLToPath)(url));
7508
7535
  }
7509
7536
  } catch {
7510
7537
  }
7511
7538
  try {
7512
- const req = (0, import_node_module.createRequire)((0, import_node_path22.join)(process.cwd(), "package.json"));
7513
- return (0, import_node_path22.dirname)(req.resolve("@sideboard-ai/core"));
7539
+ const req = (0, import_node_module.createRequire)((0, import_node_path23.join)(process.cwd(), "package.json"));
7540
+ return (0, import_node_path23.dirname)(req.resolve("@sideboard-ai/core"));
7514
7541
  } catch {
7515
7542
  return process.cwd();
7516
7543
  }
@@ -7523,18 +7550,18 @@ function findSideboardMcpJsEntry() {
7523
7550
  let dir = corePackageDir();
7524
7551
  for (let i = 0; i < 10; i++) {
7525
7552
  const candidates = [
7526
- (0, import_node_path22.join)(dir, "mcp/run-stdio.js"),
7527
- (0, import_node_path22.join)(dir, "mcp/run-stdio.cjs"),
7528
- (0, import_node_path22.join)(dir, "dist/mcp/run-stdio.js"),
7529
- (0, import_node_path22.join)(dir, "dist/mcp/run-stdio.cjs"),
7530
- (0, import_node_path22.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
7531
- (0, import_node_path22.join)(dir, "packages/cli/dist/index.js"),
7532
- (0, import_node_path22.join)(dir, "cli/dist/index.js")
7553
+ (0, import_node_path23.join)(dir, "mcp/run-stdio.js"),
7554
+ (0, import_node_path23.join)(dir, "mcp/run-stdio.cjs"),
7555
+ (0, import_node_path23.join)(dir, "dist/mcp/run-stdio.js"),
7556
+ (0, import_node_path23.join)(dir, "dist/mcp/run-stdio.cjs"),
7557
+ (0, import_node_path23.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
7558
+ (0, import_node_path23.join)(dir, "packages/cli/dist/index.js"),
7559
+ (0, import_node_path23.join)(dir, "cli/dist/index.js")
7533
7560
  ];
7534
7561
  for (const p of candidates) {
7535
7562
  if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
7536
7563
  }
7537
- const parent = (0, import_node_path22.dirname)(dir);
7564
+ const parent = (0, import_node_path23.dirname)(dir);
7538
7565
  if (parent === dir) break;
7539
7566
  dir = parent;
7540
7567
  }
@@ -7676,19 +7703,19 @@ function writeMcpServersConfig(servers) {
7676
7703
  ...env ? { env } : {}
7677
7704
  };
7678
7705
  }
7679
- const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path22.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7680
- const cfgPath = (0, import_node_path22.join)(dir, "mcp.json");
7706
+ const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path23.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7707
+ const cfgPath = (0, import_node_path23.join)(dir, "mcp.json");
7681
7708
  (0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7682
7709
  return cfgPath;
7683
7710
  }
7684
- var import_node_fs21, import_node_module, import_node_os8, import_node_path22, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
7711
+ var import_node_fs21, import_node_module, import_node_os8, import_node_path23, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
7685
7712
  var init_injected_mcp = __esm({
7686
7713
  "src/agents/injected-mcp.ts"() {
7687
7714
  "use strict";
7688
7715
  import_node_fs21 = require("fs");
7689
7716
  import_node_module = require("module");
7690
7717
  import_node_os8 = require("os");
7691
- import_node_path22 = require("path");
7718
+ import_node_path23 = require("path");
7692
7719
  import_node_url = require("url");
7693
7720
  init_run();
7694
7721
  init_config();
@@ -8290,8 +8317,8 @@ function usageFromCodex(usage) {
8290
8317
  }
8291
8318
  function codexConfigHasNetworkAccess() {
8292
8319
  const candidates = [
8293
- (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
8294
- (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
8320
+ (0, import_node_path24.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
8321
+ (0, import_node_path24.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
8295
8322
  ];
8296
8323
  for (const path of candidates) {
8297
8324
  if (!(0, import_node_fs23.existsSync)(path)) continue;
@@ -8327,7 +8354,7 @@ function asRecord2(value) {
8327
8354
  return void 0;
8328
8355
  }
8329
8356
  function codexLooksAuthenticated() {
8330
- const authPath = (0, import_node_path23.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
8357
+ const authPath = (0, import_node_path24.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
8331
8358
  if (!(0, import_node_fs23.existsSync)(authPath)) return false;
8332
8359
  try {
8333
8360
  return (0, import_node_fs23.statSync)(authPath).size > 2;
@@ -8335,13 +8362,13 @@ function codexLooksAuthenticated() {
8335
8362
  return false;
8336
8363
  }
8337
8364
  }
8338
- var import_node_fs23, import_node_os9, import_node_path23, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
8365
+ var import_node_fs23, import_node_os9, import_node_path24, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
8339
8366
  var init_codex = __esm({
8340
8367
  "src/agents/codex.ts"() {
8341
8368
  "use strict";
8342
8369
  import_node_fs23 = require("fs");
8343
8370
  import_node_os9 = require("os");
8344
- import_node_path23 = require("path");
8371
+ import_node_path24 = require("path");
8345
8372
  init_run();
8346
8373
  init_app_settings();
8347
8374
  init_global_workspace();
@@ -8506,13 +8533,22 @@ var init_codex = __esm({
8506
8533
  const events = [
8507
8534
  { type: "tool_use", id: item.id, name: "Bash", input }
8508
8535
  ];
8509
- if (type === "item.completed" || item.status === "completed" || item.status === "failed") {
8536
+ const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
8537
+ const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
8538
+ if (finished) {
8510
8539
  events.push({
8511
8540
  type: "tool_result",
8512
8541
  id: item.id,
8513
- content: item.aggregated_output,
8542
+ content: output,
8514
8543
  isError: item.status === "failed"
8515
8544
  });
8545
+ } else if (output) {
8546
+ events.push({
8547
+ type: "tool_result",
8548
+ id: item.id,
8549
+ content: output,
8550
+ partial: true
8551
+ });
8516
8552
  }
8517
8553
  return events.length === 1 ? events[0] : events;
8518
8554
  }
@@ -8728,7 +8764,7 @@ function cursorSdkMessageToEvents(msg) {
8728
8764
  if (msg.type === "tool_call" && msg.call_id && msg.name) {
8729
8765
  const normalized = normalizeCursorToolCall(msg.name, msg.args);
8730
8766
  if (msg.status === "running") {
8731
- return [
8767
+ const events = [
8732
8768
  {
8733
8769
  type: "tool_use",
8734
8770
  id: msg.call_id,
@@ -8736,6 +8772,16 @@ function cursorSdkMessageToEvents(msg) {
8736
8772
  input: normalized.input
8737
8773
  }
8738
8774
  ];
8775
+ const live = unwrapCursorToolResult(msg.result);
8776
+ if (live) {
8777
+ events.push({
8778
+ type: "tool_result",
8779
+ id: msg.call_id,
8780
+ content: live,
8781
+ partial: true
8782
+ });
8783
+ }
8784
+ return events;
8739
8785
  }
8740
8786
  if (msg.status === "completed" || msg.status === "error") {
8741
8787
  return [
@@ -8802,7 +8848,7 @@ function platformRipgrepPackage() {
8802
8848
  }
8803
8849
  function usableRipgrepPath(candidate) {
8804
8850
  const raw = candidate?.trim();
8805
- if (!raw || !(0, import_node_path24.isAbsolute)(raw)) return null;
8851
+ if (!raw || !(0, import_node_path25.isAbsolute)(raw)) return null;
8806
8852
  const readable = nodeReadableScriptPath(raw);
8807
8853
  if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
8808
8854
  return readable;
@@ -8811,12 +8857,12 @@ function walkForBundledRipgrep(startFile) {
8811
8857
  if (!startFile) return null;
8812
8858
  const pkg = platformRipgrepPackage();
8813
8859
  const name = rgBinaryName();
8814
- let dir = (0, import_node_path24.dirname)((0, import_node_path24.resolve)(startFile));
8815
- const root = (0, import_node_path24.parse)(dir).root;
8860
+ let dir = (0, import_node_path25.dirname)((0, import_node_path25.resolve)(startFile));
8861
+ const root = (0, import_node_path25.parse)(dir).root;
8816
8862
  while (dir !== root) {
8817
- const hit = usableRipgrepPath((0, import_node_path24.join)(dir, "node_modules", pkg, "bin", name));
8863
+ const hit = usableRipgrepPath((0, import_node_path25.join)(dir, "node_modules", pkg, "bin", name));
8818
8864
  if (hit) return hit;
8819
- const next = (0, import_node_path24.dirname)(dir);
8865
+ const next = (0, import_node_path25.dirname)(dir);
8820
8866
  if (next === dir) break;
8821
8867
  dir = next;
8822
8868
  }
@@ -8826,7 +8872,7 @@ function requireResolveBundledRipgrep(fromFile) {
8826
8872
  try {
8827
8873
  const req = (0, import_node_module2.createRequire)(fromFile);
8828
8874
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
8829
- return usableRipgrepPath((0, import_node_path24.join)((0, import_node_path24.dirname)(pkgJson), "bin", rgBinaryName()));
8875
+ return usableRipgrepPath((0, import_node_path25.join)((0, import_node_path25.dirname)(pkgJson), "bin", rgBinaryName()));
8830
8876
  } catch {
8831
8877
  return null;
8832
8878
  }
@@ -8848,13 +8894,13 @@ function cursorRipgrepEnv(opts) {
8848
8894
  const path = resolveCursorRipgrepPath(opts);
8849
8895
  return path ? { [RIPGREP_ENV]: path } : {};
8850
8896
  }
8851
- var import_node_fs24, import_node_module2, import_node_path24, RIPGREP_ENV;
8897
+ var import_node_fs24, import_node_module2, import_node_path25, RIPGREP_ENV;
8852
8898
  var init_cursor_ripgrep = __esm({
8853
8899
  "src/agents/cursor-ripgrep.ts"() {
8854
8900
  "use strict";
8855
8901
  import_node_fs24 = require("fs");
8856
8902
  import_node_module2 = require("module");
8857
- import_node_path24 = require("path");
8903
+ import_node_path25 = require("path");
8858
8904
  init_node_launch();
8859
8905
  init_packaged_runtime();
8860
8906
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -8900,11 +8946,11 @@ function entryDir() {
8900
8946
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
8901
8947
  if (cjsDir) return cjsDir;
8902
8948
  try {
8903
- return (0, import_node_path25.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
8949
+ return (0, import_node_path26.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
8904
8950
  } catch {
8905
8951
  try {
8906
8952
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
8907
- return (0, import_node_path25.dirname)(req.resolve("@sideboard-ai/core"));
8953
+ return (0, import_node_path26.dirname)(req.resolve("@sideboard-ai/core"));
8908
8954
  } catch {
8909
8955
  return process.cwd();
8910
8956
  }
@@ -8915,27 +8961,27 @@ function cursorRunnerPath() {
8915
8961
  if (packaged) return packaged;
8916
8962
  const root = entryDir();
8917
8963
  const candidates = [
8918
- (0, import_node_path25.join)(root, "agents", "cursor-runner.js"),
8919
- (0, import_node_path25.join)(root, "agents", "cursor-runner.cjs"),
8964
+ (0, import_node_path26.join)(root, "agents", "cursor-runner.js"),
8965
+ (0, import_node_path26.join)(root, "agents", "cursor-runner.cjs"),
8920
8966
  // If somehow resolved from package root instead of dist/
8921
- (0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.js"),
8922
- (0, import_node_path25.join)(root, "dist", "agents", "cursor-runner.cjs"),
8967
+ (0, import_node_path26.join)(root, "dist", "agents", "cursor-runner.js"),
8968
+ (0, import_node_path26.join)(root, "dist", "agents", "cursor-runner.cjs"),
8923
8969
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
8924
- (0, import_node_path25.join)(root, "cursor-runner.ts"),
8925
- (0, import_node_path25.join)(root, "src", "agents", "cursor-runner.ts")
8970
+ (0, import_node_path26.join)(root, "cursor-runner.ts"),
8971
+ (0, import_node_path26.join)(root, "src", "agents", "cursor-runner.ts")
8926
8972
  ];
8927
8973
  for (const candidate of candidates) {
8928
8974
  if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
8929
8975
  }
8930
8976
  return candidates[0];
8931
8977
  }
8932
- var import_node_fs25, import_node_module3, import_node_path25, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8978
+ var import_node_fs25, import_node_module3, import_node_path26, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8933
8979
  var init_cursor = __esm({
8934
8980
  "src/agents/cursor.ts"() {
8935
8981
  "use strict";
8936
8982
  import_node_fs25 = require("fs");
8937
8983
  import_node_module3 = require("module");
8938
- import_node_path25 = require("path");
8984
+ import_node_path26 = require("path");
8939
8985
  import_node_url2 = require("url");
8940
8986
  import_sdk = require("@cursor/sdk");
8941
8987
  init_run();
@@ -8994,6 +9040,7 @@ var init_cursor = __esm({
8994
9040
  const req = {
8995
9041
  prompt,
8996
9042
  cwd: thread.worktreePath,
9043
+ threadId: thread.id,
8997
9044
  agentId,
8998
9045
  model: thread.model,
8999
9046
  effort: thread.effort,
@@ -9253,13 +9300,16 @@ var init_opencode = __esm({
9253
9300
  );
9254
9301
  const events = [{ type: "tool_use", id, name, input }];
9255
9302
  const output = state?.output;
9256
- if (output != null || state?.status === "completed" || state?.status === "error") {
9303
+ const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
9304
+ const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
9305
+ if (output != null || finished) {
9257
9306
  const content = typeof output === "string" ? output : output != null ? JSON.stringify(output) : formatUnknownDetail(state?.error) || void 0;
9258
9307
  events.push({
9259
9308
  type: "tool_result",
9260
9309
  id,
9261
9310
  content,
9262
- isError: state?.status === "error" || state?.status === "failed"
9311
+ isError: state?.status === "error" || state?.status === "failed",
9312
+ ...running && !finished ? { partial: true } : {}
9263
9313
  });
9264
9314
  }
9265
9315
  return events.length === 1 ? events[0] : events;
@@ -9294,14 +9344,17 @@ var init_opencode = __esm({
9294
9344
  withEventParentId({ type: "tool_use", id, name, input }, parentId)
9295
9345
  ];
9296
9346
  const output = state?.output ?? part.output;
9297
- if (output != null || state?.status === "completed" || state?.status === "error") {
9347
+ const finished = state?.status === "completed" || state?.status === "error" || state?.status === "failed";
9348
+ const running = state?.status === "running" || state?.status === "in_progress" || state?.status === "pending";
9349
+ if (output != null || finished) {
9298
9350
  nested.push(
9299
9351
  withEventParentId(
9300
9352
  {
9301
9353
  type: "tool_result",
9302
9354
  id,
9303
9355
  content: typeof output === "string" ? output : output != null ? JSON.stringify(output) : void 0,
9304
- isError: state?.status === "error" || state?.status === "failed"
9356
+ isError: state?.status === "error" || state?.status === "failed",
9357
+ ...running && !finished ? { partial: true } : {}
9305
9358
  },
9306
9359
  parentId
9307
9360
  )
@@ -10872,12 +10925,12 @@ function readTextIfPresent(abs) {
10872
10925
  }
10873
10926
  }
10874
10927
  function readLocalGuidelines(worktreePath) {
10875
- const localAbs = (0, import_node_path26.join)(worktreePath, REVIEW_REQUEST_PATH);
10928
+ const localAbs = (0, import_node_path27.join)(worktreePath, REVIEW_REQUEST_PATH);
10876
10929
  const localContent = readTextIfPresent(localAbs);
10877
10930
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
10878
10931
  return { path: REVIEW_REQUEST_PATH, content: localContent };
10879
10932
  }
10880
- const legacyAbs = (0, import_node_path26.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10933
+ const legacyAbs = (0, import_node_path27.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10881
10934
  const legacyContent = readTextIfPresent(legacyAbs);
10882
10935
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
10883
10936
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -10893,20 +10946,20 @@ function skillGuidelines(content, source) {
10893
10946
  };
10894
10947
  }
10895
10948
  function ensureReviewSkillFile(worktreePath) {
10896
- const abs = (0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH);
10949
+ const abs = (0, import_node_path27.join)(worktreePath, REVIEW_SKILL_PATH);
10897
10950
  const existing = readTextIfPresent(abs);
10898
10951
  if (existing) {
10899
10952
  return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
10900
10953
  }
10901
- const fromRepo = readTextIfPresent((0, import_node_path26.join)(worktreePath, REPO_REVIEW_PATH));
10954
+ const fromRepo = readTextIfPresent((0, import_node_path27.join)(worktreePath, REPO_REVIEW_PATH));
10902
10955
  const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
10903
10956
  const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
10904
- (0, import_node_fs27.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
10957
+ (0, import_node_fs27.mkdirSync)((0, import_node_path27.dirname)(abs), { recursive: true });
10905
10958
  (0, import_node_fs27.writeFileSync)(abs, content, "utf8");
10906
10959
  return { path: REVIEW_SKILL_PATH, content, wrote: true };
10907
10960
  }
10908
10961
  function resolveReviewGuidelines(worktreePath) {
10909
- const skillContent = readTextIfPresent((0, import_node_path26.join)(worktreePath, REVIEW_SKILL_PATH));
10962
+ const skillContent = readTextIfPresent((0, import_node_path27.join)(worktreePath, REVIEW_SKILL_PATH));
10910
10963
  if (skillContent) return skillGuidelines(skillContent, "skill");
10911
10964
  const local = readLocalGuidelines(worktreePath);
10912
10965
  if (local) {
@@ -10956,13 +11009,13 @@ async function requestReview(threadRef, send) {
10956
11009
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
10957
11010
  return { tab: started, from };
10958
11011
  }
10959
- var import_node_crypto5, import_node_fs27, import_node_path26, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
11012
+ var import_node_crypto5, import_node_fs27, import_node_path27, REPO_REVIEW_PATH, REPO_REVIEW_NAME, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
10960
11013
  var init_request_review = __esm({
10961
11014
  "src/review/request-review.ts"() {
10962
11015
  "use strict";
10963
11016
  import_node_crypto5 = require("crypto");
10964
11017
  import_node_fs27 = require("fs");
10965
- import_node_path26 = require("path");
11018
+ import_node_path27 = require("path");
10966
11019
  init_global_workspace();
10967
11020
  init_chat_tabs();
10968
11021
  init_thread_store();
@@ -10987,7 +11040,7 @@ function matchSimpleGlob(pattern, name) {
10987
11040
  return new RegExp(`^${escaped}$`).test(name);
10988
11041
  }
10989
11042
  function readWorktreeInclude(repoPath) {
10990
- const path = (0, import_node_path27.join)(repoPath, ".worktreeinclude");
11043
+ const path = (0, import_node_path28.join)(repoPath, ".worktreeinclude");
10991
11044
  if (!(0, import_node_fs28.existsSync)(path)) return [];
10992
11045
  return (0, import_node_fs28.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
10993
11046
  }
@@ -11002,7 +11055,7 @@ function resolveFilesToCopy(repoPath) {
11002
11055
  for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
11003
11056
  if (!entry.isFile()) continue;
11004
11057
  for (const glob of settings.fileIncludeGlobs) {
11005
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path27.basename)(glob), entry.name)) {
11058
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path28.basename)(glob), entry.name)) {
11006
11059
  matched.push(entry.name);
11007
11060
  break;
11008
11061
  }
@@ -11028,10 +11081,10 @@ function copyConfiguredFiles(repoPath, worktreePath) {
11028
11081
  const patterns = resolveFilesToCopy(repoPath);
11029
11082
  const copied = [];
11030
11083
  for (const rel of patterns) {
11031
- const src = (0, import_node_path27.join)(repoPath, rel);
11084
+ const src = (0, import_node_path28.join)(repoPath, rel);
11032
11085
  if (!(0, import_node_fs28.existsSync)(src)) continue;
11033
- const dest = (0, import_node_path27.join)(worktreePath, rel);
11034
- (0, import_node_fs28.mkdirSync)((0, import_node_path27.dirname)(dest), { recursive: true });
11086
+ const dest = (0, import_node_path28.join)(worktreePath, rel);
11087
+ (0, import_node_fs28.mkdirSync)((0, import_node_path28.dirname)(dest), { recursive: true });
11035
11088
  (0, import_node_fs28.copyFileSync)(src, dest);
11036
11089
  copied.push(rel);
11037
11090
  }
@@ -11067,7 +11120,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
11067
11120
  const env = stripNestedElectronEnv({
11068
11121
  ...baseEnv ?? process.env
11069
11122
  });
11070
- const name = opts.workspaceName ?? (0, import_node_path27.basename)(opts.worktreePath);
11123
+ const name = opts.workspaceName ?? (0, import_node_path28.basename)(opts.worktreePath);
11071
11124
  const ports = opts.ports ?? [];
11072
11125
  const primary = ports[0];
11073
11126
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -11328,13 +11381,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
11328
11381
  done: handle.done
11329
11382
  };
11330
11383
  }
11331
- var import_node_fs28, import_node_net, import_node_path27, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
11384
+ var import_node_fs28, import_node_net, import_node_path28, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
11332
11385
  var init_conductor = __esm({
11333
11386
  "src/hook/conductor.ts"() {
11334
11387
  "use strict";
11335
11388
  import_node_fs28 = require("fs");
11336
11389
  import_node_net = require("net");
11337
- import_node_path27 = require("path");
11390
+ import_node_path28 = require("path");
11338
11391
  import_execa4 = require("execa");
11339
11392
  import_node_readline3 = require("readline");
11340
11393
  init_settings();
@@ -11396,9 +11449,9 @@ async function findOrphanWorktrees(repoPaths) {
11396
11449
  if ((0, import_node_fs29.existsSync)(root)) {
11397
11450
  for (const entry of (0, import_node_fs29.readdirSync)(root, { withFileTypes: true })) {
11398
11451
  if (!entry.isDirectory()) continue;
11399
- const path = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
11452
+ const path = (0, import_node_path29.join)(root, entry.name).replace(/\/$/, "");
11400
11453
  if (known.has(path) || seen.has(path)) continue;
11401
- if (!(0, import_node_fs29.existsSync)((0, import_node_path28.join)(path, ".git"))) continue;
11454
+ if (!(0, import_node_fs29.existsSync)((0, import_node_path29.join)(path, ".git"))) continue;
11402
11455
  seen.add(path);
11403
11456
  let mtimeMs = 0;
11404
11457
  try {
@@ -11454,12 +11507,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
11454
11507
  const elapsed = Date.now() - Date.parse(last);
11455
11508
  return elapsed >= intervalHours * 36e5;
11456
11509
  }
11457
- var import_node_fs29, import_node_path28;
11510
+ var import_node_fs29, import_node_path29;
11458
11511
  var init_orphan_cleanup = __esm({
11459
11512
  "src/git/orphan-cleanup.ts"() {
11460
11513
  "use strict";
11461
11514
  import_node_fs29 = require("fs");
11462
- import_node_path28 = require("path");
11515
+ import_node_path29 = require("path");
11463
11516
  init_worktree();
11464
11517
  init_thread_store();
11465
11518
  init_paths();
@@ -11566,10 +11619,10 @@ __export(workspaces_exports, {
11566
11619
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
11567
11620
  });
11568
11621
  function workspacesFile() {
11569
- return (0, import_node_path29.join)(appDataDir(), "workspaces.json");
11622
+ return (0, import_node_path30.join)(appDataDir(), "workspaces.json");
11570
11623
  }
11571
11624
  function removedWorkspacesFile() {
11572
- return (0, import_node_path29.join)(appDataDir(), "removed-workspaces.json");
11625
+ return (0, import_node_path30.join)(appDataDir(), "removed-workspaces.json");
11573
11626
  }
11574
11627
  function readAll() {
11575
11628
  const path = workspacesFile();
@@ -11628,7 +11681,7 @@ async function addWorkspace(repoPath) {
11628
11681
  if (existing) return existing;
11629
11682
  const next = {
11630
11683
  path: root,
11631
- name: (0, import_node_path29.basename)(root),
11684
+ name: (0, import_node_path30.basename)(root),
11632
11685
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
11633
11686
  };
11634
11687
  writeAll([...current, next]);
@@ -11653,7 +11706,7 @@ function syncWorkspacesFromThreads(repoPaths) {
11653
11706
  if (!(0, import_node_fs30.existsSync)(path)) continue;
11654
11707
  const ws = {
11655
11708
  path,
11656
- name: (0, import_node_path29.basename)(path),
11709
+ name: (0, import_node_path30.basename)(path),
11657
11710
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
11658
11711
  };
11659
11712
  byPath.set(path, ws);
@@ -11663,12 +11716,12 @@ function syncWorkspacesFromThreads(repoPaths) {
11663
11716
  if (dirty) writeAll(next);
11664
11717
  return next.sort((a, b) => a.name.localeCompare(b.name));
11665
11718
  }
11666
- var import_node_fs30, import_node_path29;
11719
+ var import_node_fs30, import_node_path30;
11667
11720
  var init_workspaces2 = __esm({
11668
11721
  "src/store/workspaces.ts"() {
11669
11722
  "use strict";
11670
11723
  import_node_fs30 = require("fs");
11671
- import_node_path29 = require("path");
11724
+ import_node_path30 = require("path");
11672
11725
  init_paths();
11673
11726
  init_global_workspace();
11674
11727
  init_worktree();
@@ -11681,11 +11734,11 @@ async function cloneRepoIntoSideboard(opts) {
11681
11734
  if (!url) throw new Error("Clone URL is required");
11682
11735
  let name = opts.name?.trim();
11683
11736
  if (!name) {
11684
- const leaf = (0, import_node_path30.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
11737
+ const leaf = (0, import_node_path31.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
11685
11738
  name = leaf || "repo";
11686
11739
  }
11687
11740
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
11688
- const dest = (0, import_node_path30.join)(sideboardReposDir(), name);
11741
+ const dest = (0, import_node_path31.join)(sideboardReposDir(), name);
11689
11742
  if ((0, import_node_fs31.existsSync)(dest)) {
11690
11743
  const repoPath2 = await resolveRepoRoot(dest);
11691
11744
  const workspace2 = await ensureWorkspace(repoPath2);
@@ -11701,12 +11754,12 @@ async function cloneRepoIntoSideboard(opts) {
11701
11754
  const workspace = await ensureWorkspace(repoPath);
11702
11755
  return { repoPath, workspace };
11703
11756
  }
11704
- var import_node_fs31, import_node_path30, import_execa6;
11757
+ var import_node_fs31, import_node_path31, import_execa6;
11705
11758
  var init_clone_repo = __esm({
11706
11759
  "src/git/clone-repo.ts"() {
11707
11760
  "use strict";
11708
11761
  import_node_fs31 = require("fs");
11709
- import_node_path30 = require("path");
11762
+ import_node_path31 = require("path");
11710
11763
  import_execa6 = require("execa");
11711
11764
  init_paths();
11712
11765
  init_workspaces2();
@@ -11716,7 +11769,7 @@ var init_clone_repo = __esm({
11716
11769
 
11717
11770
  // src/store/desktop-host.ts
11718
11771
  function desktopHostPidPath() {
11719
- return (0, import_node_path31.join)(appDataDir(), "desktop-host.pid");
11772
+ return (0, import_node_path32.join)(appDataDir(), "desktop-host.pid");
11720
11773
  }
11721
11774
  function readDesktopHostPid() {
11722
11775
  try {
@@ -11746,12 +11799,12 @@ function thisProcessShouldDrainAgentQueues() {
11746
11799
  if (isThisProcessDesktopHost()) return true;
11747
11800
  return !isDesktopHostAlive();
11748
11801
  }
11749
- var import_node_fs32, import_node_path31;
11802
+ var import_node_fs32, import_node_path32;
11750
11803
  var init_desktop_host = __esm({
11751
11804
  "src/store/desktop-host.ts"() {
11752
11805
  "use strict";
11753
11806
  import_node_fs32 = require("fs");
11754
- import_node_path31 = require("path");
11807
+ import_node_path32 = require("path");
11755
11808
  init_paths();
11756
11809
  }
11757
11810
  });
@@ -12021,7 +12074,7 @@ function noteTurnLiveEvent(threadId, event) {
12021
12074
  buffers.delete(threadId);
12022
12075
  return;
12023
12076
  }
12024
- const immediate = event.type === "tool_use" || event.type === "tool_result";
12077
+ const immediate = event.type === "tool_use" || event.type === "tool_result" && !event.partial;
12025
12078
  if (immediate) flush(threadId);
12026
12079
  else scheduleFlush(threadId);
12027
12080
  }
@@ -12073,6 +12126,27 @@ var init_turn_live = __esm({
12073
12126
  }
12074
12127
  });
12075
12128
 
12129
+ // src/orchestrator/reconcile-heal.ts
12130
+ function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
12131
+ if (SKIP.has(eventType)) return false;
12132
+ if (lastCheckAt != null && now - lastCheckAt < RECONCILE_HEAL_MIN_MS) return false;
12133
+ return true;
12134
+ }
12135
+ var RECONCILE_HEAL_MIN_MS, SKIP;
12136
+ var init_reconcile_heal = __esm({
12137
+ "src/orchestrator/reconcile-heal.ts"() {
12138
+ "use strict";
12139
+ RECONCILE_HEAL_MIN_MS = 2e3;
12140
+ SKIP = /* @__PURE__ */ new Set([
12141
+ "stdout",
12142
+ "thinking",
12143
+ "usage",
12144
+ "stderr",
12145
+ "tool_result"
12146
+ ]);
12147
+ }
12148
+ });
12149
+
12076
12150
  // src/threads/fork-worktree.ts
12077
12151
  function requireThread2(idOrRef) {
12078
12152
  const thread = findThreadByRef(idOrRef) ?? null;
@@ -12243,7 +12317,7 @@ var init_quota_failover = __esm({
12243
12317
  // src/threads/adopt.ts
12244
12318
  function thisModuleFile() {
12245
12319
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
12246
- return cjsFile || process.argv[1] || (0, import_node_path32.join)(process.cwd(), "package.json");
12320
+ return cjsFile || process.argv[1] || (0, import_node_path33.join)(process.cwd(), "package.json");
12247
12321
  }
12248
12322
  function openReadonlySqlite(file) {
12249
12323
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -12271,7 +12345,7 @@ function resolveConductorCursorAgentId(workspacePath) {
12271
12345
  return null;
12272
12346
  }
12273
12347
  for (const hash of hashes) {
12274
- const agentsFile = (0, import_node_path32.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
12348
+ const agentsFile = (0, import_node_path33.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
12275
12349
  if (!(0, import_node_fs35.existsSync)(agentsFile)) continue;
12276
12350
  let text4;
12277
12351
  try {
@@ -12326,8 +12400,8 @@ function listConductorWorkspaces() {
12326
12400
  if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
12327
12401
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
12328
12402
  }
12329
- const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12330
- const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
12403
+ const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path33.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12404
+ const snapshot = (0, import_node_path33.join)(tmp, "conductor.db");
12331
12405
  try {
12332
12406
  (0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
12333
12407
  for (const suffix of ["-wal", "-shm"]) {
@@ -12417,8 +12491,8 @@ function importConductorWorkspace(workspaceId) {
12417
12491
  if (!(0, import_node_fs35.existsSync)(CONDUCTOR_DB)) {
12418
12492
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
12419
12493
  }
12420
- const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path32.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12421
- const snapshot = (0, import_node_path32.join)(tmp, "conductor.db");
12494
+ const tmp = (0, import_node_fs35.mkdtempSync)((0, import_node_path33.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
12495
+ const snapshot = (0, import_node_path33.join)(tmp, "conductor.db");
12422
12496
  try {
12423
12497
  (0, import_node_fs35.copyFileSync)(CONDUCTOR_DB, snapshot);
12424
12498
  for (const suffix of ["-wal", "-shm"]) {
@@ -12512,25 +12586,25 @@ function importConductorWorkspace(workspaceId) {
12512
12586
  async function importConductorWorkspaceAsync(workspaceId) {
12513
12587
  return importConductorWorkspace(workspaceId);
12514
12588
  }
12515
- var import_node_child_process3, import_node_fs35, import_node_os10, import_node_path32, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
12589
+ var import_node_child_process3, import_node_fs35, import_node_os10, import_node_path33, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
12516
12590
  var init_adopt = __esm({
12517
12591
  "src/threads/adopt.ts"() {
12518
12592
  "use strict";
12519
12593
  import_node_child_process3 = require("child_process");
12520
12594
  import_node_fs35 = require("fs");
12521
12595
  import_node_os10 = require("os");
12522
- import_node_path32 = require("path");
12596
+ import_node_path33 = require("path");
12523
12597
  import_node_module4 = require("module");
12524
12598
  init_worktree();
12525
12599
  init_thread_store();
12526
- CONDUCTOR_APP_SUPPORT = (0, import_node_path32.join)(
12600
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path33.join)(
12527
12601
  process.env.HOME ?? "",
12528
12602
  "Library",
12529
12603
  "Application Support",
12530
12604
  "com.conductor.app"
12531
12605
  );
12532
- CONDUCTOR_DB = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
12533
- CURSOR_SDK_STORE = (0, import_node_path32.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
12606
+ CONDUCTOR_DB = (0, import_node_path33.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
12607
+ CURSOR_SDK_STORE = (0, import_node_path33.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
12534
12608
  }
12535
12609
  });
12536
12610
 
@@ -12975,7 +13049,7 @@ new file mode 100644
12975
13049
  };
12976
13050
  }
12977
13051
  async function untrackedPatch(worktreePath, path, maxHunk) {
12978
- const abs = (0, import_node_path33.join)(worktreePath, path);
13052
+ const abs = (0, import_node_path34.join)(worktreePath, path);
12979
13053
  try {
12980
13054
  const st = (0, import_node_fs37.statSync)(abs);
12981
13055
  if (st.isFile() && st.size > maxHunk) {
@@ -13468,7 +13542,7 @@ function isImageRelativePath(relativePath) {
13468
13542
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13469
13543
  assertSafeRelativePath(relativePath);
13470
13544
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
13471
- const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13545
+ const abs = (0, import_node_path34.join)(worktreePath, relativePath);
13472
13546
  const st = (0, import_node_fs37.statSync)(abs);
13473
13547
  if (!st.isFile()) {
13474
13548
  throw new Error(`Not a file: ${relativePath}`);
@@ -13488,7 +13562,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
13488
13562
  function readWorktreeFile(worktreePath, relativePath, opts) {
13489
13563
  assertSafeRelativePath(relativePath);
13490
13564
  const maxBytes = opts?.maxBytes ?? 2e5;
13491
- const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13565
+ const abs = (0, import_node_path34.join)(worktreePath, relativePath);
13492
13566
  const st = (0, import_node_fs37.statSync)(abs);
13493
13567
  if (!st.isFile()) {
13494
13568
  throw new Error(`Not a file: ${relativePath}`);
@@ -13536,8 +13610,8 @@ function assertSafeRelativePath(relativePath) {
13536
13610
  }
13537
13611
  function writeWorktreeFile(worktreePath, relativePath, content) {
13538
13612
  assertSafeRelativePath(relativePath);
13539
- const abs = (0, import_node_path33.join)(worktreePath, relativePath);
13540
- (0, import_node_fs37.mkdirSync)((0, import_node_path33.dirname)(abs), { recursive: true });
13613
+ const abs = (0, import_node_path34.join)(worktreePath, relativePath);
13614
+ (0, import_node_fs37.mkdirSync)((0, import_node_path34.dirname)(abs), { recursive: true });
13541
13615
  (0, import_node_fs37.writeFileSync)(abs, content, "utf8");
13542
13616
  return { path: relativePath };
13543
13617
  }
@@ -13555,12 +13629,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
13555
13629
  truncated: full.files.length > maxFiles
13556
13630
  };
13557
13631
  }
13558
- var import_node_fs37, import_node_path33, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
13632
+ var import_node_fs37, import_node_path34, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS, DEFAULT_UPLOAD_MAX_BYTES;
13559
13633
  var init_diff = __esm({
13560
13634
  "src/diff/diff.ts"() {
13561
13635
  "use strict";
13562
13636
  import_node_fs37 = require("fs");
13563
- import_node_path33 = require("path");
13637
+ import_node_path34 = require("path");
13564
13638
  init_run();
13565
13639
  init_worktree();
13566
13640
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -13756,7 +13830,7 @@ function scanSkillsDir(dir, source, out) {
13756
13830
  }
13757
13831
  for (const entry of entries) {
13758
13832
  if (entry.startsWith(".")) continue;
13759
- const skillMd = (0, import_node_path34.join)(dir, entry, "SKILL.md");
13833
+ const skillMd = (0, import_node_path35.join)(dir, entry, "SKILL.md");
13760
13834
  if (!(0, import_node_fs38.existsSync)(skillMd)) continue;
13761
13835
  try {
13762
13836
  if (!(0, import_node_fs38.statSync)(skillMd).isFile()) continue;
@@ -13778,12 +13852,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
13778
13852
  return;
13779
13853
  }
13780
13854
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
13781
- const skill = readSkill((0, import_node_path34.join)(dir, "SKILL.md"), "cli");
13855
+ const skill = readSkill((0, import_node_path35.join)(dir, "SKILL.md"), "cli");
13782
13856
  if (skill) out.push(skill);
13783
13857
  }
13784
13858
  for (const entry of entries) {
13785
13859
  if (entry === "node_modules" || entry === ".git") continue;
13786
- const full = (0, import_node_path34.join)(dir, entry);
13860
+ const full = (0, import_node_path35.join)(dir, entry);
13787
13861
  try {
13788
13862
  if (!(0, import_node_fs38.statSync)(full).isDirectory()) continue;
13789
13863
  } catch {
@@ -13803,17 +13877,17 @@ function discoverSkills(worktreePath) {
13803
13877
  const home = (0, import_node_os11.homedir)();
13804
13878
  const collected = [];
13805
13879
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
13806
- scanSkillsDir((0, import_node_path34.join)(worktreePath, rel), "workspace", collected);
13880
+ scanSkillsDir((0, import_node_path35.join)(worktreePath, rel), "workspace", collected);
13807
13881
  }
13808
13882
  for (const abs of [
13809
- (0, import_node_path34.join)(home, ".claude/skills"),
13810
- (0, import_node_path34.join)(home, ".cursor/skills"),
13811
- (0, import_node_path34.join)(home, ".sideboard/skills"),
13812
- (0, import_node_path34.join)(home, ".brightsy/skills")
13883
+ (0, import_node_path35.join)(home, ".claude/skills"),
13884
+ (0, import_node_path35.join)(home, ".cursor/skills"),
13885
+ (0, import_node_path35.join)(home, ".sideboard/skills"),
13886
+ (0, import_node_path35.join)(home, ".brightsy/skills")
13813
13887
  ]) {
13814
13888
  scanSkillsDir(abs, "user", collected);
13815
13889
  }
13816
- scanClaudePluginSkills((0, import_node_path34.join)(home, ".claude/plugins"), collected);
13890
+ scanClaudePluginSkills((0, import_node_path35.join)(home, ".claude/plugins"), collected);
13817
13891
  const rank = { workspace: 0, user: 1, cli: 2 };
13818
13892
  const byCommand = /* @__PURE__ */ new Map();
13819
13893
  for (const skill of collected) {
@@ -13839,13 +13913,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
13839
13913
 
13840
13914
  \u2026(truncated)` : raw;
13841
13915
  }
13842
- var import_node_fs38, import_node_os11, import_node_path34;
13916
+ var import_node_fs38, import_node_os11, import_node_path35;
13843
13917
  var init_discover = __esm({
13844
13918
  "src/skills/discover.ts"() {
13845
13919
  "use strict";
13846
13920
  import_node_fs38 = require("fs");
13847
13921
  import_node_os11 = require("os");
13848
- import_node_path34 = require("path");
13922
+ import_node_path35 = require("path");
13849
13923
  }
13850
13924
  });
13851
13925
 
@@ -13936,7 +14010,7 @@ var init_expand = __esm({
13936
14010
 
13937
14011
  // src/composer/stage-files.ts
13938
14012
  function fileExtension(filePath) {
13939
- const base = (0, import_node_path35.basename)(filePath).toLowerCase();
14013
+ const base = (0, import_node_path36.basename)(filePath).toLowerCase();
13940
14014
  return base.includes(".") ? base.split(".").pop() || "" : "";
13941
14015
  }
13942
14016
  function isImageFilePath(filePath) {
@@ -13946,9 +14020,9 @@ function imageMimeType(filePath) {
13946
14020
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
13947
14021
  }
13948
14022
  function ensureAttachmentsDir(worktreePath) {
13949
- const dir = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR);
14023
+ const dir = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR);
13950
14024
  (0, import_node_fs39.mkdirSync)(dir, { recursive: true });
13951
- const gi = (0, import_node_path35.join)(dir, ".gitignore");
14025
+ const gi = (0, import_node_path36.join)(dir, ".gitignore");
13952
14026
  if (!(0, import_node_fs39.existsSync)(gi)) {
13953
14027
  (0, import_node_fs39.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
13954
14028
  }
@@ -13956,12 +14030,12 @@ function ensureAttachmentsDir(worktreePath) {
13956
14030
  }
13957
14031
  function uniqueAttachmentName(dir, originalName) {
13958
14032
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
13959
- if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, safe))) return safe;
13960
- const ext = (0, import_node_path35.extname)(safe);
14033
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path36.join)(dir, safe))) return safe;
14034
+ const ext = (0, import_node_path36.extname)(safe);
13961
14035
  const stem = ext ? safe.slice(0, -ext.length) : safe;
13962
14036
  for (let i = 1; i < 1e4; i++) {
13963
14037
  const candidate = `${stem}-${i}${ext}`;
13964
- if (!(0, import_node_fs39.existsSync)((0, import_node_path35.join)(dir, candidate))) return candidate;
14038
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path36.join)(dir, candidate))) return candidate;
13965
14039
  }
13966
14040
  return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
13967
14041
  }
@@ -14017,12 +14091,12 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
14017
14091
  const dir = ensureAttachmentsDir(worktreePath);
14018
14092
  const out = [];
14019
14093
  for (const abs of absolutePaths) {
14020
- const originalName = (0, import_node_path35.basename)(abs);
14094
+ const originalName = (0, import_node_path36.basename)(abs);
14021
14095
  try {
14022
14096
  const st = (0, import_node_fs39.statSync)(abs);
14023
14097
  if (!st.isFile()) continue;
14024
14098
  const name = uniqueAttachmentName(dir, originalName);
14025
- const destAbs = (0, import_node_path35.join)(dir, name);
14099
+ const destAbs = (0, import_node_path36.join)(dir, name);
14026
14100
  (0, import_node_fs39.copyFileSync)(abs, destAbs);
14027
14101
  const rel = `${ATTACHMENTS_DIR}/${name}`;
14028
14102
  const buf = (0, import_node_fs39.readFileSync)(destAbs);
@@ -14047,7 +14121,7 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
14047
14121
  try {
14048
14122
  const buf = Buffer.from(item.dataBase64, "base64");
14049
14123
  const name = uniqueAttachmentName(dir, originalName);
14050
- const destAbs = (0, import_node_path35.join)(dir, name);
14124
+ const destAbs = (0, import_node_path36.join)(dir, name);
14051
14125
  (0, import_node_fs39.writeFileSync)(destAbs, buf);
14052
14126
  const rel = `${ATTACHMENTS_DIR}/${name}`;
14053
14127
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
@@ -14068,15 +14142,15 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
14068
14142
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
14069
14143
  out.push({
14070
14144
  id: (0, import_node_crypto7.randomUUID)(),
14071
- name: (0, import_node_path35.basename)(rel) || "file",
14145
+ name: (0, import_node_path36.basename)(rel) || "file",
14072
14146
  kind: "file",
14073
14147
  content: `(invalid path: ${rel})`
14074
14148
  });
14075
14149
  continue;
14076
14150
  }
14077
- const name = (0, import_node_path35.basename)(rel);
14151
+ const name = (0, import_node_path36.basename)(rel);
14078
14152
  try {
14079
- const abs = (0, import_node_path35.join)(worktreePath, rel);
14153
+ const abs = (0, import_node_path36.join)(worktreePath, rel);
14080
14154
  const st = (0, import_node_fs39.statSync)(abs);
14081
14155
  if (!st.isFile()) continue;
14082
14156
  const buf = (0, import_node_fs39.readFileSync)(abs);
@@ -14092,12 +14166,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
14092
14166
  }
14093
14167
  return out;
14094
14168
  }
14095
- var import_node_fs39, import_node_path35, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
14169
+ var import_node_fs39, import_node_path36, import_node_crypto7, IMAGE_EXTENSIONS2, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES;
14096
14170
  var init_stage_files = __esm({
14097
14171
  "src/composer/stage-files.ts"() {
14098
14172
  "use strict";
14099
14173
  import_node_fs39 = require("fs");
14100
- import_node_path35 = require("path");
14174
+ import_node_path36 = require("path");
14101
14175
  import_node_crypto7 = require("crypto");
14102
14176
  init_workspace_scratch();
14103
14177
  IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -14244,14 +14318,15 @@ function formatArtifactDirective() {
14244
14318
  return [
14245
14319
  "Sideboard side column (desktop UI):",
14246
14320
  "claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
14321
+ "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.",
14247
14322
  "Documents (HTML/SVG/markdown):",
14248
14323
  "1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
14249
14324
  "```html",
14250
14325
  "<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
14251
14326
  "```",
14252
- "2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
14327
+ "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.",
14253
14328
  "CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
14254
- "3) Call Sideboard MCP `present_schema` with title, mode (table|form), and either:",
14329
+ "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:",
14255
14330
  " - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
14256
14331
  " - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
14257
14332
  "Files / media browser (CMS file manager column):",
@@ -14260,18 +14335,18 @@ function formatArtifactDirective() {
14260
14335
  "Multiple-choice questions:",
14261
14336
  "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.",
14262
14337
  "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.",
14263
- "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."
14338
+ "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."
14264
14339
  ].join("\n");
14265
14340
  }
14266
14341
  function formatUiReminder() {
14267
- return "Sideboard UI: html fence or present_artifact / present_schema / present_files; ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
14342
+ 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.";
14268
14343
  }
14269
- var import_node_fs40, import_node_path36;
14344
+ var import_node_fs40, import_node_path37;
14270
14345
  var init_instructions = __esm({
14271
14346
  "src/agents/instructions.ts"() {
14272
14347
  "use strict";
14273
14348
  import_node_fs40 = require("fs");
14274
- import_node_path36 = require("path");
14349
+ import_node_path37 = require("path");
14275
14350
  init_git_auth_mode();
14276
14351
  init_worktree_labels();
14277
14352
  }
@@ -14347,13 +14422,13 @@ __export(plan_file_exports, {
14347
14422
  writePlanFile: () => writePlanFile
14348
14423
  });
14349
14424
  function ensureAttachmentsGitignore(worktreePath) {
14350
- const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14425
+ const gitignoreAbs = (0, import_node_path38.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14351
14426
  if ((0, import_node_fs41.existsSync)(gitignoreAbs)) return;
14352
- (0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
14427
+ (0, import_node_fs41.mkdirSync)((0, import_node_path38.dirname)(gitignoreAbs), { recursive: true });
14353
14428
  (0, import_node_fs41.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14354
14429
  }
14355
14430
  function planFileAbs(worktreePath) {
14356
- return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
14431
+ return (0, import_node_path38.join)(worktreePath, PLAN_FILE_REL);
14357
14432
  }
14358
14433
  function readTextIfPresent2(abs) {
14359
14434
  if (!(0, import_node_fs41.existsSync)(abs)) return null;
@@ -14365,22 +14440,22 @@ function readTextIfPresent2(abs) {
14365
14440
  }
14366
14441
  }
14367
14442
  function readPlanFile(worktreePath) {
14368
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, LEGACY_PLAN_FILE_REL));
14443
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path38.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path38.join)(worktreePath, LEGACY_PLAN_FILE_REL));
14369
14444
  }
14370
14445
  function writePlanFile(worktreePath, content) {
14371
14446
  ensureAttachmentsGitignore(worktreePath);
14372
14447
  const abs = planFileAbs(worktreePath);
14373
- (0, import_node_fs41.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
14448
+ (0, import_node_fs41.mkdirSync)((0, import_node_path38.dirname)(abs), { recursive: true });
14374
14449
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
14375
14450
  (0, import_node_fs41.writeFileSync)(abs, body, "utf8");
14376
14451
  return PLAN_FILE_REL;
14377
14452
  }
14378
- var import_node_fs41, import_node_path37;
14453
+ var import_node_fs41, import_node_path38;
14379
14454
  var init_plan_file = __esm({
14380
14455
  "src/plan/plan-file.ts"() {
14381
14456
  "use strict";
14382
14457
  import_node_fs41 = require("fs");
14383
- import_node_path37 = require("path");
14458
+ import_node_path38 = require("path");
14384
14459
  init_workspace_scratch();
14385
14460
  init_plan_present();
14386
14461
  init_plan_present();
@@ -14440,7 +14515,7 @@ function setCaffeinateHoldHooks(next) {
14440
14515
  hooks = next;
14441
14516
  }
14442
14517
  function caffeinateHoldPath() {
14443
- return (0, import_node_path38.join)(appDataDir(), "caffeinate-hold.json");
14518
+ return (0, import_node_path39.join)(appDataDir(), "caffeinate-hold.json");
14444
14519
  }
14445
14520
  function processAlive(pid) {
14446
14521
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -14583,13 +14658,13 @@ function releaseCaffeinateHoldForThread(threadId) {
14583
14658
  }
14584
14659
  return setCaffeinateHold(false, { threadId: id });
14585
14660
  }
14586
- var import_node_child_process4, import_node_fs42, import_node_path38, hooks;
14661
+ var import_node_child_process4, import_node_fs42, import_node_path39, hooks;
14587
14662
  var init_caffeinate_hold = __esm({
14588
14663
  "src/store/caffeinate-hold.ts"() {
14589
14664
  "use strict";
14590
14665
  import_node_child_process4 = require("child_process");
14591
14666
  import_node_fs42 = require("fs");
14592
- import_node_path38 = require("path");
14667
+ import_node_path39 = require("path");
14593
14668
  init_paths();
14594
14669
  init_private_file();
14595
14670
  hooks = {};
@@ -14598,7 +14673,7 @@ var init_caffeinate_hold = __esm({
14598
14673
 
14599
14674
  // src/store/schedules.ts
14600
14675
  function schedulesPath() {
14601
- return (0, import_node_path39.join)(appDataDir(), "schedules.json");
14676
+ return (0, import_node_path40.join)(appDataDir(), "schedules.json");
14602
14677
  }
14603
14678
  function parseDurationMs(every) {
14604
14679
  const m = every.trim().match(DURATION_RE);
@@ -14812,13 +14887,13 @@ function recordScheduleRun(id, result) {
14812
14887
  writeAll2(rows);
14813
14888
  return next;
14814
14889
  }
14815
- var import_node_crypto8, import_node_fs43, import_node_path39, import_croner, DURATION_RE, UNIT_MS;
14890
+ var import_node_crypto8, import_node_fs43, import_node_path40, import_croner, DURATION_RE, UNIT_MS;
14816
14891
  var init_schedules = __esm({
14817
14892
  "src/store/schedules.ts"() {
14818
14893
  "use strict";
14819
14894
  import_node_crypto8 = require("crypto");
14820
14895
  import_node_fs43 = require("fs");
14821
- import_node_path39 = require("path");
14896
+ import_node_path40 = require("path");
14822
14897
  import_croner = require("croner");
14823
14898
  init_orchestrator_capable();
14824
14899
  init_paths();
@@ -14958,6 +15033,37 @@ var init_schedule_runner = __esm({
14958
15033
  }
14959
15034
  });
14960
15035
 
15036
+ // src/agents/cursor-store.ts
15037
+ function cursorSdkStoreDir(threadId) {
15038
+ const root = (0, import_node_path41.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
15039
+ const id = sanitizeCursorStoreSegment(threadId);
15040
+ if (!id) return root;
15041
+ return (0, import_node_path41.join)(root, "threads", id);
15042
+ }
15043
+ function cursorSdkRunsNdjsonPath(threadId) {
15044
+ return (0, import_node_path41.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
15045
+ }
15046
+ function cursorSdkRunsNdjsonSearchPaths(threadId) {
15047
+ const scoped = cursorSdkRunsNdjsonPath(threadId);
15048
+ const shared = cursorSdkRunsNdjsonPath(null);
15049
+ if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
15050
+ return [shared];
15051
+ }
15052
+ return [scoped, shared];
15053
+ }
15054
+ function sanitizeCursorStoreSegment(threadId) {
15055
+ return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
15056
+ }
15057
+ var import_node_path41, CURSOR_SDK_STORE_DIR;
15058
+ var init_cursor_store = __esm({
15059
+ "src/agents/cursor-store.ts"() {
15060
+ "use strict";
15061
+ import_node_path41 = require("path");
15062
+ init_paths();
15063
+ CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
15064
+ }
15065
+ });
15066
+
14961
15067
  // src/agents/cursor-recover.ts
14962
15068
  var cursor_recover_exports = {};
14963
15069
  __export(cursor_recover_exports, {
@@ -14966,7 +15072,14 @@ __export(cursor_recover_exports, {
14966
15072
  function recoverFinishedCursorRun(opts) {
14967
15073
  const agentId = opts.agentId.trim();
14968
15074
  if (!agentId) return null;
14969
- const runsPath = (0, import_node_path40.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
15075
+ let best = null;
15076
+ for (const runsPath of cursorSdkRunsNdjsonSearchPaths(opts.threadId)) {
15077
+ const hit = scanFinishedCursorRuns(runsPath, agentId, opts.startedAfterMs);
15078
+ if (hit && (!best || hit.endedAt >= best.endedAt)) best = hit;
15079
+ }
15080
+ return best;
15081
+ }
15082
+ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
14970
15083
  if (!(0, import_node_fs44.existsSync)(runsPath)) return null;
14971
15084
  try {
14972
15085
  const lines = (0, import_node_fs44.readFileSync)(runsPath, "utf8").split("\n");
@@ -14985,7 +15098,7 @@ function recoverFinishedCursorRun(opts) {
14985
15098
  if (typeof row.result !== "string" || !row.result.trim()) continue;
14986
15099
  const endedAt = typeof row.endedAt === "number" ? row.endedAt : 0;
14987
15100
  const createdAt = typeof row.createdAt === "number" ? row.createdAt : 0;
14988
- if (createdAt < opts.startedAfterMs && endedAt < opts.startedAfterMs) continue;
15101
+ if (createdAt < startedAfterMs && endedAt < startedAfterMs) continue;
14989
15102
  if (!best || endedAt >= best.endedAt) {
14990
15103
  best = { runId: row.runId || "", result: row.result.trim(), endedAt };
14991
15104
  }
@@ -14995,13 +15108,12 @@ function recoverFinishedCursorRun(opts) {
14995
15108
  return null;
14996
15109
  }
14997
15110
  }
14998
- var import_node_fs44, import_node_path40;
15111
+ var import_node_fs44;
14999
15112
  var init_cursor_recover = __esm({
15000
15113
  "src/agents/cursor-recover.ts"() {
15001
15114
  "use strict";
15002
15115
  import_node_fs44 = require("fs");
15003
- import_node_path40 = require("path");
15004
- init_paths();
15116
+ init_cursor_store();
15005
15117
  }
15006
15118
  });
15007
15119
 
@@ -15162,6 +15274,7 @@ var init_orchestrator = __esm({
15162
15274
  init_run();
15163
15275
  init_repo_git_lock();
15164
15276
  init_turn_live();
15277
+ init_reconcile_heal();
15165
15278
  init_request_review();
15166
15279
  init_fork_worktree();
15167
15280
  init_quota_failover();
@@ -15191,6 +15304,8 @@ var init_orchestrator = __esm({
15191
15304
  draining = /* @__PURE__ */ new Set();
15192
15305
  /** Threads past setStatus(running) but not yet in activeTurns (spawn in flight). */
15193
15306
  startingTurns = /* @__PURE__ */ new Set();
15307
+ /** Last sync thread-file read for false-stop heal (throttled per thread). */
15308
+ lastReconcileHealAt = /* @__PURE__ */ new Map();
15194
15309
  /**
15195
15310
  * Threads intentionally force-stopped. Prevents runTurn from re-asserting
15196
15311
  * `running` after spawn, and from overwriting `stopped` with idle/error when
@@ -15788,7 +15903,13 @@ var init_orchestrator = __esm({
15788
15903
  if (event.type === "stderr" && typeof event.data === "string") {
15789
15904
  pushTurnStderr(stderrTail, event.data);
15790
15905
  }
15791
- if (event.type !== "stdout" && event.type !== "thinking") {
15906
+ const now = Date.now();
15907
+ if (shouldReadThreadToHealReconcile(
15908
+ event.type,
15909
+ this.lastReconcileHealAt.get(threadId),
15910
+ now
15911
+ )) {
15912
+ this.lastReconcileHealAt.set(threadId, now);
15792
15913
  const live = readThread(threadId);
15793
15914
  if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
15794
15915
  setStatus(threadId, "running");
@@ -15832,7 +15953,8 @@ var init_orchestrator = __esm({
15832
15953
  for (let i = 0; i < 8; i++) {
15833
15954
  const recovered = recoverFinishedCursorRun2({
15834
15955
  agentId: sessionId,
15835
- startedAfterMs: turnStartedAt - 5e3
15956
+ startedAfterMs: turnStartedAt - 5e3,
15957
+ threadId
15836
15958
  });
15837
15959
  if (recovered?.result) {
15838
15960
  assistantText = recovered.result;
@@ -16933,7 +17055,7 @@ init_nested_electron_env();
16933
17055
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
16934
17056
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
16935
17057
  var import_zod4 = require("zod");
16936
- var import_node_path41 = require("path");
17058
+ var import_node_path42 = require("path");
16937
17059
  init_orchestrator();
16938
17060
  init_worktree();
16939
17061
 
@@ -18290,7 +18412,7 @@ async function startMcpServer() {
18290
18412
  async () => {
18291
18413
  const threads = orch.getThreads(true);
18292
18414
  const lines = threads.map((t) => {
18293
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path41.basename)(t.repoPath) || t.repoPath;
18415
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path42.basename)(t.repoPath) || t.repoPath;
18294
18416
  const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
18295
18417
  const progress = live?.summary ? ` ${live.summary}` : "";
18296
18418
  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}`;
@@ -18335,7 +18457,7 @@ async function startMcpServer() {
18335
18457
  }
18336
18458
  server.tool(
18337
18459
  "present_artifact",
18338
- "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.",
18460
+ "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.",
18339
18461
  {
18340
18462
  title: import_zod4.z.string().describe("Short title shown in the artifact pane header"),
18341
18463
  type: import_zod4.z.enum(["html", "svg", "markdown", "react"]).describe(
@@ -18412,7 +18534,7 @@ async function startMcpServer() {
18412
18534
  );
18413
18535
  server.tool(
18414
18536
  "present_schema",
18415
- "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.",
18537
+ "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.",
18416
18538
  {
18417
18539
  title: import_zod4.z.string().describe("Pane title"),
18418
18540
  mode: import_zod4.z.enum(["table", "form"]).optional().describe("table = list/filter records; form = edit one record"),