@sideboard-ai/core 0.1.86 → 0.1.88

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 (52) hide show
  1. package/dist/agents/cursor-runner.cjs +23 -13
  2. package/dist/agents/cursor-runner.js +2 -2
  3. package/dist/{agents-NDHD3VOL.js → agents-LMUFTGKF.js} +8 -8
  4. package/dist/{agents-HJ3Y2JN5.js → agents-ODBP7J6E.js} +9 -9
  5. package/dist/{app-settings-K6RFCRF6.js → app-settings-BRF7VKTQ.js} +3 -3
  6. package/dist/{app-settings-PEXK5VEX.js → app-settings-ZXPAB3QN.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-FWJYLBO6.js → chunk-3WA37BRI.js} +1 -1
  10. package/dist/{chunk-IGEL6M4G.js → chunk-6EZRSCIT.js} +3 -3
  11. package/dist/{chunk-AY53MPDE.js → chunk-6LFV4VFI.js} +15 -2
  12. package/dist/{chunk-OBHZKT2T.js → chunk-7D27DD2X.js} +3 -3
  13. package/dist/{chunk-RV6DBEDQ.js → chunk-7KDBDMNC.js} +1 -1
  14. package/dist/{chunk-U4RZ3IQI.js → chunk-B2KIO2SD.js} +5 -5
  15. package/dist/{chunk-M37RITA6.js → chunk-B4R2VB2A.js} +164 -30
  16. package/dist/{chunk-6K5VAPVR.js → chunk-DKHGWYWR.js} +1 -1
  17. package/dist/{chunk-I3FRXL7J.js → chunk-FT2SQOL4.js} +2 -2
  18. package/dist/{chunk-KE6QLNTJ.js → chunk-JE75QW2I.js} +58 -24
  19. package/dist/{chunk-7MV3RXSC.js → chunk-JL4SJ6V7.js} +137 -26
  20. package/dist/{chunk-7FD7COKE.js → chunk-JOF3XIEM.js} +1 -1
  21. package/dist/{chunk-MFF2RE3I.js → chunk-NZPGMNFC.js} +1 -1
  22. package/dist/{chunk-HA2QTIWN.js → chunk-OB6IRIFV.js} +5 -5
  23. package/dist/{chunk-HHTHF5BQ.js → chunk-QSLE4VEM.js} +4 -4
  24. package/dist/{chunk-4Y745GLN.js → chunk-RJLBSYUO.js} +59 -25
  25. package/dist/{chunk-5KLC2MWZ.js → chunk-TLPJHLLM.js} +14 -1
  26. package/dist/{chunk-EWKHP6DD.js → chunk-UHTNJKZX.js} +5 -5
  27. package/dist/{chunk-ZN4NDAHV.js → chunk-VZ2L4AEJ.js} +5 -5
  28. package/dist/{chunk-45U4RQ74.js → chunk-WANQFU3S.js} +3 -3
  29. package/dist/{chunk-6ZGTM2E7.js → chunk-ZXYWWSHZ.js} +3 -3
  30. package/dist/{connected-teams-BNBM7OIC.js → connected-teams-SWHJWK2A.js} +2 -2
  31. package/dist/{connected-teams-LSQ5TAZP.js → connected-teams-TLVKZPJP.js} +2 -2
  32. package/dist/{coordinator-prompt-L65MIGCV.js → coordinator-prompt-CI5SHONJ.js} +5 -5
  33. package/dist/{coordinator-prompt-HOMHBR2L.js → coordinator-prompt-UK5LYFN5.js} +6 -6
  34. package/dist/{cursor-recover-L5PNQUDT.js → cursor-recover-G34BYKL2.js} +1 -1
  35. package/dist/{cursor-recover-NNK7JPQM.js → cursor-recover-S5ORPW34.js} +1 -1
  36. package/dist/{global-workspace-MXOLTUAR.js → global-workspace-2YZ2V4I5.js} +6 -6
  37. package/dist/{global-workspace-VGKPYFE2.js → global-workspace-JQQLPJM5.js} +7 -7
  38. package/dist/index.cjs +693 -541
  39. package/dist/index.d.cts +43 -9
  40. package/dist/index.d.ts +43 -9
  41. package/dist/index.js +213 -253
  42. package/dist/mcp/run-stdio.cjs +630 -505
  43. package/dist/mcp/run-stdio.js +184 -225
  44. package/dist/{paths-VPH3ITBK.js → paths-JQM2XRAD.js} +1 -1
  45. package/dist/{paths-2OFB7UJG.js → paths-TZX4L5X7.js} +1 -1
  46. package/dist/{thread-store-BUBR24YA.js → thread-store-V7NOOXKE.js} +2 -2
  47. package/dist/{thread-store-XTPFCJAI.js → thread-store-XAKWCV2E.js} +2 -2
  48. package/dist/{workspaces-VWQ5YSND.js → workspaces-FDO5L4NI.js} +7 -7
  49. package/dist/{workspaces-2GZ2VNNU.js → workspaces-YWCC3WV4.js} +8 -8
  50. package/dist/{worktree-RFCCG23P.js → worktree-4555QBQ7.js} +4 -4
  51. package/dist/{worktree-WZJ3CFEN.js → worktree-7YNSJ224.js} +5 -5
  52. package/package.json +1 -1
@@ -57,6 +57,18 @@ function wrapElectronAsNodeLaunch(file, args) {
57
57
  function isStrippedElectronLaunch(command, args) {
58
58
  return command === "/bin/sh" && Boolean(args?.[1]?.includes("ELECTRON_RUN_AS_NODE") && args[1].includes("unset"));
59
59
  }
60
+ function isElectronLikeCommand(command) {
61
+ const name = command.trim();
62
+ if (!name) return false;
63
+ if (process.versions.electron && name === process.execPath) return true;
64
+ return /(?:^|[/\\])Electron(?:\.exe)?$/i.test(name) || /Sideboard\.app[/\\]/i.test(name) || /Electron\.app[/\\]/i.test(name);
65
+ }
66
+ function unwrapStrippedElectronLaunch(command, args) {
67
+ if (!isStrippedElectronLaunch(command, args) || !args || args.length < 4) {
68
+ return null;
69
+ }
70
+ return { file: args[3], args: args.slice(4) };
71
+ }
60
72
  var NESTED_ELECTRON_ENV_PREFIXES, STRIP_NESTED_ELECTRON_THEN_EXEC;
61
73
  var init_nested_electron_env = __esm({
62
74
  "src/hook/nested-electron-env.ts"() {
@@ -71,10 +83,129 @@ var init_nested_electron_env = __esm({
71
83
  }
72
84
  });
73
85
 
86
+ // src/hook/convention-setup.ts
87
+ function isFile(path) {
88
+ try {
89
+ return (0, import_node_fs.statSync)(path).isFile();
90
+ } catch {
91
+ return false;
92
+ }
93
+ }
94
+ function normPath(p) {
95
+ return p.replace(/\/+$/, "");
96
+ }
97
+ function findConventionSetup(worktreePath, repoPath) {
98
+ const roots = [
99
+ { root: worktreePath, where: "worktree" }
100
+ ];
101
+ if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
102
+ roots.push({ root: repoPath, where: "main repo" });
103
+ }
104
+ for (const { root, where } of roots) {
105
+ for (const relPath of CONVENTION_SETUP_RELPATHS) {
106
+ const absPath = (0, import_node_path.join)(root, relPath);
107
+ if (!(0, import_node_fs.existsSync)(absPath) || !isFile(absPath)) continue;
108
+ return {
109
+ relPath,
110
+ absPath,
111
+ command: `bash ${JSON.stringify(absPath)}`,
112
+ source: `${relPath} (${where})`
113
+ };
114
+ }
115
+ }
116
+ return null;
117
+ }
118
+ var import_node_fs, import_node_path, CONVENTION_SETUP_RELPATHS;
119
+ var init_convention_setup = __esm({
120
+ "src/hook/convention-setup.ts"() {
121
+ "use strict";
122
+ import_node_fs = require("fs");
123
+ import_node_path = require("path");
124
+ CONVENTION_SETUP_RELPATHS = [
125
+ "script/setup",
126
+ "bin/setup",
127
+ "scripts/setup.sh",
128
+ "scripts/setup"
129
+ ];
130
+ }
131
+ });
132
+
133
+ // src/hook/cursor-worktrees.ts
134
+ function loadCursorWorktreesJson(rootPath) {
135
+ const path = (0, import_node_path2.join)(rootPath, ".cursor", "worktrees.json");
136
+ if (!(0, import_node_fs2.existsSync)(path)) return null;
137
+ try {
138
+ return JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
139
+ } catch {
140
+ return null;
141
+ }
142
+ }
143
+ function resolveSetupSpec(config) {
144
+ if (process.platform === "win32") {
145
+ return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
146
+ }
147
+ return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
148
+ }
149
+ async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
150
+ const fromWorktree = loadCursorWorktreesJson(worktreePath);
151
+ const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
152
+ const config = fromWorktree ?? fromRepo;
153
+ if (!config) return { ran: false, exitCode: null, source: null };
154
+ const spec = resolveSetupSpec(config);
155
+ if (!spec) return { ran: false, exitCode: null, source: null };
156
+ const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
157
+ const env = {
158
+ ...process.env,
159
+ ROOT_WORKTREE_PATH: repoPath
160
+ };
161
+ if (process.platform === "win32") {
162
+ env.ROOT_WORKTREE_PATH = repoPath;
163
+ }
164
+ const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path2.join)(
165
+ fromWorktree ? worktreePath : repoPath,
166
+ ".cursor",
167
+ spec
168
+ ) : spec];
169
+ let lastExit = 0;
170
+ for (const command of commands) {
171
+ const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
172
+ const shell = process.platform === "win32" ? "powershell" : "bash";
173
+ const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
174
+ onLine?.(`[cursor setup] ${command}`);
175
+ const child = (0, import_execa.execa)(shell, args, {
176
+ cwd: worktreePath,
177
+ reject: false,
178
+ env
179
+ });
180
+ if (child.stdout && onLine) {
181
+ const rl = (0, import_node_readline.createInterface)({ input: child.stdout });
182
+ rl.on("line", onLine);
183
+ }
184
+ if (child.stderr && onLine) {
185
+ const rl = (0, import_node_readline.createInterface)({ input: child.stderr });
186
+ rl.on("line", onLine);
187
+ }
188
+ const result = await child;
189
+ lastExit = result.exitCode ?? null;
190
+ if (lastExit !== 0 && lastExit !== null) break;
191
+ }
192
+ return { ran: true, exitCode: lastExit, source: sourceLabel };
193
+ }
194
+ var import_node_fs2, import_node_path2, import_execa, import_node_readline;
195
+ var init_cursor_worktrees = __esm({
196
+ "src/hook/cursor-worktrees.ts"() {
197
+ "use strict";
198
+ import_node_fs2 = require("fs");
199
+ import_node_path2 = require("path");
200
+ import_execa = require("execa");
201
+ import_node_readline = require("readline");
202
+ }
203
+ });
204
+
74
205
  // src/hook/settings.ts
75
206
  function expandHome(path) {
76
207
  if (path.startsWith("~/") || path === "~") {
77
- return (0, import_node_path.join)((0, import_node_os.homedir)(), path.slice(2));
208
+ return (0, import_node_path3.join)((0, import_node_os.homedir)(), path.slice(2));
78
209
  }
79
210
  return path;
80
211
  }
@@ -87,8 +218,8 @@ function parseAvailableIn(raw) {
87
218
  return out.length ? out : void 0;
88
219
  }
89
220
  function parseSettingsFile(path, source) {
90
- if (!(0, import_node_fs.existsSync)(path)) return null;
91
- const raw = (0, import_node_fs.readFileSync)(path, "utf8");
221
+ if (!(0, import_node_fs3.existsSync)(path)) return null;
222
+ const raw = (0, import_node_fs3.readFileSync)(path, "utf8");
92
223
  const data = (0, import_smol_toml.parse)(raw);
93
224
  const scripts = data.scripts ?? {};
94
225
  const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
@@ -191,15 +322,15 @@ function finalizeSettings(parsed) {
191
322
  };
192
323
  }
193
324
  function familyFiles(rootPath, source) {
194
- const dir = (0, import_node_path.join)(rootPath, `.${source}`);
325
+ const dir = (0, import_node_path3.join)(rootPath, `.${source}`);
195
326
  return {
196
- toml: (0, import_node_path.join)(dir, "settings.toml"),
197
- local: (0, import_node_path.join)(dir, "settings.local.toml")
327
+ toml: (0, import_node_path3.join)(dir, "settings.toml"),
328
+ local: (0, import_node_path3.join)(dir, "settings.local.toml")
198
329
  };
199
330
  }
200
331
  function familyExists(rootPath, source) {
201
332
  const files = familyFiles(rootPath, source);
202
- return (0, import_node_fs.existsSync)(files.toml) || (0, import_node_fs.existsSync)(files.local);
333
+ return (0, import_node_fs3.existsSync)(files.toml) || (0, import_node_fs3.existsSync)(files.local);
203
334
  }
204
335
  function detectFamily(rootPath) {
205
336
  if (familyExists(rootPath, "sideboard")) return "sideboard";
@@ -218,7 +349,7 @@ function loadAnyLocal(rootPath) {
218
349
  loadLocalToml(rootPath, "sideboard")
219
350
  );
220
351
  }
221
- function normPath(p) {
352
+ function normPath2(p) {
222
353
  return p.replace(/\/+$/, "");
223
354
  }
224
355
  function loadRepoSettings(repoPath) {
@@ -232,11 +363,11 @@ function loadRepoSettings(repoPath) {
232
363
  }
233
364
  function loadWorkspaceSettings(worktreePath, repoPath) {
234
365
  const wtFamily = detectFamily(worktreePath);
235
- const repoFamily = repoPath && normPath(repoPath) !== normPath(worktreePath) ? detectFamily(repoPath) : null;
366
+ const repoFamily = repoPath && normPath2(repoPath) !== normPath2(worktreePath) ? detectFamily(repoPath) : null;
236
367
  const wtToml = wtFamily ? loadCommittedToml(worktreePath, wtFamily) : null;
237
368
  const repoToml = repoPath && repoFamily ? loadCommittedToml(repoPath, repoFamily) : null;
238
369
  let merged = wtToml ?? repoToml;
239
- if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
370
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
240
371
  merged = mergeSettings(merged, loadAnyLocal(repoPath));
241
372
  }
242
373
  merged = mergeSettings(merged, loadAnyLocal(worktreePath));
@@ -246,29 +377,31 @@ function settingsSourceLabel(rootPath) {
246
377
  const family = detectFamily(rootPath);
247
378
  if (!family) return null;
248
379
  const files = familyFiles(rootPath, family);
249
- if ((0, import_node_fs.existsSync)(files.toml) && (0, import_node_fs.existsSync)(files.local)) {
380
+ if ((0, import_node_fs3.existsSync)(files.toml) && (0, import_node_fs3.existsSync)(files.local)) {
250
381
  return `.${family}/settings.toml + local`;
251
382
  }
252
- if ((0, import_node_fs.existsSync)(files.local)) return `.${family}/settings.local.toml`;
383
+ if ((0, import_node_fs3.existsSync)(files.local)) return `.${family}/settings.local.toml`;
253
384
  return `.${family}/settings.toml`;
254
385
  }
255
386
  function workspaceSettingsSourceLabel(worktreePath, repoPath) {
256
387
  const wt = settingsSourceLabel(worktreePath);
257
388
  if (wt) return `${wt} (worktree)`;
258
- if (repoPath && normPath(repoPath) !== normPath(worktreePath)) {
389
+ if (repoPath && normPath2(repoPath) !== normPath2(worktreePath)) {
259
390
  const repo = settingsSourceLabel(repoPath);
260
391
  if (repo) return `${repo} (main repo)`;
261
392
  }
262
393
  return null;
263
394
  }
264
- var import_node_fs, import_node_os, import_node_path, import_smol_toml;
395
+ var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
265
396
  var init_settings = __esm({
266
397
  "src/hook/settings.ts"() {
267
398
  "use strict";
268
- import_node_fs = require("fs");
399
+ import_node_fs3 = require("fs");
269
400
  import_node_os = require("os");
270
- import_node_path = require("path");
401
+ import_node_path3 = require("path");
271
402
  import_smol_toml = require("smol-toml");
403
+ init_convention_setup();
404
+ init_cursor_worktrees();
272
405
  }
273
406
  });
274
407
 
@@ -289,89 +422,89 @@ __export(paths_exports, {
289
422
  });
290
423
  function appDataDir() {
291
424
  const override = process.env.SIDEBOARD_APP_DATA?.trim();
292
- const base = override ? override : process.platform === "darwin" ? (0, import_node_path3.join)((0, import_node_os2.homedir)(), "Library", "Application Support", "sideboard") : process.platform === "win32" ? (0, import_node_path3.join)(process.env.APPDATA ?? (0, import_node_path3.join)((0, import_node_os2.homedir)(), "AppData", "Roaming"), "sideboard") : (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".local", "share", "sideboard");
293
- (0, import_node_fs2.mkdirSync)(base, { recursive: true });
425
+ 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");
426
+ (0, import_node_fs4.mkdirSync)(base, { recursive: true });
294
427
  return base;
295
428
  }
296
429
  function threadsDir() {
297
- const dir = (0, import_node_path3.join)(appDataDir(), "threads");
298
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
430
+ const dir = (0, import_node_path5.join)(appDataDir(), "threads");
431
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
299
432
  return dir;
300
433
  }
301
434
  function locksDir() {
302
- const dir = (0, import_node_path3.join)(appDataDir(), "locks");
303
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
435
+ const dir = (0, import_node_path5.join)(appDataDir(), "locks");
436
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
304
437
  return dir;
305
438
  }
306
439
  function sideboardHomeDir() {
307
- const dir = (0, import_node_path3.join)((0, import_node_os2.homedir)(), "sideboard");
308
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
440
+ const dir = (0, import_node_path5.join)((0, import_node_os2.homedir)(), "sideboard");
441
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
309
442
  return dir;
310
443
  }
311
444
  function sideboardReposDir() {
312
- const dir = (0, import_node_path3.join)(sideboardHomeDir(), "repos");
313
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
445
+ const dir = (0, import_node_path5.join)(sideboardHomeDir(), "repos");
446
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
314
447
  return dir;
315
448
  }
316
449
  function sideboardWorkspacesDir() {
317
- const dir = (0, import_node_path3.join)(sideboardHomeDir(), "workspaces");
318
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
450
+ const dir = (0, import_node_path5.join)(sideboardHomeDir(), "workspaces");
451
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
319
452
  return dir;
320
453
  }
321
454
  function repoSlug(repoPath) {
322
- return (0, import_node_path2.basename)(repoPath.replace(/\/$/, "")) || "repo";
455
+ return (0, import_node_path4.basename)(repoPath.replace(/\/$/, "")) || "repo";
323
456
  }
324
457
  function worktreesRoot(repoPath) {
325
458
  const settings = loadRepoSettings(repoPath);
326
459
  if (settings?.worktreesRoot) {
327
- (0, import_node_fs2.mkdirSync)(settings.worktreesRoot, { recursive: true });
460
+ (0, import_node_fs4.mkdirSync)(settings.worktreesRoot, { recursive: true });
328
461
  return settings.worktreesRoot;
329
462
  }
330
- const dir = (0, import_node_path3.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
331
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
463
+ const dir = (0, import_node_path5.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
464
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
332
465
  return dir;
333
466
  }
334
467
  function threadFilePath(id) {
335
- return (0, import_node_path3.join)(threadsDir(), `${id}.json`);
468
+ return (0, import_node_path5.join)(threadsDir(), `${id}.json`);
336
469
  }
337
470
  function threadLockPath(id) {
338
- return (0, import_node_path3.join)(locksDir(), `${id}.lock`);
471
+ return (0, import_node_path5.join)(locksDir(), `${id}.lock`);
339
472
  }
340
473
  function globalAgentCwd() {
341
- const dir = (0, import_node_path3.join)(appDataDir(), "global");
342
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true });
474
+ const dir = (0, import_node_path5.join)(appDataDir(), "global");
475
+ (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
343
476
  return dir;
344
477
  }
345
- var import_node_path2, import_node_os2, import_node_path3, import_node_fs2;
478
+ var import_node_path4, import_node_os2, import_node_path5, import_node_fs4;
346
479
  var init_paths = __esm({
347
480
  "src/store/paths.ts"() {
348
481
  "use strict";
349
- import_node_path2 = require("path");
482
+ import_node_path4 = require("path");
350
483
  import_node_os2 = require("os");
351
- import_node_path3 = require("path");
352
- import_node_fs2 = require("fs");
484
+ import_node_path5 = require("path");
485
+ import_node_fs4 = require("fs");
353
486
  init_settings();
354
487
  }
355
488
  });
356
489
 
357
490
  // src/store/private-file.ts
358
491
  function writePrivateFile(path, contents) {
359
- (0, import_node_fs3.mkdirSync)((0, import_node_path4.dirname)(path), { recursive: true });
360
- (0, import_node_fs3.writeFileSync)(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
492
+ (0, import_node_fs5.mkdirSync)((0, import_node_path6.dirname)(path), { recursive: true });
493
+ (0, import_node_fs5.writeFileSync)(path, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
361
494
  chmodOwnerOnly(path);
362
495
  }
363
496
  function chmodOwnerOnly(path) {
364
497
  try {
365
- (0, import_node_fs3.chmodSync)(path, PRIVATE_FILE_MODE);
498
+ (0, import_node_fs5.chmodSync)(path, PRIVATE_FILE_MODE);
366
499
  } catch {
367
500
  }
368
501
  }
369
- var import_node_fs3, import_node_path4, PRIVATE_FILE_MODE;
502
+ var import_node_fs5, import_node_path6, PRIVATE_FILE_MODE;
370
503
  var init_private_file = __esm({
371
504
  "src/store/private-file.ts"() {
372
505
  "use strict";
373
- import_node_fs3 = require("fs");
374
- import_node_path4 = require("path");
506
+ import_node_fs5 = require("fs");
507
+ import_node_path6 = require("path");
375
508
  PRIVATE_FILE_MODE = 384;
376
509
  }
377
510
  });
@@ -457,11 +590,11 @@ function decryptEnvelope(envelope, key) {
457
590
  return JSON.parse(plaintext.toString("utf8"));
458
591
  }
459
592
  function readSecureJson(path) {
460
- if (!(0, import_node_fs4.existsSync)(path)) return null;
593
+ if (!(0, import_node_fs6.existsSync)(path)) return null;
461
594
  chmodOwnerOnly(path);
462
595
  let parsed;
463
596
  try {
464
- parsed = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8"));
597
+ parsed = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
465
598
  } catch {
466
599
  return null;
467
600
  }
@@ -481,20 +614,20 @@ function writeSecureJson(path, value) {
481
614
  `);
482
615
  }
483
616
  function isSecureFileEncrypted(path) {
484
- if (!(0, import_node_fs4.existsSync)(path)) return false;
617
+ if (!(0, import_node_fs6.existsSync)(path)) return false;
485
618
  try {
486
- return isEnvelope(JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8")));
619
+ return isEnvelope(JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8")));
487
620
  } catch {
488
621
  return false;
489
622
  }
490
623
  }
491
- var import_node_child_process, import_node_crypto, import_node_fs4, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
624
+ var import_node_child_process, import_node_crypto, import_node_fs6, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
492
625
  var init_secure_file = __esm({
493
626
  "src/store/secure-file.ts"() {
494
627
  "use strict";
495
628
  import_node_child_process = require("child_process");
496
629
  import_node_crypto = require("crypto");
497
- import_node_fs4 = require("fs");
630
+ import_node_fs6 = require("fs");
498
631
  init_private_file();
499
632
  KEYCHAIN_SERVICE = "ai.sideboard.app";
500
633
  KEYCHAIN_ACCOUNT = "secret-vault-v1";
@@ -598,7 +731,7 @@ function createEmptyThread(partial) {
598
731
  }
599
732
  async function withThreadLock(id, fn) {
600
733
  const lockPath = threadLockPath(id);
601
- (0, import_node_fs5.writeFileSync)(lockPath, "", { flag: "a" });
734
+ (0, import_node_fs7.writeFileSync)(lockPath, "", { flag: "a" });
602
735
  let release;
603
736
  try {
604
737
  release = await import_proper_lockfile.default.lock(lockPath, {
@@ -612,26 +745,26 @@ async function withThreadLock(id, fn) {
612
745
  }
613
746
  function readThread(id) {
614
747
  const path = threadFilePath(id);
615
- if (!(0, import_node_fs5.existsSync)(path)) return null;
616
- const raw = (0, import_node_fs5.readFileSync)(path, "utf8");
748
+ if (!(0, import_node_fs7.existsSync)(path)) return null;
749
+ const raw = (0, import_node_fs7.readFileSync)(path, "utf8");
617
750
  return normalizeThread(JSON.parse(raw));
618
751
  }
619
752
  function writeThread(thread) {
620
753
  const path = threadFilePath(idPath(thread.id));
621
754
  const tmp = `${path}.${process.pid}.tmp`;
622
755
  const next = { ...thread, updatedAt: nowIso() };
623
- (0, import_node_fs5.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
624
- (0, import_node_fs5.renameSync)(tmp, path);
756
+ (0, import_node_fs7.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
757
+ (0, import_node_fs7.renameSync)(tmp, path);
625
758
  }
626
759
  function idPath(id) {
627
760
  return id;
628
761
  }
629
762
  function listThreads(opts) {
630
- const files = (0, import_node_fs5.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
763
+ const files = (0, import_node_fs7.readdirSync)(threadsDir()).filter((f) => f.endsWith(".json"));
631
764
  const threads = files.map((f) => {
632
765
  try {
633
766
  return normalizeThread(
634
- JSON.parse((0, import_node_fs5.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
767
+ JSON.parse((0, import_node_fs7.readFileSync)(threadFilePath(f.replace(/\.json$/, "")), "utf8"))
635
768
  );
636
769
  } catch {
637
770
  return null;
@@ -642,11 +775,11 @@ function listThreads(opts) {
642
775
  }
643
776
  function deleteThreadRecord(id) {
644
777
  const path = threadFilePath(id);
645
- if ((0, import_node_fs5.existsSync)(path)) (0, import_node_fs5.unlinkSync)(path);
778
+ if ((0, import_node_fs7.existsSync)(path)) (0, import_node_fs7.unlinkSync)(path);
646
779
  const lock = threadLockPath(id);
647
- if ((0, import_node_fs5.existsSync)(lock)) {
780
+ if ((0, import_node_fs7.existsSync)(lock)) {
648
781
  try {
649
- (0, import_node_fs5.unlinkSync)(lock);
782
+ (0, import_node_fs7.unlinkSync)(lock);
650
783
  } catch {
651
784
  }
652
785
  }
@@ -670,12 +803,12 @@ function findThreadByRef(ref) {
670
803
  const all = listThreads({ includeArchived: true });
671
804
  return all.find((t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref) ?? null;
672
805
  }
673
- var import_node_crypto2, import_node_fs5, import_proper_lockfile;
806
+ var import_node_crypto2, import_node_fs7, import_proper_lockfile;
674
807
  var init_thread_store = __esm({
675
808
  "src/store/thread-store.ts"() {
676
809
  "use strict";
677
810
  import_node_crypto2 = require("crypto");
678
- import_node_fs5 = require("fs");
811
+ import_node_fs7 = require("fs");
679
812
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
680
813
  init_thinking_effort();
681
814
  init_paths();
@@ -1734,7 +1867,7 @@ var init_gh_errors = __esm({
1734
1867
 
1735
1868
  // src/store/secret-vault.ts
1736
1869
  function secretVaultPath() {
1737
- return (0, import_node_path8.join)(appDataDir(), "secrets.json");
1870
+ return (0, import_node_path10.join)(appDataDir(), "secrets.json");
1738
1871
  }
1739
1872
  function loadSecretVault() {
1740
1873
  const parsed = readSecureJson(secretVaultPath());
@@ -1778,11 +1911,11 @@ function normalizeVault(raw) {
1778
1911
  }
1779
1912
  return out;
1780
1913
  }
1781
- var import_node_path8;
1914
+ var import_node_path10;
1782
1915
  var init_secret_vault = __esm({
1783
1916
  "src/store/secret-vault.ts"() {
1784
1917
  "use strict";
1785
- import_node_path8 = require("path");
1918
+ import_node_path10 = require("path");
1786
1919
  init_paths();
1787
1920
  init_secure_file();
1788
1921
  }
@@ -1883,10 +2016,10 @@ function toPublicAppSettings(settings) {
1883
2016
  };
1884
2017
  }
1885
2018
  function appSettingsPath() {
1886
- return (0, import_node_path9.join)(appDataDir(), "settings.json");
2019
+ return (0, import_node_path11.join)(appDataDir(), "settings.json");
1887
2020
  }
1888
2021
  function claudeUserSettingsPath() {
1889
- return (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
2022
+ return (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
1890
2023
  }
1891
2024
  function normalizeClaude(raw) {
1892
2025
  if (!raw || typeof raw !== "object") return {};
@@ -2129,10 +2262,10 @@ function normalizeSettings(raw) {
2129
2262
  }
2130
2263
  function readSettingsFile() {
2131
2264
  const path = appSettingsPath();
2132
- if (!(0, import_node_fs8.existsSync)(path)) return { ...EMPTY_SETTINGS };
2265
+ if (!(0, import_node_fs10.existsSync)(path)) return { ...EMPTY_SETTINGS };
2133
2266
  try {
2134
2267
  chmodOwnerOnly(path);
2135
- const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
2268
+ const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf8"));
2136
2269
  return normalizeSettings(parsed);
2137
2270
  } catch {
2138
2271
  return { ...EMPTY_SETTINGS };
@@ -2692,14 +2825,14 @@ function childEnvWithAppSettings(extra) {
2692
2825
  function harnessEnvKey(harness) {
2693
2826
  return HARNESS_ENV_KEYS[harness];
2694
2827
  }
2695
- var import_node_crypto3, import_node_fs8, import_node_os3, import_node_path9, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
2828
+ var import_node_crypto3, import_node_fs10, import_node_os3, import_node_path11, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, DEFAULT_CLI_BIN;
2696
2829
  var init_app_settings = __esm({
2697
2830
  "src/store/app-settings.ts"() {
2698
2831
  "use strict";
2699
2832
  import_node_crypto3 = require("crypto");
2700
- import_node_fs8 = require("fs");
2833
+ import_node_fs10 = require("fs");
2701
2834
  import_node_os3 = require("os");
2702
- import_node_path9 = require("path");
2835
+ import_node_path11 = require("path");
2703
2836
  init_thinking_effort();
2704
2837
  init_nested_electron_env();
2705
2838
  init_paths();
@@ -2749,17 +2882,17 @@ var init_app_settings = __esm({
2749
2882
 
2750
2883
  // src/agents/path.ts
2751
2884
  function prependPathDir(env, dir) {
2752
- if (!dir || !(0, import_node_fs9.existsSync)(dir)) return;
2885
+ if (!dir || !(0, import_node_fs11.existsSync)(dir)) return;
2753
2886
  const current = env.PATH ?? "";
2754
- const parts = current.split(import_node_path10.delimiter).filter(Boolean);
2887
+ const parts = current.split(import_node_path12.delimiter).filter(Boolean);
2755
2888
  if (parts.includes(dir)) {
2756
2889
  env.PATH = current;
2757
2890
  return;
2758
2891
  }
2759
- env.PATH = [dir, ...parts].join(import_node_path10.delimiter);
2892
+ env.PATH = [dir, ...parts].join(import_node_path12.delimiter);
2760
2893
  }
2761
2894
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
2762
- return (0, import_node_path10.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
2895
+ return (0, import_node_path12.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
2763
2896
  }
2764
2897
  function isConductorBundledCli(filePath) {
2765
2898
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -2768,21 +2901,21 @@ function isConductorBundledCli(filePath) {
2768
2901
  function ensureAgentPath(env = process.env) {
2769
2902
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
2770
2903
  const current = env.PATH ?? "";
2771
- const parts = current.split(import_node_path10.delimiter).filter(Boolean);
2904
+ const parts = current.split(import_node_path12.delimiter).filter(Boolean);
2772
2905
  const seen = new Set(parts);
2773
2906
  const extras = [
2774
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path10.join)(home, rel)),
2907
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path12.join)(home, rel)),
2775
2908
  "/opt/homebrew/bin",
2776
2909
  "/usr/local/bin",
2777
2910
  // Keep after Homebrew/npm so a user-installed CLI still wins.
2778
2911
  conductorBundledBinDir(home)
2779
2912
  ];
2780
2913
  for (const dir of extras.reverse()) {
2781
- if (!dir || seen.has(dir) || !(0, import_node_fs9.existsSync)(dir)) continue;
2914
+ if (!dir || seen.has(dir) || !(0, import_node_fs11.existsSync)(dir)) continue;
2782
2915
  parts.unshift(dir);
2783
2916
  seen.add(dir);
2784
2917
  }
2785
- const next = parts.join(import_node_path10.delimiter);
2918
+ const next = parts.join(import_node_path12.delimiter);
2786
2919
  env.PATH = next;
2787
2920
  return next;
2788
2921
  }
@@ -2796,7 +2929,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
2796
2929
  stdio: ["ignore", "pipe", "ignore"]
2797
2930
  }).trim().split(/\r?\n/).find(Boolean);
2798
2931
  if (prefix) {
2799
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path10.join)(prefix, "bin");
2932
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path12.join)(prefix, "bin");
2800
2933
  prependPathDir(env, binDir);
2801
2934
  }
2802
2935
  } catch {
@@ -2824,14 +2957,14 @@ function withExportedPath(command, pathValue) {
2824
2957
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
2825
2958
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
2826
2959
  }
2827
- var import_node_fs9, import_node_child_process2, import_node_os4, import_node_path10, EXTRA_BIN_DIRS;
2960
+ var import_node_fs11, import_node_child_process2, import_node_os4, import_node_path12, EXTRA_BIN_DIRS;
2828
2961
  var init_path = __esm({
2829
2962
  "src/agents/path.ts"() {
2830
2963
  "use strict";
2831
- import_node_fs9 = require("fs");
2964
+ import_node_fs11 = require("fs");
2832
2965
  import_node_child_process2 = require("child_process");
2833
2966
  import_node_os4 = require("os");
2834
- import_node_path10 = require("path");
2967
+ import_node_path12 = require("path");
2835
2968
  EXTRA_BIN_DIRS = [
2836
2969
  ".local/bin",
2837
2970
  ".cargo/bin",
@@ -2859,7 +2992,7 @@ __export(run_exports, {
2859
2992
  async function run(file, args, opts) {
2860
2993
  ensureAgentPath();
2861
2994
  try {
2862
- const result = await (0, import_execa.execa)(file, args, {
2995
+ const result = await (0, import_execa2.execa)(file, args, {
2863
2996
  cwd: opts?.cwd,
2864
2997
  env: { ...process.env, ...opts?.env },
2865
2998
  reject: opts?.reject ?? true,
@@ -2923,11 +3056,11 @@ async function resolveGhAuthToken(cwd) {
2923
3056
  const token = result.stdout.trim();
2924
3057
  return token || null;
2925
3058
  }
2926
- var import_execa;
3059
+ var import_execa2;
2927
3060
  var init_run = __esm({
2928
3061
  "src/git/run.ts"() {
2929
3062
  "use strict";
2930
- import_execa = require("execa");
3063
+ import_execa2 = require("execa");
2931
3064
  init_path();
2932
3065
  }
2933
3066
  });
@@ -4122,8 +4255,8 @@ function isLocalPrFetchBranch(ref) {
4122
4255
  }
4123
4256
  async function createThreadWorktree(opts) {
4124
4257
  let branchName = `thread/${opts.slug}`;
4125
- const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
4126
- if ((0, import_node_fs10.existsSync)(worktreePath)) {
4258
+ const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
4259
+ if ((0, import_node_fs12.existsSync)(worktreePath)) {
4127
4260
  throw new Error(`Worktree already exists at ${worktreePath}`);
4128
4261
  }
4129
4262
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4192,8 +4325,8 @@ ${add.stdout}`;
4192
4325
  async function createExistingBranchWorktree(opts) {
4193
4326
  const branchName = opts.branchName.trim();
4194
4327
  if (!branchName) throw new Error("branch name required");
4195
- const worktreePath = (0, import_node_path11.join)(worktreesRoot(opts.repoPath), opts.slug);
4196
- if ((0, import_node_fs10.existsSync)(worktreePath)) {
4328
+ const worktreePath = (0, import_node_path13.join)(worktreesRoot(opts.repoPath), opts.slug);
4329
+ if ((0, import_node_fs12.existsSync)(worktreePath)) {
4197
4330
  throw new Error(`Worktree already exists at ${worktreePath}`);
4198
4331
  }
4199
4332
  await ensureGhPreferOrigin(opts.repoPath);
@@ -4481,10 +4614,10 @@ function sameRepoPath(a, b) {
4481
4614
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
4482
4615
  }
4483
4616
  function listLocalThreadBranchSlugs(repoPath) {
4484
- const refsDir = (0, import_node_path11.join)(repoPath, ".git", "refs", "heads", "thread");
4485
- if (!(0, import_node_fs10.existsSync)(refsDir)) return [];
4617
+ const refsDir = (0, import_node_path13.join)(repoPath, ".git", "refs", "heads", "thread");
4618
+ if (!(0, import_node_fs12.existsSync)(refsDir)) return [];
4486
4619
  try {
4487
- return (0, import_node_fs10.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
4620
+ return (0, import_node_fs12.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
4488
4621
  } catch {
4489
4622
  return [];
4490
4623
  }
@@ -4492,8 +4625,8 @@ function listLocalThreadBranchSlugs(repoPath) {
4492
4625
  function collectTakenTeamSlugs(repoPath) {
4493
4626
  const taken = /* @__PURE__ */ new Set();
4494
4627
  const root = worktreesRoot(repoPath);
4495
- if ((0, import_node_fs10.existsSync)(root)) {
4496
- for (const entry of (0, import_node_fs10.readdirSync)(root, { withFileTypes: true })) {
4628
+ if ((0, import_node_fs12.existsSync)(root)) {
4629
+ for (const entry of (0, import_node_fs12.readdirSync)(root, { withFileTypes: true })) {
4497
4630
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
4498
4631
  taken.add(normalizeTakenSlug(entry.name));
4499
4632
  }
@@ -4514,18 +4647,18 @@ function allocateTeamSlug(repoPath) {
4514
4647
  const taken = collectTakenTeamSlugs(repoPath);
4515
4648
  for (let attempt = 0; attempt < 32; attempt++) {
4516
4649
  const team = allocateTeamName(taken);
4517
- const path = (0, import_node_path11.join)(worktreesRoot(repoPath), team.slug);
4518
- if (!(0, import_node_fs10.existsSync)(path)) return team;
4650
+ const path = (0, import_node_path13.join)(worktreesRoot(repoPath), team.slug);
4651
+ if (!(0, import_node_fs12.existsSync)(path)) return team;
4519
4652
  taken.add(team.slug);
4520
4653
  }
4521
4654
  throw new Error("No available soccer team worktree directories left");
4522
4655
  }
4523
- var import_node_fs10, import_node_path11;
4656
+ var import_node_fs12, import_node_path13;
4524
4657
  var init_worktree = __esm({
4525
4658
  "src/git/worktree.ts"() {
4526
4659
  "use strict";
4527
- import_node_fs10 = require("fs");
4528
- import_node_path11 = require("path");
4660
+ import_node_fs12 = require("fs");
4661
+ import_node_path13 = require("path");
4529
4662
  init_paths();
4530
4663
  init_thread_store();
4531
4664
  init_teams();
@@ -4667,7 +4800,7 @@ function coordinatorTurnReminder(opts) {
4667
4800
  function ensureGlobalCoordinatorCwd(opts) {
4668
4801
  const dir = globalAgentCwd();
4669
4802
  try {
4670
- (0, import_node_fs11.mkdirSync)(dir, { recursive: true });
4803
+ (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
4671
4804
  } catch {
4672
4805
  return dir;
4673
4806
  }
@@ -4675,7 +4808,7 @@ function ensureGlobalCoordinatorCwd(opts) {
4675
4808
  let orchId = opts?.orchestratorThreadId?.trim() || "";
4676
4809
  if (!orchId) {
4677
4810
  try {
4678
- const existing = (0, import_node_fs11.readFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), "utf8");
4811
+ const existing = (0, import_node_fs13.readFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), "utf8");
4679
4812
  const m = existing.match(
4680
4813
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
4681
4814
  );
@@ -4717,9 +4850,9 @@ function ensureGlobalCoordinatorCwd(opts) {
4717
4850
  "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
4718
4851
  ].join("\n");
4719
4852
  try {
4720
- (0, import_node_fs11.writeFileSync)((0, import_node_path12.join)(dir, "CLAUDE.md"), `${body}
4853
+ (0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "CLAUDE.md"), `${body}
4721
4854
  `, "utf8");
4722
- (0, import_node_fs11.writeFileSync)((0, import_node_path12.join)(dir, "AGENTS.md"), `${body}
4855
+ (0, import_node_fs13.writeFileSync)((0, import_node_path14.join)(dir, "AGENTS.md"), `${body}
4723
4856
  `, "utf8");
4724
4857
  } catch {
4725
4858
  }
@@ -4751,12 +4884,12 @@ function coordinatorSystemPrompt(opts) {
4751
4884
  formatWorkspaceInventory(opts.workspaces)
4752
4885
  ].join("\n");
4753
4886
  }
4754
- var import_node_fs11, import_node_path12, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
4887
+ var import_node_fs13, import_node_path14, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
4755
4888
  var init_coordinator_prompt = __esm({
4756
4889
  "src/orchestrator/coordinator-prompt.ts"() {
4757
4890
  "use strict";
4758
- import_node_fs11 = require("fs");
4759
- import_node_path12 = require("path");
4891
+ import_node_fs13 = require("fs");
4892
+ import_node_path14 = require("path");
4760
4893
  init_worktree();
4761
4894
  init_app_settings();
4762
4895
  init_paths();
@@ -4777,7 +4910,7 @@ var init_coordinator_prompt = __esm({
4777
4910
  "Workspaces:",
4778
4911
  "- add_workspace / remove_workspace \u2014 register or unregister a git repo",
4779
4912
  "Worktree threads (chats):",
4780
- "- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
4913
+ "- create_thread \u2014 create a worktree + chat from branch | pr | ticket; pass repoPath + parentThreadId; omit agent and model to use Sideboard Account defaults (Settings \u2192 Default agent, model & effort). If the repo has a setup script, Sideboard runs it in the background (does not block send_to_thread). If you are Codex, do not set agent=codex (nested Codex deadlocks)",
4781
4914
  "- fork_worktree \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
4782
4915
  "- fork_chat \u2014 fork a worktree chat (same worktree tab) OR a Global orchestration chat (new orchestration tab); optional agent; leave model unset (Auto) unless you have a reason. Remote coordinators: use this to continue another orchestration chat on a different agent after session limits.",
4783
4916
  "- send_to_thread \u2014 queue a prompt (start/continue a chat turn); pass force_stop: true to interrupt mid-turn / clear stale queued prompts before replacing with a new request",
@@ -4785,7 +4918,7 @@ var init_coordinator_prompt = __esm({
4785
4918
  "- stop_thread \u2014 force-stop: kill in-flight turn AND clear queued prompts (do not leave stale queue after an interrupt)",
4786
4919
  "- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
4787
4920
  "Setup / run:",
4788
- "- run_setup \u2014 re-run worktree setup",
4921
+ "- run_setup \u2014 re-run worktree setup (already runs automatically on create when a script exists)",
4789
4922
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
4790
4923
  "Inspect / review / PRs:",
4791
4924
  "- get_diff \u2014 compact diff summary",
@@ -5054,32 +5187,32 @@ var init_global_workspace = __esm({
5054
5187
 
5055
5188
  // src/brightsy/config.ts
5056
5189
  function brightsyConfigPath() {
5057
- return (0, import_node_path13.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
5190
+ return (0, import_node_path15.join)((0, import_node_os5.homedir)(), ".brightsy", "config.json");
5058
5191
  }
5059
5192
  function loadBrightsyConfig() {
5060
5193
  const path = brightsyConfigPath();
5061
- if (!(0, import_node_fs12.existsSync)(path)) {
5194
+ if (!(0, import_node_fs14.existsSync)(path)) {
5062
5195
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
5063
5196
  }
5064
- const raw = JSON.parse((0, import_node_fs12.readFileSync)(path, "utf8"));
5197
+ const raw = JSON.parse((0, import_node_fs14.readFileSync)(path, "utf8"));
5065
5198
  if (!raw.access_token || !raw.account_id) {
5066
5199
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
5067
5200
  }
5068
5201
  return raw;
5069
5202
  }
5070
5203
  function saveBrightsyConfig(cfg) {
5071
- (0, import_node_fs12.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5204
+ (0, import_node_fs14.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
5072
5205
  `, {
5073
5206
  mode: 384
5074
5207
  });
5075
5208
  }
5076
- var import_node_fs12, import_node_os5, import_node_path13;
5209
+ var import_node_fs14, import_node_os5, import_node_path15;
5077
5210
  var init_config = __esm({
5078
5211
  "src/brightsy/config.ts"() {
5079
5212
  "use strict";
5080
- import_node_fs12 = require("fs");
5213
+ import_node_fs14 = require("fs");
5081
5214
  import_node_os5 = require("os");
5082
- import_node_path13 = require("path");
5215
+ import_node_path15 = require("path");
5083
5216
  }
5084
5217
  });
5085
5218
 
@@ -5094,22 +5227,22 @@ var init_accounts = __esm({
5094
5227
 
5095
5228
  // src/brightsy/connected-teams.ts
5096
5229
  function storePath4() {
5097
- return (0, import_node_path14.join)(appDataDir(), "brightsy-teams.json");
5230
+ return (0, import_node_path16.join)(appDataDir(), "brightsy-teams.json");
5098
5231
  }
5099
5232
  function readStore4() {
5100
5233
  const path = storePath4();
5101
- if (!(0, import_node_fs13.existsSync)(path)) return [];
5234
+ if (!(0, import_node_fs15.existsSync)(path)) return [];
5102
5235
  try {
5103
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(path, "utf8"));
5236
+ const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
5104
5237
  return Array.isArray(parsed.teams) ? parsed.teams : [];
5105
5238
  } catch {
5106
5239
  return [];
5107
5240
  }
5108
5241
  }
5109
5242
  function writeStore2(teams) {
5110
- (0, import_node_fs13.mkdirSync)(appDataDir(), { recursive: true });
5243
+ (0, import_node_fs15.mkdirSync)(appDataDir(), { recursive: true });
5111
5244
  const path = storePath4();
5112
- (0, import_node_fs13.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
5245
+ (0, import_node_fs15.writeFileSync)(path, `${JSON.stringify({ teams }, null, 2)}
5113
5246
  `, {
5114
5247
  mode: 384
5115
5248
  });
@@ -5221,12 +5354,12 @@ function brightsyMcpServerName(slug) {
5221
5354
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
5222
5355
  return `brightsy_${cleaned || "team"}`;
5223
5356
  }
5224
- var import_node_fs13, import_node_path14;
5357
+ var import_node_fs15, import_node_path16;
5225
5358
  var init_connected_teams = __esm({
5226
5359
  "src/brightsy/connected-teams.ts"() {
5227
5360
  "use strict";
5228
- import_node_fs13 = require("fs");
5229
- import_node_path14 = require("path");
5361
+ import_node_fs15 = require("fs");
5362
+ import_node_path16 = require("path");
5230
5363
  init_paths();
5231
5364
  init_accounts();
5232
5365
  init_config();
@@ -5553,11 +5686,11 @@ async function syncCliForTarget(accountId) {
5553
5686
  }
5554
5687
  applyConnectedTeamToCli(team);
5555
5688
  }
5556
- var import_node_fs14, brightsyAdapter;
5689
+ var import_node_fs16, brightsyAdapter;
5557
5690
  var init_brightsy = __esm({
5558
5691
  "src/agents/brightsy.ts"() {
5559
5692
  "use strict";
5560
- import_node_fs14 = require("fs");
5693
+ import_node_fs16 = require("fs");
5561
5694
  init_run();
5562
5695
  init_connected_teams();
5563
5696
  init_config();
@@ -5572,7 +5705,7 @@ var init_brightsy = __esm({
5572
5705
  async detect() {
5573
5706
  const brightsy = resolveAgentExecutable("brightsy");
5574
5707
  if (brightsy !== "brightsy") {
5575
- if (!(0, import_node_fs14.existsSync)(brightsy)) {
5708
+ if (!(0, import_node_fs16.existsSync)(brightsy)) {
5576
5709
  return {
5577
5710
  agent: "brightsy",
5578
5711
  installed: false,
@@ -5822,35 +5955,35 @@ function corePackageDir() {
5822
5955
  try {
5823
5956
  const url = import_meta.url;
5824
5957
  if (typeof url === "string" && url.length > 0) {
5825
- return (0, import_node_path15.dirname)((0, import_node_url.fileURLToPath)(url));
5958
+ return (0, import_node_path17.dirname)((0, import_node_url.fileURLToPath)(url));
5826
5959
  }
5827
5960
  } catch {
5828
5961
  }
5829
5962
  try {
5830
- const req = (0, import_node_module.createRequire)((0, import_node_path15.join)(process.cwd(), "package.json"));
5831
- return (0, import_node_path15.dirname)(req.resolve("@sideboard-ai/core"));
5963
+ const req = (0, import_node_module.createRequire)((0, import_node_path17.join)(process.cwd(), "package.json"));
5964
+ return (0, import_node_path17.dirname)(req.resolve("@sideboard-ai/core"));
5832
5965
  } catch {
5833
5966
  return process.cwd();
5834
5967
  }
5835
5968
  }
5836
5969
  function findSideboardMcpJsEntry() {
5837
5970
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
5838
- if (override && (0, import_node_fs15.existsSync)(override)) return override;
5971
+ if (override && (0, import_node_fs17.existsSync)(override)) return override;
5839
5972
  let dir = corePackageDir();
5840
5973
  for (let i = 0; i < 10; i++) {
5841
5974
  const candidates = [
5842
- (0, import_node_path15.join)(dir, "mcp/run-stdio.js"),
5843
- (0, import_node_path15.join)(dir, "mcp/run-stdio.cjs"),
5844
- (0, import_node_path15.join)(dir, "dist/mcp/run-stdio.js"),
5845
- (0, import_node_path15.join)(dir, "dist/mcp/run-stdio.cjs"),
5846
- (0, import_node_path15.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
5847
- (0, import_node_path15.join)(dir, "packages/cli/dist/index.js"),
5848
- (0, import_node_path15.join)(dir, "cli/dist/index.js")
5975
+ (0, import_node_path17.join)(dir, "mcp/run-stdio.js"),
5976
+ (0, import_node_path17.join)(dir, "mcp/run-stdio.cjs"),
5977
+ (0, import_node_path17.join)(dir, "dist/mcp/run-stdio.js"),
5978
+ (0, import_node_path17.join)(dir, "dist/mcp/run-stdio.cjs"),
5979
+ (0, import_node_path17.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
5980
+ (0, import_node_path17.join)(dir, "packages/cli/dist/index.js"),
5981
+ (0, import_node_path17.join)(dir, "cli/dist/index.js")
5849
5982
  ];
5850
5983
  for (const p of candidates) {
5851
- if ((0, import_node_fs15.existsSync)(p)) return p;
5984
+ if ((0, import_node_fs17.existsSync)(p)) return p;
5852
5985
  }
5853
- const parent = (0, import_node_path15.dirname)(dir);
5986
+ const parent = (0, import_node_path17.dirname)(dir);
5854
5987
  if (parent === dir) break;
5855
5988
  dir = parent;
5856
5989
  }
@@ -5912,22 +6045,52 @@ async function buildInjectedMcpServers(opts) {
5912
6045
  }
5913
6046
  return servers;
5914
6047
  }
6048
+ function shSingleQuote(value) {
6049
+ return `'${value.replace(/'/g, `'\\''`)}'`;
6050
+ }
6051
+ function cursorSafeMcpLaunch(command, args) {
6052
+ if (process.platform === "win32") {
6053
+ return args && args.length > 0 ? { command, args } : { command };
6054
+ }
6055
+ const unwrapped = unwrapStrippedElectronLaunch(command, args);
6056
+ const file = unwrapped?.file ?? command;
6057
+ const fileArgs = unwrapped?.args ?? args ?? [];
6058
+ if (!isElectronLikeCommand(file)) {
6059
+ return fileArgs.length > 0 ? { command: file, args: fileArgs } : { command: file };
6060
+ }
6061
+ const dir = (0, import_node_path17.join)(appDataDir(), "mcp-launch");
6062
+ (0, import_node_fs17.mkdirSync)(dir, { recursive: true });
6063
+ const wrap = (0, import_node_path17.join)(dir, "cursor-electron-as-node.sh");
6064
+ const execLine = [file, ...fileArgs].map(shSingleQuote).join(" ");
6065
+ (0, import_node_fs17.writeFileSync)(
6066
+ wrap,
6067
+ [
6068
+ "#!/bin/sh",
6069
+ "vars=`printenv | awk -F= '/^(ELECTRON_|CHROME_)/{print $1}'`",
6070
+ '[ -n "$vars" ] && unset $vars',
6071
+ "export ELECTRON_RUN_AS_NODE=1",
6072
+ `exec ${execLine} "$@"`,
6073
+ ""
6074
+ ].join("\n"),
6075
+ { mode: 493 }
6076
+ );
6077
+ return { command: wrap };
6078
+ }
6079
+ function mcpSpawnEnv(env) {
6080
+ if (!env) return void 0;
6081
+ const out = { ...env };
6082
+ delete out.ELECTRON_RUN_AS_NODE;
6083
+ return Object.keys(out).length > 0 ? out : void 0;
6084
+ }
5915
6085
  function toCursorMcpServers(servers) {
5916
6086
  const out = {};
5917
6087
  for (const s of servers) {
5918
- const env = s.env ? { ...s.env } : void 0;
5919
- if (env) delete env.ELECTRON_RUN_AS_NODE;
5920
- let command = s.command;
5921
- let args = s.args;
5922
- if (process.platform !== "win32" && !isStrippedElectronLaunch(command, args)) {
5923
- const wrapped = wrapElectronAsNodeLaunch(command, args ?? []);
5924
- command = wrapped.file;
5925
- args = wrapped.args;
5926
- }
6088
+ const env = mcpSpawnEnv(s.env);
6089
+ const launch = cursorSafeMcpLaunch(s.command, s.args);
5927
6090
  out[s.name] = {
5928
- command,
5929
- ...args && args.length > 0 ? { args } : {},
5930
- ...env && Object.keys(env).length > 0 ? { env } : {}
6091
+ command: launch.command,
6092
+ ...launch.args && launch.args.length > 0 ? { args: launch.args } : {},
6093
+ ...env ? { env } : {}
5931
6094
  };
5932
6095
  }
5933
6096
  return out;
@@ -5940,8 +6103,9 @@ function toCodexMcpConfigArgs(servers) {
5940
6103
  if (s.args?.length) {
5941
6104
  args.push("-c", `${prefix}.args=${JSON.stringify(s.args)}`);
5942
6105
  }
5943
- if (s.env) {
5944
- for (const [key, value] of Object.entries(s.env)) {
6106
+ const env = mcpSpawnEnv(s.env);
6107
+ if (env) {
6108
+ for (const [key, value] of Object.entries(env)) {
5945
6109
  args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
5946
6110
  }
5947
6111
  }
@@ -5954,11 +6118,12 @@ function toCodexMcpConfigArgs(servers) {
5954
6118
  function toOpencodeMcpConfigContent(servers) {
5955
6119
  const mcp = {};
5956
6120
  for (const s of servers) {
6121
+ const env = mcpSpawnEnv(s.env);
5957
6122
  mcp[s.name] = {
5958
6123
  type: "local",
5959
6124
  command: [s.command, ...s.args ?? []],
5960
6125
  enabled: true,
5961
- ...s.env && Object.keys(s.env).length > 0 ? { environment: s.env } : {}
6126
+ ...env ? { environment: env } : {}
5962
6127
  };
5963
6128
  }
5964
6129
  return JSON.stringify({ mcp });
@@ -5967,25 +6132,26 @@ function writeMcpServersConfig(servers) {
5967
6132
  if (servers.length === 0) return null;
5968
6133
  const mcpServers = {};
5969
6134
  for (const s of servers) {
6135
+ const env = mcpSpawnEnv(s.env);
5970
6136
  mcpServers[s.name] = {
5971
6137
  command: s.command,
5972
6138
  ...s.args ? { args: s.args } : {},
5973
- ...s.env ? { env: s.env } : {}
6139
+ ...env ? { env } : {}
5974
6140
  };
5975
6141
  }
5976
- const dir = (0, import_node_fs15.mkdtempSync)((0, import_node_path15.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
5977
- const cfgPath = (0, import_node_path15.join)(dir, "mcp.json");
5978
- (0, import_node_fs15.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
6142
+ const dir = (0, import_node_fs17.mkdtempSync)((0, import_node_path17.join)((0, import_node_os6.tmpdir)(), "sideboard-mcp-"));
6143
+ const cfgPath = (0, import_node_path17.join)(dir, "mcp.json");
6144
+ (0, import_node_fs17.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
5979
6145
  return cfgPath;
5980
6146
  }
5981
- var import_node_fs15, import_node_module, import_node_os6, import_node_path15, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
6147
+ var import_node_fs17, import_node_module, import_node_os6, import_node_path17, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
5982
6148
  var init_injected_mcp = __esm({
5983
6149
  "src/agents/injected-mcp.ts"() {
5984
6150
  "use strict";
5985
- import_node_fs15 = require("fs");
6151
+ import_node_fs17 = require("fs");
5986
6152
  import_node_module = require("module");
5987
6153
  import_node_os6 = require("os");
5988
- import_node_path15 = require("path");
6154
+ import_node_path17 = require("path");
5989
6155
  import_node_url = require("url");
5990
6156
  init_run();
5991
6157
  init_config();
@@ -6173,11 +6339,11 @@ function parseIssuesJson(raw) {
6173
6339
  }
6174
6340
  return [];
6175
6341
  }
6176
- var import_node_fs16, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
6342
+ var import_node_fs18, BASE_ALLOWED_TOOLS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
6177
6343
  var init_claude = __esm({
6178
6344
  "src/agents/claude.ts"() {
6179
6345
  "use strict";
6180
- import_node_fs16 = require("fs");
6346
+ import_node_fs18 = require("fs");
6181
6347
  init_run();
6182
6348
  init_app_settings();
6183
6349
  init_claude_mcp();
@@ -6206,7 +6372,7 @@ var init_claude = __esm({
6206
6372
  async detect() {
6207
6373
  const claude = resolveClaudeExecutable();
6208
6374
  if (claude !== "claude") {
6209
- if (!(0, import_node_fs16.existsSync)(claude)) {
6375
+ if (!(0, import_node_fs18.existsSync)(claude)) {
6210
6376
  return {
6211
6377
  agent: "claude",
6212
6378
  installed: false,
@@ -6443,7 +6609,7 @@ async function listCodexModels() {
6443
6609
  if (codex === "codex") {
6444
6610
  const which = await run("which", ["codex"], { reject: false });
6445
6611
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
6446
- } else if (!(0, import_node_fs17.existsSync)(codex)) {
6612
+ } else if (!(0, import_node_fs19.existsSync)(codex)) {
6447
6613
  return FALLBACK_CODEX_MODELS;
6448
6614
  }
6449
6615
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -6478,12 +6644,12 @@ function usageFromCodex(usage) {
6478
6644
  }
6479
6645
  function codexConfigHasNetworkAccess() {
6480
6646
  const candidates = [
6481
- (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
6482
- (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
6647
+ (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".codex", "config.toml"),
6648
+ (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".config", "codex", "config.toml")
6483
6649
  ];
6484
6650
  for (const path of candidates) {
6485
- if (!(0, import_node_fs17.existsSync)(path)) continue;
6486
- const text3 = (0, import_node_fs17.readFileSync)(path, "utf8");
6651
+ if (!(0, import_node_fs19.existsSync)(path)) continue;
6652
+ const text3 = (0, import_node_fs19.readFileSync)(path, "utf8");
6487
6653
  if (/network_access\s*=\s*true/.test(text3)) return true;
6488
6654
  }
6489
6655
  return false;
@@ -6515,21 +6681,21 @@ function asRecord(value) {
6515
6681
  return void 0;
6516
6682
  }
6517
6683
  function codexLooksAuthenticated() {
6518
- const authPath = (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
6519
- if (!(0, import_node_fs17.existsSync)(authPath)) return false;
6684
+ const authPath = (0, import_node_path18.join)((0, import_node_os7.homedir)(), ".codex", "auth.json");
6685
+ if (!(0, import_node_fs19.existsSync)(authPath)) return false;
6520
6686
  try {
6521
- return (0, import_node_fs17.statSync)(authPath).size > 2;
6687
+ return (0, import_node_fs19.statSync)(authPath).size > 2;
6522
6688
  } catch {
6523
6689
  return false;
6524
6690
  }
6525
6691
  }
6526
- var import_node_fs17, import_node_os7, import_node_path16, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
6692
+ var import_node_fs19, import_node_os7, import_node_path18, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
6527
6693
  var init_codex = __esm({
6528
6694
  "src/agents/codex.ts"() {
6529
6695
  "use strict";
6530
- import_node_fs17 = require("fs");
6696
+ import_node_fs19 = require("fs");
6531
6697
  import_node_os7 = require("os");
6532
- import_node_path16 = require("path");
6698
+ import_node_path18 = require("path");
6533
6699
  init_run();
6534
6700
  init_app_settings();
6535
6701
  init_global_workspace();
@@ -6554,7 +6720,7 @@ var init_codex = __esm({
6554
6720
  async detect() {
6555
6721
  const codex = resolveAgentExecutable("codex");
6556
6722
  if (codex !== "codex") {
6557
- if (!(0, import_node_fs17.existsSync)(codex)) {
6723
+ if (!(0, import_node_fs19.existsSync)(codex)) {
6558
6724
  return {
6559
6725
  agent: "codex",
6560
6726
  installed: false,
@@ -6988,11 +7154,11 @@ function entryDir() {
6988
7154
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
6989
7155
  if (cjsDir) return cjsDir;
6990
7156
  try {
6991
- return (0, import_node_path17.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
7157
+ return (0, import_node_path19.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
6992
7158
  } catch {
6993
7159
  try {
6994
7160
  const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
6995
- return (0, import_node_path17.dirname)(req.resolve("@sideboard-ai/core"));
7161
+ return (0, import_node_path19.dirname)(req.resolve("@sideboard-ai/core"));
6996
7162
  } catch {
6997
7163
  return process.cwd();
6998
7164
  }
@@ -7001,27 +7167,27 @@ function entryDir() {
7001
7167
  function cursorRunnerPath() {
7002
7168
  const root = entryDir();
7003
7169
  const candidates = [
7004
- (0, import_node_path17.join)(root, "agents", "cursor-runner.js"),
7005
- (0, import_node_path17.join)(root, "agents", "cursor-runner.cjs"),
7170
+ (0, import_node_path19.join)(root, "agents", "cursor-runner.js"),
7171
+ (0, import_node_path19.join)(root, "agents", "cursor-runner.cjs"),
7006
7172
  // If somehow resolved from package root instead of dist/
7007
- (0, import_node_path17.join)(root, "dist", "agents", "cursor-runner.js"),
7008
- (0, import_node_path17.join)(root, "dist", "agents", "cursor-runner.cjs"),
7173
+ (0, import_node_path19.join)(root, "dist", "agents", "cursor-runner.js"),
7174
+ (0, import_node_path19.join)(root, "dist", "agents", "cursor-runner.cjs"),
7009
7175
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
7010
- (0, import_node_path17.join)(root, "cursor-runner.ts"),
7011
- (0, import_node_path17.join)(root, "src", "agents", "cursor-runner.ts")
7176
+ (0, import_node_path19.join)(root, "cursor-runner.ts"),
7177
+ (0, import_node_path19.join)(root, "src", "agents", "cursor-runner.ts")
7012
7178
  ];
7013
7179
  for (const candidate of candidates) {
7014
- if ((0, import_node_fs18.existsSync)(candidate)) return candidate;
7180
+ if ((0, import_node_fs20.existsSync)(candidate)) return candidate;
7015
7181
  }
7016
7182
  return candidates[0];
7017
7183
  }
7018
- var import_node_fs18, import_node_module2, import_node_path17, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
7184
+ var import_node_fs20, import_node_module2, import_node_path19, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
7019
7185
  var init_cursor = __esm({
7020
7186
  "src/agents/cursor.ts"() {
7021
7187
  "use strict";
7022
- import_node_fs18 = require("fs");
7188
+ import_node_fs20 = require("fs");
7023
7189
  import_node_module2 = require("module");
7024
- import_node_path17 = require("path");
7190
+ import_node_path19 = require("path");
7025
7191
  import_node_url2 = require("url");
7026
7192
  import_sdk = require("@cursor/sdk");
7027
7193
  init_run();
@@ -7150,7 +7316,7 @@ async function listOpencodeModels() {
7150
7316
  if (opencode === "opencode") {
7151
7317
  const which = await run("which", ["opencode"], { reject: false });
7152
7318
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
7153
- } else if (!(0, import_node_fs19.existsSync)(opencode)) {
7319
+ } else if (!(0, import_node_fs21.existsSync)(opencode)) {
7154
7320
  return FALLBACK_OPENCODE_MODELS;
7155
7321
  }
7156
7322
  const listed = await run(opencode, ["models"], { reject: false });
@@ -7180,11 +7346,11 @@ function usageFromOpencode(tokens) {
7180
7346
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
7181
7347
  };
7182
7348
  }
7183
- var import_node_fs19, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
7349
+ var import_node_fs21, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
7184
7350
  var init_opencode = __esm({
7185
7351
  "src/agents/opencode.ts"() {
7186
7352
  "use strict";
7187
- import_node_fs19 = require("fs");
7353
+ import_node_fs21 = require("fs");
7188
7354
  init_run();
7189
7355
  init_app_settings();
7190
7356
  init_global_workspace();
@@ -7210,7 +7376,7 @@ var init_opencode = __esm({
7210
7376
  async detect() {
7211
7377
  const opencode = resolveAgentExecutable("opencode");
7212
7378
  if (opencode !== "opencode") {
7213
- if (!(0, import_node_fs19.existsSync)(opencode)) {
7379
+ if (!(0, import_node_fs21.existsSync)(opencode)) {
7214
7380
  return {
7215
7381
  agent: "opencode",
7216
7382
  installed: false,
@@ -7947,38 +8113,38 @@ __export(workspaces_exports, {
7947
8113
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
7948
8114
  });
7949
8115
  function workspacesFile() {
7950
- return (0, import_node_path21.join)(appDataDir(), "workspaces.json");
8116
+ return (0, import_node_path22.join)(appDataDir(), "workspaces.json");
7951
8117
  }
7952
8118
  function removedWorkspacesFile() {
7953
- return (0, import_node_path21.join)(appDataDir(), "removed-workspaces.json");
8119
+ return (0, import_node_path22.join)(appDataDir(), "removed-workspaces.json");
7954
8120
  }
7955
8121
  function readAll() {
7956
8122
  const path = workspacesFile();
7957
- if (!(0, import_node_fs23.existsSync)(path)) return [];
8123
+ if (!(0, import_node_fs24.existsSync)(path)) return [];
7958
8124
  try {
7959
- const raw = JSON.parse((0, import_node_fs23.readFileSync)(path, "utf8"));
8125
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
7960
8126
  return Array.isArray(raw) ? raw : [];
7961
8127
  } catch {
7962
8128
  return [];
7963
8129
  }
7964
8130
  }
7965
8131
  function writeAll(list) {
7966
- (0, import_node_fs23.mkdirSync)(appDataDir(), { recursive: true });
7967
- (0, import_node_fs23.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
8132
+ (0, import_node_fs24.mkdirSync)(appDataDir(), { recursive: true });
8133
+ (0, import_node_fs24.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
7968
8134
  }
7969
8135
  function readRemoved() {
7970
8136
  const path = removedWorkspacesFile();
7971
- if (!(0, import_node_fs23.existsSync)(path)) return /* @__PURE__ */ new Set();
8137
+ if (!(0, import_node_fs24.existsSync)(path)) return /* @__PURE__ */ new Set();
7972
8138
  try {
7973
- const raw = JSON.parse((0, import_node_fs23.readFileSync)(path, "utf8"));
8139
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(path, "utf8"));
7974
8140
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
7975
8141
  } catch {
7976
8142
  return /* @__PURE__ */ new Set();
7977
8143
  }
7978
8144
  }
7979
8145
  function writeRemoved(paths) {
7980
- (0, import_node_fs23.mkdirSync)(appDataDir(), { recursive: true });
7981
- (0, import_node_fs23.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
8146
+ (0, import_node_fs24.mkdirSync)(appDataDir(), { recursive: true });
8147
+ (0, import_node_fs24.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
7982
8148
  }
7983
8149
  function rememberRemoved(repoPath) {
7984
8150
  const next = readRemoved();
@@ -8001,7 +8167,7 @@ function listWorkspaces() {
8001
8167
  async function addWorkspace(repoPath) {
8002
8168
  const root = await resolveRepoRoot(repoPath);
8003
8169
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
8004
- if (!(0, import_node_fs23.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
8170
+ if (!(0, import_node_fs24.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
8005
8171
  forgetRemoved(root);
8006
8172
  await ensureGhPreferOrigin(root);
8007
8173
  const current = readAll();
@@ -8009,7 +8175,7 @@ async function addWorkspace(repoPath) {
8009
8175
  if (existing) return existing;
8010
8176
  const next = {
8011
8177
  path: root,
8012
- name: (0, import_node_path21.basename)(root),
8178
+ name: (0, import_node_path22.basename)(root),
8013
8179
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
8014
8180
  };
8015
8181
  writeAll([...current, next]);
@@ -8031,10 +8197,10 @@ function syncWorkspacesFromThreads(repoPaths) {
8031
8197
  if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || removed.has(path)) {
8032
8198
  continue;
8033
8199
  }
8034
- if (!(0, import_node_fs23.existsSync)(path)) continue;
8200
+ if (!(0, import_node_fs24.existsSync)(path)) continue;
8035
8201
  const ws = {
8036
8202
  path,
8037
- name: (0, import_node_path21.basename)(path),
8203
+ name: (0, import_node_path22.basename)(path),
8038
8204
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
8039
8205
  };
8040
8206
  byPath.set(path, ws);
@@ -8044,12 +8210,12 @@ function syncWorkspacesFromThreads(repoPaths) {
8044
8210
  if (dirty) writeAll(next);
8045
8211
  return next.sort((a, b) => a.name.localeCompare(b.name));
8046
8212
  }
8047
- var import_node_fs23, import_node_path21;
8213
+ var import_node_fs24, import_node_path22;
8048
8214
  var init_workspaces = __esm({
8049
8215
  "src/store/workspaces.ts"() {
8050
8216
  "use strict";
8051
- import_node_fs23 = require("fs");
8052
- import_node_path21 = require("path");
8217
+ import_node_fs24 = require("fs");
8218
+ import_node_path22 = require("path");
8053
8219
  init_paths();
8054
8220
  init_global_workspace();
8055
8221
  init_worktree();
@@ -8126,40 +8292,40 @@ __export(plan_file_exports, {
8126
8292
  writePlanFile: () => writePlanFile
8127
8293
  });
8128
8294
  function ensureAttachmentsGitignore2(worktreePath) {
8129
- const gitignoreAbs = (0, import_node_path29.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
8130
- if ((0, import_node_fs33.existsSync)(gitignoreAbs)) return;
8131
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(gitignoreAbs), { recursive: true });
8132
- (0, import_node_fs33.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
8295
+ const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
8296
+ if ((0, import_node_fs34.existsSync)(gitignoreAbs)) return;
8297
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
8298
+ (0, import_node_fs34.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
8133
8299
  }
8134
8300
  function planFileAbs(worktreePath) {
8135
- return (0, import_node_path29.join)(worktreePath, PLAN_FILE_REL);
8301
+ return (0, import_node_path30.join)(worktreePath, PLAN_FILE_REL);
8136
8302
  }
8137
8303
  function readTextIfPresent2(abs) {
8138
- if (!(0, import_node_fs33.existsSync)(abs)) return null;
8304
+ if (!(0, import_node_fs34.existsSync)(abs)) return null;
8139
8305
  try {
8140
- const content = (0, import_node_fs33.readFileSync)(abs, "utf8");
8306
+ const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
8141
8307
  return content.trim() ? content : null;
8142
8308
  } catch {
8143
8309
  return null;
8144
8310
  }
8145
8311
  }
8146
8312
  function readPlanFile(worktreePath) {
8147
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path29.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path29.join)(worktreePath, LEGACY_PLAN_FILE_REL));
8313
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path30.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path30.join)(worktreePath, LEGACY_PLAN_FILE_REL));
8148
8314
  }
8149
8315
  function writePlanFile(worktreePath, content) {
8150
8316
  ensureAttachmentsGitignore2(worktreePath);
8151
8317
  const abs = planFileAbs(worktreePath);
8152
- (0, import_node_fs33.mkdirSync)((0, import_node_path29.dirname)(abs), { recursive: true });
8318
+ (0, import_node_fs34.mkdirSync)((0, import_node_path30.dirname)(abs), { recursive: true });
8153
8319
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
8154
- (0, import_node_fs33.writeFileSync)(abs, body, "utf8");
8320
+ (0, import_node_fs34.writeFileSync)(abs, body, "utf8");
8155
8321
  return PLAN_FILE_REL;
8156
8322
  }
8157
- var import_node_fs33, import_node_path29;
8323
+ var import_node_fs34, import_node_path30;
8158
8324
  var init_plan_file = __esm({
8159
8325
  "src/plan/plan-file.ts"() {
8160
8326
  "use strict";
8161
- import_node_fs33 = require("fs");
8162
- import_node_path29 = require("path");
8327
+ import_node_fs34 = require("fs");
8328
+ import_node_path30 = require("path");
8163
8329
  init_workspace_scratch();
8164
8330
  init_plan_present();
8165
8331
  init_plan_present();
@@ -8180,7 +8346,7 @@ function setCaffeinateHoldHooks(next) {
8180
8346
  hooks = next;
8181
8347
  }
8182
8348
  function caffeinateHoldPath() {
8183
- return (0, import_node_path30.join)(appDataDir(), "caffeinate-hold.json");
8349
+ return (0, import_node_path31.join)(appDataDir(), "caffeinate-hold.json");
8184
8350
  }
8185
8351
  function processAlive(pid) {
8186
8352
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -8214,9 +8380,9 @@ function uniqueIds(ids) {
8214
8380
  }
8215
8381
  function readHold() {
8216
8382
  const path = caffeinateHoldPath();
8217
- if (!(0, import_node_fs34.existsSync)(path)) return null;
8383
+ if (!(0, import_node_fs35.existsSync)(path)) return null;
8218
8384
  try {
8219
- const parsed = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
8385
+ const parsed = JSON.parse((0, import_node_fs35.readFileSync)(path, "utf8"));
8220
8386
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
8221
8387
  return {
8222
8388
  pid: parsed.pid,
@@ -8238,7 +8404,7 @@ function writeHold(pid, threadIds) {
8238
8404
  }
8239
8405
  function clearHold() {
8240
8406
  try {
8241
- (0, import_node_fs34.unlinkSync)(caffeinateHoldPath());
8407
+ (0, import_node_fs35.unlinkSync)(caffeinateHoldPath());
8242
8408
  } catch {
8243
8409
  }
8244
8410
  }
@@ -8323,13 +8489,13 @@ function releaseCaffeinateHoldForThread(threadId) {
8323
8489
  }
8324
8490
  return setCaffeinateHold(false, { threadId: id });
8325
8491
  }
8326
- var import_node_child_process4, import_node_fs34, import_node_path30, hooks;
8492
+ var import_node_child_process4, import_node_fs35, import_node_path31, hooks;
8327
8493
  var init_caffeinate_hold = __esm({
8328
8494
  "src/store/caffeinate-hold.ts"() {
8329
8495
  "use strict";
8330
8496
  import_node_child_process4 = require("child_process");
8331
- import_node_fs34 = require("fs");
8332
- import_node_path30 = require("path");
8497
+ import_node_fs35 = require("fs");
8498
+ import_node_path31 = require("path");
8333
8499
  init_paths();
8334
8500
  init_private_file();
8335
8501
  hooks = {};
@@ -8344,10 +8510,10 @@ __export(cursor_recover_exports, {
8344
8510
  function recoverFinishedCursorRun(opts) {
8345
8511
  const agentId = opts.agentId.trim();
8346
8512
  if (!agentId) return null;
8347
- const runsPath = (0, import_node_path31.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
8348
- if (!(0, import_node_fs35.existsSync)(runsPath)) return null;
8513
+ const runsPath = (0, import_node_path32.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
8514
+ if (!(0, import_node_fs36.existsSync)(runsPath)) return null;
8349
8515
  try {
8350
- const lines = (0, import_node_fs35.readFileSync)(runsPath, "utf8").split("\n");
8516
+ const lines = (0, import_node_fs36.readFileSync)(runsPath, "utf8").split("\n");
8351
8517
  let best = null;
8352
8518
  for (const line of lines) {
8353
8519
  const trimmed = line.trim();
@@ -8373,12 +8539,12 @@ function recoverFinishedCursorRun(opts) {
8373
8539
  return null;
8374
8540
  }
8375
8541
  }
8376
- var import_node_fs35, import_node_path31;
8542
+ var import_node_fs36, import_node_path32;
8377
8543
  var init_cursor_recover = __esm({
8378
8544
  "src/agents/cursor-recover.ts"() {
8379
8545
  "use strict";
8380
- import_node_fs35 = require("fs");
8381
- import_node_path31 = require("path");
8546
+ import_node_fs36 = require("fs");
8547
+ import_node_path32 = require("path");
8382
8548
  init_paths();
8383
8549
  }
8384
8550
  });
@@ -8390,14 +8556,14 @@ init_nested_electron_env();
8390
8556
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
8391
8557
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
8392
8558
  var import_zod3 = require("zod");
8393
- var import_node_path32 = require("path");
8559
+ var import_node_path33 = require("path");
8394
8560
 
8395
8561
  // src/orchestrator/orchestrator.ts
8396
8562
  var import_node_events = require("events");
8397
8563
 
8398
8564
  // src/slack/outbound-watch.ts
8399
- var import_node_fs7 = require("fs");
8400
- var import_node_path7 = require("path");
8565
+ var import_node_fs9 = require("fs");
8566
+ var import_node_path9 = require("path");
8401
8567
  init_paths();
8402
8568
  init_private_file();
8403
8569
  init_secure_file();
@@ -8440,19 +8606,19 @@ async function slackApi(token, method, params, fetchImpl) {
8440
8606
  }
8441
8607
 
8442
8608
  // src/slack/reply-target.ts
8443
- var import_node_fs6 = require("fs");
8444
- var import_node_path5 = require("path");
8609
+ var import_node_fs8 = require("fs");
8610
+ var import_node_path7 = require("path");
8445
8611
  init_paths();
8446
8612
  init_private_file();
8447
8613
  init_secure_file();
8448
8614
  function storePath() {
8449
- return (0, import_node_path5.join)(appDataDir(), "slack-reply-to.json");
8615
+ return (0, import_node_path7.join)(appDataDir(), "slack-reply-to.json");
8450
8616
  }
8451
8617
  function readStore() {
8452
8618
  const path = storePath();
8453
- if (!(0, import_node_fs6.existsSync)(path)) return {};
8619
+ if (!(0, import_node_fs8.existsSync)(path)) return {};
8454
8620
  try {
8455
- const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
8621
+ const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
8456
8622
  return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
8457
8623
  } catch {
8458
8624
  return {};
@@ -8463,11 +8629,11 @@ function getSlackReplyTarget(threadId) {
8463
8629
  }
8464
8630
 
8465
8631
  // src/slack/workspaces.ts
8466
- var import_node_path6 = require("path");
8632
+ var import_node_path8 = require("path");
8467
8633
  init_paths();
8468
8634
  init_secure_file();
8469
8635
  function storePath2() {
8470
- return (0, import_node_path6.join)(appDataDir(), "slack-workspaces.json");
8636
+ return (0, import_node_path8.join)(appDataDir(), "slack-workspaces.json");
8471
8637
  }
8472
8638
  function readStore2() {
8473
8639
  try {
@@ -8537,7 +8703,7 @@ var POLL_INTERVAL_MS = 12e3;
8537
8703
  var lastPollMs = 0;
8538
8704
  var nameCache = /* @__PURE__ */ new Map();
8539
8705
  function storePath3() {
8540
- return (0, import_node_path7.join)(appDataDir(), "slack-outbound-watch.json");
8706
+ return (0, import_node_path9.join)(appDataDir(), "slack-outbound-watch.json");
8541
8707
  }
8542
8708
  function watchId(teamId, channelId, ts) {
8543
8709
  return `${teamId}:${channelId}:${ts}`;
@@ -8567,9 +8733,9 @@ function tsNewer(a, b) {
8567
8733
  }
8568
8734
  function readStore3() {
8569
8735
  const path = storePath3();
8570
- if (!(0, import_node_fs7.existsSync)(path)) return [];
8736
+ if (!(0, import_node_fs9.existsSync)(path)) return [];
8571
8737
  try {
8572
- const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs7.readFileSync)(path, "utf8"));
8738
+ const parsed = isSecureFileEncrypted(path) ? readSecureJson(path) : JSON.parse((0, import_node_fs9.readFileSync)(path, "utf8"));
8573
8739
  return Array.isArray(parsed?.watches) ? parsed.watches : [];
8574
8740
  } catch {
8575
8741
  return [];
@@ -8901,12 +9067,12 @@ async function refreshSlackReplyBadges(opts) {
8901
9067
  }
8902
9068
 
8903
9069
  // src/orchestrator/orchestrator.ts
8904
- var import_node_fs36 = require("fs");
9070
+ var import_node_fs37 = require("fs");
8905
9071
  init_error_detail();
8906
9072
 
8907
9073
  // src/agents/spawn.ts
8908
- var import_node_readline = require("readline");
8909
- var import_execa2 = require("execa");
9074
+ var import_node_readline2 = require("readline");
9075
+ var import_execa3 = require("execa");
8910
9076
  init_worktree();
8911
9077
  init_git_auth_mode();
8912
9078
  init_app_settings();
@@ -9182,7 +9348,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
9182
9348
  const detail = err instanceof Error ? err.message : String(err);
9183
9349
  console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
9184
9350
  }
9185
- const child = (0, import_execa2.execa)(cmd.file, cmd.args, {
9351
+ const child = (0, import_execa3.execa)(cmd.file, cmd.args, {
9186
9352
  cwd: cmd.cwd,
9187
9353
  env,
9188
9354
  reject: false,
@@ -9202,7 +9368,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
9202
9368
  let usage = null;
9203
9369
  const consume = (stream, kind) => {
9204
9370
  if (!stream) return;
9205
- const rl = (0, import_node_readline.createInterface)({ input: stream, crlfDelay: Infinity });
9371
+ const rl = (0, import_node_readline2.createInterface)({ input: stream, crlfDelay: Infinity });
9206
9372
  rl.on("line", (line) => {
9207
9373
  if (kind === "stderr") {
9208
9374
  onEvent({ type: "stderr", data: line });
@@ -9387,13 +9553,15 @@ function shouldAutoArchiveOnPrMerge(opts) {
9387
9553
  }
9388
9554
 
9389
9555
  // src/hook/conductor.ts
9390
- var import_node_fs20 = require("fs");
9556
+ var import_node_fs22 = require("fs");
9391
9557
  var import_node_net = require("net");
9392
- var import_node_path18 = require("path");
9393
- var import_execa3 = require("execa");
9394
- var import_node_readline2 = require("readline");
9558
+ var import_node_path20 = require("path");
9559
+ var import_execa4 = require("execa");
9560
+ var import_node_readline3 = require("readline");
9395
9561
  init_settings();
9396
9562
  init_nested_electron_env();
9563
+ init_convention_setup();
9564
+ init_cursor_worktrees();
9397
9565
  init_git_auth_mode();
9398
9566
  init_nested_electron_env();
9399
9567
  var PORT_RANGE_SIZE = 10;
@@ -9402,9 +9570,9 @@ function matchSimpleGlob(pattern, name) {
9402
9570
  return new RegExp(`^${escaped}$`).test(name);
9403
9571
  }
9404
9572
  function readWorktreeInclude(repoPath) {
9405
- const path = (0, import_node_path18.join)(repoPath, ".worktreeinclude");
9406
- if (!(0, import_node_fs20.existsSync)(path)) return [];
9407
- return (0, import_node_fs20.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
9573
+ const path = (0, import_node_path20.join)(repoPath, ".worktreeinclude");
9574
+ if (!(0, import_node_fs22.existsSync)(path)) return [];
9575
+ return (0, import_node_fs22.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
9408
9576
  }
9409
9577
  function resolveFilesToCopy(repoPath) {
9410
9578
  const fromInclude = readWorktreeInclude(repoPath);
@@ -9414,10 +9582,10 @@ function resolveFilesToCopy(repoPath) {
9414
9582
  if (settings?.fileIncludeGlobs?.length) {
9415
9583
  const matched = [];
9416
9584
  try {
9417
- for (const entry of (0, import_node_fs20.readdirSync)(repoPath, { withFileTypes: true })) {
9585
+ for (const entry of (0, import_node_fs22.readdirSync)(repoPath, { withFileTypes: true })) {
9418
9586
  if (!entry.isFile()) continue;
9419
9587
  for (const glob of settings.fileIncludeGlobs) {
9420
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path18.basename)(glob), entry.name)) {
9588
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path20.basename)(glob), entry.name)) {
9421
9589
  matched.push(entry.name);
9422
9590
  break;
9423
9591
  }
@@ -9429,7 +9597,7 @@ function resolveFilesToCopy(repoPath) {
9429
9597
  }
9430
9598
  const defaults = [];
9431
9599
  try {
9432
- for (const entry of (0, import_node_fs20.readdirSync)(repoPath, { withFileTypes: true })) {
9600
+ for (const entry of (0, import_node_fs22.readdirSync)(repoPath, { withFileTypes: true })) {
9433
9601
  if (entry.isFile() && entry.name.startsWith(".env")) {
9434
9602
  defaults.push(entry.name);
9435
9603
  }
@@ -9443,11 +9611,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
9443
9611
  const patterns = resolveFilesToCopy(repoPath);
9444
9612
  const copied = [];
9445
9613
  for (const rel of patterns) {
9446
- const src = (0, import_node_path18.join)(repoPath, rel);
9447
- if (!(0, import_node_fs20.existsSync)(src)) continue;
9448
- const dest = (0, import_node_path18.join)(worktreePath, rel);
9449
- (0, import_node_fs20.mkdirSync)((0, import_node_path18.dirname)(dest), { recursive: true });
9450
- (0, import_node_fs20.copyFileSync)(src, dest);
9614
+ const src = (0, import_node_path20.join)(repoPath, rel);
9615
+ if (!(0, import_node_fs22.existsSync)(src)) continue;
9616
+ const dest = (0, import_node_path20.join)(worktreePath, rel);
9617
+ (0, import_node_fs22.mkdirSync)((0, import_node_path20.dirname)(dest), { recursive: true });
9618
+ (0, import_node_fs22.copyFileSync)(src, dest);
9451
9619
  copied.push(rel);
9452
9620
  }
9453
9621
  return copied;
@@ -9457,7 +9625,7 @@ async function captureLoginEnv() {
9457
9625
  if (cachedLoginEnv) return { ...cachedLoginEnv };
9458
9626
  const shell = process.env.SHELL?.trim() || (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
9459
9627
  try {
9460
- const result = await (0, import_execa3.execa)(shell, ["-l", "-c", "env -0"], {
9628
+ const result = await (0, import_execa4.execa)(shell, ["-l", "-c", "env -0"], {
9461
9629
  reject: false,
9462
9630
  timeout: 5e3
9463
9631
  });
@@ -9483,7 +9651,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
9483
9651
  const env = stripNestedElectronEnv({
9484
9652
  ...baseEnv ?? process.env
9485
9653
  });
9486
- const name = opts.workspaceName ?? (0, import_node_path18.basename)(opts.worktreePath);
9654
+ const name = opts.workspaceName ?? (0, import_node_path20.basename)(opts.worktreePath);
9487
9655
  const ports = opts.ports ?? [];
9488
9656
  const primary = ports[0];
9489
9657
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -9510,7 +9678,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
9510
9678
  }
9511
9679
  function pipeLines(stream, onLine) {
9512
9680
  if (!stream || !onLine) return;
9513
- const rl = (0, import_node_readline2.createInterface)({ input: stream });
9681
+ const rl = (0, import_node_readline3.createInterface)({ input: stream });
9514
9682
  rl.on("line", onLine);
9515
9683
  }
9516
9684
  function killScriptTree(child, ports = []) {
@@ -9518,7 +9686,7 @@ function killScriptTree(child, ports = []) {
9518
9686
  if (pid) {
9519
9687
  try {
9520
9688
  if (process.platform === "win32") {
9521
- void (0, import_execa3.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
9689
+ void (0, import_execa4.execa)("taskkill", ["/pid", String(pid), "/T", "/F"], { reject: false });
9522
9690
  } else {
9523
9691
  process.kill(-pid, "SIGTERM");
9524
9692
  setTimeout(() => {
@@ -9538,7 +9706,7 @@ function killScriptTree(child, ports = []) {
9538
9706
  for (const port of ports) {
9539
9707
  if (!Number.isFinite(port) || port <= 0) continue;
9540
9708
  if (process.platform === "win32") {
9541
- void (0, import_execa3.execa)(
9709
+ void (0, import_execa4.execa)(
9542
9710
  "powershell",
9543
9711
  [
9544
9712
  "-NoProfile",
@@ -9548,7 +9716,7 @@ function killScriptTree(child, ports = []) {
9548
9716
  { reject: false }
9549
9717
  );
9550
9718
  } else {
9551
- void (0, import_execa3.execa)(
9719
+ void (0, import_execa4.execa)(
9552
9720
  "zsh",
9553
9721
  ["-lc", `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`],
9554
9722
  { reject: false }
@@ -9573,7 +9741,7 @@ async function spawnWorkspaceScript(command, opts) {
9573
9741
  } catch {
9574
9742
  }
9575
9743
  const shell = process.platform === "darwin" ? "zsh" : "bash";
9576
- const child = (0, import_execa3.execa)(shell, ["-lc", command], {
9744
+ const child = (0, import_execa4.execa)(shell, ["-lc", command], {
9577
9745
  cwd: opts.worktreePath,
9578
9746
  reject: false,
9579
9747
  env,
@@ -9591,6 +9759,14 @@ async function spawnWorkspaceScript(command, opts) {
9591
9759
  child
9592
9760
  };
9593
9761
  }
9762
+ async function attachAbort(handle, signal) {
9763
+ if (signal) {
9764
+ const onAbort = () => handle.kill();
9765
+ if (signal.aborted) onAbort();
9766
+ else signal.addEventListener("abort", onAbort, { once: true });
9767
+ }
9768
+ return handle.done;
9769
+ }
9594
9770
  async function runSetupScript(repoPath, worktreePath, onLine, opts) {
9595
9771
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
9596
9772
  if (!settings?.setup) return { ran: false, exitCode: null, source: null };
@@ -9600,12 +9776,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
9600
9776
  defaultBranch: opts?.defaultBranch,
9601
9777
  onLine
9602
9778
  });
9603
- if (opts?.signal) {
9604
- const onAbort = () => handle.kill();
9605
- if (opts.signal.aborted) onAbort();
9606
- else opts.signal.addEventListener("abort", onAbort, { once: true });
9607
- }
9608
- const exitCode = await handle.done;
9779
+ const exitCode = await attachAbort(handle, opts?.signal);
9609
9780
  return {
9610
9781
  ran: true,
9611
9782
  exitCode,
@@ -9613,6 +9784,34 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
9613
9784
  kill: handle.kill
9614
9785
  };
9615
9786
  }
9787
+ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
9788
+ const found = findConventionSetup(worktreePath, repoPath);
9789
+ if (!found) return { ran: false, exitCode: null, source: null };
9790
+ onLine?.(`[setup] ${found.source}`);
9791
+ const handle = await spawnWorkspaceScript(found.command, {
9792
+ worktreePath,
9793
+ repoPath,
9794
+ defaultBranch: opts?.defaultBranch,
9795
+ onLine
9796
+ });
9797
+ const exitCode = await attachAbort(handle, opts?.signal);
9798
+ return {
9799
+ ran: true,
9800
+ exitCode,
9801
+ source: found.source,
9802
+ kill: handle.kill
9803
+ };
9804
+ }
9805
+ async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
9806
+ let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
9807
+ if (!setup.ran) {
9808
+ setup = await runCursorWorktreeSetup(repoPath, worktreePath, onLine);
9809
+ }
9810
+ if (!setup.ran) {
9811
+ setup = await runConventionSetup(repoPath, worktreePath, onLine, opts);
9812
+ }
9813
+ return setup;
9814
+ }
9616
9815
  async function runArchiveScript(repoPath, worktreePath, onLine) {
9617
9816
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
9618
9817
  if (!settings?.archive) return { ran: false, exitCode: null };
@@ -9705,75 +9904,9 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
9705
9904
  };
9706
9905
  }
9707
9906
 
9708
- // src/hook/cursor-worktrees.ts
9709
- var import_node_fs21 = require("fs");
9710
- var import_node_path19 = require("path");
9711
- var import_execa4 = require("execa");
9712
- var import_node_readline3 = require("readline");
9713
- function loadCursorWorktreesJson(rootPath) {
9714
- const path = (0, import_node_path19.join)(rootPath, ".cursor", "worktrees.json");
9715
- if (!(0, import_node_fs21.existsSync)(path)) return null;
9716
- try {
9717
- return JSON.parse((0, import_node_fs21.readFileSync)(path, "utf8"));
9718
- } catch {
9719
- return null;
9720
- }
9721
- }
9722
- function resolveSetupSpec(config) {
9723
- if (process.platform === "win32") {
9724
- return config["setup-worktree-windows"] ?? config["setup-worktree"] ?? null;
9725
- }
9726
- return config["setup-worktree-unix"] ?? config["setup-worktree"] ?? null;
9727
- }
9728
- async function runCursorWorktreeSetup(repoPath, worktreePath, onLine) {
9729
- const fromWorktree = loadCursorWorktreesJson(worktreePath);
9730
- const fromRepo = worktreePath !== repoPath ? loadCursorWorktreesJson(repoPath) : null;
9731
- const config = fromWorktree ?? fromRepo;
9732
- if (!config) return { ran: false, exitCode: null, source: null };
9733
- const spec = resolveSetupSpec(config);
9734
- if (!spec) return { ran: false, exitCode: null, source: null };
9735
- const sourceLabel = fromWorktree ? ".cursor/worktrees.json (worktree)" : ".cursor/worktrees.json (main repo)";
9736
- const env = {
9737
- ...process.env,
9738
- ROOT_WORKTREE_PATH: repoPath
9739
- };
9740
- if (process.platform === "win32") {
9741
- env.ROOT_WORKTREE_PATH = repoPath;
9742
- }
9743
- const commands = Array.isArray(spec) ? spec : [spec.endsWith(".sh") || spec.endsWith(".ps1") ? (0, import_node_path19.join)(
9744
- fromWorktree ? worktreePath : repoPath,
9745
- ".cursor",
9746
- spec
9747
- ) : spec];
9748
- let lastExit = 0;
9749
- for (const command of commands) {
9750
- const isScriptPath = typeof spec === "string" && (spec.endsWith(".sh") || spec.endsWith(".ps1"));
9751
- const shell = process.platform === "win32" ? "powershell" : "bash";
9752
- const args = process.platform === "win32" ? isScriptPath ? ["-File", command] : ["-Command", command] : isScriptPath ? [command] : ["-lc", command];
9753
- onLine?.(`[cursor setup] ${command}`);
9754
- const child = (0, import_execa4.execa)(shell, args, {
9755
- cwd: worktreePath,
9756
- reject: false,
9757
- env
9758
- });
9759
- if (child.stdout && onLine) {
9760
- const rl = (0, import_node_readline3.createInterface)({ input: child.stdout });
9761
- rl.on("line", onLine);
9762
- }
9763
- if (child.stderr && onLine) {
9764
- const rl = (0, import_node_readline3.createInterface)({ input: child.stderr });
9765
- rl.on("line", onLine);
9766
- }
9767
- const result = await child;
9768
- lastExit = result.exitCode ?? null;
9769
- if (lastExit !== 0 && lastExit !== null) break;
9770
- }
9771
- return { ran: true, exitCode: lastExit, source: sourceLabel };
9772
- }
9773
-
9774
9907
  // src/git/orphan-cleanup.ts
9775
- var import_node_fs22 = require("fs");
9776
- var import_node_path20 = require("path");
9908
+ var import_node_fs23 = require("fs");
9909
+ var import_node_path21 = require("path");
9777
9910
  init_worktree();
9778
9911
  init_thread_store();
9779
9912
  init_paths();
@@ -9788,9 +9921,9 @@ async function findOrphanWorktrees(repoPaths) {
9788
9921
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
9789
9922
  );
9790
9923
  const homeRoot = sideboardWorkspacesDir();
9791
- if ((0, import_node_fs22.existsSync)(homeRoot)) {
9924
+ if ((0, import_node_fs23.existsSync)(homeRoot)) {
9792
9925
  try {
9793
- for (const entry of (0, import_node_fs22.readdirSync)(homeRoot, { withFileTypes: true })) {
9926
+ for (const entry of (0, import_node_fs23.readdirSync)(homeRoot, { withFileTypes: true })) {
9794
9927
  if (!entry.isDirectory()) continue;
9795
9928
  void entry;
9796
9929
  }
@@ -9800,7 +9933,7 @@ async function findOrphanWorktrees(repoPaths) {
9800
9933
  const orphans = [];
9801
9934
  const seen = /* @__PURE__ */ new Set();
9802
9935
  for (const repoPath of repos) {
9803
- if (!repoPath || !(0, import_node_fs22.existsSync)(repoPath)) continue;
9936
+ if (!repoPath || !(0, import_node_fs23.existsSync)(repoPath)) continue;
9804
9937
  try {
9805
9938
  const wts = await listWorktrees(repoPath);
9806
9939
  for (const wt of wts) {
@@ -9811,7 +9944,7 @@ async function findOrphanWorktrees(repoPaths) {
9811
9944
  seen.add(path);
9812
9945
  let mtimeMs = 0;
9813
9946
  try {
9814
- mtimeMs = (0, import_node_fs22.statSync)(path).mtimeMs;
9947
+ mtimeMs = (0, import_node_fs23.statSync)(path).mtimeMs;
9815
9948
  } catch {
9816
9949
  mtimeMs = 0;
9817
9950
  }
@@ -9821,16 +9954,16 @@ async function findOrphanWorktrees(repoPaths) {
9821
9954
  }
9822
9955
  try {
9823
9956
  const root = worktreesRoot(repoPath);
9824
- if ((0, import_node_fs22.existsSync)(root)) {
9825
- for (const entry of (0, import_node_fs22.readdirSync)(root, { withFileTypes: true })) {
9957
+ if ((0, import_node_fs23.existsSync)(root)) {
9958
+ for (const entry of (0, import_node_fs23.readdirSync)(root, { withFileTypes: true })) {
9826
9959
  if (!entry.isDirectory()) continue;
9827
- const path = (0, import_node_path20.join)(root, entry.name).replace(/\/$/, "");
9960
+ const path = (0, import_node_path21.join)(root, entry.name).replace(/\/$/, "");
9828
9961
  if (known.has(path) || seen.has(path)) continue;
9829
- if (!(0, import_node_fs22.existsSync)((0, import_node_path20.join)(path, ".git"))) continue;
9962
+ if (!(0, import_node_fs23.existsSync)((0, import_node_path21.join)(path, ".git"))) continue;
9830
9963
  seen.add(path);
9831
9964
  let mtimeMs = 0;
9832
9965
  try {
9833
- mtimeMs = (0, import_node_fs22.statSync)(path).mtimeMs;
9966
+ mtimeMs = (0, import_node_fs23.statSync)(path).mtimeMs;
9834
9967
  } catch {
9835
9968
  mtimeMs = Date.now();
9836
9969
  }
@@ -9967,8 +10100,8 @@ async function applyThreadIntoMain(thread, opts) {
9967
10100
  }
9968
10101
 
9969
10102
  // src/git/clone-repo.ts
9970
- var import_node_fs24 = require("fs");
9971
- var import_node_path22 = require("path");
10103
+ var import_node_fs25 = require("fs");
10104
+ var import_node_path23 = require("path");
9972
10105
  var import_execa6 = require("execa");
9973
10106
  init_paths();
9974
10107
  init_workspaces();
@@ -9978,12 +10111,12 @@ async function cloneRepoIntoSideboard(opts) {
9978
10111
  if (!url) throw new Error("Clone URL is required");
9979
10112
  let name = opts.name?.trim();
9980
10113
  if (!name) {
9981
- const leaf = (0, import_node_path22.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
10114
+ const leaf = (0, import_node_path23.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
9982
10115
  name = leaf || "repo";
9983
10116
  }
9984
10117
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
9985
- const dest = (0, import_node_path22.join)(sideboardReposDir(), name);
9986
- if ((0, import_node_fs24.existsSync)(dest)) {
10118
+ const dest = (0, import_node_path23.join)(sideboardReposDir(), name);
10119
+ if ((0, import_node_fs25.existsSync)(dest)) {
9987
10120
  const repoPath2 = await resolveRepoRoot(dest);
9988
10121
  const workspace2 = await ensureWorkspace(repoPath2);
9989
10122
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -10003,7 +10136,7 @@ async function cloneRepoIntoSideboard(opts) {
10003
10136
  init_thread_store();
10004
10137
 
10005
10138
  // src/threads/create.ts
10006
- var import_node_fs25 = require("fs");
10139
+ var import_node_fs26 = require("fs");
10007
10140
 
10008
10141
  // src/detect/detect.ts
10009
10142
  init_agents();
@@ -10048,7 +10181,7 @@ async function createThread(input, _onSetupLine) {
10048
10181
  });
10049
10182
  await requireAgent(resolved.agent);
10050
10183
  const repoPath = await resolveRepoRoot(input.repoPath);
10051
- if (!(0, import_node_fs25.existsSync)(repoPath)) {
10184
+ if (!(0, import_node_fs26.existsSync)(repoPath)) {
10052
10185
  throw new Error(`Repo not found: ${repoPath}`);
10053
10186
  }
10054
10187
  let sourceRef = input.sourceRef;
@@ -10511,8 +10644,8 @@ function forkChatTab(input) {
10511
10644
 
10512
10645
  // src/review/request-review.ts
10513
10646
  var import_node_crypto5 = require("crypto");
10514
- var import_node_fs26 = require("fs");
10515
- var import_node_path23 = require("path");
10647
+ var import_node_fs27 = require("fs");
10648
+ var import_node_path24 = require("path");
10516
10649
  init_global_workspace();
10517
10650
  init_thread_store();
10518
10651
 
@@ -10660,22 +10793,22 @@ function shouldRefreshReviewRequestTemplate(content) {
10660
10793
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
10661
10794
  }
10662
10795
  function readTextIfPresent(abs) {
10663
- if (!(0, import_node_fs26.existsSync)(abs)) return null;
10796
+ if (!(0, import_node_fs27.existsSync)(abs)) return null;
10664
10797
  try {
10665
- const content = (0, import_node_fs26.readFileSync)(abs, "utf8");
10798
+ const content = (0, import_node_fs27.readFileSync)(abs, "utf8");
10666
10799
  return content.trim() ? content : null;
10667
10800
  } catch {
10668
10801
  return null;
10669
10802
  }
10670
10803
  }
10671
10804
  function ensureAttachmentsGitignore(worktreePath) {
10672
- const gitignoreAbs = (0, import_node_path23.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
10673
- if ((0, import_node_fs26.existsSync)(gitignoreAbs)) return;
10674
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(gitignoreAbs), { recursive: true });
10675
- (0, import_node_fs26.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
10805
+ const gitignoreAbs = (0, import_node_path24.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
10806
+ if ((0, import_node_fs27.existsSync)(gitignoreAbs)) return;
10807
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(gitignoreAbs), { recursive: true });
10808
+ (0, import_node_fs27.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
10676
10809
  }
10677
10810
  function resolveReviewGuidelines(worktreePath) {
10678
- const repoAbs = (0, import_node_path23.join)(worktreePath, REPO_REVIEW_PATH);
10811
+ const repoAbs = (0, import_node_path24.join)(worktreePath, REPO_REVIEW_PATH);
10679
10812
  const repoContent = readTextIfPresent(repoAbs);
10680
10813
  if (repoContent) {
10681
10814
  return {
@@ -10685,7 +10818,7 @@ function resolveReviewGuidelines(worktreePath) {
10685
10818
  source: "repo"
10686
10819
  };
10687
10820
  }
10688
- const localAbs = (0, import_node_path23.join)(worktreePath, REVIEW_REQUEST_PATH);
10821
+ const localAbs = (0, import_node_path24.join)(worktreePath, REVIEW_REQUEST_PATH);
10689
10822
  const localContent = readTextIfPresent(localAbs);
10690
10823
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
10691
10824
  return {
@@ -10695,7 +10828,7 @@ function resolveReviewGuidelines(worktreePath) {
10695
10828
  source: "local"
10696
10829
  };
10697
10830
  }
10698
- const legacyAbs = (0, import_node_path23.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10831
+ const legacyAbs = (0, import_node_path24.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
10699
10832
  const legacyContent = readTextIfPresent(legacyAbs);
10700
10833
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
10701
10834
  return {
@@ -10706,8 +10839,8 @@ function resolveReviewGuidelines(worktreePath) {
10706
10839
  };
10707
10840
  }
10708
10841
  ensureAttachmentsGitignore(worktreePath);
10709
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(localAbs), { recursive: true });
10710
- (0, import_node_fs26.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
10842
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(localAbs), { recursive: true });
10843
+ (0, import_node_fs27.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
10711
10844
  return {
10712
10845
  path: REVIEW_REQUEST_PATH,
10713
10846
  name: REVIEW_REQUEST_NAME,
@@ -10907,20 +11040,20 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
10907
11040
 
10908
11041
  // src/threads/adopt.ts
10909
11042
  var import_node_child_process3 = require("child_process");
10910
- var import_node_fs27 = require("fs");
11043
+ var import_node_fs28 = require("fs");
10911
11044
  var import_node_os8 = require("os");
10912
- var import_node_path24 = require("path");
11045
+ var import_node_path25 = require("path");
10913
11046
  var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
10914
11047
  init_worktree();
10915
11048
  init_thread_store();
10916
- var CONDUCTOR_APP_SUPPORT = (0, import_node_path24.join)(
11049
+ var CONDUCTOR_APP_SUPPORT = (0, import_node_path25.join)(
10917
11050
  process.env.HOME ?? "",
10918
11051
  "Library",
10919
11052
  "Application Support",
10920
11053
  "com.conductor.app"
10921
11054
  );
10922
- var CONDUCTOR_DB = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
10923
- var CURSOR_SDK_STORE = (0, import_node_path24.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
11055
+ var CONDUCTOR_DB = (0, import_node_path25.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
11056
+ var CURSOR_SDK_STORE = (0, import_node_path25.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
10924
11057
  function mapAgentType(raw) {
10925
11058
  if (!raw) return null;
10926
11059
  const v = raw.toLowerCase();
@@ -10932,21 +11065,21 @@ function mapAgentType(raw) {
10932
11065
  return null;
10933
11066
  }
10934
11067
  function resolveConductorCursorAgentId(workspacePath) {
10935
- if (!workspacePath || !(0, import_node_fs27.existsSync)(CURSOR_SDK_STORE)) return null;
11068
+ if (!workspacePath || !(0, import_node_fs28.existsSync)(CURSOR_SDK_STORE)) return null;
10936
11069
  const normalized = workspacePath.replace(/\/$/, "");
10937
11070
  let best = null;
10938
11071
  let hashes;
10939
11072
  try {
10940
- hashes = (0, import_node_fs27.readdirSync)(CURSOR_SDK_STORE);
11073
+ hashes = (0, import_node_fs28.readdirSync)(CURSOR_SDK_STORE);
10941
11074
  } catch {
10942
11075
  return null;
10943
11076
  }
10944
11077
  for (const hash of hashes) {
10945
- const agentsFile = (0, import_node_path24.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
10946
- if (!(0, import_node_fs27.existsSync)(agentsFile)) continue;
11078
+ const agentsFile = (0, import_node_path25.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
11079
+ if (!(0, import_node_fs28.existsSync)(agentsFile)) continue;
10947
11080
  let text3;
10948
11081
  try {
10949
- text3 = (0, import_node_fs27.readFileSync)(agentsFile, "utf8");
11082
+ text3 = (0, import_node_fs28.readFileSync)(agentsFile, "utf8");
10950
11083
  } catch {
10951
11084
  continue;
10952
11085
  }
@@ -10970,7 +11103,7 @@ function resolveConductorCursorAgentId(workspacePath) {
10970
11103
  return best?.agentId ?? null;
10971
11104
  }
10972
11105
  async function adoptThread(input) {
10973
- if (!(0, import_node_fs27.existsSync)(input.worktreePath)) {
11106
+ if (!(0, import_node_fs28.existsSync)(input.worktreePath)) {
10974
11107
  throw new Error(`Worktree not found: ${input.worktreePath}`);
10975
11108
  }
10976
11109
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -10994,18 +11127,18 @@ async function adoptThread(input) {
10994
11127
  return thread;
10995
11128
  }
10996
11129
  function listConductorWorkspaces() {
10997
- if (!(0, import_node_fs27.existsSync)(CONDUCTOR_DB)) {
11130
+ if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
10998
11131
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
10999
11132
  }
11000
- const tmp = (0, import_node_fs27.mkdtempSync)((0, import_node_path24.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11001
- const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
11133
+ const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11134
+ const snapshot = (0, import_node_path25.join)(tmp, "conductor.db");
11002
11135
  try {
11003
- (0, import_node_fs27.copyFileSync)(CONDUCTOR_DB, snapshot);
11136
+ (0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
11004
11137
  for (const suffix of ["-wal", "-shm"]) {
11005
11138
  const src = `${CONDUCTOR_DB}${suffix}`;
11006
- if ((0, import_node_fs27.existsSync)(src)) {
11139
+ if ((0, import_node_fs28.existsSync)(src)) {
11007
11140
  try {
11008
- (0, import_node_fs27.copyFileSync)(src, `${snapshot}${suffix}`);
11141
+ (0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
11009
11142
  } catch {
11010
11143
  }
11011
11144
  }
@@ -11081,22 +11214,22 @@ function listConductorWorkspaces() {
11081
11214
  db.close();
11082
11215
  }
11083
11216
  } finally {
11084
- (0, import_node_fs27.rmSync)(tmp, { recursive: true, force: true });
11217
+ (0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
11085
11218
  }
11086
11219
  }
11087
11220
  function importConductorWorkspace(workspaceId) {
11088
- if (!(0, import_node_fs27.existsSync)(CONDUCTOR_DB)) {
11221
+ if (!(0, import_node_fs28.existsSync)(CONDUCTOR_DB)) {
11089
11222
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
11090
11223
  }
11091
- const tmp = (0, import_node_fs27.mkdtempSync)((0, import_node_path24.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11092
- const snapshot = (0, import_node_path24.join)(tmp, "conductor.db");
11224
+ const tmp = (0, import_node_fs28.mkdtempSync)((0, import_node_path25.join)((0, import_node_os8.tmpdir)(), "sideboard-conductor-"));
11225
+ const snapshot = (0, import_node_path25.join)(tmp, "conductor.db");
11093
11226
  try {
11094
- (0, import_node_fs27.copyFileSync)(CONDUCTOR_DB, snapshot);
11227
+ (0, import_node_fs28.copyFileSync)(CONDUCTOR_DB, snapshot);
11095
11228
  for (const suffix of ["-wal", "-shm"]) {
11096
11229
  const src = `${CONDUCTOR_DB}${suffix}`;
11097
- if ((0, import_node_fs27.existsSync)(src)) {
11230
+ if ((0, import_node_fs28.existsSync)(src)) {
11098
11231
  try {
11099
- (0, import_node_fs27.copyFileSync)(src, `${snapshot}${suffix}`);
11232
+ (0, import_node_fs28.copyFileSync)(src, `${snapshot}${suffix}`);
11100
11233
  } catch {
11101
11234
  }
11102
11235
  }
@@ -11114,7 +11247,7 @@ function importConductorWorkspace(workspaceId) {
11114
11247
  ).get(workspaceId);
11115
11248
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
11116
11249
  const worktreePath = String(row.workspacePath);
11117
- if (!(0, import_node_fs27.existsSync)(worktreePath)) {
11250
+ if (!(0, import_node_fs28.existsSync)(worktreePath)) {
11118
11251
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
11119
11252
  }
11120
11253
  let sessionId = null;
@@ -11177,7 +11310,7 @@ function importConductorWorkspace(workspaceId) {
11177
11310
  db.close();
11178
11311
  }
11179
11312
  } finally {
11180
- (0, import_node_fs27.rmSync)(tmp, { recursive: true, force: true });
11313
+ (0, import_node_fs28.rmSync)(tmp, { recursive: true, force: true });
11181
11314
  }
11182
11315
  }
11183
11316
  async function importConductorWorkspaceAsync(workspaceId) {
@@ -11185,7 +11318,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
11185
11318
  }
11186
11319
 
11187
11320
  // src/threads/stack-layers.ts
11188
- var import_node_fs28 = require("fs");
11321
+ var import_node_fs29 = require("fs");
11189
11322
  init_run();
11190
11323
  init_stack();
11191
11324
  init_worktree();
@@ -11253,7 +11386,7 @@ async function openStackLayer(input, _onSetupLine) {
11253
11386
  let createdWorktree = false;
11254
11387
  const trees = await listWorktrees(repoPath);
11255
11388
  const checkedOut = trees.find((w) => w.branch === branchName);
11256
- if (checkedOut?.path && (0, import_node_fs28.existsSync)(checkedOut.path)) {
11389
+ if (checkedOut?.path && (0, import_node_fs29.existsSync)(checkedOut.path)) {
11257
11390
  if (input.reuseExistingWorktree !== false) {
11258
11391
  worktreePath = checkedOut.path;
11259
11392
  } else {
@@ -11395,7 +11528,7 @@ async function initStackFromThread(input, onSetupLine) {
11395
11528
  async function createPrStack(input, onSetupLine) {
11396
11529
  await requireAgent(input.agent);
11397
11530
  const repoPath = await resolveRepoRoot(input.repoPath);
11398
- if (!(0, import_node_fs28.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
11531
+ if (!(0, import_node_fs29.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
11399
11532
  if (!input.branches.length) throw new Error("At least one branch name required");
11400
11533
  const status = await detectGhStack(repoPath);
11401
11534
  if (!status.available) throw new Error(status.reason);
@@ -11462,7 +11595,7 @@ async function createPrStack(input, onSetupLine) {
11462
11595
  }
11463
11596
  }
11464
11597
  const claimed = new Set(threads.map((t) => t.worktreePath));
11465
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs28.existsSync)(bootstrap.worktreePath)) {
11598
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs29.existsSync)(bootstrap.worktreePath)) {
11466
11599
  try {
11467
11600
  await removeWorktree(repoPath, bootstrap.worktreePath, {
11468
11601
  deleteBranch: bootstrap.branchName
@@ -11477,12 +11610,12 @@ async function createPrStack(input, onSetupLine) {
11477
11610
  init_worktree();
11478
11611
 
11479
11612
  // src/diff/diff.ts
11480
- var import_node_fs29 = require("fs");
11481
- var import_node_path25 = require("path");
11613
+ var import_node_fs30 = require("fs");
11614
+ var import_node_path26 = require("path");
11482
11615
  init_run();
11483
11616
  init_worktree();
11484
11617
  async function inspectGitWorktree(worktreePath) {
11485
- if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) return "missing_worktree";
11618
+ if (!worktreePath || !(0, import_node_fs30.existsSync)(worktreePath)) return "missing_worktree";
11486
11619
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
11487
11620
  reject: false
11488
11621
  });
@@ -11490,7 +11623,7 @@ async function inspectGitWorktree(worktreePath) {
11490
11623
  return "ok";
11491
11624
  }
11492
11625
  async function initializeGitRepository(worktreePath) {
11493
- if (!worktreePath || !(0, import_node_fs29.existsSync)(worktreePath)) {
11626
+ if (!worktreePath || !(0, import_node_fs30.existsSync)(worktreePath)) {
11494
11627
  throw new Error("Worktree not found");
11495
11628
  }
11496
11629
  const status = await inspectGitWorktree(worktreePath);
@@ -11625,11 +11758,11 @@ new file mode 100644
11625
11758
  };
11626
11759
  }
11627
11760
  async function untrackedPatch(worktreePath, path, maxHunk) {
11628
- const abs = (0, import_node_path25.join)(worktreePath, path);
11761
+ const abs = (0, import_node_path26.join)(worktreePath, path);
11629
11762
  try {
11630
- const st = (0, import_node_fs29.statSync)(abs);
11763
+ const st = (0, import_node_fs30.statSync)(abs);
11631
11764
  if (st.isFile() && st.size > maxHunk) {
11632
- const buf = (0, import_node_fs29.readFileSync)(abs).subarray(0, maxHunk);
11765
+ const buf = (0, import_node_fs30.readFileSync)(abs).subarray(0, maxHunk);
11633
11766
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
11634
11767
  }
11635
11768
  } catch {
@@ -12130,8 +12263,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
12130
12263
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12131
12264
  assertSafeRelativePath(relativePath);
12132
12265
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
12133
- const abs = (0, import_node_path25.join)(worktreePath, relativePath);
12134
- const st = (0, import_node_fs29.statSync)(abs);
12266
+ const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12267
+ const st = (0, import_node_fs30.statSync)(abs);
12135
12268
  if (!st.isFile()) {
12136
12269
  throw new Error(`Not a file: ${relativePath}`);
12137
12270
  }
@@ -12140,7 +12273,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12140
12273
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
12141
12274
  );
12142
12275
  }
12143
- const buf = (0, import_node_fs29.readFileSync)(abs);
12276
+ const buf = (0, import_node_fs30.readFileSync)(abs);
12144
12277
  return {
12145
12278
  path: relativePath,
12146
12279
  contentBase64: buf.toString("base64"),
@@ -12150,12 +12283,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
12150
12283
  function readWorktreeFile(worktreePath, relativePath, opts) {
12151
12284
  assertSafeRelativePath(relativePath);
12152
12285
  const maxBytes = opts?.maxBytes ?? 2e5;
12153
- const abs = (0, import_node_path25.join)(worktreePath, relativePath);
12154
- const st = (0, import_node_fs29.statSync)(abs);
12286
+ const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12287
+ const st = (0, import_node_fs30.statSync)(abs);
12155
12288
  if (!st.isFile()) {
12156
12289
  throw new Error(`Not a file: ${relativePath}`);
12157
12290
  }
12158
- const buf = (0, import_node_fs29.readFileSync)(abs);
12291
+ const buf = (0, import_node_fs30.readFileSync)(abs);
12159
12292
  if (isImageRelativePath(relativePath)) {
12160
12293
  const maxImageBytes = Math.max(maxBytes, 15e6);
12161
12294
  const truncated2 = buf.length > maxImageBytes;
@@ -12198,9 +12331,9 @@ function assertSafeRelativePath(relativePath) {
12198
12331
  }
12199
12332
  function writeWorktreeFile(worktreePath, relativePath, content) {
12200
12333
  assertSafeRelativePath(relativePath);
12201
- const abs = (0, import_node_path25.join)(worktreePath, relativePath);
12202
- (0, import_node_fs29.mkdirSync)((0, import_node_path25.dirname)(abs), { recursive: true });
12203
- (0, import_node_fs29.writeFileSync)(abs, content, "utf8");
12334
+ const abs = (0, import_node_path26.join)(worktreePath, relativePath);
12335
+ (0, import_node_fs30.mkdirSync)((0, import_node_path26.dirname)(abs), { recursive: true });
12336
+ (0, import_node_fs30.writeFileSync)(abs, content, "utf8");
12204
12337
  return { path: relativePath };
12205
12338
  }
12206
12339
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -12304,9 +12437,9 @@ async function confirmLand(thread, opts) {
12304
12437
  }
12305
12438
 
12306
12439
  // src/skills/discover.ts
12307
- var import_node_fs30 = require("fs");
12440
+ var import_node_fs31 = require("fs");
12308
12441
  var import_node_os9 = require("os");
12309
- var import_node_path26 = require("path");
12442
+ var import_node_path27 = require("path");
12310
12443
  function toCommand(name) {
12311
12444
  return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
12312
12445
  }
@@ -12338,7 +12471,7 @@ function parseFrontmatter(content) {
12338
12471
  }
12339
12472
  function readSkill(skillMd, source) {
12340
12473
  try {
12341
- const content = (0, import_node_fs30.readFileSync)(skillMd, "utf8");
12474
+ const content = (0, import_node_fs31.readFileSync)(skillMd, "utf8");
12342
12475
  const { name: fmName, description } = parseFrontmatter(content);
12343
12476
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
12344
12477
  const name = fmName || dirName;
@@ -12357,19 +12490,19 @@ function readSkill(skillMd, source) {
12357
12490
  }
12358
12491
  }
12359
12492
  function scanSkillsDir(dir, source, out) {
12360
- if (!(0, import_node_fs30.existsSync)(dir)) return;
12493
+ if (!(0, import_node_fs31.existsSync)(dir)) return;
12361
12494
  let entries;
12362
12495
  try {
12363
- entries = (0, import_node_fs30.readdirSync)(dir);
12496
+ entries = (0, import_node_fs31.readdirSync)(dir);
12364
12497
  } catch {
12365
12498
  return;
12366
12499
  }
12367
12500
  for (const entry of entries) {
12368
12501
  if (entry.startsWith(".")) continue;
12369
- const skillMd = (0, import_node_path26.join)(dir, entry, "SKILL.md");
12370
- if (!(0, import_node_fs30.existsSync)(skillMd)) continue;
12502
+ const skillMd = (0, import_node_path27.join)(dir, entry, "SKILL.md");
12503
+ if (!(0, import_node_fs31.existsSync)(skillMd)) continue;
12371
12504
  try {
12372
- if (!(0, import_node_fs30.statSync)(skillMd).isFile()) continue;
12505
+ if (!(0, import_node_fs31.statSync)(skillMd).isFile()) continue;
12373
12506
  } catch {
12374
12507
  continue;
12375
12508
  }
@@ -12378,24 +12511,24 @@ function scanSkillsDir(dir, source, out) {
12378
12511
  }
12379
12512
  }
12380
12513
  function scanClaudePluginSkills(pluginsRoot, out) {
12381
- if (!(0, import_node_fs30.existsSync)(pluginsRoot)) return;
12514
+ if (!(0, import_node_fs31.existsSync)(pluginsRoot)) return;
12382
12515
  const walk = (dir, depth, lookingForSkillsDir) => {
12383
12516
  if (depth > 7) return;
12384
12517
  let entries;
12385
12518
  try {
12386
- entries = (0, import_node_fs30.readdirSync)(dir);
12519
+ entries = (0, import_node_fs31.readdirSync)(dir);
12387
12520
  } catch {
12388
12521
  return;
12389
12522
  }
12390
12523
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
12391
- const skill = readSkill((0, import_node_path26.join)(dir, "SKILL.md"), "cli");
12524
+ const skill = readSkill((0, import_node_path27.join)(dir, "SKILL.md"), "cli");
12392
12525
  if (skill) out.push(skill);
12393
12526
  }
12394
12527
  for (const entry of entries) {
12395
12528
  if (entry === "node_modules" || entry === ".git") continue;
12396
- const full = (0, import_node_path26.join)(dir, entry);
12529
+ const full = (0, import_node_path27.join)(dir, entry);
12397
12530
  try {
12398
- if (!(0, import_node_fs30.statSync)(full).isDirectory()) continue;
12531
+ if (!(0, import_node_fs31.statSync)(full).isDirectory()) continue;
12399
12532
  } catch {
12400
12533
  continue;
12401
12534
  }
@@ -12413,17 +12546,17 @@ function discoverSkills(worktreePath) {
12413
12546
  const home = (0, import_node_os9.homedir)();
12414
12547
  const collected = [];
12415
12548
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
12416
- scanSkillsDir((0, import_node_path26.join)(worktreePath, rel), "workspace", collected);
12549
+ scanSkillsDir((0, import_node_path27.join)(worktreePath, rel), "workspace", collected);
12417
12550
  }
12418
12551
  for (const abs of [
12419
- (0, import_node_path26.join)(home, ".claude/skills"),
12420
- (0, import_node_path26.join)(home, ".cursor/skills"),
12421
- (0, import_node_path26.join)(home, ".sideboard/skills"),
12422
- (0, import_node_path26.join)(home, ".brightsy/skills")
12552
+ (0, import_node_path27.join)(home, ".claude/skills"),
12553
+ (0, import_node_path27.join)(home, ".cursor/skills"),
12554
+ (0, import_node_path27.join)(home, ".sideboard/skills"),
12555
+ (0, import_node_path27.join)(home, ".brightsy/skills")
12423
12556
  ]) {
12424
12557
  scanSkillsDir(abs, "user", collected);
12425
12558
  }
12426
- scanClaudePluginSkills((0, import_node_path26.join)(home, ".claude/plugins"), collected);
12559
+ scanClaudePluginSkills((0, import_node_path27.join)(home, ".claude/plugins"), collected);
12427
12560
  const rank = { workspace: 0, user: 1, cli: 2 };
12428
12561
  const byCommand = /* @__PURE__ */ new Map();
12429
12562
  for (const skill of collected) {
@@ -12435,7 +12568,7 @@ function discoverSkills(worktreePath) {
12435
12568
  return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
12436
12569
  }
12437
12570
  function readSkillBody(skillPath, maxChars = 12e3) {
12438
- const raw = (0, import_node_fs30.readFileSync)(skillPath, "utf8");
12571
+ const raw = (0, import_node_fs31.readFileSync)(skillPath, "utf8");
12439
12572
  if (raw.startsWith("---")) {
12440
12573
  const end = raw.indexOf("\n---", 3);
12441
12574
  if (end >= 0) {
@@ -12528,8 +12661,8 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
12528
12661
  }
12529
12662
 
12530
12663
  // src/composer/stage-files.ts
12531
- var import_node_fs31 = require("fs");
12532
- var import_node_path27 = require("path");
12664
+ var import_node_fs32 = require("fs");
12665
+ var import_node_path28 = require("path");
12533
12666
  var import_node_crypto7 = require("crypto");
12534
12667
  init_workspace_scratch();
12535
12668
  var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
@@ -12555,7 +12688,7 @@ var IMAGE_MIME_BY_EXT = {
12555
12688
  var MAX_INLINE_BYTES = 4e5;
12556
12689
  var MAX_PREVIEW_BYTES = 5e6;
12557
12690
  function fileExtension(filePath) {
12558
- const base = (0, import_node_path27.basename)(filePath).toLowerCase();
12691
+ const base = (0, import_node_path28.basename)(filePath).toLowerCase();
12559
12692
  return base.includes(".") ? base.split(".").pop() || "" : "";
12560
12693
  }
12561
12694
  function isImageFilePath(filePath) {
@@ -12565,22 +12698,22 @@ function imageMimeType(filePath) {
12565
12698
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
12566
12699
  }
12567
12700
  function ensureAttachmentsDir(worktreePath) {
12568
- const dir = (0, import_node_path27.join)(worktreePath, ATTACHMENTS_DIR);
12569
- (0, import_node_fs31.mkdirSync)(dir, { recursive: true });
12570
- const gi = (0, import_node_path27.join)(dir, ".gitignore");
12571
- if (!(0, import_node_fs31.existsSync)(gi)) {
12572
- (0, import_node_fs31.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12701
+ const dir = (0, import_node_path28.join)(worktreePath, ATTACHMENTS_DIR);
12702
+ (0, import_node_fs32.mkdirSync)(dir, { recursive: true });
12703
+ const gi = (0, import_node_path28.join)(dir, ".gitignore");
12704
+ if (!(0, import_node_fs32.existsSync)(gi)) {
12705
+ (0, import_node_fs32.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
12573
12706
  }
12574
12707
  return dir;
12575
12708
  }
12576
12709
  function uniqueAttachmentName(dir, originalName) {
12577
12710
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
12578
- if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(dir, safe))) return safe;
12579
- const ext = (0, import_node_path27.extname)(safe);
12711
+ if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(dir, safe))) return safe;
12712
+ const ext = (0, import_node_path28.extname)(safe);
12580
12713
  const stem = ext ? safe.slice(0, -ext.length) : safe;
12581
12714
  for (let i = 1; i < 1e4; i++) {
12582
12715
  const candidate = `${stem}-${i}${ext}`;
12583
- if (!(0, import_node_fs31.existsSync)((0, import_node_path27.join)(dir, candidate))) return candidate;
12716
+ if (!(0, import_node_fs32.existsSync)((0, import_node_path28.join)(dir, candidate))) return candidate;
12584
12717
  }
12585
12718
  return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
12586
12719
  }
@@ -12636,15 +12769,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
12636
12769
  const dir = ensureAttachmentsDir(worktreePath);
12637
12770
  const out = [];
12638
12771
  for (const abs of absolutePaths) {
12639
- const originalName = (0, import_node_path27.basename)(abs);
12772
+ const originalName = (0, import_node_path28.basename)(abs);
12640
12773
  try {
12641
- const st = (0, import_node_fs31.statSync)(abs);
12774
+ const st = (0, import_node_fs32.statSync)(abs);
12642
12775
  if (!st.isFile()) continue;
12643
12776
  const name = uniqueAttachmentName(dir, originalName);
12644
- const destAbs = (0, import_node_path27.join)(dir, name);
12645
- (0, import_node_fs31.copyFileSync)(abs, destAbs);
12777
+ const destAbs = (0, import_node_path28.join)(dir, name);
12778
+ (0, import_node_fs32.copyFileSync)(abs, destAbs);
12646
12779
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12647
- const buf = (0, import_node_fs31.readFileSync)(destAbs);
12780
+ const buf = (0, import_node_fs32.readFileSync)(destAbs);
12648
12781
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12649
12782
  } catch (err) {
12650
12783
  out.push({
@@ -12666,8 +12799,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
12666
12799
  try {
12667
12800
  const buf = Buffer.from(item.dataBase64, "base64");
12668
12801
  const name = uniqueAttachmentName(dir, originalName);
12669
- const destAbs = (0, import_node_path27.join)(dir, name);
12670
- (0, import_node_fs31.writeFileSync)(destAbs, buf);
12802
+ const destAbs = (0, import_node_path28.join)(dir, name);
12803
+ (0, import_node_fs32.writeFileSync)(destAbs, buf);
12671
12804
  const rel = `${ATTACHMENTS_DIR}/${name}`;
12672
12805
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
12673
12806
  } catch (err) {
@@ -12687,18 +12820,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
12687
12820
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
12688
12821
  out.push({
12689
12822
  id: (0, import_node_crypto7.randomUUID)(),
12690
- name: (0, import_node_path27.basename)(rel) || "file",
12823
+ name: (0, import_node_path28.basename)(rel) || "file",
12691
12824
  kind: "file",
12692
12825
  content: `(invalid path: ${rel})`
12693
12826
  });
12694
12827
  continue;
12695
12828
  }
12696
- const name = (0, import_node_path27.basename)(rel);
12829
+ const name = (0, import_node_path28.basename)(rel);
12697
12830
  try {
12698
- const abs = (0, import_node_path27.join)(worktreePath, rel);
12699
- const st = (0, import_node_fs31.statSync)(abs);
12831
+ const abs = (0, import_node_path28.join)(worktreePath, rel);
12832
+ const st = (0, import_node_fs32.statSync)(abs);
12700
12833
  if (!st.isFile()) continue;
12701
- const buf = (0, import_node_fs31.readFileSync)(abs);
12834
+ const buf = (0, import_node_fs32.readFileSync)(abs);
12702
12835
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
12703
12836
  } catch (err) {
12704
12837
  out.push({
@@ -12713,11 +12846,11 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
12713
12846
  }
12714
12847
 
12715
12848
  // src/agents/instructions.ts
12716
- var import_node_fs32 = require("fs");
12717
- var import_node_path28 = require("path");
12849
+ var import_node_fs33 = require("fs");
12850
+ var import_node_path29 = require("path");
12718
12851
  init_git_auth_mode();
12719
12852
  init_worktree_labels();
12720
- function normPath2(p) {
12853
+ function normPath3(p) {
12721
12854
  return p.replace(/\/+$/, "");
12722
12855
  }
12723
12856
  function formatRenameBranchDirective(thread, opts) {
@@ -12738,8 +12871,8 @@ function formatRenameBranchDirective(thread, opts) {
12738
12871
  return lines.join("\n");
12739
12872
  }
12740
12873
  function formatWorktreeDirective(thread, opts) {
12741
- const worktree = normPath2(thread.worktreePath);
12742
- const repo = normPath2(thread.repoPath);
12874
+ const worktree = normPath3(thread.worktreePath);
12875
+ const repo = normPath3(thread.repoPath);
12743
12876
  const dir = worktreeNameFromPath(thread.worktreePath);
12744
12877
  const lines = [
12745
12878
  "Sideboard workspace (mandatory):",
@@ -12988,7 +13121,7 @@ var Orchestrator = class {
12988
13121
  }
12989
13122
  continue;
12990
13123
  }
12991
- if (!(0, import_node_fs36.existsSync)(thread.worktreePath)) {
13124
+ if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
12992
13125
  setStatus(thread.id, "broken", "Worktree missing on disk");
12993
13126
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
12994
13127
  continue;
@@ -13163,14 +13296,7 @@ var Orchestrator = class {
13163
13296
  return thread;
13164
13297
  }
13165
13298
  async finishCreateThread(threadId, prompt) {
13166
- await this.runSetupAfterCreate(threadId);
13167
- const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
13168
- if (autoRunAfterSetupEnabled2()) {
13169
- try {
13170
- await this.startDev(threadId);
13171
- } catch {
13172
- }
13173
- }
13299
+ const setup = this.runSetupAfterCreate(threadId);
13174
13300
  if (prompt) {
13175
13301
  try {
13176
13302
  await this.send(threadId, prompt);
@@ -13181,6 +13307,14 @@ var Orchestrator = class {
13181
13307
  });
13182
13308
  }
13183
13309
  }
13310
+ await setup;
13311
+ const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
13312
+ if (autoRunAfterSetupEnabled2()) {
13313
+ try {
13314
+ await this.startDev(threadId);
13315
+ } catch {
13316
+ }
13317
+ }
13184
13318
  }
13185
13319
  /** Run workspace setup after a new worktree is created (no-op if none configured). */
13186
13320
  async runSetupAfterCreate(threadId) {
@@ -13878,7 +14012,7 @@ var Orchestrator = class {
13878
14012
  });
13879
14013
  this.emit({ type: "setup_started", threadId: thread.id });
13880
14014
  try {
13881
- let setup = await runSetupScript(
14015
+ const setup = await runWorkspaceSetup(
13882
14016
  thread.repoPath,
13883
14017
  thread.worktreePath,
13884
14018
  (line) => {
@@ -13886,18 +14020,9 @@ var Orchestrator = class {
13886
14020
  },
13887
14021
  { signal: abort.signal }
13888
14022
  );
13889
- if (!setup.ran) {
13890
- setup = await runCursorWorktreeSetup(
13891
- thread.repoPath,
13892
- thread.worktreePath,
13893
- (line) => {
13894
- this.emit({ type: "setup_output", threadId: thread.id, line });
13895
- }
13896
- );
13897
- }
13898
14023
  if (!setup.ran) {
13899
14024
  throw new Error(
13900
- "No setup script in .sideboard/settings.toml, .conductor/settings.toml, or .cursor/worktrees.json"
14025
+ "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)"
13901
14026
  );
13902
14027
  }
13903
14028
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
@@ -14205,7 +14330,7 @@ var Orchestrator = class {
14205
14330
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
14206
14331
  }
14207
14332
  for (const id of result.createdThreadIds) {
14208
- await this.runSetupAfterCreate(id);
14333
+ void this.runSetupAfterCreate(id);
14209
14334
  }
14210
14335
  return { stack: result.stack, threads: result.threads };
14211
14336
  }
@@ -14222,7 +14347,7 @@ var Orchestrator = class {
14222
14347
  status: result.thread.status
14223
14348
  });
14224
14349
  if (result.createdWorktree) {
14225
- await this.runSetupAfterCreate(result.thread.id);
14350
+ void this.runSetupAfterCreate(result.thread.id);
14226
14351
  }
14227
14352
  return { stack: result.stack, thread: result.thread };
14228
14353
  }
@@ -14237,7 +14362,7 @@ var Orchestrator = class {
14237
14362
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
14238
14363
  }
14239
14364
  for (const id of result.createdThreadIds) {
14240
- await this.runSetupAfterCreate(id);
14365
+ void this.runSetupAfterCreate(id);
14241
14366
  }
14242
14367
  return { stack: result.stack, threads: result.threads };
14243
14368
  }
@@ -14248,7 +14373,7 @@ var Orchestrator = class {
14248
14373
  this.emit({ type: "status_changed", threadId: t.id, status: t.status });
14249
14374
  }
14250
14375
  for (const id of result.createdThreadIds) {
14251
- await this.runSetupAfterCreate(id);
14376
+ void this.runSetupAfterCreate(id);
14252
14377
  }
14253
14378
  return { stack: result.stack, threads: result.threads };
14254
14379
  }
@@ -14379,7 +14504,7 @@ var Orchestrator = class {
14379
14504
  async forkThreadWorktree(input) {
14380
14505
  const thread = await forkThreadWorktree(input);
14381
14506
  this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
14382
- await this.runSetupAfterCreate(thread.id);
14507
+ void this.runSetupAfterCreate(thread.id);
14383
14508
  return thread;
14384
14509
  }
14385
14510
  renameThread(threadRef, title) {
@@ -14482,7 +14607,7 @@ var Orchestrator = class {
14482
14607
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
14483
14608
  return restored2;
14484
14609
  }
14485
- if (!(0, import_node_fs36.existsSync)(thread.worktreePath)) {
14610
+ if (!(0, import_node_fs37.existsSync)(thread.worktreePath)) {
14486
14611
  const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
14487
14612
  const { execa: execa7 } = await import("execa");
14488
14613
  const slug = thread.worktreePath.split("/").pop();
@@ -15713,7 +15838,7 @@ async function startMcpServer() {
15713
15838
  async () => {
15714
15839
  const threads = orch.getThreads(true);
15715
15840
  const lines = threads.map((t) => {
15716
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path32.basename)(t.repoPath) || t.repoPath;
15841
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path33.basename)(t.repoPath) || t.repoPath;
15717
15842
  return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
15718
15843
  });
15719
15844
  return {
@@ -15924,7 +16049,7 @@ async function startMcpServer() {
15924
16049
  );
15925
16050
  server.tool(
15926
16051
  "create_thread",
15927
- `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Then use send_to_thread to chat.`,
16052
+ `Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Setup (settings.toml, .cursor/worktrees.json, or script/setup) runs in the background in parallel with the first turn. Then use send_to_thread to chat.`,
15928
16053
  {
15929
16054
  sourceType: import_zod3.z.enum(["branch", "pr", "ticket"]),
15930
16055
  sourceRef: import_zod3.z.string(),
@@ -16442,7 +16567,7 @@ async function startMcpServer() {
16442
16567
  );
16443
16568
  server.tool(
16444
16569
  "run_setup",
16445
- "Re-run workspace setup (Sideboard/Conductor settings or .cursor/worktrees.json)",
16570
+ "Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
16446
16571
  { ref: import_zod3.z.string() },
16447
16572
  async ({ ref }) => {
16448
16573
  const result = await orch.runSetup(ref);