@sideboard-ai/core 0.1.153 → 0.1.156

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.
package/dist/index.cjs CHANGED
@@ -7524,7 +7524,7 @@ function ensureGlobalCoordinatorCwd(opts) {
7524
7524
  "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.",
7525
7525
  "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).",
7526
7526
  "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.",
7527
- "Typical flow (find work): list_workspaces \u2192 pick repo(s) matching viewer roles/notes \u2192 list_issues (tickets) or list_prs(queue=review) (reviews) \u2192 show the options. 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.",
7527
+ "Typical flow (find work): list_workspaces \u2192 pick repo(s) matching viewer roles/notes \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.",
7528
7528
  'Typical flow (review inbox): list_workspaces \u2192 list_prs(queue=review, limit=N) \u2192 show those PRs (ticket ids in the title when present). create_thread sourceType=pr only when they asked to start / do the work. Do not list_issues for "tickets to review".',
7529
7529
  "Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
7530
7530
  "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). If the user gave a goal (Greptile 5/5, CI green), pass that goal through so they watch-fix-push until it lands \u2014 do not start that loop on a plain push, and do not tell the human to poll. Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
@@ -7581,8 +7581,8 @@ var init_coordinator_prompt = __esm({
7581
7581
  "- list_workspaces \u2014 registered repos (path + github slug + roles/notes when set). Use that profile to pick the right repo for tickets or reviews.",
7582
7582
  "- list_board \u2014 Home Kanban of worktrees (New / Draft / Review / Merged; one card per checkout). Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
7583
7583
  '- list_branches / list_prs / list_issues \u2014 pass repoPath from list_workspaces. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_thread sourceType=pr. That is open non-draft PRs labeled eng-review with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Prefer teams that match Settings \u2192 Agents / Projects roles (check one or more of Engineering, Design, Product, or extras they added \u2014 never a combined both value; project roles override account for that repo). queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, use their notes (assignee=me or unassigned as the notes say) and prefer ones that match their roles.',
7584
- "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) roles and notes. Tickets \u2192 list_issues. Reviews \u2192 list_prs(queue=review). Show the options \u2014 do not create_thread or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted.",
7585
- "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; get/create/update/comment with ENG-123. Scope errors: reconnect Linear in Account settings.",
7584
+ "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) roles and notes. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_thread or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted.",
7585
+ "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; get/create/update/comment with ENG-123. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
7586
7586
  "- abletime_* (when AbleTime is connected) \u2014 orientation first; ensure_task when work has no ticket (or create_thread from the default branch auto-creates one).",
7587
7587
  "- list_teams / slack_list_channels / slack_list_users / slack_search / slack_read / slack_post / slack_replies \u2014 Slack workspaces from Settings \u2192 Remote; pass team_id from list_teams",
7588
7588
  "- Optional connectors (Vercel, Supabase, PostHog, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`) with those env vars. PostHog has no first-class CLI \u2014 use the HTTP API (`POSTHOG_PERSONAL_API_KEY`). If a CLI is missing, the user can Install CLI on that row (not auto-installed on Connect). Do not add vendor MCPs or ask the user to paste tokens again. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues; Slack stays Settings \u2192 Remote (Sideboard MCP).",
@@ -10743,7 +10743,7 @@ function toCodexMcpConfigArgs(servers) {
10743
10743
  }
10744
10744
  return args;
10745
10745
  }
10746
- function toOpencodeMcpConfigContent(servers) {
10746
+ function toOpencodeMcpConfigContent(servers, opts) {
10747
10747
  const mcp = {};
10748
10748
  for (const s of servers) {
10749
10749
  const env = mcpSpawnEnv(s.env);
@@ -10754,6 +10754,11 @@ function toOpencodeMcpConfigContent(servers) {
10754
10754
  ...env ? { environment: env } : {}
10755
10755
  };
10756
10756
  }
10757
+ for (const name of opts?.disableNames ?? []) {
10758
+ const key = name.trim();
10759
+ if (!key || mcp[key]?.enabled === true) continue;
10760
+ mcp[key] = { ...mcp[key], enabled: false };
10761
+ }
10757
10762
  return JSON.stringify({ mcp });
10758
10763
  }
10759
10764
  function writeMcpServersConfig(servers) {
@@ -10991,13 +10996,50 @@ function claudeString(obj, key) {
10991
10996
  const v = obj[key];
10992
10997
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
10993
10998
  }
10999
+ function mcpStatusThinkingFromClaudeInit(obj) {
11000
+ const raw = obj.mcp_servers ?? obj.mcpServers;
11001
+ const servers = [];
11002
+ if (Array.isArray(raw)) {
11003
+ for (const item of raw) {
11004
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
11005
+ const rec = item;
11006
+ const name = typeof rec.name === "string" && rec.name.trim() || typeof rec.server === "string" && rec.server.trim() || "";
11007
+ const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "";
11008
+ if (name) servers.push({ name, status: status || "unknown" });
11009
+ }
11010
+ } else if (raw && typeof raw === "object") {
11011
+ for (const [name, value] of Object.entries(raw)) {
11012
+ if (!name.trim()) continue;
11013
+ if (typeof value === "string" && value.trim()) {
11014
+ servers.push({ name, status: value.trim() });
11015
+ continue;
11016
+ }
11017
+ if (value && typeof value === "object" && !Array.isArray(value)) {
11018
+ const rec = value;
11019
+ const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "unknown";
11020
+ servers.push({ name, status });
11021
+ }
11022
+ }
11023
+ }
11024
+ const notable = servers.filter((s) => !isCleanMcpConnect(s.status));
11025
+ if (notable.length === 0) return null;
11026
+ return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
11027
+ }
11028
+ function isCleanMcpConnect(status) {
11029
+ return /^(connected|ok|ready|success)$/i.test(status.trim());
11030
+ }
10994
11031
  function eventsFromClaudeSystem(obj) {
10995
11032
  const subtype = claudeString(obj, "subtype") ?? "";
10996
11033
  const parentId = claudeParentToolUseId(obj);
10997
11034
  if (subtype === "init") {
10998
11035
  if (parentId) return null;
10999
11036
  const sid = claudeString(obj, "session_id");
11000
- return sid ? { type: "session_id", data: sid } : null;
11037
+ const mcpNote = mcpStatusThinkingFromClaudeInit(obj);
11038
+ const events = [];
11039
+ if (sid) events.push({ type: "session_id", data: sid });
11040
+ if (mcpNote) events.push({ type: "thinking", data: mcpNote, replace: true });
11041
+ if (events.length === 0) return null;
11042
+ return events.length === 1 ? events[0] : events;
11001
11043
  }
11002
11044
  if (subtype === "task_started") {
11003
11045
  const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
@@ -11261,6 +11303,9 @@ var init_claude = __esm({
11261
11303
  const mcpConfigPath = writeMcpServersConfig(injectedServers);
11262
11304
  if (mcpConfigPath) {
11263
11305
  args.push("--mcp-config", mcpConfigPath);
11306
+ if (isOrchestrator) {
11307
+ args.push("--strict-mcp-config");
11308
+ }
11264
11309
  }
11265
11310
  if (chromeOn) {
11266
11311
  args.push("--chrome");
@@ -11290,7 +11335,10 @@ var init_claude = __esm({
11290
11335
  // abandoned at Claude Code’s 10-minute default.
11291
11336
  env: {
11292
11337
  CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
11293
- CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
11338
+ CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS),
11339
+ // `--strict-mcp-config` still fetches claude.ai connectors on some CLI
11340
+ // builds (anthropics/claude-code#60252). Coordinators do not need them.
11341
+ ...isOrchestrator ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {}
11294
11342
  }
11295
11343
  };
11296
11344
  },
@@ -11414,6 +11462,178 @@ var init_claude = __esm({
11414
11462
  }
11415
11463
  });
11416
11464
 
11465
+ // src/agents/user-mcp-config.ts
11466
+ function userCursorMcpConfigPath() {
11467
+ return (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
11468
+ }
11469
+ function userClaudeMcpConfigPath() {
11470
+ return (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".claude.json");
11471
+ }
11472
+ function asObject(value) {
11473
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
11474
+ return { ...value };
11475
+ }
11476
+ function stripElectronSpawnEnv(env) {
11477
+ if (!env) return void 0;
11478
+ const next = { ...env };
11479
+ delete next.ELECTRON_RUN_AS_NODE;
11480
+ delete next.ELECTRON_RUN_AS_NODE;
11481
+ return Object.keys(next).length > 0 ? next : void 0;
11482
+ }
11483
+ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
11484
+ const root = asObject(existing);
11485
+ const servers = asObject(root.mcpServers);
11486
+ const env = stripElectronSpawnEnv(sideboard.env);
11487
+ servers.sideboard = {
11488
+ type: "stdio",
11489
+ command: sideboard.command,
11490
+ ...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
11491
+ ...env ? { env } : {}
11492
+ };
11493
+ return { ...root, mcpServers: servers };
11494
+ }
11495
+ function writeMergedMcpServersJson(configPath, sideboard) {
11496
+ let existing = {};
11497
+ if ((0, import_node_fs30.existsSync)(configPath)) {
11498
+ try {
11499
+ existing = JSON.parse((0, import_node_fs30.readFileSync)(configPath, "utf8"));
11500
+ } catch {
11501
+ existing = {};
11502
+ }
11503
+ }
11504
+ const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
11505
+ (0, import_node_fs30.mkdirSync)((0, import_node_path31.dirname)(configPath), { recursive: true });
11506
+ (0, import_node_fs30.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
11507
+ `);
11508
+ }
11509
+ function launchFromResolved(server) {
11510
+ return {
11511
+ command: server.command,
11512
+ args: server.args,
11513
+ env: {
11514
+ ...server.env ?? {},
11515
+ SIDEBOARD_APP_DATA: appDataDir()
11516
+ }
11517
+ };
11518
+ }
11519
+ async function registerPackagedUserMcpClients() {
11520
+ const launch = launchFromResolved(await resolveSideboardMcpServer());
11521
+ const cursor = userCursorMcpConfigPath();
11522
+ writeMergedMcpServersJson(cursor, launch);
11523
+ const claude = userClaudeMcpConfigPath();
11524
+ if ((0, import_node_fs30.existsSync)(claude)) {
11525
+ writeMergedMcpServersJson(claude, launch);
11526
+ return { cursor, claude };
11527
+ }
11528
+ return { cursor };
11529
+ }
11530
+ var import_node_fs30, import_node_os10, import_node_path31;
11531
+ var init_user_mcp_config = __esm({
11532
+ "src/agents/user-mcp-config.ts"() {
11533
+ "use strict";
11534
+ import_node_fs30 = require("fs");
11535
+ import_node_os10 = require("os");
11536
+ import_node_path31 = require("path");
11537
+ init_paths();
11538
+ init_injected_mcp();
11539
+ }
11540
+ });
11541
+
11542
+ // src/agents/orch-mcp-isolation.ts
11543
+ function isInjectedOrchMcpName(name) {
11544
+ const n = name.trim().toLowerCase();
11545
+ return n === "sideboard" || n === "brightsy" || n.startsWith("brightsy_");
11546
+ }
11547
+ function asObject2(value) {
11548
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
11549
+ return value;
11550
+ }
11551
+ function listMcpNamesFromJsonMap(raw, key) {
11552
+ return Object.keys(asObject2(asObject2(raw)[key])).filter((n) => n.trim());
11553
+ }
11554
+ function listMcpNamesFromCodexToml(text5) {
11555
+ try {
11556
+ const parsed = (0, import_smol_toml2.parse)(text5);
11557
+ return Object.keys(asObject2(parsed.mcp_servers)).filter((n) => n.trim());
11558
+ } catch {
11559
+ return [];
11560
+ }
11561
+ }
11562
+ function readJsonObject(path2) {
11563
+ try {
11564
+ return JSON.parse((0, import_node_fs31.readFileSync)(path2, "utf8"));
11565
+ } catch {
11566
+ return {};
11567
+ }
11568
+ }
11569
+ function readText(path2) {
11570
+ try {
11571
+ return (0, import_node_fs31.readFileSync)(path2, "utf8");
11572
+ } catch {
11573
+ return "";
11574
+ }
11575
+ }
11576
+ function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
11577
+ return [(0, import_node_path32.join)(home, ".codex", "config.toml"), (0, import_node_path32.join)(home, ".config", "codex", "config.toml")];
11578
+ }
11579
+ function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
11580
+ return [
11581
+ (0, import_node_path32.join)(home, ".config", "opencode", "opencode.json"),
11582
+ (0, import_node_path32.join)(home, ".config", "opencode", "opencode.jsonc")
11583
+ ];
11584
+ }
11585
+ function userMcpNamesToDisable(opts) {
11586
+ const keep = new Set(
11587
+ [...opts.injectedNames ?? []].map((n) => n.trim().toLowerCase()).filter(Boolean)
11588
+ );
11589
+ const out = [];
11590
+ const seen = /* @__PURE__ */ new Set();
11591
+ for (const raw of opts.names) {
11592
+ const name = raw.trim();
11593
+ if (!name) continue;
11594
+ const key = name.toLowerCase();
11595
+ if (seen.has(key) || keep.has(key) || isInjectedOrchMcpName(name)) continue;
11596
+ seen.add(key);
11597
+ out.push(name);
11598
+ }
11599
+ return out;
11600
+ }
11601
+ function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
11602
+ const names = [];
11603
+ for (const path2 of userCodexConfigPaths(home)) {
11604
+ if (!(0, import_node_fs31.existsSync)(path2)) continue;
11605
+ names.push(...listMcpNamesFromCodexToml(readText(path2)));
11606
+ }
11607
+ return names;
11608
+ }
11609
+ function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
11610
+ const names = [];
11611
+ for (const path2 of userOpencodeConfigPaths(home)) {
11612
+ if (!(0, import_node_fs31.existsSync)(path2)) continue;
11613
+ names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
11614
+ }
11615
+ return names;
11616
+ }
11617
+ function toCodexDisableUserMcpArgs(names) {
11618
+ const args = [];
11619
+ for (const name of names) {
11620
+ if (!/^[A-Za-z0-9_-]+$/.test(name)) continue;
11621
+ args.push("-c", `mcp_servers.${name}.enabled=false`);
11622
+ }
11623
+ return args;
11624
+ }
11625
+ var import_node_fs31, import_node_os11, import_node_path32, import_smol_toml2;
11626
+ var init_orch_mcp_isolation = __esm({
11627
+ "src/agents/orch-mcp-isolation.ts"() {
11628
+ "use strict";
11629
+ import_node_fs31 = require("fs");
11630
+ import_node_os11 = require("os");
11631
+ import_node_path32 = require("path");
11632
+ import_smol_toml2 = require("smol-toml");
11633
+ init_user_mcp_config();
11634
+ }
11635
+ });
11636
+
11417
11637
  // src/agents/codex.ts
11418
11638
  async function listCodexModels() {
11419
11639
  const now = Date.now();
@@ -11424,7 +11644,7 @@ async function listCodexModels() {
11424
11644
  if (codex === "codex") {
11425
11645
  const which = await run("which", ["codex"], { reject: false });
11426
11646
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
11427
- } else if (!(0, import_node_fs30.existsSync)(codex)) {
11647
+ } else if (!(0, import_node_fs32.existsSync)(codex)) {
11428
11648
  return FALLBACK_CODEX_MODELS;
11429
11649
  }
11430
11650
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -11459,12 +11679,12 @@ function usageFromCodex(usage) {
11459
11679
  }
11460
11680
  function codexConfigHasNetworkAccess() {
11461
11681
  const candidates = [
11462
- (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".codex", "config.toml"),
11463
- (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".config", "codex", "config.toml")
11682
+ (0, import_node_path33.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
11683
+ (0, import_node_path33.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
11464
11684
  ];
11465
11685
  for (const path2 of candidates) {
11466
- if (!(0, import_node_fs30.existsSync)(path2)) continue;
11467
- const text5 = (0, import_node_fs30.readFileSync)(path2, "utf8");
11686
+ if (!(0, import_node_fs32.existsSync)(path2)) continue;
11687
+ const text5 = (0, import_node_fs32.readFileSync)(path2, "utf8");
11468
11688
  if (/network_access\s*=\s*true/.test(text5)) return true;
11469
11689
  }
11470
11690
  return false;
@@ -11496,21 +11716,21 @@ function asRecord2(value) {
11496
11716
  return void 0;
11497
11717
  }
11498
11718
  function codexLooksAuthenticated() {
11499
- const authPath = (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".codex", "auth.json");
11500
- if (!(0, import_node_fs30.existsSync)(authPath)) return false;
11719
+ const authPath = (0, import_node_path33.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
11720
+ if (!(0, import_node_fs32.existsSync)(authPath)) return false;
11501
11721
  try {
11502
- return (0, import_node_fs30.statSync)(authPath).size > 2;
11722
+ return (0, import_node_fs32.statSync)(authPath).size > 2;
11503
11723
  } catch {
11504
11724
  return false;
11505
11725
  }
11506
11726
  }
11507
- var import_node_fs30, import_node_os10, import_node_path31, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
11727
+ var import_node_fs32, import_node_os12, import_node_path33, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
11508
11728
  var init_codex = __esm({
11509
11729
  "src/agents/codex.ts"() {
11510
11730
  "use strict";
11511
- import_node_fs30 = require("fs");
11512
- import_node_os10 = require("os");
11513
- import_node_path31 = require("path");
11731
+ import_node_fs32 = require("fs");
11732
+ import_node_os12 = require("os");
11733
+ import_node_path33 = require("path");
11514
11734
  init_run();
11515
11735
  init_app_settings();
11516
11736
  init_global_workspace();
@@ -11518,6 +11738,7 @@ var init_codex = __esm({
11518
11738
  init_usage();
11519
11739
  init_git_auth_mode();
11520
11740
  init_injected_mcp();
11741
+ init_orch_mcp_isolation();
11521
11742
  init_turn_input();
11522
11743
  init_types();
11523
11744
  CODEX_PROMPT_ARG_MAX = 2e5;
@@ -11535,7 +11756,7 @@ var init_codex = __esm({
11535
11756
  async detect() {
11536
11757
  const codex = resolveAgentExecutable("codex");
11537
11758
  if (codex !== "codex") {
11538
- if (!(0, import_node_fs30.existsSync)(codex)) {
11759
+ if (!(0, import_node_fs32.existsSync)(codex)) {
11539
11760
  return {
11540
11761
  agent: "codex",
11541
11762
  installed: false,
@@ -11595,7 +11816,15 @@ var init_codex = __esm({
11595
11816
  }),
11596
11817
  orchestratorThreadId: isOrchestrator ? thread.id : null
11597
11818
  });
11598
- const mcpOverrides = toCodexMcpConfigArgs(injected2);
11819
+ const mcpOverrides = [
11820
+ ...toCodexMcpConfigArgs(injected2),
11821
+ ...isOrchestrator ? toCodexDisableUserMcpArgs(
11822
+ userMcpNamesToDisable({
11823
+ injectedNames: injected2.map((s) => s.name),
11824
+ names: listUserCodexMcpNames()
11825
+ })
11826
+ ) : []
11827
+ ];
11599
11828
  const execOpts = [
11600
11829
  // Global orchestration cwd is not a git repo; without this Codex ≥0.147
11601
11830
  // refuses to start ("Not inside a trusted directory").
@@ -12022,21 +12251,21 @@ function platformRipgrepPackage() {
12022
12251
  }
12023
12252
  function usableRipgrepPath(candidate) {
12024
12253
  const raw = candidate?.trim();
12025
- if (!raw || !(0, import_node_path32.isAbsolute)(raw)) return null;
12254
+ if (!raw || !(0, import_node_path34.isAbsolute)(raw)) return null;
12026
12255
  const readable = nodeReadableScriptPath(raw);
12027
- if (!(0, import_node_fs31.existsSync)(readable) || isAsarPath(readable)) return null;
12256
+ if (!(0, import_node_fs33.existsSync)(readable) || isAsarPath(readable)) return null;
12028
12257
  return readable;
12029
12258
  }
12030
12259
  function walkForBundledRipgrep(startFile) {
12031
12260
  if (!startFile) return null;
12032
12261
  const pkg = platformRipgrepPackage();
12033
12262
  const name = rgBinaryName();
12034
- let dir = (0, import_node_path32.dirname)((0, import_node_path32.resolve)(startFile));
12035
- const root = (0, import_node_path32.parse)(dir).root;
12263
+ let dir = (0, import_node_path34.dirname)((0, import_node_path34.resolve)(startFile));
12264
+ const root = (0, import_node_path34.parse)(dir).root;
12036
12265
  while (dir !== root) {
12037
- const hit = usableRipgrepPath((0, import_node_path32.join)(dir, "node_modules", pkg, "bin", name));
12266
+ const hit = usableRipgrepPath((0, import_node_path34.join)(dir, "node_modules", pkg, "bin", name));
12038
12267
  if (hit) return hit;
12039
- const next = (0, import_node_path32.dirname)(dir);
12268
+ const next = (0, import_node_path34.dirname)(dir);
12040
12269
  if (next === dir) break;
12041
12270
  dir = next;
12042
12271
  }
@@ -12046,7 +12275,7 @@ function requireResolveBundledRipgrep(fromFile) {
12046
12275
  try {
12047
12276
  const req = (0, import_node_module2.createRequire)(fromFile);
12048
12277
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
12049
- return usableRipgrepPath((0, import_node_path32.join)((0, import_node_path32.dirname)(pkgJson), "bin", rgBinaryName()));
12278
+ return usableRipgrepPath((0, import_node_path34.join)((0, import_node_path34.dirname)(pkgJson), "bin", rgBinaryName()));
12050
12279
  } catch {
12051
12280
  return null;
12052
12281
  }
@@ -12068,13 +12297,13 @@ function cursorRipgrepEnv(opts) {
12068
12297
  const path2 = resolveCursorRipgrepPath(opts);
12069
12298
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
12070
12299
  }
12071
- var import_node_fs31, import_node_module2, import_node_path32, RIPGREP_ENV;
12300
+ var import_node_fs33, import_node_module2, import_node_path34, RIPGREP_ENV;
12072
12301
  var init_cursor_ripgrep = __esm({
12073
12302
  "src/agents/cursor-ripgrep.ts"() {
12074
12303
  "use strict";
12075
- import_node_fs31 = require("fs");
12304
+ import_node_fs33 = require("fs");
12076
12305
  import_node_module2 = require("module");
12077
- import_node_path32 = require("path");
12306
+ import_node_path34 = require("path");
12078
12307
  init_node_launch();
12079
12308
  init_packaged_runtime();
12080
12309
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -12120,11 +12349,11 @@ function entryDir() {
12120
12349
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12121
12350
  if (cjsDir) return cjsDir;
12122
12351
  try {
12123
- return (0, import_node_path33.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12352
+ return (0, import_node_path35.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12124
12353
  } catch {
12125
12354
  try {
12126
12355
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
12127
- return (0, import_node_path33.dirname)(req.resolve("@sideboard-ai/core"));
12356
+ return (0, import_node_path35.dirname)(req.resolve("@sideboard-ai/core"));
12128
12357
  } catch {
12129
12358
  return process.cwd();
12130
12359
  }
@@ -12135,27 +12364,27 @@ function cursorRunnerPath() {
12135
12364
  if (packaged) return packaged;
12136
12365
  const root = entryDir();
12137
12366
  const candidates = [
12138
- (0, import_node_path33.join)(root, "agents", "cursor-runner.js"),
12139
- (0, import_node_path33.join)(root, "agents", "cursor-runner.cjs"),
12367
+ (0, import_node_path35.join)(root, "agents", "cursor-runner.js"),
12368
+ (0, import_node_path35.join)(root, "agents", "cursor-runner.cjs"),
12140
12369
  // If somehow resolved from package root instead of dist/
12141
- (0, import_node_path33.join)(root, "dist", "agents", "cursor-runner.js"),
12142
- (0, import_node_path33.join)(root, "dist", "agents", "cursor-runner.cjs"),
12370
+ (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.js"),
12371
+ (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.cjs"),
12143
12372
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
12144
- (0, import_node_path33.join)(root, "cursor-runner.ts"),
12145
- (0, import_node_path33.join)(root, "src", "agents", "cursor-runner.ts")
12373
+ (0, import_node_path35.join)(root, "cursor-runner.ts"),
12374
+ (0, import_node_path35.join)(root, "src", "agents", "cursor-runner.ts")
12146
12375
  ];
12147
12376
  for (const candidate of candidates) {
12148
- if ((0, import_node_fs32.existsSync)(candidate)) return candidate;
12377
+ if ((0, import_node_fs34.existsSync)(candidate)) return candidate;
12149
12378
  }
12150
12379
  return candidates[0];
12151
12380
  }
12152
- var import_node_fs32, import_node_module3, import_node_path33, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12381
+ 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;
12153
12382
  var init_cursor = __esm({
12154
12383
  "src/agents/cursor.ts"() {
12155
12384
  "use strict";
12156
- import_node_fs32 = require("fs");
12385
+ import_node_fs34 = require("fs");
12157
12386
  import_node_module3 = require("module");
12158
- import_node_path33 = require("path");
12387
+ import_node_path35 = require("path");
12159
12388
  import_node_url2 = require("url");
12160
12389
  import_sdk = require("@cursor/sdk");
12161
12390
  init_run();
@@ -12221,6 +12450,7 @@ var init_cursor = __esm({
12221
12450
  fast: thread.fast,
12222
12451
  planMode: thread.planMode,
12223
12452
  apiKey,
12453
+ ...isOrchestrator ? { isolateAmbientMcp: true } : {},
12224
12454
  ...Object.keys(mcpServers).length > 0 ? { mcpServers } : {}
12225
12455
  };
12226
12456
  const runner = cursorRunnerPath();
@@ -12306,7 +12536,7 @@ async function listOpencodeModels() {
12306
12536
  if (opencode === "opencode") {
12307
12537
  const which = await run("which", ["opencode"], { reject: false });
12308
12538
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
12309
- } else if (!(0, import_node_fs33.existsSync)(opencode)) {
12539
+ } else if (!(0, import_node_fs35.existsSync)(opencode)) {
12310
12540
  return FALLBACK_OPENCODE_MODELS;
12311
12541
  }
12312
12542
  const listed = await run(opencode, ["models"], { reject: false });
@@ -12336,17 +12566,18 @@ function usageFromOpencode(tokens) {
12336
12566
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
12337
12567
  };
12338
12568
  }
12339
- var import_node_fs33, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12569
+ var import_node_fs35, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12340
12570
  var init_opencode = __esm({
12341
12571
  "src/agents/opencode.ts"() {
12342
12572
  "use strict";
12343
- import_node_fs33 = require("fs");
12573
+ import_node_fs35 = require("fs");
12344
12574
  init_run();
12345
12575
  init_app_settings();
12346
12576
  init_global_workspace();
12347
12577
  init_error_detail();
12348
12578
  init_message_parts();
12349
12579
  init_injected_mcp();
12580
+ init_orch_mcp_isolation();
12350
12581
  init_turn_input();
12351
12582
  init_types();
12352
12583
  FALLBACK_OPENCODE_MODELS = [
@@ -12367,7 +12598,7 @@ var init_opencode = __esm({
12367
12598
  async detect() {
12368
12599
  const opencode = resolveAgentExecutable("opencode");
12369
12600
  if (opencode !== "opencode") {
12370
- if (!(0, import_node_fs33.existsSync)(opencode)) {
12601
+ if (!(0, import_node_fs35.existsSync)(opencode)) {
12371
12602
  return {
12372
12603
  agent: "opencode",
12373
12604
  installed: false,
@@ -12429,7 +12660,11 @@ var init_opencode = __esm({
12429
12660
  }),
12430
12661
  orchestratorThreadId: isOrchestrator ? thread.id : null
12431
12662
  });
12432
- const mcpContent = injected2.length > 0 ? toOpencodeMcpConfigContent(injected2) : null;
12663
+ const disableNames = isOrchestrator ? userMcpNamesToDisable({
12664
+ injectedNames: injected2.map((s) => s.name),
12665
+ names: listUserOpencodeMcpNames()
12666
+ }) : [];
12667
+ const mcpContent = injected2.length > 0 || disableNames.length > 0 ? toOpencodeMcpConfigContent(injected2, { disableNames }) : null;
12433
12668
  return {
12434
12669
  file: resolveAgentExecutable("opencode"),
12435
12670
  args,
@@ -13114,6 +13349,7 @@ __export(agents_exports, {
13114
13349
  listModelsForAgent: () => listModelsForAgent,
13115
13350
  listOpencodeModels: () => listOpencodeModels,
13116
13351
  loginAgent: () => loginAgent,
13352
+ mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
13117
13353
  openInSystemTerminal: () => openInSystemTerminal,
13118
13354
  opencodeAdapter: () => opencodeAdapter,
13119
13355
  parseCursorRunnerLine: () => parseCursorRunnerLine,
@@ -14224,21 +14460,21 @@ function shouldRefreshReviewRequestTemplate(content) {
14224
14460
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
14225
14461
  }
14226
14462
  function readTextIfPresent(abs) {
14227
- if (!(0, import_node_fs34.existsSync)(abs)) return null;
14463
+ if (!(0, import_node_fs36.existsSync)(abs)) return null;
14228
14464
  try {
14229
- const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
14465
+ const content = (0, import_node_fs36.readFileSync)(abs, "utf8");
14230
14466
  return content.trim() ? content : null;
14231
14467
  } catch {
14232
14468
  return null;
14233
14469
  }
14234
14470
  }
14235
14471
  function readLocalGuidelines(worktreePath) {
14236
- const localAbs = (0, import_node_path34.join)(worktreePath, REVIEW_REQUEST_PATH);
14472
+ const localAbs = (0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH);
14237
14473
  const localContent = readTextIfPresent(localAbs);
14238
14474
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14239
14475
  return { path: REVIEW_REQUEST_PATH, content: localContent };
14240
14476
  }
14241
- const legacyAbs = (0, import_node_path34.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14477
+ const legacyAbs = (0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14242
14478
  const legacyContent = readTextIfPresent(legacyAbs);
14243
14479
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
14244
14480
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -14262,27 +14498,27 @@ function contextGuidelines(content, source) {
14262
14498
  };
14263
14499
  }
14264
14500
  function writeContextGuidelines(worktreePath, content) {
14265
- const abs = (0, import_node_path34.join)(worktreePath, CONTEXT_REVIEW_PATH);
14266
- (0, import_node_fs34.mkdirSync)((0, import_node_path34.dirname)(abs), { recursive: true });
14501
+ const abs = (0, import_node_path36.join)(worktreePath, CONTEXT_REVIEW_PATH);
14502
+ (0, import_node_fs36.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
14267
14503
  const body = content.endsWith("\n") ? content : `${content}
14268
14504
  `;
14269
- (0, import_node_fs34.writeFileSync)(abs, body, "utf8");
14505
+ (0, import_node_fs36.writeFileSync)(abs, body, "utf8");
14270
14506
  return body;
14271
14507
  }
14272
14508
  function readSideboardReview(worktreePath, repoPath) {
14273
- const fromWorktree = readTextIfPresent((0, import_node_path34.join)(worktreePath, REPO_REVIEW_PATH));
14509
+ const fromWorktree = readTextIfPresent((0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH));
14274
14510
  if (fromWorktree) return fromWorktree;
14275
14511
  const repo = repoPath?.replace(/\/+$/, "");
14276
14512
  const wt = worktreePath.replace(/\/+$/, "");
14277
14513
  if (!repo || repo === wt) return null;
14278
- return readTextIfPresent((0, import_node_path34.join)(repo, REPO_REVIEW_PATH));
14514
+ return readTextIfPresent((0, import_node_path36.join)(repo, REPO_REVIEW_PATH));
14279
14515
  }
14280
14516
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
14281
- const skillContent = readTextIfPresent((0, import_node_path34.join)(worktreePath, REVIEW_SKILL_PATH));
14517
+ const skillContent = readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_SKILL_PATH));
14282
14518
  if (skillContent) {
14283
14519
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
14284
14520
  }
14285
- const contextContent = readTextIfPresent((0, import_node_path34.join)(worktreePath, CONTEXT_REVIEW_PATH));
14521
+ const contextContent = readTextIfPresent((0, import_node_path36.join)(worktreePath, CONTEXT_REVIEW_PATH));
14286
14522
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
14287
14523
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
14288
14524
  }
@@ -14320,7 +14556,7 @@ function buildReviewRequestAttachment(content, opts) {
14320
14556
  };
14321
14557
  }
14322
14558
  function readExistingReviewRequestFile(worktreePath) {
14323
- return readTextIfPresent((0, import_node_path34.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path34.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path34.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path34.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path34.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14559
+ return readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14324
14560
  }
14325
14561
  async function requestReview(threadRef, send2) {
14326
14562
  const from = findThreadByRef(threadRef);
@@ -14347,13 +14583,13 @@ async function requestReview(threadRef, send2) {
14347
14583
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
14348
14584
  return { tab: started, from };
14349
14585
  }
14350
- var import_node_crypto8, import_node_fs34, import_node_path34, 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;
14586
+ var import_node_crypto8, import_node_fs36, import_node_path36, 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;
14351
14587
  var init_request_review = __esm({
14352
14588
  "src/review/request-review.ts"() {
14353
14589
  "use strict";
14354
14590
  import_node_crypto8 = require("crypto");
14355
- import_node_fs34 = require("fs");
14356
- import_node_path34 = require("path");
14591
+ import_node_fs36 = require("fs");
14592
+ import_node_path36 = require("path");
14357
14593
  init_global_workspace();
14358
14594
  init_chat_tabs();
14359
14595
  init_thread_store();
@@ -14379,9 +14615,9 @@ function matchSimpleGlob(pattern, name) {
14379
14615
  return new RegExp(`^${escaped}$`).test(name);
14380
14616
  }
14381
14617
  function readWorktreeInclude(repoPath) {
14382
- const path2 = (0, import_node_path35.join)(repoPath, ".worktreeinclude");
14383
- if (!(0, import_node_fs35.existsSync)(path2)) return [];
14384
- return (0, import_node_fs35.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14618
+ const path2 = (0, import_node_path37.join)(repoPath, ".worktreeinclude");
14619
+ if (!(0, import_node_fs37.existsSync)(path2)) return [];
14620
+ return (0, import_node_fs37.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14385
14621
  }
14386
14622
  function resolveFilesToCopy(repoPath) {
14387
14623
  const fromInclude = readWorktreeInclude(repoPath);
@@ -14391,10 +14627,10 @@ function resolveFilesToCopy(repoPath) {
14391
14627
  if (settings?.fileIncludeGlobs?.length) {
14392
14628
  const matched = [];
14393
14629
  try {
14394
- for (const entry of (0, import_node_fs35.readdirSync)(repoPath, { withFileTypes: true })) {
14630
+ for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
14395
14631
  if (!entry.isFile()) continue;
14396
14632
  for (const glob of settings.fileIncludeGlobs) {
14397
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path35.basename)(glob), entry.name)) {
14633
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path37.basename)(glob), entry.name)) {
14398
14634
  matched.push(entry.name);
14399
14635
  break;
14400
14636
  }
@@ -14406,7 +14642,7 @@ function resolveFilesToCopy(repoPath) {
14406
14642
  }
14407
14643
  const defaults = [];
14408
14644
  try {
14409
- for (const entry of (0, import_node_fs35.readdirSync)(repoPath, { withFileTypes: true })) {
14645
+ for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
14410
14646
  if (entry.isFile() && entry.name.startsWith(".env")) {
14411
14647
  defaults.push(entry.name);
14412
14648
  }
@@ -14420,11 +14656,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
14420
14656
  const patterns = resolveFilesToCopy(repoPath);
14421
14657
  const copied = [];
14422
14658
  for (const rel of patterns) {
14423
- const src = (0, import_node_path35.join)(repoPath, rel);
14424
- if (!(0, import_node_fs35.existsSync)(src)) continue;
14425
- const dest = (0, import_node_path35.join)(worktreePath, rel);
14426
- (0, import_node_fs35.mkdirSync)((0, import_node_path35.dirname)(dest), { recursive: true });
14427
- (0, import_node_fs35.copyFileSync)(src, dest);
14659
+ const src = (0, import_node_path37.join)(repoPath, rel);
14660
+ if (!(0, import_node_fs37.existsSync)(src)) continue;
14661
+ const dest = (0, import_node_path37.join)(worktreePath, rel);
14662
+ (0, import_node_fs37.mkdirSync)((0, import_node_path37.dirname)(dest), { recursive: true });
14663
+ (0, import_node_fs37.copyFileSync)(src, dest);
14428
14664
  copied.push(rel);
14429
14665
  }
14430
14666
  return copied;
@@ -14459,7 +14695,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
14459
14695
  const env = stripNestedElectronEnv({
14460
14696
  ...baseEnv ?? process.env
14461
14697
  });
14462
- const name = opts.workspaceName ?? (0, import_node_path35.basename)(opts.worktreePath);
14698
+ const name = opts.workspaceName ?? (0, import_node_path37.basename)(opts.worktreePath);
14463
14699
  const ports = opts.ports ?? [];
14464
14700
  const primary = ports[0];
14465
14701
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -14721,13 +14957,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
14721
14957
  done: handle.done
14722
14958
  };
14723
14959
  }
14724
- var import_node_fs35, import_node_net, import_node_path35, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
14960
+ var import_node_fs37, import_node_net, import_node_path37, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
14725
14961
  var init_conductor = __esm({
14726
14962
  "src/hook/conductor.ts"() {
14727
14963
  "use strict";
14728
- import_node_fs35 = require("fs");
14964
+ import_node_fs37 = require("fs");
14729
14965
  import_node_net = require("net");
14730
- import_node_path35 = require("path");
14966
+ import_node_path37 = require("path");
14731
14967
  import_execa4 = require("execa");
14732
14968
  import_node_readline3 = require("readline");
14733
14969
  init_settings();
@@ -14754,9 +14990,9 @@ async function findOrphanWorktrees(repoPaths) {
14754
14990
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
14755
14991
  );
14756
14992
  const homeRoot = sideboardWorkspacesDir();
14757
- if ((0, import_node_fs36.existsSync)(homeRoot)) {
14993
+ if ((0, import_node_fs38.existsSync)(homeRoot)) {
14758
14994
  try {
14759
- for (const entry of (0, import_node_fs36.readdirSync)(homeRoot, { withFileTypes: true })) {
14995
+ for (const entry of (0, import_node_fs38.readdirSync)(homeRoot, { withFileTypes: true })) {
14760
14996
  if (!entry.isDirectory()) continue;
14761
14997
  void entry;
14762
14998
  }
@@ -14766,7 +15002,7 @@ async function findOrphanWorktrees(repoPaths) {
14766
15002
  const orphans = [];
14767
15003
  const seen = /* @__PURE__ */ new Set();
14768
15004
  for (const repoPath of repos) {
14769
- if (!repoPath || !(0, import_node_fs36.existsSync)(repoPath)) continue;
15005
+ if (!repoPath || !(0, import_node_fs38.existsSync)(repoPath)) continue;
14770
15006
  try {
14771
15007
  const wts = await listWorktrees(repoPath);
14772
15008
  for (const wt of wts) {
@@ -14777,7 +15013,7 @@ async function findOrphanWorktrees(repoPaths) {
14777
15013
  seen.add(path2);
14778
15014
  let mtimeMs = 0;
14779
15015
  try {
14780
- mtimeMs = (0, import_node_fs36.statSync)(path2).mtimeMs;
15016
+ mtimeMs = (0, import_node_fs38.statSync)(path2).mtimeMs;
14781
15017
  } catch {
14782
15018
  mtimeMs = 0;
14783
15019
  }
@@ -14787,16 +15023,16 @@ async function findOrphanWorktrees(repoPaths) {
14787
15023
  }
14788
15024
  try {
14789
15025
  const root = worktreesRoot(repoPath);
14790
- if ((0, import_node_fs36.existsSync)(root)) {
14791
- for (const entry of (0, import_node_fs36.readdirSync)(root, { withFileTypes: true })) {
15026
+ if ((0, import_node_fs38.existsSync)(root)) {
15027
+ for (const entry of (0, import_node_fs38.readdirSync)(root, { withFileTypes: true })) {
14792
15028
  if (!entry.isDirectory()) continue;
14793
- const path2 = (0, import_node_path36.join)(root, entry.name).replace(/\/$/, "");
15029
+ const path2 = (0, import_node_path38.join)(root, entry.name).replace(/\/$/, "");
14794
15030
  if (known.has(path2) || seen.has(path2)) continue;
14795
- if (!(0, import_node_fs36.existsSync)((0, import_node_path36.join)(path2, ".git"))) continue;
15031
+ if (!(0, import_node_fs38.existsSync)((0, import_node_path38.join)(path2, ".git"))) continue;
14796
15032
  seen.add(path2);
14797
15033
  let mtimeMs = 0;
14798
15034
  try {
14799
- mtimeMs = (0, import_node_fs36.statSync)(path2).mtimeMs;
15035
+ mtimeMs = (0, import_node_fs38.statSync)(path2).mtimeMs;
14800
15036
  } catch {
14801
15037
  mtimeMs = Date.now();
14802
15038
  }
@@ -14857,12 +15093,12 @@ function worktreeCleanupSettings() {
14857
15093
  autoCleanupOrphans: a.autoCleanupOrphans
14858
15094
  };
14859
15095
  }
14860
- var import_node_fs36, import_node_path36;
15096
+ var import_node_fs38, import_node_path38;
14861
15097
  var init_orphan_cleanup = __esm({
14862
15098
  "src/git/orphan-cleanup.ts"() {
14863
15099
  "use strict";
14864
- import_node_fs36 = require("fs");
14865
- import_node_path36 = require("path");
15100
+ import_node_fs38 = require("fs");
15101
+ import_node_path38 = require("path");
14866
15102
  init_worktree();
14867
15103
  init_thread_store();
14868
15104
  init_paths();
@@ -14965,12 +15201,12 @@ async function cloneRepoIntoSideboard(opts) {
14965
15201
  if (!url) throw new Error("Clone URL is required");
14966
15202
  let name = opts.name?.trim();
14967
15203
  if (!name) {
14968
- const leaf = (0, import_node_path37.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15204
+ const leaf = (0, import_node_path39.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
14969
15205
  name = leaf || "repo";
14970
15206
  }
14971
15207
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
14972
- const dest = (0, import_node_path37.join)(sideboardReposDir(), name);
14973
- if ((0, import_node_fs37.existsSync)(dest)) {
15208
+ const dest = (0, import_node_path39.join)(sideboardReposDir(), name);
15209
+ if ((0, import_node_fs39.existsSync)(dest)) {
14974
15210
  const repoPath2 = await resolveRepoRoot(dest);
14975
15211
  const workspace2 = await ensureWorkspace(repoPath2);
14976
15212
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -14985,12 +15221,12 @@ async function cloneRepoIntoSideboard(opts) {
14985
15221
  const workspace = await ensureWorkspace(repoPath);
14986
15222
  return { repoPath, workspace };
14987
15223
  }
14988
- var import_node_fs37, import_node_path37, import_execa6;
15224
+ var import_node_fs39, import_node_path39, import_execa6;
14989
15225
  var init_clone_repo = __esm({
14990
15226
  "src/git/clone-repo.ts"() {
14991
15227
  "use strict";
14992
- import_node_fs37 = require("fs");
14993
- import_node_path37 = require("path");
15228
+ import_node_fs39 = require("fs");
15229
+ import_node_path39 = require("path");
14994
15230
  import_execa6 = require("execa");
14995
15231
  init_paths();
14996
15232
  init_workspaces();
@@ -16087,7 +16323,7 @@ function reuseLiveThread(input, repoPath, match) {
16087
16323
  }
16088
16324
  async function createThread(input, _onSetupLine) {
16089
16325
  const repoPath = await resolveRepoRoot(input.repoPath);
16090
- if (!(0, import_node_fs38.existsSync)(repoPath)) {
16326
+ if (!(0, import_node_fs40.existsSync)(repoPath)) {
16091
16327
  throw new Error(`Repo not found: ${repoPath}`);
16092
16328
  }
16093
16329
  const reused = reuseLiveThread(input, repoPath, {
@@ -16267,11 +16503,11 @@ async function listLinearIssues(agent, repoPath) {
16267
16503
  }
16268
16504
  return adapter.listLinearIssues(repoPath);
16269
16505
  }
16270
- var import_node_fs38;
16506
+ var import_node_fs40;
16271
16507
  var init_create = __esm({
16272
16508
  "src/threads/create.ts"() {
16273
16509
  "use strict";
16274
- import_node_fs38 = require("fs");
16510
+ import_node_fs40 = require("fs");
16275
16511
  init_detect();
16276
16512
  init_worktree();
16277
16513
  init_home_board();
@@ -16374,20 +16610,20 @@ function writeTurnLive(threadId, progress) {
16374
16610
  const path2 = threadLivePath(threadId);
16375
16611
  const tmp = `${path2}.${process.pid}.tmp`;
16376
16612
  try {
16377
- (0, import_node_fs39.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
16378
- (0, import_node_fs39.renameSync)(tmp, path2);
16613
+ (0, import_node_fs41.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
16614
+ (0, import_node_fs41.renameSync)(tmp, path2);
16379
16615
  } catch {
16380
16616
  try {
16381
- (0, import_node_fs39.unlinkSync)(tmp);
16617
+ (0, import_node_fs41.unlinkSync)(tmp);
16382
16618
  } catch {
16383
16619
  }
16384
16620
  }
16385
16621
  }
16386
16622
  function readTurnLive(threadId) {
16387
16623
  const path2 = threadLivePath(threadId);
16388
- if (!(0, import_node_fs39.existsSync)(path2)) return null;
16624
+ if (!(0, import_node_fs41.existsSync)(path2)) return null;
16389
16625
  try {
16390
- const raw = JSON.parse((0, import_node_fs39.readFileSync)(path2, "utf8"));
16626
+ const raw = JSON.parse((0, import_node_fs41.readFileSync)(path2, "utf8"));
16391
16627
  if (!raw || typeof raw.summary !== "string") return null;
16392
16628
  return raw;
16393
16629
  } catch {
@@ -16399,17 +16635,17 @@ function clearTurnLive(threadId) {
16399
16635
  if (buf?.timer) clearTimeout(buf.timer);
16400
16636
  buffers.delete(threadId);
16401
16637
  const path2 = threadLivePath(threadId);
16402
- if (!(0, import_node_fs39.existsSync)(path2)) return;
16638
+ if (!(0, import_node_fs41.existsSync)(path2)) return;
16403
16639
  try {
16404
- (0, import_node_fs39.unlinkSync)(path2);
16640
+ (0, import_node_fs41.unlinkSync)(path2);
16405
16641
  } catch {
16406
16642
  }
16407
16643
  }
16408
- var import_node_fs39, buffers, FLUSH_MS, MAX_PARTS;
16644
+ var import_node_fs41, buffers, FLUSH_MS, MAX_PARTS;
16409
16645
  var init_turn_live = __esm({
16410
16646
  "src/store/turn-live.ts"() {
16411
16647
  "use strict";
16412
- import_node_fs39 = require("fs");
16648
+ import_node_fs41 = require("fs");
16413
16649
  init_message_parts();
16414
16650
  init_paths();
16415
16651
  buffers = /* @__PURE__ */ new Map();
@@ -16442,9 +16678,13 @@ var init_reconcile_heal = __esm({
16442
16678
  // src/orchestrator/setup-last-error.ts
16443
16679
  function shouldStampSetupLastError(opts) {
16444
16680
  if (opts.turnInFlight) return false;
16445
- if (opts.status === "running") return false;
16681
+ if (opts.status === "running" || opts.status === "queued") return false;
16682
+ if (opts.hasQueuedPrompt) return false;
16446
16683
  return true;
16447
16684
  }
16685
+ function isSetupLastError(err) {
16686
+ return /^Setup (exited|failed)\b/i.test(err?.trim() ?? "");
16687
+ }
16448
16688
  function isStaleLastErrorDuringTurn(err) {
16449
16689
  return Boolean(err?.trim());
16450
16690
  }
@@ -16625,7 +16865,7 @@ var init_quota_failover = __esm({
16625
16865
  // src/threads/adopt.ts
16626
16866
  function thisModuleFile() {
16627
16867
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
16628
- return cjsFile || process.argv[1] || (0, import_node_path38.join)(process.cwd(), "package.json");
16868
+ return cjsFile || process.argv[1] || (0, import_node_path40.join)(process.cwd(), "package.json");
16629
16869
  }
16630
16870
  function openReadonlySqlite(file) {
16631
16871
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -16643,21 +16883,21 @@ function mapAgentType(raw) {
16643
16883
  return null;
16644
16884
  }
16645
16885
  function resolveConductorCursorAgentId(workspacePath) {
16646
- if (!workspacePath || !(0, import_node_fs40.existsSync)(CURSOR_SDK_STORE)) return null;
16886
+ if (!workspacePath || !(0, import_node_fs42.existsSync)(CURSOR_SDK_STORE)) return null;
16647
16887
  const normalized = workspacePath.replace(/\/$/, "");
16648
16888
  let best = null;
16649
16889
  let hashes;
16650
16890
  try {
16651
- hashes = (0, import_node_fs40.readdirSync)(CURSOR_SDK_STORE);
16891
+ hashes = (0, import_node_fs42.readdirSync)(CURSOR_SDK_STORE);
16652
16892
  } catch {
16653
16893
  return null;
16654
16894
  }
16655
16895
  for (const hash of hashes) {
16656
- const agentsFile = (0, import_node_path38.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
16657
- if (!(0, import_node_fs40.existsSync)(agentsFile)) continue;
16896
+ const agentsFile = (0, import_node_path40.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
16897
+ if (!(0, import_node_fs42.existsSync)(agentsFile)) continue;
16658
16898
  let text5;
16659
16899
  try {
16660
- text5 = (0, import_node_fs40.readFileSync)(agentsFile, "utf8");
16900
+ text5 = (0, import_node_fs42.readFileSync)(agentsFile, "utf8");
16661
16901
  } catch {
16662
16902
  continue;
16663
16903
  }
@@ -16681,7 +16921,7 @@ function resolveConductorCursorAgentId(workspacePath) {
16681
16921
  return best?.agentId ?? null;
16682
16922
  }
16683
16923
  async function adoptThread(input) {
16684
- if (!(0, import_node_fs40.existsSync)(input.worktreePath)) {
16924
+ if (!(0, import_node_fs42.existsSync)(input.worktreePath)) {
16685
16925
  throw new Error(`Worktree not found: ${input.worktreePath}`);
16686
16926
  }
16687
16927
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -16710,18 +16950,18 @@ function conductorDbPath() {
16710
16950
  return CONDUCTOR_DB;
16711
16951
  }
16712
16952
  function listConductorWorkspaces() {
16713
- if (!(0, import_node_fs40.existsSync)(CONDUCTOR_DB)) {
16953
+ if (!(0, import_node_fs42.existsSync)(CONDUCTOR_DB)) {
16714
16954
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
16715
16955
  }
16716
- const tmp = (0, import_node_fs40.mkdtempSync)((0, import_node_path38.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
16717
- const snapshot = (0, import_node_path38.join)(tmp, "conductor.db");
16956
+ const tmp = (0, import_node_fs42.mkdtempSync)((0, import_node_path40.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16957
+ const snapshot = (0, import_node_path40.join)(tmp, "conductor.db");
16718
16958
  try {
16719
- (0, import_node_fs40.copyFileSync)(CONDUCTOR_DB, snapshot);
16959
+ (0, import_node_fs42.copyFileSync)(CONDUCTOR_DB, snapshot);
16720
16960
  for (const suffix of ["-wal", "-shm"]) {
16721
16961
  const src = `${CONDUCTOR_DB}${suffix}`;
16722
- if ((0, import_node_fs40.existsSync)(src)) {
16962
+ if ((0, import_node_fs42.existsSync)(src)) {
16723
16963
  try {
16724
- (0, import_node_fs40.copyFileSync)(src, `${snapshot}${suffix}`);
16964
+ (0, import_node_fs42.copyFileSync)(src, `${snapshot}${suffix}`);
16725
16965
  } catch {
16726
16966
  }
16727
16967
  }
@@ -16797,22 +17037,22 @@ function listConductorWorkspaces() {
16797
17037
  db.close();
16798
17038
  }
16799
17039
  } finally {
16800
- (0, import_node_fs40.rmSync)(tmp, { recursive: true, force: true });
17040
+ (0, import_node_fs42.rmSync)(tmp, { recursive: true, force: true });
16801
17041
  }
16802
17042
  }
16803
17043
  function importConductorWorkspace(workspaceId) {
16804
- if (!(0, import_node_fs40.existsSync)(CONDUCTOR_DB)) {
17044
+ if (!(0, import_node_fs42.existsSync)(CONDUCTOR_DB)) {
16805
17045
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
16806
17046
  }
16807
- const tmp = (0, import_node_fs40.mkdtempSync)((0, import_node_path38.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
16808
- const snapshot = (0, import_node_path38.join)(tmp, "conductor.db");
17047
+ const tmp = (0, import_node_fs42.mkdtempSync)((0, import_node_path40.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17048
+ const snapshot = (0, import_node_path40.join)(tmp, "conductor.db");
16809
17049
  try {
16810
- (0, import_node_fs40.copyFileSync)(CONDUCTOR_DB, snapshot);
17050
+ (0, import_node_fs42.copyFileSync)(CONDUCTOR_DB, snapshot);
16811
17051
  for (const suffix of ["-wal", "-shm"]) {
16812
17052
  const src = `${CONDUCTOR_DB}${suffix}`;
16813
- if ((0, import_node_fs40.existsSync)(src)) {
17053
+ if ((0, import_node_fs42.existsSync)(src)) {
16814
17054
  try {
16815
- (0, import_node_fs40.copyFileSync)(src, `${snapshot}${suffix}`);
17055
+ (0, import_node_fs42.copyFileSync)(src, `${snapshot}${suffix}`);
16816
17056
  } catch {
16817
17057
  }
16818
17058
  }
@@ -16830,7 +17070,7 @@ function importConductorWorkspace(workspaceId) {
16830
17070
  ).get(workspaceId);
16831
17071
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
16832
17072
  const worktreePath = String(row.workspacePath);
16833
- if (!(0, import_node_fs40.existsSync)(worktreePath)) {
17073
+ if (!(0, import_node_fs42.existsSync)(worktreePath)) {
16834
17074
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
16835
17075
  }
16836
17076
  let sessionId = null;
@@ -16893,31 +17133,31 @@ function importConductorWorkspace(workspaceId) {
16893
17133
  db.close();
16894
17134
  }
16895
17135
  } finally {
16896
- (0, import_node_fs40.rmSync)(tmp, { recursive: true, force: true });
17136
+ (0, import_node_fs42.rmSync)(tmp, { recursive: true, force: true });
16897
17137
  }
16898
17138
  }
16899
17139
  async function importConductorWorkspaceAsync(workspaceId) {
16900
17140
  return importConductorWorkspace(workspaceId);
16901
17141
  }
16902
- var import_node_child_process4, import_node_fs40, import_node_os11, import_node_path38, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
17142
+ var import_node_child_process4, import_node_fs42, import_node_os13, import_node_path40, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
16903
17143
  var init_adopt = __esm({
16904
17144
  "src/threads/adopt.ts"() {
16905
17145
  "use strict";
16906
17146
  import_node_child_process4 = require("child_process");
16907
- import_node_fs40 = require("fs");
16908
- import_node_os11 = require("os");
16909
- import_node_path38 = require("path");
17147
+ import_node_fs42 = require("fs");
17148
+ import_node_os13 = require("os");
17149
+ import_node_path40 = require("path");
16910
17150
  import_node_module4 = require("module");
16911
17151
  init_worktree();
16912
17152
  init_thread_store();
16913
- CONDUCTOR_APP_SUPPORT = (0, import_node_path38.join)(
17153
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path40.join)(
16914
17154
  process.env.HOME ?? "",
16915
17155
  "Library",
16916
17156
  "Application Support",
16917
17157
  "com.conductor.app"
16918
17158
  );
16919
- CONDUCTOR_DB = (0, import_node_path38.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
16920
- CURSOR_SDK_STORE = (0, import_node_path38.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
17159
+ CONDUCTOR_DB = (0, import_node_path40.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
17160
+ CURSOR_SDK_STORE = (0, import_node_path40.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
16921
17161
  }
16922
17162
  });
16923
17163
 
@@ -16984,7 +17224,7 @@ async function openStackLayer(input, _onSetupLine) {
16984
17224
  let createdWorktree = false;
16985
17225
  const trees = await listWorktrees(repoPath);
16986
17226
  const checkedOut = trees.find((w) => w.branch === branchName);
16987
- if (checkedOut?.path && (0, import_node_fs41.existsSync)(checkedOut.path)) {
17227
+ if (checkedOut?.path && (0, import_node_fs43.existsSync)(checkedOut.path)) {
16988
17228
  if (input.reuseExistingWorktree !== false) {
16989
17229
  worktreePath = checkedOut.path;
16990
17230
  } else {
@@ -17126,7 +17366,7 @@ async function initStackFromThread(input, onSetupLine) {
17126
17366
  async function createPrStack(input, onSetupLine) {
17127
17367
  await requireAgent(input.agent);
17128
17368
  const repoPath = await resolveRepoRoot(input.repoPath);
17129
- if (!(0, import_node_fs41.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
17369
+ if (!(0, import_node_fs43.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
17130
17370
  if (!input.branches.length) throw new Error("At least one branch name required");
17131
17371
  const status = await detectGhStack(repoPath);
17132
17372
  if (!status.available) throw new Error(status.reason);
@@ -17193,7 +17433,7 @@ async function createPrStack(input, onSetupLine) {
17193
17433
  }
17194
17434
  }
17195
17435
  const claimed = new Set(threads.map((t) => t.worktreePath));
17196
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs41.existsSync)(bootstrap.worktreePath)) {
17436
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs43.existsSync)(bootstrap.worktreePath)) {
17197
17437
  try {
17198
17438
  await removeWorktree(repoPath, bootstrap.worktreePath, {
17199
17439
  deleteBranch: bootstrap.branchName
@@ -17213,11 +17453,11 @@ function stackAgentDefaultsFrom(input) {
17213
17453
  planMode: input.planMode
17214
17454
  };
17215
17455
  }
17216
- var import_node_fs41;
17456
+ var import_node_fs43;
17217
17457
  var init_stack_layers = __esm({
17218
17458
  "src/threads/stack-layers.ts"() {
17219
17459
  "use strict";
17220
- import_node_fs41 = require("fs");
17460
+ import_node_fs43 = require("fs");
17221
17461
  init_detect();
17222
17462
  init_run();
17223
17463
  init_stack();
@@ -17230,7 +17470,7 @@ var init_stack_layers = __esm({
17230
17470
 
17231
17471
  // src/diff/diff.ts
17232
17472
  async function inspectGitWorktree(worktreePath) {
17233
- if (!worktreePath || !(0, import_node_fs42.existsSync)(worktreePath)) return "missing_worktree";
17473
+ if (!worktreePath || !(0, import_node_fs44.existsSync)(worktreePath)) return "missing_worktree";
17234
17474
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
17235
17475
  reject: false
17236
17476
  });
@@ -17238,7 +17478,7 @@ async function inspectGitWorktree(worktreePath) {
17238
17478
  return "ok";
17239
17479
  }
17240
17480
  async function initializeGitRepository(worktreePath) {
17241
- if (!worktreePath || !(0, import_node_fs42.existsSync)(worktreePath)) {
17481
+ if (!worktreePath || !(0, import_node_fs44.existsSync)(worktreePath)) {
17242
17482
  throw new Error("Worktree not found");
17243
17483
  }
17244
17484
  const status = await inspectGitWorktree(worktreePath);
@@ -17372,11 +17612,11 @@ new file mode 100644
17372
17612
  };
17373
17613
  }
17374
17614
  async function untrackedPatch(worktreePath, path2, maxHunk) {
17375
- const abs = (0, import_node_path39.join)(worktreePath, path2);
17615
+ const abs = (0, import_node_path41.join)(worktreePath, path2);
17376
17616
  try {
17377
- const st = (0, import_node_fs42.statSync)(abs);
17617
+ const st = (0, import_node_fs44.statSync)(abs);
17378
17618
  if (st.isFile() && st.size > maxHunk) {
17379
- const buf = (0, import_node_fs42.readFileSync)(abs).subarray(0, maxHunk);
17619
+ const buf = (0, import_node_fs44.readFileSync)(abs).subarray(0, maxHunk);
17380
17620
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
17381
17621
  }
17382
17622
  } catch {
@@ -17865,8 +18105,8 @@ function isImageRelativePath(relativePath) {
17865
18105
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17866
18106
  assertSafeRelativePath(relativePath);
17867
18107
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
17868
- const abs = (0, import_node_path39.join)(worktreePath, relativePath);
17869
- const st = (0, import_node_fs42.statSync)(abs);
18108
+ const abs = (0, import_node_path41.join)(worktreePath, relativePath);
18109
+ const st = (0, import_node_fs44.statSync)(abs);
17870
18110
  if (!st.isFile()) {
17871
18111
  throw new Error(`Not a file: ${relativePath}`);
17872
18112
  }
@@ -17875,7 +18115,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17875
18115
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
17876
18116
  );
17877
18117
  }
17878
- const buf = (0, import_node_fs42.readFileSync)(abs);
18118
+ const buf = (0, import_node_fs44.readFileSync)(abs);
17879
18119
  return {
17880
18120
  path: relativePath,
17881
18121
  contentBase64: buf.toString("base64"),
@@ -17885,12 +18125,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17885
18125
  function readWorktreeFile(worktreePath, relativePath, opts) {
17886
18126
  assertSafeRelativePath(relativePath);
17887
18127
  const maxBytes = opts?.maxBytes ?? 2e5;
17888
- const abs = (0, import_node_path39.join)(worktreePath, relativePath);
17889
- const st = (0, import_node_fs42.statSync)(abs);
18128
+ const abs = (0, import_node_path41.join)(worktreePath, relativePath);
18129
+ const st = (0, import_node_fs44.statSync)(abs);
17890
18130
  if (!st.isFile()) {
17891
18131
  throw new Error(`Not a file: ${relativePath}`);
17892
18132
  }
17893
- const buf = (0, import_node_fs42.readFileSync)(abs);
18133
+ const buf = (0, import_node_fs44.readFileSync)(abs);
17894
18134
  if (isImageRelativePath(relativePath)) {
17895
18135
  const maxImageBytes = Math.max(maxBytes, 15e6);
17896
18136
  const truncated2 = buf.length > maxImageBytes;
@@ -17933,9 +18173,9 @@ function assertSafeRelativePath(relativePath) {
17933
18173
  }
17934
18174
  function writeWorktreeFile(worktreePath, relativePath, content) {
17935
18175
  assertSafeRelativePath(relativePath);
17936
- const abs = (0, import_node_path39.join)(worktreePath, relativePath);
17937
- (0, import_node_fs42.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
17938
- (0, import_node_fs42.writeFileSync)(abs, content, "utf8");
18176
+ const abs = (0, import_node_path41.join)(worktreePath, relativePath);
18177
+ (0, import_node_fs44.mkdirSync)((0, import_node_path41.dirname)(abs), { recursive: true });
18178
+ (0, import_node_fs44.writeFileSync)(abs, content, "utf8");
17939
18179
  return { path: relativePath };
17940
18180
  }
17941
18181
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -17952,12 +18192,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
17952
18192
  truncated: full.files.length > maxFiles
17953
18193
  };
17954
18194
  }
17955
- var import_node_fs42, import_node_path39, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
18195
+ var import_node_fs44, import_node_path41, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
17956
18196
  var init_diff = __esm({
17957
18197
  "src/diff/diff.ts"() {
17958
18198
  "use strict";
17959
- import_node_fs42 = require("fs");
17960
- import_node_path39 = require("path");
18199
+ import_node_fs44 = require("fs");
18200
+ import_node_path41 = require("path");
17961
18201
  init_run();
17962
18202
  init_worktree();
17963
18203
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -18225,7 +18465,7 @@ function parseFrontmatter(content) {
18225
18465
  }
18226
18466
  function readSkill(skillMd, source) {
18227
18467
  try {
18228
- const content = (0, import_node_fs43.readFileSync)(skillMd, "utf8");
18468
+ const content = (0, import_node_fs45.readFileSync)(skillMd, "utf8");
18229
18469
  const { name: fmName, description } = parseFrontmatter(content);
18230
18470
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
18231
18471
  const name = fmName || dirName;
@@ -18244,19 +18484,19 @@ function readSkill(skillMd, source) {
18244
18484
  }
18245
18485
  }
18246
18486
  function scanSkillsDir(dir, source, out) {
18247
- if (!(0, import_node_fs43.existsSync)(dir)) return;
18487
+ if (!(0, import_node_fs45.existsSync)(dir)) return;
18248
18488
  let entries;
18249
18489
  try {
18250
- entries = (0, import_node_fs43.readdirSync)(dir);
18490
+ entries = (0, import_node_fs45.readdirSync)(dir);
18251
18491
  } catch {
18252
18492
  return;
18253
18493
  }
18254
18494
  for (const entry of entries) {
18255
18495
  if (entry.startsWith(".")) continue;
18256
- const skillMd = (0, import_node_path40.join)(dir, entry, "SKILL.md");
18257
- if (!(0, import_node_fs43.existsSync)(skillMd)) continue;
18496
+ const skillMd = (0, import_node_path42.join)(dir, entry, "SKILL.md");
18497
+ if (!(0, import_node_fs45.existsSync)(skillMd)) continue;
18258
18498
  try {
18259
- if (!(0, import_node_fs43.statSync)(skillMd).isFile()) continue;
18499
+ if (!(0, import_node_fs45.statSync)(skillMd).isFile()) continue;
18260
18500
  } catch {
18261
18501
  continue;
18262
18502
  }
@@ -18265,24 +18505,24 @@ function scanSkillsDir(dir, source, out) {
18265
18505
  }
18266
18506
  }
18267
18507
  function scanClaudePluginSkills(pluginsRoot, out) {
18268
- if (!(0, import_node_fs43.existsSync)(pluginsRoot)) return;
18508
+ if (!(0, import_node_fs45.existsSync)(pluginsRoot)) return;
18269
18509
  const walk = (dir, depth, lookingForSkillsDir) => {
18270
18510
  if (depth > 7) return;
18271
18511
  let entries;
18272
18512
  try {
18273
- entries = (0, import_node_fs43.readdirSync)(dir);
18513
+ entries = (0, import_node_fs45.readdirSync)(dir);
18274
18514
  } catch {
18275
18515
  return;
18276
18516
  }
18277
18517
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
18278
- const skill = readSkill((0, import_node_path40.join)(dir, "SKILL.md"), "cli");
18518
+ const skill = readSkill((0, import_node_path42.join)(dir, "SKILL.md"), "cli");
18279
18519
  if (skill) out.push(skill);
18280
18520
  }
18281
18521
  for (const entry of entries) {
18282
18522
  if (entry === "node_modules" || entry === ".git") continue;
18283
- const full = (0, import_node_path40.join)(dir, entry);
18523
+ const full = (0, import_node_path42.join)(dir, entry);
18284
18524
  try {
18285
- if (!(0, import_node_fs43.statSync)(full).isDirectory()) continue;
18525
+ if (!(0, import_node_fs45.statSync)(full).isDirectory()) continue;
18286
18526
  } catch {
18287
18527
  continue;
18288
18528
  }
@@ -18297,20 +18537,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
18297
18537
  walk(pluginsRoot, 0, false);
18298
18538
  }
18299
18539
  function discoverSkills(worktreePath) {
18300
- const home = (0, import_node_os12.homedir)();
18540
+ const home = (0, import_node_os14.homedir)();
18301
18541
  const collected = [];
18302
18542
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
18303
- scanSkillsDir((0, import_node_path40.join)(worktreePath, rel), "workspace", collected);
18543
+ scanSkillsDir((0, import_node_path42.join)(worktreePath, rel), "workspace", collected);
18304
18544
  }
18305
18545
  for (const abs of [
18306
- (0, import_node_path40.join)(home, ".claude/skills"),
18307
- (0, import_node_path40.join)(home, ".cursor/skills"),
18308
- (0, import_node_path40.join)(home, ".sideboard/skills"),
18309
- (0, import_node_path40.join)(home, ".brightsy/skills")
18546
+ (0, import_node_path42.join)(home, ".claude/skills"),
18547
+ (0, import_node_path42.join)(home, ".cursor/skills"),
18548
+ (0, import_node_path42.join)(home, ".sideboard/skills"),
18549
+ (0, import_node_path42.join)(home, ".brightsy/skills")
18310
18550
  ]) {
18311
18551
  scanSkillsDir(abs, "user", collected);
18312
18552
  }
18313
- scanClaudePluginSkills((0, import_node_path40.join)(home, ".claude/plugins"), collected);
18553
+ scanClaudePluginSkills((0, import_node_path42.join)(home, ".claude/plugins"), collected);
18314
18554
  collected.push(...bundledSkills());
18315
18555
  const rank = {
18316
18556
  workspace: 0,
@@ -18336,7 +18576,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
18336
18576
  \u2026(truncated)` : body;
18337
18577
  }
18338
18578
  }
18339
- const raw = (0, import_node_fs43.readFileSync)(skillPath, "utf8");
18579
+ const raw = (0, import_node_fs45.readFileSync)(skillPath, "utf8");
18340
18580
  if (raw.startsWith("---")) {
18341
18581
  const end = raw.indexOf("\n---", 3);
18342
18582
  if (end >= 0) {
@@ -18350,13 +18590,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
18350
18590
 
18351
18591
  \u2026(truncated)` : raw;
18352
18592
  }
18353
- var import_node_fs43, import_node_os12, import_node_path40, BUNDLED_SKILL_PREFIX;
18593
+ var import_node_fs45, import_node_os14, import_node_path42, BUNDLED_SKILL_PREFIX;
18354
18594
  var init_discover = __esm({
18355
18595
  "src/skills/discover.ts"() {
18356
18596
  "use strict";
18357
- import_node_fs43 = require("fs");
18358
- import_node_os12 = require("os");
18359
- import_node_path40 = require("path");
18597
+ import_node_fs45 = require("fs");
18598
+ import_node_os14 = require("os");
18599
+ import_node_path42 = require("path");
18360
18600
  init_long_running();
18361
18601
  BUNDLED_SKILL_PREFIX = "bundled:";
18362
18602
  }
@@ -18451,17 +18691,17 @@ var init_expand = __esm({
18451
18691
  function packagedDetachedJobPath() {
18452
18692
  const dir = packagedMcpDir();
18453
18693
  if (!dir) return null;
18454
- const script = (0, import_node_path41.join)(dir, "scripts", "detached-job.js");
18455
- return (0, import_node_fs44.existsSync)(script) ? script : null;
18694
+ const script = (0, import_node_path43.join)(dir, "scripts", "detached-job.js");
18695
+ return (0, import_node_fs46.existsSync)(script) ? script : null;
18456
18696
  }
18457
18697
  function resolveDetachedJobScript() {
18458
18698
  const packaged = packagedDetachedJobPath();
18459
18699
  if (packaged) return packaged;
18460
- let dir = (0, import_node_path41.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
18700
+ let dir = (0, import_node_path43.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
18461
18701
  for (let i = 0; i < 8; i++) {
18462
- const candidate = (0, import_node_path41.join)(dir, "scripts", "detached-job.js");
18463
- if ((0, import_node_fs44.existsSync)(candidate)) return candidate;
18464
- const parent = (0, import_node_path41.dirname)(dir);
18702
+ const candidate = (0, import_node_path43.join)(dir, "scripts", "detached-job.js");
18703
+ if ((0, import_node_fs46.existsSync)(candidate)) return candidate;
18704
+ const parent = (0, import_node_path43.dirname)(dir);
18465
18705
  if (parent === dir) break;
18466
18706
  dir = parent;
18467
18707
  }
@@ -18472,12 +18712,12 @@ function formatDetachedJobInvoke(scriptPath) {
18472
18712
  if (resolved) return `node ${JSON.stringify(resolved)}`;
18473
18713
  return "node scripts/detached-job.js";
18474
18714
  }
18475
- var import_node_fs44, import_node_path41, import_node_url3, import_meta3;
18715
+ var import_node_fs46, import_node_path43, import_node_url3, import_meta3;
18476
18716
  var init_detached_job_path = __esm({
18477
18717
  "src/skills/detached-job-path.ts"() {
18478
18718
  "use strict";
18479
- import_node_fs44 = require("fs");
18480
- import_node_path41 = require("path");
18719
+ import_node_fs46 = require("fs");
18720
+ import_node_path43 = require("path");
18481
18721
  import_node_url3 = require("url");
18482
18722
  init_packaged_runtime();
18483
18723
  import_meta3 = {};
@@ -18662,11 +18902,11 @@ function loadAgentInstructions(worktreePath, agent) {
18662
18902
  const out = [];
18663
18903
  for (const rel of candidates) {
18664
18904
  if (seenPaths.has(rel)) continue;
18665
- const abs = (0, import_node_path42.join)(worktreePath, rel);
18666
- if (!(0, import_node_fs45.existsSync)(abs)) continue;
18905
+ const abs = (0, import_node_path44.join)(worktreePath, rel);
18906
+ if (!(0, import_node_fs47.existsSync)(abs)) continue;
18667
18907
  try {
18668
- if (!(0, import_node_fs45.statSync)(abs).isFile()) continue;
18669
- let content = (0, import_node_fs45.readFileSync)(abs, "utf8");
18908
+ if (!(0, import_node_fs47.statSync)(abs).isFile()) continue;
18909
+ let content = (0, import_node_fs47.readFileSync)(abs, "utf8");
18670
18910
  if (!content.trim()) continue;
18671
18911
  if (content.length > MAX_CHARS_PER_FILE) {
18672
18912
  content = `${content.slice(0, MAX_CHARS_PER_FILE)}
@@ -18706,12 +18946,12 @@ function withAgentInstructions(prompt, files) {
18706
18946
 
18707
18947
  ${prompt}`;
18708
18948
  }
18709
- var import_node_fs45, import_node_path42, FILES_BY_AGENT, MAX_CHARS_PER_FILE;
18949
+ var import_node_fs47, import_node_path44, FILES_BY_AGENT, MAX_CHARS_PER_FILE;
18710
18950
  var init_instructions = __esm({
18711
18951
  "src/agents/instructions.ts"() {
18712
18952
  "use strict";
18713
- import_node_fs45 = require("fs");
18714
- import_node_path42 = require("path");
18953
+ import_node_fs47 = require("fs");
18954
+ import_node_path44 = require("path");
18715
18955
  init_git_auth_mode();
18716
18956
  init_worktree_labels();
18717
18957
  init_detached_job_path();
@@ -19057,40 +19297,40 @@ __export(plan_file_exports, {
19057
19297
  writePlanFile: () => writePlanFile
19058
19298
  });
19059
19299
  function ensureAttachmentsGitignore(worktreePath) {
19060
- const gitignoreAbs = (0, import_node_path43.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
19061
- if ((0, import_node_fs46.existsSync)(gitignoreAbs)) return;
19062
- (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(gitignoreAbs), { recursive: true });
19063
- (0, import_node_fs46.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
19300
+ const gitignoreAbs = (0, import_node_path45.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
19301
+ if ((0, import_node_fs48.existsSync)(gitignoreAbs)) return;
19302
+ (0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(gitignoreAbs), { recursive: true });
19303
+ (0, import_node_fs48.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
19064
19304
  }
19065
19305
  function planFileAbs(worktreePath) {
19066
- return (0, import_node_path43.join)(worktreePath, PLAN_FILE_REL);
19306
+ return (0, import_node_path45.join)(worktreePath, PLAN_FILE_REL);
19067
19307
  }
19068
19308
  function readTextIfPresent2(abs) {
19069
- if (!(0, import_node_fs46.existsSync)(abs)) return null;
19309
+ if (!(0, import_node_fs48.existsSync)(abs)) return null;
19070
19310
  try {
19071
- const content = (0, import_node_fs46.readFileSync)(abs, "utf8");
19311
+ const content = (0, import_node_fs48.readFileSync)(abs, "utf8");
19072
19312
  return content.trim() ? content : null;
19073
19313
  } catch {
19074
19314
  return null;
19075
19315
  }
19076
19316
  }
19077
19317
  function readPlanFile(worktreePath) {
19078
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path43.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path43.join)(worktreePath, LEGACY_PLAN_FILE_REL));
19318
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path45.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path45.join)(worktreePath, LEGACY_PLAN_FILE_REL));
19079
19319
  }
19080
19320
  function writePlanFile(worktreePath, content) {
19081
19321
  ensureAttachmentsGitignore(worktreePath);
19082
19322
  const abs = planFileAbs(worktreePath);
19083
- (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
19323
+ (0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
19084
19324
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
19085
- (0, import_node_fs46.writeFileSync)(abs, body, "utf8");
19325
+ (0, import_node_fs48.writeFileSync)(abs, body, "utf8");
19086
19326
  return PLAN_FILE_REL;
19087
19327
  }
19088
- var import_node_fs46, import_node_path43;
19328
+ var import_node_fs48, import_node_path45;
19089
19329
  var init_plan_file = __esm({
19090
19330
  "src/plan/plan-file.ts"() {
19091
19331
  "use strict";
19092
- import_node_fs46 = require("fs");
19093
- import_node_path43 = require("path");
19332
+ import_node_fs48 = require("fs");
19333
+ import_node_path45 = require("path");
19094
19334
  init_workspace_scratch();
19095
19335
  init_plan_present();
19096
19336
  init_plan_present();
@@ -19138,13 +19378,13 @@ var init_sync_branch = __esm({
19138
19378
 
19139
19379
  // src/agents/cursor-store.ts
19140
19380
  function cursorSdkStoreDir(threadId) {
19141
- const root = (0, import_node_path44.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
19381
+ const root = (0, import_node_path46.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
19142
19382
  const id = sanitizeCursorStoreSegment(threadId);
19143
19383
  if (!id) return root;
19144
- return (0, import_node_path44.join)(root, "threads", id);
19384
+ return (0, import_node_path46.join)(root, "threads", id);
19145
19385
  }
19146
19386
  function cursorSdkRunsNdjsonPath(threadId) {
19147
- return (0, import_node_path44.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
19387
+ return (0, import_node_path46.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
19148
19388
  }
19149
19389
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
19150
19390
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -19157,11 +19397,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
19157
19397
  function sanitizeCursorStoreSegment(threadId) {
19158
19398
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
19159
19399
  }
19160
- var import_node_path44, CURSOR_SDK_STORE_DIR;
19400
+ var import_node_path46, CURSOR_SDK_STORE_DIR;
19161
19401
  var init_cursor_store = __esm({
19162
19402
  "src/agents/cursor-store.ts"() {
19163
19403
  "use strict";
19164
- import_node_path44 = require("path");
19404
+ import_node_path46 = require("path");
19165
19405
  init_paths();
19166
19406
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
19167
19407
  }
@@ -19183,9 +19423,9 @@ function recoverFinishedCursorRun(opts) {
19183
19423
  return best;
19184
19424
  }
19185
19425
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
19186
- if (!(0, import_node_fs47.existsSync)(runsPath)) return null;
19426
+ if (!(0, import_node_fs49.existsSync)(runsPath)) return null;
19187
19427
  try {
19188
- const lines = (0, import_node_fs47.readFileSync)(runsPath, "utf8").split("\n");
19428
+ const lines = (0, import_node_fs49.readFileSync)(runsPath, "utf8").split("\n");
19189
19429
  let best = null;
19190
19430
  for (const line of lines) {
19191
19431
  const trimmed = line.trim();
@@ -19211,11 +19451,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
19211
19451
  return null;
19212
19452
  }
19213
19453
  }
19214
- var import_node_fs47;
19454
+ var import_node_fs49;
19215
19455
  var init_cursor_recover = __esm({
19216
19456
  "src/agents/cursor-recover.ts"() {
19217
19457
  "use strict";
19218
- import_node_fs47 = require("fs");
19458
+ import_node_fs49 = require("fs");
19219
19459
  init_cursor_store();
19220
19460
  }
19221
19461
  });
@@ -19347,13 +19587,13 @@ async function startOrchestration(opts) {
19347
19587
  }
19348
19588
  return updated;
19349
19589
  }
19350
- var import_node_events, import_node_fs48, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
19590
+ var import_node_events, import_node_fs50, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
19351
19591
  var init_orchestrator = __esm({
19352
19592
  "src/orchestrator/orchestrator.ts"() {
19353
19593
  "use strict";
19354
19594
  import_node_events = require("events");
19355
19595
  init_outbound_watch();
19356
- import_node_fs48 = require("fs");
19596
+ import_node_fs50 = require("fs");
19357
19597
  init_error_detail();
19358
19598
  init_run();
19359
19599
  init_stale_lock();
@@ -19521,7 +19761,7 @@ var init_orchestrator = __esm({
19521
19761
  }
19522
19762
  continue;
19523
19763
  }
19524
- if (!(0, import_node_fs48.existsSync)(thread.worktreePath)) {
19764
+ if (!(0, import_node_fs50.existsSync)(thread.worktreePath)) {
19525
19765
  setStatus(thread.id, "broken", "Worktree missing on disk");
19526
19766
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
19527
19767
  continue;
@@ -19791,21 +20031,11 @@ var init_orchestrator = __esm({
19791
20031
  /** Run workspace setup after a new worktree is created (no-op if none configured). */
19792
20032
  async runSetupAfterCreate(threadId) {
19793
20033
  try {
19794
- await this.runSetup(threadId);
20034
+ await this.runSetup(threadId, { stampLastError: false });
19795
20035
  } catch (err) {
19796
20036
  const message = err instanceof Error ? err.message : String(err);
19797
20037
  if (/no setup script/i.test(message)) return;
19798
20038
  if (/already running/i.test(message)) return;
19799
- const live = readThread(threadId);
19800
- if (!shouldStampSetupLastError({
19801
- turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
19802
- status: live?.status
19803
- })) {
19804
- return;
19805
- }
19806
- updateThread(threadId, {
19807
- lastError: `Setup failed: ${message}`
19808
- });
19809
20039
  }
19810
20040
  }
19811
20041
  listWorkspaces() {
@@ -20593,7 +20823,7 @@ var init_orchestrator = __esm({
20593
20823
  }
20594
20824
  return snap;
20595
20825
  }
20596
- async runSetup(threadRef) {
20826
+ async runSetup(threadRef, opts) {
20597
20827
  const thread = this.requireThread(threadRef);
20598
20828
  this.assertNotGlobal(thread, "Setup");
20599
20829
  const key = `${thread.id}:setup`;
@@ -20634,9 +20864,10 @@ var init_orchestrator = __esm({
20634
20864
  }
20635
20865
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
20636
20866
  const live = readThread(thread.id);
20637
- if (shouldStampSetupLastError({
20867
+ if ((opts?.stampLastError ?? true) && shouldStampSetupLastError({
20638
20868
  turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
20639
- status: live?.status
20869
+ status: live?.status,
20870
+ hasQueuedPrompt: Boolean(live?.queue?.length)
20640
20871
  })) {
20641
20872
  updateThread(thread.id, {
20642
20873
  lastError: `Setup exited ${setup.exitCode}`
@@ -21339,7 +21570,7 @@ var init_orchestrator = __esm({
21339
21570
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
21340
21571
  return restored2;
21341
21572
  }
21342
- if (!(0, import_node_fs48.existsSync)(thread.worktreePath)) {
21573
+ if (!(0, import_node_fs50.existsSync)(thread.worktreePath)) {
21343
21574
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
21344
21575
  throw new Error(
21345
21576
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -21936,6 +22167,7 @@ __export(index_exports, {
21936
22167
  isImageFilePath: () => isImageFilePath,
21937
22168
  isInPrStack: () => isInPrStack,
21938
22169
  isInboundForThisDesktop: () => isInboundForThisDesktop,
22170
+ isInjectedOrchMcpName: () => isInjectedOrchMcpName,
21939
22171
  isInternalAgentStatusText: () => isInternalAgentStatusText,
21940
22172
  isIssueSourceConnected: () => isIssueSourceConnected,
21941
22173
  isLinearConnected: () => isLinearConnected,
@@ -21951,11 +22183,13 @@ __export(index_exports, {
21951
22183
  isPresentPlanToolName: () => isPresentPlanToolName,
21952
22184
  isPrimaryCheckoutThread: () => isPrimaryCheckoutThread,
21953
22185
  isSessionQuotaLimit: () => isSessionQuotaLimit,
22186
+ isSetupLastError: () => isSetupLastError,
21954
22187
  isShellToolName: () => isShellToolName,
21955
22188
  isSideboardScratchPath: () => isSideboardScratchPath,
21956
22189
  isSlackCoordinatorThread: () => isSlackCoordinatorThread,
21957
22190
  isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
21958
22191
  isSlackOAuthCancelled: () => isSlackOAuthCancelled,
22192
+ isStaleLastErrorDuringTurn: () => isStaleLastErrorDuringTurn,
21959
22193
  isSubagentToolName: () => isSubagentToolName,
21960
22194
  isThinkingEffort: () => isThinkingEffort,
21961
22195
  isThisProcessDesktopHost: () => isThisProcessDesktopHost,
@@ -22021,6 +22255,7 @@ __export(index_exports, {
22021
22255
  maybeCompactContext: () => maybeCompactContext,
22022
22256
  mcpAllowTools: () => mcpAllowTools,
22023
22257
  mcpAuthWarnings: () => mcpAuthWarnings,
22258
+ mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
22024
22259
  mergeAgentGitAuthEnv: () => mergeAgentGitAuthEnv,
22025
22260
  mergePr: () => mergePr,
22026
22261
  mergePrStack: () => mergePrStack,
@@ -22173,6 +22408,7 @@ __export(index_exports, {
22173
22408
  shouldRemoveWorktreeOnTeardown: () => shouldRemoveWorktreeOnTeardown,
22174
22409
  shouldResetSessionForOccupancy: () => shouldResetSessionForOccupancy,
22175
22410
  shouldRunWorktreeCleanup: () => shouldRunWorktreeCleanup,
22411
+ shouldStampSetupLastError: () => shouldStampSetupLastError,
22176
22412
  showCostEnabled: () => showCostEnabled,
22177
22413
  sideboardHomeDir: () => sideboardHomeDir,
22178
22414
  sideboardMcpProfile: () => sideboardMcpProfile,
@@ -22245,6 +22481,7 @@ __export(index_exports, {
22245
22481
  updateThread: () => updateThread,
22246
22482
  userClaudeMcpConfigPath: () => userClaudeMcpConfigPath,
22247
22483
  userCursorMcpConfigPath: () => userCursorMcpConfigPath,
22484
+ userMcpNamesToDisable: () => userMcpNamesToDisable,
22248
22485
  validateLinearApiKey: () => validateLinearApiKey,
22249
22486
  verifyAbleTimeConnection: () => verifyAbleTimeConnection,
22250
22487
  verifyOptionalService: () => verifyOptionalService,
@@ -23609,6 +23846,7 @@ init_fork_worktree();
23609
23846
  init_stack_layers();
23610
23847
  init_adopt();
23611
23848
  init_orchestrator();
23849
+ init_setup_last_error();
23612
23850
  init_request_review();
23613
23851
  init_workspace_scratch();
23614
23852
 
@@ -23743,7 +23981,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
23743
23981
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
23744
23982
  var import_zod5 = require("zod");
23745
23983
  var import_node_crypto13 = require("crypto");
23746
- var import_node_path47 = require("path");
23984
+ var import_node_path49 = require("path");
23747
23985
  init_orchestrator();
23748
23986
  init_worktree();
23749
23987
  init_global_workspace();
@@ -24817,27 +25055,27 @@ init_gh_errors();
24817
25055
  init_git_auth_mode();
24818
25056
 
24819
25057
  // src/board/load-home-board.ts
24820
- var import_node_fs50 = require("fs");
24821
- var import_node_path46 = require("path");
25058
+ var import_node_fs52 = require("fs");
25059
+ var import_node_path48 = require("path");
24822
25060
  init_worktree();
24823
25061
  init_paths();
24824
25062
 
24825
25063
  // src/board/board-pins.ts
24826
25064
  var import_node_crypto12 = require("crypto");
24827
- var import_node_fs49 = require("fs");
24828
- var import_node_path45 = require("path");
25065
+ var import_node_fs51 = require("fs");
25066
+ var import_node_path47 = require("path");
24829
25067
  init_paths();
24830
25068
  init_home_board();
24831
25069
  var FILE = "home-board-pins.json";
24832
25070
  var VERSION = 1;
24833
25071
  function pinsFile() {
24834
- return (0, import_node_path45.join)(appDataDir(), FILE);
25072
+ return (0, import_node_path47.join)(appDataDir(), FILE);
24835
25073
  }
24836
25074
  function readDisk() {
24837
25075
  const path2 = pinsFile();
24838
- if (!(0, import_node_fs49.existsSync)(path2)) return [];
25076
+ if (!(0, import_node_fs51.existsSync)(path2)) return [];
24839
25077
  try {
24840
- const raw = JSON.parse((0, import_node_fs49.readFileSync)(path2, "utf8"));
25078
+ const raw = JSON.parse((0, import_node_fs51.readFileSync)(path2, "utf8"));
24841
25079
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
24842
25080
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
24843
25081
  } catch {
@@ -24845,8 +25083,8 @@ function readDisk() {
24845
25083
  }
24846
25084
  }
24847
25085
  function writeDisk(items) {
24848
- (0, import_node_fs49.mkdirSync)(appDataDir(), { recursive: true });
24849
- (0, import_node_fs49.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
25086
+ (0, import_node_fs51.mkdirSync)(appDataDir(), { recursive: true });
25087
+ (0, import_node_fs51.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
24850
25088
  }
24851
25089
  function listBoardPins() {
24852
25090
  return readDisk();
@@ -24898,7 +25136,7 @@ function replaceBoardPins(items) {
24898
25136
  }
24899
25137
  function clearBoardPins() {
24900
25138
  try {
24901
- (0, import_node_fs49.unlinkSync)(pinsFile());
25139
+ (0, import_node_fs51.unlinkSync)(pinsFile());
24902
25140
  } catch {
24903
25141
  }
24904
25142
  }
@@ -24915,7 +25153,7 @@ function homeBoardWorkspaceKey(workspaces) {
24915
25153
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
24916
25154
  }
24917
25155
  function cacheFile() {
24918
- return (0, import_node_path46.join)(appDataDir(), "home-board-cache.json");
25156
+ return (0, import_node_path48.join)(appDataDir(), "home-board-cache.json");
24919
25157
  }
24920
25158
  function emptyInputs() {
24921
25159
  return {
@@ -24941,9 +25179,9 @@ function shouldCacheHomeBoardInputs(inputs) {
24941
25179
  }
24942
25180
  function readDiskCache() {
24943
25181
  const path2 = cacheFile();
24944
- if (!(0, import_node_fs50.existsSync)(path2)) return null;
25182
+ if (!(0, import_node_fs52.existsSync)(path2)) return null;
24945
25183
  try {
24946
- const raw = JSON.parse((0, import_node_fs50.readFileSync)(path2, "utf8"));
25184
+ const raw = JSON.parse((0, import_node_fs52.readFileSync)(path2, "utf8"));
24947
25185
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
24948
25186
  return null;
24949
25187
  }
@@ -24957,14 +25195,14 @@ function readDiskCache() {
24957
25195
  }
24958
25196
  function writeDiskCache(entry) {
24959
25197
  try {
24960
- (0, import_node_fs50.mkdirSync)(appDataDir(), { recursive: true });
24961
- (0, import_node_fs50.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
25198
+ (0, import_node_fs52.mkdirSync)(appDataDir(), { recursive: true });
25199
+ (0, import_node_fs52.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
24962
25200
  } catch {
24963
25201
  }
24964
25202
  }
24965
25203
  function deleteDiskCache() {
24966
25204
  try {
24967
- (0, import_node_fs50.unlinkSync)(cacheFile());
25205
+ (0, import_node_fs52.unlinkSync)(cacheFile());
24968
25206
  } catch {
24969
25207
  }
24970
25208
  }
@@ -25268,7 +25506,7 @@ async function startMcpServer() {
25268
25506
  async () => {
25269
25507
  const threads = orch.getThreads(true);
25270
25508
  const lines = threads.map((t) => {
25271
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path47.basename)(t.repoPath) || t.repoPath;
25509
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path49.basename)(t.repoPath) || t.repoPath;
25272
25510
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
25273
25511
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
25274
25512
  const preview = lastMessagePreview(t.messages, 80);
@@ -26740,79 +26978,8 @@ init_accounts();
26740
26978
  init_connected_teams();
26741
26979
  init_oauth();
26742
26980
  init_injected_mcp();
26743
-
26744
- // src/agents/user-mcp-config.ts
26745
- var import_node_fs51 = require("fs");
26746
- var import_node_os13 = require("os");
26747
- var import_node_path48 = require("path");
26748
- init_paths();
26749
- init_injected_mcp();
26750
- function userCursorMcpConfigPath() {
26751
- return (0, import_node_path48.join)((0, import_node_os13.homedir)(), ".cursor", "mcp.json");
26752
- }
26753
- function userClaudeMcpConfigPath() {
26754
- return (0, import_node_path48.join)((0, import_node_os13.homedir)(), ".claude.json");
26755
- }
26756
- function asObject(value) {
26757
- if (!value || typeof value !== "object" || Array.isArray(value)) return {};
26758
- return { ...value };
26759
- }
26760
- function stripElectronSpawnEnv(env) {
26761
- if (!env) return void 0;
26762
- const next = { ...env };
26763
- delete next.ELECTRON_RUN_AS_NODE;
26764
- delete next.ELECTRON_RUN_AS_NODE;
26765
- return Object.keys(next).length > 0 ? next : void 0;
26766
- }
26767
- function mergeSideboardIntoMcpServersJson(existing, sideboard) {
26768
- const root = asObject(existing);
26769
- const servers = asObject(root.mcpServers);
26770
- const env = stripElectronSpawnEnv(sideboard.env);
26771
- servers.sideboard = {
26772
- type: "stdio",
26773
- command: sideboard.command,
26774
- ...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
26775
- ...env ? { env } : {}
26776
- };
26777
- return { ...root, mcpServers: servers };
26778
- }
26779
- function writeMergedMcpServersJson(configPath, sideboard) {
26780
- let existing = {};
26781
- if ((0, import_node_fs51.existsSync)(configPath)) {
26782
- try {
26783
- existing = JSON.parse((0, import_node_fs51.readFileSync)(configPath, "utf8"));
26784
- } catch {
26785
- existing = {};
26786
- }
26787
- }
26788
- const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
26789
- (0, import_node_fs51.mkdirSync)((0, import_node_path48.dirname)(configPath), { recursive: true });
26790
- (0, import_node_fs51.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
26791
- `);
26792
- }
26793
- function launchFromResolved(server) {
26794
- return {
26795
- command: server.command,
26796
- args: server.args,
26797
- env: {
26798
- ...server.env ?? {},
26799
- SIDEBOARD_APP_DATA: appDataDir()
26800
- }
26801
- };
26802
- }
26803
- async function registerPackagedUserMcpClients() {
26804
- const launch = launchFromResolved(await resolveSideboardMcpServer());
26805
- const cursor = userCursorMcpConfigPath();
26806
- writeMergedMcpServersJson(cursor, launch);
26807
- const claude = userClaudeMcpConfigPath();
26808
- if ((0, import_node_fs51.existsSync)(claude)) {
26809
- writeMergedMcpServersJson(claude, launch);
26810
- return { cursor, claude };
26811
- }
26812
- return { cursor };
26813
- }
26814
-
26815
- // src/index.ts
26981
+ init_user_mcp_config();
26982
+ init_orch_mcp_isolation();
26816
26983
  init_workspaces2();
26817
26984
 
26818
26985
  // src/slack/oauth.ts
@@ -28435,9 +28602,9 @@ var import_node_http3 = require("http");
28435
28602
  var import_ws3 = require("ws");
28436
28603
 
28437
28604
  // src/slack/relay-static.ts
28438
- var import_node_fs52 = require("fs");
28605
+ var import_node_fs53 = require("fs");
28439
28606
  var import_promises = require("fs/promises");
28440
- var import_node_path49 = __toESM(require("path"), 1);
28607
+ var import_node_path50 = __toESM(require("path"), 1);
28441
28608
  var TYPES = {
28442
28609
  ".css": "text/css; charset=utf-8",
28443
28610
  ".html": "text/html; charset=utf-8",
@@ -28468,9 +28635,9 @@ function resolveStaticPath(root, requestUrl) {
28468
28635
  return null;
28469
28636
  }
28470
28637
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
28471
- const rootResolved = import_node_path49.default.resolve(root);
28472
- const candidate = import_node_path49.default.resolve(rootResolved, `.${pathname}`);
28473
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path49.default.sep)) {
28638
+ const rootResolved = import_node_path50.default.resolve(root);
28639
+ const candidate = import_node_path50.default.resolve(rootResolved, `.${pathname}`);
28640
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path50.default.sep)) {
28474
28641
  return null;
28475
28642
  }
28476
28643
  return candidate;
@@ -28484,7 +28651,7 @@ async function fileSize(file) {
28484
28651
  }
28485
28652
  }
28486
28653
  function sendFile(req, res, file, size) {
28487
- const ext = import_node_path49.default.extname(file).toLowerCase();
28654
+ const ext = import_node_path50.default.extname(file).toLowerCase();
28488
28655
  res.writeHead(200, {
28489
28656
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
28490
28657
  "Content-Length": size,
@@ -28494,7 +28661,7 @@ function sendFile(req, res, file, size) {
28494
28661
  res.end();
28495
28662
  return true;
28496
28663
  }
28497
- (0, import_node_fs52.createReadStream)(file).pipe(res);
28664
+ (0, import_node_fs53.createReadStream)(file).pipe(res);
28498
28665
  return true;
28499
28666
  }
28500
28667
  async function tryServeStatic(req, res, root) {
@@ -28503,7 +28670,7 @@ async function tryServeStatic(req, res, root) {
28503
28670
  if (!candidate) return false;
28504
28671
  const direct = await fileSize(candidate);
28505
28672
  if (direct != null) return sendFile(req, res, candidate, direct);
28506
- const asIndex = import_node_path49.default.join(candidate, "index.html");
28673
+ const asIndex = import_node_path50.default.join(candidate, "index.html");
28507
28674
  const indexSize = await fileSize(asIndex);
28508
28675
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
28509
28676
  return false;
@@ -29132,6 +29299,7 @@ init_outbound_watch();
29132
29299
  isImageFilePath,
29133
29300
  isInPrStack,
29134
29301
  isInboundForThisDesktop,
29302
+ isInjectedOrchMcpName,
29135
29303
  isInternalAgentStatusText,
29136
29304
  isIssueSourceConnected,
29137
29305
  isLinearConnected,
@@ -29147,11 +29315,13 @@ init_outbound_watch();
29147
29315
  isPresentPlanToolName,
29148
29316
  isPrimaryCheckoutThread,
29149
29317
  isSessionQuotaLimit,
29318
+ isSetupLastError,
29150
29319
  isShellToolName,
29151
29320
  isSideboardScratchPath,
29152
29321
  isSlackCoordinatorThread,
29153
29322
  isSlackExternalReplyPrompt,
29154
29323
  isSlackOAuthCancelled,
29324
+ isStaleLastErrorDuringTurn,
29155
29325
  isSubagentToolName,
29156
29326
  isThinkingEffort,
29157
29327
  isThisProcessDesktopHost,
@@ -29217,6 +29387,7 @@ init_outbound_watch();
29217
29387
  maybeCompactContext,
29218
29388
  mcpAllowTools,
29219
29389
  mcpAuthWarnings,
29390
+ mcpStatusThinkingFromClaudeInit,
29220
29391
  mergeAgentGitAuthEnv,
29221
29392
  mergePr,
29222
29393
  mergePrStack,
@@ -29369,6 +29540,7 @@ init_outbound_watch();
29369
29540
  shouldRemoveWorktreeOnTeardown,
29370
29541
  shouldResetSessionForOccupancy,
29371
29542
  shouldRunWorktreeCleanup,
29543
+ shouldStampSetupLastError,
29372
29544
  showCostEnabled,
29373
29545
  sideboardHomeDir,
29374
29546
  sideboardMcpProfile,
@@ -29441,6 +29613,7 @@ init_outbound_watch();
29441
29613
  updateThread,
29442
29614
  userClaudeMcpConfigPath,
29443
29615
  userCursorMcpConfigPath,
29616
+ userMcpNamesToDisable,
29444
29617
  validateLinearApiKey,
29445
29618
  verifyAbleTimeConnection,
29446
29619
  verifyOptionalService,