@sideboard-ai/core 0.1.85 → 0.1.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/agents/cursor-runner.cjs +77 -29
  2. package/dist/agents/cursor-runner.js +55 -17
  3. package/dist/{agents-YAYNNJWC.js → agents-V6PVSQYH.js} +8 -8
  4. package/dist/{agents-FD77JUOP.js → agents-W5446HSV.js} +8 -8
  5. package/dist/{app-settings-PEXK5VEX.js → app-settings-F36ISTCF.js} +2 -2
  6. package/dist/{app-settings-K6RFCRF6.js → app-settings-HFINR3XG.js} +2 -2
  7. package/dist/{caffeinate-hold-EAZNWJBE.js → caffeinate-hold-I7SG6UQR.js} +2 -2
  8. package/dist/{caffeinate-hold-OHAUWOA6.js → caffeinate-hold-U3QJBV67.js} +2 -2
  9. package/dist/{chunk-XVFV56JG.js → chunk-3MA6JH6G.js} +5 -5
  10. package/dist/{chunk-FWJYLBO6.js → chunk-3WA37BRI.js} +1 -1
  11. package/dist/{chunk-JTHWVYSD.js → chunk-4PTN2LED.js} +5 -5
  12. package/dist/{chunk-RV6DBEDQ.js → chunk-7KDBDMNC.js} +1 -1
  13. package/dist/{chunk-SH75CXJR.js → chunk-A7LONVNO.js} +5 -5
  14. package/dist/{chunk-M37RITA6.js → chunk-B4R2VB2A.js} +164 -30
  15. package/dist/{chunk-6WQAYBVE.js → chunk-CY45C3GA.js} +4 -4
  16. package/dist/{chunk-6K5VAPVR.js → chunk-DKHGWYWR.js} +1 -1
  17. package/dist/{chunk-2N5DVTGH.js → chunk-HBXQQ5TO.js} +3 -3
  18. package/dist/{chunk-7MV3RXSC.js → chunk-JL4SJ6V7.js} +137 -26
  19. package/dist/{chunk-7FD7COKE.js → chunk-JOF3XIEM.js} +1 -1
  20. package/dist/{chunk-KRAUS3RF.js → chunk-L63LLCTX.js} +4 -4
  21. package/dist/{chunk-MFF2RE3I.js → chunk-NZPGMNFC.js} +1 -1
  22. package/dist/{chunk-HHTHF5BQ.js → chunk-QSLE4VEM.js} +4 -4
  23. package/dist/{chunk-3CCRD6WS.js → chunk-QWNROSRB.js} +6 -6
  24. package/dist/{chunk-JFQ2M6NQ.js → chunk-R2EOZNQI.js} +3 -3
  25. package/dist/{chunk-AY53MPDE.js → chunk-TC2KY5G7.js} +1 -1
  26. package/dist/{chunk-WGI6KXKJ.js → chunk-U4GZKLIV.js} +6 -6
  27. package/dist/{chunk-6GKDYUTJ.js → chunk-UVNXLTFB.js} +5 -5
  28. package/dist/{chunk-I3FRXL7J.js → chunk-XY6XXMAK.js} +1 -1
  29. package/dist/{connected-teams-BNBM7OIC.js → connected-teams-SWHJWK2A.js} +2 -2
  30. package/dist/{connected-teams-LSQ5TAZP.js → connected-teams-TLVKZPJP.js} +2 -2
  31. package/dist/{coordinator-prompt-VN7FF76K.js → coordinator-prompt-EC3KQLN3.js} +5 -5
  32. package/dist/{coordinator-prompt-YYQSPLIP.js → coordinator-prompt-PYRAXZN3.js} +5 -5
  33. package/dist/{cursor-recover-L5PNQUDT.js → cursor-recover-G34BYKL2.js} +1 -1
  34. package/dist/{cursor-recover-NNK7JPQM.js → cursor-recover-S5ORPW34.js} +1 -1
  35. package/dist/{global-workspace-BRIDCBMY.js → global-workspace-ICWOWUW6.js} +6 -6
  36. package/dist/{global-workspace-U3XVTQLL.js → global-workspace-T5IAJF4R.js} +6 -6
  37. package/dist/index.cjs +633 -526
  38. package/dist/index.d.cts +45 -11
  39. package/dist/index.d.ts +45 -11
  40. package/dist/index.js +212 -252
  41. package/dist/mcp/run-stdio.cjs +570 -490
  42. package/dist/mcp/run-stdio.js +184 -225
  43. package/dist/{paths-VPH3ITBK.js → paths-JQM2XRAD.js} +1 -1
  44. package/dist/{paths-2OFB7UJG.js → paths-TZX4L5X7.js} +1 -1
  45. package/dist/{thread-store-BUBR24YA.js → thread-store-V7NOOXKE.js} +2 -2
  46. package/dist/{thread-store-XTPFCJAI.js → thread-store-XAKWCV2E.js} +2 -2
  47. package/dist/{workspaces-IWQIWAMQ.js → workspaces-AJCAFW64.js} +7 -7
  48. package/dist/{workspaces-AIZDG6PS.js → workspaces-J4ULXOUH.js} +7 -7
  49. package/dist/{worktree-6ZALJUWG.js → worktree-4Z2VSHAQ.js} +4 -4
  50. package/dist/{worktree-7Y22WHR7.js → worktree-H57CCHWO.js} +4 -4
  51. package/package.json +1 -1
@@ -71,10 +71,129 @@ var init_nested_electron_env = __esm({
71
71
  }
72
72
  });
73
73
 
74
+ // src/hook/convention-setup.ts
75
+ function isFile(path) {
76
+ try {
77
+ return (0, import_node_fs.statSync)(path).isFile();
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
82
+ function normPath(p) {
83
+ return p.replace(/\/+$/, "");
84
+ }
85
+ function findConventionSetup(worktreePath, repoPath) {
86
+ const roots = [
87
+ { root: worktreePath, where: "worktree" }
88
+ ];
89
+ if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
90
+ roots.push({ root: repoPath, where: "main repo" });
91
+ }
92
+ for (const { root, where } of roots) {
93
+ for (const relPath of CONVENTION_SETUP_RELPATHS) {
94
+ const absPath = (0, import_node_path.join)(root, relPath);
95
+ if (!(0, import_node_fs.existsSync)(absPath) || !isFile(absPath)) continue;
96
+ return {
97
+ relPath,
98
+ absPath,
99
+ command: `bash ${JSON.stringify(absPath)}`,
100
+ source: `${relPath} (${where})`
101
+ };
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ var import_node_fs, import_node_path, CONVENTION_SETUP_RELPATHS;
107
+ var init_convention_setup = __esm({
108
+ "src/hook/convention-setup.ts"() {
109
+ "use strict";
110
+ import_node_fs = require("fs");
111
+ import_node_path = require("path");
112
+ CONVENTION_SETUP_RELPATHS = [
113
+ "script/setup",
114
+ "bin/setup",
115
+ "scripts/setup.sh",
116
+ "scripts/setup"
117
+ ];
118
+ }
119
+ });
120
+
121
+ // src/hook/cursor-worktrees.ts
122
+ function loadCursorWorktreesJson(rootPath) {
123
+ const path = (0, import_node_path2.join)(rootPath, ".cursor", "worktrees.json");
124
+ if (!(0, import_node_fs2.existsSync)(path)) return null;
125
+ try {
126
+ return JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
127
+ } catch {
128
+ return null;
129
+ }
130
+ }
131
+ function resolveSetupSpec(config) {
132
+ if (process.platform === "win32") {
133
+ return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
134
+ }
135
+ return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
136
+ }
137
+ async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
138
+ const fromWorktree = loadCursorWorktreesJson(worktreePath);
139
+ const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
140
+ const config = fromWorktree ?? fromRepo;
141
+ if (!config) return { ran: false, exitCode: null, source: null };
142
+ const spec = resolveSetupSpec(config);
143
+ if (!spec) return { ran: false, exitCode: null, source: null };
144
+ const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
145
+ const env = {
146
+ ...process.env,
147
+ ROOT_WORKTREE_PATH: repoPath
148
+ };
149
+ if (process.platform === "win32") {
150
+ env.ROOT_WORKTREE_PATH = repoPath;
151
+ }
152
+ const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path2.join)(
153
+ fromWorktree ? worktreePath : repoPath,
154
+ ".cursor",
155
+ spec
156
+ ) : spec];
157
+ let lastExit = 0;
158
+ for (const command of commands) {
159
+ const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
160
+ const shell = process.platform === "win32" ? "powershell" : "bash";
161
+ const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
162
+ onLine?.(`[cursor setup] ${command}`);
163
+ const child = (0, import_execa.execa)(shell, args, {
164
+ cwd: worktreePath,
165
+ reject: false,
166
+ env
167
+ });
168
+ if (child.stdout && onLine) {
169
+ const rl = (0, import_node_readline.createInterface)({ input: child.stdout });
170
+ rl.on("line", onLine);
171
+ }
172
+ if (child.stderr && onLine) {
173
+ const rl = (0, import_node_readline.createInterface)({ input: child.stderr });
174
+ rl.on("line", onLine);
175
+ }
176
+ const result = await child;
177
+ lastExit = result.exitCode ?? null;
178
+ if (lastExit !== 0 && lastExit !== null) break;
179
+ }
180
+ return { ran: true, exitCode: lastExit, source: sourceLabel };
181
+ }
182
+ var import_node_fs2, import_node_path2, import_execa, import_node_readline;
183
+ var init_cursor_worktrees = __esm({
184
+ "src/hook/cursor-worktrees.ts"() {
185
+ "use strict";
186
+ import_node_fs2 = require("fs");
187
+ import_node_path2 = require("path");
188
+ import_execa = require("execa");
189
+ import_node_readline = require("readline");
190
+ }
191
+ });
192
+
74
193
  // src/hook/settings.ts
75
194
  function expandHome(path) {
76
195
  if (path.startsWith("~/") || path === "~") {
77
- return (0, import_node_path.join)((0, import_node_os.homedir)(), path.slice(2));
196
+ return (0, import_node_path3.join)((0, import_node_os.homedir)(), path.slice(2));
78
197
  }
79
198
  return path;
80
199
  }
@@ -87,8 +206,8 @@ function parseAvailableIn(raw) {
87
206
  return out.length ? out : void 0;
88
207
  }
89
208
  function parseSettingsFile(path, source) {
90
- if (!(0, import_node_fs.existsSync)(path)) return null;
91
- const raw = (0, import_node_fs.readFileSync)(path, "utf8");
209
+ if (!(0, import_node_fs3.existsSync)(path)) return null;
210
+ const raw = (0, import_node_fs3.readFileSync)(path, "utf8");
92
211
  const data = (0, import_smol_toml.parse)(raw);
93
212
  const scripts = data.scripts ?? {};
94
213
  const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
@@ -191,15 +310,15 @@ function finalizeSettings(parsed) {
191
310
  };
192
311
  }
193
312
  function familyFiles(rootPath, source) {
194
- const dir = (0, import_node_path.join)(rootPath, `.${source}`);
313
+ const dir = (0, import_node_path3.join)(rootPath, `.${source}`);
195
314
  return {
196
- toml: (0, import_node_path.join)(dir, "settings.toml"),
197
- local: (0, import_node_path.join)(dir, "settings.local.toml")
315
+ toml: (0, import_node_path3.join)(dir, "settings.toml"),
316
+ local: (0, import_node_path3.join)(dir, "settings.local.toml")
198
317
  };
199
318
  }
200
319
  function familyExists(rootPath, source) {
201
320
  const files = familyFiles(rootPath, source);
202
- return (0, import_node_fs.existsSync)(files.toml) || (0, import_node_fs.existsSync)(files.local);
321
+ return (0, import_node_fs3.existsSync)(files.toml) || (0, import_node_fs3.existsSync)(files.local);
203
322
  }
204
323
  function detectFamily(rootPath) {
205
324
  if (familyExists(rootPath, "sideboard")) return "sideboard";
@@ -218,7 +337,7 @@ function loadAnyLocal(rootPath) {
218
337
  loadLocalToml(rootPath, "sideboard")
219
338
  );
220
339
  }
221
- function normPath(p) {
340
+ function normPath2(p) {
222
341
  return p.replace(/\/+$/, "");
223
342
  }
224
343
  function loadRepoSettings(repoPath) {
@@ -232,11 +351,11 @@ function loadRepoSettings(repoPath) {
232
351
  }
233
352
  function loadWorkspaceSettings(worktreePath, repoPath) {
234
353
  const wtFamily = detectFamily(worktreePath);
235
- const repoFamily = repoPath && normPath(repoPath) !== normPath(worktreePath) ? detectFamily(repoPath) : null;
354
+ const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
236
355
  const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
237
356
  const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
238
357
  let merged = wtToml ?? repoToml;
239
- if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
358
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
240
359
  merged = mergeSettings(merged, loadAnyLocal(repoPath));
241
360
  }
242
361
  merged = mergeSettings(merged, loadAnyLocal(worktreePath));
@@ -246,29 +365,31 @@ function settingsSourceLabel(rootPath) {
246
365
  const family = detectFamily(rootPath);
247
366
  if (!family) return null;
248
367
  const files = familyFiles(rootPath, family);
249
- if ((0, import_node_fs.existsSync)(files.toml) && (0, import_node_fs.existsSync)(files.local)) {
368
+ if ((0, import_node_fs3.existsSync)(files.toml) && (0, import_node_fs3.existsSync)(files.local)) {
250
369
  return `.${family}/settings.toml + local`;
251
370
  }
252
- if ((0, import_node_fs.existsSync)(files.local)) return `.${family}/settings.local.toml`;
371
+ if ((0, import_node_fs3.existsSync)(files.local)) return `.${family}/settings.local.toml`;
253
372
  return `.${family}/settings.toml`;
254
373
  }
255
374
  function workspaceSettingsSourceLabel(worktreePath, repoPath) {
256
375
  const wt = settingsSourceLabel(worktreePath);
257
376
  if (wt) return `${wt} (worktree)`;
258
- if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
377
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
259
378
  const repo = settingsSourceLabel(repoPath);
260
379
  if (repo) return `${repo} (main repo)`;
261
380
  }
262
381
  return null;
263
382
  }
264
- var import_node_fs, import_node_os, import_node_path, import_smol_toml;
383
+ var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
265
384
  var init_settings = __esm({
266
385
  "src/hook/settings.ts"() {
267
386
  "use strict";
268
- import_node_fs = require("fs");
387
+ import_node_fs3 = require("fs");
269
388
  import_node_os = require("os");
270
- import_node_path = require("path");
389
+ import_node_path3 = require("path");
271
390
  import_smol_toml = require("smol-toml");
391
+ init_convention_setup();
392
+ init_cursor_worktrees();
272
393
  }
273
394
  });
274
395
 
@@ -289,89 +410,89 @@ __export(paths_exports, {
289
410
  });
290
411
  function appDataDir() {
291
412
  const override = process.env.SIDEBOARD_APP_DATA?.trim();
292
- const base = override ? override : process.platform === "darwin" ? (0, import_node_path3.join)((0, import_node_os2.homedir)(), "Library", "Application Support", "sideboard") : process.platform === "win32" ? (0, import_node_path3.join)(process.env.APPDATA ?? (0, import_node_path3.join)((0, import_node_os2.homedir)(), "AppData", "Roaming"), "sideboard") : (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".local", "share", "sideboard");
293
- (0, import_node_fs2.mkdirSync)(base, { recursive: true });
413
+ const base = override ? override : process.platform === "darwin" ? (0, import_node_path5.join)((0, import_node_os2.homedir)(), "Library", "Application Support", "sideboard") : process.platform === "win32" ? (0, import_node_path5.join)(process.env.APPDATA ?? (0, import_node_path5.join)((0, import_node_os2.homedir)(), "AppData", "Roaming"), "sideboard") : (0, import_node_path5.join)((0, import_node_os2.homedir)(), ".local", "share", "sideboard");
414
+ (0, import_node_fs4.mkdirSync)(base, { recursive: true });
294
415
  return base;
295
416
  }
296
417
  function threadsDir() {
297
- const dir = (0, import_node_path3.join)(appDataDir(), "threads");
298
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
418
+ const dir = (0, import_node_path5.join)(appDataDir(), "threads");
419
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
299
420
  return dir;
300
421
  }
301
422
  function locksDir() {
302
- const dir = (0, import_node_path3.join)(appDataDir(), "locks");
303
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
423
+ const dir = (0, import_node_path5.join)(appDataDir(), "locks");
424
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
304
425
  return dir;
305
426
  }
306
427
  function sideboardHomeDir() {
307
- const dir = (0, import_node_path3.join)((0, import_node_os2.homedir)(), "sideboard");
308
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
428
+ const dir = (0, import_node_path5.join)((0, import_node_os2.homedir)(), "sideboard");
429
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
309
430
  return dir;
310
431
  }
311
432
  function sideboardReposDir() {
312
- const dir = (0, import_node_path3.join)(sideboardHomeDir(), "repos");
313
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
433
+ const dir = (0, import_node_path5.join)(sideboardHomeDir(), "repos");
434
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
314
435
  return dir;
315
436
  }
316
437
  function sideboardWorkspacesDir() {
317
- const dir = (0, import_node_path3.join)(sideboardHomeDir(), "workspaces");
318
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
438
+ const dir = (0, import_node_path5.join)(sideboardHomeDir(), "workspaces");
439
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
319
440
  return dir;
320
441
  }
321
442
  function repoSlug(repoPath) {
322
- return (0, import_node_path2.basename)(repoPath.replace(/\/$/, "")) || "repo";
443
+ return (0, import_node_path4.basename)(repoPath.replace(/\/$/, "")) || "repo";
323
444
  }
324
445
  function worktreesRoot(repoPath) {
325
446
  const settings = loadRepoSettings(repoPath);
326
447
  if (settings?.worktreesRoot) {
327
- (0, import_node_fs2.mkdirSync)(settings.worktreesRoot, { recursive: true });
448
+ (0, import_node_fs4.mkdirSync)(settings.worktreesRoot, { recursive: true });
328
449
  return settings.worktreesRoot;
329
450
  }
330
- const dir = (0, import_node_path3.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
331
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
451
+ const dir = (0, import_node_path5.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
452
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
332
453
  return dir;
333
454
  }
334
455
  function threadFilePath(id) {
335
- return (0, import_node_path3.join)(threadsDir(), `${id}.json`);
456
+ return (0, import_node_path5.join)(threadsDir(), `${id}.json`);
336
457
  }
337
458
  function threadLockPath(id) {
338
- return (0, import_node_path3.join)(locksDir(), `${id}.lock`);
459
+ return (0, import_node_path5.join)(locksDir(), `${id}.lock`);
339
460
  }
340
461
  function globalAgentCwd() {
341
- const dir = (0, import_node_path3.join)(appDataDir(), "global");
342
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
462
+ const dir = (0, import_node_path5.join)(appDataDir(), "global");
463
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
343
464
  return dir;
344
465
  }
345
- var import_node_path2, import_node_os2, import_node_path3, import_node_fs2;
466
+ var import_node_path4, import_node_os2, import_node_path5, import_node_fs4;
346
467
  var init_paths = __esm({
347
468
  "src/store/paths.ts"() {
348
469
  "use strict";
349
- import_node_path2 = require("path");
470
+ import_node_path4 = require("path");
350
471
  import_node_os2 = require("os");
351
- import_node_path3 = require("path");
352
- import_node_fs2 = require("fs");
472
+ import_node_path5 = require("path");
473
+ import_node_fs4 = require("fs");
353
474
  init_settings();
354
475
  }
355
476
  });
356
477
 
357
478
  // src/store/private-file.ts
358
479
  function writePrivateFile(path, contents) {
359
- (0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(path), { recursive: true });
360
- (0, import_node_fs3.writeFileSync)(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
480
+ (0, import_node_fs5.mkdirSync)((0, import_node_path6.dirname)(path), { recursive: true });
481
+ (0, import_node_fs5.writeFileSync)(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
361
482
  chmodOwnerOnly(path);
362
483
  }
363
484
  function chmodOwnerOnly(path) {
364
485
  try {
365
- (0, import_node_fs3.chmodSync)(path, PRIVATE_FILE_MODE);
486
+ (0, import_node_fs5.chmodSync)(path, PRIVATE_FILE_MODE);
366
487
  } catch {
367
488
  }
368
489
  }
369
- var import_node_fs3, import_node_path4, PRIVATE_FILE_MODE;
490
+ var import_node_fs5, import_node_path6, PRIVATE_FILE_MODE;
370
491
  var init_private_file = __esm({
371
492
  "src/store/private-file.ts"() {
372
493
  "use strict";
373
- import_node_fs3 = require("fs");
374
- import_node_path4 = require("path");
494
+ import_node_fs5 = require("fs");
495
+ import_node_path6 = require("path");
375
496
  PRIVATE_FILE_MODE = 384;
376
497
  }
377
498
  });
@@ -457,11 +578,11 @@ function decryptEnvelope(envelope, key) {
457
578
  return JSON.parse(plaintext.toString("utf8"));
458
579
  }
459
580
  function readSecureJson(path) {
460
- if (!(0, import_node_fs4.existsSync)(path)) return null;
581
+ if (!(0, import_node_fs6.existsSync)(path)) return null;
461
582
  chmodOwnerOnly(path);
462
583
  let parsed;
463
584
  try {
464
- parsed = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8"));
585
+ parsed = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
465
586
  } catch {
466
587
  return null;
467
588
  }
@@ -481,20 +602,20 @@ function writeSecureJson(path, value) {
481
602
  `);
482
603
  }
483
604
  function isSecureFileEncrypted(path) {
484
- if (!(0, import_node_fs4.existsSync)(path)) return false;
605
+ if (!(0, import_node_fs6.existsSync)(path)) return false;
485
606
  try {
486
- return isEnvelope(JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8")));
607
+ return isEnvelope(JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8")));
487
608
  } catch {
488
609
  return false;
489
610
  }
490
611
  }
491
- var import_node_child_process, import_node_crypto, import_node_fs4, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
612
+ var import_node_child_process, import_node_crypto, import_node_fs6, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
492
613
  var init_secure_file = __esm({
493
614
  "src/store/secure-file.ts"() {
494
615
  "use strict";
495
616
  import_node_child_process = require("child_process");
496
617
  import_node_crypto = require("crypto");
497
- import_node_fs4 = require("fs");
618
+ import_node_fs6 = require("fs");
498
619
  init_private_file();
499
620
  KEYCHAIN_SERVICE = "ai.sideboard.app";
500
621
  KEYCHAIN_ACCOUNT = "secret-vault-v1";
@@ -598,7 +719,7 @@ function createEmptyThread(partial) {
598
719
  }
599
720
  async function withThreadLock(id, fn) {
600
721
  const lockPath = threadLockPath(id);
601
- (0, import_node_fs5.writeFileSync)(lockPath, "", { flag: "a" });
722
+ (0, import_node_fs7.writeFileSync)(lockPath, "", { flag: "a" });
602
723
  let release;
603
724
  try {
604
725
  release = await import_proper_lockfile.default.lock(lockPath, {
@@ -612,26 +733,26 @@ async function withThreadLock(id, fn) {
612
733
  }
613
734
  function readThread(id) {
614
735
  const path = threadFilePath(id);
615
- if (!(0, import_node_fs5.existsSync)(path)) return null;
616
- const raw = (0, import_node_fs5.readFileSync)(path, "utf8");
736
+ if (!(0, import_node_fs7.existsSync)(path)) return null;
737
+ const raw = (0, import_node_fs7.readFileSync)(path, "utf8");
617
738
  return normalizeThread(JSON.parse(raw));
618
739
  }
619
740
  function writeThread(thread) {
620
741
  const path = threadFilePath(idPath(thread.id));
621
742
  const tmp = `${path}.${process.pid}.tmp`;
622
743
  const next = { ...thread, updatedAt: nowIso() };
623
- (0, import_node_fs5.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
624
- (0, import_node_fs5.renameSync)(tmp, path);
744
+ (0, import_node_fs7.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
745
+ (0, import_node_fs7.renameSync)(tmp, path);
625
746
  }
626
747
  function idPath(id) {
627
748
  return id;
628
749
  }
629
750
  function listThreads(opts) {
630
- const files = (0, import_node_fs5.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
751
+ const files = (0, import_node_fs7.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
631
752
  const threads = files.map((f) => {
632
753
  try {
633
754
  return normalizeThread(
634
- JSON.parse((0, import_node_fs5.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
755
+ JSON.parse((0, import_node_fs7.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
635
756
  );
636
757
  } catch {
637
758
  return null;
@@ -642,11 +763,11 @@ function listThreads(opts) {
642
763
  }
643
764
  function deleteThreadRecord(id) {
644
765
  const path = threadFilePath(id);
645
- if ((0, import_node_fs5.existsSync)(path)) (0, import_node_fs5.unlinkSync)(path);
766
+ if ((0, import_node_fs7.existsSync)(path)) (0, import_node_fs7.unlinkSync)(path);
646
767
  const lock = threadLockPath(id);
647
- if ((0, import_node_fs5.existsSync)(lock)) {
768
+ if ((0, import_node_fs7.existsSync)(lock)) {
648
769
  try {
649
- (0, import_node_fs5.unlinkSync)(lock);
770
+ (0, import_node_fs7.unlinkSync)(lock);
650
771
  } catch {
651
772
  }
652
773
  }
@@ -670,12 +791,12 @@ function findThreadByRef(ref) {
670
791
  const all = listThreads({ includeArchived: true });
671
792
  return all.find((t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref) ?? null;
672
793
  }
673
- var import_node_crypto2, import_node_fs5, import_proper_lockfile;
794
+ var import_node_crypto2, import_node_fs7, import_proper_lockfile;
674
795
  var init_thread_store = __esm({
675
796
  "src/store/thread-store.ts"() {
676
797
  "use strict";
677
798
  import_node_crypto2 = require("crypto");
678
- import_node_fs5 = require("fs");
799
+ import_node_fs7 = require("fs");
679
800
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
680
801
  init_thinking_effort();
681
802
  init_paths();
@@ -1734,7 +1855,7 @@ var init_gh_errors = __esm({
1734
1855
 
1735
1856
  // src/store/secret-vault.ts
1736
1857
  function secretVaultPath() {
1737
- return (0, import_node_path8.join)(appDataDir(), "secrets.json");
1858
+ return (0, import_node_path10.join)(appDataDir(), "secrets.json");
1738
1859
  }
1739
1860
  function loadSecretVault() {
1740
1861
  const parsed = readSecureJson(secretVaultPath());
@@ -1778,11 +1899,11 @@ function normalizeVault(raw) {
1778
1899
  }
1779
1900
  return out;
1780
1901
  }
1781
- var import_node_path8;
1902
+ var import_node_path10;
1782
1903
  var init_secret_vault = __esm({
1783
1904
  "src/store/secret-vault.ts"() {
1784
1905
  "use strict";
1785
- import_node_path8 = require("path");
1906
+ import_node_path10 = require("path");
1786
1907
  init_paths();
1787
1908
  init_secure_file();
1788
1909
  }
@@ -1883,10 +2004,10 @@ function toPublicAppSettings(settings) {
1883
2004
  };
1884
2005
  }
1885
2006
  function appSettingsPath() {
1886
- return (0, import_node_path9.join)(appDataDir(), "settings.json");
2007
+ return (0, import_node_path11.join)(appDataDir(), "settings.json");
1887
2008
  }
1888
2009
  function claudeUserSettingsPath() {
1889
- return (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
2010
+ return (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
1890
2011
  }
1891
2012
  function normalizeClaude(raw) {
1892
2013
  if (!raw || typeof raw !== "object") return {};
@@ -2129,10 +2250,10 @@ function normalizeSettings(raw) {
2129
2250
  }
2130
2251
  function readSettingsFile() {
2131
2252
  const path = appSettingsPath();
2132
- if (!(0, import_node_fs8.existsSync)(path)) return { ...EMPTY_SETTINGS };
2253
+ if (!(0, import_node_fs10.existsSync)(path)) return { ...EMPTY_SETTINGS };
2133
2254
  try {
2134
2255
  chmodOwnerOnly(path);
2135
- const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
2256
+ const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf8"));
2136
2257
  return normalizeSettings(parsed);
2137
2258
  } catch {
2138
2259
  return { ...EMPTY_SETTINGS };
@@ -2692,14 +2813,14 @@ function childEnvWithAppSettings(extra) {
2692
2813
  function harnessEnvKey(harness) {
2693
2814
  return HARNESS_ENV_KEYS[harness];
2694
2815
  }
2695
- var import_node_crypto3, import_node_fs8, import_node_os3, import_node_path9, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
2816
+ var import_node_crypto3, import_node_fs10, import_node_os3, import_node_path11, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
2696
2817
  var init_app_settings = __esm({
2697
2818
  "src/store/app-settings.ts"() {
2698
2819
  "use strict";
2699
2820
  import_node_crypto3 = require("crypto");
2700
- import_node_fs8 = require("fs");
2821
+ import_node_fs10 = require("fs");
2701
2822
  import_node_os3 = require("os");
2702
- import_node_path9 = require("path");
2823
+ import_node_path11 = require("path");
2703
2824
  init_thinking_effort();
2704
2825
  init_nested_electron_env();
2705
2826
  init_paths();
@@ -2749,17 +2870,17 @@ var init_app_settings = __esm({
2749
2870
 
2750
2871
  // src/agents/path.ts
2751
2872
  function prependPathDir(env, dir) {
2752
- if (!dir || !(0, import_node_fs9.existsSync)(dir)) return;
2873
+ if (!dir || !(0, import_node_fs11.existsSync)(dir)) return;
2753
2874
  const current = env.PATH ?? "";
2754
- const parts = current.split(import_node_path10.delimiter).filter(Boolean);
2875
+ const parts = current.split(import_node_path12.delimiter).filter(Boolean);
2755
2876
  if (parts.includes(dir)) {
2756
2877
  env.PATH = current;
2757
2878
  return;
2758
2879
  }
2759
- env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
2880
+ env.PATH = [dir, ...parts].join(import_node_path12.delimiter);
2760
2881
  }
2761
2882
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
2762
- return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
2883
+ return (0, import_node_path12.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
2763
2884
  }
2764
2885
  function isConductorBundledCli(filePath) {
2765
2886
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -2768,21 +2889,21 @@ function isConductorBundledCli(filePath) {
2768
2889
  function ensureAgentPath(env = process.env) {
2769
2890
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
2770
2891
  const current = env.PATH ?? "";
2771
- const parts = current.split(import_node_path10.delimiter).filter(Boolean);
2892
+ const parts = current.split(import_node_path12.delimiter).filter(Boolean);
2772
2893
  const seen = new Set(parts);
2773
2894
  const extras = [
2774
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
2895
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path12.join)(home, rel)),
2775
2896
  "/opt/homebrew/bin",
2776
2897
  "/usr/local/bin",
2777
2898
  // Keep after Homebrew/npm so a user-installed CLI still wins.
2778
2899
  conductorBundledBinDir(home)
2779
2900
  ];
2780
2901
  for (const dir of extras.reverse()) {
2781
- if (!dir || seen.has(dir) || !(0, import_node_fs9.existsSync)(dir)) continue;
2902
+ if (!dir || seen.has(dir) || !(0, import_node_fs11.existsSync)(dir)) continue;
2782
2903
  parts.unshift(dir);
2783
2904
  seen.add(dir);
2784
2905
  }
2785
- const next = parts.join(import_node_path10.delimiter);
2906
+ const next = parts.join(import_node_path12.delimiter);
2786
2907
  env.PATH = next;
2787
2908
  return next;
2788
2909
  }
@@ -2796,7 +2917,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
2796
2917
  stdio: ["ignore", "pipe", "ignore"]
2797
2918
  }).trim().split(/\r?\n/).find(Boolean);
2798
2919
  if (prefix) {
2799
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
2920
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path12.join)(prefix, "bin");
2800
2921
  prependPathDir(env, binDir);
2801
2922
  }
2802
2923
  } catch {
@@ -2824,14 +2945,14 @@ function withExportedPath(command, pathValue) {
2824
2945
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
2825
2946
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
2826
2947
  }
2827
- var import_node_fs9, import_node_child_process2, import_node_os4, import_node_path10, EXTRA_BIN_DIRS;
2948
+ var import_node_fs11, import_node_child_process2, import_node_os4, import_node_path12, EXTRA_BIN_DIRS;
2828
2949
  var init_path = __esm({
2829
2950
  "src/agents/path.ts"() {
2830
2951
  "use strict";
2831
- import_node_fs9 = require("fs");
2952
+ import_node_fs11 = require("fs");
2832
2953
  import_node_child_process2 = require("child_process");
2833
2954
  import_node_os4 = require("os");
2834
- import_node_path10 = require("path");
2955
+ import_node_path12 = require("path");
2835
2956
  EXTRA_BIN_DIRS = [
2836
2957
  ".local/bin",
2837
2958
  ".cargo/bin",
@@ -2859,7 +2980,7 @@ __export(run_exports, {
2859
2980
  async function run(file, args, opts) {
2860
2981
  ensureAgentPath();
2861
2982
  try {
2862
- const result = await (0, import_execa.execa)(file, args, {
2983
+ const result = await (0, import_execa2.execa)(file, args, {
2863
2984
  cwd: opts?.cwd,
2864
2985
  env: { ...process.env, ...opts?.env },
2865
2986
  reject: opts?.reject ?? true,
@@ -2923,11 +3044,11 @@ async function resolveGhAuthToken(cwd) {
2923
3044
  const token = result.stdout.trim();
2924
3045
  return token || null;
2925
3046
  }
2926
- var import_execa;
3047
+ var import_execa2;
2927
3048
  var init_run = __esm({
2928
3049
  "src/git/run.ts"() {
2929
3050
  "use strict";
2930
- import_execa = require("execa");
3051
+ import_execa2 = require("execa");
2931
3052
  init_path();
2932
3053
  }
2933
3054
  });
@@ -3052,7 +3173,7 @@ function formatGitAuthModeDirective(mode) {
3052
3173
  default:
3053
3174
  return [
3054
3175
  "Git authentication (Account \u2192 GitHub mode: auto):",
3055
- "- This process rewrites GitHub SSH remotes to HTTPS and authenticates with `GH_TOKEN` from `gh` so git/ssh never prompt the macOS Keychain (required for Slack / unattended Cursor).",
3176
+ "- This process rewrites GitHub SSH remotes to HTTPS and authenticates with `GH_TOKEN` from `gh` so git/ssh never prompt the macOS Keychain (required for unattended orchestrator turns).",
3056
3177
  "- Do not switch remotes to SSH. Push with `git push -u origin HEAD`.",
3057
3178
  "- If HTTPS auth fails, tell the user to run `gh auth login` on this Mac or set Account \u2192 GitHub to a PAT \u2014 do not wait for a Keychain dialog."
3058
3179
  ].join("\n");
@@ -4122,8 +4243,8 @@ function isLocalPrFetchBranch(ref) {
4122
4243
  }
4123
4244
  async function createThreadWorktree(opts) {
4124
4245
  let branchName = `thread/${opts.slug}`;
4125
- const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
4126
- if ((0, import_node_fs10.existsSync)(worktreePath)) {
4246
+ const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
4247
+ if ((0, import_node_fs12.existsSync)(worktreePath)) {
4127
4248
  throw new Error(`Worktree already exists at ${worktreePath}`);
4128
4249
  }
4129
4250
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4192,8 +4313,8 @@ ${add.stdout}`;
4192
4313
  async function createExistingBranchWorktree(opts) {
4193
4314
  const branchName = opts.branchName.trim();
4194
4315
  if (!branchName) throw new Error("branch name required");
4195
- const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
4196
- if ((0, import_node_fs10.existsSync)(worktreePath)) {
4316
+ const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
4317
+ if ((0, import_node_fs12.existsSync)(worktreePath)) {
4197
4318
  throw new Error(`Worktree already exists at ${worktreePath}`);
4198
4319
  }
4199
4320
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4481,10 +4602,10 @@ function sameRepoPath(a, b) {
4481
4602
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
4482
4603
  }
4483
4604
  function listLocalThreadBranchSlugs(repoPath) {
4484
- const refsDir = (0, import_node_path11.join)(repoPath, ".git", "refs", "heads", "thread");
4485
- if (!(0, import_node_fs10.existsSync)(refsDir)) return [];
4605
+ const refsDir = (0, import_node_path13.join)(repoPath, ".git", "refs", "heads", "thread");
4606
+ if (!(0, import_node_fs12.existsSync)(refsDir)) return [];
4486
4607
  try {
4487
- return (0, import_node_fs10.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
4608
+ return (0, import_node_fs12.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
4488
4609
  } catch {
4489
4610
  return [];
4490
4611
  }
@@ -4492,8 +4613,8 @@ function listLocalThreadBranchSlugs(repoPath) {
4492
4613
  function collectTakenTeamSlugs(repoPath) {
4493
4614
  const taken = /* @__PURE__ */ new Set();
4494
4615
  const root = worktreesRoot(repoPath);
4495
- if ((0, import_node_fs10.existsSync)(root)) {
4496
- for (const entry of (0, import_node_fs10.readdirSync)(root, { withFileTypes: true })) {
4616
+ if ((0, import_node_fs12.existsSync)(root)) {
4617
+ for (const entry of (0, import_node_fs12.readdirSync)(root, { withFileTypes: true })) {
4497
4618
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
4498
4619
  taken.add(normalizeTakenSlug(entry.name));
4499
4620
  }
@@ -4514,18 +4635,18 @@ function allocateTeamSlug(repoPath) {
4514
4635
  const taken = collectTakenTeamSlugs(repoPath);
4515
4636
  for (let attempt = 0; attempt < 32; attempt++) {
4516
4637
  const team = allocateTeamName(taken);
4517
- const path = (0, import_node_path11.join)(worktreesRoot(repoPath), team.slug);
4518
- if (!(0, import_node_fs10.existsSync)(path)) return team;
4638
+ const path = (0, import_node_path13.join)(worktreesRoot(repoPath), team.slug);
4639
+ if (!(0, import_node_fs12.existsSync)(path)) return team;
4519
4640
  taken.add(team.slug);
4520
4641
  }
4521
4642
  throw new Error("No available soccer team worktree directories left");
4522
4643
  }
4523
- var import_node_fs10, import_node_path11;
4644
+ var import_node_fs12, import_node_path13;
4524
4645
  var init_worktree = __esm({
4525
4646
  "src/git/worktree.ts"() {
4526
4647
  "use strict";
4527
- import_node_fs10 = require("fs");
4528
- import_node_path11 = require("path");
4648
+ import_node_fs12 = require("fs");
4649
+ import_node_path13 = require("path");
4529
4650
  init_paths();
4530
4651
  init_thread_store();
4531
4652
  init_teams();
@@ -4667,7 +4788,7 @@ function coordinatorTurnReminder(opts) {
4667
4788
  function ensureGlobalCoordinatorCwd(opts) {
4668
4789
  const dir = globalAgentCwd();
4669
4790
  try {
4670
- (0, import_node_fs11.mkdirSync)(dir, { recursive: true });
4791
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
4671
4792
  } catch {
4672
4793
  return dir;
4673
4794
  }
@@ -4675,7 +4796,7 @@ function ensureGlobalCoordinatorCwd(opts) {
4675
4796
  let orchId = opts?.orchestratorThreadId?.trim() || "";
4676
4797
  if (!orchId) {
4677
4798
  try {
4678
- const existing = (0, import_node_fs11.readFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), "utf8");
4799
+ const existing = (0, import_node_fs13.readFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), "utf8");
4679
4800
  const m = existing.match(
4680
4801
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
4681
4802
  );
@@ -4717,9 +4838,9 @@ function ensureGlobalCoordinatorCwd(opts) {
4717
4838
  "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."
4718
4839
  ].join("\n");
4719
4840
  try {
4720
- (0, import_node_fs11.writeFileSync)((0, import_node_path12.join)(dir, "CLAUDE.md"), `${body}
4841
+ (0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "CLAUDE.md"), `${body}
4721
4842
  `, "utf8");
4722
- (0, import_node_fs11.writeFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), `${body}
4843
+ (0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), `${body}
4723
4844
  `, "utf8");
4724
4845
  } catch {
4725
4846
  }
@@ -4751,12 +4872,12 @@ function coordinatorSystemPrompt(opts) {
4751
4872
  formatWorkspaceInventory(opts.workspaces)
4752
4873
  ].join("\n");
4753
4874
  }
4754
- var import_node_fs11, import_node_path12, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
4875
+ var import_node_fs13, import_node_path14, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
4755
4876
  var init_coordinator_prompt = __esm({
4756
4877
  "src/orchestrator/coordinator-prompt.ts"() {
4757
4878
  "use strict";
4758
- import_node_fs11 = require("fs");
4759
- import_node_path12 = require("path");
4879
+ import_node_fs13 = require("fs");
4880
+ import_node_path14 = require("path");
4760
4881
  init_worktree();
4761
4882
  init_app_settings();
4762
4883
  init_paths();
@@ -4777,7 +4898,7 @@ var init_coordinator_prompt = __esm({
4777
4898
  "Workspaces:",
4778
4899
  "- add_workspace / remove_workspace \u2014 register or unregister a git repo",
4779
4900
  "Worktree threads (chats):",
4780
- "- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
4901
+ "- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If the repo has a setup script, Sideboard runs it in the background (does not block send_to_thread). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
4781
4902
  "- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
4782
4903
  "- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
4783
4904
  "- send_to_thread \u2014 queue a prompt (start/continue a chat turn); pass force_stop: true to interrupt mid-turn / clear stale queued prompts before replacing with a new request",
@@ -4785,7 +4906,7 @@ var init_coordinator_prompt = __esm({
4785
4906
  "- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
4786
4907
  "- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
4787
4908
  "Setup / run:",
4788
- "- run_setup \u2014 re-run worktree setup",
4909
+ "- run_setup \u2014 re-run worktree setup (already runs automatically on create when a script exists)",
4789
4910
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
4790
4911
  "Inspect / review / PRs:",
4791
4912
  "- get_diff \u2014 compact diff summary",
@@ -5054,32 +5175,32 @@ var init_global_workspace = __esm({
5054
5175
 
5055
5176
  // src/brightsy/config.ts
5056
5177
  function brightsyConfigPath() {
5057
- return (0, import_node_path13.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
5178
+ return (0, import_node_path15.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
5058
5179
  }
5059
5180
  function loadBrightsyConfig() {
5060
5181
  const path = brightsyConfigPath();
5061
- if (!(0, import_node_fs12.existsSync)(path)) {
5182
+ if (!(0, import_node_fs14.existsSync)(path)) {
5062
5183
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
5063
5184
  }
5064
- const raw = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
5185
+ const raw = JSON.parse((0, import_node_fs14.readFileSync)(path, "utf8"));
5065
5186
  if (!raw.access_token || !raw.account_id) {
5066
5187
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
5067
5188
  }
5068
5189
  return raw;
5069
5190
  }
5070
5191
  function saveBrightsyConfig(cfg) {
5071
- (0, import_node_fs12.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5192
+ (0, import_node_fs14.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5072
5193
  `, {
5073
5194
  mode: 384
5074
5195
  });
5075
5196
  }
5076
- var import_node_fs12, import_node_os5, import_node_path13;
5197
+ var import_node_fs14, import_node_os5, import_node_path15;
5077
5198
  var init_config = __esm({
5078
5199
  "src/brightsy/config.ts"() {
5079
5200
  "use strict";
5080
- import_node_fs12 = require("fs");
5201
+ import_node_fs14 = require("fs");
5081
5202
  import_node_os5 = require("os");
5082
- import_node_path13 = require("path");
5203
+ import_node_path15 = require("path");
5083
5204
  }
5084
5205
  });
5085
5206
 
@@ -5094,22 +5215,22 @@ var init_accounts = __esm({
5094
5215
 
5095
5216
  // src/brightsy/connected-teams.ts
5096
5217
  function storePath4() {
5097
- return (0, import_node_path14.join)(appDataDir(), "brightsy-teams.json");
5218
+ return (0, import_node_path16.join)(appDataDir(), "brightsy-teams.json");
5098
5219
  }
5099
5220
  function readStore4() {
5100
5221
  const path = storePath4();
5101
- if (!(0, import_node_fs13.existsSync)(path)) return [];
5222
+ if (!(0, import_node_fs15.existsSync)(path)) return [];
5102
5223
  try {
5103
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(path, "utf8"));
5224
+ const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
5104
5225
  return Array.isArray(parsed.teams) ? parsed.teams : [];
5105
5226
  } catch {
5106
5227
  return [];
5107
5228
  }
5108
5229
  }
5109
5230
  function writeStore2(teams) {
5110
- (0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
5231
+ (0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
5111
5232
  const path = storePath4();
5112
- (0, import_node_fs13.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
5233
+ (0, import_node_fs15.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
5113
5234
  `, {
5114
5235
  mode: 384
5115
5236
  });
@@ -5221,12 +5342,12 @@ function brightsyMcpServerName(slug) {
5221
5342
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
5222
5343
  return `brightsy_${cleaned || "team"}`;
5223
5344
  }
5224
- var import_node_fs13, import_node_path14;
5345
+ var import_node_fs15, import_node_path16;
5225
5346
  var init_connected_teams = __esm({
5226
5347
  "src/brightsy/connected-teams.ts"() {
5227
5348
  "use strict";
5228
- import_node_fs13 = require("fs");
5229
- import_node_path14 = require("path");
5349
+ import_node_fs15 = require("fs");
5350
+ import_node_path16 = require("path");
5230
5351
  init_paths();
5231
5352
  init_accounts();
5232
5353
  init_config();
@@ -5553,11 +5674,11 @@ async function syncCliForTarget(accountId) {
5553
5674
  }
5554
5675
  applyConnectedTeamToCli(team);
5555
5676
  }
5556
- var import_node_fs14, brightsyAdapter;
5677
+ var import_node_fs16, brightsyAdapter;
5557
5678
  var init_brightsy = __esm({
5558
5679
  "src/agents/brightsy.ts"() {
5559
5680
  "use strict";
5560
- import_node_fs14 = require("fs");
5681
+ import_node_fs16 = require("fs");
5561
5682
  init_run();
5562
5683
  init_connected_teams();
5563
5684
  init_config();
@@ -5572,7 +5693,7 @@ var init_brightsy = __esm({
5572
5693
  async detect() {
5573
5694
  const brightsy = resolveAgentExecutable("brightsy");
5574
5695
  if (brightsy !== "brightsy") {
5575
- if (!(0, import_node_fs14.existsSync)(brightsy)) {
5696
+ if (!(0, import_node_fs16.existsSync)(brightsy)) {
5576
5697
  return {
5577
5698
  agent: "brightsy",
5578
5699
  installed: false,
@@ -5822,35 +5943,35 @@ function corePackageDir() {
5822
5943
  try {
5823
5944
  const url = import_meta.url;
5824
5945
  if (typeof url === "string" && url.length > 0) {
5825
- return (0, import_node_path15.dirname)((0, import_node_url.fileURLToPath)(url));
5946
+ return (0, import_node_path17.dirname)((0, import_node_url.fileURLToPath)(url));
5826
5947
  }
5827
5948
  } catch {
5828
5949
  }
5829
5950
  try {
5830
- const req = (0, import_node_module.createRequire)((0, import_node_path15.join)(process.cwd(), "package.json"));
5831
- return (0, import_node_path15.dirname)(req.resolve("@sideboard-ai/core"));
5951
+ const req = (0, import_node_module.createRequire)((0, import_node_path17.join)(process.cwd(), "package.json"));
5952
+ return (0, import_node_path17.dirname)(req.resolve("@sideboard-ai/core"));
5832
5953
  } catch {
5833
5954
  return process.cwd();
5834
5955
  }
5835
5956
  }
5836
5957
  function findSideboardMcpJsEntry() {
5837
5958
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
5838
- if (override && (0, import_node_fs15.existsSync)(override)) return override;
5959
+ if (override && (0, import_node_fs17.existsSync)(override)) return override;
5839
5960
  let dir = corePackageDir();
5840
5961
  for (let i = 0; i < 10; i++) {
5841
5962
  const candidates = [
5842
- (0, import_node_path15.join)(dir, "mcp/run-stdio.js"),
5843
- (0, import_node_path15.join)(dir, "mcp/run-stdio.cjs"),
5844
- (0, import_node_path15.join)(dir, "dist/mcp/run-stdio.js"),
5845
- (0, import_node_path15.join)(dir, "dist/mcp/run-stdio.cjs"),
5846
- (0, import_node_path15.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
5847
- (0, import_node_path15.join)(dir, "packages/cli/dist/index.js"),
5848
- (0, import_node_path15.join)(dir, "cli/dist/index.js")
5963
+ (0, import_node_path17.join)(dir, "mcp/run-stdio.js"),
5964
+ (0, import_node_path17.join)(dir, "mcp/run-stdio.cjs"),
5965
+ (0, import_node_path17.join)(dir, "dist/mcp/run-stdio.js"),
5966
+ (0, import_node_path17.join)(dir, "dist/mcp/run-stdio.cjs"),
5967
+ (0, import_node_path17.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
5968
+ (0, import_node_path17.join)(dir, "packages/cli/dist/index.js"),
5969
+ (0, import_node_path17.join)(dir, "cli/dist/index.js")
5849
5970
  ];
5850
5971
  for (const p of candidates) {
5851
- if ((0, import_node_fs15.existsSync)(p)) return p;
5972
+ if ((0, import_node_fs17.existsSync)(p)) return p;
5852
5973
  }
5853
- const parent = (0, import_node_path15.dirname)(dir);
5974
+ const parent = (0, import_node_path17.dirname)(dir);
5854
5975
  if (parent === dir) break;
5855
5976
  dir = parent;
5856
5977
  }
@@ -5973,19 +6094,19 @@ function writeMcpServersConfig(servers) {
5973
6094
  ...s.env ? { env: s.env } : {}
5974
6095
  };
5975
6096
  }
5976
- const dir = (0, import_node_fs15.mkdtempSync)((0, import_node_path15.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
5977
- const cfgPath = (0, import_node_path15.join)(dir, "mcp.json");
5978
- (0, import_node_fs15.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
6097
+ const dir = (0, import_node_fs17.mkdtempSync)((0, import_node_path17.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
6098
+ const cfgPath = (0, import_node_path17.join)(dir, "mcp.json");
6099
+ (0, import_node_fs17.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
5979
6100
  return cfgPath;
5980
6101
  }
5981
- var import_node_fs15, import_node_module, import_node_os6, import_node_path15, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
6102
+ var import_node_fs17, import_node_module, import_node_os6, import_node_path17, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
5982
6103
  var init_injected_mcp = __esm({
5983
6104
  "src/agents/injected-mcp.ts"() {
5984
6105
  "use strict";
5985
- import_node_fs15 = require("fs");
6106
+ import_node_fs17 = require("fs");
5986
6107
  import_node_module = require("module");
5987
6108
  import_node_os6 = require("os");
5988
- import_node_path15 = require("path");
6109
+ import_node_path17 = require("path");
5989
6110
  import_node_url = require("url");
5990
6111
  init_run();
5991
6112
  init_config();
@@ -6173,11 +6294,11 @@ function parseIssuesJson(raw) {
6173
6294
  }
6174
6295
  return [];
6175
6296
  }
6176
- var import_node_fs16, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
6297
+ var import_node_fs18, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
6177
6298
  var init_claude = __esm({
6178
6299
  "src/agents/claude.ts"() {
6179
6300
  "use strict";
6180
- import_node_fs16 = require("fs");
6301
+ import_node_fs18 = require("fs");
6181
6302
  init_run();
6182
6303
  init_app_settings();
6183
6304
  init_claude_mcp();
@@ -6206,7 +6327,7 @@ var init_claude = __esm({
6206
6327
  async detect() {
6207
6328
  const claude = resolveClaudeExecutable();
6208
6329
  if (claude !== "claude") {
6209
- if (!(0, import_node_fs16.existsSync)(claude)) {
6330
+ if (!(0, import_node_fs18.existsSync)(claude)) {
6210
6331
  return {
6211
6332
  agent: "claude",
6212
6333
  installed: false,
@@ -6443,7 +6564,7 @@ async function listCodexModels() {
6443
6564
  if (codex === "codex") {
6444
6565
  const which = await run("which", ["codex"], { reject: false });
6445
6566
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
6446
- } else if (!(0, import_node_fs17.existsSync)(codex)) {
6567
+ } else if (!(0, import_node_fs19.existsSync)(codex)) {
6447
6568
  return FALLBACK_CODEX_MODELS;
6448
6569
  }
6449
6570
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -6478,12 +6599,12 @@ function usageFromCodex(usage) {
6478
6599
  }
6479
6600
  function codexConfigHasNetworkAccess() {
6480
6601
  const candidates = [
6481
- (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
6482
- (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
6602
+ (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
6603
+ (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
6483
6604
  ];
6484
6605
  for (const path of candidates) {
6485
- if (!(0, import_node_fs17.existsSync)(path)) continue;
6486
- const text3 = (0, import_node_fs17.readFileSync)(path, "utf8");
6606
+ if (!(0, import_node_fs19.existsSync)(path)) continue;
6607
+ const text3 = (0, import_node_fs19.readFileSync)(path, "utf8");
6487
6608
  if (/network_access\s*=\s*true/.test(text3)) return true;
6488
6609
  }
6489
6610
  return false;
@@ -6515,21 +6636,21 @@ function asRecord(value) {
6515
6636
  return void 0;
6516
6637
  }
6517
6638
  function codexLooksAuthenticated() {
6518
- const authPath = (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
6519
- if (!(0, import_node_fs17.existsSync)(authPath)) return false;
6639
+ const authPath = (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
6640
+ if (!(0, import_node_fs19.existsSync)(authPath)) return false;
6520
6641
  try {
6521
- return (0, import_node_fs17.statSync)(authPath).size > 2;
6642
+ return (0, import_node_fs19.statSync)(authPath).size > 2;
6522
6643
  } catch {
6523
6644
  return false;
6524
6645
  }
6525
6646
  }
6526
- var import_node_fs17, import_node_os7, import_node_path16, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
6647
+ var import_node_fs19, import_node_os7, import_node_path18, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
6527
6648
  var init_codex = __esm({
6528
6649
  "src/agents/codex.ts"() {
6529
6650
  "use strict";
6530
- import_node_fs17 = require("fs");
6651
+ import_node_fs19 = require("fs");
6531
6652
  import_node_os7 = require("os");
6532
- import_node_path16 = require("path");
6653
+ import_node_path18 = require("path");
6533
6654
  init_run();
6534
6655
  init_app_settings();
6535
6656
  init_global_workspace();
@@ -6554,7 +6675,7 @@ var init_codex = __esm({
6554
6675
  async detect() {
6555
6676
  const codex = resolveAgentExecutable("codex");
6556
6677
  if (codex !== "codex") {
6557
- if (!(0, import_node_fs17.existsSync)(codex)) {
6678
+ if (!(0, import_node_fs19.existsSync)(codex)) {
6558
6679
  return {
6559
6680
  agent: "codex",
6560
6681
  installed: false,
@@ -6988,11 +7109,11 @@ function entryDir() {
6988
7109
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
6989
7110
  if (cjsDir) return cjsDir;
6990
7111
  try {
6991
- return (0, import_node_path17.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
7112
+ return (0, import_node_path19.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
6992
7113
  } catch {
6993
7114
  try {
6994
7115
  const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
6995
- return (0, import_node_path17.dirname)(req.resolve("@sideboard-ai/core"));
7116
+ return (0, import_node_path19.dirname)(req.resolve("@sideboard-ai/core"));
6996
7117
  } catch {
6997
7118
  return process.cwd();
6998
7119
  }
@@ -7001,27 +7122,27 @@ function entryDir() {
7001
7122
  function cursorRunnerPath() {
7002
7123
  const root = entryDir();
7003
7124
  const candidates = [
7004
- (0, import_node_path17.join)(root, "agents", "cursor-runner.js"),
7005
- (0, import_node_path17.join)(root, "agents", "cursor-runner.cjs"),
7125
+ (0, import_node_path19.join)(root, "agents", "cursor-runner.js"),
7126
+ (0, import_node_path19.join)(root, "agents", "cursor-runner.cjs"),
7006
7127
  // If somehow resolved from package root instead of dist/
7007
- (0, import_node_path17.join)(root, "dist", "agents", "cursor-runner.js"),
7008
- (0, import_node_path17.join)(root, "dist", "agents", "cursor-runner.cjs"),
7128
+ (0, import_node_path19.join)(root, "dist", "agents", "cursor-runner.js"),
7129
+ (0, import_node_path19.join)(root, "dist", "agents", "cursor-runner.cjs"),
7009
7130
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
7010
- (0, import_node_path17.join)(root, "cursor-runner.ts"),
7011
- (0, import_node_path17.join)(root, "src", "agents", "cursor-runner.ts")
7131
+ (0, import_node_path19.join)(root, "cursor-runner.ts"),
7132
+ (0, import_node_path19.join)(root, "src", "agents", "cursor-runner.ts")
7012
7133
  ];
7013
7134
  for (const candidate of candidates) {
7014
- if ((0, import_node_fs18.existsSync)(candidate)) return candidate;
7135
+ if ((0, import_node_fs20.existsSync)(candidate)) return candidate;
7015
7136
  }
7016
7137
  return candidates[0];
7017
7138
  }
7018
- var import_node_fs18, import_node_module2, import_node_path17, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
7139
+ var import_node_fs20, import_node_module2, import_node_path19, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
7019
7140
  var init_cursor = __esm({
7020
7141
  "src/agents/cursor.ts"() {
7021
7142
  "use strict";
7022
- import_node_fs18 = require("fs");
7143
+ import_node_fs20 = require("fs");
7023
7144
  import_node_module2 = require("module");
7024
- import_node_path17 = require("path");
7145
+ import_node_path19 = require("path");
7025
7146
  import_node_url2 = require("url");
7026
7147
  import_sdk = require("@cursor/sdk");
7027
7148
  init_run();
@@ -7150,7 +7271,7 @@ async function listOpencodeModels() {
7150
7271
  if (opencode === "opencode") {
7151
7272
  const which = await run("which", ["opencode"], { reject: false });
7152
7273
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
7153
- } else if (!(0, import_node_fs19.existsSync)(opencode)) {
7274
+ } else if (!(0, import_node_fs21.existsSync)(opencode)) {
7154
7275
  return FALLBACK_OPENCODE_MODELS;
7155
7276
  }
7156
7277
  const listed = await run(opencode, ["models"], { reject: false });
@@ -7180,11 +7301,11 @@ function usageFromOpencode(tokens) {
7180
7301
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
7181
7302
  };
7182
7303
  }
7183
- var import_node_fs19, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
7304
+ var import_node_fs21, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
7184
7305
  var init_opencode = __esm({
7185
7306
  "src/agents/opencode.ts"() {
7186
7307
  "use strict";
7187
- import_node_fs19 = require("fs");
7308
+ import_node_fs21 = require("fs");
7188
7309
  init_run();
7189
7310
  init_app_settings();
7190
7311
  init_global_workspace();
@@ -7210,7 +7331,7 @@ var init_opencode = __esm({
7210
7331
  async detect() {
7211
7332
  const opencode = resolveAgentExecutable("opencode");
7212
7333
  if (opencode !== "opencode") {
7213
- if (!(0, import_node_fs19.existsSync)(opencode)) {
7334
+ if (!(0, import_node_fs21.existsSync)(opencode)) {
7214
7335
  return {
7215
7336
  agent: "opencode",
7216
7337
  installed: false,
@@ -7947,38 +8068,38 @@ __export(workspaces_exports, {
7947
8068
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
7948
8069
  });
7949
8070
  function workspacesFile() {
7950
- return (0, import_node_path21.join)(appDataDir(), "workspaces.json");
8071
+ return (0, import_node_path22.join)(appDataDir(), "workspaces.json");
7951
8072
  }
7952
8073
  function removedWorkspacesFile() {
7953
- return (0, import_node_path21.join)(appDataDir(), "removed-workspaces.json");
8074
+ return (0, import_node_path22.join)(appDataDir(), "removed-workspaces.json");
7954
8075
  }
7955
8076
  function readAll() {
7956
8077
  const path = workspacesFile();
7957
- if (!(0, import_node_fs23.existsSync)(path)) return [];
8078
+ if (!(0, import_node_fs24.existsSync)(path)) return [];
7958
8079
  try {
7959
- const raw = JSON.parse((0, import_node_fs23.readFileSync)(path, "utf8"));
8080
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
7960
8081
  return Array.isArray(raw) ? raw : [];
7961
8082
  } catch {
7962
8083
  return [];
7963
8084
  }
7964
8085
  }
7965
8086
  function writeAll(list) {
7966
- (0, import_node_fs23.mkdirSync)(appDataDir(), { recursive: true });
7967
- (0, import_node_fs23.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
8087
+ (0, import_node_fs24.mkdirSync)(appDataDir(), { recursive: true });
8088
+ (0, import_node_fs24.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
7968
8089
  }
7969
8090
  function readRemoved() {
7970
8091
  const path = removedWorkspacesFile();
7971
- if (!(0, import_node_fs23.existsSync)(path)) return /* @__PURE__ */ new Set();
8092
+ if (!(0, import_node_fs24.existsSync)(path)) return /* @__PURE__ */ new Set();
7972
8093
  try {
7973
- const raw = JSON.parse((0, import_node_fs23.readFileSync)(path, "utf8"));
8094
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
7974
8095
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
7975
8096
  } catch {
7976
8097
  return /* @__PURE__ */ new Set();
7977
8098
  }
7978
8099
  }
7979
8100
  function writeRemoved(paths) {
7980
- (0, import_node_fs23.mkdirSync)(appDataDir(), { recursive: true });
7981
- (0, import_node_fs23.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
8101
+ (0, import_node_fs24.mkdirSync)(appDataDir(), { recursive: true });
8102
+ (0, import_node_fs24.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
7982
8103
  }
7983
8104
  function rememberRemoved(repoPath) {
7984
8105
  const next = readRemoved();
@@ -8001,7 +8122,7 @@ function listWorkspaces() {
8001
8122
  async function addWorkspace(repoPath) {
8002
8123
  const root = await resolveRepoRoot(repoPath);
8003
8124
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
8004
- if (!(0, import_node_fs23.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
8125
+ if (!(0, import_node_fs24.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
8005
8126
  forgetRemoved(root);
8006
8127
  await ensureGhPreferOrigin(root);
8007
8128
  const current = readAll();
@@ -8009,7 +8130,7 @@ async function addWorkspace(repoPath) {
8009
8130
  if (existing) return existing;
8010
8131
  const next = {
8011
8132
  path: root,
8012
- name: (0, import_node_path21.basename)(root),
8133
+ name: (0, import_node_path22.basename)(root),
8013
8134
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
8014
8135
  };
8015
8136
  writeAll([...current, next]);
@@ -8031,10 +8152,10 @@ function syncWorkspacesFromThreads(repoPaths) {
8031
8152
  if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
8032
8153
  continue;
8033
8154
  }
8034
- if (!(0, import_node_fs23.existsSync)(path)) continue;
8155
+ if (!(0, import_node_fs24.existsSync)(path)) continue;
8035
8156
  const ws = {
8036
8157
  path,
8037
- name: (0, import_node_path21.basename)(path),
8158
+ name: (0, import_node_path22.basename)(path),
8038
8159
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
8039
8160
  };
8040
8161
  byPath.set(path, ws);
@@ -8044,12 +8165,12 @@ function syncWorkspacesFromThreads(repoPaths) {
8044
8165
  if (dirty) writeAll(next);
8045
8166
  return next.sort((a, b) => a.name.localeCompare(b.name));
8046
8167
  }
8047
- var import_node_fs23, import_node_path21;
8168
+ var import_node_fs24, import_node_path22;
8048
8169
  var init_workspaces = __esm({
8049
8170
  "src/store/workspaces.ts"() {
8050
8171
  "use strict";
8051
- import_node_fs23 = require("fs");
8052
- import_node_path21 = require("path");
8172
+ import_node_fs24 = require("fs");
8173
+ import_node_path22 = require("path");
8053
8174
  init_paths();
8054
8175
  init_global_workspace();
8055
8176
  init_worktree();
@@ -8126,40 +8247,40 @@ __export(plan_file_exports, {
8126
8247
  writePlanFile: () => writePlanFile
8127
8248
  });
8128
8249
  function ensureAttachmentsGitignore2(worktreePath) {
8129
- const gitignoreAbs = (0, import_node_path29.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
8130
- if ((0, import_node_fs33.existsSync)(gitignoreAbs)) return;
8131
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(gitignoreAbs), { recursive: true });
8132
- (0, import_node_fs33.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
8250
+ const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
8251
+ if ((0, import_node_fs34.existsSync)(gitignoreAbs)) return;
8252
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
8253
+ (0, import_node_fs34.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
8133
8254
  }
8134
8255
  function planFileAbs(worktreePath) {
8135
- return (0, import_node_path29.join)(worktreePath, PLAN_FILE_REL);
8256
+ return (0, import_node_path30.join)(worktreePath, PLAN_FILE_REL);
8136
8257
  }
8137
8258
  function readTextIfPresent2(abs) {
8138
- if (!(0, import_node_fs33.existsSync)(abs)) return null;
8259
+ if (!(0, import_node_fs34.existsSync)(abs)) return null;
8139
8260
  try {
8140
- const content = (0, import_node_fs33.readFileSync)(abs, "utf8");
8261
+ const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
8141
8262
  return content.trim() ? content : null;
8142
8263
  } catch {
8143
8264
  return null;
8144
8265
  }
8145
8266
  }
8146
8267
  function readPlanFile(worktreePath) {
8147
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path29.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path29.join)(worktreePath, LEGACY_PLAN_FILE_REL));
8268
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path30.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path30.join)(worktreePath, LEGACY_PLAN_FILE_REL));
8148
8269
  }
8149
8270
  function writePlanFile(worktreePath, content) {
8150
8271
  ensureAttachmentsGitignore2(worktreePath);
8151
8272
  const abs = planFileAbs(worktreePath);
8152
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(abs), { recursive: true });
8273
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(abs), { recursive: true });
8153
8274
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
8154
- (0, import_node_fs33.writeFileSync)(abs, body, "utf8");
8275
+ (0, import_node_fs34.writeFileSync)(abs, body, "utf8");
8155
8276
  return PLAN_FILE_REL;
8156
8277
  }
8157
- var import_node_fs33, import_node_path29;
8278
+ var import_node_fs34, import_node_path30;
8158
8279
  var init_plan_file = __esm({
8159
8280
  "src/plan/plan-file.ts"() {
8160
8281
  "use strict";
8161
- import_node_fs33 = require("fs");
8162
- import_node_path29 = require("path");
8282
+ import_node_fs34 = require("fs");
8283
+ import_node_path30 = require("path");
8163
8284
  init_workspace_scratch();
8164
8285
  init_plan_present();
8165
8286
  init_plan_present();
@@ -8180,7 +8301,7 @@ function setCaffeinateHoldHooks(next) {
8180
8301
  hooks = next;
8181
8302
  }
8182
8303
  function caffeinateHoldPath() {
8183
- return (0, import_node_path30.join)(appDataDir(), "caffeinate-hold.json");
8304
+ return (0, import_node_path31.join)(appDataDir(), "caffeinate-hold.json");
8184
8305
  }
8185
8306
  function processAlive(pid) {
8186
8307
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -8214,9 +8335,9 @@ function uniqueIds(ids) {
8214
8335
  }
8215
8336
  function readHold() {
8216
8337
  const path = caffeinateHoldPath();
8217
- if (!(0, import_node_fs34.existsSync)(path)) return null;
8338
+ if (!(0, import_node_fs35.existsSync)(path)) return null;
8218
8339
  try {
8219
- const parsed = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
8340
+ const parsed = JSON.parse((0, import_node_fs35.readFileSync)(path, "utf8"));
8220
8341
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
8221
8342
  return {
8222
8343
  pid: parsed.pid,
@@ -8238,7 +8359,7 @@ function writeHold(pid, threadIds) {
8238
8359
  }
8239
8360
  function clearHold() {
8240
8361
  try {
8241
- (0, import_node_fs34.unlinkSync)(caffeinateHoldPath());
8362
+ (0, import_node_fs35.unlinkSync)(caffeinateHoldPath());
8242
8363
  } catch {
8243
8364
  }
8244
8365
  }
@@ -8323,13 +8444,13 @@ function releaseCaffeinateHoldForThread(threadId) {
8323
8444
  }
8324
8445
  return setCaffeinateHold(false, { threadId: id });
8325
8446
  }
8326
- var import_node_child_process4, import_node_fs34, import_node_path30, hooks;
8447
+ var import_node_child_process4, import_node_fs35, import_node_path31, hooks;
8327
8448
  var init_caffeinate_hold = __esm({
8328
8449
  "src/store/caffeinate-hold.ts"() {
8329
8450
  "use strict";
8330
8451
  import_node_child_process4 = require("child_process");
8331
- import_node_fs34 = require("fs");
8332
- import_node_path30 = require("path");
8452
+ import_node_fs35 = require("fs");
8453
+ import_node_path31 = require("path");
8333
8454
  init_paths();
8334
8455
  init_private_file();
8335
8456
  hooks = {};
@@ -8344,10 +8465,10 @@ __export(cursor_recover_exports, {
8344
8465
  function recoverFinishedCursorRun(opts) {
8345
8466
  const agentId = opts.agentId.trim();
8346
8467
  if (!agentId) return null;
8347
- const runsPath = (0, import_node_path31.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
8348
- if (!(0, import_node_fs35.existsSync)(runsPath)) return null;
8468
+ const runsPath = (0, import_node_path32.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
8469
+ if (!(0, import_node_fs36.existsSync)(runsPath)) return null;
8349
8470
  try {
8350
- const lines = (0, import_node_fs35.readFileSync)(runsPath, "utf8").split("\n");
8471
+ const lines = (0, import_node_fs36.readFileSync)(runsPath, "utf8").split("\n");
8351
8472
  let best = null;
8352
8473
  for (const line of lines) {
8353
8474
  const trimmed = line.trim();
@@ -8373,12 +8494,12 @@ function recoverFinishedCursorRun(opts) {
8373
8494
  return null;
8374
8495
  }
8375
8496
  }
8376
- var import_node_fs35, import_node_path31;
8497
+ var import_node_fs36, import_node_path32;
8377
8498
  var init_cursor_recover = __esm({
8378
8499
  "src/agents/cursor-recover.ts"() {
8379
8500
  "use strict";
8380
- import_node_fs35 = require("fs");
8381
- import_node_path31 = require("path");
8501
+ import_node_fs36 = require("fs");
8502
+ import_node_path32 = require("path");
8382
8503
  init_paths();
8383
8504
  }
8384
8505
  });
@@ -8390,14 +8511,14 @@ init_nested_electron_env();
8390
8511
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
8391
8512
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
8392
8513
  var import_zod3 = require("zod");
8393
- var import_node_path32 = require("path");
8514
+ var import_node_path33 = require("path");
8394
8515
 
8395
8516
  // src/orchestrator/orchestrator.ts
8396
8517
  var import_node_events = require("events");
8397
8518
 
8398
8519
  // src/slack/outbound-watch.ts
8399
- var import_node_fs7 = require("fs");
8400
- var import_node_path7 = require("path");
8520
+ var import_node_fs9 = require("fs");
8521
+ var import_node_path9 = require("path");
8401
8522
  init_paths();
8402
8523
  init_private_file();
8403
8524
  init_secure_file();
@@ -8440,19 +8561,19 @@ async function slackApi(token, method, params, fetchImpl) {
8440
8561
  }
8441
8562
 
8442
8563
  // src/slack/reply-target.ts
8443
- var import_node_fs6 = require("fs");
8444
- var import_node_path5 = require("path");
8564
+ var import_node_fs8 = require("fs");
8565
+ var import_node_path7 = require("path");
8445
8566
  init_paths();
8446
8567
  init_private_file();
8447
8568
  init_secure_file();
8448
8569
  function storePath() {
8449
- return (0, import_node_path5.join)(appDataDir(), "slack-reply-to.json");
8570
+ return (0, import_node_path7.join)(appDataDir(), "slack-reply-to.json");
8450
8571
  }
8451
8572
  function readStore() {
8452
8573
  const path = storePath();
8453
- if (!(0, import_node_fs6.existsSync)(path)) return {};
8574
+ if (!(0, import_node_fs8.existsSync)(path)) return {};
8454
8575
  try {
8455
- const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
8576
+ const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
8456
8577
  return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
8457
8578
  } catch {
8458
8579
  return {};
@@ -8463,11 +8584,11 @@ function getSlackReplyTarget(threadId) {
8463
8584
  }
8464
8585
 
8465
8586
  // src/slack/workspaces.ts
8466
- var import_node_path6 = require("path");
8587
+ var import_node_path8 = require("path");
8467
8588
  init_paths();
8468
8589
  init_secure_file();
8469
8590
  function storePath2() {
8470
- return (0, import_node_path6.join)(appDataDir(), "slack-workspaces.json");
8591
+ return (0, import_node_path8.join)(appDataDir(), "slack-workspaces.json");
8471
8592
  }
8472
8593
  function readStore2() {
8473
8594
  try {
@@ -8537,7 +8658,7 @@ var POLL_INTERVAL_MS = 12e3;
8537
8658
  var lastPollMs = 0;
8538
8659
  var nameCache = /* @__PURE__ */ new Map();
8539
8660
  function storePath3() {
8540
- return (0, import_node_path7.join)(appDataDir(), "slack-outbound-watch.json");
8661
+ return (0, import_node_path9.join)(appDataDir(), "slack-outbound-watch.json");
8541
8662
  }
8542
8663
  function watchId(teamId, channelId, ts) {
8543
8664
  return `${teamId}:${channelId}:${ts}`;
@@ -8567,9 +8688,9 @@ function tsNewer(a, b) {
8567
8688
  }
8568
8689
  function readStore3() {
8569
8690
  const path = storePath3();
8570
- if (!(0, import_node_fs7.existsSync)(path)) return [];
8691
+ if (!(0, import_node_fs9.existsSync)(path)) return [];
8571
8692
  try {
8572
- const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs7.readFileSync)(path, "utf8"));
8693
+ const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs9.readFileSync)(path, "utf8"));
8573
8694
  return Array.isArray(parsed?.watches) ? parsed.watches : [];
8574
8695
  } catch {
8575
8696
  return [];
@@ -8901,12 +9022,12 @@ async function refreshSlackReplyBadges(opts) {
8901
9022
  }
8902
9023
 
8903
9024
  // src/orchestrator/orchestrator.ts
8904
- var import_node_fs36 = require("fs");
9025
+ var import_node_fs37 = require("fs");
8905
9026
  init_error_detail();
8906
9027
 
8907
9028
  // src/agents/spawn.ts
8908
- var import_node_readline = require("readline");
8909
- var import_execa2 = require("execa");
9029
+ var import_node_readline2 = require("readline");
9030
+ var import_execa3 = require("execa");
8910
9031
  init_worktree();
8911
9032
  init_git_auth_mode();
8912
9033
  init_app_settings();
@@ -9182,7 +9303,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
9182
9303
  const detail = err instanceof Error ? err.message : String(err);
9183
9304
  console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
9184
9305
  }
9185
- const child = (0, import_execa2.execa)(cmd.file, cmd.args, {
9306
+ const child = (0, import_execa3.execa)(cmd.file, cmd.args, {
9186
9307
  cwd: cmd.cwd,
9187
9308
  env,
9188
9309
  reject: false,
@@ -9202,7 +9323,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
9202
9323
  let usage = null;
9203
9324
  const consume = (stream, kind) => {
9204
9325
  if (!stream) return;
9205
- const rl = (0, import_node_readline.createInterface)({ input: stream, crlfDelay: Infinity });
9326
+ const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
9206
9327
  rl.on("line", (line) => {
9207
9328
  if (kind === "stderr") {
9208
9329
  onEvent({ type: "stderr", data: line });
@@ -9387,13 +9508,15 @@ function shouldAutoArchiveOnPrMerge(opts) {
9387
9508
  }
9388
9509
 
9389
9510
  // src/hook/conductor.ts
9390
- var import_node_fs20 = require("fs");
9511
+ var import_node_fs22 = require("fs");
9391
9512
  var import_node_net = require("net");
9392
- var import_node_path18 = require("path");
9393
- var import_execa3 = require("execa");
9394
- var import_node_readline2 = require("readline");
9513
+ var import_node_path20 = require("path");
9514
+ var import_execa4 = require("execa");
9515
+ var import_node_readline3 = require("readline");
9395
9516
  init_settings();
9396
9517
  init_nested_electron_env();
9518
+ init_convention_setup();
9519
+ init_cursor_worktrees();
9397
9520
  init_git_auth_mode();
9398
9521
  init_nested_electron_env();
9399
9522
  var PORT_RANGE_SIZE = 10;
@@ -9402,9 +9525,9 @@ function matchSimpleGlob(pattern, name) {
9402
9525
  return new RegExp(`^${escaped}$`).test(name);
9403
9526
  }
9404
9527
  function readWorktreeInclude(repoPath) {
9405
- const path = (0, import_node_path18.join)(repoPath, ".worktreeinclude");
9406
- if (!(0, import_node_fs20.existsSync)(path)) return [];
9407
- return (0, import_node_fs20.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
9528
+ const path = (0, import_node_path20.join)(repoPath, ".worktreeinclude");
9529
+ if (!(0, import_node_fs22.existsSync)(path)) return [];
9530
+ return (0, import_node_fs22.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
9408
9531
  }
9409
9532
  function resolveFilesToCopy(repoPath) {
9410
9533
  const fromInclude = readWorktreeInclude(repoPath);
@@ -9414,10 +9537,10 @@ function resolveFilesToCopy(repoPath) {
9414
9537
  if (settings?.fileIncludeGlobs?.length) {
9415
9538
  const matched = [];
9416
9539
  try {
9417
- for (const entry of (0, import_node_fs20.readdirSync)(repoPath, { withFileTypes: true })) {
9540
+ for (const entry of (0, import_node_fs22.readdirSync)(repoPath, { withFileTypes: true })) {
9418
9541
  if (!entry.isFile()) continue;
9419
9542
  for (const glob of settings.fileIncludeGlobs) {
9420
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path18.basename)(glob), entry.name)) {
9543
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path20.basename)(glob), entry.name)) {
9421
9544
  matched.push(entry.name);
9422
9545
  break;
9423
9546
  }
@@ -9429,7 +9552,7 @@ function resolveFilesToCopy(repoPath) {
9429
9552
  }
9430
9553
  const defaults = [];
9431
9554
  try {
9432
- for (const entry of (0, import_node_fs20.readdirSync)(repoPath, { withFileTypes: true })) {
9555
+ for (const entry of (0, import_node_fs22.readdirSync)(repoPath, { withFileTypes: true })) {
9433
9556
  if (entry.isFile() && entry.name.startsWith(".env")) {
9434
9557
  defaults.push(entry.name);
9435
9558
  }
@@ -9443,11 +9566,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
9443
9566
  const patterns = resolveFilesToCopy(repoPath);
9444
9567
  const copied = [];
9445
9568
  for (const rel of patterns) {
9446
- const src = (0, import_node_path18.join)(repoPath, rel);
9447
- if (!(0, import_node_fs20.existsSync)(src)) continue;
9448
- const dest = (0, import_node_path18.join)(worktreePath, rel);
9449
- (0, import_node_fs20.mkdirSync)((0, import_node_path18.dirname)(dest), { recursive: true });
9450
- (0, import_node_fs20.copyFileSync)(src, dest);
9569
+ const src = (0, import_node_path20.join)(repoPath, rel);
9570
+ if (!(0, import_node_fs22.existsSync)(src)) continue;
9571
+ const dest = (0, import_node_path20.join)(worktreePath, rel);
9572
+ (0, import_node_fs22.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
9573
+ (0, import_node_fs22.copyFileSync)(src, dest);
9451
9574
  copied.push(rel);
9452
9575
  }
9453
9576
  return copied;
@@ -9457,7 +9580,7 @@ async function captureLoginEnv() {
9457
9580
  if (cachedLoginEnv) return { ...cachedLoginEnv };
9458
9581
  const shell = process.env.SHELL?.trim() || (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
9459
9582
  try {
9460
- const result = await (0, import_execa3.execa)(shell, ["-l", "-c", "env -0"], {
9583
+ const result = await (0, import_execa4.execa)(shell, ["-l", "-c", "env -0"], {
9461
9584
  reject: false,
9462
9585
  timeout: 5e3
9463
9586
  });
@@ -9483,7 +9606,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
9483
9606
  const env = stripNestedElectronEnv({
9484
9607
  ...baseEnv ?? process.env
9485
9608
  });
9486
- const name = opts.workspaceName ?? (0, import_node_path18.basename)(opts.worktreePath);
9609
+ const name = opts.workspaceName ?? (0, import_node_path20.basename)(opts.worktreePath);
9487
9610
  const ports = opts.ports ?? [];
9488
9611
  const primary = ports[0];
9489
9612
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -9510,7 +9633,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
9510
9633
  }
9511
9634
  function pipeLines(stream, onLine) {
9512
9635
  if (!stream || !onLine) return;
9513
- const rl = (0, import_node_readline2.createInterface)({ input: stream });
9636
+ const rl = (0, import_node_readline3.createInterface)({ input: stream });
9514
9637
  rl.on("line", onLine);
9515
9638
  }
9516
9639
  function killScriptTree(child, ports = []) {
@@ -9518,7 +9641,7 @@ function killScriptTree(child, ports = []) {
9518
9641
  if (pid) {
9519
9642
  try {
9520
9643
  if (process.platform === "win32") {
9521
- void (0, import_execa3.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
9644
+ void (0, import_execa4.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
9522
9645
  } else {
9523
9646
  process.kill(-pid, "SIGTERM");
9524
9647
  setTimeout(() => {
@@ -9538,7 +9661,7 @@ function killScriptTree(child, ports = []) {
9538
9661
  for (const port of ports) {
9539
9662
  if (!Number.isFinite(port) || port <= 0) continue;
9540
9663
  if (process.platform === "win32") {
9541
- void (0, import_execa3.execa)(
9664
+ void (0, import_execa4.execa)(
9542
9665
  "powershell",
9543
9666
  [
9544
9667
  "-NoProfile",
@@ -9548,7 +9671,7 @@ function killScriptTree(child, ports = []) {
9548
9671
  { reject: false }
9549
9672
  );
9550
9673
  } else {
9551
- void (0, import_execa3.execa)(
9674
+ void (0, import_execa4.execa)(
9552
9675
  "zsh",
9553
9676
  ["-lc", `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`],
9554
9677
  { reject: false }
@@ -9573,7 +9696,7 @@ async function spawnWorkspaceScript(command, opts) {
9573
9696
  } catch {
9574
9697
  }
9575
9698
  const shell = process.platform === "darwin" ? "zsh" : "bash";
9576
- const child = (0, import_execa3.execa)(shell, ["-lc", command], {
9699
+ const child = (0, import_execa4.execa)(shell, ["-lc", command], {
9577
9700
  cwd: opts.worktreePath,
9578
9701
  reject: false,
9579
9702
  env,
@@ -9591,6 +9714,14 @@ async function spawnWorkspaceScript(command, opts) {
9591
9714
  child
9592
9715
  };
9593
9716
  }
9717
+ async function attachAbort(handle, signal) {
9718
+ if (signal) {
9719
+ const onAbort = () => handle.kill();
9720
+ if (signal.aborted) onAbort();
9721
+ else signal.addEventListener("abort", onAbort, { once: true });
9722
+ }
9723
+ return handle.done;
9724
+ }
9594
9725
  async function runSetupScript(repoPath, worktreePath, onLine, opts) {
9595
9726
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
9596
9727
  if (!settings?.setup) return { ran: false, exitCode: null, source: null };
@@ -9600,12 +9731,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
9600
9731
  defaultBranch: opts?.defaultBranch,
9601
9732
  onLine
9602
9733
  });
9603
- if (opts?.signal) {
9604
- const onAbort = () => handle.kill();
9605
- if (opts.signal.aborted) onAbort();
9606
- else opts.signal.addEventListener("abort", onAbort, { once: true });
9607
- }
9608
- const exitCode = await handle.done;
9734
+ const exitCode = await attachAbort(handle, opts?.signal);
9609
9735
  return {
9610
9736
  ran: true,
9611
9737
  exitCode,
@@ -9613,6 +9739,34 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
9613
9739
  kill: handle.kill
9614
9740
  };
9615
9741
  }
9742
+ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
9743
+ const found = findConventionSetup(worktreePath, repoPath);
9744
+ if (!found) return { ran: false, exitCode: null, source: null };
9745
+ onLine?.(`[setup] ${found.source}`);
9746
+ const handle = await spawnWorkspaceScript(found.command, {
9747
+ worktreePath,
9748
+ repoPath,
9749
+ defaultBranch: opts?.defaultBranch,
9750
+ onLine
9751
+ });
9752
+ const exitCode = await attachAbort(handle, opts?.signal);
9753
+ return {
9754
+ ran: true,
9755
+ exitCode,
9756
+ source: found.source,
9757
+ kill: handle.kill
9758
+ };
9759
+ }
9760
+ async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
9761
+ let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
9762
+ if (!setup.ran) {
9763
+ setup = await runCursorWorktreeSetup(repoPath, worktreePath, onLine);
9764
+ }
9765
+ if (!setup.ran) {
9766
+ setup = await runConventionSetup(repoPath, worktreePath, onLine, opts);
9767
+ }
9768
+ return setup;
9769
+ }
9616
9770
  async function runArchiveScript(repoPath, worktreePath, onLine) {
9617
9771
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
9618
9772
  if (!settings?.archive) return { ran: false, exitCode: null };
@@ -9705,75 +9859,9 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
9705
9859
  };
9706
9860
  }
9707
9861
 
9708
- // src/hook/cursor-worktrees.ts
9709
- var import_node_fs21 = require("fs");
9710
- var import_node_path19 = require("path");
9711
- var import_execa4 = require("execa");
9712
- var import_node_readline3 = require("readline");
9713
- function loadCursorWorktreesJson(rootPath) {
9714
- const path = (0, import_node_path19.join)(rootPath, ".cursor", "worktrees.json");
9715
- if (!(0, import_node_fs21.existsSync)(path)) return null;
9716
- try {
9717
- return JSON.parse((0, import_node_fs21.readFileSync)(path, "utf8"));
9718
- } catch {
9719
- return null;
9720
- }
9721
- }
9722
- function resolveSetupSpec(config) {
9723
- if (process.platform === "win32") {
9724
- return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
9725
- }
9726
- return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
9727
- }
9728
- async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
9729
- const fromWorktree = loadCursorWorktreesJson(worktreePath);
9730
- const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
9731
- const config = fromWorktree ?? fromRepo;
9732
- if (!config) return { ran: false, exitCode: null, source: null };
9733
- const spec = resolveSetupSpec(config);
9734
- if (!spec) return { ran: false, exitCode: null, source: null };
9735
- const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
9736
- const env = {
9737
- ...process.env,
9738
- ROOT_WORKTREE_PATH: repoPath
9739
- };
9740
- if (process.platform === "win32") {
9741
- env.ROOT_WORKTREE_PATH = repoPath;
9742
- }
9743
- const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path19.join)(
9744
- fromWorktree ? worktreePath : repoPath,
9745
- ".cursor",
9746
- spec
9747
- ) : spec];
9748
- let lastExit = 0;
9749
- for (const command of commands) {
9750
- const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
9751
- const shell = process.platform === "win32" ? "powershell" : "bash";
9752
- const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
9753
- onLine?.(`[cursor setup] ${command}`);
9754
- const child = (0, import_execa4.execa)(shell, args, {
9755
- cwd: worktreePath,
9756
- reject: false,
9757
- env
9758
- });
9759
- if (child.stdout && onLine) {
9760
- const rl = (0, import_node_readline3.createInterface)({ input: child.stdout });
9761
- rl.on("line", onLine);
9762
- }
9763
- if (child.stderr && onLine) {
9764
- const rl = (0, import_node_readline3.createInterface)({ input: child.stderr });
9765
- rl.on("line", onLine);
9766
- }
9767
- const result = await child;
9768
- lastExit = result.exitCode ?? null;
9769
- if (lastExit !== 0 && lastExit !== null) break;
9770
- }
9771
- return { ran: true, exitCode: lastExit, source: sourceLabel };
9772
- }
9773
-
9774
9862
  // src/git/orphan-cleanup.ts
9775
- var import_node_fs22 = require("fs");
9776
- var import_node_path20 = require("path");
9863
+ var import_node_fs23 = require("fs");
9864
+ var import_node_path21 = require("path");
9777
9865
  init_worktree();
9778
9866
  init_thread_store();
9779
9867
  init_paths();
@@ -9788,9 +9876,9 @@ async function findOrphanWorktrees(repoPaths) {
9788
9876
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
9789
9877
  );
9790
9878
  const homeRoot = sideboardWorkspacesDir();
9791
- if ((0, import_node_fs22.existsSync)(homeRoot)) {
9879
+ if ((0, import_node_fs23.existsSync)(homeRoot)) {
9792
9880
  try {
9793
- for (const entry of (0, import_node_fs22.readdirSync)(homeRoot, { withFileTypes: true })) {
9881
+ for (const entry of (0, import_node_fs23.readdirSync)(homeRoot, { withFileTypes: true })) {
9794
9882
  if (!entry.isDirectory()) continue;
9795
9883
  void entry;
9796
9884
  }
@@ -9800,7 +9888,7 @@ async function findOrphanWorktrees(repoPaths) {
9800
9888
  const orphans = [];
9801
9889
  const seen = /* @__PURE__ */ new Set();
9802
9890
  for (const repoPath of repos) {
9803
- if (!repoPath || !(0, import_node_fs22.existsSync)(repoPath)) continue;
9891
+ if (!repoPath || !(0, import_node_fs23.existsSync)(repoPath)) continue;
9804
9892
  try {
9805
9893
  const wts = await listWorktrees(repoPath);
9806
9894
  for (const wt of wts) {
@@ -9811,7 +9899,7 @@ async function findOrphanWorktrees(repoPaths) {
9811
9899
  seen.add(path);
9812
9900
  let mtimeMs = 0;
9813
9901
  try {
9814
- mtimeMs = (0, import_node_fs22.statSync)(path).mtimeMs;
9902
+ mtimeMs = (0, import_node_fs23.statSync)(path).mtimeMs;
9815
9903
  } catch {
9816
9904
  mtimeMs = 0;
9817
9905
  }
@@ -9821,16 +9909,16 @@ async function findOrphanWorktrees(repoPaths) {
9821
9909
  }
9822
9910
  try {
9823
9911
  const root = worktreesRoot(repoPath);
9824
- if ((0, import_node_fs22.existsSync)(root)) {
9825
- for (const entry of (0, import_node_fs22.readdirSync)(root, { withFileTypes: true })) {
9912
+ if ((0, import_node_fs23.existsSync)(root)) {
9913
+ for (const entry of (0, import_node_fs23.readdirSync)(root, { withFileTypes: true })) {
9826
9914
  if (!entry.isDirectory()) continue;
9827
- const path = (0, import_node_path20.join)(root, entry.name).replace(/\/$/, "");
9915
+ const path = (0, import_node_path21.join)(root, entry.name).replace(/\/$/, "");
9828
9916
  if (known.has(path) || seen.has(path)) continue;
9829
- if (!(0, import_node_fs22.existsSync)((0, import_node_path20.join)(path, ".git"))) continue;
9917
+ if (!(0, import_node_fs23.existsSync)((0, import_node_path21.join)(path, ".git"))) continue;
9830
9918
  seen.add(path);
9831
9919
  let mtimeMs = 0;
9832
9920
  try {
9833
- mtimeMs = (0, import_node_fs22.statSync)(path).mtimeMs;
9921
+ mtimeMs = (0, import_node_fs23.statSync)(path).mtimeMs;
9834
9922
  } catch {
9835
9923
  mtimeMs = Date.now();
9836
9924
  }
@@ -9967,8 +10055,8 @@ async function applyThreadIntoMain(thread, opts) {
9967
10055
  }
9968
10056
 
9969
10057
  // src/git/clone-repo.ts
9970
- var import_node_fs24 = require("fs");
9971
- var import_node_path22 = require("path");
10058
+ var import_node_fs25 = require("fs");
10059
+ var import_node_path23 = require("path");
9972
10060
  var import_execa6 = require("execa");
9973
10061
  init_paths();
9974
10062
  init_workspaces();
@@ -9978,12 +10066,12 @@ async function cloneRepoIntoSideboard(opts) {
9978
10066
  if (!url) throw new Error("Clone URL is required");
9979
10067
  let name = opts.name?.trim();
9980
10068
  if (!name) {
9981
- const leaf = (0, import_node_path22.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
10069
+ const leaf = (0, import_node_path23.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
9982
10070
  name = leaf || "repo";
9983
10071
  }
9984
10072
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
9985
- const dest = (0, import_node_path22.join)(sideboardReposDir(), name);
9986
- if ((0, import_node_fs24.existsSync)(dest)) {
10073
+ const dest = (0, import_node_path23.join)(sideboardReposDir(), name);
10074
+ if ((0, import_node_fs25.existsSync)(dest)) {
9987
10075
  const repoPath2 = await resolveRepoRoot(dest);
9988
10076
  const workspace2 = await ensureWorkspace(repoPath2);
9989
10077
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -10003,7 +10091,7 @@ async function cloneRepoIntoSideboard(opts) {
10003
10091
  init_thread_store();
10004
10092
 
10005
10093
  // src/threads/create.ts
10006
- var import_node_fs25 = require("fs");
10094
+ var import_node_fs26 = require("fs");
10007
10095
 
10008
10096
  // src/detect/detect.ts
10009
10097
  init_agents();
@@ -10048,7 +10136,7 @@ async function createThread(input, _onSetupLine) {
10048
10136
  });
10049
10137
  await requireAgent(resolved.agent);
10050
10138
  const repoPath = await resolveRepoRoot(input.repoPath);
10051
- if (!(0, import_node_fs25.existsSync)(repoPath)) {
10139
+ if (!(0, import_node_fs26.existsSync)(repoPath)) {
10052
10140
  throw new Error(`Repo not found: ${repoPath}`);
10053
10141
  }
10054
10142
  let sourceRef = input.sourceRef;
@@ -10511,8 +10599,8 @@ function forkChatTab(input) {
10511
10599
 
10512
10600
  // src/review/request-review.ts
10513
10601
  var import_node_crypto5 = require("crypto");
10514
- var import_node_fs26 = require("fs");
10515
- var import_node_path23 = require("path");
10602
+ var import_node_fs27 = require("fs");
10603
+ var import_node_path24 = require("path");
10516
10604
  init_global_workspace();
10517
10605
  init_thread_store();
10518
10606
 
@@ -10660,22 +10748,22 @@ function shouldRefreshReviewRequestTemplate(content) {
10660
10748
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
10661
10749
  }
10662
10750
  function readTextIfPresent(abs) {
10663
- if (!(0, import_node_fs26.existsSync)(abs)) return null;
10751
+ if (!(0, import_node_fs27.existsSync)(abs)) return null;
10664
10752
  try {
10665
- const content = (0, import_node_fs26.readFileSync)(abs, "utf8");
10753
+ const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
10666
10754
  return content.trim() ? content : null;
10667
10755
  } catch {
10668
10756
  return null;
10669
10757
  }
10670
10758
  }
10671
10759
  function ensureAttachmentsGitignore(worktreePath) {
10672
- const gitignoreAbs = (0, import_node_path23.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
10673
- if ((0, import_node_fs26.existsSync)(gitignoreAbs)) return;
10674
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(gitignoreAbs), { recursive: true });
10675
- (0, import_node_fs26.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
10760
+ const gitignoreAbs = (0, import_node_path24.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
10761
+ if ((0, import_node_fs27.existsSync)(gitignoreAbs)) return;
10762
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(gitignoreAbs), { recursive: true });
10763
+ (0, import_node_fs27.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
10676
10764
  }
10677
10765
  function resolveReviewGuidelines(worktreePath) {
10678
- const repoAbs = (0, import_node_path23.join)(worktreePath, REPO_REVIEW_PATH);
10766
+ const repoAbs = (0, import_node_path24.join)(worktreePath, REPO_REVIEW_PATH);
10679
10767
  const repoContent = readTextIfPresent(repoAbs);
10680
10768
  if (repoContent) {
10681
10769
  return {
@@ -10685,7 +10773,7 @@ function resolveReviewGuidelines(worktreePath) {
10685
10773
  source: "repo"
10686
10774
  };
10687
10775
  }
10688
- const localAbs = (0, import_node_path23.join)(worktreePath, REVIEW_REQUEST_PATH);
10776
+ const localAbs = (0, import_node_path24.join)(worktreePath, REVIEW_REQUEST_PATH);
10689
10777
  const localContent = readTextIfPresent(localAbs);
10690
10778
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
10691
10779
  return {
@@ -10695,7 +10783,7 @@ function resolveReviewGuidelines(worktreePath) {
10695
10783
  source: "local"
10696
10784
  };
10697
10785
  }
10698
- const legacyAbs = (0, import_node_path23.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10786
+ const legacyAbs = (0, import_node_path24.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10699
10787
  const legacyContent = readTextIfPresent(legacyAbs);
10700
10788
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
10701
10789
  return {
@@ -10706,8 +10794,8 @@ function resolveReviewGuidelines(worktreePath) {
10706
10794
  };
10707
10795
  }
10708
10796
  ensureAttachmentsGitignore(worktreePath);
10709
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(localAbs), { recursive: true });
10710
- (0, import_node_fs26.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
10797
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(localAbs), { recursive: true });
10798
+ (0, import_node_fs27.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
10711
10799
  return {
10712
10800
  path: REVIEW_REQUEST_PATH,
10713
10801
  name: REVIEW_REQUEST_NAME,
@@ -10907,20 +10995,20 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
10907
10995
 
10908
10996
  // src/threads/adopt.ts
10909
10997
  var import_node_child_process3 = require("child_process");
10910
- var import_node_fs27 = require("fs");
10998
+ var import_node_fs28 = require("fs");
10911
10999
  var import_node_os8 = require("os");
10912
- var import_node_path24 = require("path");
11000
+ var import_node_path25 = require("path");
10913
11001
  var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
10914
11002
  init_worktree();
10915
11003
  init_thread_store();
10916
- var CONDUCTOR_APP_SUPPORT = (0, import_node_path24.join)(
11004
+ var CONDUCTOR_APP_SUPPORT = (0, import_node_path25.join)(
10917
11005
  process.env.HOME ?? "",
10918
11006
  "Library",
10919
11007
  "Application Support",
10920
11008
  "com.conductor.app"
10921
11009
  );
10922
- var CONDUCTOR_DB = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
10923
- var CURSOR_SDK_STORE = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
11010
+ var CONDUCTOR_DB = (0, import_node_path25.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
11011
+ var CURSOR_SDK_STORE = (0, import_node_path25.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
10924
11012
  function mapAgentType(raw) {
10925
11013
  if (!raw) return null;
10926
11014
  const v = raw.toLowerCase();
@@ -10932,21 +11020,21 @@ function mapAgentType(raw) {
10932
11020
  return null;
10933
11021
  }
10934
11022
  function resolveConductorCursorAgentId(workspacePath) {
10935
- if (!workspacePath || !(0, import_node_fs27.existsSync)(CURSOR_SDK_STORE)) return null;
11023
+ if (!workspacePath || !(0, import_node_fs28.existsSync)(CURSOR_SDK_STORE)) return null;
10936
11024
  const normalized = workspacePath.replace(/\/$/, "");
10937
11025
  let best = null;
10938
11026
  let hashes;
10939
11027
  try {
10940
- hashes = (0, import_node_fs27.readdirSync)(CURSOR_SDK_STORE);
11028
+ hashes = (0, import_node_fs28.readdirSync)(CURSOR_SDK_STORE);
10941
11029
  } catch {
10942
11030
  return null;
10943
11031
  }
10944
11032
  for (const hash of hashes) {
10945
- const agentsFile = (0, import_node_path24.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
10946
- if (!(0, import_node_fs27.existsSync)(agentsFile)) continue;
11033
+ const agentsFile = (0, import_node_path25.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
11034
+ if (!(0, import_node_fs28.existsSync)(agentsFile)) continue;
10947
11035
  let text3;
10948
11036
  try {
10949
- text3 = (0, import_node_fs27.readFileSync)(agentsFile, "utf8");
11037
+ text3 = (0, import_node_fs28.readFileSync)(agentsFile, "utf8");
10950
11038
  } catch {
10951
11039
  continue;
10952
11040
  }
@@ -10970,7 +11058,7 @@ function resolveConductorCursorAgentId(workspacePath) {
10970
11058
  return best?.agentId ?? null;
10971
11059
  }
10972
11060
  async function adoptThread(input) {
10973
- if (!(0, import_node_fs27.existsSync)(input.worktreePath)) {
11061
+ if (!(0, import_node_fs28.existsSync)(input.worktreePath)) {
10974
11062
  throw new Error(`Worktree not found: ${input.worktreePath}`);
10975
11063
  }
10976
11064
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -10994,18 +11082,18 @@ async function adoptThread(input) {
10994
11082
  return thread;
10995
11083
  }
10996
11084
  function listConductorWorkspaces() {
10997
- if (!(0, import_node_fs27.existsSync)(CONDUCTOR_DB)) {
11085
+ if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
10998
11086
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
10999
11087
  }
11000
- const tmp = (0, import_node_fs27.mkdtempSync)((0, import_node_path24.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11001
- const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
11088
+ const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11089
+ const snapshot = (0, import_node_path25.join)(tmp, "conductor.db");
11002
11090
  try {
11003
- (0, import_node_fs27.copyFileSync)(CONDUCTOR_DB, snapshot);
11091
+ (0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
11004
11092
  for (const suffix of ["-wal", "-shm"]) {
11005
11093
  const src = `${CONDUCTOR_DB}${suffix}`;
11006
- if ((0, import_node_fs27.existsSync)(src)) {
11094
+ if ((0, import_node_fs28.existsSync)(src)) {
11007
11095
  try {
11008
- (0, import_node_fs27.copyFileSync)(src, `${snapshot}${suffix}`);
11096
+ (0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
11009
11097
  } catch {
11010
11098
  }
11011
11099
  }
@@ -11081,22 +11169,22 @@ function listConductorWorkspaces() {
11081
11169
  db.close();
11082
11170
  }
11083
11171
  } finally {
11084
- (0, import_node_fs27.rmSync)(tmp, { recursive: true, force: true });
11172
+ (0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
11085
11173
  }
11086
11174
  }
11087
11175
  function importConductorWorkspace(workspaceId) {
11088
- if (!(0, import_node_fs27.existsSync)(CONDUCTOR_DB)) {
11176
+ if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
11089
11177
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
11090
11178
  }
11091
- const tmp = (0, import_node_fs27.mkdtempSync)((0, import_node_path24.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11092
- const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
11179
+ const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11180
+ const snapshot = (0, import_node_path25.join)(tmp, "conductor.db");
11093
11181
  try {
11094
- (0, import_node_fs27.copyFileSync)(CONDUCTOR_DB, snapshot);
11182
+ (0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
11095
11183
  for (const suffix of ["-wal", "-shm"]) {
11096
11184
  const src = `${CONDUCTOR_DB}${suffix}`;
11097
- if ((0, import_node_fs27.existsSync)(src)) {
11185
+ if ((0, import_node_fs28.existsSync)(src)) {
11098
11186
  try {
11099
- (0, import_node_fs27.copyFileSync)(src, `${snapshot}${suffix}`);
11187
+ (0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
11100
11188
  } catch {
11101
11189
  }
11102
11190
  }
@@ -11114,7 +11202,7 @@ function importConductorWorkspace(workspaceId) {
11114
11202
  ).get(workspaceId);
11115
11203
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
11116
11204
  const worktreePath = String(row.workspacePath);
11117
- if (!(0, import_node_fs27.existsSync)(worktreePath)) {
11205
+ if (!(0, import_node_fs28.existsSync)(worktreePath)) {
11118
11206
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
11119
11207
  }
11120
11208
  let sessionId = null;
@@ -11177,7 +11265,7 @@ function importConductorWorkspace(workspaceId) {
11177
11265
  db.close();
11178
11266
  }
11179
11267
  } finally {
11180
- (0, import_node_fs27.rmSync)(tmp, { recursive: true, force: true });
11268
+ (0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
11181
11269
  }
11182
11270
  }
11183
11271
  async function importConductorWorkspaceAsync(workspaceId) {
@@ -11185,7 +11273,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
11185
11273
  }
11186
11274
 
11187
11275
  // src/threads/stack-layers.ts
11188
- var import_node_fs28 = require("fs");
11276
+ var import_node_fs29 = require("fs");
11189
11277
  init_run();
11190
11278
  init_stack();
11191
11279
  init_worktree();
@@ -11253,7 +11341,7 @@ async function openStackLayer(input, _onSetupLine) {
11253
11341
  let createdWorktree = false;
11254
11342
  const trees = await listWorktrees(repoPath);
11255
11343
  const checkedOut = trees.find((w) => w.branch === branchName);
11256
- if (checkedOut?.path && (0, import_node_fs28.existsSync)(checkedOut.path)) {
11344
+ if (checkedOut?.path && (0, import_node_fs29.existsSync)(checkedOut.path)) {
11257
11345
  if (input.reuseExistingWorktree !== false) {
11258
11346
  worktreePath = checkedOut.path;
11259
11347
  } else {
@@ -11395,7 +11483,7 @@ async function initStackFromThread(input, onSetupLine) {
11395
11483
  async function createPrStack(input, onSetupLine) {
11396
11484
  await requireAgent(input.agent);
11397
11485
  const repoPath = await resolveRepoRoot(input.repoPath);
11398
- if (!(0, import_node_fs28.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
11486
+ if (!(0, import_node_fs29.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
11399
11487
  if (!input.branches.length) throw new Error("At least one branch name required");
11400
11488
  const status = await detectGhStack(repoPath);
11401
11489
  if (!status.available) throw new Error(status.reason);
@@ -11462,7 +11550,7 @@ async function createPrStack(input, onSetupLine) {
11462
11550
  }
11463
11551
  }
11464
11552
  const claimed = new Set(threads.map((t) => t.worktreePath));
11465
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs28.existsSync)(bootstrap.worktreePath)) {
11553
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs29.existsSync)(bootstrap.worktreePath)) {
11466
11554
  try {
11467
11555
  await removeWorktree(repoPath, bootstrap.worktreePath, {
11468
11556
  deleteBranch: bootstrap.branchName
@@ -11477,12 +11565,12 @@ async function createPrStack(input, onSetupLine) {
11477
11565
  init_worktree();
11478
11566
 
11479
11567
  // src/diff/diff.ts
11480
- var import_node_fs29 = require("fs");
11481
- var import_node_path25 = require("path");
11568
+ var import_node_fs30 = require("fs");
11569
+ var import_node_path26 = require("path");
11482
11570
  init_run();
11483
11571
  init_worktree();
11484
11572
  async function inspectGitWorktree(worktreePath) {
11485
- if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) return "missing_worktree";
11573
+ if (!worktreePath || !(0, import_node_fs30.existsSync)(worktreePath)) return "missing_worktree";
11486
11574
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
11487
11575
  reject: false
11488
11576
  });
@@ -11490,7 +11578,7 @@ async function inspectGitWorktree(worktreePath) {
11490
11578
  return "ok";
11491
11579
  }
11492
11580
  async function initializeGitRepository(worktreePath) {
11493
- if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) {
11581
+ if (!worktreePath || !(0, import_node_fs30.existsSync)(worktreePath)) {
11494
11582
  throw new Error("Worktree not found");
11495
11583
  }
11496
11584
  const status = await inspectGitWorktree(worktreePath);
@@ -11625,11 +11713,11 @@ new file mode 100644
11625
11713
  };
11626
11714
  }
11627
11715
  async function untrackedPatch(worktreePath, path, maxHunk) {
11628
- const abs = (0, import_node_path25.join)(worktreePath, path);
11716
+ const abs = (0, import_node_path26.join)(worktreePath, path);
11629
11717
  try {
11630
- const st = (0, import_node_fs29.statSync)(abs);
11718
+ const st = (0, import_node_fs30.statSync)(abs);
11631
11719
  if (st.isFile() && st.size > maxHunk) {
11632
- const buf = (0, import_node_fs29.readFileSync)(abs).subarray(0, maxHunk);
11720
+ const buf = (0, import_node_fs30.readFileSync)(abs).subarray(0, maxHunk);
11633
11721
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
11634
11722
  }
11635
11723
  } catch {
@@ -12130,8 +12218,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
12130
12218
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12131
12219
  assertSafeRelativePath(relativePath);
12132
12220
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
12133
- const abs = (0, import_node_path25.join)(worktreePath, relativePath);
12134
- const st = (0, import_node_fs29.statSync)(abs);
12221
+ const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12222
+ const st = (0, import_node_fs30.statSync)(abs);
12135
12223
  if (!st.isFile()) {
12136
12224
  throw new Error(`Not a file: ${relativePath}`);
12137
12225
  }
@@ -12140,7 +12228,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12140
12228
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
12141
12229
  );
12142
12230
  }
12143
- const buf = (0, import_node_fs29.readFileSync)(abs);
12231
+ const buf = (0, import_node_fs30.readFileSync)(abs);
12144
12232
  return {
12145
12233
  path: relativePath,
12146
12234
  contentBase64: buf.toString("base64"),
@@ -12150,12 +12238,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12150
12238
  function readWorktreeFile(worktreePath, relativePath, opts) {
12151
12239
  assertSafeRelativePath(relativePath);
12152
12240
  const maxBytes = opts?.maxBytes ?? 2e5;
12153
- const abs = (0, import_node_path25.join)(worktreePath, relativePath);
12154
- const st = (0, import_node_fs29.statSync)(abs);
12241
+ const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12242
+ const st = (0, import_node_fs30.statSync)(abs);
12155
12243
  if (!st.isFile()) {
12156
12244
  throw new Error(`Not a file: ${relativePath}`);
12157
12245
  }
12158
- const buf = (0, import_node_fs29.readFileSync)(abs);
12246
+ const buf = (0, import_node_fs30.readFileSync)(abs);
12159
12247
  if (isImageRelativePath(relativePath)) {
12160
12248
  const maxImageBytes = Math.max(maxBytes, 15e6);
12161
12249
  const truncated2 = buf.length > maxImageBytes;
@@ -12198,9 +12286,9 @@ function assertSafeRelativePath(relativePath) {
12198
12286
  }
12199
12287
  function writeWorktreeFile(worktreePath, relativePath, content) {
12200
12288
  assertSafeRelativePath(relativePath);
12201
- const abs = (0, import_node_path25.join)(worktreePath, relativePath);
12202
- (0, import_node_fs29.mkdirSync)((0, import_node_path25.dirname)(abs), { recursive: true });
12203
- (0, import_node_fs29.writeFileSync)(abs, content, "utf8");
12289
+ const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12290
+ (0, import_node_fs30.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
12291
+ (0, import_node_fs30.writeFileSync)(abs, content, "utf8");
12204
12292
  return { path: relativePath };
12205
12293
  }
12206
12294
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -12304,9 +12392,9 @@ async function confirmLand(thread, opts) {
12304
12392
  }
12305
12393
 
12306
12394
  // src/skills/discover.ts
12307
- var import_node_fs30 = require("fs");
12395
+ var import_node_fs31 = require("fs");
12308
12396
  var import_node_os9 = require("os");
12309
- var import_node_path26 = require("path");
12397
+ var import_node_path27 = require("path");
12310
12398
  function toCommand(name) {
12311
12399
  return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
12312
12400
  }
@@ -12338,7 +12426,7 @@ function parseFrontmatter(content) {
12338
12426
  }
12339
12427
  function readSkill(skillMd, source) {
12340
12428
  try {
12341
- const content = (0, import_node_fs30.readFileSync)(skillMd, "utf8");
12429
+ const content = (0, import_node_fs31.readFileSync)(skillMd, "utf8");
12342
12430
  const { name: fmName, description } = parseFrontmatter(content);
12343
12431
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
12344
12432
  const name = fmName || dirName;
@@ -12357,19 +12445,19 @@ function readSkill(skillMd, source) {
12357
12445
  }
12358
12446
  }
12359
12447
  function scanSkillsDir(dir, source, out) {
12360
- if (!(0, import_node_fs30.existsSync)(dir)) return;
12448
+ if (!(0, import_node_fs31.existsSync)(dir)) return;
12361
12449
  let entries;
12362
12450
  try {
12363
- entries = (0, import_node_fs30.readdirSync)(dir);
12451
+ entries = (0, import_node_fs31.readdirSync)(dir);
12364
12452
  } catch {
12365
12453
  return;
12366
12454
  }
12367
12455
  for (const entry of entries) {
12368
12456
  if (entry.startsWith(".")) continue;
12369
- const skillMd = (0, import_node_path26.join)(dir, entry, "SKILL.md");
12370
- if (!(0, import_node_fs30.existsSync)(skillMd)) continue;
12457
+ const skillMd = (0, import_node_path27.join)(dir, entry, "SKILL.md");
12458
+ if (!(0, import_node_fs31.existsSync)(skillMd)) continue;
12371
12459
  try {
12372
- if (!(0, import_node_fs30.statSync)(skillMd).isFile()) continue;
12460
+ if (!(0, import_node_fs31.statSync)(skillMd).isFile()) continue;
12373
12461
  } catch {
12374
12462
  continue;
12375
12463
  }
@@ -12378,24 +12466,24 @@ function scanSkillsDir(dir, source, out) {
12378
12466
  }
12379
12467
  }
12380
12468
  function scanClaudePluginSkills(pluginsRoot, out) {
12381
- if (!(0, import_node_fs30.existsSync)(pluginsRoot)) return;
12469
+ if (!(0, import_node_fs31.existsSync)(pluginsRoot)) return;
12382
12470
  const walk = (dir, depth, lookingForSkillsDir) => {
12383
12471
  if (depth > 7) return;
12384
12472
  let entries;
12385
12473
  try {
12386
- entries = (0, import_node_fs30.readdirSync)(dir);
12474
+ entries = (0, import_node_fs31.readdirSync)(dir);
12387
12475
  } catch {
12388
12476
  return;
12389
12477
  }
12390
12478
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
12391
- const skill = readSkill((0, import_node_path26.join)(dir, "SKILL.md"), "cli");
12479
+ const skill = readSkill((0, import_node_path27.join)(dir, "SKILL.md"), "cli");
12392
12480
  if (skill) out.push(skill);
12393
12481
  }
12394
12482
  for (const entry of entries) {
12395
12483
  if (entry === "node_modules" || entry === ".git") continue;
12396
- const full = (0, import_node_path26.join)(dir, entry);
12484
+ const full = (0, import_node_path27.join)(dir, entry);
12397
12485
  try {
12398
- if (!(0, import_node_fs30.statSync)(full).isDirectory()) continue;
12486
+ if (!(0, import_node_fs31.statSync)(full).isDirectory()) continue;
12399
12487
  } catch {
12400
12488
  continue;
12401
12489
  }
@@ -12413,17 +12501,17 @@ function discoverSkills(worktreePath) {
12413
12501
  const home = (0, import_node_os9.homedir)();
12414
12502
  const collected = [];
12415
12503
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
12416
- scanSkillsDir((0, import_node_path26.join)(worktreePath, rel), "workspace", collected);
12504
+ scanSkillsDir((0, import_node_path27.join)(worktreePath, rel), "workspace", collected);
12417
12505
  }
12418
12506
  for (const abs of [
12419
- (0, import_node_path26.join)(home, ".claude/skills"),
12420
- (0, import_node_path26.join)(home, ".cursor/skills"),
12421
- (0, import_node_path26.join)(home, ".sideboard/skills"),
12422
- (0, import_node_path26.join)(home, ".brightsy/skills")
12507
+ (0, import_node_path27.join)(home, ".claude/skills"),
12508
+ (0, import_node_path27.join)(home, ".cursor/skills"),
12509
+ (0, import_node_path27.join)(home, ".sideboard/skills"),
12510
+ (0, import_node_path27.join)(home, ".brightsy/skills")
12423
12511
  ]) {
12424
12512
  scanSkillsDir(abs, "user", collected);
12425
12513
  }
12426
- scanClaudePluginSkills((0, import_node_path26.join)(home, ".claude/plugins"), collected);
12514
+ scanClaudePluginSkills((0, import_node_path27.join)(home, ".claude/plugins"), collected);
12427
12515
  const rank = { workspace: 0, user: 1, cli: 2 };
12428
12516
  const byCommand = /* @__PURE__ */ new Map();
12429
12517
  for (const skill of collected) {
@@ -12435,7 +12523,7 @@ function discoverSkills(worktreePath) {
12435
12523
  return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
12436
12524
  }
12437
12525
  function readSkillBody(skillPath, maxChars = 12e3) {
12438
- const raw = (0, import_node_fs30.readFileSync)(skillPath, "utf8");
12526
+ const raw = (0, import_node_fs31.readFileSync)(skillPath, "utf8");
12439
12527
  if (raw.startsWith("---")) {
12440
12528
  const end = raw.indexOf("\n---", 3);
12441
12529
  if (end >= 0) {
@@ -12528,8 +12616,8 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
12528
12616
  }
12529
12617
 
12530
12618
  // src/composer/stage-files.ts
12531
- var import_node_fs31 = require("fs");
12532
- var import_node_path27 = require("path");
12619
+ var import_node_fs32 = require("fs");
12620
+ var import_node_path28 = require("path");
12533
12621
  var import_node_crypto7 = require("crypto");
12534
12622
  init_workspace_scratch();
12535
12623
  var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -12555,7 +12643,7 @@ var IMAGE_MIME_BY_EXT = {
12555
12643
  var MAX_INLINE_BYTES = 4e5;
12556
12644
  var MAX_PREVIEW_BYTES = 5e6;
12557
12645
  function fileExtension(filePath) {
12558
- const base = (0, import_node_path27.basename)(filePath).toLowerCase();
12646
+ const base = (0, import_node_path28.basename)(filePath).toLowerCase();
12559
12647
  return base.includes(".") ? base.split(".").pop() || "" : "";
12560
12648
  }
12561
12649
  function isImageFilePath(filePath) {
@@ -12565,22 +12653,22 @@ function imageMimeType(filePath) {
12565
12653
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
12566
12654
  }
12567
12655
  function ensureAttachmentsDir(worktreePath) {
12568
- const dir = (0, import_node_path27.join)(worktreePath, ATTACHMENTS_DIR);
12569
- (0, import_node_fs31.mkdirSync)(dir, { recursive: true });
12570
- const gi = (0, import_node_path27.join)(dir, ".gitignore");
12571
- if (!(0, import_node_fs31.existsSync)(gi)) {
12572
- (0, import_node_fs31.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12656
+ const dir = (0, import_node_path28.join)(worktreePath, ATTACHMENTS_DIR);
12657
+ (0, import_node_fs32.mkdirSync)(dir, { recursive: true });
12658
+ const gi = (0, import_node_path28.join)(dir, ".gitignore");
12659
+ if (!(0, import_node_fs32.existsSync)(gi)) {
12660
+ (0, import_node_fs32.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12573
12661
  }
12574
12662
  return dir;
12575
12663
  }
12576
12664
  function uniqueAttachmentName(dir, originalName) {
12577
12665
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
12578
- if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(dir, safe))) return safe;
12579
- const ext = (0, import_node_path27.extname)(safe);
12666
+ if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(dir, safe))) return safe;
12667
+ const ext = (0, import_node_path28.extname)(safe);
12580
12668
  const stem = ext ? safe.slice(0, -ext.length) : safe;
12581
12669
  for (let i = 1; i < 1e4; i++) {
12582
12670
  const candidate = `${stem}-${i}${ext}`;
12583
- if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(dir, candidate))) return candidate;
12671
+ if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(dir, candidate))) return candidate;
12584
12672
  }
12585
12673
  return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
12586
12674
  }
@@ -12636,15 +12724,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
12636
12724
  const dir = ensureAttachmentsDir(worktreePath);
12637
12725
  const out = [];
12638
12726
  for (const abs of absolutePaths) {
12639
- const originalName = (0, import_node_path27.basename)(abs);
12727
+ const originalName = (0, import_node_path28.basename)(abs);
12640
12728
  try {
12641
- const st = (0, import_node_fs31.statSync)(abs);
12729
+ const st = (0, import_node_fs32.statSync)(abs);
12642
12730
  if (!st.isFile()) continue;
12643
12731
  const name = uniqueAttachmentName(dir, originalName);
12644
- const destAbs = (0, import_node_path27.join)(dir, name);
12645
- (0, import_node_fs31.copyFileSync)(abs, destAbs);
12732
+ const destAbs = (0, import_node_path28.join)(dir, name);
12733
+ (0, import_node_fs32.copyFileSync)(abs, destAbs);
12646
12734
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12647
- const buf = (0, import_node_fs31.readFileSync)(destAbs);
12735
+ const buf = (0, import_node_fs32.readFileSync)(destAbs);
12648
12736
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12649
12737
  } catch (err) {
12650
12738
  out.push({
@@ -12666,8 +12754,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
12666
12754
  try {
12667
12755
  const buf = Buffer.from(item.dataBase64, "base64");
12668
12756
  const name = uniqueAttachmentName(dir, originalName);
12669
- const destAbs = (0, import_node_path27.join)(dir, name);
12670
- (0, import_node_fs31.writeFileSync)(destAbs, buf);
12757
+ const destAbs = (0, import_node_path28.join)(dir, name);
12758
+ (0, import_node_fs32.writeFileSync)(destAbs, buf);
12671
12759
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12672
12760
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
12673
12761
  } catch (err) {
@@ -12687,18 +12775,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
12687
12775
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
12688
12776
  out.push({
12689
12777
  id: (0, import_node_crypto7.randomUUID)(),
12690
- name: (0, import_node_path27.basename)(rel) || "file",
12778
+ name: (0, import_node_path28.basename)(rel) || "file",
12691
12779
  kind: "file",
12692
12780
  content: `(invalid path: ${rel})`
12693
12781
  });
12694
12782
  continue;
12695
12783
  }
12696
- const name = (0, import_node_path27.basename)(rel);
12784
+ const name = (0, import_node_path28.basename)(rel);
12697
12785
  try {
12698
- const abs = (0, import_node_path27.join)(worktreePath, rel);
12699
- const st = (0, import_node_fs31.statSync)(abs);
12786
+ const abs = (0, import_node_path28.join)(worktreePath, rel);
12787
+ const st = (0, import_node_fs32.statSync)(abs);
12700
12788
  if (!st.isFile()) continue;
12701
- const buf = (0, import_node_fs31.readFileSync)(abs);
12789
+ const buf = (0, import_node_fs32.readFileSync)(abs);
12702
12790
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12703
12791
  } catch (err) {
12704
12792
  out.push({
@@ -12713,11 +12801,11 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
12713
12801
  }
12714
12802
 
12715
12803
  // src/agents/instructions.ts
12716
- var import_node_fs32 = require("fs");
12717
- var import_node_path28 = require("path");
12804
+ var import_node_fs33 = require("fs");
12805
+ var import_node_path29 = require("path");
12718
12806
  init_git_auth_mode();
12719
12807
  init_worktree_labels();
12720
- function normPath2(p) {
12808
+ function normPath3(p) {
12721
12809
  return p.replace(/\/+$/, "");
12722
12810
  }
12723
12811
  function formatRenameBranchDirective(thread, opts) {
@@ -12738,8 +12826,8 @@ function formatRenameBranchDirective(thread, opts) {
12738
12826
  return lines.join("\n");
12739
12827
  }
12740
12828
  function formatWorktreeDirective(thread, opts) {
12741
- const worktree = normPath2(thread.worktreePath);
12742
- const repo = normPath2(thread.repoPath);
12829
+ const worktree = normPath3(thread.worktreePath);
12830
+ const repo = normPath3(thread.repoPath);
12743
12831
  const dir = worktreeNameFromPath(thread.worktreePath);
12744
12832
  const lines = [
12745
12833
  "Sideboard workspace (mandatory):",
@@ -12988,7 +13076,7 @@ var Orchestrator = class {
12988
13076
  }
12989
13077
  continue;
12990
13078
  }
12991
- if (!(0, import_node_fs36.existsSync)(thread.worktreePath)) {
13079
+ if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
12992
13080
  setStatus(thread.id, "broken", "Worktree missing on disk");
12993
13081
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
12994
13082
  continue;
@@ -13163,14 +13251,7 @@ var Orchestrator = class {
13163
13251
  return thread;
13164
13252
  }
13165
13253
  async finishCreateThread(threadId, prompt) {
13166
- await this.runSetupAfterCreate(threadId);
13167
- const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
13168
- if (autoRunAfterSetupEnabled2()) {
13169
- try {
13170
- await this.startDev(threadId);
13171
- } catch {
13172
- }
13173
- }
13254
+ const setup = this.runSetupAfterCreate(threadId);
13174
13255
  if (prompt) {
13175
13256
  try {
13176
13257
  await this.send(threadId, prompt);
@@ -13181,6 +13262,14 @@ var Orchestrator = class {
13181
13262
  });
13182
13263
  }
13183
13264
  }
13265
+ await setup;
13266
+ const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
13267
+ if (autoRunAfterSetupEnabled2()) {
13268
+ try {
13269
+ await this.startDev(threadId);
13270
+ } catch {
13271
+ }
13272
+ }
13184
13273
  }
13185
13274
  /** Run workspace setup after a new worktree is created (no-op if none configured). */
13186
13275
  async runSetupAfterCreate(threadId) {
@@ -13878,7 +13967,7 @@ var Orchestrator = class {
13878
13967
  });
13879
13968
  this.emit({ type: "setup_started", threadId: thread.id });
13880
13969
  try {
13881
- let setup = await runSetupScript(
13970
+ const setup = await runWorkspaceSetup(
13882
13971
  thread.repoPath,
13883
13972
  thread.worktreePath,
13884
13973
  (line) => {
@@ -13886,18 +13975,9 @@ var Orchestrator = class {
13886
13975
  },
13887
13976
  { signal: abort.signal }
13888
13977
  );
13889
- if (!setup.ran) {
13890
- setup = await runCursorWorktreeSetup(
13891
- thread.repoPath,
13892
- thread.worktreePath,
13893
- (line) => {
13894
- this.emit({ type: "setup_output", threadId: thread.id, line });
13895
- }
13896
- );
13897
- }
13898
13978
  if (!setup.ran) {
13899
13979
  throw new Error(
13900
- "No setup script in .sideboard/settings.toml, .conductor/settings.toml, or .cursor/worktrees.json"
13980
+ "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)"
13901
13981
  );
13902
13982
  }
13903
13983
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
@@ -14205,7 +14285,7 @@ var Orchestrator = class {
14205
14285
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
14206
14286
  }
14207
14287
  for (const id of result.createdThreadIds) {
14208
- await this.runSetupAfterCreate(id);
14288
+ void this.runSetupAfterCreate(id);
14209
14289
  }
14210
14290
  return { stack: result.stack, threads: result.threads };
14211
14291
  }
@@ -14222,7 +14302,7 @@ var Orchestrator = class {
14222
14302
  status: result.thread.status
14223
14303
  });
14224
14304
  if (result.createdWorktree) {
14225
- await this.runSetupAfterCreate(result.thread.id);
14305
+ void this.runSetupAfterCreate(result.thread.id);
14226
14306
  }
14227
14307
  return { stack: result.stack, thread: result.thread };
14228
14308
  }
@@ -14237,7 +14317,7 @@ var Orchestrator = class {
14237
14317
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
14238
14318
  }
14239
14319
  for (const id of result.createdThreadIds) {
14240
- await this.runSetupAfterCreate(id);
14320
+ void this.runSetupAfterCreate(id);
14241
14321
  }
14242
14322
  return { stack: result.stack, threads: result.threads };
14243
14323
  }
@@ -14248,7 +14328,7 @@ var Orchestrator = class {
14248
14328
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
14249
14329
  }
14250
14330
  for (const id of result.createdThreadIds) {
14251
- await this.runSetupAfterCreate(id);
14331
+ void this.runSetupAfterCreate(id);
14252
14332
  }
14253
14333
  return { stack: result.stack, threads: result.threads };
14254
14334
  }
@@ -14379,7 +14459,7 @@ var Orchestrator = class {
14379
14459
  async forkThreadWorktree(input) {
14380
14460
  const thread = await forkThreadWorktree(input);
14381
14461
  this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
14382
- await this.runSetupAfterCreate(thread.id);
14462
+ void this.runSetupAfterCreate(thread.id);
14383
14463
  return thread;
14384
14464
  }
14385
14465
  renameThread(threadRef, title) {
@@ -14482,7 +14562,7 @@ var Orchestrator = class {
14482
14562
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
14483
14563
  return restored2;
14484
14564
  }
14485
- if (!(0, import_node_fs36.existsSync)(thread.worktreePath)) {
14565
+ if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
14486
14566
  const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
14487
14567
  const { execa: execa7 } = await import("execa");
14488
14568
  const slug = thread.worktreePath.split("/").pop();
@@ -15713,7 +15793,7 @@ async function startMcpServer() {
15713
15793
  async () => {
15714
15794
  const threads = orch.getThreads(true);
15715
15795
  const lines = threads.map((t) => {
15716
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path32.basename)(t.repoPath) || t.repoPath;
15796
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path33.basename)(t.repoPath) || t.repoPath;
15717
15797
  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}` : ""}`;
15718
15798
  });
15719
15799
  return {
@@ -15924,7 +16004,7 @@ async function startMcpServer() {
15924
16004
  );
15925
16005
  server.tool(
15926
16006
  "create_thread",
15927
- `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Then use send_to_thread to chat.`,
16007
+ `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn. Then use send_to_thread to chat.`,
15928
16008
  {
15929
16009
  sourceType: import_zod3.z.enum(["branch", "pr", "ticket"]),
15930
16010
  sourceRef: import_zod3.z.string(),
@@ -16442,7 +16522,7 @@ async function startMcpServer() {
16442
16522
  );
16443
16523
  server.tool(
16444
16524
  "run_setup",
16445
- "Re-run workspace setup (Sideboard/Conductor settings or .cursor/worktrees.json)",
16525
+ "Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
16446
16526
  { ref: import_zod3.z.string() },
16447
16527
  async ({ ref }) => {
16448
16528
  const result = await orch.runSetup(ref);