@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.
@@ -7511,7 +7511,7 @@ function ensureGlobalCoordinatorCwd(opts) {
7511
7511
  "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.",
7512
7512
  "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).",
7513
7513
  "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.",
7514
- "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.",
7514
+ "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.",
7515
7515
  '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".',
7516
7516
  "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.",
7517
7517
  "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."
@@ -7568,8 +7568,8 @@ var init_coordinator_prompt = __esm({
7568
7568
  "- list_workspaces \u2014 registered repos (path + github slug + roles/notes when set). Use that profile to pick the right repo for tickets or reviews.",
7569
7569
  "- 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.",
7570
7570
  '- 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.',
7571
- "- 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.",
7572
- "- 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.",
7571
+ "- 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.",
7572
+ "- 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.",
7573
7573
  "- 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).",
7574
7574
  "- 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",
7575
7575
  "- 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).",
@@ -9593,7 +9593,7 @@ function toCodexMcpConfigArgs(servers) {
9593
9593
  }
9594
9594
  return args;
9595
9595
  }
9596
- function toOpencodeMcpConfigContent(servers) {
9596
+ function toOpencodeMcpConfigContent(servers, opts) {
9597
9597
  const mcp = {};
9598
9598
  for (const s of servers) {
9599
9599
  const env = mcpSpawnEnv(s.env);
@@ -9604,6 +9604,11 @@ function toOpencodeMcpConfigContent(servers) {
9604
9604
  ...env ? { environment: env } : {}
9605
9605
  };
9606
9606
  }
9607
+ for (const name of opts?.disableNames ?? []) {
9608
+ const key = name.trim();
9609
+ if (!key || mcp[key]?.enabled === true) continue;
9610
+ mcp[key] = { ...mcp[key], enabled: false };
9611
+ }
9607
9612
  return JSON.stringify({ mcp });
9608
9613
  }
9609
9614
  function writeMcpServersConfig(servers) {
@@ -9834,13 +9839,50 @@ function claudeString(obj, key) {
9834
9839
  const v = obj[key];
9835
9840
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
9836
9841
  }
9842
+ function mcpStatusThinkingFromClaudeInit(obj) {
9843
+ const raw = obj.mcp_servers ?? obj.mcpServers;
9844
+ const servers = [];
9845
+ if (Array.isArray(raw)) {
9846
+ for (const item of raw) {
9847
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
9848
+ const rec = item;
9849
+ const name = typeof rec.name === "string" && rec.name.trim() || typeof rec.server === "string" && rec.server.trim() || "";
9850
+ const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "";
9851
+ if (name) servers.push({ name, status: status || "unknown" });
9852
+ }
9853
+ } else if (raw && typeof raw === "object") {
9854
+ for (const [name, value] of Object.entries(raw)) {
9855
+ if (!name.trim()) continue;
9856
+ if (typeof value === "string" && value.trim()) {
9857
+ servers.push({ name, status: value.trim() });
9858
+ continue;
9859
+ }
9860
+ if (value && typeof value === "object" && !Array.isArray(value)) {
9861
+ const rec = value;
9862
+ const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "unknown";
9863
+ servers.push({ name, status });
9864
+ }
9865
+ }
9866
+ }
9867
+ const notable = servers.filter((s) => !isCleanMcpConnect(s.status));
9868
+ if (notable.length === 0) return null;
9869
+ return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
9870
+ }
9871
+ function isCleanMcpConnect(status) {
9872
+ return /^(connected|ok|ready|success)$/i.test(status.trim());
9873
+ }
9837
9874
  function eventsFromClaudeSystem(obj) {
9838
9875
  const subtype = claudeString(obj, "subtype") ?? "";
9839
9876
  const parentId = claudeParentToolUseId(obj);
9840
9877
  if (subtype === "init") {
9841
9878
  if (parentId) return null;
9842
9879
  const sid = claudeString(obj, "session_id");
9843
- return sid ? { type: "session_id", data: sid } : null;
9880
+ const mcpNote = mcpStatusThinkingFromClaudeInit(obj);
9881
+ const events = [];
9882
+ if (sid) events.push({ type: "session_id", data: sid });
9883
+ if (mcpNote) events.push({ type: "thinking", data: mcpNote, replace: true });
9884
+ if (events.length === 0) return null;
9885
+ return events.length === 1 ? events[0] : events;
9844
9886
  }
9845
9887
  if (subtype === "task_started") {
9846
9888
  const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
@@ -10104,6 +10146,9 @@ var init_claude = __esm({
10104
10146
  const mcpConfigPath = writeMcpServersConfig(injectedServers);
10105
10147
  if (mcpConfigPath) {
10106
10148
  args.push("--mcp-config", mcpConfigPath);
10149
+ if (isOrchestrator) {
10150
+ args.push("--strict-mcp-config");
10151
+ }
10107
10152
  }
10108
10153
  if (chromeOn) {
10109
10154
  args.push("--chrome");
@@ -10133,7 +10178,10 @@ var init_claude = __esm({
10133
10178
  // abandoned at Claude Code’s 10-minute default.
10134
10179
  env: {
10135
10180
  CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
10136
- CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
10181
+ CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS),
10182
+ // `--strict-mcp-config` still fetches claude.ai connectors on some CLI
10183
+ // builds (anthropics/claude-code#60252). Coordinators do not need them.
10184
+ ...isOrchestrator ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {}
10137
10185
  }
10138
10186
  };
10139
10187
  },
@@ -10257,6 +10305,114 @@ var init_claude = __esm({
10257
10305
  }
10258
10306
  });
10259
10307
 
10308
+ // src/agents/user-mcp-config.ts
10309
+ var import_node_fs26, import_node_os10, import_node_path27;
10310
+ var init_user_mcp_config = __esm({
10311
+ "src/agents/user-mcp-config.ts"() {
10312
+ "use strict";
10313
+ import_node_fs26 = require("fs");
10314
+ import_node_os10 = require("os");
10315
+ import_node_path27 = require("path");
10316
+ init_paths();
10317
+ init_injected_mcp();
10318
+ }
10319
+ });
10320
+
10321
+ // src/agents/orch-mcp-isolation.ts
10322
+ function isInjectedOrchMcpName(name) {
10323
+ const n = name.trim().toLowerCase();
10324
+ return n === "sideboard" || n === "brightsy" || n.startsWith("brightsy_");
10325
+ }
10326
+ function asObject(value) {
10327
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
10328
+ return value;
10329
+ }
10330
+ function listMcpNamesFromJsonMap(raw, key) {
10331
+ return Object.keys(asObject(asObject(raw)[key])).filter((n) => n.trim());
10332
+ }
10333
+ function listMcpNamesFromCodexToml(text5) {
10334
+ try {
10335
+ const parsed = (0, import_smol_toml2.parse)(text5);
10336
+ return Object.keys(asObject(parsed.mcp_servers)).filter((n) => n.trim());
10337
+ } catch {
10338
+ return [];
10339
+ }
10340
+ }
10341
+ function readJsonObject(path) {
10342
+ try {
10343
+ return JSON.parse((0, import_node_fs27.readFileSync)(path, "utf8"));
10344
+ } catch {
10345
+ return {};
10346
+ }
10347
+ }
10348
+ function readText(path) {
10349
+ try {
10350
+ return (0, import_node_fs27.readFileSync)(path, "utf8");
10351
+ } catch {
10352
+ return "";
10353
+ }
10354
+ }
10355
+ function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
10356
+ return [(0, import_node_path28.join)(home, ".codex", "config.toml"), (0, import_node_path28.join)(home, ".config", "codex", "config.toml")];
10357
+ }
10358
+ function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
10359
+ return [
10360
+ (0, import_node_path28.join)(home, ".config", "opencode", "opencode.json"),
10361
+ (0, import_node_path28.join)(home, ".config", "opencode", "opencode.jsonc")
10362
+ ];
10363
+ }
10364
+ function userMcpNamesToDisable(opts) {
10365
+ const keep = new Set(
10366
+ [...opts.injectedNames ?? []].map((n) => n.trim().toLowerCase()).filter(Boolean)
10367
+ );
10368
+ const out = [];
10369
+ const seen = /* @__PURE__ */ new Set();
10370
+ for (const raw of opts.names) {
10371
+ const name = raw.trim();
10372
+ if (!name) continue;
10373
+ const key = name.toLowerCase();
10374
+ if (seen.has(key) || keep.has(key) || isInjectedOrchMcpName(name)) continue;
10375
+ seen.add(key);
10376
+ out.push(name);
10377
+ }
10378
+ return out;
10379
+ }
10380
+ function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
10381
+ const names = [];
10382
+ for (const path of userCodexConfigPaths(home)) {
10383
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
10384
+ names.push(...listMcpNamesFromCodexToml(readText(path)));
10385
+ }
10386
+ return names;
10387
+ }
10388
+ function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
10389
+ const names = [];
10390
+ for (const path of userOpencodeConfigPaths(home)) {
10391
+ if (!(0, import_node_fs27.existsSync)(path)) continue;
10392
+ names.push(...listMcpNamesFromJsonMap(readJsonObject(path), "mcp"));
10393
+ }
10394
+ return names;
10395
+ }
10396
+ function toCodexDisableUserMcpArgs(names) {
10397
+ const args = [];
10398
+ for (const name of names) {
10399
+ if (!/^[A-Za-z0-9_-]+$/.test(name)) continue;
10400
+ args.push("-c", `mcp_servers.${name}.enabled=false`);
10401
+ }
10402
+ return args;
10403
+ }
10404
+ var import_node_fs27, import_node_os11, import_node_path28, import_smol_toml2;
10405
+ var init_orch_mcp_isolation = __esm({
10406
+ "src/agents/orch-mcp-isolation.ts"() {
10407
+ "use strict";
10408
+ import_node_fs27 = require("fs");
10409
+ import_node_os11 = require("os");
10410
+ import_node_path28 = require("path");
10411
+ import_smol_toml2 = require("smol-toml");
10412
+ init_user_mcp_config();
10413
+ }
10414
+ });
10415
+
10260
10416
  // src/agents/codex.ts
10261
10417
  async function listCodexModels() {
10262
10418
  const now = Date.now();
@@ -10267,7 +10423,7 @@ async function listCodexModels() {
10267
10423
  if (codex === "codex") {
10268
10424
  const which = await run("which", ["codex"], { reject: false });
10269
10425
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
10270
- } else if (!(0, import_node_fs26.existsSync)(codex)) {
10426
+ } else if (!(0, import_node_fs28.existsSync)(codex)) {
10271
10427
  return FALLBACK_CODEX_MODELS;
10272
10428
  }
10273
10429
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -10302,12 +10458,12 @@ function usageFromCodex(usage) {
10302
10458
  }
10303
10459
  function codexConfigHasNetworkAccess() {
10304
10460
  const candidates = [
10305
- (0, import_node_path27.join)((0, import_node_os10.homedir)(), ".codex", "config.toml"),
10306
- (0, import_node_path27.join)((0, import_node_os10.homedir)(), ".config", "codex", "config.toml")
10461
+ (0, import_node_path29.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
10462
+ (0, import_node_path29.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
10307
10463
  ];
10308
10464
  for (const path of candidates) {
10309
- if (!(0, import_node_fs26.existsSync)(path)) continue;
10310
- const text5 = (0, import_node_fs26.readFileSync)(path, "utf8");
10465
+ if (!(0, import_node_fs28.existsSync)(path)) continue;
10466
+ const text5 = (0, import_node_fs28.readFileSync)(path, "utf8");
10311
10467
  if (/network_access\s*=\s*true/.test(text5)) return true;
10312
10468
  }
10313
10469
  return false;
@@ -10339,21 +10495,21 @@ function asRecord2(value) {
10339
10495
  return void 0;
10340
10496
  }
10341
10497
  function codexLooksAuthenticated() {
10342
- const authPath = (0, import_node_path27.join)((0, import_node_os10.homedir)(), ".codex", "auth.json");
10343
- if (!(0, import_node_fs26.existsSync)(authPath)) return false;
10498
+ const authPath = (0, import_node_path29.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
10499
+ if (!(0, import_node_fs28.existsSync)(authPath)) return false;
10344
10500
  try {
10345
- return (0, import_node_fs26.statSync)(authPath).size > 2;
10501
+ return (0, import_node_fs28.statSync)(authPath).size > 2;
10346
10502
  } catch {
10347
10503
  return false;
10348
10504
  }
10349
10505
  }
10350
- var import_node_fs26, import_node_os10, import_node_path27, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
10506
+ var import_node_fs28, import_node_os12, import_node_path29, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
10351
10507
  var init_codex = __esm({
10352
10508
  "src/agents/codex.ts"() {
10353
10509
  "use strict";
10354
- import_node_fs26 = require("fs");
10355
- import_node_os10 = require("os");
10356
- import_node_path27 = require("path");
10510
+ import_node_fs28 = require("fs");
10511
+ import_node_os12 = require("os");
10512
+ import_node_path29 = require("path");
10357
10513
  init_run();
10358
10514
  init_app_settings();
10359
10515
  init_global_workspace();
@@ -10361,6 +10517,7 @@ var init_codex = __esm({
10361
10517
  init_usage();
10362
10518
  init_git_auth_mode();
10363
10519
  init_injected_mcp();
10520
+ init_orch_mcp_isolation();
10364
10521
  init_turn_input();
10365
10522
  init_types();
10366
10523
  CODEX_PROMPT_ARG_MAX = 2e5;
@@ -10378,7 +10535,7 @@ var init_codex = __esm({
10378
10535
  async detect() {
10379
10536
  const codex = resolveAgentExecutable("codex");
10380
10537
  if (codex !== "codex") {
10381
- if (!(0, import_node_fs26.existsSync)(codex)) {
10538
+ if (!(0, import_node_fs28.existsSync)(codex)) {
10382
10539
  return {
10383
10540
  agent: "codex",
10384
10541
  installed: false,
@@ -10438,7 +10595,15 @@ var init_codex = __esm({
10438
10595
  }),
10439
10596
  orchestratorThreadId: isOrchestrator ? thread.id : null
10440
10597
  });
10441
- const mcpOverrides = toCodexMcpConfigArgs(injected2);
10598
+ const mcpOverrides = [
10599
+ ...toCodexMcpConfigArgs(injected2),
10600
+ ...isOrchestrator ? toCodexDisableUserMcpArgs(
10601
+ userMcpNamesToDisable({
10602
+ injectedNames: injected2.map((s) => s.name),
10603
+ names: listUserCodexMcpNames()
10604
+ })
10605
+ ) : []
10606
+ ];
10442
10607
  const execOpts = [
10443
10608
  // Global orchestration cwd is not a git repo; without this Codex ≥0.147
10444
10609
  // refuses to start ("Not inside a trusted directory").
@@ -10673,21 +10838,21 @@ function platformRipgrepPackage() {
10673
10838
  }
10674
10839
  function usableRipgrepPath(candidate) {
10675
10840
  const raw = candidate?.trim();
10676
- if (!raw || !(0, import_node_path28.isAbsolute)(raw)) return null;
10841
+ if (!raw || !(0, import_node_path30.isAbsolute)(raw)) return null;
10677
10842
  const readable = nodeReadableScriptPath(raw);
10678
- if (!(0, import_node_fs27.existsSync)(readable) || isAsarPath(readable)) return null;
10843
+ if (!(0, import_node_fs29.existsSync)(readable) || isAsarPath(readable)) return null;
10679
10844
  return readable;
10680
10845
  }
10681
10846
  function walkForBundledRipgrep(startFile) {
10682
10847
  if (!startFile) return null;
10683
10848
  const pkg = platformRipgrepPackage();
10684
10849
  const name = rgBinaryName();
10685
- let dir = (0, import_node_path28.dirname)((0, import_node_path28.resolve)(startFile));
10686
- const root = (0, import_node_path28.parse)(dir).root;
10850
+ let dir = (0, import_node_path30.dirname)((0, import_node_path30.resolve)(startFile));
10851
+ const root = (0, import_node_path30.parse)(dir).root;
10687
10852
  while (dir !== root) {
10688
- const hit = usableRipgrepPath((0, import_node_path28.join)(dir, "node_modules", pkg, "bin", name));
10853
+ const hit = usableRipgrepPath((0, import_node_path30.join)(dir, "node_modules", pkg, "bin", name));
10689
10854
  if (hit) return hit;
10690
- const next = (0, import_node_path28.dirname)(dir);
10855
+ const next = (0, import_node_path30.dirname)(dir);
10691
10856
  if (next === dir) break;
10692
10857
  dir = next;
10693
10858
  }
@@ -10697,7 +10862,7 @@ function requireResolveBundledRipgrep(fromFile) {
10697
10862
  try {
10698
10863
  const req = (0, import_node_module2.createRequire)(fromFile);
10699
10864
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
10700
- return usableRipgrepPath((0, import_node_path28.join)((0, import_node_path28.dirname)(pkgJson), "bin", rgBinaryName()));
10865
+ return usableRipgrepPath((0, import_node_path30.join)((0, import_node_path30.dirname)(pkgJson), "bin", rgBinaryName()));
10701
10866
  } catch {
10702
10867
  return null;
10703
10868
  }
@@ -10719,13 +10884,13 @@ function cursorRipgrepEnv(opts) {
10719
10884
  const path = resolveCursorRipgrepPath(opts);
10720
10885
  return path ? { [RIPGREP_ENV]: path } : {};
10721
10886
  }
10722
- var import_node_fs27, import_node_module2, import_node_path28, RIPGREP_ENV;
10887
+ var import_node_fs29, import_node_module2, import_node_path30, RIPGREP_ENV;
10723
10888
  var init_cursor_ripgrep = __esm({
10724
10889
  "src/agents/cursor-ripgrep.ts"() {
10725
10890
  "use strict";
10726
- import_node_fs27 = require("fs");
10891
+ import_node_fs29 = require("fs");
10727
10892
  import_node_module2 = require("module");
10728
- import_node_path28 = require("path");
10893
+ import_node_path30 = require("path");
10729
10894
  init_node_launch();
10730
10895
  init_packaged_runtime();
10731
10896
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -10763,11 +10928,11 @@ function entryDir() {
10763
10928
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
10764
10929
  if (cjsDir) return cjsDir;
10765
10930
  try {
10766
- return (0, import_node_path29.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
10931
+ return (0, import_node_path31.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
10767
10932
  } catch {
10768
10933
  try {
10769
10934
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
10770
- return (0, import_node_path29.dirname)(req.resolve("@sideboard-ai/core"));
10935
+ return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
10771
10936
  } catch {
10772
10937
  return process.cwd();
10773
10938
  }
@@ -10778,27 +10943,27 @@ function cursorRunnerPath() {
10778
10943
  if (packaged) return packaged;
10779
10944
  const root = entryDir();
10780
10945
  const candidates = [
10781
- (0, import_node_path29.join)(root, "agents", "cursor-runner.js"),
10782
- (0, import_node_path29.join)(root, "agents", "cursor-runner.cjs"),
10946
+ (0, import_node_path31.join)(root, "agents", "cursor-runner.js"),
10947
+ (0, import_node_path31.join)(root, "agents", "cursor-runner.cjs"),
10783
10948
  // If somehow resolved from package root instead of dist/
10784
- (0, import_node_path29.join)(root, "dist", "agents", "cursor-runner.js"),
10785
- (0, import_node_path29.join)(root, "dist", "agents", "cursor-runner.cjs"),
10949
+ (0, import_node_path31.join)(root, "dist", "agents", "cursor-runner.js"),
10950
+ (0, import_node_path31.join)(root, "dist", "agents", "cursor-runner.cjs"),
10786
10951
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
10787
- (0, import_node_path29.join)(root, "cursor-runner.ts"),
10788
- (0, import_node_path29.join)(root, "src", "agents", "cursor-runner.ts")
10952
+ (0, import_node_path31.join)(root, "cursor-runner.ts"),
10953
+ (0, import_node_path31.join)(root, "src", "agents", "cursor-runner.ts")
10789
10954
  ];
10790
10955
  for (const candidate of candidates) {
10791
- if ((0, import_node_fs28.existsSync)(candidate)) return candidate;
10956
+ if ((0, import_node_fs30.existsSync)(candidate)) return candidate;
10792
10957
  }
10793
10958
  return candidates[0];
10794
10959
  }
10795
- var import_node_fs28, import_node_module3, import_node_path29, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
10960
+ var import_node_fs30, import_node_module3, import_node_path31, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
10796
10961
  var init_cursor = __esm({
10797
10962
  "src/agents/cursor.ts"() {
10798
10963
  "use strict";
10799
- import_node_fs28 = require("fs");
10964
+ import_node_fs30 = require("fs");
10800
10965
  import_node_module3 = require("module");
10801
- import_node_path29 = require("path");
10966
+ import_node_path31 = require("path");
10802
10967
  import_node_url2 = require("url");
10803
10968
  import_sdk = require("@cursor/sdk");
10804
10969
  init_run();
@@ -10864,6 +11029,7 @@ var init_cursor = __esm({
10864
11029
  fast: thread.fast,
10865
11030
  planMode: thread.planMode,
10866
11031
  apiKey,
11032
+ ...isOrchestrator ? { isolateAmbientMcp: true } : {},
10867
11033
  ...Object.keys(mcpServers).length > 0 ? { mcpServers } : {}
10868
11034
  };
10869
11035
  const runner = cursorRunnerPath();
@@ -10949,7 +11115,7 @@ async function listOpencodeModels() {
10949
11115
  if (opencode === "opencode") {
10950
11116
  const which = await run("which", ["opencode"], { reject: false });
10951
11117
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
10952
- } else if (!(0, import_node_fs29.existsSync)(opencode)) {
11118
+ } else if (!(0, import_node_fs31.existsSync)(opencode)) {
10953
11119
  return FALLBACK_OPENCODE_MODELS;
10954
11120
  }
10955
11121
  const listed = await run(opencode, ["models"], { reject: false });
@@ -10979,17 +11145,18 @@ function usageFromOpencode(tokens) {
10979
11145
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
10980
11146
  };
10981
11147
  }
10982
- var import_node_fs29, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
11148
+ var import_node_fs31, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
10983
11149
  var init_opencode = __esm({
10984
11150
  "src/agents/opencode.ts"() {
10985
11151
  "use strict";
10986
- import_node_fs29 = require("fs");
11152
+ import_node_fs31 = require("fs");
10987
11153
  init_run();
10988
11154
  init_app_settings();
10989
11155
  init_global_workspace();
10990
11156
  init_error_detail();
10991
11157
  init_message_parts();
10992
11158
  init_injected_mcp();
11159
+ init_orch_mcp_isolation();
10993
11160
  init_turn_input();
10994
11161
  init_types();
10995
11162
  FALLBACK_OPENCODE_MODELS = [
@@ -11010,7 +11177,7 @@ var init_opencode = __esm({
11010
11177
  async detect() {
11011
11178
  const opencode = resolveAgentExecutable("opencode");
11012
11179
  if (opencode !== "opencode") {
11013
- if (!(0, import_node_fs29.existsSync)(opencode)) {
11180
+ if (!(0, import_node_fs31.existsSync)(opencode)) {
11014
11181
  return {
11015
11182
  agent: "opencode",
11016
11183
  installed: false,
@@ -11072,7 +11239,11 @@ var init_opencode = __esm({
11072
11239
  }),
11073
11240
  orchestratorThreadId: isOrchestrator ? thread.id : null
11074
11241
  });
11075
- const mcpContent = injected2.length > 0 ? toOpencodeMcpConfigContent(injected2) : null;
11242
+ const disableNames = isOrchestrator ? userMcpNamesToDisable({
11243
+ injectedNames: injected2.map((s) => s.name),
11244
+ names: listUserOpencodeMcpNames()
11245
+ }) : [];
11246
+ const mcpContent = injected2.length > 0 || disableNames.length > 0 ? toOpencodeMcpConfigContent(injected2, { disableNames }) : null;
11076
11247
  return {
11077
11248
  file: resolveAgentExecutable("opencode"),
11078
11249
  args,
@@ -12544,21 +12715,21 @@ function shouldRefreshReviewRequestTemplate(content) {
12544
12715
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
12545
12716
  }
12546
12717
  function readTextIfPresent(abs) {
12547
- if (!(0, import_node_fs30.existsSync)(abs)) return null;
12718
+ if (!(0, import_node_fs32.existsSync)(abs)) return null;
12548
12719
  try {
12549
- const content = (0, import_node_fs30.readFileSync)(abs, "utf8");
12720
+ const content = (0, import_node_fs32.readFileSync)(abs, "utf8");
12550
12721
  return content.trim() ? content : null;
12551
12722
  } catch {
12552
12723
  return null;
12553
12724
  }
12554
12725
  }
12555
12726
  function readLocalGuidelines(worktreePath) {
12556
- const localAbs = (0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH);
12727
+ const localAbs = (0, import_node_path32.join)(worktreePath, REVIEW_REQUEST_PATH);
12557
12728
  const localContent = readTextIfPresent(localAbs);
12558
12729
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
12559
12730
  return { path: REVIEW_REQUEST_PATH, content: localContent };
12560
12731
  }
12561
- const legacyAbs = (0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
12732
+ const legacyAbs = (0, import_node_path32.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
12562
12733
  const legacyContent = readTextIfPresent(legacyAbs);
12563
12734
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
12564
12735
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -12582,27 +12753,27 @@ function contextGuidelines(content, source) {
12582
12753
  };
12583
12754
  }
12584
12755
  function writeContextGuidelines(worktreePath, content) {
12585
- const abs = (0, import_node_path30.join)(worktreePath, CONTEXT_REVIEW_PATH);
12586
- (0, import_node_fs30.mkdirSync)((0, import_node_path30.dirname)(abs), { recursive: true });
12756
+ const abs = (0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH);
12757
+ (0, import_node_fs32.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
12587
12758
  const body = content.endsWith("\n") ? content : `${content}
12588
12759
  `;
12589
- (0, import_node_fs30.writeFileSync)(abs, body, "utf8");
12760
+ (0, import_node_fs32.writeFileSync)(abs, body, "utf8");
12590
12761
  return body;
12591
12762
  }
12592
12763
  function readSideboardReview(worktreePath, repoPath) {
12593
- const fromWorktree = readTextIfPresent((0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH));
12764
+ const fromWorktree = readTextIfPresent((0, import_node_path32.join)(worktreePath, REPO_REVIEW_PATH));
12594
12765
  if (fromWorktree) return fromWorktree;
12595
12766
  const repo = repoPath?.replace(/\/+$/, "");
12596
12767
  const wt = worktreePath.replace(/\/+$/, "");
12597
12768
  if (!repo || repo === wt) return null;
12598
- return readTextIfPresent((0, import_node_path30.join)(repo, REPO_REVIEW_PATH));
12769
+ return readTextIfPresent((0, import_node_path32.join)(repo, REPO_REVIEW_PATH));
12599
12770
  }
12600
12771
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
12601
- const skillContent = readTextIfPresent((0, import_node_path30.join)(worktreePath, REVIEW_SKILL_PATH));
12772
+ const skillContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_SKILL_PATH));
12602
12773
  if (skillContent) {
12603
12774
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
12604
12775
  }
12605
- const contextContent = readTextIfPresent((0, import_node_path30.join)(worktreePath, CONTEXT_REVIEW_PATH));
12776
+ const contextContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH));
12606
12777
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
12607
12778
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
12608
12779
  }
@@ -12657,13 +12828,13 @@ async function requestReview(threadRef, send) {
12657
12828
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
12658
12829
  return { tab: started, from };
12659
12830
  }
12660
- var import_node_crypto7, import_node_fs30, import_node_path30, 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;
12831
+ var import_node_crypto7, import_node_fs32, import_node_path32, 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;
12661
12832
  var init_request_review = __esm({
12662
12833
  "src/review/request-review.ts"() {
12663
12834
  "use strict";
12664
12835
  import_node_crypto7 = require("crypto");
12665
- import_node_fs30 = require("fs");
12666
- import_node_path30 = require("path");
12836
+ import_node_fs32 = require("fs");
12837
+ import_node_path32 = require("path");
12667
12838
  init_global_workspace();
12668
12839
  init_chat_tabs();
12669
12840
  init_thread_store();
@@ -12689,9 +12860,9 @@ function matchSimpleGlob(pattern, name) {
12689
12860
  return new RegExp(`^${escaped}$`).test(name);
12690
12861
  }
12691
12862
  function readWorktreeInclude(repoPath) {
12692
- const path = (0, import_node_path31.join)(repoPath, ".worktreeinclude");
12693
- if (!(0, import_node_fs31.existsSync)(path)) return [];
12694
- return (0, import_node_fs31.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
12863
+ const path = (0, import_node_path33.join)(repoPath, ".worktreeinclude");
12864
+ if (!(0, import_node_fs33.existsSync)(path)) return [];
12865
+ return (0, import_node_fs33.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
12695
12866
  }
12696
12867
  function resolveFilesToCopy(repoPath) {
12697
12868
  const fromInclude = readWorktreeInclude(repoPath);
@@ -12701,10 +12872,10 @@ function resolveFilesToCopy(repoPath) {
12701
12872
  if (settings?.fileIncludeGlobs?.length) {
12702
12873
  const matched = [];
12703
12874
  try {
12704
- for (const entry of (0, import_node_fs31.readdirSync)(repoPath, { withFileTypes: true })) {
12875
+ for (const entry of (0, import_node_fs33.readdirSync)(repoPath, { withFileTypes: true })) {
12705
12876
  if (!entry.isFile()) continue;
12706
12877
  for (const glob of settings.fileIncludeGlobs) {
12707
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path31.basename)(glob), entry.name)) {
12878
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path33.basename)(glob), entry.name)) {
12708
12879
  matched.push(entry.name);
12709
12880
  break;
12710
12881
  }
@@ -12716,7 +12887,7 @@ function resolveFilesToCopy(repoPath) {
12716
12887
  }
12717
12888
  const defaults = [];
12718
12889
  try {
12719
- for (const entry of (0, import_node_fs31.readdirSync)(repoPath, { withFileTypes: true })) {
12890
+ for (const entry of (0, import_node_fs33.readdirSync)(repoPath, { withFileTypes: true })) {
12720
12891
  if (entry.isFile() && entry.name.startsWith(".env")) {
12721
12892
  defaults.push(entry.name);
12722
12893
  }
@@ -12730,11 +12901,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
12730
12901
  const patterns = resolveFilesToCopy(repoPath);
12731
12902
  const copied = [];
12732
12903
  for (const rel of patterns) {
12733
- const src = (0, import_node_path31.join)(repoPath, rel);
12734
- if (!(0, import_node_fs31.existsSync)(src)) continue;
12735
- const dest = (0, import_node_path31.join)(worktreePath, rel);
12736
- (0, import_node_fs31.mkdirSync)((0, import_node_path31.dirname)(dest), { recursive: true });
12737
- (0, import_node_fs31.copyFileSync)(src, dest);
12904
+ const src = (0, import_node_path33.join)(repoPath, rel);
12905
+ if (!(0, import_node_fs33.existsSync)(src)) continue;
12906
+ const dest = (0, import_node_path33.join)(worktreePath, rel);
12907
+ (0, import_node_fs33.mkdirSync)((0, import_node_path33.dirname)(dest), { recursive: true });
12908
+ (0, import_node_fs33.copyFileSync)(src, dest);
12738
12909
  copied.push(rel);
12739
12910
  }
12740
12911
  return copied;
@@ -12769,7 +12940,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
12769
12940
  const env = stripNestedElectronEnv({
12770
12941
  ...baseEnv ?? process.env
12771
12942
  });
12772
- const name = opts.workspaceName ?? (0, import_node_path31.basename)(opts.worktreePath);
12943
+ const name = opts.workspaceName ?? (0, import_node_path33.basename)(opts.worktreePath);
12773
12944
  const ports = opts.ports ?? [];
12774
12945
  const primary = ports[0];
12775
12946
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -13031,13 +13202,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
13031
13202
  done: handle.done
13032
13203
  };
13033
13204
  }
13034
- var import_node_fs31, import_node_net, import_node_path31, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
13205
+ var import_node_fs33, import_node_net, import_node_path33, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
13035
13206
  var init_conductor = __esm({
13036
13207
  "src/hook/conductor.ts"() {
13037
13208
  "use strict";
13038
- import_node_fs31 = require("fs");
13209
+ import_node_fs33 = require("fs");
13039
13210
  import_node_net = require("net");
13040
- import_node_path31 = require("path");
13211
+ import_node_path33 = require("path");
13041
13212
  import_execa4 = require("execa");
13042
13213
  import_node_readline3 = require("readline");
13043
13214
  init_settings();
@@ -13055,7 +13226,7 @@ var init_conductor = __esm({
13055
13226
 
13056
13227
  // src/store/setup-log.ts
13057
13228
  function setupLogPath(threadId) {
13058
- return (0, import_node_path32.join)(threadsDir(), `${threadId}.setup.log.json`);
13229
+ return (0, import_node_path34.join)(threadsDir(), `${threadId}.setup.log.json`);
13059
13230
  }
13060
13231
  function emptySetupLog() {
13061
13232
  return { ...EMPTY };
@@ -13072,7 +13243,7 @@ function persistNow(threadId) {
13072
13243
  const snap = memory.get(threadId);
13073
13244
  if (!snap) return;
13074
13245
  try {
13075
- (0, import_node_fs32.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
13246
+ (0, import_node_fs34.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
13076
13247
  `, "utf8");
13077
13248
  } catch {
13078
13249
  }
@@ -13089,9 +13260,9 @@ function schedulePersist(threadId) {
13089
13260
  }
13090
13261
  function loadFromDisk(threadId) {
13091
13262
  const path = setupLogPath(threadId);
13092
- if (!(0, import_node_fs32.existsSync)(path)) return null;
13263
+ if (!(0, import_node_fs34.existsSync)(path)) return null;
13093
13264
  try {
13094
- const raw = JSON.parse((0, import_node_fs32.readFileSync)(path, "utf8"));
13265
+ const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
13095
13266
  return {
13096
13267
  output: typeof raw.output === "string" ? raw.output : "",
13097
13268
  running: Boolean(raw.running),
@@ -13147,12 +13318,12 @@ function finishSetupLog(threadId, exitCode, source) {
13147
13318
  persistNow(threadId);
13148
13319
  return clone(snap);
13149
13320
  }
13150
- var import_node_fs32, import_node_path32, EMPTY, memory, persistTimers;
13321
+ var import_node_fs34, import_node_path34, EMPTY, memory, persistTimers;
13151
13322
  var init_setup_log = __esm({
13152
13323
  "src/store/setup-log.ts"() {
13153
13324
  "use strict";
13154
- import_node_fs32 = require("fs");
13155
- import_node_path32 = require("path");
13325
+ import_node_fs34 = require("fs");
13326
+ import_node_path34 = require("path");
13156
13327
  init_paths();
13157
13328
  EMPTY = {
13158
13329
  output: "",
@@ -13176,9 +13347,9 @@ async function findOrphanWorktrees(repoPaths) {
13176
13347
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
13177
13348
  );
13178
13349
  const homeRoot = sideboardWorkspacesDir();
13179
- if ((0, import_node_fs33.existsSync)(homeRoot)) {
13350
+ if ((0, import_node_fs35.existsSync)(homeRoot)) {
13180
13351
  try {
13181
- for (const entry of (0, import_node_fs33.readdirSync)(homeRoot, { withFileTypes: true })) {
13352
+ for (const entry of (0, import_node_fs35.readdirSync)(homeRoot, { withFileTypes: true })) {
13182
13353
  if (!entry.isDirectory()) continue;
13183
13354
  void entry;
13184
13355
  }
@@ -13188,7 +13359,7 @@ async function findOrphanWorktrees(repoPaths) {
13188
13359
  const orphans = [];
13189
13360
  const seen = /* @__PURE__ */ new Set();
13190
13361
  for (const repoPath of repos) {
13191
- if (!repoPath || !(0, import_node_fs33.existsSync)(repoPath)) continue;
13362
+ if (!repoPath || !(0, import_node_fs35.existsSync)(repoPath)) continue;
13192
13363
  try {
13193
13364
  const wts = await listWorktrees(repoPath);
13194
13365
  for (const wt of wts) {
@@ -13199,7 +13370,7 @@ async function findOrphanWorktrees(repoPaths) {
13199
13370
  seen.add(path);
13200
13371
  let mtimeMs = 0;
13201
13372
  try {
13202
- mtimeMs = (0, import_node_fs33.statSync)(path).mtimeMs;
13373
+ mtimeMs = (0, import_node_fs35.statSync)(path).mtimeMs;
13203
13374
  } catch {
13204
13375
  mtimeMs = 0;
13205
13376
  }
@@ -13209,16 +13380,16 @@ async function findOrphanWorktrees(repoPaths) {
13209
13380
  }
13210
13381
  try {
13211
13382
  const root = worktreesRoot(repoPath);
13212
- if ((0, import_node_fs33.existsSync)(root)) {
13213
- for (const entry of (0, import_node_fs33.readdirSync)(root, { withFileTypes: true })) {
13383
+ if ((0, import_node_fs35.existsSync)(root)) {
13384
+ for (const entry of (0, import_node_fs35.readdirSync)(root, { withFileTypes: true })) {
13214
13385
  if (!entry.isDirectory()) continue;
13215
- const path = (0, import_node_path33.join)(root, entry.name).replace(/\/$/, "");
13386
+ const path = (0, import_node_path35.join)(root, entry.name).replace(/\/$/, "");
13216
13387
  if (known.has(path) || seen.has(path)) continue;
13217
- if (!(0, import_node_fs33.existsSync)((0, import_node_path33.join)(path, ".git"))) continue;
13388
+ if (!(0, import_node_fs35.existsSync)((0, import_node_path35.join)(path, ".git"))) continue;
13218
13389
  seen.add(path);
13219
13390
  let mtimeMs = 0;
13220
13391
  try {
13221
- mtimeMs = (0, import_node_fs33.statSync)(path).mtimeMs;
13392
+ mtimeMs = (0, import_node_fs35.statSync)(path).mtimeMs;
13222
13393
  } catch {
13223
13394
  mtimeMs = Date.now();
13224
13395
  }
@@ -13270,12 +13441,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
13270
13441
  const elapsed = Date.now() - Date.parse(last);
13271
13442
  return elapsed >= intervalHours * 36e5;
13272
13443
  }
13273
- var import_node_fs33, import_node_path33;
13444
+ var import_node_fs35, import_node_path35;
13274
13445
  var init_orphan_cleanup = __esm({
13275
13446
  "src/git/orphan-cleanup.ts"() {
13276
13447
  "use strict";
13277
- import_node_fs33 = require("fs");
13278
- import_node_path33 = require("path");
13448
+ import_node_fs35 = require("fs");
13449
+ import_node_path35 = require("path");
13279
13450
  init_worktree();
13280
13451
  init_thread_store();
13281
13452
  init_paths();
@@ -13378,12 +13549,12 @@ async function cloneRepoIntoSideboard(opts) {
13378
13549
  if (!url) throw new Error("Clone URL is required");
13379
13550
  let name = opts.name?.trim();
13380
13551
  if (!name) {
13381
- const leaf = (0, import_node_path34.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
13552
+ const leaf = (0, import_node_path36.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
13382
13553
  name = leaf || "repo";
13383
13554
  }
13384
13555
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
13385
- const dest = (0, import_node_path34.join)(sideboardReposDir(), name);
13386
- if ((0, import_node_fs34.existsSync)(dest)) {
13556
+ const dest = (0, import_node_path36.join)(sideboardReposDir(), name);
13557
+ if ((0, import_node_fs36.existsSync)(dest)) {
13387
13558
  const repoPath2 = await resolveRepoRoot(dest);
13388
13559
  const workspace2 = await ensureWorkspace(repoPath2);
13389
13560
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -13398,12 +13569,12 @@ async function cloneRepoIntoSideboard(opts) {
13398
13569
  const workspace = await ensureWorkspace(repoPath);
13399
13570
  return { repoPath, workspace };
13400
13571
  }
13401
- var import_node_fs34, import_node_path34, import_execa6;
13572
+ var import_node_fs36, import_node_path36, import_execa6;
13402
13573
  var init_clone_repo = __esm({
13403
13574
  "src/git/clone-repo.ts"() {
13404
13575
  "use strict";
13405
- import_node_fs34 = require("fs");
13406
- import_node_path34 = require("path");
13576
+ import_node_fs36 = require("fs");
13577
+ import_node_path36 = require("path");
13407
13578
  import_execa6 = require("execa");
13408
13579
  init_paths();
13409
13580
  init_workspaces2();
@@ -13413,11 +13584,11 @@ var init_clone_repo = __esm({
13413
13584
 
13414
13585
  // src/store/desktop-host.ts
13415
13586
  function desktopHostPidPath() {
13416
- return (0, import_node_path35.join)(appDataDir(), "desktop-host.pid");
13587
+ return (0, import_node_path37.join)(appDataDir(), "desktop-host.pid");
13417
13588
  }
13418
13589
  function readDesktopHostPid() {
13419
13590
  try {
13420
- const pid = Number.parseInt((0, import_node_fs35.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
13591
+ const pid = Number.parseInt((0, import_node_fs37.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
13421
13592
  if (!Number.isFinite(pid) || pid <= 0) return null;
13422
13593
  return pid;
13423
13594
  } catch {
@@ -13443,12 +13614,12 @@ function thisProcessShouldDrainAgentQueues() {
13443
13614
  if (isThisProcessDesktopHost()) return true;
13444
13615
  return !isDesktopHostAlive();
13445
13616
  }
13446
- var import_node_fs35, import_node_path35;
13617
+ var import_node_fs37, import_node_path37;
13447
13618
  var init_desktop_host = __esm({
13448
13619
  "src/store/desktop-host.ts"() {
13449
13620
  "use strict";
13450
- import_node_fs35 = require("fs");
13451
- import_node_path35 = require("path");
13621
+ import_node_fs37 = require("fs");
13622
+ import_node_path37 = require("path");
13452
13623
  init_paths();
13453
13624
  }
13454
13625
  });
@@ -14500,7 +14671,7 @@ function reuseLiveThread(input, repoPath, match) {
14500
14671
  }
14501
14672
  async function createThread(input, _onSetupLine) {
14502
14673
  const repoPath = await resolveRepoRoot(input.repoPath);
14503
- if (!(0, import_node_fs36.existsSync)(repoPath)) {
14674
+ if (!(0, import_node_fs38.existsSync)(repoPath)) {
14504
14675
  throw new Error(`Repo not found: ${repoPath}`);
14505
14676
  }
14506
14677
  const reused = reuseLiveThread(input, repoPath, {
@@ -14671,11 +14842,11 @@ async function createThread(input, _onSetupLine) {
14671
14842
  await ensureWorkspace(repoPath);
14672
14843
  return readThread(thread.id) ?? thread;
14673
14844
  }
14674
- var import_node_fs36;
14845
+ var import_node_fs38;
14675
14846
  var init_create = __esm({
14676
14847
  "src/threads/create.ts"() {
14677
14848
  "use strict";
14678
- import_node_fs36 = require("fs");
14849
+ import_node_fs38 = require("fs");
14679
14850
  init_detect();
14680
14851
  init_worktree();
14681
14852
  init_home_board();
@@ -14778,20 +14949,20 @@ function writeTurnLive(threadId, progress) {
14778
14949
  const path = threadLivePath(threadId);
14779
14950
  const tmp = `${path}.${process.pid}.tmp`;
14780
14951
  try {
14781
- (0, import_node_fs37.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
14782
- (0, import_node_fs37.renameSync)(tmp, path);
14952
+ (0, import_node_fs39.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
14953
+ (0, import_node_fs39.renameSync)(tmp, path);
14783
14954
  } catch {
14784
14955
  try {
14785
- (0, import_node_fs37.unlinkSync)(tmp);
14956
+ (0, import_node_fs39.unlinkSync)(tmp);
14786
14957
  } catch {
14787
14958
  }
14788
14959
  }
14789
14960
  }
14790
14961
  function readTurnLive(threadId) {
14791
14962
  const path = threadLivePath(threadId);
14792
- if (!(0, import_node_fs37.existsSync)(path)) return null;
14963
+ if (!(0, import_node_fs39.existsSync)(path)) return null;
14793
14964
  try {
14794
- const raw = JSON.parse((0, import_node_fs37.readFileSync)(path, "utf8"));
14965
+ const raw = JSON.parse((0, import_node_fs39.readFileSync)(path, "utf8"));
14795
14966
  if (!raw || typeof raw.summary !== "string") return null;
14796
14967
  return raw;
14797
14968
  } catch {
@@ -14803,17 +14974,17 @@ function clearTurnLive(threadId) {
14803
14974
  if (buf?.timer) clearTimeout(buf.timer);
14804
14975
  buffers.delete(threadId);
14805
14976
  const path = threadLivePath(threadId);
14806
- if (!(0, import_node_fs37.existsSync)(path)) return;
14977
+ if (!(0, import_node_fs39.existsSync)(path)) return;
14807
14978
  try {
14808
- (0, import_node_fs37.unlinkSync)(path);
14979
+ (0, import_node_fs39.unlinkSync)(path);
14809
14980
  } catch {
14810
14981
  }
14811
14982
  }
14812
- var import_node_fs37, buffers, FLUSH_MS, MAX_PARTS;
14983
+ var import_node_fs39, buffers, FLUSH_MS, MAX_PARTS;
14813
14984
  var init_turn_live = __esm({
14814
14985
  "src/store/turn-live.ts"() {
14815
14986
  "use strict";
14816
- import_node_fs37 = require("fs");
14987
+ import_node_fs39 = require("fs");
14817
14988
  init_message_parts();
14818
14989
  init_paths();
14819
14990
  buffers = /* @__PURE__ */ new Map();
@@ -14846,7 +15017,8 @@ var init_reconcile_heal = __esm({
14846
15017
  // src/orchestrator/setup-last-error.ts
14847
15018
  function shouldStampSetupLastError(opts) {
14848
15019
  if (opts.turnInFlight) return false;
14849
- if (opts.status === "running") return false;
15020
+ if (opts.status === "running" || opts.status === "queued") return false;
15021
+ if (opts.hasQueuedPrompt) return false;
14850
15022
  return true;
14851
15023
  }
14852
15024
  function isStaleLastErrorDuringTurn(err) {
@@ -15029,7 +15201,7 @@ var init_quota_failover = __esm({
15029
15201
  // src/threads/adopt.ts
15030
15202
  function thisModuleFile() {
15031
15203
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
15032
- return cjsFile || process.argv[1] || (0, import_node_path36.join)(process.cwd(), "package.json");
15204
+ return cjsFile || process.argv[1] || (0, import_node_path38.join)(process.cwd(), "package.json");
15033
15205
  }
15034
15206
  function openReadonlySqlite(file) {
15035
15207
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -15047,21 +15219,21 @@ function mapAgentType(raw) {
15047
15219
  return null;
15048
15220
  }
15049
15221
  function resolveConductorCursorAgentId(workspacePath) {
15050
- if (!workspacePath || !(0, import_node_fs38.existsSync)(CURSOR_SDK_STORE)) return null;
15222
+ if (!workspacePath || !(0, import_node_fs40.existsSync)(CURSOR_SDK_STORE)) return null;
15051
15223
  const normalized = workspacePath.replace(/\/$/, "");
15052
15224
  let best = null;
15053
15225
  let hashes;
15054
15226
  try {
15055
- hashes = (0, import_node_fs38.readdirSync)(CURSOR_SDK_STORE);
15227
+ hashes = (0, import_node_fs40.readdirSync)(CURSOR_SDK_STORE);
15056
15228
  } catch {
15057
15229
  return null;
15058
15230
  }
15059
15231
  for (const hash of hashes) {
15060
- const agentsFile = (0, import_node_path36.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
15061
- if (!(0, import_node_fs38.existsSync)(agentsFile)) continue;
15232
+ const agentsFile = (0, import_node_path38.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
15233
+ if (!(0, import_node_fs40.existsSync)(agentsFile)) continue;
15062
15234
  let text5;
15063
15235
  try {
15064
- text5 = (0, import_node_fs38.readFileSync)(agentsFile, "utf8");
15236
+ text5 = (0, import_node_fs40.readFileSync)(agentsFile, "utf8");
15065
15237
  } catch {
15066
15238
  continue;
15067
15239
  }
@@ -15085,7 +15257,7 @@ function resolveConductorCursorAgentId(workspacePath) {
15085
15257
  return best?.agentId ?? null;
15086
15258
  }
15087
15259
  async function adoptThread(input) {
15088
- if (!(0, import_node_fs38.existsSync)(input.worktreePath)) {
15260
+ if (!(0, import_node_fs40.existsSync)(input.worktreePath)) {
15089
15261
  throw new Error(`Worktree not found: ${input.worktreePath}`);
15090
15262
  }
15091
15263
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -15111,18 +15283,18 @@ async function adoptThread(input) {
15111
15283
  return thread;
15112
15284
  }
15113
15285
  function listConductorWorkspaces() {
15114
- if (!(0, import_node_fs38.existsSync)(CONDUCTOR_DB)) {
15286
+ if (!(0, import_node_fs40.existsSync)(CONDUCTOR_DB)) {
15115
15287
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
15116
15288
  }
15117
- const tmp = (0, import_node_fs38.mkdtempSync)((0, import_node_path36.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
15118
- const snapshot = (0, import_node_path36.join)(tmp, "conductor.db");
15289
+ const tmp = (0, import_node_fs40.mkdtempSync)((0, import_node_path38.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
15290
+ const snapshot = (0, import_node_path38.join)(tmp, "conductor.db");
15119
15291
  try {
15120
- (0, import_node_fs38.copyFileSync)(CONDUCTOR_DB, snapshot);
15292
+ (0, import_node_fs40.copyFileSync)(CONDUCTOR_DB, snapshot);
15121
15293
  for (const suffix of ["-wal", "-shm"]) {
15122
15294
  const src = `${CONDUCTOR_DB}${suffix}`;
15123
- if ((0, import_node_fs38.existsSync)(src)) {
15295
+ if ((0, import_node_fs40.existsSync)(src)) {
15124
15296
  try {
15125
- (0, import_node_fs38.copyFileSync)(src, `${snapshot}${suffix}`);
15297
+ (0, import_node_fs40.copyFileSync)(src, `${snapshot}${suffix}`);
15126
15298
  } catch {
15127
15299
  }
15128
15300
  }
@@ -15198,22 +15370,22 @@ function listConductorWorkspaces() {
15198
15370
  db.close();
15199
15371
  }
15200
15372
  } finally {
15201
- (0, import_node_fs38.rmSync)(tmp, { recursive: true, force: true });
15373
+ (0, import_node_fs40.rmSync)(tmp, { recursive: true, force: true });
15202
15374
  }
15203
15375
  }
15204
15376
  function importConductorWorkspace(workspaceId) {
15205
- if (!(0, import_node_fs38.existsSync)(CONDUCTOR_DB)) {
15377
+ if (!(0, import_node_fs40.existsSync)(CONDUCTOR_DB)) {
15206
15378
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
15207
15379
  }
15208
- const tmp = (0, import_node_fs38.mkdtempSync)((0, import_node_path36.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
15209
- const snapshot = (0, import_node_path36.join)(tmp, "conductor.db");
15380
+ const tmp = (0, import_node_fs40.mkdtempSync)((0, import_node_path38.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
15381
+ const snapshot = (0, import_node_path38.join)(tmp, "conductor.db");
15210
15382
  try {
15211
- (0, import_node_fs38.copyFileSync)(CONDUCTOR_DB, snapshot);
15383
+ (0, import_node_fs40.copyFileSync)(CONDUCTOR_DB, snapshot);
15212
15384
  for (const suffix of ["-wal", "-shm"]) {
15213
15385
  const src = `${CONDUCTOR_DB}${suffix}`;
15214
- if ((0, import_node_fs38.existsSync)(src)) {
15386
+ if ((0, import_node_fs40.existsSync)(src)) {
15215
15387
  try {
15216
- (0, import_node_fs38.copyFileSync)(src, `${snapshot}${suffix}`);
15388
+ (0, import_node_fs40.copyFileSync)(src, `${snapshot}${suffix}`);
15217
15389
  } catch {
15218
15390
  }
15219
15391
  }
@@ -15231,7 +15403,7 @@ function importConductorWorkspace(workspaceId) {
15231
15403
  ).get(workspaceId);
15232
15404
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
15233
15405
  const worktreePath = String(row.workspacePath);
15234
- if (!(0, import_node_fs38.existsSync)(worktreePath)) {
15406
+ if (!(0, import_node_fs40.existsSync)(worktreePath)) {
15235
15407
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
15236
15408
  }
15237
15409
  let sessionId = null;
@@ -15294,31 +15466,31 @@ function importConductorWorkspace(workspaceId) {
15294
15466
  db.close();
15295
15467
  }
15296
15468
  } finally {
15297
- (0, import_node_fs38.rmSync)(tmp, { recursive: true, force: true });
15469
+ (0, import_node_fs40.rmSync)(tmp, { recursive: true, force: true });
15298
15470
  }
15299
15471
  }
15300
15472
  async function importConductorWorkspaceAsync(workspaceId) {
15301
15473
  return importConductorWorkspace(workspaceId);
15302
15474
  }
15303
- var import_node_child_process3, import_node_fs38, import_node_os11, import_node_path36, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
15475
+ var import_node_child_process3, import_node_fs40, import_node_os13, import_node_path38, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
15304
15476
  var init_adopt = __esm({
15305
15477
  "src/threads/adopt.ts"() {
15306
15478
  "use strict";
15307
15479
  import_node_child_process3 = require("child_process");
15308
- import_node_fs38 = require("fs");
15309
- import_node_os11 = require("os");
15310
- import_node_path36 = require("path");
15480
+ import_node_fs40 = require("fs");
15481
+ import_node_os13 = require("os");
15482
+ import_node_path38 = require("path");
15311
15483
  import_node_module4 = require("module");
15312
15484
  init_worktree();
15313
15485
  init_thread_store();
15314
- CONDUCTOR_APP_SUPPORT = (0, import_node_path36.join)(
15486
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path38.join)(
15315
15487
  process.env.HOME ?? "",
15316
15488
  "Library",
15317
15489
  "Application Support",
15318
15490
  "com.conductor.app"
15319
15491
  );
15320
- CONDUCTOR_DB = (0, import_node_path36.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
15321
- CURSOR_SDK_STORE = (0, import_node_path36.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
15492
+ CONDUCTOR_DB = (0, import_node_path38.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
15493
+ CURSOR_SDK_STORE = (0, import_node_path38.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
15322
15494
  }
15323
15495
  });
15324
15496
 
@@ -15385,7 +15557,7 @@ async function openStackLayer(input, _onSetupLine) {
15385
15557
  let createdWorktree = false;
15386
15558
  const trees = await listWorktrees(repoPath);
15387
15559
  const checkedOut = trees.find((w) => w.branch === branchName);
15388
- if (checkedOut?.path && (0, import_node_fs39.existsSync)(checkedOut.path)) {
15560
+ if (checkedOut?.path && (0, import_node_fs41.existsSync)(checkedOut.path)) {
15389
15561
  if (input.reuseExistingWorktree !== false) {
15390
15562
  worktreePath = checkedOut.path;
15391
15563
  } else {
@@ -15527,7 +15699,7 @@ async function initStackFromThread(input, onSetupLine) {
15527
15699
  async function createPrStack(input, onSetupLine) {
15528
15700
  await requireAgent(input.agent);
15529
15701
  const repoPath = await resolveRepoRoot(input.repoPath);
15530
- if (!(0, import_node_fs39.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
15702
+ if (!(0, import_node_fs41.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
15531
15703
  if (!input.branches.length) throw new Error("At least one branch name required");
15532
15704
  const status = await detectGhStack(repoPath);
15533
15705
  if (!status.available) throw new Error(status.reason);
@@ -15594,7 +15766,7 @@ async function createPrStack(input, onSetupLine) {
15594
15766
  }
15595
15767
  }
15596
15768
  const claimed = new Set(threads.map((t) => t.worktreePath));
15597
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs39.existsSync)(bootstrap.worktreePath)) {
15769
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs41.existsSync)(bootstrap.worktreePath)) {
15598
15770
  try {
15599
15771
  await removeWorktree(repoPath, bootstrap.worktreePath, {
15600
15772
  deleteBranch: bootstrap.branchName
@@ -15604,11 +15776,11 @@ async function createPrStack(input, onSetupLine) {
15604
15776
  }
15605
15777
  return { stack, threads, createdThreadIds };
15606
15778
  }
15607
- var import_node_fs39;
15779
+ var import_node_fs41;
15608
15780
  var init_stack_layers = __esm({
15609
15781
  "src/threads/stack-layers.ts"() {
15610
15782
  "use strict";
15611
- import_node_fs39 = require("fs");
15783
+ import_node_fs41 = require("fs");
15612
15784
  init_detect();
15613
15785
  init_run();
15614
15786
  init_stack();
@@ -15621,7 +15793,7 @@ var init_stack_layers = __esm({
15621
15793
 
15622
15794
  // src/diff/diff.ts
15623
15795
  async function inspectGitWorktree(worktreePath) {
15624
- if (!worktreePath || !(0, import_node_fs40.existsSync)(worktreePath)) return "missing_worktree";
15796
+ if (!worktreePath || !(0, import_node_fs42.existsSync)(worktreePath)) return "missing_worktree";
15625
15797
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
15626
15798
  reject: false
15627
15799
  });
@@ -15629,7 +15801,7 @@ async function inspectGitWorktree(worktreePath) {
15629
15801
  return "ok";
15630
15802
  }
15631
15803
  async function initializeGitRepository(worktreePath) {
15632
- if (!worktreePath || !(0, import_node_fs40.existsSync)(worktreePath)) {
15804
+ if (!worktreePath || !(0, import_node_fs42.existsSync)(worktreePath)) {
15633
15805
  throw new Error("Worktree not found");
15634
15806
  }
15635
15807
  const status = await inspectGitWorktree(worktreePath);
@@ -15763,11 +15935,11 @@ new file mode 100644
15763
15935
  };
15764
15936
  }
15765
15937
  async function untrackedPatch(worktreePath, path, maxHunk) {
15766
- const abs = (0, import_node_path37.join)(worktreePath, path);
15938
+ const abs = (0, import_node_path39.join)(worktreePath, path);
15767
15939
  try {
15768
- const st = (0, import_node_fs40.statSync)(abs);
15940
+ const st = (0, import_node_fs42.statSync)(abs);
15769
15941
  if (st.isFile() && st.size > maxHunk) {
15770
- const buf = (0, import_node_fs40.readFileSync)(abs).subarray(0, maxHunk);
15942
+ const buf = (0, import_node_fs42.readFileSync)(abs).subarray(0, maxHunk);
15771
15943
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
15772
15944
  }
15773
15945
  } catch {
@@ -16256,8 +16428,8 @@ function isImageRelativePath(relativePath) {
16256
16428
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
16257
16429
  assertSafeRelativePath(relativePath);
16258
16430
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
16259
- const abs = (0, import_node_path37.join)(worktreePath, relativePath);
16260
- const st = (0, import_node_fs40.statSync)(abs);
16431
+ const abs = (0, import_node_path39.join)(worktreePath, relativePath);
16432
+ const st = (0, import_node_fs42.statSync)(abs);
16261
16433
  if (!st.isFile()) {
16262
16434
  throw new Error(`Not a file: ${relativePath}`);
16263
16435
  }
@@ -16266,7 +16438,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
16266
16438
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
16267
16439
  );
16268
16440
  }
16269
- const buf = (0, import_node_fs40.readFileSync)(abs);
16441
+ const buf = (0, import_node_fs42.readFileSync)(abs);
16270
16442
  return {
16271
16443
  path: relativePath,
16272
16444
  contentBase64: buf.toString("base64"),
@@ -16276,12 +16448,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
16276
16448
  function readWorktreeFile(worktreePath, relativePath, opts) {
16277
16449
  assertSafeRelativePath(relativePath);
16278
16450
  const maxBytes = opts?.maxBytes ?? 2e5;
16279
- const abs = (0, import_node_path37.join)(worktreePath, relativePath);
16280
- const st = (0, import_node_fs40.statSync)(abs);
16451
+ const abs = (0, import_node_path39.join)(worktreePath, relativePath);
16452
+ const st = (0, import_node_fs42.statSync)(abs);
16281
16453
  if (!st.isFile()) {
16282
16454
  throw new Error(`Not a file: ${relativePath}`);
16283
16455
  }
16284
- const buf = (0, import_node_fs40.readFileSync)(abs);
16456
+ const buf = (0, import_node_fs42.readFileSync)(abs);
16285
16457
  if (isImageRelativePath(relativePath)) {
16286
16458
  const maxImageBytes = Math.max(maxBytes, 15e6);
16287
16459
  const truncated2 = buf.length > maxImageBytes;
@@ -16324,9 +16496,9 @@ function assertSafeRelativePath(relativePath) {
16324
16496
  }
16325
16497
  function writeWorktreeFile(worktreePath, relativePath, content) {
16326
16498
  assertSafeRelativePath(relativePath);
16327
- const abs = (0, import_node_path37.join)(worktreePath, relativePath);
16328
- (0, import_node_fs40.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
16329
- (0, import_node_fs40.writeFileSync)(abs, content, "utf8");
16499
+ const abs = (0, import_node_path39.join)(worktreePath, relativePath);
16500
+ (0, import_node_fs42.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
16501
+ (0, import_node_fs42.writeFileSync)(abs, content, "utf8");
16330
16502
  return { path: relativePath };
16331
16503
  }
16332
16504
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -16343,12 +16515,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
16343
16515
  truncated: full.files.length > maxFiles
16344
16516
  };
16345
16517
  }
16346
- var import_node_fs40, import_node_path37, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
16518
+ var import_node_fs42, import_node_path39, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
16347
16519
  var init_diff = __esm({
16348
16520
  "src/diff/diff.ts"() {
16349
16521
  "use strict";
16350
- import_node_fs40 = require("fs");
16351
- import_node_path37 = require("path");
16522
+ import_node_fs42 = require("fs");
16523
+ import_node_path39 = require("path");
16352
16524
  init_run();
16353
16525
  init_worktree();
16354
16526
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -16616,7 +16788,7 @@ function parseFrontmatter(content) {
16616
16788
  }
16617
16789
  function readSkill(skillMd, source) {
16618
16790
  try {
16619
- const content = (0, import_node_fs41.readFileSync)(skillMd, "utf8");
16791
+ const content = (0, import_node_fs43.readFileSync)(skillMd, "utf8");
16620
16792
  const { name: fmName, description } = parseFrontmatter(content);
16621
16793
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
16622
16794
  const name = fmName || dirName;
@@ -16635,19 +16807,19 @@ function readSkill(skillMd, source) {
16635
16807
  }
16636
16808
  }
16637
16809
  function scanSkillsDir(dir, source, out) {
16638
- if (!(0, import_node_fs41.existsSync)(dir)) return;
16810
+ if (!(0, import_node_fs43.existsSync)(dir)) return;
16639
16811
  let entries;
16640
16812
  try {
16641
- entries = (0, import_node_fs41.readdirSync)(dir);
16813
+ entries = (0, import_node_fs43.readdirSync)(dir);
16642
16814
  } catch {
16643
16815
  return;
16644
16816
  }
16645
16817
  for (const entry of entries) {
16646
16818
  if (entry.startsWith(".")) continue;
16647
- const skillMd = (0, import_node_path38.join)(dir, entry, "SKILL.md");
16648
- if (!(0, import_node_fs41.existsSync)(skillMd)) continue;
16819
+ const skillMd = (0, import_node_path40.join)(dir, entry, "SKILL.md");
16820
+ if (!(0, import_node_fs43.existsSync)(skillMd)) continue;
16649
16821
  try {
16650
- if (!(0, import_node_fs41.statSync)(skillMd).isFile()) continue;
16822
+ if (!(0, import_node_fs43.statSync)(skillMd).isFile()) continue;
16651
16823
  } catch {
16652
16824
  continue;
16653
16825
  }
@@ -16656,24 +16828,24 @@ function scanSkillsDir(dir, source, out) {
16656
16828
  }
16657
16829
  }
16658
16830
  function scanClaudePluginSkills(pluginsRoot, out) {
16659
- if (!(0, import_node_fs41.existsSync)(pluginsRoot)) return;
16831
+ if (!(0, import_node_fs43.existsSync)(pluginsRoot)) return;
16660
16832
  const walk = (dir, depth, lookingForSkillsDir) => {
16661
16833
  if (depth > 7) return;
16662
16834
  let entries;
16663
16835
  try {
16664
- entries = (0, import_node_fs41.readdirSync)(dir);
16836
+ entries = (0, import_node_fs43.readdirSync)(dir);
16665
16837
  } catch {
16666
16838
  return;
16667
16839
  }
16668
16840
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
16669
- const skill = readSkill((0, import_node_path38.join)(dir, "SKILL.md"), "cli");
16841
+ const skill = readSkill((0, import_node_path40.join)(dir, "SKILL.md"), "cli");
16670
16842
  if (skill) out.push(skill);
16671
16843
  }
16672
16844
  for (const entry of entries) {
16673
16845
  if (entry === "node_modules" || entry === ".git") continue;
16674
- const full = (0, import_node_path38.join)(dir, entry);
16846
+ const full = (0, import_node_path40.join)(dir, entry);
16675
16847
  try {
16676
- if (!(0, import_node_fs41.statSync)(full).isDirectory()) continue;
16848
+ if (!(0, import_node_fs43.statSync)(full).isDirectory()) continue;
16677
16849
  } catch {
16678
16850
  continue;
16679
16851
  }
@@ -16688,20 +16860,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
16688
16860
  walk(pluginsRoot, 0, false);
16689
16861
  }
16690
16862
  function discoverSkills(worktreePath) {
16691
- const home = (0, import_node_os12.homedir)();
16863
+ const home = (0, import_node_os14.homedir)();
16692
16864
  const collected = [];
16693
16865
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
16694
- scanSkillsDir((0, import_node_path38.join)(worktreePath, rel), "workspace", collected);
16866
+ scanSkillsDir((0, import_node_path40.join)(worktreePath, rel), "workspace", collected);
16695
16867
  }
16696
16868
  for (const abs of [
16697
- (0, import_node_path38.join)(home, ".claude/skills"),
16698
- (0, import_node_path38.join)(home, ".cursor/skills"),
16699
- (0, import_node_path38.join)(home, ".sideboard/skills"),
16700
- (0, import_node_path38.join)(home, ".brightsy/skills")
16869
+ (0, import_node_path40.join)(home, ".claude/skills"),
16870
+ (0, import_node_path40.join)(home, ".cursor/skills"),
16871
+ (0, import_node_path40.join)(home, ".sideboard/skills"),
16872
+ (0, import_node_path40.join)(home, ".brightsy/skills")
16701
16873
  ]) {
16702
16874
  scanSkillsDir(abs, "user", collected);
16703
16875
  }
16704
- scanClaudePluginSkills((0, import_node_path38.join)(home, ".claude/plugins"), collected);
16876
+ scanClaudePluginSkills((0, import_node_path40.join)(home, ".claude/plugins"), collected);
16705
16877
  collected.push(...bundledSkills());
16706
16878
  const rank = {
16707
16879
  workspace: 0,
@@ -16727,7 +16899,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
16727
16899
  \u2026(truncated)` : body;
16728
16900
  }
16729
16901
  }
16730
- const raw = (0, import_node_fs41.readFileSync)(skillPath, "utf8");
16902
+ const raw = (0, import_node_fs43.readFileSync)(skillPath, "utf8");
16731
16903
  if (raw.startsWith("---")) {
16732
16904
  const end = raw.indexOf("\n---", 3);
16733
16905
  if (end >= 0) {
@@ -16741,13 +16913,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
16741
16913
 
16742
16914
  \u2026(truncated)` : raw;
16743
16915
  }
16744
- var import_node_fs41, import_node_os12, import_node_path38, BUNDLED_SKILL_PREFIX;
16916
+ var import_node_fs43, import_node_os14, import_node_path40, BUNDLED_SKILL_PREFIX;
16745
16917
  var init_discover = __esm({
16746
16918
  "src/skills/discover.ts"() {
16747
16919
  "use strict";
16748
- import_node_fs41 = require("fs");
16749
- import_node_os12 = require("os");
16750
- import_node_path38 = require("path");
16920
+ import_node_fs43 = require("fs");
16921
+ import_node_os14 = require("os");
16922
+ import_node_path40 = require("path");
16751
16923
  init_long_running();
16752
16924
  BUNDLED_SKILL_PREFIX = "bundled:";
16753
16925
  }
@@ -16842,17 +17014,17 @@ var init_expand = __esm({
16842
17014
  function packagedDetachedJobPath() {
16843
17015
  const dir = packagedMcpDir();
16844
17016
  if (!dir) return null;
16845
- const script = (0, import_node_path39.join)(dir, "scripts", "detached-job.js");
16846
- return (0, import_node_fs42.existsSync)(script) ? script : null;
17017
+ const script = (0, import_node_path41.join)(dir, "scripts", "detached-job.js");
17018
+ return (0, import_node_fs44.existsSync)(script) ? script : null;
16847
17019
  }
16848
17020
  function resolveDetachedJobScript() {
16849
17021
  const packaged = packagedDetachedJobPath();
16850
17022
  if (packaged) return packaged;
16851
- let dir = (0, import_node_path39.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
17023
+ let dir = (0, import_node_path41.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
16852
17024
  for (let i = 0; i < 8; i++) {
16853
- const candidate = (0, import_node_path39.join)(dir, "scripts", "detached-job.js");
16854
- if ((0, import_node_fs42.existsSync)(candidate)) return candidate;
16855
- const parent = (0, import_node_path39.dirname)(dir);
17025
+ const candidate = (0, import_node_path41.join)(dir, "scripts", "detached-job.js");
17026
+ if ((0, import_node_fs44.existsSync)(candidate)) return candidate;
17027
+ const parent = (0, import_node_path41.dirname)(dir);
16856
17028
  if (parent === dir) break;
16857
17029
  dir = parent;
16858
17030
  }
@@ -16863,12 +17035,12 @@ function formatDetachedJobInvoke(scriptPath) {
16863
17035
  if (resolved) return `node ${JSON.stringify(resolved)}`;
16864
17036
  return "node scripts/detached-job.js";
16865
17037
  }
16866
- var import_node_fs42, import_node_path39, import_node_url3, import_meta3;
17038
+ var import_node_fs44, import_node_path41, import_node_url3, import_meta3;
16867
17039
  var init_detached_job_path = __esm({
16868
17040
  "src/skills/detached-job-path.ts"() {
16869
17041
  "use strict";
16870
- import_node_fs42 = require("fs");
16871
- import_node_path39 = require("path");
17042
+ import_node_fs44 = require("fs");
17043
+ import_node_path41 = require("path");
16872
17044
  import_node_url3 = require("url");
16873
17045
  init_packaged_runtime();
16874
17046
  import_meta3 = {};
@@ -17046,12 +17218,12 @@ function formatArtifactDirective() {
17046
17218
  function formatUiReminder() {
17047
17219
  return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
17048
17220
  }
17049
- var import_node_fs43, import_node_path40;
17221
+ var import_node_fs45, import_node_path42;
17050
17222
  var init_instructions = __esm({
17051
17223
  "src/agents/instructions.ts"() {
17052
17224
  "use strict";
17053
- import_node_fs43 = require("fs");
17054
- import_node_path40 = require("path");
17225
+ import_node_fs45 = require("fs");
17226
+ import_node_path42 = require("path");
17055
17227
  init_git_auth_mode();
17056
17228
  init_worktree_labels();
17057
17229
  init_detached_job_path();
@@ -17221,40 +17393,40 @@ __export(plan_file_exports, {
17221
17393
  writePlanFile: () => writePlanFile
17222
17394
  });
17223
17395
  function ensureAttachmentsGitignore(worktreePath) {
17224
- const gitignoreAbs = (0, import_node_path41.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
17225
- if ((0, import_node_fs44.existsSync)(gitignoreAbs)) return;
17226
- (0, import_node_fs44.mkdirSync)((0, import_node_path41.dirname)(gitignoreAbs), { recursive: true });
17227
- (0, import_node_fs44.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
17396
+ const gitignoreAbs = (0, import_node_path43.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
17397
+ if ((0, import_node_fs46.existsSync)(gitignoreAbs)) return;
17398
+ (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(gitignoreAbs), { recursive: true });
17399
+ (0, import_node_fs46.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
17228
17400
  }
17229
17401
  function planFileAbs(worktreePath) {
17230
- return (0, import_node_path41.join)(worktreePath, PLAN_FILE_REL);
17402
+ return (0, import_node_path43.join)(worktreePath, PLAN_FILE_REL);
17231
17403
  }
17232
17404
  function readTextIfPresent2(abs) {
17233
- if (!(0, import_node_fs44.existsSync)(abs)) return null;
17405
+ if (!(0, import_node_fs46.existsSync)(abs)) return null;
17234
17406
  try {
17235
- const content = (0, import_node_fs44.readFileSync)(abs, "utf8");
17407
+ const content = (0, import_node_fs46.readFileSync)(abs, "utf8");
17236
17408
  return content.trim() ? content : null;
17237
17409
  } catch {
17238
17410
  return null;
17239
17411
  }
17240
17412
  }
17241
17413
  function readPlanFile(worktreePath) {
17242
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path41.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path41.join)(worktreePath, LEGACY_PLAN_FILE_REL));
17414
+ 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));
17243
17415
  }
17244
17416
  function writePlanFile(worktreePath, content) {
17245
17417
  ensureAttachmentsGitignore(worktreePath);
17246
17418
  const abs = planFileAbs(worktreePath);
17247
- (0, import_node_fs44.mkdirSync)((0, import_node_path41.dirname)(abs), { recursive: true });
17419
+ (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
17248
17420
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
17249
- (0, import_node_fs44.writeFileSync)(abs, body, "utf8");
17421
+ (0, import_node_fs46.writeFileSync)(abs, body, "utf8");
17250
17422
  return PLAN_FILE_REL;
17251
17423
  }
17252
- var import_node_fs44, import_node_path41;
17424
+ var import_node_fs46, import_node_path43;
17253
17425
  var init_plan_file = __esm({
17254
17426
  "src/plan/plan-file.ts"() {
17255
17427
  "use strict";
17256
- import_node_fs44 = require("fs");
17257
- import_node_path41 = require("path");
17428
+ import_node_fs46 = require("fs");
17429
+ import_node_path43 = require("path");
17258
17430
  init_workspace_scratch();
17259
17431
  init_plan_present();
17260
17432
  init_plan_present();
@@ -17314,7 +17486,7 @@ function setCaffeinateHoldHooks(next) {
17314
17486
  hooks = next;
17315
17487
  }
17316
17488
  function caffeinateHoldPath() {
17317
- return (0, import_node_path42.join)(appDataDir(), "caffeinate-hold.json");
17489
+ return (0, import_node_path44.join)(appDataDir(), "caffeinate-hold.json");
17318
17490
  }
17319
17491
  function processAlive(pid) {
17320
17492
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -17348,9 +17520,9 @@ function uniqueIds(ids) {
17348
17520
  }
17349
17521
  function readHold() {
17350
17522
  const path = caffeinateHoldPath();
17351
- if (!(0, import_node_fs45.existsSync)(path)) return null;
17523
+ if (!(0, import_node_fs47.existsSync)(path)) return null;
17352
17524
  try {
17353
- const parsed = JSON.parse((0, import_node_fs45.readFileSync)(path, "utf8"));
17525
+ const parsed = JSON.parse((0, import_node_fs47.readFileSync)(path, "utf8"));
17354
17526
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
17355
17527
  return {
17356
17528
  pid: parsed.pid,
@@ -17372,7 +17544,7 @@ function writeHold(pid, threadIds) {
17372
17544
  }
17373
17545
  function clearHold() {
17374
17546
  try {
17375
- (0, import_node_fs45.unlinkSync)(caffeinateHoldPath());
17547
+ (0, import_node_fs47.unlinkSync)(caffeinateHoldPath());
17376
17548
  } catch {
17377
17549
  }
17378
17550
  }
@@ -17457,13 +17629,13 @@ function releaseCaffeinateHoldForThread(threadId) {
17457
17629
  }
17458
17630
  return setCaffeinateHold(false, { threadId: id });
17459
17631
  }
17460
- var import_node_child_process4, import_node_fs45, import_node_path42, hooks;
17632
+ var import_node_child_process4, import_node_fs47, import_node_path44, hooks;
17461
17633
  var init_caffeinate_hold = __esm({
17462
17634
  "src/store/caffeinate-hold.ts"() {
17463
17635
  "use strict";
17464
17636
  import_node_child_process4 = require("child_process");
17465
- import_node_fs45 = require("fs");
17466
- import_node_path42 = require("path");
17637
+ import_node_fs47 = require("fs");
17638
+ import_node_path44 = require("path");
17467
17639
  init_paths();
17468
17640
  init_private_file();
17469
17641
  hooks = {};
@@ -17472,7 +17644,7 @@ var init_caffeinate_hold = __esm({
17472
17644
 
17473
17645
  // src/store/schedules.ts
17474
17646
  function schedulesPath() {
17475
- return (0, import_node_path43.join)(appDataDir(), "schedules.json");
17647
+ return (0, import_node_path45.join)(appDataDir(), "schedules.json");
17476
17648
  }
17477
17649
  function parseDurationMs(every) {
17478
17650
  const m = every.trim().match(DURATION_RE);
@@ -17572,9 +17744,9 @@ function normalizeTask(raw) {
17572
17744
  }
17573
17745
  function readAll2() {
17574
17746
  const path = schedulesPath();
17575
- if (!(0, import_node_fs46.existsSync)(path)) return [];
17747
+ if (!(0, import_node_fs48.existsSync)(path)) return [];
17576
17748
  try {
17577
- const parsed = JSON.parse((0, import_node_fs46.readFileSync)(path, "utf8"));
17749
+ const parsed = JSON.parse((0, import_node_fs48.readFileSync)(path, "utf8"));
17578
17750
  if (!Array.isArray(parsed)) return [];
17579
17751
  return parsed.map((row) => {
17580
17752
  try {
@@ -17686,13 +17858,13 @@ function recordScheduleRun(id, result) {
17686
17858
  writeAll2(rows);
17687
17859
  return next;
17688
17860
  }
17689
- var import_node_crypto9, import_node_fs46, import_node_path43, import_croner, DURATION_RE, UNIT_MS;
17861
+ var import_node_crypto9, import_node_fs48, import_node_path45, import_croner, DURATION_RE, UNIT_MS;
17690
17862
  var init_schedules = __esm({
17691
17863
  "src/store/schedules.ts"() {
17692
17864
  "use strict";
17693
17865
  import_node_crypto9 = require("crypto");
17694
- import_node_fs46 = require("fs");
17695
- import_node_path43 = require("path");
17866
+ import_node_fs48 = require("fs");
17867
+ import_node_path45 = require("path");
17696
17868
  import_croner = require("croner");
17697
17869
  init_orchestrator_capable();
17698
17870
  init_paths();
@@ -17834,13 +18006,13 @@ var init_schedule_runner = __esm({
17834
18006
 
17835
18007
  // src/agents/cursor-store.ts
17836
18008
  function cursorSdkStoreDir(threadId) {
17837
- const root = (0, import_node_path44.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
18009
+ const root = (0, import_node_path46.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
17838
18010
  const id = sanitizeCursorStoreSegment(threadId);
17839
18011
  if (!id) return root;
17840
- return (0, import_node_path44.join)(root, "threads", id);
18012
+ return (0, import_node_path46.join)(root, "threads", id);
17841
18013
  }
17842
18014
  function cursorSdkRunsNdjsonPath(threadId) {
17843
- return (0, import_node_path44.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
18015
+ return (0, import_node_path46.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
17844
18016
  }
17845
18017
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
17846
18018
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -17853,11 +18025,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
17853
18025
  function sanitizeCursorStoreSegment(threadId) {
17854
18026
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
17855
18027
  }
17856
- var import_node_path44, CURSOR_SDK_STORE_DIR;
18028
+ var import_node_path46, CURSOR_SDK_STORE_DIR;
17857
18029
  var init_cursor_store = __esm({
17858
18030
  "src/agents/cursor-store.ts"() {
17859
18031
  "use strict";
17860
- import_node_path44 = require("path");
18032
+ import_node_path46 = require("path");
17861
18033
  init_paths();
17862
18034
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
17863
18035
  }
@@ -17879,9 +18051,9 @@ function recoverFinishedCursorRun(opts) {
17879
18051
  return best;
17880
18052
  }
17881
18053
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
17882
- if (!(0, import_node_fs47.existsSync)(runsPath)) return null;
18054
+ if (!(0, import_node_fs49.existsSync)(runsPath)) return null;
17883
18055
  try {
17884
- const lines = (0, import_node_fs47.readFileSync)(runsPath, "utf8").split("\n");
18056
+ const lines = (0, import_node_fs49.readFileSync)(runsPath, "utf8").split("\n");
17885
18057
  let best = null;
17886
18058
  for (const line of lines) {
17887
18059
  const trimmed = line.trim();
@@ -17907,11 +18079,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
17907
18079
  return null;
17908
18080
  }
17909
18081
  }
17910
- var import_node_fs47;
18082
+ var import_node_fs49;
17911
18083
  var init_cursor_recover = __esm({
17912
18084
  "src/agents/cursor-recover.ts"() {
17913
18085
  "use strict";
17914
- import_node_fs47 = require("fs");
18086
+ import_node_fs49 = require("fs");
17915
18087
  init_cursor_store();
17916
18088
  }
17917
18089
  });
@@ -18043,13 +18215,13 @@ async function startOrchestration(opts) {
18043
18215
  }
18044
18216
  return updated;
18045
18217
  }
18046
- var import_node_events, import_node_fs48, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
18218
+ var import_node_events, import_node_fs50, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
18047
18219
  var init_orchestrator = __esm({
18048
18220
  "src/orchestrator/orchestrator.ts"() {
18049
18221
  "use strict";
18050
18222
  import_node_events = require("events");
18051
18223
  init_outbound_watch();
18052
- import_node_fs48 = require("fs");
18224
+ import_node_fs50 = require("fs");
18053
18225
  init_error_detail();
18054
18226
  init_run();
18055
18227
  init_stale_lock();
@@ -18217,7 +18389,7 @@ var init_orchestrator = __esm({
18217
18389
  }
18218
18390
  continue;
18219
18391
  }
18220
- if (!(0, import_node_fs48.existsSync)(thread.worktreePath)) {
18392
+ if (!(0, import_node_fs50.existsSync)(thread.worktreePath)) {
18221
18393
  setStatus(thread.id, "broken", "Worktree missing on disk");
18222
18394
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
18223
18395
  continue;
@@ -18487,21 +18659,11 @@ var init_orchestrator = __esm({
18487
18659
  /** Run workspace setup after a new worktree is created (no-op if none configured). */
18488
18660
  async runSetupAfterCreate(threadId) {
18489
18661
  try {
18490
- await this.runSetup(threadId);
18662
+ await this.runSetup(threadId, { stampLastError: false });
18491
18663
  } catch (err) {
18492
18664
  const message = err instanceof Error ? err.message : String(err);
18493
18665
  if (/no setup script/i.test(message)) return;
18494
18666
  if (/already running/i.test(message)) return;
18495
- const live = readThread(threadId);
18496
- if (!shouldStampSetupLastError({
18497
- turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
18498
- status: live?.status
18499
- })) {
18500
- return;
18501
- }
18502
- updateThread(threadId, {
18503
- lastError: `Setup failed: ${message}`
18504
- });
18505
18667
  }
18506
18668
  }
18507
18669
  listWorkspaces() {
@@ -19289,7 +19451,7 @@ var init_orchestrator = __esm({
19289
19451
  }
19290
19452
  return snap;
19291
19453
  }
19292
- async runSetup(threadRef) {
19454
+ async runSetup(threadRef, opts) {
19293
19455
  const thread = this.requireThread(threadRef);
19294
19456
  this.assertNotGlobal(thread, "Setup");
19295
19457
  const key = `${thread.id}:setup`;
@@ -19330,9 +19492,10 @@ var init_orchestrator = __esm({
19330
19492
  }
19331
19493
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
19332
19494
  const live = readThread(thread.id);
19333
- if (shouldStampSetupLastError({
19495
+ if ((opts?.stampLastError ?? true) && shouldStampSetupLastError({
19334
19496
  turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
19335
- status: live?.status
19497
+ status: live?.status,
19498
+ hasQueuedPrompt: Boolean(live?.queue?.length)
19336
19499
  })) {
19337
19500
  updateThread(thread.id, {
19338
19501
  lastError: `Setup exited ${setup.exitCode}`
@@ -20035,7 +20198,7 @@ var init_orchestrator = __esm({
20035
20198
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
20036
20199
  return restored2;
20037
20200
  }
20038
- if (!(0, import_node_fs48.existsSync)(thread.worktreePath)) {
20201
+ if (!(0, import_node_fs50.existsSync)(thread.worktreePath)) {
20039
20202
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
20040
20203
  throw new Error(
20041
20204
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -20118,7 +20281,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
20118
20281
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
20119
20282
  var import_zod5 = require("zod");
20120
20283
  var import_node_crypto12 = require("crypto");
20121
- var import_node_path47 = require("path");
20284
+ var import_node_path49 = require("path");
20122
20285
  init_orchestrator();
20123
20286
  init_worktree();
20124
20287
 
@@ -22019,27 +22182,27 @@ init_gh_errors();
22019
22182
  init_git_auth_mode();
22020
22183
 
22021
22184
  // src/board/load-home-board.ts
22022
- var import_node_fs50 = require("fs");
22023
- var import_node_path46 = require("path");
22185
+ var import_node_fs52 = require("fs");
22186
+ var import_node_path48 = require("path");
22024
22187
  init_worktree();
22025
22188
  init_paths();
22026
22189
 
22027
22190
  // src/board/board-pins.ts
22028
22191
  var import_node_crypto11 = require("crypto");
22029
- var import_node_fs49 = require("fs");
22030
- var import_node_path45 = require("path");
22192
+ var import_node_fs51 = require("fs");
22193
+ var import_node_path47 = require("path");
22031
22194
  init_paths();
22032
22195
  init_home_board();
22033
22196
  var FILE = "home-board-pins.json";
22034
22197
  var VERSION = 1;
22035
22198
  function pinsFile() {
22036
- return (0, import_node_path45.join)(appDataDir(), FILE);
22199
+ return (0, import_node_path47.join)(appDataDir(), FILE);
22037
22200
  }
22038
22201
  function readDisk() {
22039
22202
  const path = pinsFile();
22040
- if (!(0, import_node_fs49.existsSync)(path)) return [];
22203
+ if (!(0, import_node_fs51.existsSync)(path)) return [];
22041
22204
  try {
22042
- const raw = JSON.parse((0, import_node_fs49.readFileSync)(path, "utf8"));
22205
+ const raw = JSON.parse((0, import_node_fs51.readFileSync)(path, "utf8"));
22043
22206
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
22044
22207
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
22045
22208
  } catch {
@@ -22047,8 +22210,8 @@ function readDisk() {
22047
22210
  }
22048
22211
  }
22049
22212
  function writeDisk(items) {
22050
- (0, import_node_fs49.mkdirSync)(appDataDir(), { recursive: true });
22051
- (0, import_node_fs49.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
22213
+ (0, import_node_fs51.mkdirSync)(appDataDir(), { recursive: true });
22214
+ (0, import_node_fs51.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
22052
22215
  }
22053
22216
  function listBoardPins() {
22054
22217
  return readDisk();
@@ -22069,7 +22232,7 @@ function homeBoardWorkspaceKey(workspaces) {
22069
22232
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
22070
22233
  }
22071
22234
  function cacheFile() {
22072
- return (0, import_node_path46.join)(appDataDir(), "home-board-cache.json");
22235
+ return (0, import_node_path48.join)(appDataDir(), "home-board-cache.json");
22073
22236
  }
22074
22237
  function emptyInputs() {
22075
22238
  return {
@@ -22095,9 +22258,9 @@ function shouldCacheHomeBoardInputs(inputs) {
22095
22258
  }
22096
22259
  function readDiskCache() {
22097
22260
  const path = cacheFile();
22098
- if (!(0, import_node_fs50.existsSync)(path)) return null;
22261
+ if (!(0, import_node_fs52.existsSync)(path)) return null;
22099
22262
  try {
22100
- const raw = JSON.parse((0, import_node_fs50.readFileSync)(path, "utf8"));
22263
+ const raw = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
22101
22264
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
22102
22265
  return null;
22103
22266
  }
@@ -22111,8 +22274,8 @@ function readDiskCache() {
22111
22274
  }
22112
22275
  function writeDiskCache(entry) {
22113
22276
  try {
22114
- (0, import_node_fs50.mkdirSync)(appDataDir(), { recursive: true });
22115
- (0, import_node_fs50.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
22277
+ (0, import_node_fs52.mkdirSync)(appDataDir(), { recursive: true });
22278
+ (0, import_node_fs52.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
22116
22279
  } catch {
22117
22280
  }
22118
22281
  }
@@ -22408,7 +22571,7 @@ async function startMcpServer() {
22408
22571
  async () => {
22409
22572
  const threads = orch.getThreads(true);
22410
22573
  const lines = threads.map((t) => {
22411
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path47.basename)(t.repoPath) || t.repoPath;
22574
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path49.basename)(t.repoPath) || t.repoPath;
22412
22575
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
22413
22576
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
22414
22577
  const preview = lastMessagePreview(t.messages, 80);