@sideboard-ai/core 0.1.97 → 0.1.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3072,23 +3072,23 @@ var init_gh_errors = __esm({
3072
3072
  function githubAgentAuthDir() {
3073
3073
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
3074
3074
  if (override) return override;
3075
- return (0, import_node_path10.join)((0, import_node_os4.homedir)(), ".sideboard-git-auth");
3075
+ return (0, import_node_path11.join)((0, import_node_os4.homedir)(), ".sideboard-git-auth");
3076
3076
  }
3077
3077
  function githubCredentialStorePath() {
3078
- return (0, import_node_path10.join)(githubAgentAuthDir(), "git-credentials");
3078
+ return (0, import_node_path11.join)(githubAgentAuthDir(), "git-credentials");
3079
3079
  }
3080
3080
  function githubGhConfigDir() {
3081
- return (0, import_node_path10.join)(githubAgentAuthDir(), "gh");
3081
+ return (0, import_node_path11.join)(githubAgentAuthDir(), "gh");
3082
3082
  }
3083
3083
  function writePrivateFile2(file, body) {
3084
- (0, import_node_fs10.mkdirSync)((0, import_node_path10.dirname)(file), { recursive: true, mode: 448 });
3084
+ (0, import_node_fs11.mkdirSync)((0, import_node_path11.dirname)(file), { recursive: true, mode: 448 });
3085
3085
  try {
3086
- (0, import_node_fs10.chmodSync)((0, import_node_path10.dirname)(file), 448);
3086
+ (0, import_node_fs11.chmodSync)((0, import_node_path11.dirname)(file), 448);
3087
3087
  } catch {
3088
3088
  }
3089
- (0, import_node_fs10.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
3089
+ (0, import_node_fs11.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
3090
3090
  try {
3091
- (0, import_node_fs10.chmodSync)(file, 384);
3091
+ (0, import_node_fs11.chmodSync)(file, 384);
3092
3092
  } catch {
3093
3093
  }
3094
3094
  }
@@ -3113,19 +3113,19 @@ function materializeGithubAgentAuth(token, user) {
3113
3113
  const trimmed = token.trim();
3114
3114
  if (!trimmed) return;
3115
3115
  const root = githubAgentAuthDir();
3116
- (0, import_node_fs10.mkdirSync)(root, { recursive: true, mode: 448 });
3116
+ (0, import_node_fs11.mkdirSync)(root, { recursive: true, mode: 448 });
3117
3117
  try {
3118
- (0, import_node_fs10.chmodSync)(root, 448);
3118
+ (0, import_node_fs11.chmodSync)(root, 448);
3119
3119
  } catch {
3120
3120
  }
3121
3121
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
3122
3122
  const ghDir = githubGhConfigDir();
3123
- (0, import_node_fs10.mkdirSync)(ghDir, { recursive: true, mode: 448 });
3124
- writePrivateFile2((0, import_node_path10.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
3125
- writePrivateFile2((0, import_node_path10.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
3123
+ (0, import_node_fs11.mkdirSync)(ghDir, { recursive: true, mode: 448 });
3124
+ writePrivateFile2((0, import_node_path11.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
3125
+ writePrivateFile2((0, import_node_path11.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
3126
3126
  }
3127
3127
  function githubAgentAuthReady() {
3128
- return (0, import_node_fs10.existsSync)(githubCredentialStorePath()) && (0, import_node_fs10.existsSync)((0, import_node_path10.join)(githubGhConfigDir(), "hosts.yml"));
3128
+ return (0, import_node_fs11.existsSync)(githubCredentialStorePath()) && (0, import_node_fs11.existsSync)((0, import_node_path11.join)(githubGhConfigDir(), "hosts.yml"));
3129
3129
  }
3130
3130
  function githubCredentialHelperGitConfig() {
3131
3131
  const file = githubCredentialStorePath();
@@ -3140,29 +3140,29 @@ function githubGhConfigEnv() {
3140
3140
  GH_PROMPT_DISABLED: "1"
3141
3141
  };
3142
3142
  }
3143
- var import_node_fs10, import_node_os4, import_node_path10;
3143
+ var import_node_fs11, import_node_os4, import_node_path11;
3144
3144
  var init_github_agent_auth = __esm({
3145
3145
  "src/git/github-agent-auth.ts"() {
3146
3146
  "use strict";
3147
- import_node_fs10 = require("fs");
3147
+ import_node_fs11 = require("fs");
3148
3148
  import_node_os4 = require("os");
3149
- import_node_path10 = require("path");
3149
+ import_node_path11 = require("path");
3150
3150
  }
3151
3151
  });
3152
3152
 
3153
3153
  // src/agents/path.ts
3154
3154
  function prependPathDir(env, dir) {
3155
- if (!dir || !(0, import_node_fs11.existsSync)(dir)) return;
3155
+ if (!dir || !(0, import_node_fs12.existsSync)(dir)) return;
3156
3156
  const current = env.PATH ?? "";
3157
- const parts = current.split(import_node_path11.delimiter).filter(Boolean);
3157
+ const parts = current.split(import_node_path12.delimiter).filter(Boolean);
3158
3158
  if (parts.includes(dir)) {
3159
3159
  env.PATH = current;
3160
3160
  return;
3161
3161
  }
3162
- env.PATH = [dir, ...parts].join(import_node_path11.delimiter);
3162
+ env.PATH = [dir, ...parts].join(import_node_path12.delimiter);
3163
3163
  }
3164
3164
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os5.homedir)()) {
3165
- return (0, import_node_path11.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
3165
+ return (0, import_node_path12.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
3166
3166
  }
3167
3167
  function isConductorBundledCli(filePath) {
3168
3168
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -3171,21 +3171,21 @@ function isConductorBundledCli(filePath) {
3171
3171
  function ensureAgentPath(env = process.env) {
3172
3172
  const home = env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)();
3173
3173
  const current = env.PATH ?? "";
3174
- const parts = current.split(import_node_path11.delimiter).filter(Boolean);
3174
+ const parts = current.split(import_node_path12.delimiter).filter(Boolean);
3175
3175
  const seen = new Set(parts);
3176
3176
  const extras = [
3177
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path11.join)(home, rel)),
3177
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path12.join)(home, rel)),
3178
3178
  "/opt/homebrew/bin",
3179
3179
  "/usr/local/bin",
3180
3180
  // Keep after Homebrew/npm so a user-installed CLI still wins.
3181
3181
  conductorBundledBinDir(home)
3182
3182
  ];
3183
3183
  for (const dir of extras.reverse()) {
3184
- if (!dir || seen.has(dir) || !(0, import_node_fs11.existsSync)(dir)) continue;
3184
+ if (!dir || seen.has(dir) || !(0, import_node_fs12.existsSync)(dir)) continue;
3185
3185
  parts.unshift(dir);
3186
3186
  seen.add(dir);
3187
3187
  }
3188
- const next = parts.join(import_node_path11.delimiter);
3188
+ const next = parts.join(import_node_path12.delimiter);
3189
3189
  env.PATH = next;
3190
3190
  return next;
3191
3191
  }
@@ -3199,7 +3199,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
3199
3199
  stdio: ["ignore", "pipe", "ignore"]
3200
3200
  }).trim().split(/\r?\n/).find(Boolean);
3201
3201
  if (prefix) {
3202
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path11.join)(prefix, "bin");
3202
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path12.join)(prefix, "bin");
3203
3203
  prependPathDir(env, binDir);
3204
3204
  }
3205
3205
  } catch {
@@ -3227,14 +3227,14 @@ function withExportedPath(command, pathValue) {
3227
3227
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
3228
3228
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
3229
3229
  }
3230
- var import_node_fs11, import_node_child_process3, import_node_os5, import_node_path11, EXTRA_BIN_DIRS;
3230
+ var import_node_fs12, import_node_child_process3, import_node_os5, import_node_path12, EXTRA_BIN_DIRS;
3231
3231
  var init_path = __esm({
3232
3232
  "src/agents/path.ts"() {
3233
3233
  "use strict";
3234
- import_node_fs11 = require("fs");
3234
+ import_node_fs12 = require("fs");
3235
3235
  import_node_child_process3 = require("child_process");
3236
3236
  import_node_os5 = require("os");
3237
- import_node_path11 = require("path");
3237
+ import_node_path12 = require("path");
3238
3238
  EXTRA_BIN_DIRS = [
3239
3239
  ".local/bin",
3240
3240
  ".cargo/bin",
@@ -3426,7 +3426,7 @@ async function warmGithubAgentAuth(opts) {
3426
3426
  }
3427
3427
  function normalizeWritableRoot(raw) {
3428
3428
  const trimmed = raw.trim().replace(/\/+$/, "");
3429
- return trimmed && (0, import_node_path12.isAbsolute)(trimmed) ? trimmed : null;
3429
+ return trimmed && (0, import_node_path13.isAbsolute)(trimmed) ? trimmed : null;
3430
3430
  }
3431
3431
  async function resolveCodexGitWritableRoots(cwd) {
3432
3432
  const roots = /* @__PURE__ */ new Set();
@@ -3503,11 +3503,11 @@ function formatGitAuthModeDirective(mode) {
3503
3503
  ].join("\n");
3504
3504
  }
3505
3505
  }
3506
- var import_node_path12, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
3506
+ var import_node_path13, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
3507
3507
  var init_git_auth_mode = __esm({
3508
3508
  "src/git/git-auth-mode.ts"() {
3509
3509
  "use strict";
3510
- import_node_path12 = require("path");
3510
+ import_node_path13 = require("path");
3511
3511
  init_app_settings();
3512
3512
  init_github_agent_auth();
3513
3513
  init_run();
@@ -4669,8 +4669,8 @@ function isLocalPrFetchBranch(ref) {
4669
4669
  }
4670
4670
  async function createThreadWorktree(opts) {
4671
4671
  let branchName = `thread/${opts.slug}`;
4672
- const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
4673
- if ((0, import_node_fs12.existsSync)(worktreePath)) {
4672
+ const worktreePath = (0, import_node_path14.join)(worktreesRoot(opts.repoPath), opts.slug);
4673
+ if ((0, import_node_fs13.existsSync)(worktreePath)) {
4674
4674
  throw new Error(`Worktree already exists at ${worktreePath}`);
4675
4675
  }
4676
4676
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4739,8 +4739,8 @@ ${add.stdout}`;
4739
4739
  async function createExistingBranchWorktree(opts) {
4740
4740
  const branchName = opts.branchName.trim();
4741
4741
  if (!branchName) throw new Error("branch name required");
4742
- const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
4743
- if ((0, import_node_fs12.existsSync)(worktreePath)) {
4742
+ const worktreePath = (0, import_node_path14.join)(worktreesRoot(opts.repoPath), opts.slug);
4743
+ if ((0, import_node_fs13.existsSync)(worktreePath)) {
4744
4744
  throw new Error(`Worktree already exists at ${worktreePath}`);
4745
4745
  }
4746
4746
  await ensureGhPreferOrigin(opts.repoPath);
@@ -5028,10 +5028,10 @@ function sameRepoPath(a, b) {
5028
5028
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
5029
5029
  }
5030
5030
  function listLocalThreadBranchSlugs(repoPath) {
5031
- const refsDir = (0, import_node_path13.join)(repoPath, ".git", "refs", "heads", "thread");
5032
- if (!(0, import_node_fs12.existsSync)(refsDir)) return [];
5031
+ const refsDir = (0, import_node_path14.join)(repoPath, ".git", "refs", "heads", "thread");
5032
+ if (!(0, import_node_fs13.existsSync)(refsDir)) return [];
5033
5033
  try {
5034
- return (0, import_node_fs12.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
5034
+ return (0, import_node_fs13.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
5035
5035
  } catch {
5036
5036
  return [];
5037
5037
  }
@@ -5039,8 +5039,8 @@ function listLocalThreadBranchSlugs(repoPath) {
5039
5039
  function collectTakenTeamSlugs(repoPath) {
5040
5040
  const taken = /* @__PURE__ */ new Set();
5041
5041
  const root = worktreesRoot(repoPath);
5042
- if ((0, import_node_fs12.existsSync)(root)) {
5043
- for (const entry of (0, import_node_fs12.readdirSync)(root, { withFileTypes: true })) {
5042
+ if ((0, import_node_fs13.existsSync)(root)) {
5043
+ for (const entry of (0, import_node_fs13.readdirSync)(root, { withFileTypes: true })) {
5044
5044
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
5045
5045
  taken.add(normalizeTakenSlug(entry.name));
5046
5046
  }
@@ -5061,18 +5061,18 @@ function allocateTeamSlug(repoPath) {
5061
5061
  const taken = collectTakenTeamSlugs(repoPath);
5062
5062
  for (let attempt = 0; attempt < 32; attempt++) {
5063
5063
  const team = allocateTeamName(taken);
5064
- const path2 = (0, import_node_path13.join)(worktreesRoot(repoPath), team.slug);
5065
- if (!(0, import_node_fs12.existsSync)(path2)) return team;
5064
+ const path2 = (0, import_node_path14.join)(worktreesRoot(repoPath), team.slug);
5065
+ if (!(0, import_node_fs13.existsSync)(path2)) return team;
5066
5066
  taken.add(team.slug);
5067
5067
  }
5068
5068
  throw new Error("No available soccer team worktree directories left");
5069
5069
  }
5070
- var import_node_fs12, import_node_path13;
5070
+ var import_node_fs13, import_node_path14;
5071
5071
  var init_worktree = __esm({
5072
5072
  "src/git/worktree.ts"() {
5073
5073
  "use strict";
5074
- import_node_fs12 = require("fs");
5075
- import_node_path13 = require("path");
5074
+ import_node_fs13 = require("fs");
5075
+ import_node_path14 = require("path");
5076
5076
  init_paths();
5077
5077
  init_thread_store();
5078
5078
  init_teams();
@@ -5156,7 +5156,7 @@ function coordinatorTurnReminder(opts) {
5156
5156
  function ensureGlobalCoordinatorCwd(opts) {
5157
5157
  const dir = globalAgentCwd();
5158
5158
  try {
5159
- (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
5159
+ (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
5160
5160
  } catch {
5161
5161
  return dir;
5162
5162
  }
@@ -5164,7 +5164,7 @@ function ensureGlobalCoordinatorCwd(opts) {
5164
5164
  let orchId = opts?.orchestratorThreadId?.trim() || "";
5165
5165
  if (!orchId) {
5166
5166
  try {
5167
- const existing = (0, import_node_fs13.readFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), "utf8");
5167
+ const existing = (0, import_node_fs14.readFileSync)((0, import_node_path15.join)(dir, "AGENTS.md"), "utf8");
5168
5168
  const m = existing.match(
5169
5169
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
5170
5170
  );
@@ -5206,9 +5206,9 @@ function ensureGlobalCoordinatorCwd(opts) {
5206
5206
  "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
5207
5207
  ].join("\n");
5208
5208
  try {
5209
- (0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "CLAUDE.md"), `${body}
5209
+ (0, import_node_fs14.writeFileSync)((0, import_node_path15.join)(dir, "CLAUDE.md"), `${body}
5210
5210
  `, "utf8");
5211
- (0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), `${body}
5211
+ (0, import_node_fs14.writeFileSync)((0, import_node_path15.join)(dir, "AGENTS.md"), `${body}
5212
5212
  `, "utf8");
5213
5213
  } catch {
5214
5214
  }
@@ -5240,12 +5240,12 @@ function coordinatorSystemPrompt(opts) {
5240
5240
  formatWorkspaceInventory(opts.workspaces)
5241
5241
  ].join("\n");
5242
5242
  }
5243
- var import_node_fs13, import_node_path14, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5243
+ var import_node_fs14, import_node_path15, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5244
5244
  var init_coordinator_prompt = __esm({
5245
5245
  "src/orchestrator/coordinator-prompt.ts"() {
5246
5246
  "use strict";
5247
- import_node_fs13 = require("fs");
5248
- import_node_path14 = require("path");
5247
+ import_node_fs14 = require("fs");
5248
+ import_node_path15 = require("path");
5249
5249
  init_worktree();
5250
5250
  init_app_settings();
5251
5251
  init_paths();
@@ -5307,6 +5307,7 @@ __export(global_workspace_exports, {
5307
5307
  createGlobalChat: () => createGlobalChat,
5308
5308
  ensureCloudCoordinator: () => ensureCloudCoordinator,
5309
5309
  ensureSlackCoordinator: () => ensureSlackCoordinator,
5310
+ findSlackCoordinator: () => findSlackCoordinator,
5310
5311
  globalAgentCwd: () => globalAgentCwd,
5311
5312
  healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
5312
5313
  isCloudCoordinatorThread: () => isCloudCoordinatorThread,
@@ -5453,42 +5454,40 @@ function findSlackCoordinator(teamId, userId) {
5453
5454
  (t) => t.status !== "archived" && t.sourceRef === ref && isSlackCoordinatorThread(t)
5454
5455
  );
5455
5456
  }
5456
- function ensureSlackCoordinator(teamId, userId, agent) {
5457
+ function ensureSlackCoordinator(teamId, userId, agent, opts) {
5457
5458
  const defaults = resolveThreadDefaults();
5458
5459
  const desired = assertOrchestratorCapableAgent(agent);
5459
5460
  const ref = slackCoordinatorSourceRef(teamId, userId);
5460
- const existing = findSlackCoordinator(teamId, userId);
5461
- if (existing) {
5462
- const patch = {};
5463
- if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
5464
- patch.repoPath = GLOBAL_WORKSPACE_ID;
5465
- patch.worktreePath = globalAgentCwd();
5466
- patch.branchName = "global";
5467
- }
5468
- const hasAgentTurns = existing.messages.some((m) => m.role === "agent");
5469
- const canRetarget = !existing.sessionId && !hasAgentTurns && existing.status !== "running" && existing.status !== "queued";
5470
- if (canRetarget) {
5471
- if (existing.agent !== desired) patch.agent = desired;
5472
- if (existing.model !== defaults.model) patch.model = defaults.model;
5473
- if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
5474
- if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
5475
- }
5476
- if (Object.keys(patch).length > 0) {
5477
- return updateThread(existing.id, patch);
5461
+ if (!opts?.forceNew) {
5462
+ const existing = findSlackCoordinator(teamId, userId);
5463
+ if (existing) {
5464
+ const patch = {};
5465
+ if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
5466
+ patch.repoPath = GLOBAL_WORKSPACE_ID;
5467
+ patch.worktreePath = globalAgentCwd();
5468
+ patch.branchName = "global";
5469
+ }
5470
+ const hasAgentTurns = existing.messages.some((m) => m.role === "agent");
5471
+ const canRetarget = !existing.sessionId && !hasAgentTurns && existing.status !== "running" && existing.status !== "queued";
5472
+ if (canRetarget) {
5473
+ if (existing.agent !== desired) patch.agent = desired;
5474
+ if (existing.model !== defaults.model) patch.model = defaults.model;
5475
+ if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
5476
+ if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
5477
+ }
5478
+ if (Object.keys(patch).length > 0) {
5479
+ return updateThread(existing.id, patch);
5480
+ }
5481
+ return existing;
5478
5482
  }
5479
- return existing;
5480
5483
  }
5481
- const created = createGlobalChat({
5484
+ return createGlobalChat({
5482
5485
  sourceRef: ref,
5483
5486
  agent: desired,
5484
5487
  model: defaults.model,
5485
5488
  effort: defaults.effort,
5486
5489
  fast: defaults.fast
5487
5490
  });
5488
- const all = listThreads({ includeArchived: true }).filter(
5489
- (t) => t.status !== "archived" && t.sourceRef === ref && isSlackCoordinatorThread(t)
5490
- ).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
5491
- return all[0] ?? created;
5492
5491
  }
5493
5492
  function ensureCloudCoordinator(agent) {
5494
5493
  const defaults = resolveThreadDefaults();
@@ -5551,38 +5550,38 @@ __export(workspaces_exports, {
5551
5550
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
5552
5551
  });
5553
5552
  function workspacesFile() {
5554
- return (0, import_node_path15.join)(appDataDir(), "workspaces.json");
5553
+ return (0, import_node_path16.join)(appDataDir(), "workspaces.json");
5555
5554
  }
5556
5555
  function removedWorkspacesFile() {
5557
- return (0, import_node_path15.join)(appDataDir(), "removed-workspaces.json");
5556
+ return (0, import_node_path16.join)(appDataDir(), "removed-workspaces.json");
5558
5557
  }
5559
5558
  function readAll() {
5560
5559
  const path2 = workspacesFile();
5561
- if (!(0, import_node_fs14.existsSync)(path2)) return [];
5560
+ if (!(0, import_node_fs15.existsSync)(path2)) return [];
5562
5561
  try {
5563
- const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
5562
+ const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
5564
5563
  return Array.isArray(raw) ? raw : [];
5565
5564
  } catch {
5566
5565
  return [];
5567
5566
  }
5568
5567
  }
5569
5568
  function writeAll(list) {
5570
- (0, import_node_fs14.mkdirSync)(appDataDir(), { recursive: true });
5571
- (0, import_node_fs14.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
5569
+ (0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
5570
+ (0, import_node_fs15.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
5572
5571
  }
5573
5572
  function readRemoved() {
5574
5573
  const path2 = removedWorkspacesFile();
5575
- if (!(0, import_node_fs14.existsSync)(path2)) return /* @__PURE__ */ new Set();
5574
+ if (!(0, import_node_fs15.existsSync)(path2)) return /* @__PURE__ */ new Set();
5576
5575
  try {
5577
- const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
5576
+ const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
5578
5577
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
5579
5578
  } catch {
5580
5579
  return /* @__PURE__ */ new Set();
5581
5580
  }
5582
5581
  }
5583
5582
  function writeRemoved(paths) {
5584
- (0, import_node_fs14.mkdirSync)(appDataDir(), { recursive: true });
5585
- (0, import_node_fs14.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
5583
+ (0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
5584
+ (0, import_node_fs15.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
5586
5585
  }
5587
5586
  function rememberRemoved(repoPath) {
5588
5587
  const next = readRemoved();
@@ -5605,7 +5604,7 @@ function listWorkspaces() {
5605
5604
  async function addWorkspace(repoPath) {
5606
5605
  const root = await resolveRepoRoot(repoPath);
5607
5606
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
5608
- if (!(0, import_node_fs14.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
5607
+ if (!(0, import_node_fs15.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
5609
5608
  forgetRemoved(root);
5610
5609
  await ensureGhPreferOrigin(root);
5611
5610
  const current = readAll();
@@ -5613,7 +5612,7 @@ async function addWorkspace(repoPath) {
5613
5612
  if (existing) return existing;
5614
5613
  const next = {
5615
5614
  path: root,
5616
- name: (0, import_node_path15.basename)(root),
5615
+ name: (0, import_node_path16.basename)(root),
5617
5616
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
5618
5617
  };
5619
5618
  writeAll([...current, next]);
@@ -5635,10 +5634,10 @@ function syncWorkspacesFromThreads(repoPaths) {
5635
5634
  if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
5636
5635
  continue;
5637
5636
  }
5638
- if (!(0, import_node_fs14.existsSync)(path2)) continue;
5637
+ if (!(0, import_node_fs15.existsSync)(path2)) continue;
5639
5638
  const ws = {
5640
5639
  path: path2,
5641
- name: (0, import_node_path15.basename)(path2),
5640
+ name: (0, import_node_path16.basename)(path2),
5642
5641
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
5643
5642
  };
5644
5643
  byPath.set(path2, ws);
@@ -5648,12 +5647,12 @@ function syncWorkspacesFromThreads(repoPaths) {
5648
5647
  if (dirty) writeAll(next);
5649
5648
  return next.sort((a, b) => a.name.localeCompare(b.name));
5650
5649
  }
5651
- var import_node_fs14, import_node_path15;
5650
+ var import_node_fs15, import_node_path16;
5652
5651
  var init_workspaces = __esm({
5653
5652
  "src/store/workspaces.ts"() {
5654
5653
  "use strict";
5655
- import_node_fs14 = require("fs");
5656
- import_node_path15 = require("path");
5654
+ import_node_fs15 = require("fs");
5655
+ import_node_path16 = require("path");
5657
5656
  init_paths();
5658
5657
  init_global_workspace();
5659
5658
  init_worktree();
@@ -5662,32 +5661,32 @@ var init_workspaces = __esm({
5662
5661
 
5663
5662
  // src/brightsy/config.ts
5664
5663
  function brightsyConfigPath() {
5665
- return (0, import_node_path16.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
5664
+ return (0, import_node_path17.join)((0, import_node_os6.homedir)(), ".brightsy", "config.json");
5666
5665
  }
5667
5666
  function loadBrightsyConfig() {
5668
5667
  const path2 = brightsyConfigPath();
5669
- if (!(0, import_node_fs15.existsSync)(path2)) {
5668
+ if (!(0, import_node_fs16.existsSync)(path2)) {
5670
5669
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
5671
5670
  }
5672
- const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
5671
+ const raw = JSON.parse((0, import_node_fs16.readFileSync)(path2, "utf8"));
5673
5672
  if (!raw.access_token || !raw.account_id) {
5674
5673
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
5675
5674
  }
5676
5675
  return raw;
5677
5676
  }
5678
5677
  function saveBrightsyConfig(cfg) {
5679
- (0, import_node_fs15.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5678
+ (0, import_node_fs16.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5680
5679
  `, {
5681
5680
  mode: 384
5682
5681
  });
5683
5682
  }
5684
- var import_node_fs15, import_node_os6, import_node_path16;
5683
+ var import_node_fs16, import_node_os6, import_node_path17;
5685
5684
  var init_config = __esm({
5686
5685
  "src/brightsy/config.ts"() {
5687
5686
  "use strict";
5688
- import_node_fs15 = require("fs");
5687
+ import_node_fs16 = require("fs");
5689
5688
  import_node_os6 = require("os");
5690
- import_node_path16 = require("path");
5689
+ import_node_path17 = require("path");
5691
5690
  }
5692
5691
  });
5693
5692
 
@@ -5790,22 +5789,22 @@ __export(connected_teams_exports, {
5790
5789
  listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
5791
5790
  });
5792
5791
  function storePath() {
5793
- return (0, import_node_path17.join)(appDataDir(), "brightsy-teams.json");
5792
+ return (0, import_node_path18.join)(appDataDir(), "brightsy-teams.json");
5794
5793
  }
5795
5794
  function readStore() {
5796
5795
  const path2 = storePath();
5797
- if (!(0, import_node_fs16.existsSync)(path2)) return [];
5796
+ if (!(0, import_node_fs17.existsSync)(path2)) return [];
5798
5797
  try {
5799
- const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path2, "utf8"));
5798
+ const parsed = JSON.parse((0, import_node_fs17.readFileSync)(path2, "utf8"));
5800
5799
  return Array.isArray(parsed.teams) ? parsed.teams : [];
5801
5800
  } catch {
5802
5801
  return [];
5803
5802
  }
5804
5803
  }
5805
5804
  function writeStore(teams) {
5806
- (0, import_node_fs16.mkdirSync)(appDataDir(), { recursive: true });
5805
+ (0, import_node_fs17.mkdirSync)(appDataDir(), { recursive: true });
5807
5806
  const path2 = storePath();
5808
- (0, import_node_fs16.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
5807
+ (0, import_node_fs17.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
5809
5808
  `, {
5810
5809
  mode: 384
5811
5810
  });
@@ -5967,12 +5966,12 @@ function brightsyMcpServerName(slug) {
5967
5966
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
5968
5967
  return `brightsy_${cleaned || "team"}`;
5969
5968
  }
5970
- var import_node_fs16, import_node_path17;
5969
+ var import_node_fs17, import_node_path18;
5971
5970
  var init_connected_teams = __esm({
5972
5971
  "src/brightsy/connected-teams.ts"() {
5973
5972
  "use strict";
5974
- import_node_fs16 = require("fs");
5975
- import_node_path17 = require("path");
5973
+ import_node_fs17 = require("fs");
5974
+ import_node_path18 = require("path");
5976
5975
  init_paths();
5977
5976
  init_accounts();
5978
5977
  init_config();
@@ -6522,11 +6521,11 @@ async function syncCliForTarget(accountId) {
6522
6521
  }
6523
6522
  applyConnectedTeamToCli(team);
6524
6523
  }
6525
- var import_node_fs17, brightsyAdapter;
6524
+ var import_node_fs18, brightsyAdapter;
6526
6525
  var init_brightsy = __esm({
6527
6526
  "src/agents/brightsy.ts"() {
6528
6527
  "use strict";
6529
- import_node_fs17 = require("fs");
6528
+ import_node_fs18 = require("fs");
6530
6529
  init_run();
6531
6530
  init_connected_teams();
6532
6531
  init_config();
@@ -6541,7 +6540,7 @@ var init_brightsy = __esm({
6541
6540
  async detect() {
6542
6541
  const brightsy = resolveAgentExecutable("brightsy");
6543
6542
  if (brightsy !== "brightsy") {
6544
- if (!(0, import_node_fs17.existsSync)(brightsy)) {
6543
+ if (!(0, import_node_fs18.existsSync)(brightsy)) {
6545
6544
  return {
6546
6545
  agent: "brightsy",
6547
6546
  installed: false,
@@ -6683,7 +6682,7 @@ function unpackedAsarPath(filePath) {
6683
6682
  if (!isAsarPath(filePath)) return null;
6684
6683
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
6685
6684
  if (unpacked === filePath) return null;
6686
- return (0, import_node_fs18.existsSync)(unpacked) ? unpacked : null;
6685
+ return (0, import_node_fs19.existsSync)(unpacked) ? unpacked : null;
6687
6686
  }
6688
6687
  function nodeReadableScriptPath(scriptPath) {
6689
6688
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -6694,11 +6693,11 @@ async function findSystemNode() {
6694
6693
  if (fromWhich && !isElectronLikeCommand(fromWhich)) return fromWhich;
6695
6694
  const fallbacks = [
6696
6695
  ...WELL_KNOWN_NODE_BINS,
6697
- (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".local/share/fnm/aliases/default/bin/node"),
6698
- (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".nvm/current/bin/node")
6696
+ (0, import_node_path19.join)((0, import_node_os7.homedir)(), ".local/share/fnm/aliases/default/bin/node"),
6697
+ (0, import_node_path19.join)((0, import_node_os7.homedir)(), ".nvm/current/bin/node")
6699
6698
  ];
6700
6699
  for (const bin of fallbacks) {
6701
- if ((0, import_node_fs18.existsSync)(bin) && !isElectronLikeCommand(bin)) return bin;
6700
+ if ((0, import_node_fs19.existsSync)(bin) && !isElectronLikeCommand(bin)) return bin;
6702
6701
  }
6703
6702
  return null;
6704
6703
  }
@@ -6728,13 +6727,13 @@ async function resolveNodeLaunch(scriptPath) {
6728
6727
  env: { ELECTRON_RUN_AS_NODE: "1" }
6729
6728
  };
6730
6729
  }
6731
- var import_node_fs18, import_node_os7, import_node_path18, WELL_KNOWN_NODE_BINS;
6730
+ var import_node_fs19, import_node_os7, import_node_path19, WELL_KNOWN_NODE_BINS;
6732
6731
  var init_node_launch = __esm({
6733
6732
  "src/agents/node-launch.ts"() {
6734
6733
  "use strict";
6735
- import_node_fs18 = require("fs");
6734
+ import_node_fs19 = require("fs");
6736
6735
  import_node_os7 = require("os");
6737
- import_node_path18 = require("path");
6736
+ import_node_path19 = require("path");
6738
6737
  init_nested_electron_env();
6739
6738
  init_run();
6740
6739
  WELL_KNOWN_NODE_BINS = [
@@ -6753,36 +6752,36 @@ function electronResourcesPath() {
6753
6752
  function packagedCursorRuntimeDir() {
6754
6753
  const resources = electronResourcesPath();
6755
6754
  if (!resources) return null;
6756
- const dir = (0, import_node_path19.join)(resources, "cursor-runtime");
6757
- if (!(0, import_node_fs19.existsSync)((0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
6755
+ const dir = (0, import_node_path20.join)(resources, "cursor-runtime");
6756
+ if (!(0, import_node_fs20.existsSync)((0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
6758
6757
  return dir;
6759
6758
  }
6760
6759
  function packagedCursorRunnerPath() {
6761
6760
  const dir = packagedCursorRuntimeDir();
6762
- return dir ? (0, import_node_path19.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
6761
+ return dir ? (0, import_node_path20.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
6763
6762
  }
6764
6763
  function packagedMcpDir() {
6765
6764
  const resources = electronResourcesPath();
6766
6765
  if (!resources) return null;
6767
- const dir = (0, import_node_path19.join)(resources, "sideboard-mcp");
6768
- if (!(0, import_node_fs19.existsSync)((0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
6766
+ const dir = (0, import_node_path20.join)(resources, "sideboard-mcp");
6767
+ if (!(0, import_node_fs20.existsSync)((0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
6769
6768
  return dir;
6770
6769
  }
6771
6770
  function packagedMcpStdioPath() {
6772
6771
  const dir = packagedMcpDir();
6773
- return dir ? (0, import_node_path19.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
6772
+ return dir ? (0, import_node_path20.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
6774
6773
  }
6775
6774
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
6776
6775
  const dir = packagedCursorRuntimeDir();
6777
6776
  if (!dir) return null;
6778
- return (0, import_node_path19.join)(dir, "node_modules", platformPkg, "bin", binName);
6777
+ return (0, import_node_path20.join)(dir, "node_modules", platformPkg, "bin", binName);
6779
6778
  }
6780
- var import_node_fs19, import_node_path19;
6779
+ var import_node_fs20, import_node_path20;
6781
6780
  var init_packaged_runtime = __esm({
6782
6781
  "src/agents/packaged-runtime.ts"() {
6783
6782
  "use strict";
6784
- import_node_fs19 = require("fs");
6785
- import_node_path19 = require("path");
6783
+ import_node_fs20 = require("fs");
6784
+ import_node_path20 = require("path");
6786
6785
  }
6787
6786
  });
6788
6787
 
@@ -6869,37 +6868,37 @@ function corePackageDir() {
6869
6868
  try {
6870
6869
  const url = import_meta.url;
6871
6870
  if (typeof url === "string" && url.length > 0) {
6872
- return (0, import_node_path20.dirname)((0, import_node_url.fileURLToPath)(url));
6871
+ return (0, import_node_path21.dirname)((0, import_node_url.fileURLToPath)(url));
6873
6872
  }
6874
6873
  } catch {
6875
6874
  }
6876
6875
  try {
6877
- const req = (0, import_node_module.createRequire)((0, import_node_path20.join)(process.cwd(), "package.json"));
6878
- return (0, import_node_path20.dirname)(req.resolve("@sideboard-ai/core"));
6876
+ const req = (0, import_node_module.createRequire)((0, import_node_path21.join)(process.cwd(), "package.json"));
6877
+ return (0, import_node_path21.dirname)(req.resolve("@sideboard-ai/core"));
6879
6878
  } catch {
6880
6879
  return process.cwd();
6881
6880
  }
6882
6881
  }
6883
6882
  function findSideboardMcpJsEntry() {
6884
6883
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
6885
- if (override && (0, import_node_fs20.existsSync)(override)) return override;
6884
+ if (override && (0, import_node_fs21.existsSync)(override)) return override;
6886
6885
  const packaged = packagedMcpStdioPath();
6887
6886
  if (packaged) return packaged;
6888
6887
  let dir = corePackageDir();
6889
6888
  for (let i = 0; i < 10; i++) {
6890
6889
  const candidates = [
6891
- (0, import_node_path20.join)(dir, "mcp/run-stdio.js"),
6892
- (0, import_node_path20.join)(dir, "mcp/run-stdio.cjs"),
6893
- (0, import_node_path20.join)(dir, "dist/mcp/run-stdio.js"),
6894
- (0, import_node_path20.join)(dir, "dist/mcp/run-stdio.cjs"),
6895
- (0, import_node_path20.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
6896
- (0, import_node_path20.join)(dir, "packages/cli/dist/index.js"),
6897
- (0, import_node_path20.join)(dir, "cli/dist/index.js")
6890
+ (0, import_node_path21.join)(dir, "mcp/run-stdio.js"),
6891
+ (0, import_node_path21.join)(dir, "mcp/run-stdio.cjs"),
6892
+ (0, import_node_path21.join)(dir, "dist/mcp/run-stdio.js"),
6893
+ (0, import_node_path21.join)(dir, "dist/mcp/run-stdio.cjs"),
6894
+ (0, import_node_path21.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
6895
+ (0, import_node_path21.join)(dir, "packages/cli/dist/index.js"),
6896
+ (0, import_node_path21.join)(dir, "cli/dist/index.js")
6898
6897
  ];
6899
6898
  for (const p of candidates) {
6900
- if ((0, import_node_fs20.existsSync)(p) && !isAsarPath(p)) return p;
6899
+ if ((0, import_node_fs21.existsSync)(p) && !isAsarPath(p)) return p;
6901
6900
  }
6902
- const parent = (0, import_node_path20.dirname)(dir);
6901
+ const parent = (0, import_node_path21.dirname)(dir);
6903
6902
  if (parent === dir) break;
6904
6903
  dir = parent;
6905
6904
  }
@@ -7040,22 +7039,22 @@ function writeMcpServersConfig(servers) {
7040
7039
  ...env ? { env } : {}
7041
7040
  };
7042
7041
  }
7043
- const dir = (0, import_node_fs20.mkdtempSync)((0, import_node_path20.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7044
- const cfgPath = (0, import_node_path20.join)(dir, "mcp.json");
7045
- (0, import_node_fs20.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7042
+ const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path21.join)((0, import_node_os8.tmpdir)(), "sideboard-mcp-"));
7043
+ const cfgPath = (0, import_node_path21.join)(dir, "mcp.json");
7044
+ (0, import_node_fs21.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
7046
7045
  return cfgPath;
7047
7046
  }
7048
7047
  async function writeInjectedMcpConfig(opts) {
7049
7048
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
7050
7049
  }
7051
- var import_node_fs20, import_node_module, import_node_os8, import_node_path20, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
7050
+ var import_node_fs21, import_node_module, import_node_os8, import_node_path21, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
7052
7051
  var init_injected_mcp = __esm({
7053
7052
  "src/agents/injected-mcp.ts"() {
7054
7053
  "use strict";
7055
- import_node_fs20 = require("fs");
7054
+ import_node_fs21 = require("fs");
7056
7055
  import_node_module = require("module");
7057
7056
  import_node_os8 = require("os");
7058
- import_node_path20 = require("path");
7057
+ import_node_path21 = require("path");
7059
7058
  import_node_url = require("url");
7060
7059
  init_run();
7061
7060
  init_config();
@@ -7248,11 +7247,11 @@ function parseIssuesJson(raw) {
7248
7247
  }
7249
7248
  return [];
7250
7249
  }
7251
- var import_node_fs21, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
7250
+ var import_node_fs22, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
7252
7251
  var init_claude = __esm({
7253
7252
  "src/agents/claude.ts"() {
7254
7253
  "use strict";
7255
- import_node_fs21 = require("fs");
7254
+ import_node_fs22 = require("fs");
7256
7255
  init_run();
7257
7256
  init_app_settings();
7258
7257
  init_claude_mcp();
@@ -7281,7 +7280,7 @@ var init_claude = __esm({
7281
7280
  async detect() {
7282
7281
  const claude = resolveClaudeExecutable();
7283
7282
  if (claude !== "claude") {
7284
- if (!(0, import_node_fs21.existsSync)(claude)) {
7283
+ if (!(0, import_node_fs22.existsSync)(claude)) {
7285
7284
  return {
7286
7285
  agent: "claude",
7287
7286
  installed: false,
@@ -7518,7 +7517,7 @@ async function listCodexModels() {
7518
7517
  if (codex === "codex") {
7519
7518
  const which = await run("which", ["codex"], { reject: false });
7520
7519
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
7521
- } else if (!(0, import_node_fs22.existsSync)(codex)) {
7520
+ } else if (!(0, import_node_fs23.existsSync)(codex)) {
7522
7521
  return FALLBACK_CODEX_MODELS;
7523
7522
  }
7524
7523
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -7553,12 +7552,12 @@ function usageFromCodex(usage) {
7553
7552
  }
7554
7553
  function codexConfigHasNetworkAccess() {
7555
7554
  const candidates = [
7556
- (0, import_node_path21.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
7557
- (0, import_node_path21.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
7555
+ (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "config.toml"),
7556
+ (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".config", "codex", "config.toml")
7558
7557
  ];
7559
7558
  for (const path2 of candidates) {
7560
- if (!(0, import_node_fs22.existsSync)(path2)) continue;
7561
- const text3 = (0, import_node_fs22.readFileSync)(path2, "utf8");
7559
+ if (!(0, import_node_fs23.existsSync)(path2)) continue;
7560
+ const text3 = (0, import_node_fs23.readFileSync)(path2, "utf8");
7562
7561
  if (/network_access\s*=\s*true/.test(text3)) return true;
7563
7562
  }
7564
7563
  return false;
@@ -7590,21 +7589,21 @@ function asRecord(value) {
7590
7589
  return void 0;
7591
7590
  }
7592
7591
  function codexLooksAuthenticated() {
7593
- const authPath = (0, import_node_path21.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
7594
- if (!(0, import_node_fs22.existsSync)(authPath)) return false;
7592
+ const authPath = (0, import_node_path22.join)((0, import_node_os9.homedir)(), ".codex", "auth.json");
7593
+ if (!(0, import_node_fs23.existsSync)(authPath)) return false;
7595
7594
  try {
7596
- return (0, import_node_fs22.statSync)(authPath).size > 2;
7595
+ return (0, import_node_fs23.statSync)(authPath).size > 2;
7597
7596
  } catch {
7598
7597
  return false;
7599
7598
  }
7600
7599
  }
7601
- var import_node_fs22, import_node_os9, import_node_path21, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
7600
+ var import_node_fs23, import_node_os9, import_node_path22, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
7602
7601
  var init_codex = __esm({
7603
7602
  "src/agents/codex.ts"() {
7604
7603
  "use strict";
7605
- import_node_fs22 = require("fs");
7604
+ import_node_fs23 = require("fs");
7606
7605
  import_node_os9 = require("os");
7607
- import_node_path21 = require("path");
7606
+ import_node_path22 = require("path");
7608
7607
  init_run();
7609
7608
  init_app_settings();
7610
7609
  init_global_workspace();
@@ -7629,7 +7628,7 @@ var init_codex = __esm({
7629
7628
  async detect() {
7630
7629
  const codex = resolveAgentExecutable("codex");
7631
7630
  if (codex !== "codex") {
7632
- if (!(0, import_node_fs22.existsSync)(codex)) {
7631
+ if (!(0, import_node_fs23.existsSync)(codex)) {
7633
7632
  return {
7634
7633
  agent: "codex",
7635
7634
  installed: false,
@@ -8038,21 +8037,21 @@ function platformRipgrepPackage() {
8038
8037
  }
8039
8038
  function usableRipgrepPath(candidate) {
8040
8039
  const raw = candidate?.trim();
8041
- if (!raw || !(0, import_node_path22.isAbsolute)(raw)) return null;
8040
+ if (!raw || !(0, import_node_path23.isAbsolute)(raw)) return null;
8042
8041
  const readable = nodeReadableScriptPath(raw);
8043
- if (!(0, import_node_fs23.existsSync)(readable) || isAsarPath(readable)) return null;
8042
+ if (!(0, import_node_fs24.existsSync)(readable) || isAsarPath(readable)) return null;
8044
8043
  return readable;
8045
8044
  }
8046
8045
  function walkForBundledRipgrep(startFile) {
8047
8046
  if (!startFile) return null;
8048
8047
  const pkg = platformRipgrepPackage();
8049
8048
  const name = rgBinaryName();
8050
- let dir = (0, import_node_path22.dirname)((0, import_node_path22.resolve)(startFile));
8051
- const root = (0, import_node_path22.parse)(dir).root;
8049
+ let dir = (0, import_node_path23.dirname)((0, import_node_path23.resolve)(startFile));
8050
+ const root = (0, import_node_path23.parse)(dir).root;
8052
8051
  while (dir !== root) {
8053
- const hit = usableRipgrepPath((0, import_node_path22.join)(dir, "node_modules", pkg, "bin", name));
8052
+ const hit = usableRipgrepPath((0, import_node_path23.join)(dir, "node_modules", pkg, "bin", name));
8054
8053
  if (hit) return hit;
8055
- const next = (0, import_node_path22.dirname)(dir);
8054
+ const next = (0, import_node_path23.dirname)(dir);
8056
8055
  if (next === dir) break;
8057
8056
  dir = next;
8058
8057
  }
@@ -8062,7 +8061,7 @@ function requireResolveBundledRipgrep(fromFile) {
8062
8061
  try {
8063
8062
  const req = (0, import_node_module2.createRequire)(fromFile);
8064
8063
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
8065
- return usableRipgrepPath((0, import_node_path22.join)((0, import_node_path22.dirname)(pkgJson), "bin", rgBinaryName()));
8064
+ return usableRipgrepPath((0, import_node_path23.join)((0, import_node_path23.dirname)(pkgJson), "bin", rgBinaryName()));
8066
8065
  } catch {
8067
8066
  return null;
8068
8067
  }
@@ -8082,13 +8081,13 @@ function cursorRipgrepEnv(opts) {
8082
8081
  const path2 = resolveCursorRipgrepPath(opts);
8083
8082
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
8084
8083
  }
8085
- var import_node_fs23, import_node_module2, import_node_path22, import_node_url2, import_meta2, RIPGREP_ENV;
8084
+ var import_node_fs24, import_node_module2, import_node_path23, import_node_url2, import_meta2, RIPGREP_ENV;
8086
8085
  var init_cursor_ripgrep = __esm({
8087
8086
  "src/agents/cursor-ripgrep.ts"() {
8088
8087
  "use strict";
8089
- import_node_fs23 = require("fs");
8088
+ import_node_fs24 = require("fs");
8090
8089
  import_node_module2 = require("module");
8091
- import_node_path22 = require("path");
8090
+ import_node_path23 = require("path");
8092
8091
  import_node_url2 = require("url");
8093
8092
  init_node_launch();
8094
8093
  init_packaged_runtime();
@@ -8136,11 +8135,11 @@ function entryDir() {
8136
8135
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
8137
8136
  if (cjsDir) return cjsDir;
8138
8137
  try {
8139
- return (0, import_node_path23.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
8138
+ return (0, import_node_path24.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
8140
8139
  } catch {
8141
8140
  try {
8142
8141
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
8143
- return (0, import_node_path23.dirname)(req.resolve("@sideboard-ai/core"));
8142
+ return (0, import_node_path24.dirname)(req.resolve("@sideboard-ai/core"));
8144
8143
  } catch {
8145
8144
  return process.cwd();
8146
8145
  }
@@ -8151,27 +8150,27 @@ function cursorRunnerPath() {
8151
8150
  if (packaged) return packaged;
8152
8151
  const root = entryDir();
8153
8152
  const candidates = [
8154
- (0, import_node_path23.join)(root, "agents", "cursor-runner.js"),
8155
- (0, import_node_path23.join)(root, "agents", "cursor-runner.cjs"),
8153
+ (0, import_node_path24.join)(root, "agents", "cursor-runner.js"),
8154
+ (0, import_node_path24.join)(root, "agents", "cursor-runner.cjs"),
8156
8155
  // If somehow resolved from package root instead of dist/
8157
- (0, import_node_path23.join)(root, "dist", "agents", "cursor-runner.js"),
8158
- (0, import_node_path23.join)(root, "dist", "agents", "cursor-runner.cjs"),
8156
+ (0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.js"),
8157
+ (0, import_node_path24.join)(root, "dist", "agents", "cursor-runner.cjs"),
8159
8158
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
8160
- (0, import_node_path23.join)(root, "cursor-runner.ts"),
8161
- (0, import_node_path23.join)(root, "src", "agents", "cursor-runner.ts")
8159
+ (0, import_node_path24.join)(root, "cursor-runner.ts"),
8160
+ (0, import_node_path24.join)(root, "src", "agents", "cursor-runner.ts")
8162
8161
  ];
8163
8162
  for (const candidate of candidates) {
8164
- if ((0, import_node_fs24.existsSync)(candidate)) return candidate;
8163
+ if ((0, import_node_fs25.existsSync)(candidate)) return candidate;
8165
8164
  }
8166
8165
  return candidates[0];
8167
8166
  }
8168
- var import_node_fs24, import_node_module3, import_node_path23, import_node_url3, import_sdk, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8167
+ var import_node_fs25, import_node_module3, import_node_path24, import_node_url3, import_sdk, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
8169
8168
  var init_cursor = __esm({
8170
8169
  "src/agents/cursor.ts"() {
8171
8170
  "use strict";
8172
- import_node_fs24 = require("fs");
8171
+ import_node_fs25 = require("fs");
8173
8172
  import_node_module3 = require("module");
8174
- import_node_path23 = require("path");
8173
+ import_node_path24 = require("path");
8175
8174
  import_node_url3 = require("url");
8176
8175
  import_sdk = require("@cursor/sdk");
8177
8176
  init_run();
@@ -8303,7 +8302,7 @@ async function listOpencodeModels() {
8303
8302
  if (opencode === "opencode") {
8304
8303
  const which = await run("which", ["opencode"], { reject: false });
8305
8304
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
8306
- } else if (!(0, import_node_fs25.existsSync)(opencode)) {
8305
+ } else if (!(0, import_node_fs26.existsSync)(opencode)) {
8307
8306
  return FALLBACK_OPENCODE_MODELS;
8308
8307
  }
8309
8308
  const listed = await run(opencode, ["models"], { reject: false });
@@ -8333,11 +8332,11 @@ function usageFromOpencode(tokens) {
8333
8332
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
8334
8333
  };
8335
8334
  }
8336
- var import_node_fs25, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
8335
+ var import_node_fs26, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
8337
8336
  var init_opencode = __esm({
8338
8337
  "src/agents/opencode.ts"() {
8339
8338
  "use strict";
8340
- import_node_fs25 = require("fs");
8339
+ import_node_fs26 = require("fs");
8341
8340
  init_run();
8342
8341
  init_app_settings();
8343
8342
  init_global_workspace();
@@ -8363,7 +8362,7 @@ var init_opencode = __esm({
8363
8362
  async detect() {
8364
8363
  const opencode = resolveAgentExecutable("opencode");
8365
8364
  if (opencode !== "opencode") {
8366
- if (!(0, import_node_fs25.existsSync)(opencode)) {
8365
+ if (!(0, import_node_fs26.existsSync)(opencode)) {
8367
8366
  return {
8368
8367
  agent: "opencode",
8369
8368
  installed: false,
@@ -9160,40 +9159,40 @@ __export(plan_file_exports, {
9160
9159
  writePlanFile: () => writePlanFile
9161
9160
  });
9162
9161
  function ensureAttachmentsGitignore2(worktreePath) {
9163
- const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
9164
- if ((0, import_node_fs39.existsSync)(gitignoreAbs)) return;
9165
- (0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
9166
- (0, import_node_fs39.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
9162
+ const gitignoreAbs = (0, import_node_path37.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
9163
+ if ((0, import_node_fs40.existsSync)(gitignoreAbs)) return;
9164
+ (0, import_node_fs40.mkdirSync)((0, import_node_path37.dirname)(gitignoreAbs), { recursive: true });
9165
+ (0, import_node_fs40.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
9167
9166
  }
9168
9167
  function planFileAbs(worktreePath) {
9169
- return (0, import_node_path36.join)(worktreePath, PLAN_FILE_REL);
9168
+ return (0, import_node_path37.join)(worktreePath, PLAN_FILE_REL);
9170
9169
  }
9171
9170
  function readTextIfPresent2(abs) {
9172
- if (!(0, import_node_fs39.existsSync)(abs)) return null;
9171
+ if (!(0, import_node_fs40.existsSync)(abs)) return null;
9173
9172
  try {
9174
- const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
9173
+ const content = (0, import_node_fs40.readFileSync)(abs, "utf8");
9175
9174
  return content.trim() ? content : null;
9176
9175
  } catch {
9177
9176
  return null;
9178
9177
  }
9179
9178
  }
9180
9179
  function readPlanFile(worktreePath) {
9181
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, LEGACY_PLAN_FILE_REL));
9180
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path37.join)(worktreePath, LEGACY_PLAN_FILE_REL));
9182
9181
  }
9183
9182
  function writePlanFile(worktreePath, content) {
9184
9183
  ensureAttachmentsGitignore2(worktreePath);
9185
9184
  const abs = planFileAbs(worktreePath);
9186
- (0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
9185
+ (0, import_node_fs40.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
9187
9186
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
9188
- (0, import_node_fs39.writeFileSync)(abs, body, "utf8");
9187
+ (0, import_node_fs40.writeFileSync)(abs, body, "utf8");
9189
9188
  return PLAN_FILE_REL;
9190
9189
  }
9191
- var import_node_fs39, import_node_path36;
9190
+ var import_node_fs40, import_node_path37;
9192
9191
  var init_plan_file = __esm({
9193
9192
  "src/plan/plan-file.ts"() {
9194
9193
  "use strict";
9195
- import_node_fs39 = require("fs");
9196
- import_node_path36 = require("path");
9194
+ import_node_fs40 = require("fs");
9195
+ import_node_path37 = require("path");
9197
9196
  init_workspace_scratch();
9198
9197
  init_plan_present();
9199
9198
  init_plan_present();
@@ -9208,10 +9207,10 @@ __export(cursor_recover_exports, {
9208
9207
  function recoverFinishedCursorRun(opts) {
9209
9208
  const agentId = opts.agentId.trim();
9210
9209
  if (!agentId) return null;
9211
- const runsPath = (0, import_node_path37.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
9212
- if (!(0, import_node_fs40.existsSync)(runsPath)) return null;
9210
+ const runsPath = (0, import_node_path38.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
9211
+ if (!(0, import_node_fs41.existsSync)(runsPath)) return null;
9213
9212
  try {
9214
- const lines = (0, import_node_fs40.readFileSync)(runsPath, "utf8").split("\n");
9213
+ const lines = (0, import_node_fs41.readFileSync)(runsPath, "utf8").split("\n");
9215
9214
  let best = null;
9216
9215
  for (const line of lines) {
9217
9216
  const trimmed = line.trim();
@@ -9237,12 +9236,12 @@ function recoverFinishedCursorRun(opts) {
9237
9236
  return null;
9238
9237
  }
9239
9238
  }
9240
- var import_node_fs40, import_node_path37;
9239
+ var import_node_fs41, import_node_path38;
9241
9240
  var init_cursor_recover = __esm({
9242
9241
  "src/agents/cursor-recover.ts"() {
9243
9242
  "use strict";
9244
- import_node_fs40 = require("fs");
9245
- import_node_path37 = require("path");
9243
+ import_node_fs41 = require("fs");
9244
+ import_node_path38 = require("path");
9246
9245
  init_paths();
9247
9246
  }
9248
9247
  });
@@ -9389,6 +9388,7 @@ __export(index_exports, {
9389
9388
  captureTurnBaseline: () => captureTurnBaseline,
9390
9389
  checkoutPrStackLayer: () => checkoutPrStackLayer,
9391
9390
  childEnvWithAppSettings: () => childEnvWithAppSettings,
9391
+ claimDesktopHost: () => claimDesktopHost,
9392
9392
  claudeAdapter: () => claudeAdapter,
9393
9393
  claudeChromeEnabled: () => claudeChromeEnabled,
9394
9394
  claudeUserSettingsPath: () => claudeUserSettingsPath,
@@ -9427,6 +9427,7 @@ __export(index_exports, {
9427
9427
  decodeBrightsyTarget: () => decodeBrightsyTarget,
9428
9428
  deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
9429
9429
  deleteThreadRecord: () => deleteThreadRecord,
9430
+ desktopHostPidPath: () => desktopHostPidPath,
9430
9431
  detectAgents: () => detectAgents,
9431
9432
  detectGhStack: () => detectGhStack,
9432
9433
  detectLocalMergeConflicts: () => detectLocalMergeConflicts,
@@ -9460,6 +9461,7 @@ __export(index_exports, {
9460
9461
  findConventionSetup: () => findConventionSetup,
9461
9462
  findInvalidCacheControlTtlOrder: () => findInvalidCacheControlTtlOrder,
9462
9463
  findOrphanWorktrees: () => findOrphanWorktrees,
9464
+ findSlackCoordinator: () => findSlackCoordinator,
9463
9465
  findThreadByRef: () => findThreadByRef,
9464
9466
  findThreadForStackLayer: () => findThreadForStackLayer,
9465
9467
  flattenTurnInput: () => flattenTurnInput,
@@ -9551,6 +9553,7 @@ __export(index_exports, {
9551
9553
  isConductorBundledCli: () => isConductorBundledCli,
9552
9554
  isCursorAutoModel: () => isCursorAutoModel,
9553
9555
  isDefaultishSourceRef: () => isDefaultishSourceRef,
9556
+ isDesktopHostAlive: () => isDesktopHostAlive,
9554
9557
  isDirty: () => isDirty,
9555
9558
  isGhRateLimitError: () => isGhRateLimitError,
9556
9559
  isGlobalRepoPath: () => isGlobalRepoPath,
@@ -9572,6 +9575,7 @@ __export(index_exports, {
9572
9575
  isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
9573
9576
  isSlackOAuthCancelled: () => isSlackOAuthCancelled,
9574
9577
  isThinkingEffort: () => isThinkingEffort,
9578
+ isThisProcessDesktopHost: () => isThisProcessDesktopHost,
9575
9579
  isThreadCaffeinated: () => isThreadCaffeinated,
9576
9580
  isWorkspaceScratchPath: () => isWorkspaceScratchPath,
9577
9581
  linearAuthorizationHeader: () => linearAuthorizationHeader,
@@ -9673,6 +9677,7 @@ __export(index_exports, {
9673
9677
  refreshSlackReplyBadges: () => refreshSlackReplyBadges,
9674
9678
  registerPackagedUserMcpClients: () => registerPackagedUserMcpClients,
9675
9679
  releaseCaffeinateHoldForThread: () => releaseCaffeinateHoldForThread,
9680
+ releaseDesktopHost: () => releaseDesktopHost,
9676
9681
  removeWorkspace: () => removeWorkspace,
9677
9682
  removeWorktree: () => removeWorktree,
9678
9683
  repoSlug: () => repoSlug,
@@ -9773,6 +9778,7 @@ __export(index_exports, {
9773
9778
  taskMessageText: () => taskMessageText,
9774
9779
  thinkingEffortBars: () => thinkingEffortBars,
9775
9780
  thinkingEffortLabel: () => thinkingEffortLabel,
9781
+ thisProcessShouldDrainAgentQueues: () => thisProcessShouldDrainAgentQueues,
9776
9782
  threadDisplayLabel: () => threadDisplayLabel,
9777
9783
  threadFilePath: () => threadFilePath,
9778
9784
  threadLockPath: () => threadLockPath,
@@ -9820,6 +9826,55 @@ init_app_settings();
9820
9826
  init_caffeinate_hold();
9821
9827
  init_secure_file();
9822
9828
  init_thread_store();
9829
+
9830
+ // src/store/desktop-host.ts
9831
+ var import_node_fs10 = require("fs");
9832
+ var import_node_path10 = require("path");
9833
+ init_paths();
9834
+ function desktopHostPidPath() {
9835
+ return (0, import_node_path10.join)(appDataDir(), "desktop-host.pid");
9836
+ }
9837
+ function claimDesktopHost(pid = process.pid) {
9838
+ (0, import_node_fs10.writeFileSync)(desktopHostPidPath(), `${pid}
9839
+ `, "utf8");
9840
+ }
9841
+ function releaseDesktopHost(pid = process.pid) {
9842
+ if (readDesktopHostPid() !== pid) return;
9843
+ try {
9844
+ (0, import_node_fs10.unlinkSync)(desktopHostPidPath());
9845
+ } catch {
9846
+ }
9847
+ }
9848
+ function readDesktopHostPid() {
9849
+ try {
9850
+ const pid = Number.parseInt((0, import_node_fs10.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
9851
+ if (!Number.isFinite(pid) || pid <= 0) return null;
9852
+ return pid;
9853
+ } catch {
9854
+ return null;
9855
+ }
9856
+ }
9857
+ function pidAlive(pid) {
9858
+ try {
9859
+ process.kill(pid, 0);
9860
+ return true;
9861
+ } catch {
9862
+ return false;
9863
+ }
9864
+ }
9865
+ function isDesktopHostAlive() {
9866
+ const pid = readDesktopHostPid();
9867
+ return pid != null && pidAlive(pid);
9868
+ }
9869
+ function isThisProcessDesktopHost() {
9870
+ return readDesktopHostPid() === process.pid && pidAlive(process.pid);
9871
+ }
9872
+ function thisProcessShouldDrainAgentQueues() {
9873
+ if (isThisProcessDesktopHost()) return true;
9874
+ return !isDesktopHostAlive();
9875
+ }
9876
+
9877
+ // src/index.ts
9823
9878
  init_workspaces();
9824
9879
  init_global_workspace();
9825
9880
  init_run();
@@ -10979,8 +11034,8 @@ init_usage();
10979
11034
  init_claude_mcp();
10980
11035
 
10981
11036
  // src/agents/instructions.ts
10982
- var import_node_fs26 = require("fs");
10983
- var import_node_path24 = require("path");
11037
+ var import_node_fs27 = require("fs");
11038
+ var import_node_path25 = require("path");
10984
11039
  init_git_auth_mode();
10985
11040
  init_worktree_labels();
10986
11041
  function normPath3(p) {
@@ -11151,11 +11206,11 @@ function loadAgentInstructions(worktreePath, agent) {
11151
11206
  const out = [];
11152
11207
  for (const rel of candidates) {
11153
11208
  if (seenPaths.has(rel)) continue;
11154
- const abs = (0, import_node_path24.join)(worktreePath, rel);
11155
- if (!(0, import_node_fs26.existsSync)(abs)) continue;
11209
+ const abs = (0, import_node_path25.join)(worktreePath, rel);
11210
+ if (!(0, import_node_fs27.existsSync)(abs)) continue;
11156
11211
  try {
11157
- if (!(0, import_node_fs26.statSync)(abs).isFile()) continue;
11158
- let content = (0, import_node_fs26.readFileSync)(abs, "utf8");
11212
+ if (!(0, import_node_fs27.statSync)(abs).isFile()) continue;
11213
+ let content = (0, import_node_fs27.readFileSync)(abs, "utf8");
11159
11214
  if (!content.trim()) continue;
11160
11215
  if (content.length > MAX_CHARS_PER_FILE) {
11161
11216
  content = `${content.slice(0, MAX_CHARS_PER_FILE)}
@@ -11237,9 +11292,9 @@ async function requireAgent(agent, opts) {
11237
11292
  init_settings();
11238
11293
 
11239
11294
  // src/hook/conductor.ts
11240
- var import_node_fs27 = require("fs");
11295
+ var import_node_fs28 = require("fs");
11241
11296
  var import_node_net = require("net");
11242
- var import_node_path25 = require("path");
11297
+ var import_node_path26 = require("path");
11243
11298
  var import_execa4 = require("execa");
11244
11299
  var import_node_readline3 = require("readline");
11245
11300
  init_settings();
@@ -11254,9 +11309,9 @@ function matchSimpleGlob(pattern, name) {
11254
11309
  return new RegExp(`^${escaped}$`).test(name);
11255
11310
  }
11256
11311
  function readWorktreeInclude(repoPath) {
11257
- const path2 = (0, import_node_path25.join)(repoPath, ".worktreeinclude");
11258
- if (!(0, import_node_fs27.existsSync)(path2)) return [];
11259
- return (0, import_node_fs27.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
11312
+ const path2 = (0, import_node_path26.join)(repoPath, ".worktreeinclude");
11313
+ if (!(0, import_node_fs28.existsSync)(path2)) return [];
11314
+ return (0, import_node_fs28.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
11260
11315
  }
11261
11316
  function resolveFilesToCopy(repoPath) {
11262
11317
  const fromInclude = readWorktreeInclude(repoPath);
@@ -11266,10 +11321,10 @@ function resolveFilesToCopy(repoPath) {
11266
11321
  if (settings?.fileIncludeGlobs?.length) {
11267
11322
  const matched = [];
11268
11323
  try {
11269
- for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
11324
+ for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
11270
11325
  if (!entry.isFile()) continue;
11271
11326
  for (const glob of settings.fileIncludeGlobs) {
11272
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path25.basename)(glob), entry.name)) {
11327
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path26.basename)(glob), entry.name)) {
11273
11328
  matched.push(entry.name);
11274
11329
  break;
11275
11330
  }
@@ -11281,7 +11336,7 @@ function resolveFilesToCopy(repoPath) {
11281
11336
  }
11282
11337
  const defaults = [];
11283
11338
  try {
11284
- for (const entry of (0, import_node_fs27.readdirSync)(repoPath, { withFileTypes: true })) {
11339
+ for (const entry of (0, import_node_fs28.readdirSync)(repoPath, { withFileTypes: true })) {
11285
11340
  if (entry.isFile() && entry.name.startsWith(".env")) {
11286
11341
  defaults.push(entry.name);
11287
11342
  }
@@ -11295,11 +11350,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
11295
11350
  const patterns = resolveFilesToCopy(repoPath);
11296
11351
  const copied = [];
11297
11352
  for (const rel of patterns) {
11298
- const src = (0, import_node_path25.join)(repoPath, rel);
11299
- if (!(0, import_node_fs27.existsSync)(src)) continue;
11300
- const dest = (0, import_node_path25.join)(worktreePath, rel);
11301
- (0, import_node_fs27.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
11302
- (0, import_node_fs27.copyFileSync)(src, dest);
11353
+ const src = (0, import_node_path26.join)(repoPath, rel);
11354
+ if (!(0, import_node_fs28.existsSync)(src)) continue;
11355
+ const dest = (0, import_node_path26.join)(worktreePath, rel);
11356
+ (0, import_node_fs28.mkdirSync)((0, import_node_path26.dirname)(dest), { recursive: true });
11357
+ (0, import_node_fs28.copyFileSync)(src, dest);
11303
11358
  copied.push(rel);
11304
11359
  }
11305
11360
  return copied;
@@ -11335,7 +11390,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
11335
11390
  const env = stripNestedElectronEnv({
11336
11391
  ...baseEnv ?? process.env
11337
11392
  });
11338
- const name = opts.workspaceName ?? (0, import_node_path25.basename)(opts.worktreePath);
11393
+ const name = opts.workspaceName ?? (0, import_node_path26.basename)(opts.worktreePath);
11339
11394
  const ports = opts.ports ?? [];
11340
11395
  const primary = ports[0];
11341
11396
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -11596,12 +11651,12 @@ init_convention_setup();
11596
11651
  init_cursor_worktrees();
11597
11652
 
11598
11653
  // src/diff/diff.ts
11599
- var import_node_fs28 = require("fs");
11600
- var import_node_path26 = require("path");
11654
+ var import_node_fs29 = require("fs");
11655
+ var import_node_path27 = require("path");
11601
11656
  init_run();
11602
11657
  init_worktree();
11603
11658
  async function inspectGitWorktree(worktreePath) {
11604
- if (!worktreePath || !(0, import_node_fs28.existsSync)(worktreePath)) return "missing_worktree";
11659
+ if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) return "missing_worktree";
11605
11660
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
11606
11661
  reject: false
11607
11662
  });
@@ -11609,7 +11664,7 @@ async function inspectGitWorktree(worktreePath) {
11609
11664
  return "ok";
11610
11665
  }
11611
11666
  async function initializeGitRepository(worktreePath) {
11612
- if (!worktreePath || !(0, import_node_fs28.existsSync)(worktreePath)) {
11667
+ if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) {
11613
11668
  throw new Error("Worktree not found");
11614
11669
  }
11615
11670
  const status = await inspectGitWorktree(worktreePath);
@@ -11745,11 +11800,11 @@ new file mode 100644
11745
11800
  };
11746
11801
  }
11747
11802
  async function untrackedPatch(worktreePath, path2, maxHunk) {
11748
- const abs = (0, import_node_path26.join)(worktreePath, path2);
11803
+ const abs = (0, import_node_path27.join)(worktreePath, path2);
11749
11804
  try {
11750
- const st = (0, import_node_fs28.statSync)(abs);
11805
+ const st = (0, import_node_fs29.statSync)(abs);
11751
11806
  if (st.isFile() && st.size > maxHunk) {
11752
- const buf = (0, import_node_fs28.readFileSync)(abs).subarray(0, maxHunk);
11807
+ const buf = (0, import_node_fs29.readFileSync)(abs).subarray(0, maxHunk);
11753
11808
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
11754
11809
  }
11755
11810
  } catch {
@@ -12250,8 +12305,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
12250
12305
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12251
12306
  assertSafeRelativePath(relativePath);
12252
12307
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
12253
- const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12254
- const st = (0, import_node_fs28.statSync)(abs);
12308
+ const abs = (0, import_node_path27.join)(worktreePath, relativePath);
12309
+ const st = (0, import_node_fs29.statSync)(abs);
12255
12310
  if (!st.isFile()) {
12256
12311
  throw new Error(`Not a file: ${relativePath}`);
12257
12312
  }
@@ -12260,7 +12315,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12260
12315
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
12261
12316
  );
12262
12317
  }
12263
- const buf = (0, import_node_fs28.readFileSync)(abs);
12318
+ const buf = (0, import_node_fs29.readFileSync)(abs);
12264
12319
  return {
12265
12320
  path: relativePath,
12266
12321
  contentBase64: buf.toString("base64"),
@@ -12270,12 +12325,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12270
12325
  function readWorktreeFile(worktreePath, relativePath, opts) {
12271
12326
  assertSafeRelativePath(relativePath);
12272
12327
  const maxBytes = opts?.maxBytes ?? 2e5;
12273
- const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12274
- const st = (0, import_node_fs28.statSync)(abs);
12328
+ const abs = (0, import_node_path27.join)(worktreePath, relativePath);
12329
+ const st = (0, import_node_fs29.statSync)(abs);
12275
12330
  if (!st.isFile()) {
12276
12331
  throw new Error(`Not a file: ${relativePath}`);
12277
12332
  }
12278
- const buf = (0, import_node_fs28.readFileSync)(abs);
12333
+ const buf = (0, import_node_fs29.readFileSync)(abs);
12279
12334
  if (isImageRelativePath(relativePath)) {
12280
12335
  const maxImageBytes = Math.max(maxBytes, 15e6);
12281
12336
  const truncated2 = buf.length > maxImageBytes;
@@ -12318,9 +12373,9 @@ function assertSafeRelativePath(relativePath) {
12318
12373
  }
12319
12374
  function writeWorktreeFile(worktreePath, relativePath, content) {
12320
12375
  assertSafeRelativePath(relativePath);
12321
- const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12322
- (0, import_node_fs28.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
12323
- (0, import_node_fs28.writeFileSync)(abs, content, "utf8");
12376
+ const abs = (0, import_node_path27.join)(worktreePath, relativePath);
12377
+ (0, import_node_fs29.mkdirSync)((0, import_node_path27.dirname)(abs), { recursive: true });
12378
+ (0, import_node_fs29.writeFileSync)(abs, content, "utf8");
12324
12379
  return { path: relativePath };
12325
12380
  }
12326
12381
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -12339,9 +12394,9 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
12339
12394
  }
12340
12395
 
12341
12396
  // src/skills/discover.ts
12342
- var import_node_fs29 = require("fs");
12397
+ var import_node_fs30 = require("fs");
12343
12398
  var import_node_os10 = require("os");
12344
- var import_node_path27 = require("path");
12399
+ var import_node_path28 = require("path");
12345
12400
  function toCommand(name) {
12346
12401
  return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
12347
12402
  }
@@ -12373,7 +12428,7 @@ function parseFrontmatter(content) {
12373
12428
  }
12374
12429
  function readSkill(skillMd, source) {
12375
12430
  try {
12376
- const content = (0, import_node_fs29.readFileSync)(skillMd, "utf8");
12431
+ const content = (0, import_node_fs30.readFileSync)(skillMd, "utf8");
12377
12432
  const { name: fmName, description } = parseFrontmatter(content);
12378
12433
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
12379
12434
  const name = fmName || dirName;
@@ -12392,19 +12447,19 @@ function readSkill(skillMd, source) {
12392
12447
  }
12393
12448
  }
12394
12449
  function scanSkillsDir(dir, source, out) {
12395
- if (!(0, import_node_fs29.existsSync)(dir)) return;
12450
+ if (!(0, import_node_fs30.existsSync)(dir)) return;
12396
12451
  let entries;
12397
12452
  try {
12398
- entries = (0, import_node_fs29.readdirSync)(dir);
12453
+ entries = (0, import_node_fs30.readdirSync)(dir);
12399
12454
  } catch {
12400
12455
  return;
12401
12456
  }
12402
12457
  for (const entry of entries) {
12403
12458
  if (entry.startsWith(".")) continue;
12404
- const skillMd = (0, import_node_path27.join)(dir, entry, "SKILL.md");
12405
- if (!(0, import_node_fs29.existsSync)(skillMd)) continue;
12459
+ const skillMd = (0, import_node_path28.join)(dir, entry, "SKILL.md");
12460
+ if (!(0, import_node_fs30.existsSync)(skillMd)) continue;
12406
12461
  try {
12407
- if (!(0, import_node_fs29.statSync)(skillMd).isFile()) continue;
12462
+ if (!(0, import_node_fs30.statSync)(skillMd).isFile()) continue;
12408
12463
  } catch {
12409
12464
  continue;
12410
12465
  }
@@ -12413,24 +12468,24 @@ function scanSkillsDir(dir, source, out) {
12413
12468
  }
12414
12469
  }
12415
12470
  function scanClaudePluginSkills(pluginsRoot, out) {
12416
- if (!(0, import_node_fs29.existsSync)(pluginsRoot)) return;
12471
+ if (!(0, import_node_fs30.existsSync)(pluginsRoot)) return;
12417
12472
  const walk = (dir, depth, lookingForSkillsDir) => {
12418
12473
  if (depth > 7) return;
12419
12474
  let entries;
12420
12475
  try {
12421
- entries = (0, import_node_fs29.readdirSync)(dir);
12476
+ entries = (0, import_node_fs30.readdirSync)(dir);
12422
12477
  } catch {
12423
12478
  return;
12424
12479
  }
12425
12480
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
12426
- const skill = readSkill((0, import_node_path27.join)(dir, "SKILL.md"), "cli");
12481
+ const skill = readSkill((0, import_node_path28.join)(dir, "SKILL.md"), "cli");
12427
12482
  if (skill) out.push(skill);
12428
12483
  }
12429
12484
  for (const entry of entries) {
12430
12485
  if (entry === "node_modules" || entry === ".git") continue;
12431
- const full = (0, import_node_path27.join)(dir, entry);
12486
+ const full = (0, import_node_path28.join)(dir, entry);
12432
12487
  try {
12433
- if (!(0, import_node_fs29.statSync)(full).isDirectory()) continue;
12488
+ if (!(0, import_node_fs30.statSync)(full).isDirectory()) continue;
12434
12489
  } catch {
12435
12490
  continue;
12436
12491
  }
@@ -12448,17 +12503,17 @@ function discoverSkills(worktreePath) {
12448
12503
  const home = (0, import_node_os10.homedir)();
12449
12504
  const collected = [];
12450
12505
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
12451
- scanSkillsDir((0, import_node_path27.join)(worktreePath, rel), "workspace", collected);
12506
+ scanSkillsDir((0, import_node_path28.join)(worktreePath, rel), "workspace", collected);
12452
12507
  }
12453
12508
  for (const abs of [
12454
- (0, import_node_path27.join)(home, ".claude/skills"),
12455
- (0, import_node_path27.join)(home, ".cursor/skills"),
12456
- (0, import_node_path27.join)(home, ".sideboard/skills"),
12457
- (0, import_node_path27.join)(home, ".brightsy/skills")
12509
+ (0, import_node_path28.join)(home, ".claude/skills"),
12510
+ (0, import_node_path28.join)(home, ".cursor/skills"),
12511
+ (0, import_node_path28.join)(home, ".sideboard/skills"),
12512
+ (0, import_node_path28.join)(home, ".brightsy/skills")
12458
12513
  ]) {
12459
12514
  scanSkillsDir(abs, "user", collected);
12460
12515
  }
12461
- scanClaudePluginSkills((0, import_node_path27.join)(home, ".claude/plugins"), collected);
12516
+ scanClaudePluginSkills((0, import_node_path28.join)(home, ".claude/plugins"), collected);
12462
12517
  const rank = { workspace: 0, user: 1, cli: 2 };
12463
12518
  const byCommand = /* @__PURE__ */ new Map();
12464
12519
  for (const skill of collected) {
@@ -12470,7 +12525,7 @@ function discoverSkills(worktreePath) {
12470
12525
  return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
12471
12526
  }
12472
12527
  function readSkillBody(skillPath, maxChars = 12e3) {
12473
- const raw = (0, import_node_fs29.readFileSync)(skillPath, "utf8");
12528
+ const raw = (0, import_node_fs30.readFileSync)(skillPath, "utf8");
12474
12529
  if (raw.startsWith("---")) {
12475
12530
  const end = raw.indexOf("\n---", 3);
12476
12531
  if (end >= 0) {
@@ -12611,8 +12666,8 @@ function buildDiffCommentAttachment(input) {
12611
12666
  }
12612
12667
 
12613
12668
  // src/composer/stage-files.ts
12614
- var import_node_fs30 = require("fs");
12615
- var import_node_path28 = require("path");
12669
+ var import_node_fs31 = require("fs");
12670
+ var import_node_path29 = require("path");
12616
12671
  var import_node_crypto5 = require("crypto");
12617
12672
  init_workspace_scratch();
12618
12673
  var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -12638,7 +12693,7 @@ var IMAGE_MIME_BY_EXT = {
12638
12693
  var MAX_INLINE_BYTES = 4e5;
12639
12694
  var MAX_PREVIEW_BYTES = 5e6;
12640
12695
  function fileExtension(filePath) {
12641
- const base = (0, import_node_path28.basename)(filePath).toLowerCase();
12696
+ const base = (0, import_node_path29.basename)(filePath).toLowerCase();
12642
12697
  return base.includes(".") ? base.split(".").pop() || "" : "";
12643
12698
  }
12644
12699
  function isImageFilePath(filePath) {
@@ -12648,22 +12703,22 @@ function imageMimeType(filePath) {
12648
12703
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
12649
12704
  }
12650
12705
  function ensureAttachmentsDir(worktreePath) {
12651
- const dir = (0, import_node_path28.join)(worktreePath, ATTACHMENTS_DIR);
12652
- (0, import_node_fs30.mkdirSync)(dir, { recursive: true });
12653
- const gi = (0, import_node_path28.join)(dir, ".gitignore");
12654
- if (!(0, import_node_fs30.existsSync)(gi)) {
12655
- (0, import_node_fs30.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12706
+ const dir = (0, import_node_path29.join)(worktreePath, ATTACHMENTS_DIR);
12707
+ (0, import_node_fs31.mkdirSync)(dir, { recursive: true });
12708
+ const gi = (0, import_node_path29.join)(dir, ".gitignore");
12709
+ if (!(0, import_node_fs31.existsSync)(gi)) {
12710
+ (0, import_node_fs31.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12656
12711
  }
12657
12712
  return dir;
12658
12713
  }
12659
12714
  function uniqueAttachmentName(dir, originalName) {
12660
12715
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
12661
- if (!(0, import_node_fs30.existsSync)((0, import_node_path28.join)(dir, safe))) return safe;
12662
- const ext = (0, import_node_path28.extname)(safe);
12716
+ if (!(0, import_node_fs31.existsSync)((0, import_node_path29.join)(dir, safe))) return safe;
12717
+ const ext = (0, import_node_path29.extname)(safe);
12663
12718
  const stem = ext ? safe.slice(0, -ext.length) : safe;
12664
12719
  for (let i = 1; i < 1e4; i++) {
12665
12720
  const candidate = `${stem}-${i}${ext}`;
12666
- if (!(0, import_node_fs30.existsSync)((0, import_node_path28.join)(dir, candidate))) return candidate;
12721
+ if (!(0, import_node_fs31.existsSync)((0, import_node_path29.join)(dir, candidate))) return candidate;
12667
12722
  }
12668
12723
  return `${stem}-${(0, import_node_crypto5.randomUUID)()}${ext}`;
12669
12724
  }
@@ -12715,9 +12770,9 @@ function attachmentFromBuffer(name, buf, opts) {
12715
12770
  };
12716
12771
  }
12717
12772
  function attachmentFromAbsolutePath(absolutePath) {
12718
- const name = (0, import_node_path28.basename)(absolutePath);
12773
+ const name = (0, import_node_path29.basename)(absolutePath);
12719
12774
  try {
12720
- const st = (0, import_node_fs30.statSync)(absolutePath);
12775
+ const st = (0, import_node_fs31.statSync)(absolutePath);
12721
12776
  if (!st.isFile()) {
12722
12777
  return {
12723
12778
  id: (0, import_node_crypto5.randomUUID)(),
@@ -12726,7 +12781,7 @@ function attachmentFromAbsolutePath(absolutePath) {
12726
12781
  content: `(not a file: ${absolutePath})`
12727
12782
  };
12728
12783
  }
12729
- const buf = (0, import_node_fs30.readFileSync)(absolutePath);
12784
+ const buf = (0, import_node_fs31.readFileSync)(absolutePath);
12730
12785
  return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
12731
12786
  } catch (err) {
12732
12787
  return {
@@ -12742,15 +12797,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
12742
12797
  const dir = ensureAttachmentsDir(worktreePath);
12743
12798
  const out = [];
12744
12799
  for (const abs of absolutePaths) {
12745
- const originalName = (0, import_node_path28.basename)(abs);
12800
+ const originalName = (0, import_node_path29.basename)(abs);
12746
12801
  try {
12747
- const st = (0, import_node_fs30.statSync)(abs);
12802
+ const st = (0, import_node_fs31.statSync)(abs);
12748
12803
  if (!st.isFile()) continue;
12749
12804
  const name = uniqueAttachmentName(dir, originalName);
12750
- const destAbs = (0, import_node_path28.join)(dir, name);
12751
- (0, import_node_fs30.copyFileSync)(abs, destAbs);
12805
+ const destAbs = (0, import_node_path29.join)(dir, name);
12806
+ (0, import_node_fs31.copyFileSync)(abs, destAbs);
12752
12807
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12753
- const buf = (0, import_node_fs30.readFileSync)(destAbs);
12808
+ const buf = (0, import_node_fs31.readFileSync)(destAbs);
12754
12809
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12755
12810
  } catch (err) {
12756
12811
  out.push({
@@ -12772,8 +12827,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
12772
12827
  try {
12773
12828
  const buf = Buffer.from(item.dataBase64, "base64");
12774
12829
  const name = uniqueAttachmentName(dir, originalName);
12775
- const destAbs = (0, import_node_path28.join)(dir, name);
12776
- (0, import_node_fs30.writeFileSync)(destAbs, buf);
12830
+ const destAbs = (0, import_node_path29.join)(dir, name);
12831
+ (0, import_node_fs31.writeFileSync)(destAbs, buf);
12777
12832
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12778
12833
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
12779
12834
  } catch (err) {
@@ -12809,18 +12864,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
12809
12864
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
12810
12865
  out.push({
12811
12866
  id: (0, import_node_crypto5.randomUUID)(),
12812
- name: (0, import_node_path28.basename)(rel) || "file",
12867
+ name: (0, import_node_path29.basename)(rel) || "file",
12813
12868
  kind: "file",
12814
12869
  content: `(invalid path: ${rel})`
12815
12870
  });
12816
12871
  continue;
12817
12872
  }
12818
- const name = (0, import_node_path28.basename)(rel);
12873
+ const name = (0, import_node_path29.basename)(rel);
12819
12874
  try {
12820
- const abs = (0, import_node_path28.join)(worktreePath, rel);
12821
- const st = (0, import_node_fs30.statSync)(abs);
12875
+ const abs = (0, import_node_path29.join)(worktreePath, rel);
12876
+ const st = (0, import_node_fs31.statSync)(abs);
12822
12877
  if (!st.isFile()) continue;
12823
- const buf = (0, import_node_fs30.readFileSync)(abs);
12878
+ const buf = (0, import_node_fs31.readFileSync)(abs);
12824
12879
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12825
12880
  } catch (err) {
12826
12881
  out.push({
@@ -13308,7 +13363,7 @@ async function confirmLand(thread, opts) {
13308
13363
  }
13309
13364
 
13310
13365
  // src/threads/create.ts
13311
- var import_node_fs31 = require("fs");
13366
+ var import_node_fs32 = require("fs");
13312
13367
  init_worktree();
13313
13368
  init_app_settings();
13314
13369
  init_thread_store();
@@ -13322,7 +13377,7 @@ async function createThread(input, _onSetupLine) {
13322
13377
  });
13323
13378
  await requireAgent(resolved.agent);
13324
13379
  const repoPath = await resolveRepoRoot(input.repoPath);
13325
- if (!(0, import_node_fs31.existsSync)(repoPath)) {
13380
+ if (!(0, import_node_fs32.existsSync)(repoPath)) {
13326
13381
  throw new Error(`Repo not found: ${repoPath}`);
13327
13382
  }
13328
13383
  let sourceRef = input.sourceRef;
@@ -13474,6 +13529,7 @@ function createChatTab(input) {
13474
13529
  if (isOrchestratorThread(from) || binding.sourceType === "orchestration") {
13475
13530
  assertOrchestratorCapableAgent(nextAgent);
13476
13531
  }
13532
+ const singletonInbox = isSlackCoordinatorThread(from) || isCloudCoordinatorThread(from);
13477
13533
  const thread = createEmptyThread({
13478
13534
  title,
13479
13535
  // Chat-tab nicknames (soccer team or explicit) must stick. Post-turn
@@ -13481,6 +13537,10 @@ function createChatTab(input) {
13481
13537
  // shared worktree folder name (e.g. fork "Arsenal" → "Monaco").
13482
13538
  userSetTitle: true,
13483
13539
  ...binding,
13540
+ // Slack / Brightsy cloud identity stays on the original chat. A + tab
13541
+ // that copies `slack:team:user` would steal inbound DMs after you close
13542
+ // the connected chat.
13543
+ sourceRef: singletonInbox ? title : binding.sourceRef,
13484
13544
  agent: nextAgent,
13485
13545
  model: input.model !== void 0 ? input.model : input.agent && input.agent !== from.agent ? null : from.model,
13486
13546
  effort: input.effort !== void 0 ? input.effort : from.effort,
@@ -13557,7 +13617,7 @@ async function forkThreadWorktree(input, onSetupLine) {
13557
13617
  }
13558
13618
 
13559
13619
  // src/threads/stack-layers.ts
13560
- var import_node_fs32 = require("fs");
13620
+ var import_node_fs33 = require("fs");
13561
13621
  init_run();
13562
13622
  init_stack();
13563
13623
  init_worktree();
@@ -13625,7 +13685,7 @@ async function openStackLayer(input, _onSetupLine) {
13625
13685
  let createdWorktree = false;
13626
13686
  const trees = await listWorktrees(repoPath);
13627
13687
  const checkedOut = trees.find((w) => w.branch === branchName);
13628
- if (checkedOut?.path && (0, import_node_fs32.existsSync)(checkedOut.path)) {
13688
+ if (checkedOut?.path && (0, import_node_fs33.existsSync)(checkedOut.path)) {
13629
13689
  if (input.reuseExistingWorktree !== false) {
13630
13690
  worktreePath = checkedOut.path;
13631
13691
  } else {
@@ -13767,7 +13827,7 @@ async function initStackFromThread(input, onSetupLine) {
13767
13827
  async function createPrStack(input, onSetupLine) {
13768
13828
  await requireAgent(input.agent);
13769
13829
  const repoPath = await resolveRepoRoot(input.repoPath);
13770
- if (!(0, import_node_fs32.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
13830
+ if (!(0, import_node_fs33.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
13771
13831
  if (!input.branches.length) throw new Error("At least one branch name required");
13772
13832
  const status = await detectGhStack(repoPath);
13773
13833
  if (!status.available) throw new Error(status.reason);
@@ -13834,7 +13894,7 @@ async function createPrStack(input, onSetupLine) {
13834
13894
  }
13835
13895
  }
13836
13896
  const claimed = new Set(threads.map((t) => t.worktreePath));
13837
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs32.existsSync)(bootstrap.worktreePath)) {
13897
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs33.existsSync)(bootstrap.worktreePath)) {
13838
13898
  try {
13839
13899
  await removeWorktree(repoPath, bootstrap.worktreePath, {
13840
13900
  deleteBranch: bootstrap.branchName
@@ -13857,21 +13917,21 @@ function stackAgentDefaultsFrom(input) {
13857
13917
 
13858
13918
  // src/threads/adopt.ts
13859
13919
  var import_node_child_process4 = require("child_process");
13860
- var import_node_fs33 = require("fs");
13920
+ var import_node_fs34 = require("fs");
13861
13921
  var import_node_os11 = require("os");
13862
- var import_node_path29 = require("path");
13922
+ var import_node_path30 = require("path");
13863
13923
  var import_node_module4 = require("module");
13864
13924
  init_worktree();
13865
13925
  init_thread_store();
13866
13926
  var import_meta4 = {};
13867
- var CONDUCTOR_APP_SUPPORT = (0, import_node_path29.join)(
13927
+ var CONDUCTOR_APP_SUPPORT = (0, import_node_path30.join)(
13868
13928
  process.env.HOME ?? "",
13869
13929
  "Library",
13870
13930
  "Application Support",
13871
13931
  "com.conductor.app"
13872
13932
  );
13873
- var CONDUCTOR_DB = (0, import_node_path29.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
13874
- var CURSOR_SDK_STORE = (0, import_node_path29.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
13933
+ var CONDUCTOR_DB = (0, import_node_path30.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
13934
+ var CURSOR_SDK_STORE = (0, import_node_path30.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
13875
13935
  function openReadonlySqlite(file) {
13876
13936
  const req = (0, import_node_module4.createRequire)(import_meta4.url);
13877
13937
  const Database = req("better-sqlite3");
@@ -13888,21 +13948,21 @@ function mapAgentType(raw) {
13888
13948
  return null;
13889
13949
  }
13890
13950
  function resolveConductorCursorAgentId(workspacePath) {
13891
- if (!workspacePath || !(0, import_node_fs33.existsSync)(CURSOR_SDK_STORE)) return null;
13951
+ if (!workspacePath || !(0, import_node_fs34.existsSync)(CURSOR_SDK_STORE)) return null;
13892
13952
  const normalized = workspacePath.replace(/\/$/, "");
13893
13953
  let best = null;
13894
13954
  let hashes;
13895
13955
  try {
13896
- hashes = (0, import_node_fs33.readdirSync)(CURSOR_SDK_STORE);
13956
+ hashes = (0, import_node_fs34.readdirSync)(CURSOR_SDK_STORE);
13897
13957
  } catch {
13898
13958
  return null;
13899
13959
  }
13900
13960
  for (const hash of hashes) {
13901
- const agentsFile = (0, import_node_path29.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
13902
- if (!(0, import_node_fs33.existsSync)(agentsFile)) continue;
13961
+ const agentsFile = (0, import_node_path30.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
13962
+ if (!(0, import_node_fs34.existsSync)(agentsFile)) continue;
13903
13963
  let text3;
13904
13964
  try {
13905
- text3 = (0, import_node_fs33.readFileSync)(agentsFile, "utf8");
13965
+ text3 = (0, import_node_fs34.readFileSync)(agentsFile, "utf8");
13906
13966
  } catch {
13907
13967
  continue;
13908
13968
  }
@@ -13926,7 +13986,7 @@ function resolveConductorCursorAgentId(workspacePath) {
13926
13986
  return best?.agentId ?? null;
13927
13987
  }
13928
13988
  async function adoptThread(input) {
13929
- if (!(0, import_node_fs33.existsSync)(input.worktreePath)) {
13989
+ if (!(0, import_node_fs34.existsSync)(input.worktreePath)) {
13930
13990
  throw new Error(`Worktree not found: ${input.worktreePath}`);
13931
13991
  }
13932
13992
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -13953,18 +14013,18 @@ function conductorDbPath() {
13953
14013
  return CONDUCTOR_DB;
13954
14014
  }
13955
14015
  function listConductorWorkspaces() {
13956
- if (!(0, import_node_fs33.existsSync)(CONDUCTOR_DB)) {
14016
+ if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
13957
14017
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
13958
14018
  }
13959
- const tmp = (0, import_node_fs33.mkdtempSync)((0, import_node_path29.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
13960
- const snapshot = (0, import_node_path29.join)(tmp, "conductor.db");
14019
+ const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path30.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
14020
+ const snapshot = (0, import_node_path30.join)(tmp, "conductor.db");
13961
14021
  try {
13962
- (0, import_node_fs33.copyFileSync)(CONDUCTOR_DB, snapshot);
14022
+ (0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
13963
14023
  for (const suffix of ["-wal", "-shm"]) {
13964
14024
  const src = `${CONDUCTOR_DB}${suffix}`;
13965
- if ((0, import_node_fs33.existsSync)(src)) {
14025
+ if ((0, import_node_fs34.existsSync)(src)) {
13966
14026
  try {
13967
- (0, import_node_fs33.copyFileSync)(src, `${snapshot}${suffix}`);
14027
+ (0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
13968
14028
  } catch {
13969
14029
  }
13970
14030
  }
@@ -14040,22 +14100,22 @@ function listConductorWorkspaces() {
14040
14100
  db.close();
14041
14101
  }
14042
14102
  } finally {
14043
- (0, import_node_fs33.rmSync)(tmp, { recursive: true, force: true });
14103
+ (0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
14044
14104
  }
14045
14105
  }
14046
14106
  function importConductorWorkspace(workspaceId) {
14047
- if (!(0, import_node_fs33.existsSync)(CONDUCTOR_DB)) {
14107
+ if (!(0, import_node_fs34.existsSync)(CONDUCTOR_DB)) {
14048
14108
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
14049
14109
  }
14050
- const tmp = (0, import_node_fs33.mkdtempSync)((0, import_node_path29.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
14051
- const snapshot = (0, import_node_path29.join)(tmp, "conductor.db");
14110
+ const tmp = (0, import_node_fs34.mkdtempSync)((0, import_node_path30.join)((0, import_node_os11.tmpdir)(), "sideboard-conductor-"));
14111
+ const snapshot = (0, import_node_path30.join)(tmp, "conductor.db");
14052
14112
  try {
14053
- (0, import_node_fs33.copyFileSync)(CONDUCTOR_DB, snapshot);
14113
+ (0, import_node_fs34.copyFileSync)(CONDUCTOR_DB, snapshot);
14054
14114
  for (const suffix of ["-wal", "-shm"]) {
14055
14115
  const src = `${CONDUCTOR_DB}${suffix}`;
14056
- if ((0, import_node_fs33.existsSync)(src)) {
14116
+ if ((0, import_node_fs34.existsSync)(src)) {
14057
14117
  try {
14058
- (0, import_node_fs33.copyFileSync)(src, `${snapshot}${suffix}`);
14118
+ (0, import_node_fs34.copyFileSync)(src, `${snapshot}${suffix}`);
14059
14119
  } catch {
14060
14120
  }
14061
14121
  }
@@ -14073,7 +14133,7 @@ function importConductorWorkspace(workspaceId) {
14073
14133
  ).get(workspaceId);
14074
14134
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
14075
14135
  const worktreePath = String(row.workspacePath);
14076
- if (!(0, import_node_fs33.existsSync)(worktreePath)) {
14136
+ if (!(0, import_node_fs34.existsSync)(worktreePath)) {
14077
14137
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
14078
14138
  }
14079
14139
  let sessionId = null;
@@ -14136,7 +14196,7 @@ function importConductorWorkspace(workspaceId) {
14136
14196
  db.close();
14137
14197
  }
14138
14198
  } finally {
14139
- (0, import_node_fs33.rmSync)(tmp, { recursive: true, force: true });
14199
+ (0, import_node_fs34.rmSync)(tmp, { recursive: true, force: true });
14140
14200
  }
14141
14201
  }
14142
14202
  async function importConductorWorkspaceAsync(workspaceId) {
@@ -14147,8 +14207,8 @@ async function importConductorWorkspaceAsync(workspaceId) {
14147
14207
  var import_node_events = require("events");
14148
14208
 
14149
14209
  // src/slack/outbound-watch.ts
14150
- var import_node_fs35 = require("fs");
14151
- var import_node_path32 = require("path");
14210
+ var import_node_fs36 = require("fs");
14211
+ var import_node_path33 = require("path");
14152
14212
  init_paths();
14153
14213
  init_private_file();
14154
14214
  init_secure_file();
@@ -14194,19 +14254,19 @@ async function slackAuthTest(token) {
14194
14254
  }
14195
14255
 
14196
14256
  // src/slack/reply-target.ts
14197
- var import_node_fs34 = require("fs");
14198
- var import_node_path30 = require("path");
14257
+ var import_node_fs35 = require("fs");
14258
+ var import_node_path31 = require("path");
14199
14259
  init_paths();
14200
14260
  init_private_file();
14201
14261
  init_secure_file();
14202
14262
  function storePath2() {
14203
- return (0, import_node_path30.join)(appDataDir(), "slack-reply-to.json");
14263
+ return (0, import_node_path31.join)(appDataDir(), "slack-reply-to.json");
14204
14264
  }
14205
14265
  function readStore2() {
14206
14266
  const path2 = storePath2();
14207
- if (!(0, import_node_fs34.existsSync)(path2)) return {};
14267
+ if (!(0, import_node_fs35.existsSync)(path2)) return {};
14208
14268
  try {
14209
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs34.readFileSync)(path2, "utf8"));
14269
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs35.readFileSync)(path2, "utf8"));
14210
14270
  return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
14211
14271
  } catch {
14212
14272
  return {};
@@ -14223,11 +14283,11 @@ function getSlackReplyTarget(threadId) {
14223
14283
  }
14224
14284
 
14225
14285
  // src/slack/workspaces.ts
14226
- var import_node_path31 = require("path");
14286
+ var import_node_path32 = require("path");
14227
14287
  init_paths();
14228
14288
  init_secure_file();
14229
14289
  function storePath3() {
14230
- return (0, import_node_path31.join)(appDataDir(), "slack-workspaces.json");
14290
+ return (0, import_node_path32.join)(appDataDir(), "slack-workspaces.json");
14231
14291
  }
14232
14292
  function readStore3() {
14233
14293
  try {
@@ -14343,7 +14403,7 @@ var POLL_INTERVAL_MS = 12e3;
14343
14403
  var lastPollMs = 0;
14344
14404
  var nameCache = /* @__PURE__ */ new Map();
14345
14405
  function storePath4() {
14346
- return (0, import_node_path32.join)(appDataDir(), "slack-outbound-watch.json");
14406
+ return (0, import_node_path33.join)(appDataDir(), "slack-outbound-watch.json");
14347
14407
  }
14348
14408
  function watchId(teamId, channelId, ts) {
14349
14409
  return `${teamId}:${channelId}:${ts}`;
@@ -14373,9 +14433,9 @@ function tsNewer(a, b) {
14373
14433
  }
14374
14434
  function readStore4() {
14375
14435
  const path2 = storePath4();
14376
- if (!(0, import_node_fs35.existsSync)(path2)) return [];
14436
+ if (!(0, import_node_fs36.existsSync)(path2)) return [];
14377
14437
  try {
14378
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs35.readFileSync)(path2, "utf8"));
14438
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs36.readFileSync)(path2, "utf8"));
14379
14439
  return Array.isArray(parsed?.watches) ? parsed.watches : [];
14380
14440
  } catch {
14381
14441
  return [];
@@ -14720,7 +14780,7 @@ async function refreshSlackReplyBadges(opts) {
14720
14780
  }
14721
14781
 
14722
14782
  // src/orchestrator/orchestrator.ts
14723
- var import_node_fs41 = require("fs");
14783
+ var import_node_fs42 = require("fs");
14724
14784
  init_error_detail();
14725
14785
  init_agents();
14726
14786
  init_worktree();
@@ -14741,8 +14801,8 @@ function shouldAutoArchiveOnPrMerge(opts) {
14741
14801
  }
14742
14802
 
14743
14803
  // src/git/orphan-cleanup.ts
14744
- var import_node_fs36 = require("fs");
14745
- var import_node_path33 = require("path");
14804
+ var import_node_fs37 = require("fs");
14805
+ var import_node_path34 = require("path");
14746
14806
  init_worktree();
14747
14807
  init_thread_store();
14748
14808
  init_paths();
@@ -14757,9 +14817,9 @@ async function findOrphanWorktrees(repoPaths) {
14757
14817
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
14758
14818
  );
14759
14819
  const homeRoot = sideboardWorkspacesDir();
14760
- if ((0, import_node_fs36.existsSync)(homeRoot)) {
14820
+ if ((0, import_node_fs37.existsSync)(homeRoot)) {
14761
14821
  try {
14762
- for (const entry of (0, import_node_fs36.readdirSync)(homeRoot, { withFileTypes: true })) {
14822
+ for (const entry of (0, import_node_fs37.readdirSync)(homeRoot, { withFileTypes: true })) {
14763
14823
  if (!entry.isDirectory()) continue;
14764
14824
  void entry;
14765
14825
  }
@@ -14769,7 +14829,7 @@ async function findOrphanWorktrees(repoPaths) {
14769
14829
  const orphans = [];
14770
14830
  const seen = /* @__PURE__ */ new Set();
14771
14831
  for (const repoPath of repos) {
14772
- if (!repoPath || !(0, import_node_fs36.existsSync)(repoPath)) continue;
14832
+ if (!repoPath || !(0, import_node_fs37.existsSync)(repoPath)) continue;
14773
14833
  try {
14774
14834
  const wts = await listWorktrees(repoPath);
14775
14835
  for (const wt of wts) {
@@ -14780,7 +14840,7 @@ async function findOrphanWorktrees(repoPaths) {
14780
14840
  seen.add(path2);
14781
14841
  let mtimeMs = 0;
14782
14842
  try {
14783
- mtimeMs = (0, import_node_fs36.statSync)(path2).mtimeMs;
14843
+ mtimeMs = (0, import_node_fs37.statSync)(path2).mtimeMs;
14784
14844
  } catch {
14785
14845
  mtimeMs = 0;
14786
14846
  }
@@ -14790,16 +14850,16 @@ async function findOrphanWorktrees(repoPaths) {
14790
14850
  }
14791
14851
  try {
14792
14852
  const root = worktreesRoot(repoPath);
14793
- if ((0, import_node_fs36.existsSync)(root)) {
14794
- for (const entry of (0, import_node_fs36.readdirSync)(root, { withFileTypes: true })) {
14853
+ if ((0, import_node_fs37.existsSync)(root)) {
14854
+ for (const entry of (0, import_node_fs37.readdirSync)(root, { withFileTypes: true })) {
14795
14855
  if (!entry.isDirectory()) continue;
14796
- const path2 = (0, import_node_path33.join)(root, entry.name).replace(/\/$/, "");
14856
+ const path2 = (0, import_node_path34.join)(root, entry.name).replace(/\/$/, "");
14797
14857
  if (known.has(path2) || seen.has(path2)) continue;
14798
- if (!(0, import_node_fs36.existsSync)((0, import_node_path33.join)(path2, ".git"))) continue;
14858
+ if (!(0, import_node_fs37.existsSync)((0, import_node_path34.join)(path2, ".git"))) continue;
14799
14859
  seen.add(path2);
14800
14860
  let mtimeMs = 0;
14801
14861
  try {
14802
- mtimeMs = (0, import_node_fs36.statSync)(path2).mtimeMs;
14862
+ mtimeMs = (0, import_node_fs37.statSync)(path2).mtimeMs;
14803
14863
  } catch {
14804
14864
  mtimeMs = Date.now();
14805
14865
  }
@@ -14945,8 +15005,8 @@ async function applyThreadIntoMain(thread, opts) {
14945
15005
  }
14946
15006
 
14947
15007
  // src/git/clone-repo.ts
14948
- var import_node_fs37 = require("fs");
14949
- var import_node_path34 = require("path");
15008
+ var import_node_fs38 = require("fs");
15009
+ var import_node_path35 = require("path");
14950
15010
  var import_execa6 = require("execa");
14951
15011
  init_paths();
14952
15012
  init_workspaces();
@@ -14956,12 +15016,12 @@ async function cloneRepoIntoSideboard(opts) {
14956
15016
  if (!url) throw new Error("Clone URL is required");
14957
15017
  let name = opts.name?.trim();
14958
15018
  if (!name) {
14959
- const leaf = (0, import_node_path34.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15019
+ const leaf = (0, import_node_path35.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
14960
15020
  name = leaf || "repo";
14961
15021
  }
14962
15022
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
14963
- const dest = (0, import_node_path34.join)(sideboardReposDir(), name);
14964
- if ((0, import_node_fs37.existsSync)(dest)) {
15023
+ const dest = (0, import_node_path35.join)(sideboardReposDir(), name);
15024
+ if ((0, import_node_fs38.existsSync)(dest)) {
14965
15025
  const repoPath2 = await resolveRepoRoot(dest);
14966
15026
  const workspace2 = await ensureWorkspace(repoPath2);
14967
15027
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -14983,8 +15043,8 @@ init_orchestrator_capable();
14983
15043
 
14984
15044
  // src/review/request-review.ts
14985
15045
  var import_node_crypto8 = require("crypto");
14986
- var import_node_fs38 = require("fs");
14987
- var import_node_path35 = require("path");
15046
+ var import_node_fs39 = require("fs");
15047
+ var import_node_path36 = require("path");
14988
15048
  init_global_workspace();
14989
15049
  init_thread_store();
14990
15050
 
@@ -15132,22 +15192,22 @@ function shouldRefreshReviewRequestTemplate(content) {
15132
15192
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
15133
15193
  }
15134
15194
  function readTextIfPresent(abs) {
15135
- if (!(0, import_node_fs38.existsSync)(abs)) return null;
15195
+ if (!(0, import_node_fs39.existsSync)(abs)) return null;
15136
15196
  try {
15137
- const content = (0, import_node_fs38.readFileSync)(abs, "utf8");
15197
+ const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
15138
15198
  return content.trim() ? content : null;
15139
15199
  } catch {
15140
15200
  return null;
15141
15201
  }
15142
15202
  }
15143
15203
  function ensureAttachmentsGitignore(worktreePath) {
15144
- const gitignoreAbs = (0, import_node_path35.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
15145
- if ((0, import_node_fs38.existsSync)(gitignoreAbs)) return;
15146
- (0, import_node_fs38.mkdirSync)((0, import_node_path35.dirname)(gitignoreAbs), { recursive: true });
15147
- (0, import_node_fs38.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
15204
+ const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
15205
+ if ((0, import_node_fs39.existsSync)(gitignoreAbs)) return;
15206
+ (0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
15207
+ (0, import_node_fs39.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
15148
15208
  }
15149
15209
  function resolveReviewGuidelines(worktreePath) {
15150
- const repoAbs = (0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH);
15210
+ const repoAbs = (0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH);
15151
15211
  const repoContent = readTextIfPresent(repoAbs);
15152
15212
  if (repoContent) {
15153
15213
  return {
@@ -15157,7 +15217,7 @@ function resolveReviewGuidelines(worktreePath) {
15157
15217
  source: "repo"
15158
15218
  };
15159
15219
  }
15160
- const localAbs = (0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH);
15220
+ const localAbs = (0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH);
15161
15221
  const localContent = readTextIfPresent(localAbs);
15162
15222
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
15163
15223
  return {
@@ -15167,7 +15227,7 @@ function resolveReviewGuidelines(worktreePath) {
15167
15227
  source: "local"
15168
15228
  };
15169
15229
  }
15170
- const legacyAbs = (0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
15230
+ const legacyAbs = (0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
15171
15231
  const legacyContent = readTextIfPresent(legacyAbs);
15172
15232
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
15173
15233
  return {
@@ -15178,8 +15238,8 @@ function resolveReviewGuidelines(worktreePath) {
15178
15238
  };
15179
15239
  }
15180
15240
  ensureAttachmentsGitignore(worktreePath);
15181
- (0, import_node_fs38.mkdirSync)((0, import_node_path35.dirname)(localAbs), { recursive: true });
15182
- (0, import_node_fs38.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
15241
+ (0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(localAbs), { recursive: true });
15242
+ (0, import_node_fs39.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
15183
15243
  return {
15184
15244
  path: REVIEW_REQUEST_PATH,
15185
15245
  name: REVIEW_REQUEST_NAME,
@@ -15188,7 +15248,7 @@ function resolveReviewGuidelines(worktreePath) {
15188
15248
  };
15189
15249
  }
15190
15250
  function ensureReviewRequestFile(worktreePath) {
15191
- const repoAbs = (0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH);
15251
+ const repoAbs = (0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH);
15192
15252
  const repoContent = readTextIfPresent(repoAbs);
15193
15253
  if (repoContent) {
15194
15254
  return {
@@ -15198,10 +15258,10 @@ function ensureReviewRequestFile(worktreePath) {
15198
15258
  source: "repo"
15199
15259
  };
15200
15260
  }
15201
- const localAbs = (0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH);
15202
- const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
15261
+ const localAbs = (0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH);
15262
+ const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
15203
15263
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
15204
- const path2 = (0, import_node_fs38.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
15264
+ const path2 = (0, import_node_fs39.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
15205
15265
  return {
15206
15266
  path: path2,
15207
15267
  name: REVIEW_REQUEST_NAME,
@@ -15209,8 +15269,8 @@ function ensureReviewRequestFile(worktreePath) {
15209
15269
  source: "local"
15210
15270
  };
15211
15271
  }
15212
- (0, import_node_fs38.mkdirSync)((0, import_node_path35.dirname)(repoAbs), { recursive: true });
15213
- (0, import_node_fs38.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
15272
+ (0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(repoAbs), { recursive: true });
15273
+ (0, import_node_fs39.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
15214
15274
  return {
15215
15275
  path: REPO_REVIEW_PATH,
15216
15276
  name: REPO_REVIEW_NAME,
@@ -15230,7 +15290,7 @@ function buildReviewRequestAttachment(content, opts) {
15230
15290
  };
15231
15291
  }
15232
15292
  function readExistingReviewRequestFile(worktreePath) {
15233
- return readTextIfPresent((0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
15293
+ return readTextIfPresent((0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
15234
15294
  }
15235
15295
  async function requestReview(threadRef, send2) {
15236
15296
  const from = findThreadByRef(threadRef);
@@ -15496,7 +15556,7 @@ var Orchestrator = class {
15496
15556
  }
15497
15557
  continue;
15498
15558
  }
15499
- if (!(0, import_node_fs41.existsSync)(thread.worktreePath)) {
15559
+ if (!(0, import_node_fs42.existsSync)(thread.worktreePath)) {
15500
15560
  setStatus(thread.id, "broken", "Worktree missing on disk");
15501
15561
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
15502
15562
  continue;
@@ -15734,6 +15794,9 @@ var Orchestrator = class {
15734
15794
  }
15735
15795
  return withThreadLock(thread.id, async () => {
15736
15796
  const current = this.requireThread(thread.id);
15797
+ if (current.status === "archived") {
15798
+ throw new Error(`Thread is archived: ${thread.id}`);
15799
+ }
15737
15800
  const queue = [...current.queue, prompt];
15738
15801
  this.haltDrain.delete(thread.id);
15739
15802
  const patch = { queue, status: "queued" };
@@ -15744,7 +15807,9 @@ var Orchestrator = class {
15744
15807
  updateThread(thread.id, patch);
15745
15808
  this.emit({ type: "queue_changed", threadId: thread.id, queue });
15746
15809
  this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
15747
- void this.drainQueue(thread.id);
15810
+ if (thisProcessShouldDrainAgentQueues()) {
15811
+ void this.drainQueue(thread.id);
15812
+ }
15748
15813
  return this.requireThread(thread.id);
15749
15814
  });
15750
15815
  }
@@ -15797,10 +15862,10 @@ var Orchestrator = class {
15797
15862
  async sendQueuedMessageNow(threadRef, index) {
15798
15863
  const thread = this.requireThread(threadRef);
15799
15864
  const promoted = await withThreadLock(thread.id, async () => {
15800
- const current = this.requireThread(thread.id);
15801
- if (index < 0 || index >= current.queue.length) return false;
15802
- const item = current.queue[index];
15803
- const rest = current.queue.filter((_, i) => i !== index);
15865
+ const current2 = this.requireThread(thread.id);
15866
+ if (index < 0 || index >= current2.queue.length) return false;
15867
+ const item = current2.queue[index];
15868
+ const rest = current2.queue.filter((_, i) => i !== index);
15804
15869
  const queue = [item, ...rest];
15805
15870
  this.haltDrain.delete(thread.id);
15806
15871
  updateThread(thread.id, { queue });
@@ -15808,10 +15873,16 @@ var Orchestrator = class {
15808
15873
  return true;
15809
15874
  });
15810
15875
  if (!promoted) return this.requireThread(thread.id);
15876
+ const current = this.requireThread(thread.id);
15811
15877
  const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id);
15878
+ const livePid = current.agentPid;
15879
+ const foreignLive = !inFlight && typeof livePid === "number" && livePid > 0 && isPidAlive(livePid);
15812
15880
  if (inFlight) {
15813
15881
  this.stop(thread.id, { clearQueue: false, continueQueue: true });
15814
15882
  } else {
15883
+ if (foreignLive) {
15884
+ this.stop(thread.id, { clearQueue: false, continueQueue: true });
15885
+ }
15815
15886
  void this.drainQueue(thread.id);
15816
15887
  }
15817
15888
  return this.requireThread(thread.id);
@@ -16246,6 +16317,13 @@ var Orchestrator = class {
16246
16317
  if (handle) handle.kill();
16247
16318
  const proc = this.processes.get(`${thread.id}:agent`);
16248
16319
  if (proc) proc.kill();
16320
+ const pid = thread.agentPid;
16321
+ if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) {
16322
+ try {
16323
+ process.kill(pid, "SIGTERM");
16324
+ } catch {
16325
+ }
16326
+ }
16249
16327
  const stopped = writeLiveStatus(thread.id, "stopped") ?? readThread(thread.id) ?? thread;
16250
16328
  if (stopped.status === "stopped") {
16251
16329
  this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
@@ -17026,7 +17104,7 @@ var Orchestrator = class {
17026
17104
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
17027
17105
  return restored2;
17028
17106
  }
17029
- if (!(0, import_node_fs41.existsSync)(thread.worktreePath)) {
17107
+ if (!(0, import_node_fs42.existsSync)(thread.worktreePath)) {
17030
17108
  const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
17031
17109
  const { execa: execa7 } = await import("execa");
17032
17110
  const slug = thread.worktreePath.split("/").pop();
@@ -17267,7 +17345,7 @@ init_coordinator_prompt();
17267
17345
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
17268
17346
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
17269
17347
  var import_zod3 = require("zod");
17270
- var import_node_path38 = require("path");
17348
+ var import_node_path39 = require("path");
17271
17349
  init_worktree();
17272
17350
  init_global_workspace();
17273
17351
  init_list_models();
@@ -17954,7 +18032,7 @@ async function startMcpServer() {
17954
18032
  async () => {
17955
18033
  const threads = orch.getThreads(true);
17956
18034
  const lines = threads.map((t) => {
17957
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path38.basename)(t.repoPath) || t.repoPath;
18035
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path39.basename)(t.repoPath) || t.repoPath;
17958
18036
  return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
17959
18037
  });
17960
18038
  return {
@@ -19263,16 +19341,16 @@ init_connected_teams();
19263
19341
  init_injected_mcp();
19264
19342
 
19265
19343
  // src/agents/user-mcp-config.ts
19266
- var import_node_fs42 = require("fs");
19344
+ var import_node_fs43 = require("fs");
19267
19345
  var import_node_os12 = require("os");
19268
- var import_node_path39 = require("path");
19346
+ var import_node_path40 = require("path");
19269
19347
  init_paths();
19270
19348
  init_injected_mcp();
19271
19349
  function userCursorMcpConfigPath() {
19272
- return (0, import_node_path39.join)((0, import_node_os12.homedir)(), ".cursor", "mcp.json");
19350
+ return (0, import_node_path40.join)((0, import_node_os12.homedir)(), ".cursor", "mcp.json");
19273
19351
  }
19274
19352
  function userClaudeMcpConfigPath() {
19275
- return (0, import_node_path39.join)((0, import_node_os12.homedir)(), ".claude.json");
19353
+ return (0, import_node_path40.join)((0, import_node_os12.homedir)(), ".claude.json");
19276
19354
  }
19277
19355
  function asObject(value) {
19278
19356
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -19299,16 +19377,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
19299
19377
  }
19300
19378
  function writeMergedMcpServersJson(configPath, sideboard) {
19301
19379
  let existing = {};
19302
- if ((0, import_node_fs42.existsSync)(configPath)) {
19380
+ if ((0, import_node_fs43.existsSync)(configPath)) {
19303
19381
  try {
19304
- existing = JSON.parse((0, import_node_fs42.readFileSync)(configPath, "utf8"));
19382
+ existing = JSON.parse((0, import_node_fs43.readFileSync)(configPath, "utf8"));
19305
19383
  } catch {
19306
19384
  existing = {};
19307
19385
  }
19308
19386
  }
19309
19387
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
19310
- (0, import_node_fs42.mkdirSync)((0, import_node_path39.dirname)(configPath), { recursive: true });
19311
- (0, import_node_fs42.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
19388
+ (0, import_node_fs43.mkdirSync)((0, import_node_path40.dirname)(configPath), { recursive: true });
19389
+ (0, import_node_fs43.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
19312
19390
  `);
19313
19391
  }
19314
19392
  function launchFromResolved(server) {
@@ -19326,7 +19404,7 @@ async function registerPackagedUserMcpClients() {
19326
19404
  const cursor = userCursorMcpConfigPath();
19327
19405
  writeMergedMcpServersJson(cursor, launch);
19328
19406
  const claude = userClaudeMcpConfigPath();
19329
- if ((0, import_node_fs42.existsSync)(claude)) {
19407
+ if ((0, import_node_fs43.existsSync)(claude)) {
19330
19408
  writeMergedMcpServersJson(claude, launch);
19331
19409
  return { cursor, claude };
19332
19410
  }
@@ -20130,11 +20208,16 @@ function slackInboundSuperseded(opts) {
20130
20208
  }
20131
20209
  return opts.currentInboundGeneration() !== opts.inboundGeneration;
20132
20210
  }
20133
- function interruptSlackCoordinatorForInbound(msg, agent, log = () => void 0) {
20211
+ function slackCoordinatorGone(err) {
20212
+ const errMsg = err instanceof Error ? err.message : String(err);
20213
+ return /thread not found|thread is archived/i.test(errMsg);
20214
+ }
20215
+ function interruptSlackCoordinatorForInbound(msg, _agent, log = () => void 0) {
20134
20216
  const userId = msg.userId?.trim();
20135
20217
  if (!userId) return false;
20136
20218
  try {
20137
- const coordinator = ensureSlackCoordinator(msg.teamId, userId, agent);
20219
+ const coordinator = findSlackCoordinator(msg.teamId, userId);
20220
+ if (!coordinator) return false;
20138
20221
  const fresh = readThread(coordinator.id) ?? coordinator;
20139
20222
  if (fresh.status !== "running" && fresh.status !== "queued") return false;
20140
20223
  getOrchestrator().stop(fresh.id, { clearQueue: true });
@@ -20300,15 +20383,16 @@ async function handleSlackInbound(msg, opts) {
20300
20383
  log(`skip superseded ${msg.kind} ${msg.ts}`);
20301
20384
  return;
20302
20385
  }
20303
- const coordinator = ensureSlackCoordinator(msg.teamId, userId, agent);
20304
- let fresh = readThread(coordinator.id) ?? coordinator;
20305
20386
  if (isSlackStopCommand(msg.text)) {
20306
- try {
20307
- getOrchestrator().stop(fresh.id, { clearQueue: true });
20308
- log(`stop ${msg.kind} ${msg.ts} \u2192 coordinator ${fresh.id.slice(0, 8)}`);
20309
- } catch (err) {
20310
- const errMsg = err instanceof Error ? err.message : String(err);
20311
- log(`stop ${msg.ts}: ${errMsg}`);
20387
+ const live = findSlackCoordinator(msg.teamId, userId);
20388
+ if (live) {
20389
+ try {
20390
+ getOrchestrator().stop(live.id, { clearQueue: true });
20391
+ log(`stop ${msg.kind} ${msg.ts} \u2192 coordinator ${live.id.slice(0, 8)}`);
20392
+ } catch (err) {
20393
+ const errMsg = err instanceof Error ? err.message : String(err);
20394
+ log(`stop ${msg.ts}: ${errMsg}`);
20395
+ }
20312
20396
  }
20313
20397
  if (slackInboundSuperseded(opts)) {
20314
20398
  log(`skip superseded stop reply ${msg.ts}`);
@@ -20318,34 +20402,65 @@ async function handleSlackInbound(msg, opts) {
20318
20402
  log(`replied stopped ${msg.ts}`);
20319
20403
  return;
20320
20404
  }
20405
+ const opened = ensureSlackCoordinator(msg.teamId, userId, agent);
20406
+ let fresh = readThread(opened.id) ?? opened;
20321
20407
  if (fresh.status === "running" || fresh.status === "queued") {
20322
20408
  interruptSlackCoordinatorForInbound(msg, agent, log);
20323
- fresh = readThread(coordinator.id) ?? coordinator;
20409
+ fresh = readThread(fresh.id) ?? fresh;
20324
20410
  }
20325
20411
  log(
20326
20412
  `run ${msg.kind} ${msg.ts} user ${userId} \u2192 coordinator ${fresh.id.slice(0, 8)} (${inventory.length} workspace${inventory.length === 1 ? "" : "s"})`
20327
20413
  );
20328
20414
  const prompt = formatSlackInboundPrompt(msg);
20329
- setSlackReplyTarget({
20330
- threadId: fresh.id,
20331
- teamId: msg.teamId,
20332
- channelId: msg.channelId,
20333
- threadTs: slackReplyThreadTs(msg)
20334
- });
20335
20415
  const orch = getOrchestrator();
20416
+ const bindReplyTarget = (threadId) => {
20417
+ setSlackReplyTarget({
20418
+ threadId,
20419
+ teamId: msg.teamId,
20420
+ channelId: msg.channelId,
20421
+ threadTs: slackReplyThreadTs(msg)
20422
+ });
20423
+ };
20424
+ bindReplyTarget(fresh.id);
20425
+ const runTurn = async (threadId) => {
20426
+ await orch.send(threadId, prompt);
20427
+ await orch.waitForTurn(threadId, 14 * 60 * 1e3);
20428
+ };
20336
20429
  let reply;
20337
20430
  try {
20338
- await orch.send(fresh.id, prompt);
20339
- await orch.waitForTurn(fresh.id, 14 * 60 * 1e3);
20431
+ try {
20432
+ await runTurn(fresh.id);
20433
+ } catch (err) {
20434
+ if (!slackCoordinatorGone(err)) throw err;
20435
+ log(`coordinator ${fresh.id.slice(0, 8)} gone, opening a new chat`);
20436
+ fresh = ensureSlackCoordinator(msg.teamId, userId, agent, { forceNew: true });
20437
+ bindReplyTarget(fresh.id);
20438
+ await runTurn(fresh.id);
20439
+ }
20340
20440
  if (slackInboundSuperseded(opts)) {
20341
20441
  log(`turn finished ${msg.ts} (superseded)`);
20342
20442
  return;
20343
20443
  }
20344
- const after = readThread(fresh.id);
20345
- if (!after || after.status === "stopped" || after.status === "archived") {
20444
+ let after = readThread(fresh.id);
20445
+ if (after?.status === "stopped") {
20346
20446
  log(`turn finished ${msg.ts} (interrupted, skip post)`);
20347
20447
  return;
20348
20448
  }
20449
+ if (!after || after.status === "archived") {
20450
+ log(`coordinator ${fresh.id.slice(0, 8)} closed, opening a new chat`);
20451
+ fresh = ensureSlackCoordinator(msg.teamId, userId, agent, { forceNew: true });
20452
+ bindReplyTarget(fresh.id);
20453
+ await runTurn(fresh.id);
20454
+ if (slackInboundSuperseded(opts)) {
20455
+ log(`turn finished ${msg.ts} (superseded)`);
20456
+ return;
20457
+ }
20458
+ after = readThread(fresh.id);
20459
+ if (!after || after.status === "stopped" || after.status === "archived") {
20460
+ log(`turn finished ${msg.ts} (interrupted, skip post)`);
20461
+ return;
20462
+ }
20463
+ }
20349
20464
  reply = orch.getTurnResult(fresh.id).text.trim();
20350
20465
  } catch (err) {
20351
20466
  if (slackInboundSuperseded(opts)) {
@@ -20353,8 +20468,7 @@ async function handleSlackInbound(msg, opts) {
20353
20468
  return;
20354
20469
  }
20355
20470
  const errMsg = err instanceof Error ? err.message : String(err);
20356
- const gone = /thread not found/i.test(errMsg);
20357
- if (gone) {
20471
+ if (slackCoordinatorGone(err)) {
20358
20472
  log(`turn finished ${msg.ts} (thread gone, skip post)`);
20359
20473
  return;
20360
20474
  }
@@ -20704,9 +20818,9 @@ var import_node_http3 = require("http");
20704
20818
  var import_ws3 = require("ws");
20705
20819
 
20706
20820
  // src/slack/relay-static.ts
20707
- var import_node_fs43 = require("fs");
20821
+ var import_node_fs44 = require("fs");
20708
20822
  var import_promises = require("fs/promises");
20709
- var import_node_path40 = __toESM(require("path"), 1);
20823
+ var import_node_path41 = __toESM(require("path"), 1);
20710
20824
  var TYPES = {
20711
20825
  ".css": "text/css; charset=utf-8",
20712
20826
  ".html": "text/html; charset=utf-8",
@@ -20737,9 +20851,9 @@ function resolveStaticPath(root, requestUrl) {
20737
20851
  return null;
20738
20852
  }
20739
20853
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
20740
- const rootResolved = import_node_path40.default.resolve(root);
20741
- const candidate = import_node_path40.default.resolve(rootResolved, `.${pathname}`);
20742
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path40.default.sep)) {
20854
+ const rootResolved = import_node_path41.default.resolve(root);
20855
+ const candidate = import_node_path41.default.resolve(rootResolved, `.${pathname}`);
20856
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path41.default.sep)) {
20743
20857
  return null;
20744
20858
  }
20745
20859
  return candidate;
@@ -20753,7 +20867,7 @@ async function fileSize(file) {
20753
20867
  }
20754
20868
  }
20755
20869
  function sendFile(req, res, file, size) {
20756
- const ext = import_node_path40.default.extname(file).toLowerCase();
20870
+ const ext = import_node_path41.default.extname(file).toLowerCase();
20757
20871
  res.writeHead(200, {
20758
20872
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
20759
20873
  "Content-Length": size,
@@ -20763,7 +20877,7 @@ function sendFile(req, res, file, size) {
20763
20877
  res.end();
20764
20878
  return true;
20765
20879
  }
20766
- (0, import_node_fs43.createReadStream)(file).pipe(res);
20880
+ (0, import_node_fs44.createReadStream)(file).pipe(res);
20767
20881
  return true;
20768
20882
  }
20769
20883
  async function tryServeStatic(req, res, root) {
@@ -20772,7 +20886,7 @@ async function tryServeStatic(req, res, root) {
20772
20886
  if (!candidate) return false;
20773
20887
  const direct = await fileSize(candidate);
20774
20888
  if (direct != null) return sendFile(req, res, candidate, direct);
20775
- const asIndex = import_node_path40.default.join(candidate, "index.html");
20889
+ const asIndex = import_node_path41.default.join(candidate, "index.html");
20776
20890
  const indexSize = await fileSize(asIndex);
20777
20891
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
20778
20892
  return false;
@@ -21098,6 +21212,7 @@ async function startSlackRelayServer(opts) {
21098
21212
  captureTurnBaseline,
21099
21213
  checkoutPrStackLayer,
21100
21214
  childEnvWithAppSettings,
21215
+ claimDesktopHost,
21101
21216
  claudeAdapter,
21102
21217
  claudeChromeEnabled,
21103
21218
  claudeUserSettingsPath,
@@ -21136,6 +21251,7 @@ async function startSlackRelayServer(opts) {
21136
21251
  decodeBrightsyTarget,
21137
21252
  deleteBranchOnPurgeEnabled,
21138
21253
  deleteThreadRecord,
21254
+ desktopHostPidPath,
21139
21255
  detectAgents,
21140
21256
  detectGhStack,
21141
21257
  detectLocalMergeConflicts,
@@ -21169,6 +21285,7 @@ async function startSlackRelayServer(opts) {
21169
21285
  findConventionSetup,
21170
21286
  findInvalidCacheControlTtlOrder,
21171
21287
  findOrphanWorktrees,
21288
+ findSlackCoordinator,
21172
21289
  findThreadByRef,
21173
21290
  findThreadForStackLayer,
21174
21291
  flattenTurnInput,
@@ -21260,6 +21377,7 @@ async function startSlackRelayServer(opts) {
21260
21377
  isConductorBundledCli,
21261
21378
  isCursorAutoModel,
21262
21379
  isDefaultishSourceRef,
21380
+ isDesktopHostAlive,
21263
21381
  isDirty,
21264
21382
  isGhRateLimitError,
21265
21383
  isGlobalRepoPath,
@@ -21281,6 +21399,7 @@ async function startSlackRelayServer(opts) {
21281
21399
  isSlackExternalReplyPrompt,
21282
21400
  isSlackOAuthCancelled,
21283
21401
  isThinkingEffort,
21402
+ isThisProcessDesktopHost,
21284
21403
  isThreadCaffeinated,
21285
21404
  isWorkspaceScratchPath,
21286
21405
  linearAuthorizationHeader,
@@ -21382,6 +21501,7 @@ async function startSlackRelayServer(opts) {
21382
21501
  refreshSlackReplyBadges,
21383
21502
  registerPackagedUserMcpClients,
21384
21503
  releaseCaffeinateHoldForThread,
21504
+ releaseDesktopHost,
21385
21505
  removeWorkspace,
21386
21506
  removeWorktree,
21387
21507
  repoSlug,
@@ -21482,6 +21602,7 @@ async function startSlackRelayServer(opts) {
21482
21602
  taskMessageText,
21483
21603
  thinkingEffortBars,
21484
21604
  thinkingEffortLabel,
21605
+ thisProcessShouldDrainAgentQueues,
21485
21606
  threadDisplayLabel,
21486
21607
  threadFilePath,
21487
21608
  threadLockPath,