@sideboard-ai/core 0.1.174 → 0.1.176

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 (40) hide show
  1. package/dist/{abletime-PCLL36HW.js → abletime-BFIDZR3O.js} +2 -2
  2. package/dist/{abletime-7VW4EGPT.js → abletime-INEHQH6K.js} +2 -2
  3. package/dist/agents/cursor-runner.cjs +91 -62
  4. package/dist/agents/cursor-runner.js +1 -1
  5. package/dist/{agents-ZWYRGFZB.js → agents-544IX5KA.js} +8 -6
  6. package/dist/{agents-LMPVUPOH.js → agents-UENEQ6J2.js} +7 -5
  7. package/dist/{chunk-ZY7K4T37.js → chunk-3ZFGZ7RT.js} +5 -5
  8. package/dist/{chunk-HJPGIETB.js → chunk-4ELBAYFW.js} +19 -14
  9. package/dist/{chunk-M267JPEA.js → chunk-AN3THU7F.js} +1 -1
  10. package/dist/{chunk-AQPVBVJE.js → chunk-BBNUL4IE.js} +1 -1
  11. package/dist/{chunk-VCVBICMZ.js → chunk-FJWQCZ74.js} +5 -5
  12. package/dist/{chunk-LZ6QMEQC.js → chunk-HVIEYTUK.js} +1 -1
  13. package/dist/{chunk-XD2BAANL.js → chunk-IEEAVWAP.js} +6 -6
  14. package/dist/{chunk-YEPVWJ3R.js → chunk-JUA7XEXR.js} +16 -11
  15. package/dist/{chunk-ELBYOGVA.js → chunk-N7WZ6NIN.js} +10 -1
  16. package/dist/{chunk-CUA4S537.js → chunk-NIB6BTC6.js} +9 -5
  17. package/dist/{chunk-XXIH6XYR.js → chunk-NQTKRAUF.js} +167 -35
  18. package/dist/{chunk-CMJ2FBBV.js → chunk-RE2YWFUQ.js} +1 -1
  19. package/dist/{chunk-6GN5WPYZ.js → chunk-VKQGAWHY.js} +10 -1
  20. package/dist/{chunk-TPPZXZTA.js → chunk-W44EKPIR.js} +228 -95
  21. package/dist/{chunk-S42XV45P.js → chunk-Y4MIXGPA.js} +1 -1
  22. package/dist/{connected-teams-DBWAMP7G.js → connected-teams-ON2KIKQX.js} +3 -3
  23. package/dist/{connected-teams-WGONUQOF.js → connected-teams-WOYCH7FR.js} +3 -3
  24. package/dist/{coordinator-prompt-K3HXEPFD.js → coordinator-prompt-BE2FERYE.js} +1 -1
  25. package/dist/{coordinator-prompt-LJKA2ODR.js → coordinator-prompt-PRM5ARWG.js} +1 -1
  26. package/dist/{global-workspace-VDFSU3DD.js → global-workspace-3HIWNQ3B.js} +1 -1
  27. package/dist/{global-workspace-KA7T26F5.js → global-workspace-J737XNUX.js} +1 -1
  28. package/dist/index.cjs +584 -379
  29. package/dist/index.d.cts +53 -10
  30. package/dist/index.d.ts +53 -10
  31. package/dist/index.js +76 -27
  32. package/dist/mcp/run-stdio.cjs +778 -576
  33. package/dist/mcp/run-stdio.js +78 -27
  34. package/dist/{oauth-A7XXI2TM.js → oauth-6ZQ4Q4XN.js} +2 -2
  35. package/dist/{oauth-YJBAURIJ.js → oauth-O7UGLZOY.js} +2 -2
  36. package/dist/{orchestrator-DMSSC4SV.js → orchestrator-2KZD7N4X.js} +6 -6
  37. package/dist/{orchestrator-VMUZJFTZ.js → orchestrator-GDKEVLFK.js} +7 -7
  38. package/dist/{workspaces-GOGBPATJ.js → workspaces-DR4UNOQC.js} +1 -1
  39. package/dist/{workspaces-UR7YEFMZ.js → workspaces-ULHYXM4Y.js} +1 -1
  40. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -7684,8 +7684,8 @@ function ensureGlobalCoordinatorCwd(opts) {
7684
7684
  "",
7685
7685
  "When creating threads, pass `repoPath` from `list_workspaces` (or the path you just registered).",
7686
7686
  orchId ? `Pass parentThreadId="${orchId}" (or omit it). Never invent another parentThreadId.` : "Pass `parentThreadId` for children (this chat's id from the turn reminder).",
7687
- "Omit `agent` / `model` on `create_thread` unless you have a reason to override Account defaults.",
7688
- "Never pass `agent=codex` when you yourself are Codex \u2014 nested Codex deadlocks on shared ~/.codex locks. Omit agent (Account default) or use cursor/claude.",
7687
+ "Omit `agent` / `model` on `create_thread`. Sideboard applies Settings \u2192 Default agent, model & effort. Do not pass your own agent or `agent=cursor` \u2014 those are ignored.",
7688
+ "Never pass `agent=codex` when you yourself are Codex \u2014 nested Codex can deadlock on shared ~/.codex locks. Omit agent; Sideboard applies Account defaults, and switches that nested-Codex case to Cursor only when a CURSOR_API_KEY is configured.",
7689
7689
  "Typical flow (Home board): list_board \u2192 create_thread (sourceType=ticket|pr|branch) \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft \u2192 wait_for_turn. Merge only if the user explicitly asked (`ask_git` merge).",
7690
7690
  "Typical flow (branch / explicit source): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
7691
7691
  "Typical flow (find work): list_workspaces \u2192 pick repo(s) matching account / project context \u2192 Sideboard list_issues / linear_* (tickets) or list_prs(queue=review) (reviews) \u2192 show the options. Never wait on Claude Linear MCP. Only create_thread + send_to_thread when they asked to start (e.g. \u201Cfind me work and start it\u201D) \u2014 then wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
@@ -7762,7 +7762,7 @@ var init_coordinator_prompt = __esm({
7762
7762
  "Workspaces:",
7763
7763
  "- add_workspace / remove_workspace \u2014 register or unregister a git repo",
7764
7764
  "Worktree threads (chats):",
7765
- "- create_thread \u2014 create a worktree + chat from branch | pr | ticket (appears on Home). Do not create a second worktree for a ticket, PR, or named branch that already has one \u2014 that call returns the live thread (alreadyStarted=true). Creating from the default branch still opens a new isolated worktree. Pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If the repo has a setup script, Sideboard runs it in the background (does not block send_to_thread). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
7765
+ "- create_thread \u2014 create a worktree + chat from branch | pr | ticket (appears on Home). Do not create a second worktree for a ticket, PR, or named branch that already has one \u2014 that call returns the live thread (alreadyStarted=true). Creating from the default branch still opens a new isolated worktree. Pass repoPath + parentThreadId; omit agent and model so Sideboard applies Settings \u2192 Default agent, model & effort (never pass your own agent or agent=cursor). If the repo has a setup script, Sideboard runs it in the background (does not block send_to_thread). Nested Codex (you are Codex and the child would be Codex) can deadlock on ~/.codex locks \u2014 omit agent; Sideboard switches the child to Cursor when a CURSOR_API_KEY is set, otherwise keeps the Account default",
7766
7766
  "- start_board_card \u2014 same as create_thread for a ticket/PR/named branch (attaches issue text when resolvable). Then send_to_thread.",
7767
7767
  "- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
7768
7768
  "- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
@@ -7777,9 +7777,9 @@ var init_coordinator_prompt = __esm({
7777
7777
  "- get_diff \u2014 compact diff summary",
7778
7778
  "- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
7779
7779
  '- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id',
7780
- "- ask_git \u2014 commit & push, open a draft PR, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
7780
+ "- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
7781
7781
  '- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
7782
- '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
7782
+ '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
7783
7783
  "Process guides:",
7784
7784
  "- Long child jobs (pack, test, deploy, anything that may run more than ~30s): workers always have `/long-running` (Sideboard product skill). Tell them to detach and wait; they may `stop_job` if it hangs or is doing the wrong thing; do not ask the human to poll.",
7785
7785
  "- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
@@ -8943,17 +8943,24 @@ var init_config = __esm({
8943
8943
  function setHttpFetchImpl(fetchImpl) {
8944
8944
  injected = fetchImpl;
8945
8945
  }
8946
+ function tlsIssuerHint(code, message) {
8947
+ const text7 = `${code ?? ""} ${message}`;
8948
+ return TLS_ISSUER_RE.test(text7) ? TLS_ISSUER_HINT : "";
8949
+ }
8946
8950
  function formatFetchError(err, url) {
8947
8951
  if (!(err instanceof Error)) return `${String(err)} (${url})`;
8948
8952
  const cause = err.cause;
8949
8953
  let detail = "";
8954
+ let hint = tlsIssuerHint(void 0, err.message);
8950
8955
  if (cause instanceof Error) {
8951
8956
  const code = typeof cause.code === "string" ? cause.code : void 0;
8952
8957
  detail = code ? ` [${code}: ${cause.message}]` : ` [${cause.message}]`;
8958
+ hint = tlsIssuerHint(code, `${err.message} ${cause.message}`) || hint;
8953
8959
  } else if (cause != null) {
8954
8960
  detail = ` [${String(cause)}]`;
8961
+ hint = tlsIssuerHint(void 0, String(cause)) || hint;
8955
8962
  }
8956
- return `${err.message}${detail} (${url})`;
8963
+ return `${err.message}${detail} (${url})${hint}`;
8957
8964
  }
8958
8965
  async function httpFetch(input, init) {
8959
8966
  const url = typeof input === "string" ? input : input.href;
@@ -8964,11 +8971,13 @@ async function httpFetch(input, init) {
8964
8971
  throw new Error(formatFetchError(err, url));
8965
8972
  }
8966
8973
  }
8967
- var injected;
8974
+ var injected, TLS_ISSUER_RE, TLS_ISSUER_HINT;
8968
8975
  var init_fetch = __esm({
8969
8976
  "src/http/fetch.ts"() {
8970
8977
  "use strict";
8971
8978
  injected = null;
8979
+ TLS_ISSUER_RE = /UNABLE_TO_GET_ISSUER_CERT|UNABLE_TO_VERIFY_LEAF_SIGNATURE|SELF_SIGNED_CERT_IN_CHAIN/i;
8980
+ TLS_ISSUER_HINT = " \u2014 Node rejected the TLS certificate (corporate VPN/proxy CA). Desktop Linear can still work; reconnecting the API key will not fix this.";
8972
8981
  }
8973
8982
  });
8974
8983
 
@@ -10521,6 +10530,138 @@ var init_profile = __esm({
10521
10530
  }
10522
10531
  });
10523
10532
 
10533
+ // src/http/system-ca.ts
10534
+ function splitPemCertificates(pem) {
10535
+ return pem.match(PEM_CERT_RE) ?? [];
10536
+ }
10537
+ function readExistingFile(path2) {
10538
+ try {
10539
+ return (0, import_node_fs26.existsSync)(path2) ? (0, import_node_fs26.readFileSync)(path2, "utf8") : "";
10540
+ } catch {
10541
+ return "";
10542
+ }
10543
+ }
10544
+ function darwinKeychainPem(spawn2) {
10545
+ const result = spawn2("/usr/bin/security", ["find-certificate", "-a", "-p"], {
10546
+ encoding: "utf8",
10547
+ maxBuffer: 32 * 1024 * 1024,
10548
+ timeout: 15e3
10549
+ });
10550
+ if (result.status !== 0) return "";
10551
+ return typeof result.stdout === "string" ? result.stdout : "";
10552
+ }
10553
+ function linuxSystemCaPem() {
10554
+ for (const path2 of LINUX_CA_FILES) {
10555
+ const pem = readExistingFile(path2);
10556
+ if (splitPemCertificates(pem).length > 0) return pem;
10557
+ }
10558
+ return "";
10559
+ }
10560
+ function collectSystemCaPem(io = {}) {
10561
+ const platform = io.platform ?? process.platform;
10562
+ if (platform === "darwin") {
10563
+ return darwinKeychainPem(io.spawn ?? import_node_child_process4.spawnSync);
10564
+ }
10565
+ if (platform === "linux") {
10566
+ return linuxSystemCaPem();
10567
+ }
10568
+ return "";
10569
+ }
10570
+ function systemCaBundlePath(io = {}) {
10571
+ return (0, import_node_path28.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
10572
+ }
10573
+ function bundleIsFresh(path2, now) {
10574
+ try {
10575
+ if (!(0, import_node_fs26.existsSync)(path2)) return false;
10576
+ if (splitPemCertificates((0, import_node_fs26.readFileSync)(path2, "utf8")).length === 0) return false;
10577
+ return now - (0, import_node_fs26.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
10578
+ } catch {
10579
+ return false;
10580
+ }
10581
+ }
10582
+ function materializeSystemCaBundle(io = {}) {
10583
+ const inherited = process.env.NODE_EXTRA_CA_CERTS?.trim();
10584
+ if (inherited && splitPemCertificates(readExistingFile(inherited)).length > 0) {
10585
+ return inherited;
10586
+ }
10587
+ const platform = io.platform ?? process.platform;
10588
+ if (platform === "linux") {
10589
+ for (const path2 of LINUX_CA_FILES) {
10590
+ if (splitPemCertificates(readExistingFile(path2)).length > 0) return path2;
10591
+ }
10592
+ }
10593
+ const dest = systemCaBundlePath(io);
10594
+ const now = (io.now ?? Date.now)();
10595
+ if (bundleIsFresh(dest, now)) return dest;
10596
+ const pem = collectSystemCaPem(io);
10597
+ if (splitPemCertificates(pem).length === 0) {
10598
+ return (0, import_node_fs26.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
10599
+ }
10600
+ try {
10601
+ (0, import_node_fs26.mkdirSync)((0, import_node_path28.dirname)(dest), { recursive: true });
10602
+ (0, import_node_fs26.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
10603
+ `, { mode: 384 });
10604
+ return dest;
10605
+ } catch {
10606
+ return void 0;
10607
+ }
10608
+ }
10609
+ function applySystemCaEnv(env) {
10610
+ if (!String(env[NODE_USE_SYSTEM_CA] ?? "").trim()) {
10611
+ env[NODE_USE_SYSTEM_CA] = "1";
10612
+ }
10613
+ if (String(env[NODE_EXTRA_CA_CERTS] ?? "").trim()) return;
10614
+ const inherited = process.env.NODE_EXTRA_CA_CERTS?.trim();
10615
+ if (inherited) env[NODE_EXTRA_CA_CERTS] = inherited;
10616
+ }
10617
+ function extraCertsFromBundle() {
10618
+ const path2 = process.env.NODE_EXTRA_CA_CERTS?.trim();
10619
+ if (path2) return splitPemCertificates(readExistingFile(path2));
10620
+ const dest = systemCaBundlePath();
10621
+ return splitPemCertificates(readExistingFile(dest));
10622
+ }
10623
+ function trustSystemCertificates(io = {}) {
10624
+ try {
10625
+ const api = import_node_tls.default;
10626
+ if (typeof api.getCACertificates !== "function" || typeof api.setDefaultCACertificates !== "function") {
10627
+ return false;
10628
+ }
10629
+ const current = api.getCACertificates("default");
10630
+ const system = api.getCACertificates("system");
10631
+ let extra = extraCertsFromBundle();
10632
+ if (system.length === 0 && extra.length === 0) {
10633
+ extra = splitPemCertificates(collectSystemCaPem(io));
10634
+ }
10635
+ if (system.length === 0 && extra.length === 0) return false;
10636
+ api.setDefaultCACertificates([...current, ...system, ...extra]);
10637
+ return true;
10638
+ } catch {
10639
+ return false;
10640
+ }
10641
+ }
10642
+ var import_node_child_process4, import_node_fs26, import_node_path28, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
10643
+ var init_system_ca = __esm({
10644
+ "src/http/system-ca.ts"() {
10645
+ "use strict";
10646
+ import_node_child_process4 = require("child_process");
10647
+ import_node_fs26 = require("fs");
10648
+ import_node_path28 = require("path");
10649
+ import_node_tls = __toESM(require("tls"), 1);
10650
+ init_paths();
10651
+ NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
10652
+ NODE_EXTRA_CA_CERTS = "NODE_EXTRA_CA_CERTS";
10653
+ BUNDLE_NAME = "system-ca.pem";
10654
+ BUNDLE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
10655
+ LINUX_CA_FILES = [
10656
+ "/etc/ssl/certs/ca-certificates.crt",
10657
+ "/etc/pki/tls/certs/ca-bundle.crt",
10658
+ "/etc/ssl/ca-bundle.pem",
10659
+ "/etc/ssl/cert.pem"
10660
+ ];
10661
+ PEM_CERT_RE = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
10662
+ }
10663
+ });
10664
+
10524
10665
  // src/agents/packaged-runtime.ts
10525
10666
  function electronResourcesPath() {
10526
10667
  const resources = process.resourcesPath;
@@ -10530,43 +10671,43 @@ function electronResourcesPath() {
10530
10671
  function packagedCursorRuntimeDir() {
10531
10672
  const resources = electronResourcesPath();
10532
10673
  if (!resources) return null;
10533
- const dir = (0, import_node_path28.join)(resources, "cursor-runtime");
10534
- if (!(0, import_node_fs26.existsSync)((0, import_node_path28.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
10674
+ const dir = (0, import_node_path29.join)(resources, "cursor-runtime");
10675
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
10535
10676
  return dir;
10536
10677
  }
10537
10678
  function packagedCursorRunnerPath() {
10538
10679
  const dir = packagedCursorRuntimeDir();
10539
- return dir ? (0, import_node_path28.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
10680
+ return dir ? (0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
10540
10681
  }
10541
10682
  function packagedMcpDir() {
10542
10683
  const resources = electronResourcesPath();
10543
10684
  if (!resources) return null;
10544
- const dir = (0, import_node_path28.join)(resources, "sideboard-mcp");
10545
- if (!(0, import_node_fs26.existsSync)((0, import_node_path28.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
10685
+ const dir = (0, import_node_path29.join)(resources, "sideboard-mcp");
10686
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
10546
10687
  return dir;
10547
10688
  }
10548
10689
  function packagedMcpStdioPath() {
10549
10690
  const dir = packagedMcpDir();
10550
- return dir ? (0, import_node_path28.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
10691
+ return dir ? (0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
10551
10692
  }
10552
10693
  function packagedBundledNodePath() {
10553
10694
  const resources = electronResourcesPath();
10554
10695
  if (!resources) return null;
10555
- const bin = (0, import_node_path28.join)(resources, "node", "bin", "node");
10556
- if (!(0, import_node_fs26.existsSync)(bin)) return null;
10696
+ const bin = (0, import_node_path29.join)(resources, "node", "bin", "node");
10697
+ if (!(0, import_node_fs27.existsSync)(bin)) return null;
10557
10698
  return bin;
10558
10699
  }
10559
10700
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
10560
10701
  const dir = packagedCursorRuntimeDir();
10561
10702
  if (!dir) return null;
10562
- return (0, import_node_path28.join)(dir, "node_modules", platformPkg, "bin", binName);
10703
+ return (0, import_node_path29.join)(dir, "node_modules", platformPkg, "bin", binName);
10563
10704
  }
10564
- var import_node_fs26, import_node_path28;
10705
+ var import_node_fs27, import_node_path29;
10565
10706
  var init_packaged_runtime = __esm({
10566
10707
  "src/agents/packaged-runtime.ts"() {
10567
10708
  "use strict";
10568
- import_node_fs26 = require("fs");
10569
- import_node_path28 = require("path");
10709
+ import_node_fs27 = require("fs");
10710
+ import_node_path29 = require("path");
10570
10711
  }
10571
10712
  });
10572
10713
 
@@ -10586,6 +10727,7 @@ function applyAgentRunnerHeapEnv(env) {
10586
10727
  env.NODE_OPTIONS,
10587
10728
  AGENT_RUNNER_MAX_OLD_SPACE_MB
10588
10729
  );
10730
+ applySystemCaEnv(env);
10589
10731
  }
10590
10732
  function envWithAgentHeap(env) {
10591
10733
  const next = { ...env };
@@ -10600,7 +10742,7 @@ function unpackedAsarPath(filePath) {
10600
10742
  if (!isAsarPath(filePath)) return null;
10601
10743
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
10602
10744
  if (unpacked === filePath) return null;
10603
- return (0, import_node_fs27.existsSync)(unpacked) ? unpacked : null;
10745
+ return (0, import_node_fs28.existsSync)(unpacked) ? unpacked : null;
10604
10746
  }
10605
10747
  function nodeReadableScriptPath(scriptPath) {
10606
10748
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -10640,37 +10782,37 @@ function pickPreferredNode(candidates) {
10640
10782
  return best;
10641
10783
  }
10642
10784
  function versionDirNodeBins(root, toBin) {
10643
- if (!(0, import_node_fs27.existsSync)(root)) return [];
10785
+ if (!(0, import_node_fs28.existsSync)(root)) return [];
10644
10786
  try {
10645
- return (0, import_node_fs27.readdirSync)(root).map(toBin);
10787
+ return (0, import_node_fs28.readdirSync)(root).map(toBin);
10646
10788
  } catch {
10647
10789
  return [];
10648
10790
  }
10649
10791
  }
10650
10792
  function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
10651
10793
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
10652
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path29.join)(prefix, "opt", `node@${major}`, "bin", "node"))
10794
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path30.join)(prefix, "opt", `node@${major}`, "bin", "node"))
10653
10795
  );
10654
10796
  return [
10655
10797
  ...kegs,
10656
10798
  "/opt/homebrew/bin/node",
10657
10799
  "/usr/local/bin/node",
10658
- (0, import_node_path29.join)(home, ".local/share/fnm/aliases/default/bin/node"),
10659
- (0, import_node_path29.join)(home, ".nvm/current/bin/node"),
10660
- (0, import_node_path29.join)(home, ".volta/bin/node"),
10661
- (0, import_node_path29.join)(home, ".asdf/shims/node"),
10662
- (0, import_node_path29.join)(home, ".local/share/mise/shims/node"),
10800
+ (0, import_node_path30.join)(home, ".local/share/fnm/aliases/default/bin/node"),
10801
+ (0, import_node_path30.join)(home, ".nvm/current/bin/node"),
10802
+ (0, import_node_path30.join)(home, ".volta/bin/node"),
10803
+ (0, import_node_path30.join)(home, ".asdf/shims/node"),
10804
+ (0, import_node_path30.join)(home, ".local/share/mise/shims/node"),
10663
10805
  ...versionDirNodeBins(
10664
- (0, import_node_path29.join)(home, ".nvm", "versions", "node"),
10665
- (name) => (0, import_node_path29.join)(home, ".nvm", "versions", "node", name, "bin", "node")
10806
+ (0, import_node_path30.join)(home, ".nvm", "versions", "node"),
10807
+ (name) => (0, import_node_path30.join)(home, ".nvm", "versions", "node", name, "bin", "node")
10666
10808
  ),
10667
10809
  ...versionDirNodeBins(
10668
- (0, import_node_path29.join)(home, ".local/share/fnm", "node-versions"),
10669
- (name) => (0, import_node_path29.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
10810
+ (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions"),
10811
+ (name) => (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
10670
10812
  ),
10671
10813
  ...versionDirNodeBins(
10672
- (0, import_node_path29.join)(home, ".volta", "tools", "image", "node"),
10673
- (name) => (0, import_node_path29.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
10814
+ (0, import_node_path30.join)(home, ".volta", "tools", "image", "node"),
10815
+ (name) => (0, import_node_path30.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
10674
10816
  )
10675
10817
  ];
10676
10818
  }
@@ -10679,10 +10821,10 @@ function uniqueExistingNodeBins(paths) {
10679
10821
  const out = [];
10680
10822
  for (const raw of paths) {
10681
10823
  const p = raw.trim();
10682
- if (!p || !(0, import_node_fs27.existsSync)(p) || isElectronLikeCommand(p)) continue;
10824
+ if (!p || !(0, import_node_fs28.existsSync)(p) || isElectronLikeCommand(p)) continue;
10683
10825
  let key = p;
10684
10826
  try {
10685
- key = (0, import_node_fs27.realpathSync)(p);
10827
+ key = (0, import_node_fs28.realpathSync)(p);
10686
10828
  } catch {
10687
10829
  continue;
10688
10830
  }
@@ -10762,14 +10904,15 @@ async function resolveNodeLaunch(scriptPath) {
10762
10904
  env: { ELECTRON_RUN_AS_NODE: "1" }
10763
10905
  };
10764
10906
  }
10765
- var import_node_fs27, import_node_os8, import_node_path29, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
10907
+ var import_node_fs28, import_node_os8, import_node_path30, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
10766
10908
  var init_node_launch = __esm({
10767
10909
  "src/agents/node-launch.ts"() {
10768
10910
  "use strict";
10769
- import_node_fs27 = require("fs");
10911
+ import_node_fs28 = require("fs");
10770
10912
  import_node_os8 = require("os");
10771
- import_node_path29 = require("path");
10913
+ import_node_path30 = require("path");
10772
10914
  init_nested_electron_env();
10915
+ init_system_ca();
10773
10916
  init_run();
10774
10917
  init_packaged_runtime();
10775
10918
  AGENT_RUNNER_MAX_OLD_SPACE_MB = 8192;
@@ -10869,37 +11012,37 @@ function corePackageDir() {
10869
11012
  try {
10870
11013
  const url = import_meta.url;
10871
11014
  if (typeof url === "string" && url.length > 0) {
10872
- return (0, import_node_path30.dirname)((0, import_node_url.fileURLToPath)(url));
11015
+ return (0, import_node_path31.dirname)((0, import_node_url.fileURLToPath)(url));
10873
11016
  }
10874
11017
  } catch {
10875
11018
  }
10876
11019
  try {
10877
- const req = (0, import_node_module.createRequire)((0, import_node_path30.join)(process.cwd(), "package.json"));
10878
- return (0, import_node_path30.dirname)(req.resolve("@sideboard-ai/core"));
11020
+ const req = (0, import_node_module.createRequire)((0, import_node_path31.join)(process.cwd(), "package.json"));
11021
+ return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
10879
11022
  } catch {
10880
11023
  return process.cwd();
10881
11024
  }
10882
11025
  }
10883
11026
  function findSideboardMcpJsEntry() {
10884
11027
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
10885
- if (override && (0, import_node_fs28.existsSync)(override)) return override;
11028
+ if (override && (0, import_node_fs29.existsSync)(override)) return override;
10886
11029
  const packaged = packagedMcpStdioPath();
10887
11030
  if (packaged) return packaged;
10888
11031
  let dir = corePackageDir();
10889
11032
  for (let i = 0; i < 10; i++) {
10890
11033
  const candidates = [
10891
- (0, import_node_path30.join)(dir, "mcp/run-stdio.js"),
10892
- (0, import_node_path30.join)(dir, "mcp/run-stdio.cjs"),
10893
- (0, import_node_path30.join)(dir, "dist/mcp/run-stdio.js"),
10894
- (0, import_node_path30.join)(dir, "dist/mcp/run-stdio.cjs"),
10895
- (0, import_node_path30.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
10896
- (0, import_node_path30.join)(dir, "packages/cli/dist/index.js"),
10897
- (0, import_node_path30.join)(dir, "cli/dist/index.js")
11034
+ (0, import_node_path31.join)(dir, "mcp/run-stdio.js"),
11035
+ (0, import_node_path31.join)(dir, "mcp/run-stdio.cjs"),
11036
+ (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.js"),
11037
+ (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.cjs"),
11038
+ (0, import_node_path31.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
11039
+ (0, import_node_path31.join)(dir, "packages/cli/dist/index.js"),
11040
+ (0, import_node_path31.join)(dir, "cli/dist/index.js")
10898
11041
  ];
10899
11042
  for (const p of candidates) {
10900
- if ((0, import_node_fs28.existsSync)(p) && !isAsarPath(p)) return p;
11043
+ if ((0, import_node_fs29.existsSync)(p) && !isAsarPath(p)) return p;
10901
11044
  }
10902
- const parent = (0, import_node_path30.dirname)(dir);
11045
+ const parent = (0, import_node_path31.dirname)(dir);
10903
11046
  if (parent === dir) break;
10904
11047
  dir = parent;
10905
11048
  }
@@ -11046,22 +11189,22 @@ function writeMcpServersConfig(servers) {
11046
11189
  ...env ? { env } : {}
11047
11190
  };
11048
11191
  }
11049
- const dir = (0, import_node_fs28.mkdtempSync)((0, import_node_path30.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
11050
- const cfgPath = (0, import_node_path30.join)(dir, "mcp.json");
11051
- (0, import_node_fs28.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
11192
+ const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path31.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
11193
+ const cfgPath = (0, import_node_path31.join)(dir, "mcp.json");
11194
+ (0, import_node_fs29.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
11052
11195
  return cfgPath;
11053
11196
  }
11054
11197
  async function writeInjectedMcpConfig(opts) {
11055
11198
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
11056
11199
  }
11057
- var import_node_fs28, import_node_module, import_node_os9, import_node_path30, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
11200
+ var import_node_fs29, import_node_module, import_node_os9, import_node_path31, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
11058
11201
  var init_injected_mcp = __esm({
11059
11202
  "src/agents/injected-mcp.ts"() {
11060
11203
  "use strict";
11061
- import_node_fs28 = require("fs");
11204
+ import_node_fs29 = require("fs");
11062
11205
  import_node_module = require("module");
11063
11206
  import_node_os9 = require("os");
11064
- import_node_path30 = require("path");
11207
+ import_node_path31 = require("path");
11065
11208
  import_node_url = require("url");
11066
11209
  init_run();
11067
11210
  init_config();
@@ -11448,11 +11591,11 @@ function parseIssuesJson(raw) {
11448
11591
  }
11449
11592
  return [];
11450
11593
  }
11451
- var import_node_fs29, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, mcpListCache, claudeAdapter;
11594
+ var import_node_fs30, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, mcpListCache, claudeAdapter;
11452
11595
  var init_claude = __esm({
11453
11596
  "src/agents/claude.ts"() {
11454
11597
  "use strict";
11455
- import_node_fs29 = require("fs");
11598
+ import_node_fs30 = require("fs");
11456
11599
  init_run();
11457
11600
  init_app_settings();
11458
11601
  init_claude_mcp();
@@ -11492,7 +11635,7 @@ var init_claude = __esm({
11492
11635
  async detect() {
11493
11636
  const claude = resolveClaudeExecutable();
11494
11637
  if (claude !== "claude") {
11495
- if (!(0, import_node_fs29.existsSync)(claude)) {
11638
+ if (!(0, import_node_fs30.existsSync)(claude)) {
11496
11639
  return {
11497
11640
  agent: "claude",
11498
11641
  installed: false,
@@ -11752,10 +11895,10 @@ var init_claude = __esm({
11752
11895
 
11753
11896
  // src/agents/user-mcp-config.ts
11754
11897
  function userCursorMcpConfigPath() {
11755
- return (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
11898
+ return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
11756
11899
  }
11757
11900
  function userClaudeMcpConfigPath() {
11758
- return (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".claude.json");
11901
+ return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".claude.json");
11759
11902
  }
11760
11903
  function asObject(value) {
11761
11904
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -11782,16 +11925,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
11782
11925
  }
11783
11926
  function writeMergedMcpServersJson(configPath, sideboard) {
11784
11927
  let existing = {};
11785
- if ((0, import_node_fs30.existsSync)(configPath)) {
11928
+ if ((0, import_node_fs31.existsSync)(configPath)) {
11786
11929
  try {
11787
- existing = JSON.parse((0, import_node_fs30.readFileSync)(configPath, "utf8"));
11930
+ existing = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf8"));
11788
11931
  } catch {
11789
11932
  existing = {};
11790
11933
  }
11791
11934
  }
11792
11935
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
11793
- (0, import_node_fs30.mkdirSync)((0, import_node_path31.dirname)(configPath), { recursive: true });
11794
- (0, import_node_fs30.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
11936
+ (0, import_node_fs31.mkdirSync)((0, import_node_path32.dirname)(configPath), { recursive: true });
11937
+ (0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
11795
11938
  `);
11796
11939
  }
11797
11940
  function launchFromResolved(server) {
@@ -11809,19 +11952,19 @@ async function registerPackagedUserMcpClients() {
11809
11952
  const cursor = userCursorMcpConfigPath();
11810
11953
  writeMergedMcpServersJson(cursor, launch);
11811
11954
  const claude = userClaudeMcpConfigPath();
11812
- if ((0, import_node_fs30.existsSync)(claude)) {
11955
+ if ((0, import_node_fs31.existsSync)(claude)) {
11813
11956
  writeMergedMcpServersJson(claude, launch);
11814
11957
  return { cursor, claude };
11815
11958
  }
11816
11959
  return { cursor };
11817
11960
  }
11818
- var import_node_fs30, import_node_os10, import_node_path31;
11961
+ var import_node_fs31, import_node_os10, import_node_path32;
11819
11962
  var init_user_mcp_config = __esm({
11820
11963
  "src/agents/user-mcp-config.ts"() {
11821
11964
  "use strict";
11822
- import_node_fs30 = require("fs");
11965
+ import_node_fs31 = require("fs");
11823
11966
  import_node_os10 = require("os");
11824
- import_node_path31 = require("path");
11967
+ import_node_path32 = require("path");
11825
11968
  init_paths();
11826
11969
  init_injected_mcp();
11827
11970
  }
@@ -11849,25 +11992,25 @@ function listMcpNamesFromCodexToml(text7) {
11849
11992
  }
11850
11993
  function readJsonObject(path2) {
11851
11994
  try {
11852
- return JSON.parse((0, import_node_fs31.readFileSync)(path2, "utf8"));
11995
+ return JSON.parse((0, import_node_fs32.readFileSync)(path2, "utf8"));
11853
11996
  } catch {
11854
11997
  return {};
11855
11998
  }
11856
11999
  }
11857
12000
  function readText(path2) {
11858
12001
  try {
11859
- return (0, import_node_fs31.readFileSync)(path2, "utf8");
12002
+ return (0, import_node_fs32.readFileSync)(path2, "utf8");
11860
12003
  } catch {
11861
12004
  return "";
11862
12005
  }
11863
12006
  }
11864
12007
  function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
11865
- return [(0, import_node_path32.join)(home, ".codex", "config.toml"), (0, import_node_path32.join)(home, ".config", "codex", "config.toml")];
12008
+ return [(0, import_node_path33.join)(home, ".codex", "config.toml"), (0, import_node_path33.join)(home, ".config", "codex", "config.toml")];
11866
12009
  }
11867
12010
  function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
11868
12011
  return [
11869
- (0, import_node_path32.join)(home, ".config", "opencode", "opencode.json"),
11870
- (0, import_node_path32.join)(home, ".config", "opencode", "opencode.jsonc")
12012
+ (0, import_node_path33.join)(home, ".config", "opencode", "opencode.json"),
12013
+ (0, import_node_path33.join)(home, ".config", "opencode", "opencode.jsonc")
11871
12014
  ];
11872
12015
  }
11873
12016
  function userMcpNamesToDisable(opts) {
@@ -11889,7 +12032,7 @@ function userMcpNamesToDisable(opts) {
11889
12032
  function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
11890
12033
  const names = [];
11891
12034
  for (const path2 of userCodexConfigPaths(home)) {
11892
- if (!(0, import_node_fs31.existsSync)(path2)) continue;
12035
+ if (!(0, import_node_fs32.existsSync)(path2)) continue;
11893
12036
  names.push(...listMcpNamesFromCodexToml(readText(path2)));
11894
12037
  }
11895
12038
  return names;
@@ -11897,7 +12040,7 @@ function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
11897
12040
  function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
11898
12041
  const names = [];
11899
12042
  for (const path2 of userOpencodeConfigPaths(home)) {
11900
- if (!(0, import_node_fs31.existsSync)(path2)) continue;
12043
+ if (!(0, import_node_fs32.existsSync)(path2)) continue;
11901
12044
  names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
11902
12045
  }
11903
12046
  return names;
@@ -11910,13 +12053,13 @@ function toCodexDisableUserMcpArgs(names) {
11910
12053
  }
11911
12054
  return args;
11912
12055
  }
11913
- var import_node_fs31, import_node_os11, import_node_path32, import_smol_toml2;
12056
+ var import_node_fs32, import_node_os11, import_node_path33, import_smol_toml2;
11914
12057
  var init_orch_mcp_isolation = __esm({
11915
12058
  "src/agents/orch-mcp-isolation.ts"() {
11916
12059
  "use strict";
11917
- import_node_fs31 = require("fs");
12060
+ import_node_fs32 = require("fs");
11918
12061
  import_node_os11 = require("os");
11919
- import_node_path32 = require("path");
12062
+ import_node_path33 = require("path");
11920
12063
  import_smol_toml2 = require("smol-toml");
11921
12064
  init_user_mcp_config();
11922
12065
  }
@@ -11932,7 +12075,7 @@ async function listCodexModels() {
11932
12075
  if (codex === "codex") {
11933
12076
  const which = await run("which", ["codex"], { reject: false });
11934
12077
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
11935
- } else if (!(0, import_node_fs32.existsSync)(codex)) {
12078
+ } else if (!(0, import_node_fs33.existsSync)(codex)) {
11936
12079
  return FALLBACK_CODEX_MODELS;
11937
12080
  }
11938
12081
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -11967,12 +12110,12 @@ function usageFromCodex(usage) {
11967
12110
  }
11968
12111
  function codexConfigHasNetworkAccess() {
11969
12112
  const candidates = [
11970
- (0, import_node_path33.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
11971
- (0, import_node_path33.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
12113
+ (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
12114
+ (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
11972
12115
  ];
11973
12116
  for (const path2 of candidates) {
11974
- if (!(0, import_node_fs32.existsSync)(path2)) continue;
11975
- const text7 = (0, import_node_fs32.readFileSync)(path2, "utf8");
12117
+ if (!(0, import_node_fs33.existsSync)(path2)) continue;
12118
+ const text7 = (0, import_node_fs33.readFileSync)(path2, "utf8");
11976
12119
  if (/network_access\s*=\s*true/.test(text7)) return true;
11977
12120
  }
11978
12121
  return false;
@@ -12004,21 +12147,21 @@ function asRecord2(value) {
12004
12147
  return void 0;
12005
12148
  }
12006
12149
  function codexLooksAuthenticated() {
12007
- const authPath = (0, import_node_path33.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
12008
- if (!(0, import_node_fs32.existsSync)(authPath)) return false;
12150
+ const authPath = (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
12151
+ if (!(0, import_node_fs33.existsSync)(authPath)) return false;
12009
12152
  try {
12010
- return (0, import_node_fs32.statSync)(authPath).size > 2;
12153
+ return (0, import_node_fs33.statSync)(authPath).size > 2;
12011
12154
  } catch {
12012
12155
  return false;
12013
12156
  }
12014
12157
  }
12015
- var import_node_fs32, import_node_os12, import_node_path33, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
12158
+ var import_node_fs33, import_node_os12, import_node_path34, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
12016
12159
  var init_codex = __esm({
12017
12160
  "src/agents/codex.ts"() {
12018
12161
  "use strict";
12019
- import_node_fs32 = require("fs");
12162
+ import_node_fs33 = require("fs");
12020
12163
  import_node_os12 = require("os");
12021
- import_node_path33 = require("path");
12164
+ import_node_path34 = require("path");
12022
12165
  init_run();
12023
12166
  init_app_settings();
12024
12167
  init_global_workspace();
@@ -12044,7 +12187,7 @@ var init_codex = __esm({
12044
12187
  async detect() {
12045
12188
  const codex = resolveAgentExecutable("codex");
12046
12189
  if (codex !== "codex") {
12047
- if (!(0, import_node_fs32.existsSync)(codex)) {
12190
+ if (!(0, import_node_fs33.existsSync)(codex)) {
12048
12191
  return {
12049
12192
  agent: "codex",
12050
12193
  installed: false,
@@ -12539,21 +12682,21 @@ function platformRipgrepPackage() {
12539
12682
  }
12540
12683
  function usableRipgrepPath(candidate) {
12541
12684
  const raw = candidate?.trim();
12542
- if (!raw || !(0, import_node_path34.isAbsolute)(raw)) return null;
12685
+ if (!raw || !(0, import_node_path35.isAbsolute)(raw)) return null;
12543
12686
  const readable = nodeReadableScriptPath(raw);
12544
- if (!(0, import_node_fs33.existsSync)(readable) || isAsarPath(readable)) return null;
12687
+ if (!(0, import_node_fs34.existsSync)(readable) || isAsarPath(readable)) return null;
12545
12688
  return readable;
12546
12689
  }
12547
12690
  function walkForBundledRipgrep(startFile) {
12548
12691
  if (!startFile) return null;
12549
12692
  const pkg = platformRipgrepPackage();
12550
12693
  const name = rgBinaryName();
12551
- let dir = (0, import_node_path34.dirname)((0, import_node_path34.resolve)(startFile));
12552
- const root = (0, import_node_path34.parse)(dir).root;
12694
+ let dir = (0, import_node_path35.dirname)((0, import_node_path35.resolve)(startFile));
12695
+ const root = (0, import_node_path35.parse)(dir).root;
12553
12696
  while (dir !== root) {
12554
- const hit = usableRipgrepPath((0, import_node_path34.join)(dir, "node_modules", pkg, "bin", name));
12697
+ const hit = usableRipgrepPath((0, import_node_path35.join)(dir, "node_modules", pkg, "bin", name));
12555
12698
  if (hit) return hit;
12556
- const next = (0, import_node_path34.dirname)(dir);
12699
+ const next = (0, import_node_path35.dirname)(dir);
12557
12700
  if (next === dir) break;
12558
12701
  dir = next;
12559
12702
  }
@@ -12563,7 +12706,7 @@ function requireResolveBundledRipgrep(fromFile) {
12563
12706
  try {
12564
12707
  const req = (0, import_node_module2.createRequire)(fromFile);
12565
12708
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
12566
- return usableRipgrepPath((0, import_node_path34.join)((0, import_node_path34.dirname)(pkgJson), "bin", rgBinaryName()));
12709
+ return usableRipgrepPath((0, import_node_path35.join)((0, import_node_path35.dirname)(pkgJson), "bin", rgBinaryName()));
12567
12710
  } catch {
12568
12711
  return null;
12569
12712
  }
@@ -12585,13 +12728,13 @@ function cursorRipgrepEnv(opts) {
12585
12728
  const path2 = resolveCursorRipgrepPath(opts);
12586
12729
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
12587
12730
  }
12588
- var import_node_fs33, import_node_module2, import_node_path34, RIPGREP_ENV;
12731
+ var import_node_fs34, import_node_module2, import_node_path35, RIPGREP_ENV;
12589
12732
  var init_cursor_ripgrep = __esm({
12590
12733
  "src/agents/cursor-ripgrep.ts"() {
12591
12734
  "use strict";
12592
- import_node_fs33 = require("fs");
12735
+ import_node_fs34 = require("fs");
12593
12736
  import_node_module2 = require("module");
12594
- import_node_path34 = require("path");
12737
+ import_node_path35 = require("path");
12595
12738
  init_node_launch();
12596
12739
  init_packaged_runtime();
12597
12740
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -12604,6 +12747,9 @@ function resolveCursorApiKey() {
12604
12747
  if (fromEnv) return fromEnv;
12605
12748
  return (loadAppSettings().environment.CURSOR_API_KEY || "").trim();
12606
12749
  }
12750
+ function isCursorApiKeyConfigured() {
12751
+ return Boolean(resolveCursorApiKey());
12752
+ }
12607
12753
  function isCursorAutoModel(model) {
12608
12754
  const id = (model ?? "").trim().toLowerCase();
12609
12755
  return !id || id === "default" || id === "auto";
@@ -12637,11 +12783,11 @@ function entryDir() {
12637
12783
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12638
12784
  if (cjsDir) return cjsDir;
12639
12785
  try {
12640
- return (0, import_node_path35.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12786
+ return (0, import_node_path36.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12641
12787
  } catch {
12642
12788
  try {
12643
12789
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
12644
- return (0, import_node_path35.dirname)(req.resolve("@sideboard-ai/core"));
12790
+ return (0, import_node_path36.dirname)(req.resolve("@sideboard-ai/core"));
12645
12791
  } catch {
12646
12792
  return process.cwd();
12647
12793
  }
@@ -12652,27 +12798,27 @@ function cursorRunnerPath() {
12652
12798
  if (packaged) return packaged;
12653
12799
  const root = entryDir();
12654
12800
  const candidates = [
12655
- (0, import_node_path35.join)(root, "agents", "cursor-runner.js"),
12656
- (0, import_node_path35.join)(root, "agents", "cursor-runner.cjs"),
12801
+ (0, import_node_path36.join)(root, "agents", "cursor-runner.js"),
12802
+ (0, import_node_path36.join)(root, "agents", "cursor-runner.cjs"),
12657
12803
  // If somehow resolved from package root instead of dist/
12658
- (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.js"),
12659
- (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.cjs"),
12804
+ (0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.js"),
12805
+ (0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.cjs"),
12660
12806
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
12661
- (0, import_node_path35.join)(root, "cursor-runner.ts"),
12662
- (0, import_node_path35.join)(root, "src", "agents", "cursor-runner.ts")
12807
+ (0, import_node_path36.join)(root, "cursor-runner.ts"),
12808
+ (0, import_node_path36.join)(root, "src", "agents", "cursor-runner.ts")
12663
12809
  ];
12664
12810
  for (const candidate of candidates) {
12665
- if ((0, import_node_fs34.existsSync)(candidate)) return candidate;
12811
+ if ((0, import_node_fs35.existsSync)(candidate)) return candidate;
12666
12812
  }
12667
12813
  return candidates[0];
12668
12814
  }
12669
- var import_node_fs34, import_node_module3, import_node_path35, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12815
+ var import_node_fs35, import_node_module3, import_node_path36, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12670
12816
  var init_cursor = __esm({
12671
12817
  "src/agents/cursor.ts"() {
12672
12818
  "use strict";
12673
- import_node_fs34 = require("fs");
12819
+ import_node_fs35 = require("fs");
12674
12820
  import_node_module3 = require("module");
12675
- import_node_path35 = require("path");
12821
+ import_node_path36 = require("path");
12676
12822
  import_node_url2 = require("url");
12677
12823
  import_sdk = require("@cursor/sdk");
12678
12824
  init_run();
@@ -12824,7 +12970,7 @@ async function listOpencodeModels() {
12824
12970
  if (opencode === "opencode") {
12825
12971
  const which = await run("which", ["opencode"], { reject: false });
12826
12972
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
12827
- } else if (!(0, import_node_fs35.existsSync)(opencode)) {
12973
+ } else if (!(0, import_node_fs36.existsSync)(opencode)) {
12828
12974
  return FALLBACK_OPENCODE_MODELS;
12829
12975
  }
12830
12976
  const listed = await run(opencode, ["models"], { reject: false });
@@ -12854,11 +13000,11 @@ function usageFromOpencode(tokens) {
12854
13000
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
12855
13001
  };
12856
13002
  }
12857
- var import_node_fs35, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
13003
+ var import_node_fs36, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12858
13004
  var init_opencode = __esm({
12859
13005
  "src/agents/opencode.ts"() {
12860
13006
  "use strict";
12861
- import_node_fs35 = require("fs");
13007
+ import_node_fs36 = require("fs");
12862
13008
  init_run();
12863
13009
  init_app_settings();
12864
13010
  init_global_workspace();
@@ -12886,7 +13032,7 @@ var init_opencode = __esm({
12886
13032
  async detect() {
12887
13033
  const opencode = resolveAgentExecutable("opencode");
12888
13034
  if (opencode !== "opencode") {
12889
- if (!(0, import_node_fs35.existsSync)(opencode)) {
13035
+ if (!(0, import_node_fs36.existsSync)(opencode)) {
12890
13036
  return {
12891
13037
  agent: "opencode",
12892
13038
  installed: false,
@@ -13627,6 +13773,7 @@ __export(agents_exports, {
13627
13773
  installAgent: () => installAgent,
13628
13774
  installNpmGlobalPackage: () => installNpmGlobalPackage,
13629
13775
  isConductorBundledCli: () => isConductorBundledCli,
13776
+ isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
13630
13777
  isCursorAutoModel: () => isCursorAutoModel,
13631
13778
  isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
13632
13779
  isSessionQuotaLimit: () => isSessionQuotaLimit,
@@ -13695,15 +13842,15 @@ var init_agents = __esm({
13695
13842
 
13696
13843
  // src/hook/worktree-pkg-cache.ts
13697
13844
  function worktreePkgCacheRoot(worktreePath) {
13698
- return (0, import_node_path36.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13845
+ return (0, import_node_path37.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13699
13846
  }
13700
13847
  function worktreePkgCacheEnv(worktreePath) {
13701
13848
  const root = worktreePkgCacheRoot(worktreePath);
13702
- const store = (0, import_node_path36.join)(root, "pnpm-store");
13703
- const pnpmCache = (0, import_node_path36.join)(root, "pnpm");
13704
- const npmCache = (0, import_node_path36.join)(root, "npm");
13705
- const nodeGyp = (0, import_node_path36.join)(root, "node-gyp");
13706
- const electron = (0, import_node_path36.join)(root, "electron");
13849
+ const store = (0, import_node_path37.join)(root, "pnpm-store");
13850
+ const pnpmCache = (0, import_node_path37.join)(root, "pnpm");
13851
+ const npmCache = (0, import_node_path37.join)(root, "npm");
13852
+ const nodeGyp = (0, import_node_path37.join)(root, "node-gyp");
13853
+ const electron = (0, import_node_path37.join)(root, "electron");
13707
13854
  return {
13708
13855
  npm_config_store_dir: store,
13709
13856
  PNPM_STORE_DIR: store,
@@ -13725,8 +13872,8 @@ function fillGroup(env, keys, values) {
13725
13872
  }
13726
13873
  }
13727
13874
  function ensureWorktreePkgCacheDirs(worktreePath) {
13728
- if (!(0, import_node_fs36.existsSync)(worktreePath)) return;
13729
- (0, import_node_fs36.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13875
+ if (!(0, import_node_fs37.existsSync)(worktreePath)) return;
13876
+ (0, import_node_fs37.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13730
13877
  }
13731
13878
  function applyWorktreePkgCacheEnv(env, worktreePath) {
13732
13879
  const cwd = worktreePath.trim();
@@ -13739,12 +13886,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
13739
13886
  fillGroup(env, ["electron_config_cache"], next);
13740
13887
  ensureWorktreePkgCacheDirs(cwd);
13741
13888
  }
13742
- var import_node_fs36, import_node_path36, WORKTREE_PKG_CACHE_REL;
13889
+ var import_node_fs37, import_node_path37, WORKTREE_PKG_CACHE_REL;
13743
13890
  var init_worktree_pkg_cache = __esm({
13744
13891
  "src/hook/worktree-pkg-cache.ts"() {
13745
13892
  "use strict";
13746
- import_node_fs36 = require("fs");
13747
- import_node_path36 = require("path");
13893
+ import_node_fs37 = require("fs");
13894
+ import_node_path37 = require("path");
13748
13895
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
13749
13896
  }
13750
13897
  });
@@ -14065,6 +14212,8 @@ function agentGitPrompt(action, opts) {
14065
14212
  const named = base ? ` (${base})` : "";
14066
14213
  return `Merge the remote branch${named} into your branch and resolve conflicts. Then, commit and push your changes.`;
14067
14214
  }
14215
+ case "ready-for-review":
14216
+ return "Ready for review.";
14068
14217
  case "merge":
14069
14218
  return "Merge PR.";
14070
14219
  }
@@ -14079,6 +14228,8 @@ function gitActionExpansion(action, base) {
14079
14228
  return "Commit, push, then `gh pr create --web -R <origin-owner/name>`.";
14080
14229
  case "resolve-conflicts":
14081
14230
  return `Fetch the PR base${base ? ` (\`${base}\`)` : ""}, merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable.`;
14231
+ case "ready-for-review":
14232
+ return "This phrase is the explicit ask to mark this thread's draft pull request ready for review on GitHub (`gh pr ready -R <origin-owner/name>` or `gh pr ready`). Update title/body if the purpose drifted. Do not merge.";
14082
14233
  case "merge":
14083
14234
  return "This phrase is the explicit ask to merge this thread's open pull request on GitHub. If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.";
14084
14235
  }
@@ -14121,6 +14272,7 @@ var init_agent_git_actions = __esm({
14121
14272
  "create-draft",
14122
14273
  "create-web",
14123
14274
  "resolve-conflicts",
14275
+ "ready-for-review",
14124
14276
  "merge"
14125
14277
  ];
14126
14278
  RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
@@ -14892,21 +15044,21 @@ function shouldRefreshReviewRequestTemplate(content) {
14892
15044
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
14893
15045
  }
14894
15046
  function readTextIfPresent(abs) {
14895
- if (!(0, import_node_fs37.existsSync)(abs)) return null;
15047
+ if (!(0, import_node_fs38.existsSync)(abs)) return null;
14896
15048
  try {
14897
- const content = (0, import_node_fs37.readFileSync)(abs, "utf8");
15049
+ const content = (0, import_node_fs38.readFileSync)(abs, "utf8");
14898
15050
  return content.trim() ? content : null;
14899
15051
  } catch {
14900
15052
  return null;
14901
15053
  }
14902
15054
  }
14903
15055
  function readLocalGuidelines(worktreePath) {
14904
- const localAbs = (0, import_node_path37.join)(worktreePath, REVIEW_REQUEST_PATH);
15056
+ const localAbs = (0, import_node_path38.join)(worktreePath, REVIEW_REQUEST_PATH);
14905
15057
  const localContent = readTextIfPresent(localAbs);
14906
15058
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14907
15059
  return { path: REVIEW_REQUEST_PATH, content: localContent };
14908
15060
  }
14909
- const legacyAbs = (0, import_node_path37.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
15061
+ const legacyAbs = (0, import_node_path38.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14910
15062
  const legacyContent = readTextIfPresent(legacyAbs);
14911
15063
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
14912
15064
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -14930,27 +15082,27 @@ function contextGuidelines(content, source) {
14930
15082
  };
14931
15083
  }
14932
15084
  function writeContextGuidelines(worktreePath, content) {
14933
- const abs = (0, import_node_path37.join)(worktreePath, CONTEXT_REVIEW_PATH);
14934
- (0, import_node_fs37.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
15085
+ const abs = (0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH);
15086
+ (0, import_node_fs38.mkdirSync)((0, import_node_path38.dirname)(abs), { recursive: true });
14935
15087
  const body = content.endsWith("\n") ? content : `${content}
14936
15088
  `;
14937
- (0, import_node_fs37.writeFileSync)(abs, body, "utf8");
15089
+ (0, import_node_fs38.writeFileSync)(abs, body, "utf8");
14938
15090
  return body;
14939
15091
  }
14940
15092
  function readSideboardReview(worktreePath, repoPath) {
14941
- const fromWorktree = readTextIfPresent((0, import_node_path37.join)(worktreePath, REPO_REVIEW_PATH));
15093
+ const fromWorktree = readTextIfPresent((0, import_node_path38.join)(worktreePath, REPO_REVIEW_PATH));
14942
15094
  if (fromWorktree) return fromWorktree;
14943
15095
  const repo = repoPath?.replace(/\/+$/, "");
14944
15096
  const wt = worktreePath.replace(/\/+$/, "");
14945
15097
  if (!repo || repo === wt) return null;
14946
- return readTextIfPresent((0, import_node_path37.join)(repo, REPO_REVIEW_PATH));
15098
+ return readTextIfPresent((0, import_node_path38.join)(repo, REPO_REVIEW_PATH));
14947
15099
  }
14948
15100
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
14949
- const skillContent = readTextIfPresent((0, import_node_path37.join)(worktreePath, REVIEW_SKILL_PATH));
15101
+ const skillContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_SKILL_PATH));
14950
15102
  if (skillContent) {
14951
15103
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
14952
15104
  }
14953
- const contextContent = readTextIfPresent((0, import_node_path37.join)(worktreePath, CONTEXT_REVIEW_PATH));
15105
+ const contextContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH));
14954
15106
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
14955
15107
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
14956
15108
  }
@@ -14988,7 +15140,7 @@ function buildReviewRequestAttachment(content, opts) {
14988
15140
  };
14989
15141
  }
14990
15142
  function readExistingReviewRequestFile(worktreePath) {
14991
- return readTextIfPresent((0, import_node_path37.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
15143
+ return readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path38.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14992
15144
  }
14993
15145
  async function requestReview(threadRef, send2) {
14994
15146
  const from = findThreadByRef(threadRef);
@@ -15015,13 +15167,13 @@ async function requestReview(threadRef, send2) {
15015
15167
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
15016
15168
  return { tab: started, from };
15017
15169
  }
15018
- var import_node_crypto8, import_node_fs37, import_node_path37, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
15170
+ var import_node_crypto8, import_node_fs38, import_node_path38, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
15019
15171
  var init_request_review = __esm({
15020
15172
  "src/review/request-review.ts"() {
15021
15173
  "use strict";
15022
15174
  import_node_crypto8 = require("crypto");
15023
- import_node_fs37 = require("fs");
15024
- import_node_path37 = require("path");
15175
+ import_node_fs38 = require("fs");
15176
+ import_node_path38 = require("path");
15025
15177
  init_global_workspace();
15026
15178
  init_chat_tabs();
15027
15179
  init_thread_store();
@@ -15047,9 +15199,9 @@ function matchSimpleGlob(pattern, name) {
15047
15199
  return new RegExp(`^${escaped}$`).test(name);
15048
15200
  }
15049
15201
  function readWorktreeInclude(repoPath) {
15050
- const path2 = (0, import_node_path38.join)(repoPath, ".worktreeinclude");
15051
- if (!(0, import_node_fs38.existsSync)(path2)) return [];
15052
- return (0, import_node_fs38.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
15202
+ const path2 = (0, import_node_path39.join)(repoPath, ".worktreeinclude");
15203
+ if (!(0, import_node_fs39.existsSync)(path2)) return [];
15204
+ return (0, import_node_fs39.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
15053
15205
  }
15054
15206
  function resolveFilesToCopy(repoPath) {
15055
15207
  const fromInclude = readWorktreeInclude(repoPath);
@@ -15059,10 +15211,10 @@ function resolveFilesToCopy(repoPath) {
15059
15211
  if (settings?.fileIncludeGlobs?.length) {
15060
15212
  const matched = [];
15061
15213
  try {
15062
- for (const entry of (0, import_node_fs38.readdirSync)(repoPath, { withFileTypes: true })) {
15214
+ for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
15063
15215
  if (!entry.isFile()) continue;
15064
15216
  for (const glob of settings.fileIncludeGlobs) {
15065
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path38.basename)(glob), entry.name)) {
15217
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path39.basename)(glob), entry.name)) {
15066
15218
  matched.push(entry.name);
15067
15219
  break;
15068
15220
  }
@@ -15074,7 +15226,7 @@ function resolveFilesToCopy(repoPath) {
15074
15226
  }
15075
15227
  const defaults = [];
15076
15228
  try {
15077
- for (const entry of (0, import_node_fs38.readdirSync)(repoPath, { withFileTypes: true })) {
15229
+ for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
15078
15230
  if (entry.isFile() && entry.name.startsWith(".env")) {
15079
15231
  defaults.push(entry.name);
15080
15232
  }
@@ -15088,11 +15240,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
15088
15240
  const patterns = resolveFilesToCopy(repoPath);
15089
15241
  const copied = [];
15090
15242
  for (const rel of patterns) {
15091
- const src = (0, import_node_path38.join)(repoPath, rel);
15092
- if (!(0, import_node_fs38.existsSync)(src)) continue;
15093
- const dest = (0, import_node_path38.join)(worktreePath, rel);
15094
- (0, import_node_fs38.mkdirSync)((0, import_node_path38.dirname)(dest), { recursive: true });
15095
- (0, import_node_fs38.copyFileSync)(src, dest);
15243
+ const src = (0, import_node_path39.join)(repoPath, rel);
15244
+ if (!(0, import_node_fs39.existsSync)(src)) continue;
15245
+ const dest = (0, import_node_path39.join)(worktreePath, rel);
15246
+ (0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(dest), { recursive: true });
15247
+ (0, import_node_fs39.copyFileSync)(src, dest);
15096
15248
  copied.push(rel);
15097
15249
  }
15098
15250
  return copied;
@@ -15127,7 +15279,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
15127
15279
  const env = stripNestedElectronEnv({
15128
15280
  ...baseEnv ?? process.env
15129
15281
  });
15130
- const name = opts.workspaceName ?? (0, import_node_path38.basename)(opts.worktreePath);
15282
+ const name = opts.workspaceName ?? (0, import_node_path39.basename)(opts.worktreePath);
15131
15283
  const ports = opts.ports ?? [];
15132
15284
  const primary = ports[0];
15133
15285
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -15390,13 +15542,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
15390
15542
  done: handle.done
15391
15543
  };
15392
15544
  }
15393
- var import_node_fs38, import_node_net, import_node_path38, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
15545
+ var import_node_fs39, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
15394
15546
  var init_conductor = __esm({
15395
15547
  "src/hook/conductor.ts"() {
15396
15548
  "use strict";
15397
- import_node_fs38 = require("fs");
15549
+ import_node_fs39 = require("fs");
15398
15550
  import_node_net = require("net");
15399
- import_node_path38 = require("path");
15551
+ import_node_path39 = require("path");
15400
15552
  import_execa4 = require("execa");
15401
15553
  import_node_readline3 = require("readline");
15402
15554
  init_settings();
@@ -15424,9 +15576,9 @@ async function findOrphanWorktrees(repoPaths) {
15424
15576
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
15425
15577
  );
15426
15578
  const homeRoot = sideboardWorkspacesDir();
15427
- if ((0, import_node_fs39.existsSync)(homeRoot)) {
15579
+ if ((0, import_node_fs40.existsSync)(homeRoot)) {
15428
15580
  try {
15429
- for (const entry of (0, import_node_fs39.readdirSync)(homeRoot, { withFileTypes: true })) {
15581
+ for (const entry of (0, import_node_fs40.readdirSync)(homeRoot, { withFileTypes: true })) {
15430
15582
  if (!entry.isDirectory()) continue;
15431
15583
  void entry;
15432
15584
  }
@@ -15436,7 +15588,7 @@ async function findOrphanWorktrees(repoPaths) {
15436
15588
  const orphans = [];
15437
15589
  const seen = /* @__PURE__ */ new Set();
15438
15590
  for (const repoPath of repos) {
15439
- if (!repoPath || !(0, import_node_fs39.existsSync)(repoPath)) continue;
15591
+ if (!repoPath || !(0, import_node_fs40.existsSync)(repoPath)) continue;
15440
15592
  try {
15441
15593
  const wts = await listWorktrees(repoPath);
15442
15594
  for (const wt of wts) {
@@ -15447,7 +15599,7 @@ async function findOrphanWorktrees(repoPaths) {
15447
15599
  seen.add(path2);
15448
15600
  let mtimeMs = 0;
15449
15601
  try {
15450
- mtimeMs = (0, import_node_fs39.statSync)(path2).mtimeMs;
15602
+ mtimeMs = (0, import_node_fs40.statSync)(path2).mtimeMs;
15451
15603
  } catch {
15452
15604
  mtimeMs = 0;
15453
15605
  }
@@ -15457,16 +15609,16 @@ async function findOrphanWorktrees(repoPaths) {
15457
15609
  }
15458
15610
  try {
15459
15611
  const root = worktreesRoot(repoPath);
15460
- if ((0, import_node_fs39.existsSync)(root)) {
15461
- for (const entry of (0, import_node_fs39.readdirSync)(root, { withFileTypes: true })) {
15612
+ if ((0, import_node_fs40.existsSync)(root)) {
15613
+ for (const entry of (0, import_node_fs40.readdirSync)(root, { withFileTypes: true })) {
15462
15614
  if (!entry.isDirectory()) continue;
15463
- const path2 = (0, import_node_path39.join)(root, entry.name).replace(/\/$/, "");
15615
+ const path2 = (0, import_node_path40.join)(root, entry.name).replace(/\/$/, "");
15464
15616
  if (known.has(path2) || seen.has(path2)) continue;
15465
- if (!(0, import_node_fs39.existsSync)((0, import_node_path39.join)(path2, ".git"))) continue;
15617
+ if (!(0, import_node_fs40.existsSync)((0, import_node_path40.join)(path2, ".git"))) continue;
15466
15618
  seen.add(path2);
15467
15619
  let mtimeMs = 0;
15468
15620
  try {
15469
- mtimeMs = (0, import_node_fs39.statSync)(path2).mtimeMs;
15621
+ mtimeMs = (0, import_node_fs40.statSync)(path2).mtimeMs;
15470
15622
  } catch {
15471
15623
  mtimeMs = Date.now();
15472
15624
  }
@@ -15527,12 +15679,12 @@ function worktreeCleanupSettings() {
15527
15679
  autoCleanupOrphans: a.autoCleanupOrphans
15528
15680
  };
15529
15681
  }
15530
- var import_node_fs39, import_node_path39;
15682
+ var import_node_fs40, import_node_path40;
15531
15683
  var init_orphan_cleanup = __esm({
15532
15684
  "src/git/orphan-cleanup.ts"() {
15533
15685
  "use strict";
15534
- import_node_fs39 = require("fs");
15535
- import_node_path39 = require("path");
15686
+ import_node_fs40 = require("fs");
15687
+ import_node_path40 = require("path");
15536
15688
  init_worktree();
15537
15689
  init_thread_store();
15538
15690
  init_paths();
@@ -15635,12 +15787,12 @@ async function cloneRepoIntoSideboard(opts) {
15635
15787
  if (!url) throw new Error("Clone URL is required");
15636
15788
  let name = opts.name?.trim();
15637
15789
  if (!name) {
15638
- const leaf = (0, import_node_path40.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15790
+ const leaf = (0, import_node_path41.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15639
15791
  name = leaf || "repo";
15640
15792
  }
15641
15793
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
15642
- const dest = (0, import_node_path40.join)(sideboardReposDir(), name);
15643
- if ((0, import_node_fs40.existsSync)(dest)) {
15794
+ const dest = (0, import_node_path41.join)(sideboardReposDir(), name);
15795
+ if ((0, import_node_fs41.existsSync)(dest)) {
15644
15796
  const repoPath2 = await resolveRepoRoot(dest);
15645
15797
  const workspace2 = await ensureWorkspace(repoPath2);
15646
15798
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -15655,12 +15807,12 @@ async function cloneRepoIntoSideboard(opts) {
15655
15807
  const workspace = await ensureWorkspace(repoPath);
15656
15808
  return { repoPath, workspace };
15657
15809
  }
15658
- var import_node_fs40, import_node_path40, import_execa6;
15810
+ var import_node_fs41, import_node_path41, import_execa6;
15659
15811
  var init_clone_repo = __esm({
15660
15812
  "src/git/clone-repo.ts"() {
15661
15813
  "use strict";
15662
- import_node_fs40 = require("fs");
15663
- import_node_path40 = require("path");
15814
+ import_node_fs41 = require("fs");
15815
+ import_node_path41 = require("path");
15664
15816
  import_execa6 = require("execa");
15665
15817
  init_paths();
15666
15818
  init_workspaces();
@@ -15778,24 +15930,24 @@ function jobTreeAlive(pid) {
15778
15930
  return jobAlive(pid) || processGroupAlive(pid);
15779
15931
  }
15780
15932
  function readIntFile(file) {
15781
- if (!(0, import_node_fs41.existsSync)(file)) return null;
15782
- const n = Number.parseInt((0, import_node_fs41.readFileSync)(file, "utf8").trim(), 10);
15933
+ if (!(0, import_node_fs42.existsSync)(file)) return null;
15934
+ const n = Number.parseInt((0, import_node_fs42.readFileSync)(file, "utf8").trim(), 10);
15783
15935
  return Number.isInteger(n) ? n : null;
15784
15936
  }
15785
15937
  function jobDir(root, id, legacy = false) {
15786
- return (0, import_node_path41.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15938
+ return (0, import_node_path42.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15787
15939
  }
15788
15940
  function resolveJobDir(root, id) {
15789
15941
  const modern = jobDir(root, id, false);
15790
- if ((0, import_node_fs41.existsSync)(modern)) return modern;
15942
+ if ((0, import_node_fs42.existsSync)(modern)) return modern;
15791
15943
  const legacy = jobDir(root, id, true);
15792
- if ((0, import_node_fs41.existsSync)(legacy)) return legacy;
15944
+ if ((0, import_node_fs42.existsSync)(legacy)) return legacy;
15793
15945
  return modern;
15794
15946
  }
15795
15947
  function listJobIdsIn(root, rel) {
15796
- const dir = (0, import_node_path41.join)(root, rel);
15797
- if (!(0, import_node_fs41.existsSync)(dir)) return [];
15798
- return (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15948
+ const dir = (0, import_node_path42.join)(root, rel);
15949
+ if (!(0, import_node_fs42.existsSync)(dir)) return [];
15950
+ return (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15799
15951
  }
15800
15952
  function listRunningDetachedJobs(worktreePath) {
15801
15953
  const root = worktreePath.trim();
@@ -15807,7 +15959,7 @@ function listRunningDetachedJobs(worktreePath) {
15807
15959
  const running = [];
15808
15960
  for (const id of ids) {
15809
15961
  const dir = resolveJobDir(root, id);
15810
- const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
15962
+ const pid = readIntFile((0, import_node_path42.join)(dir, "pid"));
15811
15963
  if (jobTreeAlive(pid)) running.push(id);
15812
15964
  }
15813
15965
  return running.sort();
@@ -15860,13 +16012,13 @@ function planJobContinue(opts) {
15860
16012
  return { action: "none" };
15861
16013
  }
15862
16014
  function tailProgress(logFile, maxLines = 12) {
15863
- if (!(0, import_node_fs41.existsSync)(logFile)) return "(no log yet)";
15864
- const lines = (0, import_node_fs41.readFileSync)(logFile, "utf8").split("\n");
16015
+ if (!(0, import_node_fs42.existsSync)(logFile)) return "(no log yet)";
16016
+ const lines = (0, import_node_fs42.readFileSync)(logFile, "utf8").split("\n");
15865
16017
  return lines.slice(-maxLines).join("\n");
15866
16018
  }
15867
16019
  function readLogLines(file) {
15868
- if (!(0, import_node_fs41.existsSync)(file)) return [];
15869
- const lines = (0, import_node_fs41.readFileSync)(file, "utf8").split("\n");
16020
+ if (!(0, import_node_fs42.existsSync)(file)) return [];
16021
+ const lines = (0, import_node_fs42.readFileSync)(file, "utf8").split("\n");
15870
16022
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
15871
16023
  return lines;
15872
16024
  }
@@ -15877,15 +16029,15 @@ function takeDelta(logFile, cursorFile) {
15877
16029
  return { delta: lines.slice(start).join("\n"), nextCursor: lines.length };
15878
16030
  }
15879
16031
  function snapshotJob(dir) {
15880
- const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
16032
+ const pid = readIntFile((0, import_node_path42.join)(dir, "pid"));
15881
16033
  const running = jobTreeAlive(pid);
15882
16034
  return {
15883
16035
  pid,
15884
16036
  running,
15885
- exitCode: readIntFile((0, import_node_path41.join)(dir, "exit")),
15886
- log: (0, import_node_path41.join)(dir, "log"),
15887
- cursor: (0, import_node_path41.join)(dir, "present.cursor"),
15888
- progress: tailProgress((0, import_node_path41.join)(dir, "log"))
16037
+ exitCode: readIntFile((0, import_node_path42.join)(dir, "exit")),
16038
+ log: (0, import_node_path42.join)(dir, "log"),
16039
+ cursor: (0, import_node_path42.join)(dir, "present.cursor"),
16040
+ progress: tailProgress((0, import_node_path42.join)(dir, "log"))
15889
16041
  };
15890
16042
  }
15891
16043
  function toResult(id, snap, extra) {
@@ -15894,8 +16046,8 @@ function toResult(id, snap, extra) {
15894
16046
  const stillRunning = snap.running && !ok;
15895
16047
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
15896
16048
  try {
15897
- (0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(snap.cursor), { recursive: true });
15898
- (0, import_node_fs41.writeFileSync)(snap.cursor, `${nextCursor}
16049
+ (0, import_node_fs42.mkdirSync)((0, import_node_path42.dirname)(snap.cursor), { recursive: true });
16050
+ (0, import_node_fs42.writeFileSync)(snap.cursor, `${nextCursor}
15899
16051
  `);
15900
16052
  } catch {
15901
16053
  }
@@ -15922,7 +16074,7 @@ async function waitForDetachedJob(cwd, id, opts) {
15922
16074
  const dir = resolveJobDir(root, jobId);
15923
16075
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
15924
16076
  const sleep2 = opts?.sleep ?? sleepMs;
15925
- if (!(0, import_node_fs41.existsSync)(dir)) {
16077
+ if (!(0, import_node_fs42.existsSync)(dir)) {
15926
16078
  return {
15927
16079
  stillRunning: false,
15928
16080
  ok: false,
@@ -15968,10 +16120,10 @@ function killProcessTree(pid, signal) {
15968
16120
  }
15969
16121
  function appendJobLog(logFile, line) {
15970
16122
  try {
15971
- (0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(logFile), { recursive: true });
16123
+ (0, import_node_fs42.mkdirSync)((0, import_node_path42.dirname)(logFile), { recursive: true });
15972
16124
  const body = line.endsWith("\n") ? line : `${line}
15973
16125
  `;
15974
- (0, import_node_fs41.appendFileSync)(logFile, body);
16126
+ (0, import_node_fs42.appendFileSync)(logFile, body);
15975
16127
  } catch {
15976
16128
  }
15977
16129
  }
@@ -15981,7 +16133,7 @@ async function stopDetachedJob(cwd, id, opts) {
15981
16133
  const dir = resolveJobDir(root, jobId);
15982
16134
  const sleep2 = opts?.sleep ?? sleepMs;
15983
16135
  const why = opts?.reason?.trim() ?? "";
15984
- if (!(0, import_node_fs41.existsSync)(dir)) {
16136
+ if (!(0, import_node_fs42.existsSync)(dir)) {
15985
16137
  return {
15986
16138
  stillRunning: false,
15987
16139
  ok: false,
@@ -16017,10 +16169,10 @@ async function stopDetachedJob(cwd, id, opts) {
16017
16169
  killProcessTree(targetPid, "SIGKILL");
16018
16170
  await sleep2(100);
16019
16171
  }
16020
- const exitFile = (0, import_node_path41.join)(dir, "exit");
16021
- if (!(0, import_node_fs41.existsSync)(exitFile)) {
16172
+ const exitFile = (0, import_node_path42.join)(dir, "exit");
16173
+ if (!(0, import_node_fs42.existsSync)(exitFile)) {
16022
16174
  try {
16023
- (0, import_node_fs41.writeFileSync)(exitFile, "1\n");
16175
+ (0, import_node_fs42.writeFileSync)(exitFile, "1\n");
16024
16176
  } catch {
16025
16177
  }
16026
16178
  }
@@ -16040,12 +16192,12 @@ async function stopDetachedJob(cwd, id, opts) {
16040
16192
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
16041
16193
  };
16042
16194
  }
16043
- var import_node_fs41, import_node_path41, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
16195
+ var import_node_fs42, import_node_path42, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
16044
16196
  var init_wait_for_job = __esm({
16045
16197
  "src/mcp/wait-for-job.ts"() {
16046
16198
  "use strict";
16047
- import_node_fs41 = require("fs");
16048
- import_node_path41 = require("path");
16199
+ import_node_fs42 = require("fs");
16200
+ import_node_path42 = require("path");
16049
16201
  init_workspace_scratch();
16050
16202
  init_wait_for_turn();
16051
16203
  MAX_JOB_CONTINUES = 8;
@@ -17182,7 +17334,7 @@ function reuseLiveThread(input, repoPath, match) {
17182
17334
  }
17183
17335
  async function createThread(input, _onSetupLine) {
17184
17336
  const repoPath = await resolveRepoRoot(input.repoPath);
17185
- if (!(0, import_node_fs42.existsSync)(repoPath)) {
17337
+ if (!(0, import_node_fs43.existsSync)(repoPath)) {
17186
17338
  throw new Error(`Repo not found: ${repoPath}`);
17187
17339
  }
17188
17340
  const reused = reuseLiveThread(input, repoPath, {
@@ -17363,11 +17515,11 @@ async function listLinearIssues(agent, repoPath) {
17363
17515
  }
17364
17516
  return adapter.listLinearIssues(repoPath);
17365
17517
  }
17366
- var import_node_fs42;
17518
+ var import_node_fs43;
17367
17519
  var init_create = __esm({
17368
17520
  "src/threads/create.ts"() {
17369
17521
  "use strict";
17370
- import_node_fs42 = require("fs");
17522
+ import_node_fs43 = require("fs");
17371
17523
  init_detect();
17372
17524
  init_worktree();
17373
17525
  init_home_board();
@@ -17487,20 +17639,20 @@ function writeTurnLive(threadId, progress) {
17487
17639
  const path2 = threadLivePath(threadId);
17488
17640
  const tmp = `${path2}.${process.pid}.tmp`;
17489
17641
  try {
17490
- (0, import_node_fs43.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
17491
- (0, import_node_fs43.renameSync)(tmp, path2);
17642
+ (0, import_node_fs44.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
17643
+ (0, import_node_fs44.renameSync)(tmp, path2);
17492
17644
  } catch {
17493
17645
  try {
17494
- (0, import_node_fs43.unlinkSync)(tmp);
17646
+ (0, import_node_fs44.unlinkSync)(tmp);
17495
17647
  } catch {
17496
17648
  }
17497
17649
  }
17498
17650
  }
17499
17651
  function readTurnLive(threadId) {
17500
17652
  const path2 = threadLivePath(threadId);
17501
- if (!(0, import_node_fs43.existsSync)(path2)) return null;
17653
+ if (!(0, import_node_fs44.existsSync)(path2)) return null;
17502
17654
  try {
17503
- const raw = JSON.parse((0, import_node_fs43.readFileSync)(path2, "utf8"));
17655
+ const raw = JSON.parse((0, import_node_fs44.readFileSync)(path2, "utf8"));
17504
17656
  if (!raw || typeof raw.summary !== "string") return null;
17505
17657
  return raw;
17506
17658
  } catch {
@@ -17512,17 +17664,17 @@ function clearTurnLive(threadId) {
17512
17664
  if (buf?.timer) clearTimeout(buf.timer);
17513
17665
  buffers.delete(threadId);
17514
17666
  const path2 = threadLivePath(threadId);
17515
- if (!(0, import_node_fs43.existsSync)(path2)) return;
17667
+ if (!(0, import_node_fs44.existsSync)(path2)) return;
17516
17668
  try {
17517
- (0, import_node_fs43.unlinkSync)(path2);
17669
+ (0, import_node_fs44.unlinkSync)(path2);
17518
17670
  } catch {
17519
17671
  }
17520
17672
  }
17521
- var import_node_fs43, buffers, FLUSH_MS, MAX_PARTS;
17673
+ var import_node_fs44, buffers, FLUSH_MS, MAX_PARTS;
17522
17674
  var init_turn_live = __esm({
17523
17675
  "src/store/turn-live.ts"() {
17524
17676
  "use strict";
17525
- import_node_fs43 = require("fs");
17677
+ import_node_fs44 = require("fs");
17526
17678
  init_message_parts();
17527
17679
  init_paths();
17528
17680
  buffers = /* @__PURE__ */ new Map();
@@ -17742,7 +17894,7 @@ var init_quota_failover = __esm({
17742
17894
  // src/threads/adopt.ts
17743
17895
  function thisModuleFile() {
17744
17896
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
17745
- return cjsFile || process.argv[1] || (0, import_node_path42.join)(process.cwd(), "package.json");
17897
+ return cjsFile || process.argv[1] || (0, import_node_path43.join)(process.cwd(), "package.json");
17746
17898
  }
17747
17899
  function openReadonlySqlite(file) {
17748
17900
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -17760,21 +17912,21 @@ function mapAgentType(raw) {
17760
17912
  return null;
17761
17913
  }
17762
17914
  function resolveConductorCursorAgentId(workspacePath) {
17763
- if (!workspacePath || !(0, import_node_fs44.existsSync)(CURSOR_SDK_STORE)) return null;
17915
+ if (!workspacePath || !(0, import_node_fs45.existsSync)(CURSOR_SDK_STORE)) return null;
17764
17916
  const normalized = workspacePath.replace(/\/$/, "");
17765
17917
  let best = null;
17766
17918
  let hashes;
17767
17919
  try {
17768
- hashes = (0, import_node_fs44.readdirSync)(CURSOR_SDK_STORE);
17920
+ hashes = (0, import_node_fs45.readdirSync)(CURSOR_SDK_STORE);
17769
17921
  } catch {
17770
17922
  return null;
17771
17923
  }
17772
17924
  for (const hash of hashes) {
17773
- const agentsFile = (0, import_node_path42.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
17774
- if (!(0, import_node_fs44.existsSync)(agentsFile)) continue;
17925
+ const agentsFile = (0, import_node_path43.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
17926
+ if (!(0, import_node_fs45.existsSync)(agentsFile)) continue;
17775
17927
  let text7;
17776
17928
  try {
17777
- text7 = (0, import_node_fs44.readFileSync)(agentsFile, "utf8");
17929
+ text7 = (0, import_node_fs45.readFileSync)(agentsFile, "utf8");
17778
17930
  } catch {
17779
17931
  continue;
17780
17932
  }
@@ -17798,7 +17950,7 @@ function resolveConductorCursorAgentId(workspacePath) {
17798
17950
  return best?.agentId ?? null;
17799
17951
  }
17800
17952
  async function adoptThread(input) {
17801
- if (!(0, import_node_fs44.existsSync)(input.worktreePath)) {
17953
+ if (!(0, import_node_fs45.existsSync)(input.worktreePath)) {
17802
17954
  throw new Error(`Worktree not found: ${input.worktreePath}`);
17803
17955
  }
17804
17956
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -17827,18 +17979,18 @@ function conductorDbPath() {
17827
17979
  return CONDUCTOR_DB;
17828
17980
  }
17829
17981
  function listConductorWorkspaces() {
17830
- if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
17982
+ if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
17831
17983
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
17832
17984
  }
17833
- const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17834
- const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
17985
+ const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path43.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17986
+ const snapshot = (0, import_node_path43.join)(tmp, "conductor.db");
17835
17987
  try {
17836
- (0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
17988
+ (0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
17837
17989
  for (const suffix of ["-wal", "-shm"]) {
17838
17990
  const src = `${CONDUCTOR_DB}${suffix}`;
17839
- if ((0, import_node_fs44.existsSync)(src)) {
17991
+ if ((0, import_node_fs45.existsSync)(src)) {
17840
17992
  try {
17841
- (0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
17993
+ (0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
17842
17994
  } catch {
17843
17995
  }
17844
17996
  }
@@ -17914,22 +18066,22 @@ function listConductorWorkspaces() {
17914
18066
  db.close();
17915
18067
  }
17916
18068
  } finally {
17917
- (0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
18069
+ (0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
17918
18070
  }
17919
18071
  }
17920
18072
  function importConductorWorkspace(workspaceId) {
17921
- if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
18073
+ if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
17922
18074
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
17923
18075
  }
17924
- const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17925
- const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
18076
+ const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path43.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
18077
+ const snapshot = (0, import_node_path43.join)(tmp, "conductor.db");
17926
18078
  try {
17927
- (0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
18079
+ (0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
17928
18080
  for (const suffix of ["-wal", "-shm"]) {
17929
18081
  const src = `${CONDUCTOR_DB}${suffix}`;
17930
- if ((0, import_node_fs44.existsSync)(src)) {
18082
+ if ((0, import_node_fs45.existsSync)(src)) {
17931
18083
  try {
17932
- (0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
18084
+ (0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
17933
18085
  } catch {
17934
18086
  }
17935
18087
  }
@@ -17947,7 +18099,7 @@ function importConductorWorkspace(workspaceId) {
17947
18099
  ).get(workspaceId);
17948
18100
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
17949
18101
  const worktreePath = String(row.workspacePath);
17950
- if (!(0, import_node_fs44.existsSync)(worktreePath)) {
18102
+ if (!(0, import_node_fs45.existsSync)(worktreePath)) {
17951
18103
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
17952
18104
  }
17953
18105
  let sessionId = null;
@@ -17987,7 +18139,7 @@ function importConductorWorkspace(workspaceId) {
17987
18139
  }
17988
18140
  let repoPath = worktreePath;
17989
18141
  try {
17990
- repoPath = (0, import_node_child_process4.execFileSync)("git", ["rev-parse", "--show-toplevel"], {
18142
+ repoPath = (0, import_node_child_process5.execFileSync)("git", ["rev-parse", "--show-toplevel"], {
17991
18143
  cwd: worktreePath,
17992
18144
  encoding: "utf8"
17993
18145
  }).trim();
@@ -18010,31 +18162,31 @@ function importConductorWorkspace(workspaceId) {
18010
18162
  db.close();
18011
18163
  }
18012
18164
  } finally {
18013
- (0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
18165
+ (0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
18014
18166
  }
18015
18167
  }
18016
18168
  async function importConductorWorkspaceAsync(workspaceId) {
18017
18169
  return importConductorWorkspace(workspaceId);
18018
18170
  }
18019
- var import_node_child_process4, import_node_fs44, import_node_os13, import_node_path42, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
18171
+ var import_node_child_process5, import_node_fs45, import_node_os13, import_node_path43, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
18020
18172
  var init_adopt = __esm({
18021
18173
  "src/threads/adopt.ts"() {
18022
18174
  "use strict";
18023
- import_node_child_process4 = require("child_process");
18024
- import_node_fs44 = require("fs");
18175
+ import_node_child_process5 = require("child_process");
18176
+ import_node_fs45 = require("fs");
18025
18177
  import_node_os13 = require("os");
18026
- import_node_path42 = require("path");
18178
+ import_node_path43 = require("path");
18027
18179
  import_node_module4 = require("module");
18028
18180
  init_worktree();
18029
18181
  init_thread_store();
18030
- CONDUCTOR_APP_SUPPORT = (0, import_node_path42.join)(
18182
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path43.join)(
18031
18183
  process.env.HOME ?? "",
18032
18184
  "Library",
18033
18185
  "Application Support",
18034
18186
  "com.conductor.app"
18035
18187
  );
18036
- CONDUCTOR_DB = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18037
- CURSOR_SDK_STORE = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18188
+ CONDUCTOR_DB = (0, import_node_path43.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18189
+ CURSOR_SDK_STORE = (0, import_node_path43.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18038
18190
  }
18039
18191
  });
18040
18192
 
@@ -18101,7 +18253,7 @@ async function openStackLayer(input, _onSetupLine) {
18101
18253
  let createdWorktree = false;
18102
18254
  const trees = await listWorktrees(repoPath);
18103
18255
  const checkedOut = trees.find((w) => w.branch === branchName);
18104
- if (checkedOut?.path && (0, import_node_fs45.existsSync)(checkedOut.path)) {
18256
+ if (checkedOut?.path && (0, import_node_fs46.existsSync)(checkedOut.path)) {
18105
18257
  if (input.reuseExistingWorktree !== false) {
18106
18258
  worktreePath = checkedOut.path;
18107
18259
  } else {
@@ -18243,7 +18395,7 @@ async function initStackFromThread(input, onSetupLine) {
18243
18395
  async function createPrStack(input, onSetupLine) {
18244
18396
  await requireAgent(input.agent);
18245
18397
  const repoPath = await resolveRepoRoot(input.repoPath);
18246
- if (!(0, import_node_fs45.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
18398
+ if (!(0, import_node_fs46.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
18247
18399
  if (!input.branches.length) throw new Error("At least one branch name required");
18248
18400
  const status = await detectGhStack(repoPath);
18249
18401
  if (!status.available) throw new Error(status.reason);
@@ -18310,7 +18462,7 @@ async function createPrStack(input, onSetupLine) {
18310
18462
  }
18311
18463
  }
18312
18464
  const claimed = new Set(threads.map((t) => t.worktreePath));
18313
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs45.existsSync)(bootstrap.worktreePath)) {
18465
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs46.existsSync)(bootstrap.worktreePath)) {
18314
18466
  try {
18315
18467
  await removeWorktree(repoPath, bootstrap.worktreePath, {
18316
18468
  deleteBranch: bootstrap.branchName
@@ -18330,11 +18482,11 @@ function stackAgentDefaultsFrom(input) {
18330
18482
  planMode: input.planMode
18331
18483
  };
18332
18484
  }
18333
- var import_node_fs45;
18485
+ var import_node_fs46;
18334
18486
  var init_stack_layers = __esm({
18335
18487
  "src/threads/stack-layers.ts"() {
18336
18488
  "use strict";
18337
- import_node_fs45 = require("fs");
18489
+ import_node_fs46 = require("fs");
18338
18490
  init_detect();
18339
18491
  init_run();
18340
18492
  init_stack();
@@ -18347,7 +18499,7 @@ var init_stack_layers = __esm({
18347
18499
 
18348
18500
  // src/diff/diff.ts
18349
18501
  async function inspectGitWorktree(worktreePath) {
18350
- if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) return "missing_worktree";
18502
+ if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) return "missing_worktree";
18351
18503
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
18352
18504
  reject: false
18353
18505
  });
@@ -18355,7 +18507,7 @@ async function inspectGitWorktree(worktreePath) {
18355
18507
  return "ok";
18356
18508
  }
18357
18509
  async function initializeGitRepository(worktreePath) {
18358
- if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) {
18510
+ if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) {
18359
18511
  throw new Error("Worktree not found");
18360
18512
  }
18361
18513
  const status = await inspectGitWorktree(worktreePath);
@@ -18489,11 +18641,11 @@ new file mode 100644
18489
18641
  };
18490
18642
  }
18491
18643
  async function untrackedPatch(worktreePath, path2, maxHunk) {
18492
- const abs = (0, import_node_path43.join)(worktreePath, path2);
18644
+ const abs = (0, import_node_path44.join)(worktreePath, path2);
18493
18645
  try {
18494
- const st = (0, import_node_fs46.statSync)(abs);
18646
+ const st = (0, import_node_fs47.statSync)(abs);
18495
18647
  if (st.isFile() && st.size > maxHunk) {
18496
- const buf = (0, import_node_fs46.readFileSync)(abs).subarray(0, maxHunk);
18648
+ const buf = (0, import_node_fs47.readFileSync)(abs).subarray(0, maxHunk);
18497
18649
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
18498
18650
  }
18499
18651
  } catch {
@@ -18982,8 +19134,8 @@ function isImageRelativePath(relativePath) {
18982
19134
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
18983
19135
  assertSafeRelativePath(relativePath);
18984
19136
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
18985
- const abs = (0, import_node_path43.join)(worktreePath, relativePath);
18986
- const st = (0, import_node_fs46.statSync)(abs);
19137
+ const abs = (0, import_node_path44.join)(worktreePath, relativePath);
19138
+ const st = (0, import_node_fs47.statSync)(abs);
18987
19139
  if (!st.isFile()) {
18988
19140
  throw new Error(`Not a file: ${relativePath}`);
18989
19141
  }
@@ -18992,7 +19144,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
18992
19144
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
18993
19145
  );
18994
19146
  }
18995
- const buf = (0, import_node_fs46.readFileSync)(abs);
19147
+ const buf = (0, import_node_fs47.readFileSync)(abs);
18996
19148
  return {
18997
19149
  path: relativePath,
18998
19150
  contentBase64: buf.toString("base64"),
@@ -19002,12 +19154,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19002
19154
  function readWorktreeFile(worktreePath, relativePath, opts) {
19003
19155
  assertSafeRelativePath(relativePath);
19004
19156
  const maxBytes = opts?.maxBytes ?? 2e5;
19005
- const abs = (0, import_node_path43.join)(worktreePath, relativePath);
19006
- const st = (0, import_node_fs46.statSync)(abs);
19157
+ const abs = (0, import_node_path44.join)(worktreePath, relativePath);
19158
+ const st = (0, import_node_fs47.statSync)(abs);
19007
19159
  if (!st.isFile()) {
19008
19160
  throw new Error(`Not a file: ${relativePath}`);
19009
19161
  }
19010
- const buf = (0, import_node_fs46.readFileSync)(abs);
19162
+ const buf = (0, import_node_fs47.readFileSync)(abs);
19011
19163
  if (isImageRelativePath(relativePath)) {
19012
19164
  const maxImageBytes = Math.max(maxBytes, 15e6);
19013
19165
  const truncated2 = buf.length > maxImageBytes;
@@ -19050,9 +19202,9 @@ function assertSafeRelativePath(relativePath) {
19050
19202
  }
19051
19203
  function writeWorktreeFile(worktreePath, relativePath, content) {
19052
19204
  assertSafeRelativePath(relativePath);
19053
- const abs = (0, import_node_path43.join)(worktreePath, relativePath);
19054
- (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
19055
- (0, import_node_fs46.writeFileSync)(abs, content, "utf8");
19205
+ const abs = (0, import_node_path44.join)(worktreePath, relativePath);
19206
+ (0, import_node_fs47.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
19207
+ (0, import_node_fs47.writeFileSync)(abs, content, "utf8");
19056
19208
  return { path: relativePath };
19057
19209
  }
19058
19210
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -19069,12 +19221,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
19069
19221
  truncated: full.files.length > maxFiles
19070
19222
  };
19071
19223
  }
19072
- var import_node_fs46, import_node_path43, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19224
+ var import_node_fs47, import_node_path44, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19073
19225
  var init_diff = __esm({
19074
19226
  "src/diff/diff.ts"() {
19075
19227
  "use strict";
19076
- import_node_fs46 = require("fs");
19077
- import_node_path43 = require("path");
19228
+ import_node_fs47 = require("fs");
19229
+ import_node_path44 = require("path");
19078
19230
  init_run();
19079
19231
  init_worktree();
19080
19232
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -19350,7 +19502,7 @@ function parseFrontmatter(content) {
19350
19502
  }
19351
19503
  function readSkill(skillMd, source) {
19352
19504
  try {
19353
- const content = (0, import_node_fs47.readFileSync)(skillMd, "utf8");
19505
+ const content = (0, import_node_fs48.readFileSync)(skillMd, "utf8");
19354
19506
  const { name: fmName, description } = parseFrontmatter(content);
19355
19507
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
19356
19508
  const name = fmName || dirName;
@@ -19369,19 +19521,19 @@ function readSkill(skillMd, source) {
19369
19521
  }
19370
19522
  }
19371
19523
  function scanSkillsDir(dir, source, out) {
19372
- if (!(0, import_node_fs47.existsSync)(dir)) return;
19524
+ if (!(0, import_node_fs48.existsSync)(dir)) return;
19373
19525
  let entries;
19374
19526
  try {
19375
- entries = (0, import_node_fs47.readdirSync)(dir);
19527
+ entries = (0, import_node_fs48.readdirSync)(dir);
19376
19528
  } catch {
19377
19529
  return;
19378
19530
  }
19379
19531
  for (const entry of entries) {
19380
19532
  if (entry.startsWith(".")) continue;
19381
- const skillMd = (0, import_node_path44.join)(dir, entry, "SKILL.md");
19382
- if (!(0, import_node_fs47.existsSync)(skillMd)) continue;
19533
+ const skillMd = (0, import_node_path45.join)(dir, entry, "SKILL.md");
19534
+ if (!(0, import_node_fs48.existsSync)(skillMd)) continue;
19383
19535
  try {
19384
- if (!(0, import_node_fs47.statSync)(skillMd).isFile()) continue;
19536
+ if (!(0, import_node_fs48.statSync)(skillMd).isFile()) continue;
19385
19537
  } catch {
19386
19538
  continue;
19387
19539
  }
@@ -19390,24 +19542,24 @@ function scanSkillsDir(dir, source, out) {
19390
19542
  }
19391
19543
  }
19392
19544
  function scanClaudePluginSkills(pluginsRoot, out) {
19393
- if (!(0, import_node_fs47.existsSync)(pluginsRoot)) return;
19545
+ if (!(0, import_node_fs48.existsSync)(pluginsRoot)) return;
19394
19546
  const walk = (dir, depth, lookingForSkillsDir) => {
19395
19547
  if (depth > 7) return;
19396
19548
  let entries;
19397
19549
  try {
19398
- entries = (0, import_node_fs47.readdirSync)(dir);
19550
+ entries = (0, import_node_fs48.readdirSync)(dir);
19399
19551
  } catch {
19400
19552
  return;
19401
19553
  }
19402
19554
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
19403
- const skill = readSkill((0, import_node_path44.join)(dir, "SKILL.md"), "cli");
19555
+ const skill = readSkill((0, import_node_path45.join)(dir, "SKILL.md"), "cli");
19404
19556
  if (skill) out.push(skill);
19405
19557
  }
19406
19558
  for (const entry of entries) {
19407
19559
  if (entry === "node_modules" || entry === ".git") continue;
19408
- const full = (0, import_node_path44.join)(dir, entry);
19560
+ const full = (0, import_node_path45.join)(dir, entry);
19409
19561
  try {
19410
- if (!(0, import_node_fs47.statSync)(full).isDirectory()) continue;
19562
+ if (!(0, import_node_fs48.statSync)(full).isDirectory()) continue;
19411
19563
  } catch {
19412
19564
  continue;
19413
19565
  }
@@ -19425,17 +19577,17 @@ function discoverSkills(worktreePath) {
19425
19577
  const home = (0, import_node_os14.homedir)();
19426
19578
  const collected = [];
19427
19579
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
19428
- scanSkillsDir((0, import_node_path44.join)(worktreePath, rel), "workspace", collected);
19580
+ scanSkillsDir((0, import_node_path45.join)(worktreePath, rel), "workspace", collected);
19429
19581
  }
19430
19582
  for (const abs of [
19431
- (0, import_node_path44.join)(home, ".claude/skills"),
19432
- (0, import_node_path44.join)(home, ".cursor/skills"),
19433
- (0, import_node_path44.join)(home, ".sideboard/skills"),
19434
- (0, import_node_path44.join)(home, ".brightsy/skills")
19583
+ (0, import_node_path45.join)(home, ".claude/skills"),
19584
+ (0, import_node_path45.join)(home, ".cursor/skills"),
19585
+ (0, import_node_path45.join)(home, ".sideboard/skills"),
19586
+ (0, import_node_path45.join)(home, ".brightsy/skills")
19435
19587
  ]) {
19436
19588
  scanSkillsDir(abs, "user", collected);
19437
19589
  }
19438
- scanClaudePluginSkills((0, import_node_path44.join)(home, ".claude/plugins"), collected);
19590
+ scanClaudePluginSkills((0, import_node_path45.join)(home, ".claude/plugins"), collected);
19439
19591
  collected.push(...bundledSkills());
19440
19592
  const rank = {
19441
19593
  workspace: 0,
@@ -19461,7 +19613,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
19461
19613
  \u2026(truncated)` : body;
19462
19614
  }
19463
19615
  }
19464
- const raw = (0, import_node_fs47.readFileSync)(skillPath, "utf8");
19616
+ const raw = (0, import_node_fs48.readFileSync)(skillPath, "utf8");
19465
19617
  if (raw.startsWith("---")) {
19466
19618
  const end = raw.indexOf("\n---", 3);
19467
19619
  if (end >= 0) {
@@ -19475,13 +19627,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
19475
19627
 
19476
19628
  \u2026(truncated)` : raw;
19477
19629
  }
19478
- var import_node_fs47, import_node_os14, import_node_path44, BUNDLED_SKILL_PREFIX;
19630
+ var import_node_fs48, import_node_os14, import_node_path45, BUNDLED_SKILL_PREFIX;
19479
19631
  var init_discover = __esm({
19480
19632
  "src/skills/discover.ts"() {
19481
19633
  "use strict";
19482
- import_node_fs47 = require("fs");
19634
+ import_node_fs48 = require("fs");
19483
19635
  import_node_os14 = require("os");
19484
- import_node_path44 = require("path");
19636
+ import_node_path45 = require("path");
19485
19637
  init_long_running();
19486
19638
  BUNDLED_SKILL_PREFIX = "bundled:";
19487
19639
  }
@@ -19575,8 +19727,8 @@ var init_expand = __esm({
19575
19727
  // src/skills/detached-job-path.ts
19576
19728
  function detachedJobScriptIn(dir) {
19577
19729
  for (const name of DETACHED_JOB_FILENAMES) {
19578
- const script = (0, import_node_path45.join)(dir, "scripts", name);
19579
- if ((0, import_node_fs48.existsSync)(script)) return script;
19730
+ const script = (0, import_node_path46.join)(dir, "scripts", name);
19731
+ if ((0, import_node_fs49.existsSync)(script)) return script;
19580
19732
  }
19581
19733
  return null;
19582
19734
  }
@@ -19588,11 +19740,11 @@ function packagedDetachedJobPath() {
19588
19740
  function resolveDetachedJobScript() {
19589
19741
  const packaged = packagedDetachedJobPath();
19590
19742
  if (packaged) return packaged;
19591
- let dir = (0, import_node_path45.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
19743
+ let dir = (0, import_node_path46.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
19592
19744
  for (let i = 0; i < 8; i++) {
19593
19745
  const candidate = detachedJobScriptIn(dir);
19594
19746
  if (candidate) return candidate;
19595
- const parent = (0, import_node_path45.dirname)(dir);
19747
+ const parent = (0, import_node_path46.dirname)(dir);
19596
19748
  if (parent === dir) break;
19597
19749
  dir = parent;
19598
19750
  }
@@ -19603,12 +19755,12 @@ function formatDetachedJobInvoke(scriptPath) {
19603
19755
  if (resolved) return `node ${JSON.stringify(resolved)}`;
19604
19756
  return "node scripts/detached-job.cjs";
19605
19757
  }
19606
- var import_node_fs48, import_node_path45, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
19758
+ var import_node_fs49, import_node_path46, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
19607
19759
  var init_detached_job_path = __esm({
19608
19760
  "src/skills/detached-job-path.ts"() {
19609
19761
  "use strict";
19610
- import_node_fs48 = require("fs");
19611
- import_node_path45 = require("path");
19762
+ import_node_fs49 = require("fs");
19763
+ import_node_path46 = require("path");
19612
19764
  import_node_url3 = require("url");
19613
19765
  init_packaged_runtime();
19614
19766
  import_meta3 = {};
@@ -19686,7 +19838,7 @@ function formatWorktreeDirective(thread, opts) {
19686
19838
  );
19687
19839
  }
19688
19840
  lines.push(
19689
- '- Sideboard git buttons send short phrases ("Commit and push.", "Merge PR.", \u2026) with their meaning attached \u2014 act on them without asking for clarification. If the user gives a goal (Greptile 5/5, CI green, until checks pass), you get the watch-fix-push playbook with that request.'
19841
+ '- Sideboard git buttons send short phrases ("Commit and push.", "Ready for review.", "Merge PR.", \u2026) with their meaning attached \u2014 act on them without asking for clarification. If the user gives a goal (Greptile 5/5, CI green, until checks pass), you get the watch-fix-push playbook with that request.'
19690
19842
  );
19691
19843
  lines.push("");
19692
19844
  lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
@@ -19788,9 +19940,9 @@ function formatPrGateDirective() {
19788
19940
  }
19789
19941
  function formatProcessGuideDirective(opts) {
19790
19942
  const worktree = opts?.worktreePath?.trim();
19791
- const hasGraphSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
19792
- const hasReviewSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/review/SKILL.md"));
19793
- const hasInstallSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
19943
+ const hasGraphSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path47.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
19944
+ const hasReviewSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path47.join)(worktree, ".claude/skills/review/SKILL.md"));
19945
+ const hasInstallSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path47.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
19794
19946
  return [
19795
19947
  "Process guides (recurring work only):",
19796
19948
  hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
@@ -19828,12 +19980,12 @@ function formatArtifactDirective() {
19828
19980
  function formatUiReminder() {
19829
19981
  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. type=log appends (same artifact_id, new lines only). 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.";
19830
19982
  }
19831
- var import_node_fs49, import_node_path46, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
19983
+ var import_node_fs50, import_node_path47, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
19832
19984
  var init_instructions = __esm({
19833
19985
  "src/agents/instructions.ts"() {
19834
19986
  "use strict";
19835
- import_node_fs49 = require("fs");
19836
- import_node_path46 = require("path");
19987
+ import_node_fs50 = require("fs");
19988
+ import_node_path47 = require("path");
19837
19989
  init_git_auth_mode();
19838
19990
  init_worktree_labels();
19839
19991
  init_detached_job_path();
@@ -20186,40 +20338,40 @@ __export(plan_file_exports, {
20186
20338
  writePlanFile: () => writePlanFile
20187
20339
  });
20188
20340
  function ensureAttachmentsGitignore(worktreePath) {
20189
- const gitignoreAbs = (0, import_node_path47.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20190
- if ((0, import_node_fs50.existsSync)(gitignoreAbs)) return;
20191
- (0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(gitignoreAbs), { recursive: true });
20192
- (0, import_node_fs50.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20341
+ const gitignoreAbs = (0, import_node_path48.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20342
+ if ((0, import_node_fs51.existsSync)(gitignoreAbs)) return;
20343
+ (0, import_node_fs51.mkdirSync)((0, import_node_path48.dirname)(gitignoreAbs), { recursive: true });
20344
+ (0, import_node_fs51.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20193
20345
  }
20194
20346
  function planFileAbs(worktreePath) {
20195
- return (0, import_node_path47.join)(worktreePath, PLAN_FILE_REL);
20347
+ return (0, import_node_path48.join)(worktreePath, PLAN_FILE_REL);
20196
20348
  }
20197
20349
  function readTextIfPresent2(abs) {
20198
- if (!(0, import_node_fs50.existsSync)(abs)) return null;
20350
+ if (!(0, import_node_fs51.existsSync)(abs)) return null;
20199
20351
  try {
20200
- const content = (0, import_node_fs50.readFileSync)(abs, "utf8");
20352
+ const content = (0, import_node_fs51.readFileSync)(abs, "utf8");
20201
20353
  return content.trim() ? content : null;
20202
20354
  } catch {
20203
20355
  return null;
20204
20356
  }
20205
20357
  }
20206
20358
  function readPlanFile(worktreePath) {
20207
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path47.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path47.join)(worktreePath, LEGACY_PLAN_FILE_REL));
20359
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path48.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path48.join)(worktreePath, LEGACY_PLAN_FILE_REL));
20208
20360
  }
20209
20361
  function writePlanFile(worktreePath, content) {
20210
20362
  ensureAttachmentsGitignore(worktreePath);
20211
20363
  const abs = planFileAbs(worktreePath);
20212
- (0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(abs), { recursive: true });
20364
+ (0, import_node_fs51.mkdirSync)((0, import_node_path48.dirname)(abs), { recursive: true });
20213
20365
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
20214
- (0, import_node_fs50.writeFileSync)(abs, body, "utf8");
20366
+ (0, import_node_fs51.writeFileSync)(abs, body, "utf8");
20215
20367
  return PLAN_FILE_REL;
20216
20368
  }
20217
- var import_node_fs50, import_node_path47;
20369
+ var import_node_fs51, import_node_path48;
20218
20370
  var init_plan_file = __esm({
20219
20371
  "src/plan/plan-file.ts"() {
20220
20372
  "use strict";
20221
- import_node_fs50 = require("fs");
20222
- import_node_path47 = require("path");
20373
+ import_node_fs51 = require("fs");
20374
+ import_node_path48 = require("path");
20223
20375
  init_workspace_scratch();
20224
20376
  init_plan_present();
20225
20377
  init_plan_present();
@@ -20267,13 +20419,13 @@ var init_sync_branch = __esm({
20267
20419
 
20268
20420
  // src/agents/cursor-store.ts
20269
20421
  function cursorSdkStoreDir(threadId) {
20270
- const root = (0, import_node_path48.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
20422
+ const root = (0, import_node_path49.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
20271
20423
  const id = sanitizeCursorStoreSegment(threadId);
20272
20424
  if (!id) return root;
20273
- return (0, import_node_path48.join)(root, "threads", id);
20425
+ return (0, import_node_path49.join)(root, "threads", id);
20274
20426
  }
20275
20427
  function cursorSdkRunsNdjsonPath(threadId) {
20276
- return (0, import_node_path48.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
20428
+ return (0, import_node_path49.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
20277
20429
  }
20278
20430
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
20279
20431
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -20286,11 +20438,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
20286
20438
  function sanitizeCursorStoreSegment(threadId) {
20287
20439
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
20288
20440
  }
20289
- var import_node_path48, CURSOR_SDK_STORE_DIR;
20441
+ var import_node_path49, CURSOR_SDK_STORE_DIR;
20290
20442
  var init_cursor_store = __esm({
20291
20443
  "src/agents/cursor-store.ts"() {
20292
20444
  "use strict";
20293
- import_node_path48 = require("path");
20445
+ import_node_path49 = require("path");
20294
20446
  init_paths();
20295
20447
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
20296
20448
  }
@@ -20312,9 +20464,9 @@ function recoverFinishedCursorRun(opts) {
20312
20464
  return best;
20313
20465
  }
20314
20466
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
20315
- if (!(0, import_node_fs51.existsSync)(runsPath)) return null;
20467
+ if (!(0, import_node_fs52.existsSync)(runsPath)) return null;
20316
20468
  try {
20317
- const lines = (0, import_node_fs51.readFileSync)(runsPath, "utf8").split("\n");
20469
+ const lines = (0, import_node_fs52.readFileSync)(runsPath, "utf8").split("\n");
20318
20470
  let best = null;
20319
20471
  for (const line of lines) {
20320
20472
  const trimmed = line.trim();
@@ -20340,11 +20492,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
20340
20492
  return null;
20341
20493
  }
20342
20494
  }
20343
- var import_node_fs51;
20495
+ var import_node_fs52;
20344
20496
  var init_cursor_recover = __esm({
20345
20497
  "src/agents/cursor-recover.ts"() {
20346
20498
  "use strict";
20347
- import_node_fs51 = require("fs");
20499
+ import_node_fs52 = require("fs");
20348
20500
  init_cursor_store();
20349
20501
  }
20350
20502
  });
@@ -20476,13 +20628,13 @@ async function startOrchestration(opts) {
20476
20628
  }
20477
20629
  return updated;
20478
20630
  }
20479
- var import_node_events, import_node_fs52, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
20631
+ var import_node_events, import_node_fs53, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
20480
20632
  var init_orchestrator = __esm({
20481
20633
  "src/orchestrator/orchestrator.ts"() {
20482
20634
  "use strict";
20483
20635
  import_node_events = require("events");
20484
20636
  init_outbound_watch();
20485
- import_node_fs52 = require("fs");
20637
+ import_node_fs53 = require("fs");
20486
20638
  init_error_detail();
20487
20639
  init_run();
20488
20640
  init_stale_lock();
@@ -20655,7 +20807,7 @@ var init_orchestrator = __esm({
20655
20807
  }
20656
20808
  continue;
20657
20809
  }
20658
- if (!(0, import_node_fs52.existsSync)(thread.worktreePath)) {
20810
+ if (!(0, import_node_fs53.existsSync)(thread.worktreePath)) {
20659
20811
  setStatus(thread.id, "broken", "Worktree missing on disk");
20660
20812
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
20661
20813
  continue;
@@ -22330,7 +22482,7 @@ var init_orchestrator = __esm({
22330
22482
  "ask_git targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
22331
22483
  );
22332
22484
  }
22333
- if (action === "merge" && !thread.prUrl) {
22485
+ if ((action === "merge" || action === "ready-for-review") && !thread.prUrl) {
22334
22486
  throw new Error(
22335
22487
  "No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
22336
22488
  );
@@ -22546,7 +22698,7 @@ var init_orchestrator = __esm({
22546
22698
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
22547
22699
  return restored2;
22548
22700
  }
22549
- if (!(0, import_node_fs52.existsSync)(thread.worktreePath)) {
22701
+ if (!(0, import_node_fs53.existsSync)(thread.worktreePath)) {
22550
22702
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
22551
22703
  throw new Error(
22552
22704
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -22864,6 +23016,7 @@ __export(index_exports, {
22864
23016
  applyForwardOccupancy: () => applyForwardOccupancy,
22865
23017
  applyGithubGitAuthEnv: () => applyGithubGitAuthEnv,
22866
23018
  applyPromptCacheTtlEnv: () => applyPromptCacheTtlEnv,
23019
+ applySystemCaEnv: () => applySystemCaEnv,
22867
23020
  applyThreadIntoMain: () => applyThreadIntoMain,
22868
23021
  applyTurnUsage: () => applyTurnUsage,
22869
23022
  armSchedules: () => armSchedules,
@@ -23144,6 +23297,7 @@ __export(index_exports, {
23144
23297
  isCloudCoordinatorThread: () => isCloudCoordinatorThread,
23145
23298
  isConductorBundledCli: () => isConductorBundledCli,
23146
23299
  isCowboyThread: () => isCowboyThread,
23300
+ isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
23147
23301
  isCursorAutoModel: () => isCursorAutoModel,
23148
23302
  isDefaultishSourceRef: () => isDefaultishSourceRef,
23149
23303
  isDesktopHostAlive: () => isDesktopHostAlive,
@@ -23242,6 +23396,7 @@ __export(index_exports, {
23242
23396
  lookupSoccerTeam: () => lookupSoccerTeam,
23243
23397
  mapAbleTimeTask: () => mapAbleTimeTask,
23244
23398
  markPrReady: () => markPrReady,
23399
+ materializeSystemCaBundle: () => materializeSystemCaBundle,
23245
23400
  maxConcurrentAgents: () => maxConcurrentAgents,
23246
23401
  maybeCompactContext: () => maybeCompactContext,
23247
23402
  mcpAllowTools: () => mcpAllowTools,
@@ -23465,6 +23620,7 @@ __export(index_exports, {
23465
23620
  toolDetail: () => toolDetail,
23466
23621
  toolFilePath: () => toolFilePath,
23467
23622
  totalTokens: () => totalTokens,
23623
+ trustSystemCertificates: () => trustSystemCertificates,
23468
23624
  turnCostUsdFromCursorUsage: () => turnCostUsdFromCursorUsage,
23469
23625
  updateAbleTimeTask: () => updateAbleTimeTask,
23470
23626
  updateAdvancedSettings: () => updateAdvancedSettings,
@@ -24831,6 +24987,7 @@ async function installOptionalServiceCli(id) {
24831
24987
 
24832
24988
  // src/index.ts
24833
24989
  init_fetch();
24990
+ init_system_ca();
24834
24991
  init_agents();
24835
24992
  init_spawn();
24836
24993
  init_message_parts();
@@ -25176,7 +25333,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
25176
25333
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
25177
25334
  var import_zod8 = require("zod");
25178
25335
  var import_node_crypto13 = require("crypto");
25179
- var import_node_path51 = require("path");
25336
+ var import_node_path52 = require("path");
25180
25337
  init_orchestrator();
25181
25338
  init_worktree();
25182
25339
  init_global_workspace();
@@ -26760,27 +26917,27 @@ init_gh_errors();
26760
26917
  init_git_auth_mode();
26761
26918
 
26762
26919
  // src/board/load-home-board.ts
26763
- var import_node_fs54 = require("fs");
26764
- var import_node_path50 = require("path");
26920
+ var import_node_fs55 = require("fs");
26921
+ var import_node_path51 = require("path");
26765
26922
  init_worktree();
26766
26923
  init_paths();
26767
26924
 
26768
26925
  // src/board/board-pins.ts
26769
26926
  var import_node_crypto12 = require("crypto");
26770
- var import_node_fs53 = require("fs");
26771
- var import_node_path49 = require("path");
26927
+ var import_node_fs54 = require("fs");
26928
+ var import_node_path50 = require("path");
26772
26929
  init_paths();
26773
26930
  init_home_board();
26774
26931
  var FILE = "home-board-pins.json";
26775
26932
  var VERSION = 1;
26776
26933
  function pinsFile() {
26777
- return (0, import_node_path49.join)(appDataDir(), FILE);
26934
+ return (0, import_node_path50.join)(appDataDir(), FILE);
26778
26935
  }
26779
26936
  function readDisk() {
26780
26937
  const path2 = pinsFile();
26781
- if (!(0, import_node_fs53.existsSync)(path2)) return [];
26938
+ if (!(0, import_node_fs54.existsSync)(path2)) return [];
26782
26939
  try {
26783
- const raw = JSON.parse((0, import_node_fs53.readFileSync)(path2, "utf8"));
26940
+ const raw = JSON.parse((0, import_node_fs54.readFileSync)(path2, "utf8"));
26784
26941
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
26785
26942
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
26786
26943
  } catch {
@@ -26788,8 +26945,8 @@ function readDisk() {
26788
26945
  }
26789
26946
  }
26790
26947
  function writeDisk(items) {
26791
- (0, import_node_fs53.mkdirSync)(appDataDir(), { recursive: true });
26792
- (0, import_node_fs53.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
26948
+ (0, import_node_fs54.mkdirSync)(appDataDir(), { recursive: true });
26949
+ (0, import_node_fs54.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
26793
26950
  }
26794
26951
  function listBoardPins() {
26795
26952
  return readDisk();
@@ -26841,7 +26998,7 @@ function replaceBoardPins(items) {
26841
26998
  }
26842
26999
  function clearBoardPins() {
26843
27000
  try {
26844
- (0, import_node_fs53.unlinkSync)(pinsFile());
27001
+ (0, import_node_fs54.unlinkSync)(pinsFile());
26845
27002
  } catch {
26846
27003
  }
26847
27004
  }
@@ -26858,7 +27015,7 @@ function homeBoardWorkspaceKey(workspaces) {
26858
27015
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
26859
27016
  }
26860
27017
  function cacheFile() {
26861
- return (0, import_node_path50.join)(appDataDir(), "home-board-cache.json");
27018
+ return (0, import_node_path51.join)(appDataDir(), "home-board-cache.json");
26862
27019
  }
26863
27020
  function emptyInputs() {
26864
27021
  return {
@@ -26884,9 +27041,9 @@ function shouldCacheHomeBoardInputs(inputs) {
26884
27041
  }
26885
27042
  function readDiskCache() {
26886
27043
  const path2 = cacheFile();
26887
- if (!(0, import_node_fs54.existsSync)(path2)) return null;
27044
+ if (!(0, import_node_fs55.existsSync)(path2)) return null;
26888
27045
  try {
26889
- const raw = JSON.parse((0, import_node_fs54.readFileSync)(path2, "utf8"));
27046
+ const raw = JSON.parse((0, import_node_fs55.readFileSync)(path2, "utf8"));
26890
27047
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
26891
27048
  return null;
26892
27049
  }
@@ -26900,14 +27057,14 @@ function readDiskCache() {
26900
27057
  }
26901
27058
  function writeDiskCache(entry) {
26902
27059
  try {
26903
- (0, import_node_fs54.mkdirSync)(appDataDir(), { recursive: true });
26904
- (0, import_node_fs54.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
27060
+ (0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
27061
+ (0, import_node_fs55.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
26905
27062
  } catch {
26906
27063
  }
26907
27064
  }
26908
27065
  function deleteDiskCache() {
26909
27066
  try {
26910
- (0, import_node_fs54.unlinkSync)(cacheFile());
27067
+ (0, import_node_fs55.unlinkSync)(cacheFile());
26911
27068
  } catch {
26912
27069
  }
26913
27070
  }
@@ -27043,6 +27200,54 @@ async function getHomeBoardInputs(workspaces, opts) {
27043
27200
 
27044
27201
  // src/mcp/server.ts
27045
27202
  init_home_board();
27203
+
27204
+ // src/mcp/create-thread-agent.ts
27205
+ init_cursor();
27206
+ function resolveOrchCreateThreadOptions(input) {
27207
+ const { resolveNewThreadOptions: resolveNewThreadOptions2 } = input;
27208
+ const account = resolveNewThreadOptions2({});
27209
+ const requested = input.requestedAgent;
27210
+ const parent = input.parentAgent ?? void 0;
27211
+ const cursorReady = input.cursorReady ?? isCursorApiKeyConfigured();
27212
+ let agent = account.agent;
27213
+ let ignoredAgent;
27214
+ let honorRequestedModel = false;
27215
+ if (requested) {
27216
+ const parentEcho = Boolean(parent) && requested === parent && requested !== account.agent;
27217
+ const cursorAutofill = requested === "cursor" && account.agent !== "cursor";
27218
+ if (parentEcho || cursorAutofill) {
27219
+ ignoredAgent = requested;
27220
+ } else {
27221
+ agent = requested;
27222
+ honorRequestedModel = input.requestedModel !== void 0;
27223
+ }
27224
+ }
27225
+ let coercedFrom;
27226
+ if (agent === "codex" && parent === "codex" && cursorReady) {
27227
+ coercedFrom = requested ?? "codex";
27228
+ agent = "cursor";
27229
+ }
27230
+ const opts = resolveNewThreadOptions2({
27231
+ agent,
27232
+ model: honorRequestedModel ? input.requestedModel : void 0
27233
+ });
27234
+ return {
27235
+ ...opts,
27236
+ ...ignoredAgent ? { ignoredAgent } : {},
27237
+ ...coercedFrom ? { coercedFrom } : {}
27238
+ };
27239
+ }
27240
+ function orchCreateThreadAgentNote(input) {
27241
+ if (input.coercedFrom) {
27242
+ return `Avoid nested Codex under a Codex orchestrator \u2014 used agent=${input.agent}`;
27243
+ }
27244
+ if (input.ignoredAgent) {
27245
+ return `Ignored agent=${input.ignoredAgent} \u2014 used Account default agent=${input.agent}`;
27246
+ }
27247
+ return void 0;
27248
+ }
27249
+
27250
+ // src/mcp/server.ts
27046
27251
  var MAX_ORCH_THREADS = 5;
27047
27252
  var CREATE_THREAD_TIMEOUT_MS = 9e4;
27048
27253
  function withTimeout(promise, ms, label) {
@@ -27090,18 +27295,13 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
27090
27295
  };
27091
27296
  }
27092
27297
  }
27093
- let agentArg = args.agent;
27094
- let agentCoercedFrom;
27095
- const resolvedProbe = resolveNewThreadOptions2({ agent: agentArg }).agent;
27096
- if (resolvedProbe === "codex") {
27097
- agentCoercedFrom = agentArg ?? "codex";
27098
- const accountAgent = resolveNewThreadOptions2({}).agent;
27099
- agentArg = accountAgent !== "codex" ? accountAgent : "cursor";
27100
- }
27101
- const opts = resolveNewThreadOptions2({
27102
- agent: agentArg,
27103
- model: args.model
27298
+ const opts = resolveOrchCreateThreadOptions({
27299
+ requestedAgent: args.agent,
27300
+ requestedModel: args.model,
27301
+ parentAgent: parent?.agent,
27302
+ resolveNewThreadOptions: resolveNewThreadOptions2
27104
27303
  });
27304
+ const agentNote = orchCreateThreadAgentNote(opts);
27105
27305
  try {
27106
27306
  const priorIds = new Set(orch.getThreads(false).map((t) => t.id));
27107
27307
  const thread = await withTimeout(
@@ -27137,10 +27337,9 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
27137
27337
  link: `sideboard://thread/${thread.id}`,
27138
27338
  parentThreadId: thread.parentThreadId,
27139
27339
  ...alreadyStarted ? { alreadyStarted: true } : {},
27140
- ...agentCoercedFrom ? {
27141
- agentCoercedFrom,
27142
- note: `Avoid nested Codex under a Codex orchestrator \u2014 used Account default agent=${thread.agent}`
27143
- } : {},
27340
+ ...opts.coercedFrom ? { agentCoercedFrom: opts.coercedFrom } : {},
27341
+ ...opts.ignoredAgent ? { agentIgnored: opts.ignoredAgent } : {},
27342
+ ...agentNote ? { note: agentNote } : {},
27144
27343
  ...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
27145
27344
  })
27146
27345
  };
@@ -27215,7 +27414,7 @@ async function startMcpServer() {
27215
27414
  async () => {
27216
27415
  const threads = orch.getThreads(true);
27217
27416
  const lines = threads.map((t) => {
27218
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path51.basename)(t.repoPath) || t.repoPath;
27417
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path52.basename)(t.repoPath) || t.repoPath;
27219
27418
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
27220
27419
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
27221
27420
  const preview = lastMessagePreview(t.messages, 80);
@@ -27500,11 +27699,13 @@ async function startMcpServer() {
27500
27699
  );
27501
27700
  server.tool(
27502
27701
  "create_thread",
27503
- `Create a worktree thread (chat) from branch, pr, or ticket. A ticket, PR, or named branch may have only one live worktree \u2014 if one already matches, returns it (alreadyStarted=true) instead of a second checkout. Creating from the default branch still opens a new isolated worktree. Pass repoPath from list_workspaces. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn (skipped for cowboy). Then use send_to_thread to chat.`,
27702
+ `Create a worktree thread (chat) from branch, pr, or ticket. A ticket, PR, or named branch may have only one live worktree \u2014 if one already matches, returns it (alreadyStarted=true) instead of a second checkout. Creating from the default branch still opens a new isolated worktree. Pass repoPath from list_workspaces. cowboy=true uses the project folder on the default branch (no isolated worktree; land is commit+push). From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Omit agent/model \u2014 Sideboard applies ${accountDefaultsHint}. Do not pass your own agent or agent=cursor; those are ignored. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn (skipped for cowboy). Then use send_to_thread to chat.`,
27504
27703
  {
27505
27704
  sourceType: import_zod8.z.enum(["branch", "pr", "ticket"]),
27506
27705
  sourceRef: import_zod8.z.string(),
27507
- agent: import_zod8.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(`Omit to use Account default agent (${accountDefaults.agent})`),
27706
+ agent: import_zod8.z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(
27707
+ `Usually omit. Sideboard uses Account default agent (${accountDefaults.agent}). Passing your own agent or cursor is ignored.`
27708
+ ),
27508
27709
  model: import_zod8.z.string().nullable().optional().describe(
27509
27710
  `Usually omit to use Account default model (${accountDefaults.model?.trim() || "Auto"}). Pass null only to force Auto / agent-default.`
27510
27711
  ),
@@ -27808,11 +28009,11 @@ async function startMcpServer() {
27808
28009
  );
27809
28010
  server.tool(
27810
28011
  "ask_git",
27811
- "Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Do not start a checks loop on a plain push \u2014 only if the user gave a goal (Greptile 5/5, CI green). Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. Do not run git or gh from the orchestration cwd. If this tool errors that the GraphQL/PR body is too long, the branch is already pushed \u2014 have the worktree agent retry `gh pr create --body-file` with a short description (GitHub limit 65,536 characters). Do not invent SSH/auth failures from that error.",
28012
+ "Commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Do not start a checks loop on a plain push \u2014 only if the user gave a goal (Greptile 5/5, CI green). Pass a worktree thread ref (not the orchestrator). action=ready-for-review and action=merge only when the user explicitly asked (or clicked the desktop button). Do not run git or gh from the orchestration cwd. If this tool errors that the GraphQL/PR body is too long, the branch is already pushed \u2014 have the worktree agent retry `gh pr create --body-file` with a short description (GitHub limit 65,536 characters). Do not invent SSH/auth failures from that error.",
27812
28013
  {
27813
28014
  ref: import_zod8.z.string().describe("Worktree thread id/ref"),
27814
28015
  action: import_zod8.z.enum(AGENT_GIT_ACTIONS).describe(
27815
- "commit-push | create-draft | create-web | resolve-conflicts | merge"
28016
+ "commit-push | create-draft | create-web | resolve-conflicts | ready-for-review | merge"
27816
28017
  )
27817
28018
  },
27818
28019
  async ({ ref, action }) => {
@@ -30175,9 +30376,9 @@ var import_node_http3 = require("http");
30175
30376
  var import_ws3 = require("ws");
30176
30377
 
30177
30378
  // src/slack/relay-static.ts
30178
- var import_node_fs55 = require("fs");
30379
+ var import_node_fs56 = require("fs");
30179
30380
  var import_promises = require("fs/promises");
30180
- var import_node_path52 = __toESM(require("path"), 1);
30381
+ var import_node_path53 = __toESM(require("path"), 1);
30181
30382
  var TYPES = {
30182
30383
  ".css": "text/css; charset=utf-8",
30183
30384
  ".html": "text/html; charset=utf-8",
@@ -30208,9 +30409,9 @@ function resolveStaticPath(root, requestUrl) {
30208
30409
  return null;
30209
30410
  }
30210
30411
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
30211
- const rootResolved = import_node_path52.default.resolve(root);
30212
- const candidate = import_node_path52.default.resolve(rootResolved, `.${pathname}`);
30213
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path52.default.sep)) {
30412
+ const rootResolved = import_node_path53.default.resolve(root);
30413
+ const candidate = import_node_path53.default.resolve(rootResolved, `.${pathname}`);
30414
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path53.default.sep)) {
30214
30415
  return null;
30215
30416
  }
30216
30417
  return candidate;
@@ -30224,7 +30425,7 @@ async function fileSize(file) {
30224
30425
  }
30225
30426
  }
30226
30427
  function sendFile(req, res, file, size) {
30227
- const ext = import_node_path52.default.extname(file).toLowerCase();
30428
+ const ext = import_node_path53.default.extname(file).toLowerCase();
30228
30429
  res.writeHead(200, {
30229
30430
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
30230
30431
  "Content-Length": size,
@@ -30234,7 +30435,7 @@ function sendFile(req, res, file, size) {
30234
30435
  res.end();
30235
30436
  return true;
30236
30437
  }
30237
- (0, import_node_fs55.createReadStream)(file).pipe(res);
30438
+ (0, import_node_fs56.createReadStream)(file).pipe(res);
30238
30439
  return true;
30239
30440
  }
30240
30441
  async function tryServeStatic(req, res, root) {
@@ -30243,7 +30444,7 @@ async function tryServeStatic(req, res, root) {
30243
30444
  if (!candidate) return false;
30244
30445
  const direct = await fileSize(candidate);
30245
30446
  if (direct != null) return sendFile(req, res, candidate, direct);
30246
- const asIndex = import_node_path52.default.join(candidate, "index.html");
30447
+ const asIndex = import_node_path53.default.join(candidate, "index.html");
30247
30448
  const indexSize = await fileSize(asIndex);
30248
30449
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
30249
30450
  return false;
@@ -30593,6 +30794,7 @@ init_outbound_watch();
30593
30794
  applyForwardOccupancy,
30594
30795
  applyGithubGitAuthEnv,
30595
30796
  applyPromptCacheTtlEnv,
30797
+ applySystemCaEnv,
30596
30798
  applyThreadIntoMain,
30597
30799
  applyTurnUsage,
30598
30800
  armSchedules,
@@ -30873,6 +31075,7 @@ init_outbound_watch();
30873
31075
  isCloudCoordinatorThread,
30874
31076
  isConductorBundledCli,
30875
31077
  isCowboyThread,
31078
+ isCursorApiKeyConfigured,
30876
31079
  isCursorAutoModel,
30877
31080
  isDefaultishSourceRef,
30878
31081
  isDesktopHostAlive,
@@ -30971,6 +31174,7 @@ init_outbound_watch();
30971
31174
  lookupSoccerTeam,
30972
31175
  mapAbleTimeTask,
30973
31176
  markPrReady,
31177
+ materializeSystemCaBundle,
30974
31178
  maxConcurrentAgents,
30975
31179
  maybeCompactContext,
30976
31180
  mcpAllowTools,
@@ -31194,6 +31398,7 @@ init_outbound_watch();
31194
31398
  toolDetail,
31195
31399
  toolFilePath,
31196
31400
  totalTokens,
31401
+ trustSystemCertificates,
31197
31402
  turnCostUsdFromCursorUsage,
31198
31403
  updateAbleTimeTask,
31199
31404
  updateAdvancedSettings,