@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
package/dist/index.cjs CHANGED
@@ -78,10 +78,139 @@ var init_thinking_effort = __esm({
78
78
  }
79
79
  });
80
80
 
81
+ // src/hook/convention-setup.ts
82
+ function isFile(path2) {
83
+ try {
84
+ return (0, import_node_fs.statSync)(path2).isFile();
85
+ } catch {
86
+ return false;
87
+ }
88
+ }
89
+ function normPath(p) {
90
+ return p.replace(/\/+$/, "");
91
+ }
92
+ function findConventionSetup(worktreePath, repoPath) {
93
+ const roots = [
94
+ { root: worktreePath, where: "worktree" }
95
+ ];
96
+ if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
97
+ roots.push({ root: repoPath, where: "main repo" });
98
+ }
99
+ for (const { root, where } of roots) {
100
+ for (const relPath of CONVENTION_SETUP_RELPATHS) {
101
+ const absPath = (0, import_node_path.join)(root, relPath);
102
+ if (!(0, import_node_fs.existsSync)(absPath) || !isFile(absPath)) continue;
103
+ return {
104
+ relPath,
105
+ absPath,
106
+ command: `bash ${JSON.stringify(absPath)}`,
107
+ source: `${relPath} (${where})`
108
+ };
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ function hasConventionSetup(worktreePath, repoPath) {
114
+ return findConventionSetup(worktreePath, repoPath) !== null;
115
+ }
116
+ var import_node_fs, import_node_path, CONVENTION_SETUP_RELPATHS;
117
+ var init_convention_setup = __esm({
118
+ "src/hook/convention-setup.ts"() {
119
+ "use strict";
120
+ import_node_fs = require("fs");
121
+ import_node_path = require("path");
122
+ CONVENTION_SETUP_RELPATHS = [
123
+ "script/setup",
124
+ "bin/setup",
125
+ "scripts/setup.sh",
126
+ "scripts/setup"
127
+ ];
128
+ }
129
+ });
130
+
131
+ // src/hook/cursor-worktrees.ts
132
+ function loadCursorWorktreesJson(rootPath) {
133
+ const path2 = (0, import_node_path2.join)(rootPath, ".cursor", "worktrees.json");
134
+ if (!(0, import_node_fs2.existsSync)(path2)) return null;
135
+ try {
136
+ return JSON.parse((0, import_node_fs2.readFileSync)(path2, "utf8"));
137
+ } catch {
138
+ return null;
139
+ }
140
+ }
141
+ function resolveSetupSpec(config) {
142
+ if (process.platform === "win32") {
143
+ return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
144
+ }
145
+ return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
146
+ }
147
+ async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
148
+ const fromWorktree = loadCursorWorktreesJson(worktreePath);
149
+ const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
150
+ const config = fromWorktree ?? fromRepo;
151
+ if (!config) return { ran: false, exitCode: null, source: null };
152
+ const spec = resolveSetupSpec(config);
153
+ if (!spec) return { ran: false, exitCode: null, source: null };
154
+ const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
155
+ const env = {
156
+ ...process.env,
157
+ ROOT_WORKTREE_PATH: repoPath
158
+ };
159
+ if (process.platform === "win32") {
160
+ env.ROOT_WORKTREE_PATH = repoPath;
161
+ }
162
+ const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path2.join)(
163
+ fromWorktree ? worktreePath : repoPath,
164
+ ".cursor",
165
+ spec
166
+ ) : spec];
167
+ let lastExit = 0;
168
+ for (const command of commands) {
169
+ const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
170
+ const shell = process.platform === "win32" ? "powershell" : "bash";
171
+ const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
172
+ onLine?.(`[cursor setup] ${command}`);
173
+ const child = (0, import_execa.execa)(shell, args, {
174
+ cwd: worktreePath,
175
+ reject: false,
176
+ env
177
+ });
178
+ if (child.stdout && onLine) {
179
+ const rl = (0, import_node_readline.createInterface)({ input: child.stdout });
180
+ rl.on("line", onLine);
181
+ }
182
+ if (child.stderr && onLine) {
183
+ const rl = (0, import_node_readline.createInterface)({ input: child.stderr });
184
+ rl.on("line", onLine);
185
+ }
186
+ const result = await child;
187
+ lastExit = result.exitCode ?? null;
188
+ if (lastExit !== 0 && lastExit !== null) break;
189
+ }
190
+ return { ran: true, exitCode: lastExit, source: sourceLabel };
191
+ }
192
+ function hasCursorWorktreeSetup(worktreePath, repoPath) {
193
+ if (loadCursorWorktreesJson(worktreePath)) return true;
194
+ if (repoPath && repoPath !== worktreePath && loadCursorWorktreesJson(repoPath)) {
195
+ return true;
196
+ }
197
+ return false;
198
+ }
199
+ var import_node_fs2, import_node_path2, import_execa, import_node_readline;
200
+ var init_cursor_worktrees = __esm({
201
+ "src/hook/cursor-worktrees.ts"() {
202
+ "use strict";
203
+ import_node_fs2 = require("fs");
204
+ import_node_path2 = require("path");
205
+ import_execa = require("execa");
206
+ import_node_readline = require("readline");
207
+ }
208
+ });
209
+
81
210
  // src/hook/settings.ts
82
211
  function expandHome(path2) {
83
212
  if (path2.startsWith("~/") || path2 === "~") {
84
- return (0, import_node_path.join)((0, import_node_os.homedir)(), path2.slice(2));
213
+ return (0, import_node_path3.join)((0, import_node_os.homedir)(), path2.slice(2));
85
214
  }
86
215
  return path2;
87
216
  }
@@ -94,8 +223,8 @@ function parseAvailableIn(raw) {
94
223
  return out.length ? out : void 0;
95
224
  }
96
225
  function parseSettingsFile(path2, source) {
97
- if (!(0, import_node_fs.existsSync)(path2)) return null;
98
- const raw = (0, import_node_fs.readFileSync)(path2, "utf8");
226
+ if (!(0, import_node_fs3.existsSync)(path2)) return null;
227
+ const raw = (0, import_node_fs3.readFileSync)(path2, "utf8");
99
228
  const data = (0, import_smol_toml.parse)(raw);
100
229
  const scripts = data.scripts ?? {};
101
230
  const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
@@ -198,15 +327,15 @@ function finalizeSettings(parsed) {
198
327
  };
199
328
  }
200
329
  function familyFiles(rootPath, source) {
201
- const dir = (0, import_node_path.join)(rootPath, `.${source}`);
330
+ const dir = (0, import_node_path3.join)(rootPath, `.${source}`);
202
331
  return {
203
- toml: (0, import_node_path.join)(dir, "settings.toml"),
204
- local: (0, import_node_path.join)(dir, "settings.local.toml")
332
+ toml: (0, import_node_path3.join)(dir, "settings.toml"),
333
+ local: (0, import_node_path3.join)(dir, "settings.local.toml")
205
334
  };
206
335
  }
207
336
  function familyExists(rootPath, source) {
208
337
  const files = familyFiles(rootPath, source);
209
- return (0, import_node_fs.existsSync)(files.toml) || (0, import_node_fs.existsSync)(files.local);
338
+ return (0, import_node_fs3.existsSync)(files.toml) || (0, import_node_fs3.existsSync)(files.local);
210
339
  }
211
340
  function detectFamily(rootPath) {
212
341
  if (familyExists(rootPath, "sideboard")) return "sideboard";
@@ -225,7 +354,7 @@ function loadAnyLocal(rootPath) {
225
354
  loadLocalToml(rootPath, "sideboard")
226
355
  );
227
356
  }
228
- function normPath(p) {
357
+ function normPath2(p) {
229
358
  return p.replace(/\/+$/, "");
230
359
  }
231
360
  function loadRepoSettings(repoPath) {
@@ -239,11 +368,11 @@ function loadRepoSettings(repoPath) {
239
368
  }
240
369
  function loadWorkspaceSettings(worktreePath, repoPath) {
241
370
  const wtFamily = detectFamily(worktreePath);
242
- const repoFamily = repoPath && normPath(repoPath) !== normPath(worktreePath) ? detectFamily(repoPath) : null;
371
+ const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
243
372
  const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
244
373
  const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
245
374
  let merged = wtToml ?? repoToml;
246
- if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
375
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
247
376
  merged = mergeSettings(merged, loadAnyLocal(repoPath));
248
377
  }
249
378
  merged = mergeSettings(merged, loadAnyLocal(worktreePath));
@@ -257,7 +386,7 @@ function hasRepoHook(repoPath) {
257
386
  }
258
387
  function hasWorkspaceHook(worktreePath, repoPath) {
259
388
  if (hasRepoHook(worktreePath)) return true;
260
- if (repoPath && normPath(repoPath) !== normPath(worktreePath) && hasRepoHook(repoPath)) {
389
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath) && hasRepoHook(repoPath)) {
261
390
  return true;
262
391
  }
263
392
  return false;
@@ -269,16 +398,16 @@ function settingsSourceLabel(rootPath) {
269
398
  const family = detectFamily(rootPath);
270
399
  if (!family) return null;
271
400
  const files = familyFiles(rootPath, family);
272
- if ((0, import_node_fs.existsSync)(files.toml) && (0, import_node_fs.existsSync)(files.local)) {
401
+ if ((0, import_node_fs3.existsSync)(files.toml) && (0, import_node_fs3.existsSync)(files.local)) {
273
402
  return `.${family}/settings.toml + local`;
274
403
  }
275
- if ((0, import_node_fs.existsSync)(files.local)) return `.${family}/settings.local.toml`;
404
+ if ((0, import_node_fs3.existsSync)(files.local)) return `.${family}/settings.local.toml`;
276
405
  return `.${family}/settings.toml`;
277
406
  }
278
407
  function workspaceSettingsSourceLabel(worktreePath, repoPath) {
279
408
  const wt = settingsSourceLabel(worktreePath);
280
409
  if (wt) return `${wt} (worktree)`;
281
- if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
410
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
282
411
  const repo = settingsSourceLabel(repoPath);
283
412
  if (repo) return `${repo} (main repo)`;
284
413
  }
@@ -286,20 +415,32 @@ function workspaceSettingsSourceLabel(worktreePath, repoPath) {
286
415
  }
287
416
  function getRepoSetupInfo(worktreePath, repoPath) {
288
417
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
418
+ const convention = findConventionSetup(worktreePath, repoPath);
419
+ const cursor = hasCursorWorktreeSetup(worktreePath, repoPath);
420
+ const hasSetupScript = Boolean(settings?.setup) || cursor || Boolean(convention);
421
+ let configLabel = workspaceSettingsSourceLabel(worktreePath, repoPath);
422
+ if (!settings?.setup) {
423
+ if (convention) configLabel = convention.source;
424
+ else if (cursor) {
425
+ configLabel = hasCursorWorktreeSetup(worktreePath) ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
426
+ }
427
+ }
289
428
  return {
290
- hasConfig: hasWorkspaceHook(worktreePath, repoPath),
291
- hasSetupScript: Boolean(settings?.setup),
292
- configLabel: workspaceSettingsSourceLabel(worktreePath, repoPath)
429
+ hasConfig: hasWorkspaceHook(worktreePath, repoPath) || cursor || Boolean(convention),
430
+ hasSetupScript,
431
+ configLabel
293
432
  };
294
433
  }
295
- var import_node_fs, import_node_os, import_node_path, import_smol_toml;
434
+ var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
296
435
  var init_settings = __esm({
297
436
  "src/hook/settings.ts"() {
298
437
  "use strict";
299
- import_node_fs = require("fs");
438
+ import_node_fs3 = require("fs");
300
439
  import_node_os = require("os");
301
- import_node_path = require("path");
440
+ import_node_path3 = require("path");
302
441
  import_smol_toml = require("smol-toml");
442
+ init_convention_setup();
443
+ init_cursor_worktrees();
303
444
  }
304
445
  });
305
446
 
@@ -320,67 +461,67 @@ __export(paths_exports, {
320
461
  });
321
462
  function appDataDir() {
322
463
  const override = process.env.SIDEBOARD_APP_DATA?.trim();
323
- 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");
324
- (0, import_node_fs2.mkdirSync)(base, { recursive: true });
464
+ 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");
465
+ (0, import_node_fs4.mkdirSync)(base, { recursive: true });
325
466
  return base;
326
467
  }
327
468
  function threadsDir() {
328
- const dir = (0, import_node_path3.join)(appDataDir(), "threads");
329
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
469
+ const dir = (0, import_node_path5.join)(appDataDir(), "threads");
470
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
330
471
  return dir;
331
472
  }
332
473
  function locksDir() {
333
- const dir = (0, import_node_path3.join)(appDataDir(), "locks");
334
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
474
+ const dir = (0, import_node_path5.join)(appDataDir(), "locks");
475
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
335
476
  return dir;
336
477
  }
337
478
  function sideboardHomeDir() {
338
- const dir = (0, import_node_path3.join)((0, import_node_os2.homedir)(), "sideboard");
339
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
479
+ const dir = (0, import_node_path5.join)((0, import_node_os2.homedir)(), "sideboard");
480
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
340
481
  return dir;
341
482
  }
342
483
  function sideboardReposDir() {
343
- const dir = (0, import_node_path3.join)(sideboardHomeDir(), "repos");
344
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
484
+ const dir = (0, import_node_path5.join)(sideboardHomeDir(), "repos");
485
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
345
486
  return dir;
346
487
  }
347
488
  function sideboardWorkspacesDir() {
348
- const dir = (0, import_node_path3.join)(sideboardHomeDir(), "workspaces");
349
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
489
+ const dir = (0, import_node_path5.join)(sideboardHomeDir(), "workspaces");
490
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
350
491
  return dir;
351
492
  }
352
493
  function repoSlug(repoPath) {
353
- return (0, import_node_path2.basename)(repoPath.replace(/\/$/, "")) || "repo";
494
+ return (0, import_node_path4.basename)(repoPath.replace(/\/$/, "")) || "repo";
354
495
  }
355
496
  function worktreesRoot(repoPath) {
356
497
  const settings = loadRepoSettings(repoPath);
357
498
  if (settings?.worktreesRoot) {
358
- (0, import_node_fs2.mkdirSync)(settings.worktreesRoot, { recursive: true });
499
+ (0, import_node_fs4.mkdirSync)(settings.worktreesRoot, { recursive: true });
359
500
  return settings.worktreesRoot;
360
501
  }
361
- const dir = (0, import_node_path3.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
362
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
502
+ const dir = (0, import_node_path5.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
503
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
363
504
  return dir;
364
505
  }
365
506
  function threadFilePath(id) {
366
- return (0, import_node_path3.join)(threadsDir(), `${id}.json`);
507
+ return (0, import_node_path5.join)(threadsDir(), `${id}.json`);
367
508
  }
368
509
  function threadLockPath(id) {
369
- return (0, import_node_path3.join)(locksDir(), `${id}.lock`);
510
+ return (0, import_node_path5.join)(locksDir(), `${id}.lock`);
370
511
  }
371
512
  function globalAgentCwd() {
372
- const dir = (0, import_node_path3.join)(appDataDir(), "global");
373
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
513
+ const dir = (0, import_node_path5.join)(appDataDir(), "global");
514
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
374
515
  return dir;
375
516
  }
376
- var import_node_path2, import_node_os2, import_node_path3, import_node_fs2;
517
+ var import_node_path4, import_node_os2, import_node_path5, import_node_fs4;
377
518
  var init_paths = __esm({
378
519
  "src/store/paths.ts"() {
379
520
  "use strict";
380
- import_node_path2 = require("path");
521
+ import_node_path4 = require("path");
381
522
  import_node_os2 = require("os");
382
- import_node_path3 = require("path");
383
- import_node_fs2 = require("fs");
523
+ import_node_path5 = require("path");
524
+ import_node_fs4 = require("fs");
384
525
  init_settings();
385
526
  }
386
527
  });
@@ -422,22 +563,22 @@ var init_nested_electron_env = __esm({
422
563
 
423
564
  // src/store/private-file.ts
424
565
  function writePrivateFile(path2, contents) {
425
- (0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(path2), { recursive: true });
426
- (0, import_node_fs3.writeFileSync)(path2, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
566
+ (0, import_node_fs5.mkdirSync)((0, import_node_path6.dirname)(path2), { recursive: true });
567
+ (0, import_node_fs5.writeFileSync)(path2, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
427
568
  chmodOwnerOnly(path2);
428
569
  }
429
570
  function chmodOwnerOnly(path2) {
430
571
  try {
431
- (0, import_node_fs3.chmodSync)(path2, PRIVATE_FILE_MODE);
572
+ (0, import_node_fs5.chmodSync)(path2, PRIVATE_FILE_MODE);
432
573
  } catch {
433
574
  }
434
575
  }
435
- var import_node_fs3, import_node_path4, PRIVATE_FILE_MODE;
576
+ var import_node_fs5, import_node_path6, PRIVATE_FILE_MODE;
436
577
  var init_private_file = __esm({
437
578
  "src/store/private-file.ts"() {
438
579
  "use strict";
439
- import_node_fs3 = require("fs");
440
- import_node_path4 = require("path");
580
+ import_node_fs5 = require("fs");
581
+ import_node_path6 = require("path");
441
582
  PRIVATE_FILE_MODE = 384;
442
583
  }
443
584
  });
@@ -529,11 +670,11 @@ function decryptEnvelope(envelope, key) {
529
670
  return JSON.parse(plaintext.toString("utf8"));
530
671
  }
531
672
  function readSecureJson(path2) {
532
- if (!(0, import_node_fs4.existsSync)(path2)) return null;
673
+ if (!(0, import_node_fs6.existsSync)(path2)) return null;
533
674
  chmodOwnerOnly(path2);
534
675
  let parsed;
535
676
  try {
536
- parsed = JSON.parse((0, import_node_fs4.readFileSync)(path2, "utf8"));
677
+ parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
537
678
  } catch {
538
679
  return null;
539
680
  }
@@ -553,17 +694,17 @@ function writeSecureJson(path2, value) {
553
694
  `);
554
695
  }
555
696
  function isSecureFileEncrypted(path2) {
556
- if (!(0, import_node_fs4.existsSync)(path2)) return false;
697
+ if (!(0, import_node_fs6.existsSync)(path2)) return false;
557
698
  try {
558
- return isEnvelope(JSON.parse((0, import_node_fs4.readFileSync)(path2, "utf8")));
699
+ return isEnvelope(JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8")));
559
700
  } catch {
560
701
  return false;
561
702
  }
562
703
  }
563
704
  function secureFileUnlocksWith(path2, key) {
564
- if (!(0, import_node_fs4.existsSync)(path2) || key.length !== 32) return true;
705
+ if (!(0, import_node_fs6.existsSync)(path2) || key.length !== 32) return true;
565
706
  try {
566
- const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path2, "utf8"));
707
+ const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
567
708
  if (!isEnvelope(parsed)) return true;
568
709
  decryptEnvelope(parsed, key);
569
710
  return true;
@@ -571,13 +712,13 @@ function secureFileUnlocksWith(path2, key) {
571
712
  return false;
572
713
  }
573
714
  }
574
- var import_node_child_process, import_node_crypto, import_node_fs4, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
715
+ var import_node_child_process, import_node_crypto, import_node_fs6, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
575
716
  var init_secure_file = __esm({
576
717
  "src/store/secure-file.ts"() {
577
718
  "use strict";
578
719
  import_node_child_process = require("child_process");
579
720
  import_node_crypto = require("crypto");
580
- import_node_fs4 = require("fs");
721
+ import_node_fs6 = require("fs");
581
722
  init_private_file();
582
723
  KEYCHAIN_SERVICE = "ai.sideboard.app";
583
724
  KEYCHAIN_ACCOUNT = "secret-vault-v1";
@@ -588,7 +729,7 @@ var init_secure_file = __esm({
588
729
 
589
730
  // src/store/secret-vault.ts
590
731
  function secretVaultPath() {
591
- return (0, import_node_path5.join)(appDataDir(), "secrets.json");
732
+ return (0, import_node_path7.join)(appDataDir(), "secrets.json");
592
733
  }
593
734
  function loadSecretVault() {
594
735
  const parsed = readSecureJson(secretVaultPath());
@@ -632,11 +773,11 @@ function normalizeVault(raw) {
632
773
  }
633
774
  return out;
634
775
  }
635
- var import_node_path5;
776
+ var import_node_path7;
636
777
  var init_secret_vault = __esm({
637
778
  "src/store/secret-vault.ts"() {
638
779
  "use strict";
639
- import_node_path5 = require("path");
780
+ import_node_path7 = require("path");
640
781
  init_paths();
641
782
  init_secure_file();
642
783
  }
@@ -737,10 +878,10 @@ function toPublicAppSettings(settings) {
737
878
  };
738
879
  }
739
880
  function appSettingsPath() {
740
- return (0, import_node_path6.join)(appDataDir(), "settings.json");
881
+ return (0, import_node_path8.join)(appDataDir(), "settings.json");
741
882
  }
742
883
  function claudeUserSettingsPath() {
743
- return (0, import_node_path6.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
884
+ return (0, import_node_path8.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
744
885
  }
745
886
  function normalizeClaude(raw) {
746
887
  if (!raw || typeof raw !== "object") return {};
@@ -983,10 +1124,10 @@ function normalizeSettings(raw) {
983
1124
  }
984
1125
  function readSettingsFile() {
985
1126
  const path2 = appSettingsPath();
986
- if (!(0, import_node_fs5.existsSync)(path2)) return { ...EMPTY_SETTINGS };
1127
+ if (!(0, import_node_fs7.existsSync)(path2)) return { ...EMPTY_SETTINGS };
987
1128
  try {
988
1129
  chmodOwnerOnly(path2);
989
- const parsed = JSON.parse((0, import_node_fs5.readFileSync)(path2, "utf8"));
1130
+ const parsed = JSON.parse((0, import_node_fs7.readFileSync)(path2, "utf8"));
990
1131
  return normalizeSettings(parsed);
991
1132
  } catch {
992
1133
  return { ...EMPTY_SETTINGS };
@@ -1546,14 +1687,14 @@ function childEnvWithAppSettings(extra) {
1546
1687
  function harnessEnvKey(harness) {
1547
1688
  return HARNESS_ENV_KEYS[harness];
1548
1689
  }
1549
- var import_node_crypto2, import_node_fs5, import_node_os3, import_node_path6, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
1690
+ var import_node_crypto2, import_node_fs7, import_node_os3, import_node_path8, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
1550
1691
  var init_app_settings = __esm({
1551
1692
  "src/store/app-settings.ts"() {
1552
1693
  "use strict";
1553
1694
  import_node_crypto2 = require("crypto");
1554
- import_node_fs5 = require("fs");
1695
+ import_node_fs7 = require("fs");
1555
1696
  import_node_os3 = require("os");
1556
- import_node_path6 = require("path");
1697
+ import_node_path8 = require("path");
1557
1698
  init_thinking_effort();
1558
1699
  init_nested_electron_env();
1559
1700
  init_paths();
@@ -1615,7 +1756,7 @@ function setCaffeinateHoldHooks(next) {
1615
1756
  hooks = next;
1616
1757
  }
1617
1758
  function caffeinateHoldPath() {
1618
- return (0, import_node_path7.join)(appDataDir(), "caffeinate-hold.json");
1759
+ return (0, import_node_path9.join)(appDataDir(), "caffeinate-hold.json");
1619
1760
  }
1620
1761
  function processAlive(pid) {
1621
1762
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -1649,9 +1790,9 @@ function uniqueIds(ids) {
1649
1790
  }
1650
1791
  function readHold() {
1651
1792
  const path2 = caffeinateHoldPath();
1652
- if (!(0, import_node_fs6.existsSync)(path2)) return null;
1793
+ if (!(0, import_node_fs8.existsSync)(path2)) return null;
1653
1794
  try {
1654
- const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
1795
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path2, "utf8"));
1655
1796
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
1656
1797
  return {
1657
1798
  pid: parsed.pid,
@@ -1673,7 +1814,7 @@ function writeHold(pid, threadIds) {
1673
1814
  }
1674
1815
  function clearHold() {
1675
1816
  try {
1676
- (0, import_node_fs6.unlinkSync)(caffeinateHoldPath());
1817
+ (0, import_node_fs8.unlinkSync)(caffeinateHoldPath());
1677
1818
  } catch {
1678
1819
  }
1679
1820
  }
@@ -1758,13 +1899,13 @@ function releaseCaffeinateHoldForThread(threadId) {
1758
1899
  }
1759
1900
  return setCaffeinateHold(false, { threadId: id });
1760
1901
  }
1761
- var import_node_child_process2, import_node_fs6, import_node_path7, hooks;
1902
+ var import_node_child_process2, import_node_fs8, import_node_path9, hooks;
1762
1903
  var init_caffeinate_hold = __esm({
1763
1904
  "src/store/caffeinate-hold.ts"() {
1764
1905
  "use strict";
1765
1906
  import_node_child_process2 = require("child_process");
1766
- import_node_fs6 = require("fs");
1767
- import_node_path7 = require("path");
1907
+ import_node_fs8 = require("fs");
1908
+ import_node_path9 = require("path");
1768
1909
  init_paths();
1769
1910
  init_private_file();
1770
1911
  hooks = {};
@@ -1858,7 +1999,7 @@ function createEmptyThread(partial) {
1858
1999
  }
1859
2000
  async function withThreadLock(id, fn) {
1860
2001
  const lockPath = threadLockPath(id);
1861
- (0, import_node_fs7.writeFileSync)(lockPath, "", { flag: "a" });
2002
+ (0, import_node_fs9.writeFileSync)(lockPath, "", { flag: "a" });
1862
2003
  let release;
1863
2004
  try {
1864
2005
  release = await import_proper_lockfile.default.lock(lockPath, {
@@ -1872,26 +2013,26 @@ async function withThreadLock(id, fn) {
1872
2013
  }
1873
2014
  function readThread(id) {
1874
2015
  const path2 = threadFilePath(id);
1875
- if (!(0, import_node_fs7.existsSync)(path2)) return null;
1876
- const raw = (0, import_node_fs7.readFileSync)(path2, "utf8");
2016
+ if (!(0, import_node_fs9.existsSync)(path2)) return null;
2017
+ const raw = (0, import_node_fs9.readFileSync)(path2, "utf8");
1877
2018
  return normalizeThread(JSON.parse(raw));
1878
2019
  }
1879
2020
  function writeThread(thread) {
1880
2021
  const path2 = threadFilePath(idPath(thread.id));
1881
2022
  const tmp = `${path2}.${process.pid}.tmp`;
1882
2023
  const next = { ...thread, updatedAt: nowIso() };
1883
- (0, import_node_fs7.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
1884
- (0, import_node_fs7.renameSync)(tmp, path2);
2024
+ (0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
2025
+ (0, import_node_fs9.renameSync)(tmp, path2);
1885
2026
  }
1886
2027
  function idPath(id) {
1887
2028
  return id;
1888
2029
  }
1889
2030
  function listThreads(opts) {
1890
- const files = (0, import_node_fs7.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
2031
+ const files = (0, import_node_fs9.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
1891
2032
  const threads = files.map((f) => {
1892
2033
  try {
1893
2034
  return normalizeThread(
1894
- JSON.parse((0, import_node_fs7.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
2035
+ JSON.parse((0, import_node_fs9.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
1895
2036
  );
1896
2037
  } catch {
1897
2038
  return null;
@@ -1902,11 +2043,11 @@ function listThreads(opts) {
1902
2043
  }
1903
2044
  function deleteThreadRecord(id) {
1904
2045
  const path2 = threadFilePath(id);
1905
- if ((0, import_node_fs7.existsSync)(path2)) (0, import_node_fs7.unlinkSync)(path2);
2046
+ if ((0, import_node_fs9.existsSync)(path2)) (0, import_node_fs9.unlinkSync)(path2);
1906
2047
  const lock = threadLockPath(id);
1907
- if ((0, import_node_fs7.existsSync)(lock)) {
2048
+ if ((0, import_node_fs9.existsSync)(lock)) {
1908
2049
  try {
1909
- (0, import_node_fs7.unlinkSync)(lock);
2050
+ (0, import_node_fs9.unlinkSync)(lock);
1910
2051
  } catch {
1911
2052
  }
1912
2053
  }
@@ -1930,12 +2071,12 @@ function findThreadByRef(ref) {
1930
2071
  const all = listThreads({ includeArchived: true });
1931
2072
  return all.find((t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref) ?? null;
1932
2073
  }
1933
- var import_node_crypto3, import_node_fs7, import_proper_lockfile;
2074
+ var import_node_crypto3, import_node_fs9, import_proper_lockfile;
1934
2075
  var init_thread_store = __esm({
1935
2076
  "src/store/thread-store.ts"() {
1936
2077
  "use strict";
1937
2078
  import_node_crypto3 = require("crypto");
1938
- import_node_fs7 = require("fs");
2079
+ import_node_fs9 = require("fs");
1939
2080
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
1940
2081
  init_thinking_effort();
1941
2082
  init_paths();
@@ -2917,17 +3058,17 @@ var init_gh_errors = __esm({
2917
3058
 
2918
3059
  // src/agents/path.ts
2919
3060
  function prependPathDir(env, dir) {
2920
- if (!dir || !(0, import_node_fs8.existsSync)(dir)) return;
3061
+ if (!dir || !(0, import_node_fs10.existsSync)(dir)) return;
2921
3062
  const current = env.PATH ?? "";
2922
- const parts = current.split(import_node_path8.delimiter).filter(Boolean);
3063
+ const parts = current.split(import_node_path10.delimiter).filter(Boolean);
2923
3064
  if (parts.includes(dir)) {
2924
3065
  env.PATH = current;
2925
3066
  return;
2926
3067
  }
2927
- env.PATH = [dir, ...parts].join(import_node_path8.delimiter);
3068
+ env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
2928
3069
  }
2929
3070
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
2930
- return (0, import_node_path8.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
3071
+ return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
2931
3072
  }
2932
3073
  function isConductorBundledCli(filePath) {
2933
3074
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -2936,21 +3077,21 @@ function isConductorBundledCli(filePath) {
2936
3077
  function ensureAgentPath(env = process.env) {
2937
3078
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
2938
3079
  const current = env.PATH ?? "";
2939
- const parts = current.split(import_node_path8.delimiter).filter(Boolean);
3080
+ const parts = current.split(import_node_path10.delimiter).filter(Boolean);
2940
3081
  const seen = new Set(parts);
2941
3082
  const extras = [
2942
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path8.join)(home, rel)),
3083
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
2943
3084
  "/opt/homebrew/bin",
2944
3085
  "/usr/local/bin",
2945
3086
  // Keep after Homebrew/npm so a user-installed CLI still wins.
2946
3087
  conductorBundledBinDir(home)
2947
3088
  ];
2948
3089
  for (const dir of extras.reverse()) {
2949
- if (!dir || seen.has(dir) || !(0, import_node_fs8.existsSync)(dir)) continue;
3090
+ if (!dir || seen.has(dir) || !(0, import_node_fs10.existsSync)(dir)) continue;
2950
3091
  parts.unshift(dir);
2951
3092
  seen.add(dir);
2952
3093
  }
2953
- const next = parts.join(import_node_path8.delimiter);
3094
+ const next = parts.join(import_node_path10.delimiter);
2954
3095
  env.PATH = next;
2955
3096
  return next;
2956
3097
  }
@@ -2964,7 +3105,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
2964
3105
  stdio: ["ignore", "pipe", "ignore"]
2965
3106
  }).trim().split(/\r?\n/).find(Boolean);
2966
3107
  if (prefix) {
2967
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path8.join)(prefix, "bin");
3108
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
2968
3109
  prependPathDir(env, binDir);
2969
3110
  }
2970
3111
  } catch {
@@ -2992,14 +3133,14 @@ function withExportedPath(command, pathValue) {
2992
3133
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
2993
3134
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
2994
3135
  }
2995
- var import_node_fs8, import_node_child_process3, import_node_os4, import_node_path8, EXTRA_BIN_DIRS;
3136
+ var import_node_fs10, import_node_child_process3, import_node_os4, import_node_path10, EXTRA_BIN_DIRS;
2996
3137
  var init_path = __esm({
2997
3138
  "src/agents/path.ts"() {
2998
3139
  "use strict";
2999
- import_node_fs8 = require("fs");
3140
+ import_node_fs10 = require("fs");
3000
3141
  import_node_child_process3 = require("child_process");
3001
3142
  import_node_os4 = require("os");
3002
- import_node_path8 = require("path");
3143
+ import_node_path10 = require("path");
3003
3144
  EXTRA_BIN_DIRS = [
3004
3145
  ".local/bin",
3005
3146
  ".cargo/bin",
@@ -3027,7 +3168,7 @@ __export(run_exports, {
3027
3168
  async function run(file, args, opts) {
3028
3169
  ensureAgentPath();
3029
3170
  try {
3030
- const result = await (0, import_execa.execa)(file, args, {
3171
+ const result = await (0, import_execa2.execa)(file, args, {
3031
3172
  cwd: opts?.cwd,
3032
3173
  env: { ...process.env, ...opts?.env },
3033
3174
  reject: opts?.reject ?? true,
@@ -3091,11 +3232,11 @@ async function resolveGhAuthToken(cwd) {
3091
3232
  const token = result.stdout.trim();
3092
3233
  return token || null;
3093
3234
  }
3094
- var import_execa;
3235
+ var import_execa2;
3095
3236
  var init_run = __esm({
3096
3237
  "src/git/run.ts"() {
3097
3238
  "use strict";
3098
- import_execa = require("execa");
3239
+ import_execa2 = require("execa");
3099
3240
  init_path();
3100
3241
  }
3101
3242
  });
@@ -3220,7 +3361,7 @@ function formatGitAuthModeDirective(mode) {
3220
3361
  default:
3221
3362
  return [
3222
3363
  "Git authentication (Account \u2192 GitHub mode: auto):",
3223
- "- 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).",
3364
+ "- 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).",
3224
3365
  "- Do not switch remotes to SSH. Push with `git push -u origin HEAD`.",
3225
3366
  "- 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."
3226
3367
  ].join("\n");
@@ -4318,8 +4459,8 @@ function isLocalPrFetchBranch(ref) {
4318
4459
  }
4319
4460
  async function createThreadWorktree(opts) {
4320
4461
  let branchName = `thread/${opts.slug}`;
4321
- const worktreePath = (0, import_node_path9.join)(worktreesRoot(opts.repoPath), opts.slug);
4322
- if ((0, import_node_fs9.existsSync)(worktreePath)) {
4462
+ const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
4463
+ if ((0, import_node_fs11.existsSync)(worktreePath)) {
4323
4464
  throw new Error(`Worktree already exists at ${worktreePath}`);
4324
4465
  }
4325
4466
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4388,8 +4529,8 @@ ${add.stdout}`;
4388
4529
  async function createExistingBranchWorktree(opts) {
4389
4530
  const branchName = opts.branchName.trim();
4390
4531
  if (!branchName) throw new Error("branch name required");
4391
- const worktreePath = (0, import_node_path9.join)(worktreesRoot(opts.repoPath), opts.slug);
4392
- if ((0, import_node_fs9.existsSync)(worktreePath)) {
4532
+ const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
4533
+ if ((0, import_node_fs11.existsSync)(worktreePath)) {
4393
4534
  throw new Error(`Worktree already exists at ${worktreePath}`);
4394
4535
  }
4395
4536
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4677,10 +4818,10 @@ function sameRepoPath(a, b) {
4677
4818
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
4678
4819
  }
4679
4820
  function listLocalThreadBranchSlugs(repoPath) {
4680
- const refsDir = (0, import_node_path9.join)(repoPath, ".git", "refs", "heads", "thread");
4681
- if (!(0, import_node_fs9.existsSync)(refsDir)) return [];
4821
+ const refsDir = (0, import_node_path11.join)(repoPath, ".git", "refs", "heads", "thread");
4822
+ if (!(0, import_node_fs11.existsSync)(refsDir)) return [];
4682
4823
  try {
4683
- return (0, import_node_fs9.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
4824
+ return (0, import_node_fs11.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
4684
4825
  } catch {
4685
4826
  return [];
4686
4827
  }
@@ -4688,8 +4829,8 @@ function listLocalThreadBranchSlugs(repoPath) {
4688
4829
  function collectTakenTeamSlugs(repoPath) {
4689
4830
  const taken = /* @__PURE__ */ new Set();
4690
4831
  const root = worktreesRoot(repoPath);
4691
- if ((0, import_node_fs9.existsSync)(root)) {
4692
- for (const entry of (0, import_node_fs9.readdirSync)(root, { withFileTypes: true })) {
4832
+ if ((0, import_node_fs11.existsSync)(root)) {
4833
+ for (const entry of (0, import_node_fs11.readdirSync)(root, { withFileTypes: true })) {
4693
4834
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
4694
4835
  taken.add(normalizeTakenSlug(entry.name));
4695
4836
  }
@@ -4710,18 +4851,18 @@ function allocateTeamSlug(repoPath) {
4710
4851
  const taken = collectTakenTeamSlugs(repoPath);
4711
4852
  for (let attempt = 0; attempt < 32; attempt++) {
4712
4853
  const team = allocateTeamName(taken);
4713
- const path2 = (0, import_node_path9.join)(worktreesRoot(repoPath), team.slug);
4714
- if (!(0, import_node_fs9.existsSync)(path2)) return team;
4854
+ const path2 = (0, import_node_path11.join)(worktreesRoot(repoPath), team.slug);
4855
+ if (!(0, import_node_fs11.existsSync)(path2)) return team;
4715
4856
  taken.add(team.slug);
4716
4857
  }
4717
4858
  throw new Error("No available soccer team worktree directories left");
4718
4859
  }
4719
- var import_node_fs9, import_node_path9;
4860
+ var import_node_fs11, import_node_path11;
4720
4861
  var init_worktree = __esm({
4721
4862
  "src/git/worktree.ts"() {
4722
4863
  "use strict";
4723
- import_node_fs9 = require("fs");
4724
- import_node_path9 = require("path");
4864
+ import_node_fs11 = require("fs");
4865
+ import_node_path11 = require("path");
4725
4866
  init_paths();
4726
4867
  init_thread_store();
4727
4868
  init_teams();
@@ -4805,7 +4946,7 @@ function coordinatorTurnReminder(opts) {
4805
4946
  function ensureGlobalCoordinatorCwd(opts) {
4806
4947
  const dir = globalAgentCwd();
4807
4948
  try {
4808
- (0, import_node_fs10.mkdirSync)(dir, { recursive: true });
4949
+ (0, import_node_fs12.mkdirSync)(dir, { recursive: true });
4809
4950
  } catch {
4810
4951
  return dir;
4811
4952
  }
@@ -4813,7 +4954,7 @@ function ensureGlobalCoordinatorCwd(opts) {
4813
4954
  let orchId = opts?.orchestratorThreadId?.trim() || "";
4814
4955
  if (!orchId) {
4815
4956
  try {
4816
- const existing = (0, import_node_fs10.readFileSync)((0, import_node_path10.join)(dir, "AGENTS.md"), "utf8");
4957
+ const existing = (0, import_node_fs12.readFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), "utf8");
4817
4958
  const m = existing.match(
4818
4959
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
4819
4960
  );
@@ -4855,9 +4996,9 @@ function ensureGlobalCoordinatorCwd(opts) {
4855
4996
  "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."
4856
4997
  ].join("\n");
4857
4998
  try {
4858
- (0, import_node_fs10.writeFileSync)((0, import_node_path10.join)(dir, "CLAUDE.md"), `${body}
4999
+ (0, import_node_fs12.writeFileSync)((0, import_node_path12.join)(dir, "CLAUDE.md"), `${body}
4859
5000
  `, "utf8");
4860
- (0, import_node_fs10.writeFileSync)((0, import_node_path10.join)(dir, "AGENTS.md"), `${body}
5001
+ (0, import_node_fs12.writeFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), `${body}
4861
5002
  `, "utf8");
4862
5003
  } catch {
4863
5004
  }
@@ -4889,12 +5030,12 @@ function coordinatorSystemPrompt(opts) {
4889
5030
  formatWorkspaceInventory(opts.workspaces)
4890
5031
  ].join("\n");
4891
5032
  }
4892
- var import_node_fs10, import_node_path10, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
5033
+ var import_node_fs12, import_node_path12, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
4893
5034
  var init_coordinator_prompt = __esm({
4894
5035
  "src/orchestrator/coordinator-prompt.ts"() {
4895
5036
  "use strict";
4896
- import_node_fs10 = require("fs");
4897
- import_node_path10 = require("path");
5037
+ import_node_fs12 = require("fs");
5038
+ import_node_path12 = require("path");
4898
5039
  init_worktree();
4899
5040
  init_app_settings();
4900
5041
  init_paths();
@@ -4915,7 +5056,7 @@ var init_coordinator_prompt = __esm({
4915
5056
  "Workspaces:",
4916
5057
  "- add_workspace / remove_workspace \u2014 register or unregister a git repo",
4917
5058
  "Worktree threads (chats):",
4918
- "- 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)",
5059
+ "- 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)",
4919
5060
  "- 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.",
4920
5061
  "- 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.",
4921
5062
  "- 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",
@@ -4923,7 +5064,7 @@ var init_coordinator_prompt = __esm({
4923
5064
  "- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
4924
5065
  "- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
4925
5066
  "Setup / run:",
4926
- "- run_setup \u2014 re-run worktree setup",
5067
+ "- run_setup \u2014 re-run worktree setup (already runs automatically on create when a script exists)",
4927
5068
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
4928
5069
  "Inspect / review / PRs:",
4929
5070
  "- get_diff \u2014 compact diff summary",
@@ -5200,38 +5341,38 @@ __export(workspaces_exports, {
5200
5341
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
5201
5342
  });
5202
5343
  function workspacesFile() {
5203
- return (0, import_node_path11.join)(appDataDir(), "workspaces.json");
5344
+ return (0, import_node_path13.join)(appDataDir(), "workspaces.json");
5204
5345
  }
5205
5346
  function removedWorkspacesFile() {
5206
- return (0, import_node_path11.join)(appDataDir(), "removed-workspaces.json");
5347
+ return (0, import_node_path13.join)(appDataDir(), "removed-workspaces.json");
5207
5348
  }
5208
5349
  function readAll() {
5209
5350
  const path2 = workspacesFile();
5210
- if (!(0, import_node_fs11.existsSync)(path2)) return [];
5351
+ if (!(0, import_node_fs13.existsSync)(path2)) return [];
5211
5352
  try {
5212
- const raw = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
5353
+ const raw = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
5213
5354
  return Array.isArray(raw) ? raw : [];
5214
5355
  } catch {
5215
5356
  return [];
5216
5357
  }
5217
5358
  }
5218
5359
  function writeAll(list) {
5219
- (0, import_node_fs11.mkdirSync)(appDataDir(), { recursive: true });
5220
- (0, import_node_fs11.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
5360
+ (0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
5361
+ (0, import_node_fs13.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
5221
5362
  }
5222
5363
  function readRemoved() {
5223
5364
  const path2 = removedWorkspacesFile();
5224
- if (!(0, import_node_fs11.existsSync)(path2)) return /* @__PURE__ */ new Set();
5365
+ if (!(0, import_node_fs13.existsSync)(path2)) return /* @__PURE__ */ new Set();
5225
5366
  try {
5226
- const raw = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
5367
+ const raw = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
5227
5368
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
5228
5369
  } catch {
5229
5370
  return /* @__PURE__ */ new Set();
5230
5371
  }
5231
5372
  }
5232
5373
  function writeRemoved(paths) {
5233
- (0, import_node_fs11.mkdirSync)(appDataDir(), { recursive: true });
5234
- (0, import_node_fs11.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
5374
+ (0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
5375
+ (0, import_node_fs13.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
5235
5376
  }
5236
5377
  function rememberRemoved(repoPath) {
5237
5378
  const next = readRemoved();
@@ -5254,7 +5395,7 @@ function listWorkspaces() {
5254
5395
  async function addWorkspace(repoPath) {
5255
5396
  const root = await resolveRepoRoot(repoPath);
5256
5397
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
5257
- if (!(0, import_node_fs11.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
5398
+ if (!(0, import_node_fs13.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
5258
5399
  forgetRemoved(root);
5259
5400
  await ensureGhPreferOrigin(root);
5260
5401
  const current = readAll();
@@ -5262,7 +5403,7 @@ async function addWorkspace(repoPath) {
5262
5403
  if (existing) return existing;
5263
5404
  const next = {
5264
5405
  path: root,
5265
- name: (0, import_node_path11.basename)(root),
5406
+ name: (0, import_node_path13.basename)(root),
5266
5407
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
5267
5408
  };
5268
5409
  writeAll([...current, next]);
@@ -5284,10 +5425,10 @@ function syncWorkspacesFromThreads(repoPaths) {
5284
5425
  if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
5285
5426
  continue;
5286
5427
  }
5287
- if (!(0, import_node_fs11.existsSync)(path2)) continue;
5428
+ if (!(0, import_node_fs13.existsSync)(path2)) continue;
5288
5429
  const ws = {
5289
5430
  path: path2,
5290
- name: (0, import_node_path11.basename)(path2),
5431
+ name: (0, import_node_path13.basename)(path2),
5291
5432
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
5292
5433
  };
5293
5434
  byPath.set(path2, ws);
@@ -5297,12 +5438,12 @@ function syncWorkspacesFromThreads(repoPaths) {
5297
5438
  if (dirty) writeAll(next);
5298
5439
  return next.sort((a, b) => a.name.localeCompare(b.name));
5299
5440
  }
5300
- var import_node_fs11, import_node_path11;
5441
+ var import_node_fs13, import_node_path13;
5301
5442
  var init_workspaces = __esm({
5302
5443
  "src/store/workspaces.ts"() {
5303
5444
  "use strict";
5304
- import_node_fs11 = require("fs");
5305
- import_node_path11 = require("path");
5445
+ import_node_fs13 = require("fs");
5446
+ import_node_path13 = require("path");
5306
5447
  init_paths();
5307
5448
  init_global_workspace();
5308
5449
  init_worktree();
@@ -5311,32 +5452,32 @@ var init_workspaces = __esm({
5311
5452
 
5312
5453
  // src/brightsy/config.ts
5313
5454
  function brightsyConfigPath() {
5314
- return (0, import_node_path12.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
5455
+ return (0, import_node_path14.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
5315
5456
  }
5316
5457
  function loadBrightsyConfig() {
5317
5458
  const path2 = brightsyConfigPath();
5318
- if (!(0, import_node_fs12.existsSync)(path2)) {
5459
+ if (!(0, import_node_fs14.existsSync)(path2)) {
5319
5460
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
5320
5461
  }
5321
- const raw = JSON.parse((0, import_node_fs12.readFileSync)(path2, "utf8"));
5462
+ const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
5322
5463
  if (!raw.access_token || !raw.account_id) {
5323
5464
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
5324
5465
  }
5325
5466
  return raw;
5326
5467
  }
5327
5468
  function saveBrightsyConfig(cfg) {
5328
- (0, import_node_fs12.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5469
+ (0, import_node_fs14.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5329
5470
  `, {
5330
5471
  mode: 384
5331
5472
  });
5332
5473
  }
5333
- var import_node_fs12, import_node_os5, import_node_path12;
5474
+ var import_node_fs14, import_node_os5, import_node_path14;
5334
5475
  var init_config = __esm({
5335
5476
  "src/brightsy/config.ts"() {
5336
5477
  "use strict";
5337
- import_node_fs12 = require("fs");
5478
+ import_node_fs14 = require("fs");
5338
5479
  import_node_os5 = require("os");
5339
- import_node_path12 = require("path");
5480
+ import_node_path14 = require("path");
5340
5481
  }
5341
5482
  });
5342
5483
 
@@ -5439,22 +5580,22 @@ __export(connected_teams_exports, {
5439
5580
  listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
5440
5581
  });
5441
5582
  function storePath() {
5442
- return (0, import_node_path13.join)(appDataDir(), "brightsy-teams.json");
5583
+ return (0, import_node_path15.join)(appDataDir(), "brightsy-teams.json");
5443
5584
  }
5444
5585
  function readStore() {
5445
5586
  const path2 = storePath();
5446
- if (!(0, import_node_fs13.existsSync)(path2)) return [];
5587
+ if (!(0, import_node_fs15.existsSync)(path2)) return [];
5447
5588
  try {
5448
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
5589
+ const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
5449
5590
  return Array.isArray(parsed.teams) ? parsed.teams : [];
5450
5591
  } catch {
5451
5592
  return [];
5452
5593
  }
5453
5594
  }
5454
5595
  function writeStore(teams) {
5455
- (0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
5596
+ (0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
5456
5597
  const path2 = storePath();
5457
- (0, import_node_fs13.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
5598
+ (0, import_node_fs15.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
5458
5599
  `, {
5459
5600
  mode: 384
5460
5601
  });
@@ -5616,12 +5757,12 @@ function brightsyMcpServerName(slug) {
5616
5757
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
5617
5758
  return `brightsy_${cleaned || "team"}`;
5618
5759
  }
5619
- var import_node_fs13, import_node_path13;
5760
+ var import_node_fs15, import_node_path15;
5620
5761
  var init_connected_teams = __esm({
5621
5762
  "src/brightsy/connected-teams.ts"() {
5622
5763
  "use strict";
5623
- import_node_fs13 = require("fs");
5624
- import_node_path13 = require("path");
5764
+ import_node_fs15 = require("fs");
5765
+ import_node_path15 = require("path");
5625
5766
  init_paths();
5626
5767
  init_accounts();
5627
5768
  init_config();
@@ -6150,11 +6291,11 @@ async function syncCliForTarget(accountId) {
6150
6291
  }
6151
6292
  applyConnectedTeamToCli(team);
6152
6293
  }
6153
- var import_node_fs14, brightsyAdapter;
6294
+ var import_node_fs16, brightsyAdapter;
6154
6295
  var init_brightsy = __esm({
6155
6296
  "src/agents/brightsy.ts"() {
6156
6297
  "use strict";
6157
- import_node_fs14 = require("fs");
6298
+ import_node_fs16 = require("fs");
6158
6299
  init_run();
6159
6300
  init_connected_teams();
6160
6301
  init_config();
@@ -6169,7 +6310,7 @@ var init_brightsy = __esm({
6169
6310
  async detect() {
6170
6311
  const brightsy = resolveAgentExecutable("brightsy");
6171
6312
  if (brightsy !== "brightsy") {
6172
- if (!(0, import_node_fs14.existsSync)(brightsy)) {
6313
+ if (!(0, import_node_fs16.existsSync)(brightsy)) {
6173
6314
  return {
6174
6315
  agent: "brightsy",
6175
6316
  installed: false,
@@ -6426,35 +6567,35 @@ function corePackageDir() {
6426
6567
  try {
6427
6568
  const url = import_meta.url;
6428
6569
  if (typeof url === "string" && url.length > 0) {
6429
- return (0, import_node_path14.dirname)((0, import_node_url.fileURLToPath)(url));
6570
+ return (0, import_node_path16.dirname)((0, import_node_url.fileURLToPath)(url));
6430
6571
  }
6431
6572
  } catch {
6432
6573
  }
6433
6574
  try {
6434
- const req = (0, import_node_module.createRequire)((0, import_node_path14.join)(process.cwd(), "package.json"));
6435
- return (0, import_node_path14.dirname)(req.resolve("@sideboard-ai/core"));
6575
+ const req = (0, import_node_module.createRequire)((0, import_node_path16.join)(process.cwd(), "package.json"));
6576
+ return (0, import_node_path16.dirname)(req.resolve("@sideboard-ai/core"));
6436
6577
  } catch {
6437
6578
  return process.cwd();
6438
6579
  }
6439
6580
  }
6440
6581
  function findSideboardMcpJsEntry() {
6441
6582
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
6442
- if (override && (0, import_node_fs15.existsSync)(override)) return override;
6583
+ if (override && (0, import_node_fs17.existsSync)(override)) return override;
6443
6584
  let dir = corePackageDir();
6444
6585
  for (let i = 0; i < 10; i++) {
6445
6586
  const candidates = [
6446
- (0, import_node_path14.join)(dir, "mcp/run-stdio.js"),
6447
- (0, import_node_path14.join)(dir, "mcp/run-stdio.cjs"),
6448
- (0, import_node_path14.join)(dir, "dist/mcp/run-stdio.js"),
6449
- (0, import_node_path14.join)(dir, "dist/mcp/run-stdio.cjs"),
6450
- (0, import_node_path14.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
6451
- (0, import_node_path14.join)(dir, "packages/cli/dist/index.js"),
6452
- (0, import_node_path14.join)(dir, "cli/dist/index.js")
6587
+ (0, import_node_path16.join)(dir, "mcp/run-stdio.js"),
6588
+ (0, import_node_path16.join)(dir, "mcp/run-stdio.cjs"),
6589
+ (0, import_node_path16.join)(dir, "dist/mcp/run-stdio.js"),
6590
+ (0, import_node_path16.join)(dir, "dist/mcp/run-stdio.cjs"),
6591
+ (0, import_node_path16.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
6592
+ (0, import_node_path16.join)(dir, "packages/cli/dist/index.js"),
6593
+ (0, import_node_path16.join)(dir, "cli/dist/index.js")
6453
6594
  ];
6454
6595
  for (const p of candidates) {
6455
- if ((0, import_node_fs15.existsSync)(p)) return p;
6596
+ if ((0, import_node_fs17.existsSync)(p)) return p;
6456
6597
  }
6457
- const parent = (0, import_node_path14.dirname)(dir);
6598
+ const parent = (0, import_node_path16.dirname)(dir);
6458
6599
  if (parent === dir) break;
6459
6600
  dir = parent;
6460
6601
  }
@@ -6577,22 +6718,22 @@ function writeMcpServersConfig(servers) {
6577
6718
  ...s.env ? { env: s.env } : {}
6578
6719
  };
6579
6720
  }
6580
- const dir = (0, import_node_fs15.mkdtempSync)((0, import_node_path14.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
6581
- const cfgPath = (0, import_node_path14.join)(dir, "mcp.json");
6582
- (0, import_node_fs15.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
6721
+ const dir = (0, import_node_fs17.mkdtempSync)((0, import_node_path16.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
6722
+ const cfgPath = (0, import_node_path16.join)(dir, "mcp.json");
6723
+ (0, import_node_fs17.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
6583
6724
  return cfgPath;
6584
6725
  }
6585
6726
  async function writeInjectedMcpConfig(opts) {
6586
6727
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
6587
6728
  }
6588
- var import_node_fs15, import_node_module, import_node_os6, import_node_path14, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
6729
+ var import_node_fs17, import_node_module, import_node_os6, import_node_path16, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
6589
6730
  var init_injected_mcp = __esm({
6590
6731
  "src/agents/injected-mcp.ts"() {
6591
6732
  "use strict";
6592
- import_node_fs15 = require("fs");
6733
+ import_node_fs17 = require("fs");
6593
6734
  import_node_module = require("module");
6594
6735
  import_node_os6 = require("os");
6595
- import_node_path14 = require("path");
6736
+ import_node_path16 = require("path");
6596
6737
  import_node_url = require("url");
6597
6738
  init_run();
6598
6739
  init_config();
@@ -6784,11 +6925,11 @@ function parseIssuesJson(raw) {
6784
6925
  }
6785
6926
  return [];
6786
6927
  }
6787
- var import_node_fs16, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
6928
+ var import_node_fs18, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
6788
6929
  var init_claude = __esm({
6789
6930
  "src/agents/claude.ts"() {
6790
6931
  "use strict";
6791
- import_node_fs16 = require("fs");
6932
+ import_node_fs18 = require("fs");
6792
6933
  init_run();
6793
6934
  init_app_settings();
6794
6935
  init_claude_mcp();
@@ -6817,7 +6958,7 @@ var init_claude = __esm({
6817
6958
  async detect() {
6818
6959
  const claude = resolveClaudeExecutable();
6819
6960
  if (claude !== "claude") {
6820
- if (!(0, import_node_fs16.existsSync)(claude)) {
6961
+ if (!(0, import_node_fs18.existsSync)(claude)) {
6821
6962
  return {
6822
6963
  agent: "claude",
6823
6964
  installed: false,
@@ -7054,7 +7195,7 @@ async function listCodexModels() {
7054
7195
  if (codex === "codex") {
7055
7196
  const which = await run("which", ["codex"], { reject: false });
7056
7197
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
7057
- } else if (!(0, import_node_fs17.existsSync)(codex)) {
7198
+ } else if (!(0, import_node_fs19.existsSync)(codex)) {
7058
7199
  return FALLBACK_CODEX_MODELS;
7059
7200
  }
7060
7201
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -7089,12 +7230,12 @@ function usageFromCodex(usage) {
7089
7230
  }
7090
7231
  function codexConfigHasNetworkAccess() {
7091
7232
  const candidates = [
7092
- (0, import_node_path15.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
7093
- (0, import_node_path15.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
7233
+ (0, import_node_path17.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
7234
+ (0, import_node_path17.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
7094
7235
  ];
7095
7236
  for (const path2 of candidates) {
7096
- if (!(0, import_node_fs17.existsSync)(path2)) continue;
7097
- const text3 = (0, import_node_fs17.readFileSync)(path2, "utf8");
7237
+ if (!(0, import_node_fs19.existsSync)(path2)) continue;
7238
+ const text3 = (0, import_node_fs19.readFileSync)(path2, "utf8");
7098
7239
  if (/network_access\s*=\s*true/.test(text3)) return true;
7099
7240
  }
7100
7241
  return false;
@@ -7126,21 +7267,21 @@ function asRecord(value) {
7126
7267
  return void 0;
7127
7268
  }
7128
7269
  function codexLooksAuthenticated() {
7129
- const authPath = (0, import_node_path15.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
7130
- if (!(0, import_node_fs17.existsSync)(authPath)) return false;
7270
+ const authPath = (0, import_node_path17.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
7271
+ if (!(0, import_node_fs19.existsSync)(authPath)) return false;
7131
7272
  try {
7132
- return (0, import_node_fs17.statSync)(authPath).size > 2;
7273
+ return (0, import_node_fs19.statSync)(authPath).size > 2;
7133
7274
  } catch {
7134
7275
  return false;
7135
7276
  }
7136
7277
  }
7137
- var import_node_fs17, import_node_os7, import_node_path15, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
7278
+ var import_node_fs19, import_node_os7, import_node_path17, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
7138
7279
  var init_codex = __esm({
7139
7280
  "src/agents/codex.ts"() {
7140
7281
  "use strict";
7141
- import_node_fs17 = require("fs");
7282
+ import_node_fs19 = require("fs");
7142
7283
  import_node_os7 = require("os");
7143
- import_node_path15 = require("path");
7284
+ import_node_path17 = require("path");
7144
7285
  init_run();
7145
7286
  init_app_settings();
7146
7287
  init_global_workspace();
@@ -7165,7 +7306,7 @@ var init_codex = __esm({
7165
7306
  async detect() {
7166
7307
  const codex = resolveAgentExecutable("codex");
7167
7308
  if (codex !== "codex") {
7168
- if (!(0, import_node_fs17.existsSync)(codex)) {
7309
+ if (!(0, import_node_fs19.existsSync)(codex)) {
7169
7310
  return {
7170
7311
  agent: "codex",
7171
7312
  installed: false,
@@ -7599,11 +7740,11 @@ function entryDir() {
7599
7740
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
7600
7741
  if (cjsDir) return cjsDir;
7601
7742
  try {
7602
- return (0, import_node_path16.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
7743
+ return (0, import_node_path18.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
7603
7744
  } catch {
7604
7745
  try {
7605
7746
  const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
7606
- return (0, import_node_path16.dirname)(req.resolve("@sideboard-ai/core"));
7747
+ return (0, import_node_path18.dirname)(req.resolve("@sideboard-ai/core"));
7607
7748
  } catch {
7608
7749
  return process.cwd();
7609
7750
  }
@@ -7612,27 +7753,27 @@ function entryDir() {
7612
7753
  function cursorRunnerPath() {
7613
7754
  const root = entryDir();
7614
7755
  const candidates = [
7615
- (0, import_node_path16.join)(root, "agents", "cursor-runner.js"),
7616
- (0, import_node_path16.join)(root, "agents", "cursor-runner.cjs"),
7756
+ (0, import_node_path18.join)(root, "agents", "cursor-runner.js"),
7757
+ (0, import_node_path18.join)(root, "agents", "cursor-runner.cjs"),
7617
7758
  // If somehow resolved from package root instead of dist/
7618
- (0, import_node_path16.join)(root, "dist", "agents", "cursor-runner.js"),
7619
- (0, import_node_path16.join)(root, "dist", "agents", "cursor-runner.cjs"),
7759
+ (0, import_node_path18.join)(root, "dist", "agents", "cursor-runner.js"),
7760
+ (0, import_node_path18.join)(root, "dist", "agents", "cursor-runner.cjs"),
7620
7761
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
7621
- (0, import_node_path16.join)(root, "cursor-runner.ts"),
7622
- (0, import_node_path16.join)(root, "src", "agents", "cursor-runner.ts")
7762
+ (0, import_node_path18.join)(root, "cursor-runner.ts"),
7763
+ (0, import_node_path18.join)(root, "src", "agents", "cursor-runner.ts")
7623
7764
  ];
7624
7765
  for (const candidate of candidates) {
7625
- if ((0, import_node_fs18.existsSync)(candidate)) return candidate;
7766
+ if ((0, import_node_fs20.existsSync)(candidate)) return candidate;
7626
7767
  }
7627
7768
  return candidates[0];
7628
7769
  }
7629
- var import_node_fs18, import_node_module2, import_node_path16, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
7770
+ var import_node_fs20, import_node_module2, import_node_path18, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
7630
7771
  var init_cursor = __esm({
7631
7772
  "src/agents/cursor.ts"() {
7632
7773
  "use strict";
7633
- import_node_fs18 = require("fs");
7774
+ import_node_fs20 = require("fs");
7634
7775
  import_node_module2 = require("module");
7635
- import_node_path16 = require("path");
7776
+ import_node_path18 = require("path");
7636
7777
  import_node_url2 = require("url");
7637
7778
  import_sdk = require("@cursor/sdk");
7638
7779
  init_run();
@@ -7761,7 +7902,7 @@ async function listOpencodeModels() {
7761
7902
  if (opencode === "opencode") {
7762
7903
  const which = await run("which", ["opencode"], { reject: false });
7763
7904
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
7764
- } else if (!(0, import_node_fs19.existsSync)(opencode)) {
7905
+ } else if (!(0, import_node_fs21.existsSync)(opencode)) {
7765
7906
  return FALLBACK_OPENCODE_MODELS;
7766
7907
  }
7767
7908
  const listed = await run(opencode, ["models"], { reject: false });
@@ -7791,11 +7932,11 @@ function usageFromOpencode(tokens) {
7791
7932
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
7792
7933
  };
7793
7934
  }
7794
- var import_node_fs19, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
7935
+ var import_node_fs21, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
7795
7936
  var init_opencode = __esm({
7796
7937
  "src/agents/opencode.ts"() {
7797
7938
  "use strict";
7798
- import_node_fs19 = require("fs");
7939
+ import_node_fs21 = require("fs");
7799
7940
  init_run();
7800
7941
  init_app_settings();
7801
7942
  init_global_workspace();
@@ -7821,7 +7962,7 @@ var init_opencode = __esm({
7821
7962
  async detect() {
7822
7963
  const opencode = resolveAgentExecutable("opencode");
7823
7964
  if (opencode !== "opencode") {
7824
- if (!(0, import_node_fs19.existsSync)(opencode)) {
7965
+ if (!(0, import_node_fs21.existsSync)(opencode)) {
7825
7966
  return {
7826
7967
  agent: "opencode",
7827
7968
  installed: false,
@@ -8618,40 +8759,40 @@ __export(plan_file_exports, {
8618
8759
  writePlanFile: () => writePlanFile
8619
8760
  });
8620
8761
  function ensureAttachmentsGitignore2(worktreePath) {
8621
- const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
8622
- if ((0, import_node_fs34.existsSync)(gitignoreAbs)) return;
8623
- (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
8624
- (0, import_node_fs34.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
8762
+ const gitignoreAbs = (0, import_node_path31.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
8763
+ if ((0, import_node_fs35.existsSync)(gitignoreAbs)) return;
8764
+ (0, import_node_fs35.mkdirSync)((0, import_node_path31.dirname)(gitignoreAbs), { recursive: true });
8765
+ (0, import_node_fs35.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
8625
8766
  }
8626
8767
  function planFileAbs(worktreePath) {
8627
- return (0, import_node_path30.join)(worktreePath, PLAN_FILE_REL);
8768
+ return (0, import_node_path31.join)(worktreePath, PLAN_FILE_REL);
8628
8769
  }
8629
8770
  function readTextIfPresent2(abs) {
8630
- if (!(0, import_node_fs34.existsSync)(abs)) return null;
8771
+ if (!(0, import_node_fs35.existsSync)(abs)) return null;
8631
8772
  try {
8632
- const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
8773
+ const content = (0, import_node_fs35.readFileSync)(abs, "utf8");
8633
8774
  return content.trim() ? content : null;
8634
8775
  } catch {
8635
8776
  return null;
8636
8777
  }
8637
8778
  }
8638
8779
  function readPlanFile(worktreePath) {
8639
- 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));
8780
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path31.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path31.join)(worktreePath, LEGACY_PLAN_FILE_REL));
8640
8781
  }
8641
8782
  function writePlanFile(worktreePath, content) {
8642
8783
  ensureAttachmentsGitignore2(worktreePath);
8643
8784
  const abs = planFileAbs(worktreePath);
8644
- (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(abs), { recursive: true });
8785
+ (0, import_node_fs35.mkdirSync)((0, import_node_path31.dirname)(abs), { recursive: true });
8645
8786
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
8646
- (0, import_node_fs34.writeFileSync)(abs, body, "utf8");
8787
+ (0, import_node_fs35.writeFileSync)(abs, body, "utf8");
8647
8788
  return PLAN_FILE_REL;
8648
8789
  }
8649
- var import_node_fs34, import_node_path30;
8790
+ var import_node_fs35, import_node_path31;
8650
8791
  var init_plan_file = __esm({
8651
8792
  "src/plan/plan-file.ts"() {
8652
8793
  "use strict";
8653
- import_node_fs34 = require("fs");
8654
- import_node_path30 = require("path");
8794
+ import_node_fs35 = require("fs");
8795
+ import_node_path31 = require("path");
8655
8796
  init_workspace_scratch();
8656
8797
  init_plan_present();
8657
8798
  init_plan_present();
@@ -8666,10 +8807,10 @@ __export(cursor_recover_exports, {
8666
8807
  function recoverFinishedCursorRun(opts) {
8667
8808
  const agentId = opts.agentId.trim();
8668
8809
  if (!agentId) return null;
8669
- const runsPath = (0, import_node_path31.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
8670
- if (!(0, import_node_fs35.existsSync)(runsPath)) return null;
8810
+ const runsPath = (0, import_node_path32.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
8811
+ if (!(0, import_node_fs36.existsSync)(runsPath)) return null;
8671
8812
  try {
8672
- const lines = (0, import_node_fs35.readFileSync)(runsPath, "utf8").split("\n");
8813
+ const lines = (0, import_node_fs36.readFileSync)(runsPath, "utf8").split("\n");
8673
8814
  let best = null;
8674
8815
  for (const line of lines) {
8675
8816
  const trimmed = line.trim();
@@ -8695,12 +8836,12 @@ function recoverFinishedCursorRun(opts) {
8695
8836
  return null;
8696
8837
  }
8697
8838
  }
8698
- var import_node_fs35, import_node_path31;
8839
+ var import_node_fs36, import_node_path32;
8699
8840
  var init_cursor_recover = __esm({
8700
8841
  "src/agents/cursor-recover.ts"() {
8701
8842
  "use strict";
8702
- import_node_fs35 = require("fs");
8703
- import_node_path31 = require("path");
8843
+ import_node_fs36 = require("fs");
8844
+ import_node_path32 = require("path");
8704
8845
  init_paths();
8705
8846
  }
8706
8847
  });
@@ -8753,6 +8894,7 @@ __export(index_exports, {
8753
8894
  CONTEXT_KEEP_RECENT_CHARS: () => CONTEXT_KEEP_RECENT_CHARS,
8754
8895
  CONTEXT_KEEP_RECENT_MESSAGES: () => CONTEXT_KEEP_RECENT_MESSAGES,
8755
8896
  CONTEXT_MIN_MESSAGES: () => CONTEXT_MIN_MESSAGES,
8897
+ CONVENTION_SETUP_RELPATHS: () => CONVENTION_SETUP_RELPATHS,
8756
8898
  COORDINATOR_TOOL_PLAYBOOK: () => COORDINATOR_TOOL_PLAYBOOK,
8757
8899
  FAMOUS_SOCCER_TEAMS: () => FAMOUS_SOCCER_TEAMS,
8758
8900
  GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
@@ -8914,6 +9056,7 @@ __export(index_exports, {
8914
9056
  extractiveSummary: () => extractiveSummary,
8915
9057
  fetchPrHead: () => fetchPrHead,
8916
9058
  finalizeParts: () => finalizeParts,
9059
+ findConventionSetup: () => findConventionSetup,
8917
9060
  findInvalidCacheControlTtlOrder: () => findInvalidCacheControlTtlOrder,
8918
9061
  findOrphanWorktrees: () => findOrphanWorktrees,
8919
9062
  findThreadByRef: () => findThreadByRef,
@@ -8985,6 +9128,7 @@ __export(index_exports, {
8985
9128
  hasBakedLinearOAuth: () => hasBakedLinearOAuth,
8986
9129
  hasBakedSlackOAuth: () => hasBakedSlackOAuth,
8987
9130
  hasConductorHook: () => hasConductorHook,
9131
+ hasConventionSetup: () => hasConventionSetup,
8988
9132
  hasCursorWorktreeSetup: () => hasCursorWorktreeSetup,
8989
9133
  hasRepoHook: () => hasRepoHook,
8990
9134
  hasWorkspaceHook: () => hasWorkspaceHook,
@@ -9160,10 +9304,12 @@ __export(index_exports, {
9160
9304
  run: () => run,
9161
9305
  runArchiveScript: () => runArchiveScript,
9162
9306
  runCloudConnect: () => runCloudConnect,
9307
+ runConventionSetup: () => runConventionSetup,
9163
9308
  runCursorWorktreeSetup: () => runCursorWorktreeSetup,
9164
9309
  runSetupScript: () => runSetupScript,
9165
9310
  runSlackListen: () => runSlackListen,
9166
9311
  runSlackRelayClient: () => runSlackRelayClient,
9312
+ runWorkspaceSetup: () => runWorkspaceSetup,
9167
9313
  sameWorktreePath: () => sameWorktreePath,
9168
9314
  sanitizeMcpServerName: () => sanitizeMcpServerName,
9169
9315
  saveAppSettings: () => saveAppSettings,
@@ -10009,8 +10155,8 @@ async function listIssues(repoPath) {
10009
10155
  init_agents();
10010
10156
 
10011
10157
  // src/agents/spawn.ts
10012
- var import_node_readline = require("readline");
10013
- var import_execa2 = require("execa");
10158
+ var import_node_readline2 = require("readline");
10159
+ var import_execa3 = require("execa");
10014
10160
  init_worktree();
10015
10161
  init_git_auth_mode();
10016
10162
  init_app_settings();
@@ -10286,7 +10432,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
10286
10432
  const detail = err instanceof Error ? err.message : String(err);
10287
10433
  console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
10288
10434
  }
10289
- const child = (0, import_execa2.execa)(cmd.file, cmd.args, {
10435
+ const child = (0, import_execa3.execa)(cmd.file, cmd.args, {
10290
10436
  cwd: cmd.cwd,
10291
10437
  env,
10292
10438
  reject: false,
@@ -10306,7 +10452,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
10306
10452
  let usage = null;
10307
10453
  const consume = (stream, kind) => {
10308
10454
  if (!stream) return;
10309
- const rl = (0, import_node_readline.createInterface)({ input: stream, crlfDelay: Infinity });
10455
+ const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
10310
10456
  rl.on("line", (line) => {
10311
10457
  if (kind === "stderr") {
10312
10458
  onEvent({ type: "stderr", data: line });
@@ -10373,11 +10519,11 @@ init_usage();
10373
10519
  init_claude_mcp();
10374
10520
 
10375
10521
  // src/agents/instructions.ts
10376
- var import_node_fs20 = require("fs");
10377
- var import_node_path17 = require("path");
10522
+ var import_node_fs22 = require("fs");
10523
+ var import_node_path19 = require("path");
10378
10524
  init_git_auth_mode();
10379
10525
  init_worktree_labels();
10380
- function normPath2(p) {
10526
+ function normPath3(p) {
10381
10527
  return p.replace(/\/+$/, "");
10382
10528
  }
10383
10529
  function formatRenameBranchDirective(thread, opts) {
@@ -10398,8 +10544,8 @@ function formatRenameBranchDirective(thread, opts) {
10398
10544
  return lines.join("\n");
10399
10545
  }
10400
10546
  function formatWorktreeDirective(thread, opts) {
10401
- const worktree = normPath2(thread.worktreePath);
10402
- const repo = normPath2(thread.repoPath);
10547
+ const worktree = normPath3(thread.worktreePath);
10548
+ const repo = normPath3(thread.repoPath);
10403
10549
  const dir = worktreeNameFromPath(thread.worktreePath);
10404
10550
  const lines = [
10405
10551
  "Sideboard workspace (mandatory):",
@@ -10544,11 +10690,11 @@ function loadAgentInstructions(worktreePath, agent) {
10544
10690
  const out = [];
10545
10691
  for (const rel of candidates) {
10546
10692
  if (seenPaths.has(rel)) continue;
10547
- const abs = (0, import_node_path17.join)(worktreePath, rel);
10548
- if (!(0, import_node_fs20.existsSync)(abs)) continue;
10693
+ const abs = (0, import_node_path19.join)(worktreePath, rel);
10694
+ if (!(0, import_node_fs22.existsSync)(abs)) continue;
10549
10695
  try {
10550
- if (!(0, import_node_fs20.statSync)(abs).isFile()) continue;
10551
- let content = (0, import_node_fs20.readFileSync)(abs, "utf8");
10696
+ if (!(0, import_node_fs22.statSync)(abs).isFile()) continue;
10697
+ let content = (0, import_node_fs22.readFileSync)(abs, "utf8");
10552
10698
  if (!content.trim()) continue;
10553
10699
  if (content.length > MAX_CHARS_PER_FILE) {
10554
10700
  content = `${content.slice(0, MAX_CHARS_PER_FILE)}
@@ -10630,13 +10776,15 @@ async function requireAgent(agent, opts) {
10630
10776
  init_settings();
10631
10777
 
10632
10778
  // src/hook/conductor.ts
10633
- var import_node_fs21 = require("fs");
10779
+ var import_node_fs23 = require("fs");
10634
10780
  var import_node_net = require("net");
10635
- var import_node_path18 = require("path");
10636
- var import_execa3 = require("execa");
10637
- var import_node_readline2 = require("readline");
10781
+ var import_node_path20 = require("path");
10782
+ var import_execa4 = require("execa");
10783
+ var import_node_readline3 = require("readline");
10638
10784
  init_settings();
10639
10785
  init_nested_electron_env();
10786
+ init_convention_setup();
10787
+ init_cursor_worktrees();
10640
10788
  init_git_auth_mode();
10641
10789
  init_nested_electron_env();
10642
10790
  var PORT_RANGE_SIZE = 10;
@@ -10645,9 +10793,9 @@ function matchSimpleGlob(pattern, name) {
10645
10793
  return new RegExp(`^${escaped}$`).test(name);
10646
10794
  }
10647
10795
  function readWorktreeInclude(repoPath) {
10648
- const path2 = (0, import_node_path18.join)(repoPath, ".worktreeinclude");
10649
- if (!(0, import_node_fs21.existsSync)(path2)) return [];
10650
- return (0, import_node_fs21.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
10796
+ const path2 = (0, import_node_path20.join)(repoPath, ".worktreeinclude");
10797
+ if (!(0, import_node_fs23.existsSync)(path2)) return [];
10798
+ return (0, import_node_fs23.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
10651
10799
  }
10652
10800
  function resolveFilesToCopy(repoPath) {
10653
10801
  const fromInclude = readWorktreeInclude(repoPath);
@@ -10657,10 +10805,10 @@ function resolveFilesToCopy(repoPath) {
10657
10805
  if (settings?.fileIncludeGlobs?.length) {
10658
10806
  const matched = [];
10659
10807
  try {
10660
- for (const entry of (0, import_node_fs21.readdirSync)(repoPath, { withFileTypes: true })) {
10808
+ for (const entry of (0, import_node_fs23.readdirSync)(repoPath, { withFileTypes: true })) {
10661
10809
  if (!entry.isFile()) continue;
10662
10810
  for (const glob of settings.fileIncludeGlobs) {
10663
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path18.basename)(glob), entry.name)) {
10811
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path20.basename)(glob), entry.name)) {
10664
10812
  matched.push(entry.name);
10665
10813
  break;
10666
10814
  }
@@ -10672,7 +10820,7 @@ function resolveFilesToCopy(repoPath) {
10672
10820
  }
10673
10821
  const defaults = [];
10674
10822
  try {
10675
- for (const entry of (0, import_node_fs21.readdirSync)(repoPath, { withFileTypes: true })) {
10823
+ for (const entry of (0, import_node_fs23.readdirSync)(repoPath, { withFileTypes: true })) {
10676
10824
  if (entry.isFile() && entry.name.startsWith(".env")) {
10677
10825
  defaults.push(entry.name);
10678
10826
  }
@@ -10686,11 +10834,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
10686
10834
  const patterns = resolveFilesToCopy(repoPath);
10687
10835
  const copied = [];
10688
10836
  for (const rel of patterns) {
10689
- const src = (0, import_node_path18.join)(repoPath, rel);
10690
- if (!(0, import_node_fs21.existsSync)(src)) continue;
10691
- const dest = (0, import_node_path18.join)(worktreePath, rel);
10692
- (0, import_node_fs21.mkdirSync)((0, import_node_path18.dirname)(dest), { recursive: true });
10693
- (0, import_node_fs21.copyFileSync)(src, dest);
10837
+ const src = (0, import_node_path20.join)(repoPath, rel);
10838
+ if (!(0, import_node_fs23.existsSync)(src)) continue;
10839
+ const dest = (0, import_node_path20.join)(worktreePath, rel);
10840
+ (0, import_node_fs23.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
10841
+ (0, import_node_fs23.copyFileSync)(src, dest);
10694
10842
  copied.push(rel);
10695
10843
  }
10696
10844
  return copied;
@@ -10700,7 +10848,7 @@ async function captureLoginEnv() {
10700
10848
  if (cachedLoginEnv) return { ...cachedLoginEnv };
10701
10849
  const shell = process.env.SHELL?.trim() || (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
10702
10850
  try {
10703
- const result = await (0, import_execa3.execa)(shell, ["-l", "-c", "env -0"], {
10851
+ const result = await (0, import_execa4.execa)(shell, ["-l", "-c", "env -0"], {
10704
10852
  reject: false,
10705
10853
  timeout: 5e3
10706
10854
  });
@@ -10726,7 +10874,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
10726
10874
  const env = stripNestedElectronEnv({
10727
10875
  ...baseEnv ?? process.env
10728
10876
  });
10729
- const name = opts.workspaceName ?? (0, import_node_path18.basename)(opts.worktreePath);
10877
+ const name = opts.workspaceName ?? (0, import_node_path20.basename)(opts.worktreePath);
10730
10878
  const ports = opts.ports ?? [];
10731
10879
  const primary = ports[0];
10732
10880
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -10753,7 +10901,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
10753
10901
  }
10754
10902
  function pipeLines(stream, onLine) {
10755
10903
  if (!stream || !onLine) return;
10756
- const rl = (0, import_node_readline2.createInterface)({ input: stream });
10904
+ const rl = (0, import_node_readline3.createInterface)({ input: stream });
10757
10905
  rl.on("line", onLine);
10758
10906
  }
10759
10907
  function killScriptTree(child, ports = []) {
@@ -10761,7 +10909,7 @@ function killScriptTree(child, ports = []) {
10761
10909
  if (pid) {
10762
10910
  try {
10763
10911
  if (process.platform === "win32") {
10764
- void (0, import_execa3.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
10912
+ void (0, import_execa4.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
10765
10913
  } else {
10766
10914
  process.kill(-pid, "SIGTERM");
10767
10915
  setTimeout(() => {
@@ -10781,7 +10929,7 @@ function killScriptTree(child, ports = []) {
10781
10929
  for (const port of ports) {
10782
10930
  if (!Number.isFinite(port) || port <= 0) continue;
10783
10931
  if (process.platform === "win32") {
10784
- void (0, import_execa3.execa)(
10932
+ void (0, import_execa4.execa)(
10785
10933
  "powershell",
10786
10934
  [
10787
10935
  "-NoProfile",
@@ -10791,7 +10939,7 @@ function killScriptTree(child, ports = []) {
10791
10939
  { reject: false }
10792
10940
  );
10793
10941
  } else {
10794
- void (0, import_execa3.execa)(
10942
+ void (0, import_execa4.execa)(
10795
10943
  "zsh",
10796
10944
  ["-lc", `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`],
10797
10945
  { reject: false }
@@ -10816,7 +10964,7 @@ async function spawnWorkspaceScript(command, opts) {
10816
10964
  } catch {
10817
10965
  }
10818
10966
  const shell = process.platform === "darwin" ? "zsh" : "bash";
10819
- const child = (0, import_execa3.execa)(shell, ["-lc", command], {
10967
+ const child = (0, import_execa4.execa)(shell, ["-lc", command], {
10820
10968
  cwd: opts.worktreePath,
10821
10969
  reject: false,
10822
10970
  env,
@@ -10834,6 +10982,14 @@ async function spawnWorkspaceScript(command, opts) {
10834
10982
  child
10835
10983
  };
10836
10984
  }
10985
+ async function attachAbort(handle, signal) {
10986
+ if (signal) {
10987
+ const onAbort = () => handle.kill();
10988
+ if (signal.aborted) onAbort();
10989
+ else signal.addEventListener("abort", onAbort, { once: true });
10990
+ }
10991
+ return handle.done;
10992
+ }
10837
10993
  async function runSetupScript(repoPath, worktreePath, onLine, opts) {
10838
10994
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
10839
10995
  if (!settings?.setup) return { ran: false, exitCode: null, source: null };
@@ -10843,12 +10999,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
10843
10999
  defaultBranch: opts?.defaultBranch,
10844
11000
  onLine
10845
11001
  });
10846
- if (opts?.signal) {
10847
- const onAbort = () => handle.kill();
10848
- if (opts.signal.aborted) onAbort();
10849
- else opts.signal.addEventListener("abort", onAbort, { once: true });
10850
- }
10851
- const exitCode = await handle.done;
11002
+ const exitCode = await attachAbort(handle, opts?.signal);
10852
11003
  return {
10853
11004
  ran: true,
10854
11005
  exitCode,
@@ -10856,6 +11007,34 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
10856
11007
  kill: handle.kill
10857
11008
  };
10858
11009
  }
11010
+ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
11011
+ const found = findConventionSetup(worktreePath, repoPath);
11012
+ if (!found) return { ran: false, exitCode: null, source: null };
11013
+ onLine?.(`[setup] ${found.source}`);
11014
+ const handle = await spawnWorkspaceScript(found.command, {
11015
+ worktreePath,
11016
+ repoPath,
11017
+ defaultBranch: opts?.defaultBranch,
11018
+ onLine
11019
+ });
11020
+ const exitCode = await attachAbort(handle, opts?.signal);
11021
+ return {
11022
+ ran: true,
11023
+ exitCode,
11024
+ source: found.source,
11025
+ kill: handle.kill
11026
+ };
11027
+ }
11028
+ async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
11029
+ let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
11030
+ if (!setup.ran) {
11031
+ setup = await runCursorWorktreeSetup(repoPath, worktreePath, onLine);
11032
+ }
11033
+ if (!setup.ran) {
11034
+ setup = await runConventionSetup(repoPath, worktreePath, onLine, opts);
11035
+ }
11036
+ return setup;
11037
+ }
10859
11038
  async function runArchiveScript(repoPath, worktreePath, onLine) {
10860
11039
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
10861
11040
  if (!settings?.archive) return { ran: false, exitCode: null };
@@ -10948,86 +11127,17 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
10948
11127
  };
10949
11128
  }
10950
11129
 
10951
- // src/hook/cursor-worktrees.ts
10952
- var import_node_fs22 = require("fs");
10953
- var import_node_path19 = require("path");
10954
- var import_execa4 = require("execa");
10955
- var import_node_readline3 = require("readline");
10956
- function loadCursorWorktreesJson(rootPath) {
10957
- const path2 = (0, import_node_path19.join)(rootPath, ".cursor", "worktrees.json");
10958
- if (!(0, import_node_fs22.existsSync)(path2)) return null;
10959
- try {
10960
- return JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
10961
- } catch {
10962
- return null;
10963
- }
10964
- }
10965
- function resolveSetupSpec(config) {
10966
- if (process.platform === "win32") {
10967
- return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
10968
- }
10969
- return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
10970
- }
10971
- async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
10972
- const fromWorktree = loadCursorWorktreesJson(worktreePath);
10973
- const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
10974
- const config = fromWorktree ?? fromRepo;
10975
- if (!config) return { ran: false, exitCode: null, source: null };
10976
- const spec = resolveSetupSpec(config);
10977
- if (!spec) return { ran: false, exitCode: null, source: null };
10978
- const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
10979
- const env = {
10980
- ...process.env,
10981
- ROOT_WORKTREE_PATH: repoPath
10982
- };
10983
- if (process.platform === "win32") {
10984
- env.ROOT_WORKTREE_PATH = repoPath;
10985
- }
10986
- const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path19.join)(
10987
- fromWorktree ? worktreePath : repoPath,
10988
- ".cursor",
10989
- spec
10990
- ) : spec];
10991
- let lastExit = 0;
10992
- for (const command of commands) {
10993
- const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
10994
- const shell = process.platform === "win32" ? "powershell" : "bash";
10995
- const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
10996
- onLine?.(`[cursor setup] ${command}`);
10997
- const child = (0, import_execa4.execa)(shell, args, {
10998
- cwd: worktreePath,
10999
- reject: false,
11000
- env
11001
- });
11002
- if (child.stdout && onLine) {
11003
- const rl = (0, import_node_readline3.createInterface)({ input: child.stdout });
11004
- rl.on("line", onLine);
11005
- }
11006
- if (child.stderr && onLine) {
11007
- const rl = (0, import_node_readline3.createInterface)({ input: child.stderr });
11008
- rl.on("line", onLine);
11009
- }
11010
- const result = await child;
11011
- lastExit = result.exitCode ?? null;
11012
- if (lastExit !== 0 && lastExit !== null) break;
11013
- }
11014
- return { ran: true, exitCode: lastExit, source: sourceLabel };
11015
- }
11016
- function hasCursorWorktreeSetup(worktreePath, repoPath) {
11017
- if (loadCursorWorktreesJson(worktreePath)) return true;
11018
- if (repoPath && repoPath !== worktreePath && loadCursorWorktreesJson(repoPath)) {
11019
- return true;
11020
- }
11021
- return false;
11022
- }
11130
+ // src/index.ts
11131
+ init_convention_setup();
11132
+ init_cursor_worktrees();
11023
11133
 
11024
11134
  // src/diff/diff.ts
11025
- var import_node_fs23 = require("fs");
11026
- var import_node_path20 = require("path");
11135
+ var import_node_fs24 = require("fs");
11136
+ var import_node_path21 = require("path");
11027
11137
  init_run();
11028
11138
  init_worktree();
11029
11139
  async function inspectGitWorktree(worktreePath) {
11030
- if (!worktreePath || !(0, import_node_fs23.existsSync)(worktreePath)) return "missing_worktree";
11140
+ if (!worktreePath || !(0, import_node_fs24.existsSync)(worktreePath)) return "missing_worktree";
11031
11141
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
11032
11142
  reject: false
11033
11143
  });
@@ -11035,7 +11145,7 @@ async function inspectGitWorktree(worktreePath) {
11035
11145
  return "ok";
11036
11146
  }
11037
11147
  async function initializeGitRepository(worktreePath) {
11038
- if (!worktreePath || !(0, import_node_fs23.existsSync)(worktreePath)) {
11148
+ if (!worktreePath || !(0, import_node_fs24.existsSync)(worktreePath)) {
11039
11149
  throw new Error("Worktree not found");
11040
11150
  }
11041
11151
  const status = await inspectGitWorktree(worktreePath);
@@ -11170,11 +11280,11 @@ new file mode 100644
11170
11280
  };
11171
11281
  }
11172
11282
  async function untrackedPatch(worktreePath, path2, maxHunk) {
11173
- const abs = (0, import_node_path20.join)(worktreePath, path2);
11283
+ const abs = (0, import_node_path21.join)(worktreePath, path2);
11174
11284
  try {
11175
- const st = (0, import_node_fs23.statSync)(abs);
11285
+ const st = (0, import_node_fs24.statSync)(abs);
11176
11286
  if (st.isFile() && st.size > maxHunk) {
11177
- const buf = (0, import_node_fs23.readFileSync)(abs).subarray(0, maxHunk);
11287
+ const buf = (0, import_node_fs24.readFileSync)(abs).subarray(0, maxHunk);
11178
11288
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
11179
11289
  }
11180
11290
  } catch {
@@ -11675,8 +11785,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
11675
11785
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
11676
11786
  assertSafeRelativePath(relativePath);
11677
11787
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
11678
- const abs = (0, import_node_path20.join)(worktreePath, relativePath);
11679
- const st = (0, import_node_fs23.statSync)(abs);
11788
+ const abs = (0, import_node_path21.join)(worktreePath, relativePath);
11789
+ const st = (0, import_node_fs24.statSync)(abs);
11680
11790
  if (!st.isFile()) {
11681
11791
  throw new Error(`Not a file: ${relativePath}`);
11682
11792
  }
@@ -11685,7 +11795,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
11685
11795
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
11686
11796
  );
11687
11797
  }
11688
- const buf = (0, import_node_fs23.readFileSync)(abs);
11798
+ const buf = (0, import_node_fs24.readFileSync)(abs);
11689
11799
  return {
11690
11800
  path: relativePath,
11691
11801
  contentBase64: buf.toString("base64"),
@@ -11695,12 +11805,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
11695
11805
  function readWorktreeFile(worktreePath, relativePath, opts) {
11696
11806
  assertSafeRelativePath(relativePath);
11697
11807
  const maxBytes = opts?.maxBytes ?? 2e5;
11698
- const abs = (0, import_node_path20.join)(worktreePath, relativePath);
11699
- const st = (0, import_node_fs23.statSync)(abs);
11808
+ const abs = (0, import_node_path21.join)(worktreePath, relativePath);
11809
+ const st = (0, import_node_fs24.statSync)(abs);
11700
11810
  if (!st.isFile()) {
11701
11811
  throw new Error(`Not a file: ${relativePath}`);
11702
11812
  }
11703
- const buf = (0, import_node_fs23.readFileSync)(abs);
11813
+ const buf = (0, import_node_fs24.readFileSync)(abs);
11704
11814
  if (isImageRelativePath(relativePath)) {
11705
11815
  const maxImageBytes = Math.max(maxBytes, 15e6);
11706
11816
  const truncated2 = buf.length > maxImageBytes;
@@ -11743,9 +11853,9 @@ function assertSafeRelativePath(relativePath) {
11743
11853
  }
11744
11854
  function writeWorktreeFile(worktreePath, relativePath, content) {
11745
11855
  assertSafeRelativePath(relativePath);
11746
- const abs = (0, import_node_path20.join)(worktreePath, relativePath);
11747
- (0, import_node_fs23.mkdirSync)((0, import_node_path20.dirname)(abs), { recursive: true });
11748
- (0, import_node_fs23.writeFileSync)(abs, content, "utf8");
11856
+ const abs = (0, import_node_path21.join)(worktreePath, relativePath);
11857
+ (0, import_node_fs24.mkdirSync)((0, import_node_path21.dirname)(abs), { recursive: true });
11858
+ (0, import_node_fs24.writeFileSync)(abs, content, "utf8");
11749
11859
  return { path: relativePath };
11750
11860
  }
11751
11861
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -11764,9 +11874,9 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
11764
11874
  }
11765
11875
 
11766
11876
  // src/skills/discover.ts
11767
- var import_node_fs24 = require("fs");
11877
+ var import_node_fs25 = require("fs");
11768
11878
  var import_node_os8 = require("os");
11769
- var import_node_path21 = require("path");
11879
+ var import_node_path22 = require("path");
11770
11880
  function toCommand(name) {
11771
11881
  return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
11772
11882
  }
@@ -11798,7 +11908,7 @@ function parseFrontmatter(content) {
11798
11908
  }
11799
11909
  function readSkill(skillMd, source) {
11800
11910
  try {
11801
- const content = (0, import_node_fs24.readFileSync)(skillMd, "utf8");
11911
+ const content = (0, import_node_fs25.readFileSync)(skillMd, "utf8");
11802
11912
  const { name: fmName, description } = parseFrontmatter(content);
11803
11913
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
11804
11914
  const name = fmName || dirName;
@@ -11817,19 +11927,19 @@ function readSkill(skillMd, source) {
11817
11927
  }
11818
11928
  }
11819
11929
  function scanSkillsDir(dir, source, out) {
11820
- if (!(0, import_node_fs24.existsSync)(dir)) return;
11930
+ if (!(0, import_node_fs25.existsSync)(dir)) return;
11821
11931
  let entries;
11822
11932
  try {
11823
- entries = (0, import_node_fs24.readdirSync)(dir);
11933
+ entries = (0, import_node_fs25.readdirSync)(dir);
11824
11934
  } catch {
11825
11935
  return;
11826
11936
  }
11827
11937
  for (const entry of entries) {
11828
11938
  if (entry.startsWith(".")) continue;
11829
- const skillMd = (0, import_node_path21.join)(dir, entry, "SKILL.md");
11830
- if (!(0, import_node_fs24.existsSync)(skillMd)) continue;
11939
+ const skillMd = (0, import_node_path22.join)(dir, entry, "SKILL.md");
11940
+ if (!(0, import_node_fs25.existsSync)(skillMd)) continue;
11831
11941
  try {
11832
- if (!(0, import_node_fs24.statSync)(skillMd).isFile()) continue;
11942
+ if (!(0, import_node_fs25.statSync)(skillMd).isFile()) continue;
11833
11943
  } catch {
11834
11944
  continue;
11835
11945
  }
@@ -11838,24 +11948,24 @@ function scanSkillsDir(dir, source, out) {
11838
11948
  }
11839
11949
  }
11840
11950
  function scanClaudePluginSkills(pluginsRoot, out) {
11841
- if (!(0, import_node_fs24.existsSync)(pluginsRoot)) return;
11951
+ if (!(0, import_node_fs25.existsSync)(pluginsRoot)) return;
11842
11952
  const walk = (dir, depth, lookingForSkillsDir) => {
11843
11953
  if (depth > 7) return;
11844
11954
  let entries;
11845
11955
  try {
11846
- entries = (0, import_node_fs24.readdirSync)(dir);
11956
+ entries = (0, import_node_fs25.readdirSync)(dir);
11847
11957
  } catch {
11848
11958
  return;
11849
11959
  }
11850
11960
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
11851
- const skill = readSkill((0, import_node_path21.join)(dir, "SKILL.md"), "cli");
11961
+ const skill = readSkill((0, import_node_path22.join)(dir, "SKILL.md"), "cli");
11852
11962
  if (skill) out.push(skill);
11853
11963
  }
11854
11964
  for (const entry of entries) {
11855
11965
  if (entry === "node_modules" || entry === ".git") continue;
11856
- const full = (0, import_node_path21.join)(dir, entry);
11966
+ const full = (0, import_node_path22.join)(dir, entry);
11857
11967
  try {
11858
- if (!(0, import_node_fs24.statSync)(full).isDirectory()) continue;
11968
+ if (!(0, import_node_fs25.statSync)(full).isDirectory()) continue;
11859
11969
  } catch {
11860
11970
  continue;
11861
11971
  }
@@ -11873,17 +11983,17 @@ function discoverSkills(worktreePath) {
11873
11983
  const home = (0, import_node_os8.homedir)();
11874
11984
  const collected = [];
11875
11985
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
11876
- scanSkillsDir((0, import_node_path21.join)(worktreePath, rel), "workspace", collected);
11986
+ scanSkillsDir((0, import_node_path22.join)(worktreePath, rel), "workspace", collected);
11877
11987
  }
11878
11988
  for (const abs of [
11879
- (0, import_node_path21.join)(home, ".claude/skills"),
11880
- (0, import_node_path21.join)(home, ".cursor/skills"),
11881
- (0, import_node_path21.join)(home, ".sideboard/skills"),
11882
- (0, import_node_path21.join)(home, ".brightsy/skills")
11989
+ (0, import_node_path22.join)(home, ".claude/skills"),
11990
+ (0, import_node_path22.join)(home, ".cursor/skills"),
11991
+ (0, import_node_path22.join)(home, ".sideboard/skills"),
11992
+ (0, import_node_path22.join)(home, ".brightsy/skills")
11883
11993
  ]) {
11884
11994
  scanSkillsDir(abs, "user", collected);
11885
11995
  }
11886
- scanClaudePluginSkills((0, import_node_path21.join)(home, ".claude/plugins"), collected);
11996
+ scanClaudePluginSkills((0, import_node_path22.join)(home, ".claude/plugins"), collected);
11887
11997
  const rank = { workspace: 0, user: 1, cli: 2 };
11888
11998
  const byCommand = /* @__PURE__ */ new Map();
11889
11999
  for (const skill of collected) {
@@ -11895,7 +12005,7 @@ function discoverSkills(worktreePath) {
11895
12005
  return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
11896
12006
  }
11897
12007
  function readSkillBody(skillPath, maxChars = 12e3) {
11898
- const raw = (0, import_node_fs24.readFileSync)(skillPath, "utf8");
12008
+ const raw = (0, import_node_fs25.readFileSync)(skillPath, "utf8");
11899
12009
  if (raw.startsWith("---")) {
11900
12010
  const end = raw.indexOf("\n---", 3);
11901
12011
  if (end >= 0) {
@@ -12036,8 +12146,8 @@ function buildDiffCommentAttachment(input) {
12036
12146
  }
12037
12147
 
12038
12148
  // src/composer/stage-files.ts
12039
- var import_node_fs25 = require("fs");
12040
- var import_node_path22 = require("path");
12149
+ var import_node_fs26 = require("fs");
12150
+ var import_node_path23 = require("path");
12041
12151
  var import_node_crypto5 = require("crypto");
12042
12152
  init_workspace_scratch();
12043
12153
  var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -12063,7 +12173,7 @@ var IMAGE_MIME_BY_EXT = {
12063
12173
  var MAX_INLINE_BYTES = 4e5;
12064
12174
  var MAX_PREVIEW_BYTES = 5e6;
12065
12175
  function fileExtension(filePath) {
12066
- const base = (0, import_node_path22.basename)(filePath).toLowerCase();
12176
+ const base = (0, import_node_path23.basename)(filePath).toLowerCase();
12067
12177
  return base.includes(".") ? base.split(".").pop() || "" : "";
12068
12178
  }
12069
12179
  function isImageFilePath(filePath) {
@@ -12073,22 +12183,22 @@ function imageMimeType(filePath) {
12073
12183
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
12074
12184
  }
12075
12185
  function ensureAttachmentsDir(worktreePath) {
12076
- const dir = (0, import_node_path22.join)(worktreePath, ATTACHMENTS_DIR);
12077
- (0, import_node_fs25.mkdirSync)(dir, { recursive: true });
12078
- const gi = (0, import_node_path22.join)(dir, ".gitignore");
12079
- if (!(0, import_node_fs25.existsSync)(gi)) {
12080
- (0, import_node_fs25.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12186
+ const dir = (0, import_node_path23.join)(worktreePath, ATTACHMENTS_DIR);
12187
+ (0, import_node_fs26.mkdirSync)(dir, { recursive: true });
12188
+ const gi = (0, import_node_path23.join)(dir, ".gitignore");
12189
+ if (!(0, import_node_fs26.existsSync)(gi)) {
12190
+ (0, import_node_fs26.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12081
12191
  }
12082
12192
  return dir;
12083
12193
  }
12084
12194
  function uniqueAttachmentName(dir, originalName) {
12085
12195
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
12086
- if (!(0, import_node_fs25.existsSync)((0, import_node_path22.join)(dir, safe))) return safe;
12087
- const ext = (0, import_node_path22.extname)(safe);
12196
+ if (!(0, import_node_fs26.existsSync)((0, import_node_path23.join)(dir, safe))) return safe;
12197
+ const ext = (0, import_node_path23.extname)(safe);
12088
12198
  const stem = ext ? safe.slice(0, -ext.length) : safe;
12089
12199
  for (let i = 1; i < 1e4; i++) {
12090
12200
  const candidate = `${stem}-${i}${ext}`;
12091
- if (!(0, import_node_fs25.existsSync)((0, import_node_path22.join)(dir, candidate))) return candidate;
12201
+ if (!(0, import_node_fs26.existsSync)((0, import_node_path23.join)(dir, candidate))) return candidate;
12092
12202
  }
12093
12203
  return `${stem}-${(0, import_node_crypto5.randomUUID)()}${ext}`;
12094
12204
  }
@@ -12140,9 +12250,9 @@ function attachmentFromBuffer(name, buf, opts) {
12140
12250
  };
12141
12251
  }
12142
12252
  function attachmentFromAbsolutePath(absolutePath) {
12143
- const name = (0, import_node_path22.basename)(absolutePath);
12253
+ const name = (0, import_node_path23.basename)(absolutePath);
12144
12254
  try {
12145
- const st = (0, import_node_fs25.statSync)(absolutePath);
12255
+ const st = (0, import_node_fs26.statSync)(absolutePath);
12146
12256
  if (!st.isFile()) {
12147
12257
  return {
12148
12258
  id: (0, import_node_crypto5.randomUUID)(),
@@ -12151,7 +12261,7 @@ function attachmentFromAbsolutePath(absolutePath) {
12151
12261
  content: `(not a file: ${absolutePath})`
12152
12262
  };
12153
12263
  }
12154
- const buf = (0, import_node_fs25.readFileSync)(absolutePath);
12264
+ const buf = (0, import_node_fs26.readFileSync)(absolutePath);
12155
12265
  return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
12156
12266
  } catch (err) {
12157
12267
  return {
@@ -12167,15 +12277,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
12167
12277
  const dir = ensureAttachmentsDir(worktreePath);
12168
12278
  const out = [];
12169
12279
  for (const abs of absolutePaths) {
12170
- const originalName = (0, import_node_path22.basename)(abs);
12280
+ const originalName = (0, import_node_path23.basename)(abs);
12171
12281
  try {
12172
- const st = (0, import_node_fs25.statSync)(abs);
12282
+ const st = (0, import_node_fs26.statSync)(abs);
12173
12283
  if (!st.isFile()) continue;
12174
12284
  const name = uniqueAttachmentName(dir, originalName);
12175
- const destAbs = (0, import_node_path22.join)(dir, name);
12176
- (0, import_node_fs25.copyFileSync)(abs, destAbs);
12285
+ const destAbs = (0, import_node_path23.join)(dir, name);
12286
+ (0, import_node_fs26.copyFileSync)(abs, destAbs);
12177
12287
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12178
- const buf = (0, import_node_fs25.readFileSync)(destAbs);
12288
+ const buf = (0, import_node_fs26.readFileSync)(destAbs);
12179
12289
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12180
12290
  } catch (err) {
12181
12291
  out.push({
@@ -12197,8 +12307,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
12197
12307
  try {
12198
12308
  const buf = Buffer.from(item.dataBase64, "base64");
12199
12309
  const name = uniqueAttachmentName(dir, originalName);
12200
- const destAbs = (0, import_node_path22.join)(dir, name);
12201
- (0, import_node_fs25.writeFileSync)(destAbs, buf);
12310
+ const destAbs = (0, import_node_path23.join)(dir, name);
12311
+ (0, import_node_fs26.writeFileSync)(destAbs, buf);
12202
12312
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12203
12313
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
12204
12314
  } catch (err) {
@@ -12234,18 +12344,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
12234
12344
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
12235
12345
  out.push({
12236
12346
  id: (0, import_node_crypto5.randomUUID)(),
12237
- name: (0, import_node_path22.basename)(rel) || "file",
12347
+ name: (0, import_node_path23.basename)(rel) || "file",
12238
12348
  kind: "file",
12239
12349
  content: `(invalid path: ${rel})`
12240
12350
  });
12241
12351
  continue;
12242
12352
  }
12243
- const name = (0, import_node_path22.basename)(rel);
12353
+ const name = (0, import_node_path23.basename)(rel);
12244
12354
  try {
12245
- const abs = (0, import_node_path22.join)(worktreePath, rel);
12246
- const st = (0, import_node_fs25.statSync)(abs);
12355
+ const abs = (0, import_node_path23.join)(worktreePath, rel);
12356
+ const st = (0, import_node_fs26.statSync)(abs);
12247
12357
  if (!st.isFile()) continue;
12248
- const buf = (0, import_node_fs25.readFileSync)(abs);
12358
+ const buf = (0, import_node_fs26.readFileSync)(abs);
12249
12359
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12250
12360
  } catch (err) {
12251
12361
  out.push({
@@ -12733,7 +12843,7 @@ async function confirmLand(thread, opts) {
12733
12843
  }
12734
12844
 
12735
12845
  // src/threads/create.ts
12736
- var import_node_fs26 = require("fs");
12846
+ var import_node_fs27 = require("fs");
12737
12847
  init_worktree();
12738
12848
  init_app_settings();
12739
12849
  init_thread_store();
@@ -12747,7 +12857,7 @@ async function createThread(input, _onSetupLine) {
12747
12857
  });
12748
12858
  await requireAgent(resolved.agent);
12749
12859
  const repoPath = await resolveRepoRoot(input.repoPath);
12750
- if (!(0, import_node_fs26.existsSync)(repoPath)) {
12860
+ if (!(0, import_node_fs27.existsSync)(repoPath)) {
12751
12861
  throw new Error(`Repo not found: ${repoPath}`);
12752
12862
  }
12753
12863
  let sourceRef = input.sourceRef;
@@ -12974,7 +13084,7 @@ async function forkThreadWorktree(input, onSetupLine) {
12974
13084
  }
12975
13085
 
12976
13086
  // src/threads/stack-layers.ts
12977
- var import_node_fs27 = require("fs");
13087
+ var import_node_fs28 = require("fs");
12978
13088
  init_run();
12979
13089
  init_stack();
12980
13090
  init_worktree();
@@ -13042,7 +13152,7 @@ async function openStackLayer(input, _onSetupLine) {
13042
13152
  let createdWorktree = false;
13043
13153
  const trees = await listWorktrees(repoPath);
13044
13154
  const checkedOut = trees.find((w) => w.branch === branchName);
13045
- if (checkedOut?.path && (0, import_node_fs27.existsSync)(checkedOut.path)) {
13155
+ if (checkedOut?.path && (0, import_node_fs28.existsSync)(checkedOut.path)) {
13046
13156
  if (input.reuseExistingWorktree !== false) {
13047
13157
  worktreePath = checkedOut.path;
13048
13158
  } else {
@@ -13184,7 +13294,7 @@ async function initStackFromThread(input, onSetupLine) {
13184
13294
  async function createPrStack(input, onSetupLine) {
13185
13295
  await requireAgent(input.agent);
13186
13296
  const repoPath = await resolveRepoRoot(input.repoPath);
13187
- if (!(0, import_node_fs27.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
13297
+ if (!(0, import_node_fs28.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
13188
13298
  if (!input.branches.length) throw new Error("At least one branch name required");
13189
13299
  const status = await detectGhStack(repoPath);
13190
13300
  if (!status.available) throw new Error(status.reason);
@@ -13251,7 +13361,7 @@ async function createPrStack(input, onSetupLine) {
13251
13361
  }
13252
13362
  }
13253
13363
  const claimed = new Set(threads.map((t) => t.worktreePath));
13254
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs27.existsSync)(bootstrap.worktreePath)) {
13364
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs28.existsSync)(bootstrap.worktreePath)) {
13255
13365
  try {
13256
13366
  await removeWorktree(repoPath, bootstrap.worktreePath, {
13257
13367
  deleteBranch: bootstrap.branchName
@@ -13274,20 +13384,20 @@ function stackAgentDefaultsFrom(input) {
13274
13384
 
13275
13385
  // src/threads/adopt.ts
13276
13386
  var import_node_child_process4 = require("child_process");
13277
- var import_node_fs28 = require("fs");
13387
+ var import_node_fs29 = require("fs");
13278
13388
  var import_node_os9 = require("os");
13279
- var import_node_path23 = require("path");
13389
+ var import_node_path24 = require("path");
13280
13390
  var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
13281
13391
  init_worktree();
13282
13392
  init_thread_store();
13283
- var CONDUCTOR_APP_SUPPORT = (0, import_node_path23.join)(
13393
+ var CONDUCTOR_APP_SUPPORT = (0, import_node_path24.join)(
13284
13394
  process.env.HOME ?? "",
13285
13395
  "Library",
13286
13396
  "Application Support",
13287
13397
  "com.conductor.app"
13288
13398
  );
13289
- var CONDUCTOR_DB = (0, import_node_path23.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
13290
- var CURSOR_SDK_STORE = (0, import_node_path23.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
13399
+ var CONDUCTOR_DB = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
13400
+ var CURSOR_SDK_STORE = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
13291
13401
  function mapAgentType(raw) {
13292
13402
  if (!raw) return null;
13293
13403
  const v = raw.toLowerCase();
@@ -13299,21 +13409,21 @@ function mapAgentType(raw) {
13299
13409
  return null;
13300
13410
  }
13301
13411
  function resolveConductorCursorAgentId(workspacePath) {
13302
- if (!workspacePath || !(0, import_node_fs28.existsSync)(CURSOR_SDK_STORE)) return null;
13412
+ if (!workspacePath || !(0, import_node_fs29.existsSync)(CURSOR_SDK_STORE)) return null;
13303
13413
  const normalized = workspacePath.replace(/\/$/, "");
13304
13414
  let best = null;
13305
13415
  let hashes;
13306
13416
  try {
13307
- hashes = (0, import_node_fs28.readdirSync)(CURSOR_SDK_STORE);
13417
+ hashes = (0, import_node_fs29.readdirSync)(CURSOR_SDK_STORE);
13308
13418
  } catch {
13309
13419
  return null;
13310
13420
  }
13311
13421
  for (const hash of hashes) {
13312
- const agentsFile = (0, import_node_path23.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
13313
- if (!(0, import_node_fs28.existsSync)(agentsFile)) continue;
13422
+ const agentsFile = (0, import_node_path24.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
13423
+ if (!(0, import_node_fs29.existsSync)(agentsFile)) continue;
13314
13424
  let text3;
13315
13425
  try {
13316
- text3 = (0, import_node_fs28.readFileSync)(agentsFile, "utf8");
13426
+ text3 = (0, import_node_fs29.readFileSync)(agentsFile, "utf8");
13317
13427
  } catch {
13318
13428
  continue;
13319
13429
  }
@@ -13337,7 +13447,7 @@ function resolveConductorCursorAgentId(workspacePath) {
13337
13447
  return best?.agentId ?? null;
13338
13448
  }
13339
13449
  async function adoptThread(input) {
13340
- if (!(0, import_node_fs28.existsSync)(input.worktreePath)) {
13450
+ if (!(0, import_node_fs29.existsSync)(input.worktreePath)) {
13341
13451
  throw new Error(`Worktree not found: ${input.worktreePath}`);
13342
13452
  }
13343
13453
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -13364,18 +13474,18 @@ function conductorDbPath() {
13364
13474
  return CONDUCTOR_DB;
13365
13475
  }
13366
13476
  function listConductorWorkspaces() {
13367
- if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
13477
+ if (!(0, import_node_fs29.existsSync)(CONDUCTOR_DB)) {
13368
13478
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
13369
13479
  }
13370
- const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path23.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
13371
- const snapshot = (0, import_node_path23.join)(tmp, "conductor.db");
13480
+ const tmp = (0, import_node_fs29.mkdtempSync)((0, import_node_path24.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
13481
+ const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
13372
13482
  try {
13373
- (0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
13483
+ (0, import_node_fs29.copyFileSync)(CONDUCTOR_DB, snapshot);
13374
13484
  for (const suffix of ["-wal", "-shm"]) {
13375
13485
  const src = `${CONDUCTOR_DB}${suffix}`;
13376
- if ((0, import_node_fs28.existsSync)(src)) {
13486
+ if ((0, import_node_fs29.existsSync)(src)) {
13377
13487
  try {
13378
- (0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
13488
+ (0, import_node_fs29.copyFileSync)(src, `${snapshot}${suffix}`);
13379
13489
  } catch {
13380
13490
  }
13381
13491
  }
@@ -13451,22 +13561,22 @@ function listConductorWorkspaces() {
13451
13561
  db.close();
13452
13562
  }
13453
13563
  } finally {
13454
- (0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
13564
+ (0, import_node_fs29.rmSync)(tmp, { recursive: true, force: true });
13455
13565
  }
13456
13566
  }
13457
13567
  function importConductorWorkspace(workspaceId) {
13458
- if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
13568
+ if (!(0, import_node_fs29.existsSync)(CONDUCTOR_DB)) {
13459
13569
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
13460
13570
  }
13461
- const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path23.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
13462
- const snapshot = (0, import_node_path23.join)(tmp, "conductor.db");
13571
+ const tmp = (0, import_node_fs29.mkdtempSync)((0, import_node_path24.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
13572
+ const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
13463
13573
  try {
13464
- (0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
13574
+ (0, import_node_fs29.copyFileSync)(CONDUCTOR_DB, snapshot);
13465
13575
  for (const suffix of ["-wal", "-shm"]) {
13466
13576
  const src = `${CONDUCTOR_DB}${suffix}`;
13467
- if ((0, import_node_fs28.existsSync)(src)) {
13577
+ if ((0, import_node_fs29.existsSync)(src)) {
13468
13578
  try {
13469
- (0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
13579
+ (0, import_node_fs29.copyFileSync)(src, `${snapshot}${suffix}`);
13470
13580
  } catch {
13471
13581
  }
13472
13582
  }
@@ -13484,7 +13594,7 @@ function importConductorWorkspace(workspaceId) {
13484
13594
  ).get(workspaceId);
13485
13595
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
13486
13596
  const worktreePath = String(row.workspacePath);
13487
- if (!(0, import_node_fs28.existsSync)(worktreePath)) {
13597
+ if (!(0, import_node_fs29.existsSync)(worktreePath)) {
13488
13598
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
13489
13599
  }
13490
13600
  let sessionId = null;
@@ -13547,7 +13657,7 @@ function importConductorWorkspace(workspaceId) {
13547
13657
  db.close();
13548
13658
  }
13549
13659
  } finally {
13550
- (0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
13660
+ (0, import_node_fs29.rmSync)(tmp, { recursive: true, force: true });
13551
13661
  }
13552
13662
  }
13553
13663
  async function importConductorWorkspaceAsync(workspaceId) {
@@ -13558,8 +13668,8 @@ async function importConductorWorkspaceAsync(workspaceId) {
13558
13668
  var import_node_events = require("events");
13559
13669
 
13560
13670
  // src/slack/outbound-watch.ts
13561
- var import_node_fs30 = require("fs");
13562
- var import_node_path26 = require("path");
13671
+ var import_node_fs31 = require("fs");
13672
+ var import_node_path27 = require("path");
13563
13673
  init_paths();
13564
13674
  init_private_file();
13565
13675
  init_secure_file();
@@ -13605,19 +13715,19 @@ async function slackAuthTest(token) {
13605
13715
  }
13606
13716
 
13607
13717
  // src/slack/reply-target.ts
13608
- var import_node_fs29 = require("fs");
13609
- var import_node_path24 = require("path");
13718
+ var import_node_fs30 = require("fs");
13719
+ var import_node_path25 = require("path");
13610
13720
  init_paths();
13611
13721
  init_private_file();
13612
13722
  init_secure_file();
13613
13723
  function storePath2() {
13614
- return (0, import_node_path24.join)(appDataDir(), "slack-reply-to.json");
13724
+ return (0, import_node_path25.join)(appDataDir(), "slack-reply-to.json");
13615
13725
  }
13616
13726
  function readStore2() {
13617
13727
  const path2 = storePath2();
13618
- if (!(0, import_node_fs29.existsSync)(path2)) return {};
13728
+ if (!(0, import_node_fs30.existsSync)(path2)) return {};
13619
13729
  try {
13620
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs29.readFileSync)(path2, "utf8"));
13730
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs30.readFileSync)(path2, "utf8"));
13621
13731
  return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
13622
13732
  } catch {
13623
13733
  return {};
@@ -13634,11 +13744,11 @@ function getSlackReplyTarget(threadId) {
13634
13744
  }
13635
13745
 
13636
13746
  // src/slack/workspaces.ts
13637
- var import_node_path25 = require("path");
13747
+ var import_node_path26 = require("path");
13638
13748
  init_paths();
13639
13749
  init_secure_file();
13640
13750
  function storePath3() {
13641
- return (0, import_node_path25.join)(appDataDir(), "slack-workspaces.json");
13751
+ return (0, import_node_path26.join)(appDataDir(), "slack-workspaces.json");
13642
13752
  }
13643
13753
  function readStore3() {
13644
13754
  try {
@@ -13754,7 +13864,7 @@ var POLL_INTERVAL_MS = 12e3;
13754
13864
  var lastPollMs = 0;
13755
13865
  var nameCache = /* @__PURE__ */ new Map();
13756
13866
  function storePath4() {
13757
- return (0, import_node_path26.join)(appDataDir(), "slack-outbound-watch.json");
13867
+ return (0, import_node_path27.join)(appDataDir(), "slack-outbound-watch.json");
13758
13868
  }
13759
13869
  function watchId(teamId, channelId, ts) {
13760
13870
  return `${teamId}:${channelId}:${ts}`;
@@ -13784,9 +13894,9 @@ function tsNewer(a, b) {
13784
13894
  }
13785
13895
  function readStore4() {
13786
13896
  const path2 = storePath4();
13787
- if (!(0, import_node_fs30.existsSync)(path2)) return [];
13897
+ if (!(0, import_node_fs31.existsSync)(path2)) return [];
13788
13898
  try {
13789
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs30.readFileSync)(path2, "utf8"));
13899
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs31.readFileSync)(path2, "utf8"));
13790
13900
  return Array.isArray(parsed?.watches) ? parsed.watches : [];
13791
13901
  } catch {
13792
13902
  return [];
@@ -14131,7 +14241,7 @@ async function refreshSlackReplyBadges(opts) {
14131
14241
  }
14132
14242
 
14133
14243
  // src/orchestrator/orchestrator.ts
14134
- var import_node_fs36 = require("fs");
14244
+ var import_node_fs37 = require("fs");
14135
14245
  init_error_detail();
14136
14246
  init_agents();
14137
14247
  init_worktree();
@@ -14152,8 +14262,8 @@ function shouldAutoArchiveOnPrMerge(opts) {
14152
14262
  }
14153
14263
 
14154
14264
  // src/git/orphan-cleanup.ts
14155
- var import_node_fs31 = require("fs");
14156
- var import_node_path27 = require("path");
14265
+ var import_node_fs32 = require("fs");
14266
+ var import_node_path28 = require("path");
14157
14267
  init_worktree();
14158
14268
  init_thread_store();
14159
14269
  init_paths();
@@ -14168,9 +14278,9 @@ async function findOrphanWorktrees(repoPaths) {
14168
14278
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
14169
14279
  );
14170
14280
  const homeRoot = sideboardWorkspacesDir();
14171
- if ((0, import_node_fs31.existsSync)(homeRoot)) {
14281
+ if ((0, import_node_fs32.existsSync)(homeRoot)) {
14172
14282
  try {
14173
- for (const entry of (0, import_node_fs31.readdirSync)(homeRoot, { withFileTypes: true })) {
14283
+ for (const entry of (0, import_node_fs32.readdirSync)(homeRoot, { withFileTypes: true })) {
14174
14284
  if (!entry.isDirectory()) continue;
14175
14285
  void entry;
14176
14286
  }
@@ -14180,7 +14290,7 @@ async function findOrphanWorktrees(repoPaths) {
14180
14290
  const orphans = [];
14181
14291
  const seen = /* @__PURE__ */ new Set();
14182
14292
  for (const repoPath of repos) {
14183
- if (!repoPath || !(0, import_node_fs31.existsSync)(repoPath)) continue;
14293
+ if (!repoPath || !(0, import_node_fs32.existsSync)(repoPath)) continue;
14184
14294
  try {
14185
14295
  const wts = await listWorktrees(repoPath);
14186
14296
  for (const wt of wts) {
@@ -14191,7 +14301,7 @@ async function findOrphanWorktrees(repoPaths) {
14191
14301
  seen.add(path2);
14192
14302
  let mtimeMs = 0;
14193
14303
  try {
14194
- mtimeMs = (0, import_node_fs31.statSync)(path2).mtimeMs;
14304
+ mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
14195
14305
  } catch {
14196
14306
  mtimeMs = 0;
14197
14307
  }
@@ -14201,16 +14311,16 @@ async function findOrphanWorktrees(repoPaths) {
14201
14311
  }
14202
14312
  try {
14203
14313
  const root = worktreesRoot(repoPath);
14204
- if ((0, import_node_fs31.existsSync)(root)) {
14205
- for (const entry of (0, import_node_fs31.readdirSync)(root, { withFileTypes: true })) {
14314
+ if ((0, import_node_fs32.existsSync)(root)) {
14315
+ for (const entry of (0, import_node_fs32.readdirSync)(root, { withFileTypes: true })) {
14206
14316
  if (!entry.isDirectory()) continue;
14207
- const path2 = (0, import_node_path27.join)(root, entry.name).replace(/\/$/, "");
14317
+ const path2 = (0, import_node_path28.join)(root, entry.name).replace(/\/$/, "");
14208
14318
  if (known.has(path2) || seen.has(path2)) continue;
14209
- if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(path2, ".git"))) continue;
14319
+ if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(path2, ".git"))) continue;
14210
14320
  seen.add(path2);
14211
14321
  let mtimeMs = 0;
14212
14322
  try {
14213
- mtimeMs = (0, import_node_fs31.statSync)(path2).mtimeMs;
14323
+ mtimeMs = (0, import_node_fs32.statSync)(path2).mtimeMs;
14214
14324
  } catch {
14215
14325
  mtimeMs = Date.now();
14216
14326
  }
@@ -14356,8 +14466,8 @@ async function applyThreadIntoMain(thread, opts) {
14356
14466
  }
14357
14467
 
14358
14468
  // src/git/clone-repo.ts
14359
- var import_node_fs32 = require("fs");
14360
- var import_node_path28 = require("path");
14469
+ var import_node_fs33 = require("fs");
14470
+ var import_node_path29 = require("path");
14361
14471
  var import_execa6 = require("execa");
14362
14472
  init_paths();
14363
14473
  init_workspaces();
@@ -14367,12 +14477,12 @@ async function cloneRepoIntoSideboard(opts) {
14367
14477
  if (!url) throw new Error("Clone URL is required");
14368
14478
  let name = opts.name?.trim();
14369
14479
  if (!name) {
14370
- const leaf = (0, import_node_path28.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
14480
+ const leaf = (0, import_node_path29.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
14371
14481
  name = leaf || "repo";
14372
14482
  }
14373
14483
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
14374
- const dest = (0, import_node_path28.join)(sideboardReposDir(), name);
14375
- if ((0, import_node_fs32.existsSync)(dest)) {
14484
+ const dest = (0, import_node_path29.join)(sideboardReposDir(), name);
14485
+ if ((0, import_node_fs33.existsSync)(dest)) {
14376
14486
  const repoPath2 = await resolveRepoRoot(dest);
14377
14487
  const workspace2 = await ensureWorkspace(repoPath2);
14378
14488
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -14394,8 +14504,8 @@ init_orchestrator_capable();
14394
14504
 
14395
14505
  // src/review/request-review.ts
14396
14506
  var import_node_crypto8 = require("crypto");
14397
- var import_node_fs33 = require("fs");
14398
- var import_node_path29 = require("path");
14507
+ var import_node_fs34 = require("fs");
14508
+ var import_node_path30 = require("path");
14399
14509
  init_global_workspace();
14400
14510
  init_thread_store();
14401
14511
 
@@ -14543,22 +14653,22 @@ function shouldRefreshReviewRequestTemplate(content) {
14543
14653
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
14544
14654
  }
14545
14655
  function readTextIfPresent(abs) {
14546
- if (!(0, import_node_fs33.existsSync)(abs)) return null;
14656
+ if (!(0, import_node_fs34.existsSync)(abs)) return null;
14547
14657
  try {
14548
- const content = (0, import_node_fs33.readFileSync)(abs, "utf8");
14658
+ const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
14549
14659
  return content.trim() ? content : null;
14550
14660
  } catch {
14551
14661
  return null;
14552
14662
  }
14553
14663
  }
14554
14664
  function ensureAttachmentsGitignore(worktreePath) {
14555
- const gitignoreAbs = (0, import_node_path29.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14556
- if ((0, import_node_fs33.existsSync)(gitignoreAbs)) return;
14557
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(gitignoreAbs), { recursive: true });
14558
- (0, import_node_fs33.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14665
+ const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
14666
+ if ((0, import_node_fs34.existsSync)(gitignoreAbs)) return;
14667
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
14668
+ (0, import_node_fs34.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
14559
14669
  }
14560
14670
  function resolveReviewGuidelines(worktreePath) {
14561
- const repoAbs = (0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH);
14671
+ const repoAbs = (0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH);
14562
14672
  const repoContent = readTextIfPresent(repoAbs);
14563
14673
  if (repoContent) {
14564
14674
  return {
@@ -14568,7 +14678,7 @@ function resolveReviewGuidelines(worktreePath) {
14568
14678
  source: "repo"
14569
14679
  };
14570
14680
  }
14571
- const localAbs = (0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH);
14681
+ const localAbs = (0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH);
14572
14682
  const localContent = readTextIfPresent(localAbs);
14573
14683
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14574
14684
  return {
@@ -14578,7 +14688,7 @@ function resolveReviewGuidelines(worktreePath) {
14578
14688
  source: "local"
14579
14689
  };
14580
14690
  }
14581
- const legacyAbs = (0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14691
+ const legacyAbs = (0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14582
14692
  const legacyContent = readTextIfPresent(legacyAbs);
14583
14693
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
14584
14694
  return {
@@ -14589,8 +14699,8 @@ function resolveReviewGuidelines(worktreePath) {
14589
14699
  };
14590
14700
  }
14591
14701
  ensureAttachmentsGitignore(worktreePath);
14592
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(localAbs), { recursive: true });
14593
- (0, import_node_fs33.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
14702
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(localAbs), { recursive: true });
14703
+ (0, import_node_fs34.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
14594
14704
  return {
14595
14705
  path: REVIEW_REQUEST_PATH,
14596
14706
  name: REVIEW_REQUEST_NAME,
@@ -14599,7 +14709,7 @@ function resolveReviewGuidelines(worktreePath) {
14599
14709
  };
14600
14710
  }
14601
14711
  function ensureReviewRequestFile(worktreePath) {
14602
- const repoAbs = (0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH);
14712
+ const repoAbs = (0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH);
14603
14713
  const repoContent = readTextIfPresent(repoAbs);
14604
14714
  if (repoContent) {
14605
14715
  return {
@@ -14609,10 +14719,10 @@ function ensureReviewRequestFile(worktreePath) {
14609
14719
  source: "repo"
14610
14720
  };
14611
14721
  }
14612
- const localAbs = (0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH);
14613
- const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14722
+ const localAbs = (0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH);
14723
+ const localContent = readTextIfPresent(localAbs) ?? readTextIfPresent((0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14614
14724
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14615
- const path2 = (0, import_node_fs33.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
14725
+ const path2 = (0, import_node_fs34.existsSync)(localAbs) ? REVIEW_REQUEST_PATH : LEGACY_REVIEW_REQUEST_PATH;
14616
14726
  return {
14617
14727
  path: path2,
14618
14728
  name: REVIEW_REQUEST_NAME,
@@ -14620,8 +14730,8 @@ function ensureReviewRequestFile(worktreePath) {
14620
14730
  source: "local"
14621
14731
  };
14622
14732
  }
14623
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(repoAbs), { recursive: true });
14624
- (0, import_node_fs33.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
14733
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(repoAbs), { recursive: true });
14734
+ (0, import_node_fs34.writeFileSync)(repoAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
14625
14735
  return {
14626
14736
  path: REPO_REVIEW_PATH,
14627
14737
  name: REPO_REVIEW_NAME,
@@ -14641,7 +14751,7 @@ function buildReviewRequestAttachment(content, opts) {
14641
14751
  };
14642
14752
  }
14643
14753
  function readExistingReviewRequestFile(worktreePath) {
14644
- return readTextIfPresent((0, import_node_path29.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path29.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14754
+ return readTextIfPresent((0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14645
14755
  }
14646
14756
  async function requestReview(threadRef, send2) {
14647
14757
  const from = findThreadByRef(threadRef);
@@ -14902,7 +15012,7 @@ var Orchestrator = class {
14902
15012
  }
14903
15013
  continue;
14904
15014
  }
14905
- if (!(0, import_node_fs36.existsSync)(thread.worktreePath)) {
15015
+ if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
14906
15016
  setStatus(thread.id, "broken", "Worktree missing on disk");
14907
15017
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
14908
15018
  continue;
@@ -15077,14 +15187,7 @@ var Orchestrator = class {
15077
15187
  return thread;
15078
15188
  }
15079
15189
  async finishCreateThread(threadId, prompt) {
15080
- await this.runSetupAfterCreate(threadId);
15081
- const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
15082
- if (autoRunAfterSetupEnabled2()) {
15083
- try {
15084
- await this.startDev(threadId);
15085
- } catch {
15086
- }
15087
- }
15190
+ const setup = this.runSetupAfterCreate(threadId);
15088
15191
  if (prompt) {
15089
15192
  try {
15090
15193
  await this.send(threadId, prompt);
@@ -15095,6 +15198,14 @@ var Orchestrator = class {
15095
15198
  });
15096
15199
  }
15097
15200
  }
15201
+ await setup;
15202
+ const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
15203
+ if (autoRunAfterSetupEnabled2()) {
15204
+ try {
15205
+ await this.startDev(threadId);
15206
+ } catch {
15207
+ }
15208
+ }
15098
15209
  }
15099
15210
  /** Run workspace setup after a new worktree is created (no-op if none configured). */
15100
15211
  async runSetupAfterCreate(threadId) {
@@ -15792,7 +15903,7 @@ var Orchestrator = class {
15792
15903
  });
15793
15904
  this.emit({ type: "setup_started", threadId: thread.id });
15794
15905
  try {
15795
- let setup = await runSetupScript(
15906
+ const setup = await runWorkspaceSetup(
15796
15907
  thread.repoPath,
15797
15908
  thread.worktreePath,
15798
15909
  (line) => {
@@ -15800,18 +15911,9 @@ var Orchestrator = class {
15800
15911
  },
15801
15912
  { signal: abort.signal }
15802
15913
  );
15803
- if (!setup.ran) {
15804
- setup = await runCursorWorktreeSetup(
15805
- thread.repoPath,
15806
- thread.worktreePath,
15807
- (line) => {
15808
- this.emit({ type: "setup_output", threadId: thread.id, line });
15809
- }
15810
- );
15811
- }
15812
15914
  if (!setup.ran) {
15813
15915
  throw new Error(
15814
- "No setup script in .sideboard/settings.toml, .conductor/settings.toml, or .cursor/worktrees.json"
15916
+ "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)"
15815
15917
  );
15816
15918
  }
15817
15919
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
@@ -16119,7 +16221,7 @@ var Orchestrator = class {
16119
16221
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
16120
16222
  }
16121
16223
  for (const id of result.createdThreadIds) {
16122
- await this.runSetupAfterCreate(id);
16224
+ void this.runSetupAfterCreate(id);
16123
16225
  }
16124
16226
  return { stack: result.stack, threads: result.threads };
16125
16227
  }
@@ -16136,7 +16238,7 @@ var Orchestrator = class {
16136
16238
  status: result.thread.status
16137
16239
  });
16138
16240
  if (result.createdWorktree) {
16139
- await this.runSetupAfterCreate(result.thread.id);
16241
+ void this.runSetupAfterCreate(result.thread.id);
16140
16242
  }
16141
16243
  return { stack: result.stack, thread: result.thread };
16142
16244
  }
@@ -16151,7 +16253,7 @@ var Orchestrator = class {
16151
16253
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
16152
16254
  }
16153
16255
  for (const id of result.createdThreadIds) {
16154
- await this.runSetupAfterCreate(id);
16256
+ void this.runSetupAfterCreate(id);
16155
16257
  }
16156
16258
  return { stack: result.stack, threads: result.threads };
16157
16259
  }
@@ -16162,7 +16264,7 @@ var Orchestrator = class {
16162
16264
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
16163
16265
  }
16164
16266
  for (const id of result.createdThreadIds) {
16165
- await this.runSetupAfterCreate(id);
16267
+ void this.runSetupAfterCreate(id);
16166
16268
  }
16167
16269
  return { stack: result.stack, threads: result.threads };
16168
16270
  }
@@ -16293,7 +16395,7 @@ var Orchestrator = class {
16293
16395
  async forkThreadWorktree(input) {
16294
16396
  const thread = await forkThreadWorktree(input);
16295
16397
  this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
16296
- await this.runSetupAfterCreate(thread.id);
16398
+ void this.runSetupAfterCreate(thread.id);
16297
16399
  return thread;
16298
16400
  }
16299
16401
  renameThread(threadRef, title) {
@@ -16396,7 +16498,7 @@ var Orchestrator = class {
16396
16498
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
16397
16499
  return restored2;
16398
16500
  }
16399
- if (!(0, import_node_fs36.existsSync)(thread.worktreePath)) {
16501
+ if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
16400
16502
  const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
16401
16503
  const { execa: execa7 } = await import("execa");
16402
16504
  const slug = thread.worktreePath.split("/").pop();
@@ -16501,7 +16603,7 @@ async function startOrchestration(opts) {
16501
16603
  planMode: opts.planMode,
16502
16604
  attachments: opts.attachments
16503
16605
  };
16504
- const thread = await createThread({
16606
+ const thread = await orch.createThread({
16505
16607
  sourceType: "branch",
16506
16608
  sourceRef: "default",
16507
16609
  ...createOpts
@@ -16509,7 +16611,7 @@ async function startOrchestration(opts) {
16509
16611
  const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
16510
16612
  const repo = await resolveRepoRoot2(repoPath);
16511
16613
  const def = await resolveDefaultBranch2(repo);
16512
- return createThread({
16614
+ return orch.createThread({
16513
16615
  sourceType: "branch",
16514
16616
  sourceRef: def,
16515
16617
  ...createOpts,
@@ -16637,7 +16739,7 @@ init_coordinator_prompt();
16637
16739
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
16638
16740
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
16639
16741
  var import_zod3 = require("zod");
16640
- var import_node_path32 = require("path");
16742
+ var import_node_path33 = require("path");
16641
16743
  init_worktree();
16642
16744
  init_global_workspace();
16643
16745
  init_list_models();
@@ -17315,7 +17417,7 @@ async function startMcpServer() {
17315
17417
  async () => {
17316
17418
  const threads = orch.getThreads(true);
17317
17419
  const lines = threads.map((t) => {
17318
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path32.basename)(t.repoPath) || t.repoPath;
17420
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path33.basename)(t.repoPath) || t.repoPath;
17319
17421
  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}` : ""}`;
17320
17422
  });
17321
17423
  return {
@@ -17526,7 +17628,7 @@ async function startMcpServer() {
17526
17628
  );
17527
17629
  server.tool(
17528
17630
  "create_thread",
17529
- `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.`,
17631
+ `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.`,
17530
17632
  {
17531
17633
  sourceType: import_zod3.z.enum(["branch", "pr", "ticket"]),
17532
17634
  sourceRef: import_zod3.z.string(),
@@ -18044,7 +18146,7 @@ async function startMcpServer() {
18044
18146
  );
18045
18147
  server.tool(
18046
18148
  "run_setup",
18047
- "Re-run workspace setup (Sideboard/Conductor settings or .cursor/worktrees.json)",
18149
+ "Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
18048
18150
  { ref: import_zod3.z.string() },
18049
18151
  async ({ ref }) => {
18050
18152
  const result = await orch.runSetup(ref);
@@ -19929,9 +20031,9 @@ var import_node_http3 = require("http");
19929
20031
  var import_ws3 = require("ws");
19930
20032
 
19931
20033
  // src/slack/relay-static.ts
19932
- var import_node_fs37 = require("fs");
20034
+ var import_node_fs38 = require("fs");
19933
20035
  var import_promises = require("fs/promises");
19934
- var import_node_path33 = __toESM(require("path"), 1);
20036
+ var import_node_path34 = __toESM(require("path"), 1);
19935
20037
  var TYPES = {
19936
20038
  ".css": "text/css; charset=utf-8",
19937
20039
  ".html": "text/html; charset=utf-8",
@@ -19962,9 +20064,9 @@ function resolveStaticPath(root, requestUrl) {
19962
20064
  return null;
19963
20065
  }
19964
20066
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
19965
- const rootResolved = import_node_path33.default.resolve(root);
19966
- const candidate = import_node_path33.default.resolve(rootResolved, `.${pathname}`);
19967
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path33.default.sep)) {
20067
+ const rootResolved = import_node_path34.default.resolve(root);
20068
+ const candidate = import_node_path34.default.resolve(rootResolved, `.${pathname}`);
20069
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path34.default.sep)) {
19968
20070
  return null;
19969
20071
  }
19970
20072
  return candidate;
@@ -19978,7 +20080,7 @@ async function fileSize(file) {
19978
20080
  }
19979
20081
  }
19980
20082
  function sendFile(req, res, file, size) {
19981
- const ext = import_node_path33.default.extname(file).toLowerCase();
20083
+ const ext = import_node_path34.default.extname(file).toLowerCase();
19982
20084
  res.writeHead(200, {
19983
20085
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
19984
20086
  "Content-Length": size,
@@ -19988,7 +20090,7 @@ function sendFile(req, res, file, size) {
19988
20090
  res.end();
19989
20091
  return true;
19990
20092
  }
19991
- (0, import_node_fs37.createReadStream)(file).pipe(res);
20093
+ (0, import_node_fs38.createReadStream)(file).pipe(res);
19992
20094
  return true;
19993
20095
  }
19994
20096
  async function tryServeStatic(req, res, root) {
@@ -19997,7 +20099,7 @@ async function tryServeStatic(req, res, root) {
19997
20099
  if (!candidate) return false;
19998
20100
  const direct = await fileSize(candidate);
19999
20101
  if (direct != null) return sendFile(req, res, candidate, direct);
20000
- const asIndex = import_node_path33.default.join(candidate, "index.html");
20102
+ const asIndex = import_node_path34.default.join(candidate, "index.html");
20001
20103
  const indexSize = await fileSize(asIndex);
20002
20104
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
20003
20105
  return false;
@@ -20229,6 +20331,7 @@ async function startSlackRelayServer(opts) {
20229
20331
  CONTEXT_KEEP_RECENT_CHARS,
20230
20332
  CONTEXT_KEEP_RECENT_MESSAGES,
20231
20333
  CONTEXT_MIN_MESSAGES,
20334
+ CONVENTION_SETUP_RELPATHS,
20232
20335
  COORDINATOR_TOOL_PLAYBOOK,
20233
20336
  FAMOUS_SOCCER_TEAMS,
20234
20337
  GITHUB_GIT_AUTH_MODES,
@@ -20390,6 +20493,7 @@ async function startSlackRelayServer(opts) {
20390
20493
  extractiveSummary,
20391
20494
  fetchPrHead,
20392
20495
  finalizeParts,
20496
+ findConventionSetup,
20393
20497
  findInvalidCacheControlTtlOrder,
20394
20498
  findOrphanWorktrees,
20395
20499
  findThreadByRef,
@@ -20461,6 +20565,7 @@ async function startSlackRelayServer(opts) {
20461
20565
  hasBakedLinearOAuth,
20462
20566
  hasBakedSlackOAuth,
20463
20567
  hasConductorHook,
20568
+ hasConventionSetup,
20464
20569
  hasCursorWorktreeSetup,
20465
20570
  hasRepoHook,
20466
20571
  hasWorkspaceHook,
@@ -20636,10 +20741,12 @@ async function startSlackRelayServer(opts) {
20636
20741
  run,
20637
20742
  runArchiveScript,
20638
20743
  runCloudConnect,
20744
+ runConventionSetup,
20639
20745
  runCursorWorktreeSetup,
20640
20746
  runSetupScript,
20641
20747
  runSlackListen,
20642
20748
  runSlackRelayClient,
20749
+ runWorkspaceSetup,
20643
20750
  sameWorktreePath,
20644
20751
  sanitizeMcpServerName,
20645
20752
  saveAppSettings,