@sideboard-ai/core 0.1.234 → 0.1.236

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 (67) hide show
  1. package/dist/{abletime-WZNDTRVL.js → abletime-KOGCIQCO.js} +5 -5
  2. package/dist/{abletime-BGVOCEOU.js → abletime-VSV6AUBV.js} +5 -5
  3. package/dist/{abletime-oauth-ZLU2EYRK.js → abletime-oauth-LY7KZICW.js} +4 -4
  4. package/dist/{abletime-oauth-6M5GWEPX.js → abletime-oauth-QMDV45JC.js} +4 -4
  5. package/dist/{abletime-rest-WNHIATB3.js → abletime-rest-LXOWKPL7.js} +4 -4
  6. package/dist/{abletime-rest-F7XG5NGY.js → abletime-rest-NL56UVK5.js} +4 -4
  7. package/dist/agents/cursor-runner.cjs +39 -35
  8. package/dist/agents/cursor-runner.js +3 -3
  9. package/dist/{agents-BTXL6R5I.js → agents-JC6DRIT3.js} +9 -9
  10. package/dist/{agents-WMN7C322.js → agents-S4HYHRL3.js} +8 -8
  11. package/dist/{app-settings-KBL2G7M4.js → app-settings-2CFCRYD7.js} +2 -2
  12. package/dist/{app-settings-UXWCPDEA.js → app-settings-I27UBVI4.js} +2 -2
  13. package/dist/{caffeinate-hold-OK4JJ5PP.js → caffeinate-hold-FNKIPXDU.js} +2 -2
  14. package/dist/{caffeinate-hold-22VFDPSO.js → caffeinate-hold-PXHGH7ZN.js} +2 -2
  15. package/dist/{chunk-7J72QJOM.js → chunk-224IXQOM.js} +1 -1
  16. package/dist/{chunk-4VGCG2HV.js → chunk-3AJUH66R.js} +2 -2
  17. package/dist/{chunk-P6ZM5QJW.js → chunk-3PGFAVFL.js} +2 -2
  18. package/dist/{chunk-RZTRWN2V.js → chunk-4H5WO4H3.js} +1 -1
  19. package/dist/{chunk-MVLXDYN5.js → chunk-5ELC3KK3.js} +5 -5
  20. package/dist/{chunk-WPD7BR6C.js → chunk-5SHYLRTU.js} +1 -1
  21. package/dist/{chunk-S2OEFXST.js → chunk-5UN5C5WP.js} +5 -5
  22. package/dist/{chunk-RKKTCKVX.js → chunk-6Q2CFQ4D.js} +85 -31
  23. package/dist/{chunk-WFUDY6PC.js → chunk-A4JGXX2F.js} +155 -24
  24. package/dist/{chunk-NOIWXANG.js → chunk-ANGPU5JL.js} +284 -15
  25. package/dist/{chunk-GHRZNPBK.js → chunk-C2CBF4YE.js} +2 -2
  26. package/dist/{chunk-TNVJPFHM.js → chunk-CJKL7A4G.js} +5 -5
  27. package/dist/{chunk-SWNEA5OZ.js → chunk-CRAXJAYJ.js} +3 -3
  28. package/dist/{chunk-C774RJJA.js → chunk-CWHMLCLN.js} +3 -3
  29. package/dist/{chunk-YWI3IBP2.js → chunk-DQN5U2VH.js} +1 -1
  30. package/dist/{chunk-2UBVFL2X.js → chunk-DYXNBXE3.js} +306 -17
  31. package/dist/{chunk-SPAMHHJH.js → chunk-J5GON4SU.js} +1 -1
  32. package/dist/{chunk-4VFOJZPS.js → chunk-JXZS56VW.js} +3 -3
  33. package/dist/{chunk-EQNRWDLN.js → chunk-KK63BFYN.js} +151 -24
  34. package/dist/{chunk-X5B3OS5I.js → chunk-N6XI5KXL.js} +1 -1
  35. package/dist/{chunk-XJETIO4K.js → chunk-NJ5OXOTN.js} +2 -2
  36. package/dist/{chunk-RGNPPRZZ.js → chunk-NYAEMZ3L.js} +3 -3
  37. package/dist/{chunk-7H2CVVLF.js → chunk-O3UAQAYA.js} +3 -3
  38. package/dist/{chunk-4TYXWPAJ.js → chunk-OJFEVWZN.js} +1 -1
  39. package/dist/{chunk-I5NC7DWO.js → chunk-P3DCZRER.js} +1 -1
  40. package/dist/{chunk-TWXSZYR2.js → chunk-RRXRLHIE.js} +5 -5
  41. package/dist/{chunk-AS4UN7QL.js → chunk-VVOAXBND.js} +5 -5
  42. package/dist/{chunk-LEYY54BN.js → chunk-XMCJDWPA.js} +88 -33
  43. package/dist/{connected-teams-KQUDU7LZ.js → connected-teams-62AJRDDD.js} +2 -2
  44. package/dist/{connected-teams-JUJAQZZE.js → connected-teams-GXV22ZSF.js} +2 -2
  45. package/dist/{coordinator-prompt-CE7MN6QY.js → coordinator-prompt-2BRUH7PJ.js} +6 -6
  46. package/dist/{coordinator-prompt-IGDMFKCD.js → coordinator-prompt-BIP7ZEJ3.js} +6 -6
  47. package/dist/{cursor-recover-DTQAUDGO.js → cursor-recover-DFMCTZA4.js} +2 -2
  48. package/dist/{cursor-recover-4PQAADAU.js → cursor-recover-K3EBEM7M.js} +2 -2
  49. package/dist/{global-workspace-7WH24UFO.js → global-workspace-3XZN3QHZ.js} +6 -6
  50. package/dist/{global-workspace-NCIC2Y2U.js → global-workspace-DWCFG7LP.js} +6 -6
  51. package/dist/index.cjs +1232 -709
  52. package/dist/index.d.cts +70 -1
  53. package/dist/index.d.ts +70 -1
  54. package/dist/index.js +79 -23
  55. package/dist/mcp/run-stdio.cjs +1134 -660
  56. package/dist/mcp/run-stdio.js +45 -22
  57. package/dist/{orchestrator-7ZEGFPK4.js → orchestrator-AYPDBGIF.js} +10 -10
  58. package/dist/{orchestrator-R2WCTNJI.js → orchestrator-TEJJAQWP.js} +11 -11
  59. package/dist/{paths-C2VERLAE.js → paths-LGKOG7MY.js} +1 -1
  60. package/dist/{paths-LOXCISLX.js → paths-O6ZEAEUD.js} +1 -1
  61. package/dist/{thread-store-IKJD4EOK.js → thread-store-AYPBEZT5.js} +3 -3
  62. package/dist/{thread-store-FBK5SZ5P.js → thread-store-YOPKY74K.js} +3 -3
  63. package/dist/{workspaces-H2TRFDE2.js → workspaces-NYT2472Z.js} +6 -6
  64. package/dist/{workspaces-NSQZSDQD.js → workspaces-V7522TQH.js} +6 -6
  65. package/dist/{worktree-W7BSI4GU.js → worktree-AGVPKDBH.js} +5 -5
  66. package/dist/{worktree-FMIX4BRV.js → worktree-IRALYI6A.js} +5 -5
  67. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -220,10 +220,139 @@ var init_cursor_worktrees = __esm({
220
220
  }
221
221
  });
222
222
 
223
+ // src/hook/dev-preview.ts
224
+ function parseDevPreview(raw) {
225
+ return raw === "url" || raw === "window" ? raw : void 0;
226
+ }
227
+ function commandLooksLikeElectron(command) {
228
+ return ELECTRON_CMD_RE.test(command);
229
+ }
230
+ function pnpmFilterPackage(command) {
231
+ const m = command.match(PNPM_FILTER_RE);
232
+ return m?.[1] ?? m?.[2] ?? m?.[3] ?? null;
233
+ }
234
+ function readJsonObject(path2) {
235
+ try {
236
+ const raw = JSON.parse((0, import_node_fs3.readFileSync)(path2, "utf8"));
237
+ return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : null;
238
+ } catch {
239
+ return null;
240
+ }
241
+ }
242
+ function packageLooksLikeElectron(pkg) {
243
+ const deps = {
244
+ ...pkg.dependencies,
245
+ ...pkg.devDependencies,
246
+ ...pkg.optionalDependencies
247
+ };
248
+ if (deps.electron || deps["electron-vite"] || deps["electron-builder"] || deps["@electron-forge/cli"] || deps["electron-forge"]) {
249
+ return true;
250
+ }
251
+ const scripts = pkg.scripts;
252
+ if (scripts && typeof scripts === "object") {
253
+ for (const value of Object.values(scripts)) {
254
+ if (typeof value === "string" && commandLooksLikeElectron(value)) {
255
+ return true;
256
+ }
257
+ }
258
+ }
259
+ return false;
260
+ }
261
+ function findPackageJsonByName(root, name, budget = 80) {
262
+ const queue = [root];
263
+ let seen = 0;
264
+ while (queue.length && seen < budget) {
265
+ const dir = queue.shift();
266
+ const pkgPath = (0, import_node_path3.join)(dir, "package.json");
267
+ if ((0, import_node_fs3.existsSync)(pkgPath)) {
268
+ seen += 1;
269
+ const pkg = readJsonObject(pkgPath);
270
+ if (pkg?.name === name) return pkgPath;
271
+ }
272
+ let entries;
273
+ try {
274
+ entries = (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true });
275
+ } catch {
276
+ continue;
277
+ }
278
+ for (const entry of entries) {
279
+ if (!entry.isDirectory() || entry.isSymbolicLink() || SKIP_DIR.has(entry.name) || entry.name.startsWith(".")) {
280
+ continue;
281
+ }
282
+ queue.push((0, import_node_path3.join)(dir, entry.name));
283
+ }
284
+ }
285
+ return null;
286
+ }
287
+ function classifyRunScriptPreview(opts) {
288
+ if (opts.preview === "url" || opts.preview === "window") return opts.preview;
289
+ if (commandLooksLikeElectron(opts.command)) return "window";
290
+ const root = opts.worktreePath?.trim();
291
+ if (!root) return "url";
292
+ const filter = pnpmFilterPackage(opts.command);
293
+ if (filter) {
294
+ if (filter.startsWith(".") || filter.startsWith("/")) {
295
+ const pkg = readJsonObject((0, import_node_path3.join)(root, filter, "package.json"));
296
+ if (pkg && packageLooksLikeElectron(pkg)) return "window";
297
+ } else {
298
+ const found = findPackageJsonByName(root, filter);
299
+ if (found) {
300
+ const pkg = readJsonObject(found);
301
+ if (pkg && packageLooksLikeElectron(pkg)) return "window";
302
+ return "url";
303
+ }
304
+ }
305
+ }
306
+ const rootPkg = readJsonObject((0, import_node_path3.join)(root, "package.json"));
307
+ if (rootPkg && packageLooksLikeElectron(rootPkg)) return "window";
308
+ return "url";
309
+ }
310
+ function runScriptPreview(script, worktreePath) {
311
+ if (!script) return "url";
312
+ return classifyRunScriptPreview({
313
+ command: script.command,
314
+ preview: script.preview,
315
+ worktreePath
316
+ });
317
+ }
318
+ function activeRunPreview(scriptName, scripts, worktreePath) {
319
+ return runScriptPreview(
320
+ scripts.find((s) => s.name === scriptName),
321
+ worktreePath
322
+ );
323
+ }
324
+ function annotateDevAccessRuns(runs, scripts, worktreePath) {
325
+ return runs.map((run2) => ({
326
+ ...run2,
327
+ preview: activeRunPreview(run2.scriptName, scripts, worktreePath)
328
+ }));
329
+ }
330
+ var import_node_fs3, import_node_path3, ELECTRON_CMD_RE, PNPM_FILTER_RE, SKIP_DIR;
331
+ var init_dev_preview = __esm({
332
+ "src/hook/dev-preview.ts"() {
333
+ "use strict";
334
+ import_node_fs3 = require("fs");
335
+ import_node_path3 = require("path");
336
+ ELECTRON_CMD_RE = /\belectron(?:-vite|-forge|-builder|mon)?\b/i;
337
+ PNPM_FILTER_RE = /--filter(?:=|\s+)(?:"([^"]+)"|'([^']+)'|([^\s]+))/;
338
+ SKIP_DIR = /* @__PURE__ */ new Set([
339
+ "node_modules",
340
+ "dist",
341
+ "out",
342
+ "coverage",
343
+ ".git",
344
+ ".context",
345
+ ".next",
346
+ ".turbo",
347
+ ".output"
348
+ ]);
349
+ }
350
+ });
351
+
223
352
  // src/hook/settings.ts
224
353
  function expandHome(path2) {
225
354
  if (path2.startsWith("~/") || path2 === "~") {
226
- return (0, import_node_path3.join)((0, import_node_os.homedir)(), path2.slice(2));
355
+ return (0, import_node_path4.join)((0, import_node_os.homedir)(), path2.slice(2));
227
356
  }
228
357
  return path2;
229
358
  }
@@ -236,8 +365,8 @@ function parseAvailableIn(raw) {
236
365
  return out.length ? out : void 0;
237
366
  }
238
367
  function parseSettingsFile(path2, source) {
239
- if (!(0, import_node_fs3.existsSync)(path2)) return null;
240
- const raw = (0, import_node_fs3.readFileSync)(path2, "utf8");
368
+ if (!(0, import_node_fs4.existsSync)(path2)) return null;
369
+ const raw = (0, import_node_fs4.readFileSync)(path2, "utf8");
241
370
  const data = (0, import_smol_toml.parse)(raw);
242
371
  const scripts = data.scripts ?? {};
243
372
  const setup = typeof scripts.setup === "string" ? scripts.setup : void 0;
@@ -275,7 +404,8 @@ function parseSettingsFile(path2, source) {
275
404
  command: value.command,
276
405
  default: Boolean(value.default),
277
406
  icon: typeof value.icon === "string" ? value.icon : void 0,
278
- availableIn: parseAvailableIn(value.available_in)
407
+ availableIn: parseAvailableIn(value.available_in),
408
+ preview: parseDevPreview(value.preview)
279
409
  });
280
410
  }
281
411
  }
@@ -346,15 +476,15 @@ function finalizeSettings(parsed) {
346
476
  };
347
477
  }
348
478
  function familyFiles(rootPath, source) {
349
- const dir = (0, import_node_path3.join)(rootPath, `.${source}`);
479
+ const dir = (0, import_node_path4.join)(rootPath, `.${source}`);
350
480
  return {
351
- toml: (0, import_node_path3.join)(dir, "settings.toml"),
352
- local: (0, import_node_path3.join)(dir, "settings.local.toml")
481
+ toml: (0, import_node_path4.join)(dir, "settings.toml"),
482
+ local: (0, import_node_path4.join)(dir, "settings.local.toml")
353
483
  };
354
484
  }
355
485
  function familyExists(rootPath, source) {
356
486
  const files = familyFiles(rootPath, source);
357
- return (0, import_node_fs3.existsSync)(files.toml) || (0, import_node_fs3.existsSync)(files.local);
487
+ return (0, import_node_fs4.existsSync)(files.toml) || (0, import_node_fs4.existsSync)(files.local);
358
488
  }
359
489
  function detectFamily(rootPath) {
360
490
  if (familyExists(rootPath, "sideboard")) return "sideboard";
@@ -417,10 +547,10 @@ function settingsSourceLabel(rootPath) {
417
547
  const family = detectFamily(rootPath);
418
548
  if (!family) return null;
419
549
  const files = familyFiles(rootPath, family);
420
- if ((0, import_node_fs3.existsSync)(files.toml) && (0, import_node_fs3.existsSync)(files.local)) {
550
+ if ((0, import_node_fs4.existsSync)(files.toml) && (0, import_node_fs4.existsSync)(files.local)) {
421
551
  return `.${family}/settings.toml + local`;
422
552
  }
423
- if ((0, import_node_fs3.existsSync)(files.local)) return `.${family}/settings.local.toml`;
553
+ if ((0, import_node_fs4.existsSync)(files.local)) return `.${family}/settings.local.toml`;
424
554
  return `.${family}/settings.toml`;
425
555
  }
426
556
  function workspaceSettingsSourceLabel(worktreePath, repoPath) {
@@ -451,16 +581,17 @@ function getRepoSetupInfo(worktreePath, repoPath) {
451
581
  ...settings?.prompts ? { prompts: settings.prompts } : {}
452
582
  };
453
583
  }
454
- var import_node_fs3, import_node_os, import_node_path3, import_smol_toml;
584
+ var import_node_fs4, import_node_os, import_node_path4, import_smol_toml;
455
585
  var init_settings = __esm({
456
586
  "src/hook/settings.ts"() {
457
587
  "use strict";
458
- import_node_fs3 = require("fs");
588
+ import_node_fs4 = require("fs");
459
589
  import_node_os = require("os");
460
- import_node_path3 = require("path");
590
+ import_node_path4 = require("path");
461
591
  import_smol_toml = require("smol-toml");
462
592
  init_convention_setup();
463
593
  init_cursor_worktrees();
594
+ init_dev_preview();
464
595
  }
465
596
  });
466
597
 
@@ -482,70 +613,70 @@ __export(paths_exports, {
482
613
  });
483
614
  function appDataDir() {
484
615
  const override = process.env.SIDEBOARD_APP_DATA?.trim();
485
- 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");
486
- (0, import_node_fs4.mkdirSync)(base, { recursive: true });
616
+ const base = override ? override : process.platform === "darwin" ? (0, import_node_path6.join)((0, import_node_os2.homedir)(), "Library", "Application Support", "sideboard") : process.platform === "win32" ? (0, import_node_path6.join)(process.env.APPDATA ?? (0, import_node_path6.join)((0, import_node_os2.homedir)(), "AppData", "Roaming"), "sideboard") : (0, import_node_path6.join)((0, import_node_os2.homedir)(), ".local", "share", "sideboard");
617
+ (0, import_node_fs5.mkdirSync)(base, { recursive: true });
487
618
  return base;
488
619
  }
489
620
  function threadsDir() {
490
- const dir = (0, import_node_path5.join)(appDataDir(), "threads");
491
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
621
+ const dir = (0, import_node_path6.join)(appDataDir(), "threads");
622
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
492
623
  return dir;
493
624
  }
494
625
  function locksDir() {
495
- const dir = (0, import_node_path5.join)(appDataDir(), "locks");
496
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
626
+ const dir = (0, import_node_path6.join)(appDataDir(), "locks");
627
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
497
628
  return dir;
498
629
  }
499
630
  function sideboardHomeDir() {
500
- const dir = (0, import_node_path5.join)((0, import_node_os2.homedir)(), "sideboard");
501
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
631
+ const dir = (0, import_node_path6.join)((0, import_node_os2.homedir)(), "sideboard");
632
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
502
633
  return dir;
503
634
  }
504
635
  function sideboardReposDir() {
505
- const dir = (0, import_node_path5.join)(sideboardHomeDir(), "repos");
506
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
636
+ const dir = (0, import_node_path6.join)(sideboardHomeDir(), "repos");
637
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
507
638
  return dir;
508
639
  }
509
640
  function sideboardWorkspacesDir() {
510
- const dir = (0, import_node_path5.join)(sideboardHomeDir(), "workspaces");
511
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
641
+ const dir = (0, import_node_path6.join)(sideboardHomeDir(), "workspaces");
642
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
512
643
  return dir;
513
644
  }
514
645
  function repoSlug(repoPath) {
515
- return (0, import_node_path4.basename)(repoPath.replace(/\/$/, "")) || "repo";
646
+ return (0, import_node_path5.basename)(repoPath.replace(/\/$/, "")) || "repo";
516
647
  }
517
648
  function worktreesRoot(repoPath) {
518
649
  const settings = loadRepoSettings(repoPath);
519
650
  if (settings?.worktreesRoot) {
520
- (0, import_node_fs4.mkdirSync)(settings.worktreesRoot, { recursive: true });
651
+ (0, import_node_fs5.mkdirSync)(settings.worktreesRoot, { recursive: true });
521
652
  return settings.worktreesRoot;
522
653
  }
523
- const dir = (0, import_node_path5.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
524
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
654
+ const dir = (0, import_node_path6.join)(sideboardWorkspacesDir(), repoSlug(repoPath));
655
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
525
656
  return dir;
526
657
  }
527
658
  function threadFilePath(id) {
528
- return (0, import_node_path5.join)(threadsDir(), `${id}.json`);
659
+ return (0, import_node_path6.join)(threadsDir(), `${id}.json`);
529
660
  }
530
661
  function threadLivePath(id) {
531
- return (0, import_node_path5.join)(threadsDir(), `${id}.live.json`);
662
+ return (0, import_node_path6.join)(threadsDir(), `${id}.live.json`);
532
663
  }
533
664
  function threadLockPath(id) {
534
- return (0, import_node_path5.join)(locksDir(), `${id}.lock`);
665
+ return (0, import_node_path6.join)(locksDir(), `${id}.lock`);
535
666
  }
536
667
  function globalAgentCwd() {
537
- const dir = (0, import_node_path5.join)(appDataDir(), "global");
538
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
668
+ const dir = (0, import_node_path6.join)(appDataDir(), "global");
669
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
539
670
  return dir;
540
671
  }
541
- var import_node_path4, import_node_os2, import_node_path5, import_node_fs4;
672
+ var import_node_path5, import_node_os2, import_node_path6, import_node_fs5;
542
673
  var init_paths = __esm({
543
674
  "src/store/paths.ts"() {
544
675
  "use strict";
545
- import_node_path4 = require("path");
546
- import_node_os2 = require("os");
547
676
  import_node_path5 = require("path");
548
- import_node_fs4 = require("fs");
677
+ import_node_os2 = require("os");
678
+ import_node_path6 = require("path");
679
+ import_node_fs5 = require("fs");
549
680
  init_settings();
550
681
  }
551
682
  });
@@ -740,22 +871,22 @@ var init_account_profile = __esm({
740
871
 
741
872
  // src/store/private-file.ts
742
873
  function writePrivateFile(path2, contents) {
743
- (0, import_node_fs5.mkdirSync)((0, import_node_path6.dirname)(path2), { recursive: true });
744
- (0, import_node_fs5.writeFileSync)(path2, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
874
+ (0, import_node_fs6.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true });
875
+ (0, import_node_fs6.writeFileSync)(path2, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
745
876
  chmodOwnerOnly(path2);
746
877
  }
747
878
  function chmodOwnerOnly(path2) {
748
879
  try {
749
- (0, import_node_fs5.chmodSync)(path2, PRIVATE_FILE_MODE);
880
+ (0, import_node_fs6.chmodSync)(path2, PRIVATE_FILE_MODE);
750
881
  } catch {
751
882
  }
752
883
  }
753
- var import_node_fs5, import_node_path6, PRIVATE_FILE_MODE;
884
+ var import_node_fs6, import_node_path7, PRIVATE_FILE_MODE;
754
885
  var init_private_file = __esm({
755
886
  "src/store/private-file.ts"() {
756
887
  "use strict";
757
- import_node_fs5 = require("fs");
758
- import_node_path6 = require("path");
888
+ import_node_fs6 = require("fs");
889
+ import_node_path7 = require("path");
759
890
  PRIVATE_FILE_MODE = 384;
760
891
  }
761
892
  });
@@ -847,11 +978,11 @@ function decryptEnvelope(envelope, key) {
847
978
  return JSON.parse(plaintext.toString("utf8"));
848
979
  }
849
980
  function readSecureJson(path2) {
850
- if (!(0, import_node_fs6.existsSync)(path2)) return null;
981
+ if (!(0, import_node_fs7.existsSync)(path2)) return null;
851
982
  chmodOwnerOnly(path2);
852
983
  let parsed;
853
984
  try {
854
- parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
985
+ parsed = JSON.parse((0, import_node_fs7.readFileSync)(path2, "utf8"));
855
986
  } catch {
856
987
  return null;
857
988
  }
@@ -871,17 +1002,17 @@ function writeSecureJson(path2, value) {
871
1002
  `);
872
1003
  }
873
1004
  function isSecureFileEncrypted(path2) {
874
- if (!(0, import_node_fs6.existsSync)(path2)) return false;
1005
+ if (!(0, import_node_fs7.existsSync)(path2)) return false;
875
1006
  try {
876
- return isEnvelope(JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8")));
1007
+ return isEnvelope(JSON.parse((0, import_node_fs7.readFileSync)(path2, "utf8")));
877
1008
  } catch {
878
1009
  return false;
879
1010
  }
880
1011
  }
881
1012
  function secureFileUnlocksWith(path2, key) {
882
- if (!(0, import_node_fs6.existsSync)(path2) || key.length !== 32) return true;
1013
+ if (!(0, import_node_fs7.existsSync)(path2) || key.length !== 32) return true;
883
1014
  try {
884
- const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf8"));
1015
+ const parsed = JSON.parse((0, import_node_fs7.readFileSync)(path2, "utf8"));
885
1016
  if (!isEnvelope(parsed)) return true;
886
1017
  decryptEnvelope(parsed, key);
887
1018
  return true;
@@ -889,13 +1020,13 @@ function secureFileUnlocksWith(path2, key) {
889
1020
  return false;
890
1021
  }
891
1022
  }
892
- var import_node_child_process, import_node_crypto, import_node_fs6, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
1023
+ var import_node_child_process, import_node_crypto, import_node_fs7, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, ALG, injectedKey;
893
1024
  var init_secure_file = __esm({
894
1025
  "src/store/secure-file.ts"() {
895
1026
  "use strict";
896
1027
  import_node_child_process = require("child_process");
897
1028
  import_node_crypto = require("crypto");
898
- import_node_fs6 = require("fs");
1029
+ import_node_fs7 = require("fs");
899
1030
  init_private_file();
900
1031
  KEYCHAIN_SERVICE = "ai.sideboard.app";
901
1032
  KEYCHAIN_ACCOUNT = "secret-vault-v1";
@@ -906,7 +1037,7 @@ var init_secure_file = __esm({
906
1037
 
907
1038
  // src/store/secret-vault.ts
908
1039
  function secretVaultPath() {
909
- return (0, import_node_path7.join)(appDataDir(), "secrets.json");
1040
+ return (0, import_node_path8.join)(appDataDir(), "secrets.json");
910
1041
  }
911
1042
  function loadSecretVault() {
912
1043
  const parsed = readSecureJson(secretVaultPath());
@@ -968,11 +1099,11 @@ function normalizeVault(raw) {
968
1099
  }
969
1100
  return out;
970
1101
  }
971
- var import_node_path7;
1102
+ var import_node_path8;
972
1103
  var init_secret_vault = __esm({
973
1104
  "src/store/secret-vault.ts"() {
974
1105
  "use strict";
975
- import_node_path7 = require("path");
1106
+ import_node_path8 = require("path");
976
1107
  init_paths();
977
1108
  init_secure_file();
978
1109
  }
@@ -1398,10 +1529,10 @@ function toPublicAppSettings(settings) {
1398
1529
  };
1399
1530
  }
1400
1531
  function appSettingsPath() {
1401
- return (0, import_node_path8.join)(appDataDir(), "settings.json");
1532
+ return (0, import_node_path9.join)(appDataDir(), "settings.json");
1402
1533
  }
1403
1534
  function claudeUserSettingsPath() {
1404
- return (0, import_node_path8.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
1535
+ return (0, import_node_path9.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
1405
1536
  }
1406
1537
  function normalizeClaude(raw) {
1407
1538
  if (!raw || typeof raw !== "object") return {};
@@ -1409,7 +1540,7 @@ function normalizeClaude(raw) {
1409
1540
  const out = {};
1410
1541
  if (typeof source.executablePath === "string") {
1411
1542
  const path2 = source.executablePath.trim();
1412
- if (path2 && (0, import_node_path8.isAbsolute)(path2)) out.executablePath = path2;
1543
+ if (path2 && (0, import_node_path9.isAbsolute)(path2)) out.executablePath = path2;
1413
1544
  }
1414
1545
  if (typeof source.chromeEnabled === "boolean") {
1415
1546
  out.chromeEnabled = source.chromeEnabled;
@@ -1422,13 +1553,13 @@ function normalizeCliExecutable(raw) {
1422
1553
  const out = {};
1423
1554
  if (typeof source.executablePath === "string") {
1424
1555
  const path2 = source.executablePath.trim();
1425
- if (path2 && (0, import_node_path8.isAbsolute)(path2)) out.executablePath = path2;
1556
+ if (path2 && (0, import_node_path9.isAbsolute)(path2)) out.executablePath = path2;
1426
1557
  }
1427
1558
  return out;
1428
1559
  }
1429
1560
  function absoluteExecutablePath(value) {
1430
1561
  const path2 = value.trim();
1431
- if (!(0, import_node_path8.isAbsolute)(path2)) {
1562
+ if (!(0, import_node_path9.isAbsolute)(path2)) {
1432
1563
  throw new Error("Executable path must be absolute. Leave it empty to use the system CLI.");
1433
1564
  }
1434
1565
  return path2;
@@ -1439,7 +1570,7 @@ function normalizeBrightsy(raw) {
1439
1570
  const out = {};
1440
1571
  if (typeof source.executablePath === "string") {
1441
1572
  const path2 = source.executablePath.trim();
1442
- if (path2 && (0, import_node_path8.isAbsolute)(path2)) out.executablePath = path2;
1573
+ if (path2 && (0, import_node_path9.isAbsolute)(path2)) out.executablePath = path2;
1443
1574
  }
1444
1575
  if (typeof source.cloudConnectEnabled === "boolean") {
1445
1576
  out.cloudConnectEnabled = source.cloudConnectEnabled;
@@ -1828,10 +1959,10 @@ function normalizeSettings(raw) {
1828
1959
  }
1829
1960
  function readSettingsFile() {
1830
1961
  const path2 = appSettingsPath();
1831
- if (!(0, import_node_fs7.existsSync)(path2)) return { ...EMPTY_SETTINGS };
1962
+ if (!(0, import_node_fs8.existsSync)(path2)) return { ...EMPTY_SETTINGS };
1832
1963
  try {
1833
1964
  chmodOwnerOnly(path2);
1834
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)(path2, "utf8"));
1965
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path2, "utf8"));
1835
1966
  return normalizeSettings(parsed);
1836
1967
  } catch {
1837
1968
  return { ...EMPTY_SETTINGS };
@@ -2841,14 +2972,14 @@ function childEnvWithAppSettings(extra) {
2841
2972
  function harnessEnvKey(harness) {
2842
2973
  return HARNESS_ENV_KEYS[harness];
2843
2974
  }
2844
- var import_node_crypto2, import_node_fs7, import_node_os3, import_node_path8, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, FOLLOW_UP_BEHAVIORS, AGENT_DONE_SOUNDS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
2975
+ var import_node_crypto2, import_node_fs8, import_node_os3, import_node_path9, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, FOLLOW_UP_BEHAVIORS, AGENT_DONE_SOUNDS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
2845
2976
  var init_app_settings = __esm({
2846
2977
  "src/store/app-settings.ts"() {
2847
2978
  "use strict";
2848
2979
  import_node_crypto2 = require("crypto");
2849
- import_node_fs7 = require("fs");
2980
+ import_node_fs8 = require("fs");
2850
2981
  import_node_os3 = require("os");
2851
- import_node_path8 = require("path");
2982
+ import_node_path9 = require("path");
2852
2983
  init_orchestrator_capable();
2853
2984
  init_thinking_effort();
2854
2985
  init_nested_electron_env();
@@ -2934,7 +3065,7 @@ function setCaffeinateHoldHooks(next) {
2934
3065
  hooks = next;
2935
3066
  }
2936
3067
  function caffeinateHoldPath() {
2937
- return (0, import_node_path10.join)(appDataDir(), "caffeinate-hold.json");
3068
+ return (0, import_node_path11.join)(appDataDir(), "caffeinate-hold.json");
2938
3069
  }
2939
3070
  function processAlive(pid) {
2940
3071
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -2968,9 +3099,9 @@ function uniqueIds(ids) {
2968
3099
  }
2969
3100
  function readHold() {
2970
3101
  const path2 = caffeinateHoldPath();
2971
- if (!(0, import_node_fs9.existsSync)(path2)) return null;
3102
+ if (!(0, import_node_fs10.existsSync)(path2)) return null;
2972
3103
  try {
2973
- const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path2, "utf8"));
3104
+ const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path2, "utf8"));
2974
3105
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
2975
3106
  return {
2976
3107
  pid: parsed.pid,
@@ -2992,7 +3123,7 @@ function writeHold(pid, threadIds) {
2992
3123
  }
2993
3124
  function clearHold() {
2994
3125
  try {
2995
- (0, import_node_fs9.unlinkSync)(caffeinateHoldPath());
3126
+ (0, import_node_fs10.unlinkSync)(caffeinateHoldPath());
2996
3127
  } catch {
2997
3128
  }
2998
3129
  }
@@ -3077,13 +3208,13 @@ function releaseCaffeinateHoldForThread(threadId) {
3077
3208
  }
3078
3209
  return setCaffeinateHold(false, { threadId: id });
3079
3210
  }
3080
- var import_node_child_process2, import_node_fs9, import_node_path10, hooks;
3211
+ var import_node_child_process2, import_node_fs10, import_node_path11, hooks;
3081
3212
  var init_caffeinate_hold = __esm({
3082
3213
  "src/store/caffeinate-hold.ts"() {
3083
3214
  "use strict";
3084
3215
  import_node_child_process2 = require("child_process");
3085
- import_node_fs9 = require("fs");
3086
- import_node_path10 = require("path");
3216
+ import_node_fs10 = require("fs");
3217
+ import_node_path11 = require("path");
3087
3218
  init_paths();
3088
3219
  init_private_file();
3089
3220
  hooks = {};
@@ -3092,13 +3223,13 @@ var init_caffeinate_hold = __esm({
3092
3223
 
3093
3224
  // src/agents/cursor-store.ts
3094
3225
  function cursorSdkStoreDir(threadId) {
3095
- const root = (0, import_node_path11.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
3226
+ const root = (0, import_node_path12.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
3096
3227
  const id = sanitizeCursorStoreSegment(threadId);
3097
3228
  if (!id) return root;
3098
- return (0, import_node_path11.join)(root, "threads", id);
3229
+ return (0, import_node_path12.join)(root, "threads", id);
3099
3230
  }
3100
3231
  function cursorSdkRunsNdjsonPath(threadId) {
3101
- return (0, import_node_path11.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
3232
+ return (0, import_node_path12.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
3102
3233
  }
3103
3234
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
3104
3235
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -3111,11 +3242,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
3111
3242
  function sanitizeCursorStoreSegment(threadId) {
3112
3243
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
3113
3244
  }
3114
- var import_node_path11, CURSOR_SDK_STORE_DIR;
3245
+ var import_node_path12, CURSOR_SDK_STORE_DIR;
3115
3246
  var init_cursor_store = __esm({
3116
3247
  "src/agents/cursor-store.ts"() {
3117
3248
  "use strict";
3118
- import_node_path11 = require("path");
3249
+ import_node_path12 = require("path");
3119
3250
  init_paths();
3120
3251
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
3121
3252
  }
@@ -3242,7 +3373,7 @@ function createEmptyThread(partial) {
3242
3373
  }
3243
3374
  async function withThreadLock(id, fn) {
3244
3375
  const lockPath = threadLockPath(id);
3245
- (0, import_node_fs10.writeFileSync)(lockPath, "", { flag: "a" });
3376
+ (0, import_node_fs11.writeFileSync)(lockPath, "", { flag: "a" });
3246
3377
  let release;
3247
3378
  try {
3248
3379
  release = await import_proper_lockfile.default.lock(lockPath, {
@@ -3263,7 +3394,7 @@ function cacheForDir() {
3263
3394
  }
3264
3395
  function fileMtimeMs(path2) {
3265
3396
  try {
3266
- return (0, import_node_fs10.statSync)(path2).mtimeMs;
3397
+ return (0, import_node_fs11.statSync)(path2).mtimeMs;
3267
3398
  } catch {
3268
3399
  return null;
3269
3400
  }
@@ -3296,7 +3427,7 @@ function readThread(id) {
3296
3427
  const cache2 = cacheForDir();
3297
3428
  const cached = cache2.byId.get(id);
3298
3429
  if (cached && cache2.mtimeMs.get(id) === mtimeMs) return cached;
3299
- const raw = (0, import_node_fs10.readFileSync)(path2, "utf8");
3430
+ const raw = (0, import_node_fs11.readFileSync)(path2, "utf8");
3300
3431
  const thread = normalizeThread(JSON.parse(raw));
3301
3432
  rememberThread(thread, mtimeMs);
3302
3433
  return thread;
@@ -3305,8 +3436,8 @@ function writeThread(thread, opts) {
3305
3436
  const path2 = threadFilePath(idPath(thread.id));
3306
3437
  const tmp = `${path2}.${process.pid}.tmp`;
3307
3438
  const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
3308
- (0, import_node_fs10.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
3309
- (0, import_node_fs10.renameSync)(tmp, path2);
3439
+ (0, import_node_fs11.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
3440
+ (0, import_node_fs11.renameSync)(tmp, path2);
3310
3441
  const mtimeMs = fileMtimeMs(path2) ?? Date.now();
3311
3442
  rememberThread(next, mtimeMs);
3312
3443
  selfWriteMtimes.set(thread.id, mtimeMs);
@@ -3320,12 +3451,12 @@ function idPath(id) {
3320
3451
  return id;
3321
3452
  }
3322
3453
  function isThreadRecordFile(nameOrPath) {
3323
- const name = (0, import_node_path12.basename)(nameOrPath);
3454
+ const name = (0, import_node_path13.basename)(nameOrPath);
3324
3455
  return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
3325
3456
  }
3326
3457
  function listThreads(opts) {
3327
3458
  const cache2 = cacheForDir();
3328
- const files = (0, import_node_fs10.readdirSync)(threadsDir()).filter(isThreadRecordFile);
3459
+ const files = (0, import_node_fs11.readdirSync)(threadsDir()).filter(isThreadRecordFile);
3329
3460
  const seen = /* @__PURE__ */ new Set();
3330
3461
  for (const f of files) {
3331
3462
  const id = f.replace(/\.json$/, "");
@@ -3348,16 +3479,16 @@ function listThreads(opts) {
3348
3479
  function deleteThreadRecord(id) {
3349
3480
  forgetThread(id);
3350
3481
  const path2 = threadFilePath(id);
3351
- if ((0, import_node_fs10.existsSync)(path2)) (0, import_node_fs10.unlinkSync)(path2);
3482
+ if ((0, import_node_fs11.existsSync)(path2)) (0, import_node_fs11.unlinkSync)(path2);
3352
3483
  const lock = threadLockPath(id);
3353
- if ((0, import_node_fs10.existsSync)(lock)) {
3484
+ if ((0, import_node_fs11.existsSync)(lock)) {
3354
3485
  try {
3355
- (0, import_node_fs10.unlinkSync)(lock);
3486
+ (0, import_node_fs11.unlinkSync)(lock);
3356
3487
  } catch {
3357
3488
  }
3358
3489
  }
3359
3490
  try {
3360
- (0, import_node_fs10.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
3491
+ (0, import_node_fs11.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
3361
3492
  } catch {
3362
3493
  }
3363
3494
  }
@@ -3387,13 +3518,13 @@ function findThreadByRef(ref) {
3387
3518
  (t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
3388
3519
  ) ?? null;
3389
3520
  }
3390
- var import_node_crypto3, import_node_fs10, import_node_path12, import_proper_lockfile, listCache, selfWriteMtimes;
3521
+ var import_node_crypto3, import_node_fs11, import_node_path13, import_proper_lockfile, listCache, selfWriteMtimes;
3391
3522
  var init_thread_store = __esm({
3392
3523
  "src/store/thread-store.ts"() {
3393
3524
  "use strict";
3394
3525
  import_node_crypto3 = require("crypto");
3395
- import_node_fs10 = require("fs");
3396
- import_node_path12 = require("path");
3526
+ import_node_fs11 = require("fs");
3527
+ import_node_path13 = require("path");
3397
3528
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
3398
3529
  init_thinking_effort();
3399
3530
  init_cursor_store();
@@ -3833,7 +3964,76 @@ function visibleToolRowDetail(detail, description, worktreePath) {
3833
3964
  if (parts.length >= 2) return `\u2026/${parts.slice(-2).join("/")}`;
3834
3965
  return base;
3835
3966
  }
3967
+ function isSkillToolName(name) {
3968
+ const n = (name ?? "").trim();
3969
+ if (/^(Skill|SlashCommand)$/i.test(n)) return true;
3970
+ return /(?:^|__)Skill$/i.test(n);
3971
+ }
3972
+ function skillCommandFromInput(input) {
3973
+ const raw = str(input?.skill) ?? str(input?.command) ?? str(input?.name) ?? str(input?.skill_name) ?? str(input?.skillName);
3974
+ if (raw) return raw.replace(/^\//, "").trim() || void 0;
3975
+ const path2 = str(input?.file_path) ?? str(input?.path);
3976
+ if (path2 && /SKILL\.md$/i.test(path2)) {
3977
+ const parts = path2.replace(/\\/g, "/").split("/");
3978
+ const dir = parts[parts.length - 2];
3979
+ if (dir && dir !== "skills") return dir;
3980
+ }
3981
+ return void 0;
3982
+ }
3983
+ function looksLikeSkillBody(text7) {
3984
+ const t = text7.trim();
3985
+ if (!t) return false;
3986
+ if (/^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t)) {
3987
+ return true;
3988
+ }
3989
+ return skillNameFromFrontmatter(t) != null;
3990
+ }
3991
+ function skillNameFromFrontmatter(text7) {
3992
+ const t = text7.trim();
3993
+ if (!t.startsWith("---")) return void 0;
3994
+ const close = t.indexOf("\n---", 3);
3995
+ if (close < 0) return void 0;
3996
+ const fm = t.slice(3, close);
3997
+ const m = fm.match(/^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m);
3998
+ return m?.[1];
3999
+ }
4000
+ function skillCommandFromBody(text7) {
4001
+ return skillNameFromFrontmatter(text7) ?? text7.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1];
4002
+ }
4003
+ function isCompactToolName(name) {
4004
+ const short = (name ?? "").replace(/^mcp__[^_]+__/, "").trim();
4005
+ return /^(Compact|ConversationCompact|summarize_context|SummarizeContext|SummarizeConversation)$/i.test(
4006
+ short
4007
+ );
4008
+ }
4009
+ function isContextCompactInProgress(text7) {
4010
+ return /^Compressing context/i.test(text7.trim());
4011
+ }
4012
+ function isContextCompactDone(text7) {
4013
+ return /^Context compressed\b/i.test(text7.trim());
4014
+ }
4015
+ function looksLikeConversationSummary(text7) {
4016
+ const t = text7.trim();
4017
+ if (t.length < 80) return false;
4018
+ if (/<summarized_conversation\b/i.test(t) || /<conversation_summary\b/i.test(t)) {
4019
+ return true;
4020
+ }
4021
+ if (/this session is being continued from a previous conversation/i.test(t)) {
4022
+ return true;
4023
+ }
4024
+ if (/conversation compacted|replaced with a summary/i.test(t)) return true;
4025
+ if (/^## Prior summary\b/m.test(t)) return true;
4026
+ if (/_Automatic extractive summary/i.test(t)) return true;
4027
+ if (/"context_summary"\s*:/.test(t)) return true;
4028
+ if (/^(?:#+\s*)?(?:conversation summary|summary of (?:the )?conversation|compacted (?:conversation|context))\b/im.test(
4029
+ t
4030
+ )) {
4031
+ return true;
4032
+ }
4033
+ return false;
4034
+ }
3836
4035
  function toolDetail(name, input) {
4036
+ if (isSkillToolName(name) || isCompactToolName(name)) return void 0;
3837
4037
  if (!input) return void 0;
3838
4038
  const command = str(input.command) ?? str(input.cmd);
3839
4039
  if (command) return clipChatLine(command);
@@ -3885,6 +4085,17 @@ function toolDescription(name, input) {
3885
4085
  if (/stop_dev_script$/i.test(name)) {
3886
4086
  return str(input?.name) ? `Stop ${str(input?.name)}` : "Stop Dev script";
3887
4087
  }
4088
+ if (isSkillToolName(name)) {
4089
+ const cmd = skillCommandFromInput(input);
4090
+ return cmd ? `Using /${cmd}` : "Using skill";
4091
+ }
4092
+ if (isCompactToolName(name)) {
4093
+ const trigger = str(input?.trigger);
4094
+ if (trigger && !/^auto$/i.test(trigger) && trigger !== "injected") {
4095
+ return `Summarized conversation (${trigger})`;
4096
+ }
4097
+ return "Summarized conversation";
4098
+ }
3888
4099
  if (isSubagentToolName(name)) {
3889
4100
  const desc = str(input?.description);
3890
4101
  const sub = asRecord(input?.subagentType);
@@ -4004,6 +4215,8 @@ function toolActivityLine(parts) {
4004
4215
  });
4005
4216
  if (tools.length === 0) return null;
4006
4217
  const edited = [];
4218
+ const skillNames = [];
4219
+ let compacts = 0;
4007
4220
  let reads = 0;
4008
4221
  let searches = 0;
4009
4222
  let shells = 0;
@@ -4012,7 +4225,12 @@ function toolActivityLine(parts) {
4012
4225
  let deletions = 0;
4013
4226
  for (const tool of tools) {
4014
4227
  const kind = classifyTool(tool.name);
4015
- if (kind === "edit") {
4228
+ if (isSkillToolName(tool.name)) {
4229
+ const cmd = skillCommandFromInput(tool.input);
4230
+ skillNames.push(cmd ? `/${cmd}` : "skill");
4231
+ } else if (isCompactToolName(tool.name)) {
4232
+ compacts += 1;
4233
+ } else if (kind === "edit") {
4016
4234
  const path2 = tool.filePath ?? toolFilePath(tool.input);
4017
4235
  edited.push({
4018
4236
  name: path2 ? fileBasename(path2) : tool.name,
@@ -4040,6 +4258,10 @@ function toolActivityLine(parts) {
4040
4258
  else if (searches > 1) bits.push(`${searches} searches`);
4041
4259
  if (shells === 1) bits.push("ran 1 command");
4042
4260
  else if (shells > 1) bits.push(`ran ${shells} commands`);
4261
+ if (skillNames.length === 1) bits.push(`used ${skillNames[0]}`);
4262
+ else if (skillNames.length > 1) bits.push(`used ${skillNames.length} skills`);
4263
+ if (compacts === 1) bits.push("summarized conversation");
4264
+ else if (compacts > 1) bits.push(`summarized conversation \xD7${compacts}`);
4043
4265
  if (others === 1) bits.push("1 tool");
4044
4266
  else if (others > 1) bits.push(`${others} tools`);
4045
4267
  if (bits.length === 0) return null;
@@ -4169,10 +4391,107 @@ function withPartTimes(next, prev) {
4169
4391
  const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
4170
4392
  return { ...next, startedAt, updatedAt: now };
4171
4393
  }
4394
+ function skillToolFromTextPart(part, id) {
4395
+ const command = skillCommandFromBody(part.text);
4396
+ const input = command ? { skill: command } : void 0;
4397
+ return {
4398
+ type: "tool",
4399
+ id,
4400
+ name: "Skill",
4401
+ input,
4402
+ description: toolDescription("Skill", input),
4403
+ status: "done",
4404
+ result: clipToolResultForStore(part.text),
4405
+ ...part.parentId ? { parentId: part.parentId } : {},
4406
+ startedAt: part.startedAt,
4407
+ updatedAt: Date.now()
4408
+ };
4409
+ }
4410
+ function compactToolPart(text7, id, opts) {
4411
+ const input = { trigger: opts?.trigger ?? "auto" };
4412
+ return withPartTimes(
4413
+ {
4414
+ type: "tool",
4415
+ id,
4416
+ name: "Compact",
4417
+ input,
4418
+ description: toolDescription("Compact", input),
4419
+ status: opts?.status ?? "done",
4420
+ result: clipToolResultForStore(text7) ?? "",
4421
+ ...opts?.parentId ? { parentId: opts.parentId } : {}
4422
+ },
4423
+ opts?.prev
4424
+ );
4425
+ }
4426
+ function contextCompactInProgress(parts, parentId) {
4427
+ let compressing = false;
4428
+ for (const p of parts) {
4429
+ if (!sameParentId(p.parentId, parentId)) continue;
4430
+ if (p.type === "thinking" && isContextCompactInProgress(p.text)) compressing = true;
4431
+ if (p.type === "thinking" && isContextCompactDone(p.text)) compressing = false;
4432
+ }
4433
+ return compressing;
4434
+ }
4435
+ function lastRunningCompactIndex(parts, parentId) {
4436
+ for (let i = parts.length - 1; i >= 0; i--) {
4437
+ const p = parts[i];
4438
+ if (p.type === "tool" && isCompactToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
4439
+ return i;
4440
+ }
4441
+ }
4442
+ return -1;
4443
+ }
4444
+ function markRunningCompactDone(parts, parentId) {
4445
+ return parts.map((p) => {
4446
+ if (p.type === "tool" && isCompactToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
4447
+ return withPartTimes({ ...p, status: "done" }, p);
4448
+ }
4449
+ return p;
4450
+ });
4451
+ }
4452
+ function ensureCompactTool(parts, parentId) {
4453
+ const hasCompact = parts.some(
4454
+ (p) => p.type === "tool" && isCompactToolName(p.name) && sameParentId(p.parentId, parentId)
4455
+ );
4456
+ if (hasCompact) return parts;
4457
+ return [
4458
+ ...parts,
4459
+ compactToolPart("Context compressed", `compact-${parts.length}`, {
4460
+ parentId,
4461
+ status: "done"
4462
+ })
4463
+ ];
4464
+ }
4465
+ function withCompactFinish(parts, thinking, parentId) {
4466
+ if (!isContextCompactDone(thinking)) return parts;
4467
+ return ensureCompactTool(markRunningCompactDone(parts, parentId), parentId);
4468
+ }
4172
4469
  function applyAgentEvent(parts, event) {
4173
4470
  if (event.type === "stdout") {
4174
4471
  const data = event.data;
4175
4472
  if (!data) return parts;
4473
+ const runningIdx = lastRunningCompactIndex(parts, event.parentId);
4474
+ if (runningIdx >= 0) {
4475
+ const prev = parts[runningIdx];
4476
+ const next2 = [...parts];
4477
+ next2[runningIdx] = withPartTimes(
4478
+ {
4479
+ ...prev,
4480
+ result: clipToolResultForStore(`${prev.result ?? ""}${data}`)
4481
+ },
4482
+ prev
4483
+ );
4484
+ return next2;
4485
+ }
4486
+ if (contextCompactInProgress(parts, event.parentId)) {
4487
+ return [
4488
+ ...parts,
4489
+ compactToolPart(data, `compact-${parts.length}`, {
4490
+ parentId: event.parentId,
4491
+ status: "running"
4492
+ })
4493
+ ];
4494
+ }
4176
4495
  const next = [...parts];
4177
4496
  const last = next[next.length - 1];
4178
4497
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
@@ -4193,6 +4512,16 @@ function applyAgentEvent(parts, event) {
4193
4512
  })
4194
4513
  );
4195
4514
  }
4515
+ const acc = next[next.length - 1];
4516
+ if (acc?.type === "text" && looksLikeSkillBody(acc.text)) {
4517
+ next[next.length - 1] = skillToolFromTextPart(acc, `skill-${next.length}`);
4518
+ } else if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
4519
+ next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
4520
+ parentId: acc.parentId,
4521
+ status: "done",
4522
+ prev: acc
4523
+ });
4524
+ }
4196
4525
  return next;
4197
4526
  }
4198
4527
  if (event.type === "thinking") {
@@ -4211,7 +4540,7 @@ function applyAgentEvent(parts, event) {
4211
4540
  },
4212
4541
  prev
4213
4542
  );
4214
- return next;
4543
+ return withCompactFinish(next, data, event.parentId);
4215
4544
  }
4216
4545
  }
4217
4546
  next.push(
@@ -4221,7 +4550,7 @@ function applyAgentEvent(parts, event) {
4221
4550
  ...event.parentId ? { parentId: event.parentId } : {}
4222
4551
  })
4223
4552
  );
4224
- return next;
4553
+ return withCompactFinish(next, data, event.parentId);
4225
4554
  }
4226
4555
  const last = next[next.length - 1];
4227
4556
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
@@ -4242,7 +4571,7 @@ function applyAgentEvent(parts, event) {
4242
4571
  })
4243
4572
  );
4244
4573
  }
4245
- return next;
4574
+ return withCompactFinish(next, data, event.parentId);
4246
4575
  }
4247
4576
  if (event.type === "tool_use") {
4248
4577
  const input = asRecord(event.input);
@@ -5865,7 +6194,7 @@ function materialize(mem) {
5865
6194
  };
5866
6195
  }
5867
6196
  function setupLogPath(threadId) {
5868
- return (0, import_node_path13.join)(threadsDir(), `${threadId}.setup.log.json`);
6197
+ return (0, import_node_path14.join)(threadsDir(), `${threadId}.setup.log.json`);
5869
6198
  }
5870
6199
  function setupLogKeyForWorktree(worktreePath) {
5871
6200
  const norm = normalizeWorktreePath(worktreePath);
@@ -5891,7 +6220,7 @@ function persistNow(threadId) {
5891
6220
  const mem = memory.get(threadId);
5892
6221
  if (!mem) return;
5893
6222
  try {
5894
- (0, import_node_fs11.writeFileSync)(
6223
+ (0, import_node_fs12.writeFileSync)(
5895
6224
  setupLogPath(threadId),
5896
6225
  `${JSON.stringify(materialize(mem))}
5897
6226
  `,
@@ -5912,9 +6241,9 @@ function schedulePersist(threadId) {
5912
6241
  }
5913
6242
  function loadFromDisk(threadId) {
5914
6243
  const path2 = setupLogPath(threadId);
5915
- if (!(0, import_node_fs11.existsSync)(path2)) return null;
6244
+ if (!(0, import_node_fs12.existsSync)(path2)) return null;
5916
6245
  try {
5917
- const raw = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
6246
+ const raw = JSON.parse((0, import_node_fs12.readFileSync)(path2, "utf8"));
5918
6247
  return {
5919
6248
  output: typeof raw.output === "string" ? raw.output : "",
5920
6249
  running: Boolean(raw.running),
@@ -5970,13 +6299,13 @@ function finishSetupLog(threadId, exitCode, source) {
5970
6299
  persistNow(threadId);
5971
6300
  return materialize(mem);
5972
6301
  }
5973
- var import_node_crypto4, import_node_fs11, import_node_path13, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
6302
+ var import_node_crypto4, import_node_fs12, import_node_path14, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
5974
6303
  var init_setup_log = __esm({
5975
6304
  "src/store/setup-log.ts"() {
5976
6305
  "use strict";
5977
6306
  import_node_crypto4 = require("crypto");
5978
- import_node_fs11 = require("fs");
5979
- import_node_path13 = require("path");
6307
+ import_node_fs12 = require("fs");
6308
+ import_node_path14 = require("path");
5980
6309
  init_worktree_labels();
5981
6310
  init_paths();
5982
6311
  EMPTY = {
@@ -5994,7 +6323,7 @@ var init_setup_log = __esm({
5994
6323
 
5995
6324
  // src/store/schedules.ts
5996
6325
  function schedulesPath() {
5997
- return (0, import_node_path14.join)(appDataDir(), "schedules.json");
6326
+ return (0, import_node_path15.join)(appDataDir(), "schedules.json");
5998
6327
  }
5999
6328
  function parseDurationMs(every) {
6000
6329
  const m = every.trim().match(DURATION_RE);
@@ -6100,9 +6429,9 @@ function normalizeTask(raw) {
6100
6429
  }
6101
6430
  function readAll() {
6102
6431
  const path2 = schedulesPath();
6103
- if (!(0, import_node_fs12.existsSync)(path2)) return [];
6432
+ if (!(0, import_node_fs13.existsSync)(path2)) return [];
6104
6433
  try {
6105
- const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path2, "utf8"));
6434
+ const parsed = JSON.parse((0, import_node_fs13.readFileSync)(path2, "utf8"));
6106
6435
  if (!Array.isArray(parsed)) return [];
6107
6436
  return parsed.map((row) => {
6108
6437
  try {
@@ -6217,13 +6546,13 @@ function recordScheduleRun(id, result) {
6217
6546
  writeAll(rows);
6218
6547
  return next;
6219
6548
  }
6220
- var import_node_crypto5, import_node_fs12, import_node_path14, import_croner, DURATION_RE, UNIT_MS;
6549
+ var import_node_crypto5, import_node_fs13, import_node_path15, import_croner, DURATION_RE, UNIT_MS;
6221
6550
  var init_schedules = __esm({
6222
6551
  "src/store/schedules.ts"() {
6223
6552
  "use strict";
6224
6553
  import_node_crypto5 = require("crypto");
6225
- import_node_fs12 = require("fs");
6226
- import_node_path14 = require("path");
6554
+ import_node_fs13 = require("fs");
6555
+ import_node_path15 = require("path");
6227
6556
  import_croner = require("croner");
6228
6557
  init_orchestrator_capable();
6229
6558
  init_paths();
@@ -6240,22 +6569,22 @@ var init_schedules = __esm({
6240
6569
 
6241
6570
  // src/store/desktop-host.ts
6242
6571
  function desktopHostPidPath() {
6243
- return (0, import_node_path15.join)(appDataDir(), "desktop-host.pid");
6572
+ return (0, import_node_path16.join)(appDataDir(), "desktop-host.pid");
6244
6573
  }
6245
6574
  function claimDesktopHost(pid = process.pid) {
6246
- (0, import_node_fs13.writeFileSync)(desktopHostPidPath(), `${pid}
6575
+ (0, import_node_fs14.writeFileSync)(desktopHostPidPath(), `${pid}
6247
6576
  `, "utf8");
6248
6577
  }
6249
6578
  function releaseDesktopHost(pid = process.pid) {
6250
6579
  if (readDesktopHostPid() !== pid) return;
6251
6580
  try {
6252
- (0, import_node_fs13.unlinkSync)(desktopHostPidPath());
6581
+ (0, import_node_fs14.unlinkSync)(desktopHostPidPath());
6253
6582
  } catch {
6254
6583
  }
6255
6584
  }
6256
6585
  function readDesktopHostPid() {
6257
6586
  try {
6258
- const pid = Number.parseInt((0, import_node_fs13.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
6587
+ const pid = Number.parseInt((0, import_node_fs14.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
6259
6588
  if (!Number.isFinite(pid) || pid <= 0) return null;
6260
6589
  return pid;
6261
6590
  } catch {
@@ -6281,12 +6610,12 @@ function thisProcessShouldDrainAgentQueues() {
6281
6610
  if (isThisProcessDesktopHost()) return true;
6282
6611
  return !isDesktopHostAlive();
6283
6612
  }
6284
- var import_node_fs13, import_node_path15;
6613
+ var import_node_fs14, import_node_path16;
6285
6614
  var init_desktop_host = __esm({
6286
6615
  "src/store/desktop-host.ts"() {
6287
6616
  "use strict";
6288
- import_node_fs13 = require("fs");
6289
- import_node_path15 = require("path");
6617
+ import_node_fs14 = require("fs");
6618
+ import_node_path16 = require("path");
6290
6619
  init_paths();
6291
6620
  }
6292
6621
  });
@@ -6353,7 +6682,7 @@ var init_workspace_scratch = __esm({
6353
6682
 
6354
6683
  // src/composer/stage-files.ts
6355
6684
  function fileExtension(filePath) {
6356
- const base = (0, import_node_path16.basename)(filePath).toLowerCase();
6685
+ const base = (0, import_node_path17.basename)(filePath).toLowerCase();
6357
6686
  return base.includes(".") ? base.split(".").pop() || "" : "";
6358
6687
  }
6359
6688
  function isImageFilePath(filePath) {
@@ -6363,22 +6692,22 @@ function imageMimeType(filePath) {
6363
6692
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
6364
6693
  }
6365
6694
  function ensureAttachmentsDir(worktreePath) {
6366
- const dir = (0, import_node_path16.join)(worktreePath, ATTACHMENTS_DIR);
6367
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
6368
- const gi = (0, import_node_path16.join)(dir, ".gitignore");
6369
- if (!(0, import_node_fs14.existsSync)(gi)) {
6370
- (0, import_node_fs14.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
6695
+ const dir = (0, import_node_path17.join)(worktreePath, ATTACHMENTS_DIR);
6696
+ (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
6697
+ const gi = (0, import_node_path17.join)(dir, ".gitignore");
6698
+ if (!(0, import_node_fs15.existsSync)(gi)) {
6699
+ (0, import_node_fs15.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
6371
6700
  }
6372
6701
  return dir;
6373
6702
  }
6374
6703
  function uniqueAttachmentName(dir, originalName) {
6375
6704
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
6376
- if (!(0, import_node_fs14.existsSync)((0, import_node_path16.join)(dir, safe))) return safe;
6377
- const ext = (0, import_node_path16.extname)(safe);
6705
+ if (!(0, import_node_fs15.existsSync)((0, import_node_path17.join)(dir, safe))) return safe;
6706
+ const ext = (0, import_node_path17.extname)(safe);
6378
6707
  const stem = ext ? safe.slice(0, -ext.length) : safe;
6379
6708
  for (let i = 1; i < 1e4; i++) {
6380
6709
  const candidate = `${stem}-${i}${ext}`;
6381
- if (!(0, import_node_fs14.existsSync)((0, import_node_path16.join)(dir, candidate))) return candidate;
6710
+ if (!(0, import_node_fs15.existsSync)((0, import_node_path17.join)(dir, candidate))) return candidate;
6382
6711
  }
6383
6712
  return `${stem}-${(0, import_node_crypto6.randomUUID)()}${ext}`;
6384
6713
  }
@@ -6430,9 +6759,9 @@ function attachmentFromBuffer(name, buf, opts) {
6430
6759
  };
6431
6760
  }
6432
6761
  function attachmentFromAbsolutePath(absolutePath) {
6433
- const name = (0, import_node_path16.basename)(absolutePath);
6762
+ const name = (0, import_node_path17.basename)(absolutePath);
6434
6763
  try {
6435
- const st = (0, import_node_fs14.statSync)(absolutePath);
6764
+ const st = (0, import_node_fs15.statSync)(absolutePath);
6436
6765
  if (!st.isFile()) {
6437
6766
  return {
6438
6767
  id: (0, import_node_crypto6.randomUUID)(),
@@ -6441,7 +6770,7 @@ function attachmentFromAbsolutePath(absolutePath) {
6441
6770
  content: `(not a file: ${absolutePath})`
6442
6771
  };
6443
6772
  }
6444
- const buf = (0, import_node_fs14.readFileSync)(absolutePath);
6773
+ const buf = (0, import_node_fs15.readFileSync)(absolutePath);
6445
6774
  return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
6446
6775
  } catch (err) {
6447
6776
  return {
@@ -6457,15 +6786,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
6457
6786
  const dir = ensureAttachmentsDir(worktreePath);
6458
6787
  const out = [];
6459
6788
  for (const abs of absolutePaths) {
6460
- const originalName = (0, import_node_path16.basename)(abs);
6789
+ const originalName = (0, import_node_path17.basename)(abs);
6461
6790
  try {
6462
- const st = (0, import_node_fs14.statSync)(abs);
6791
+ const st = (0, import_node_fs15.statSync)(abs);
6463
6792
  if (!st.isFile()) continue;
6464
6793
  const name = uniqueAttachmentName(dir, originalName);
6465
- const destAbs = (0, import_node_path16.join)(dir, name);
6466
- (0, import_node_fs14.copyFileSync)(abs, destAbs);
6794
+ const destAbs = (0, import_node_path17.join)(dir, name);
6795
+ (0, import_node_fs15.copyFileSync)(abs, destAbs);
6467
6796
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6468
- const buf = (0, import_node_fs14.readFileSync)(destAbs);
6797
+ const buf = (0, import_node_fs15.readFileSync)(destAbs);
6469
6798
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
6470
6799
  } catch (err) {
6471
6800
  out.push({
@@ -6487,8 +6816,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
6487
6816
  try {
6488
6817
  const buf = Buffer.from(item.dataBase64, "base64");
6489
6818
  const name = uniqueAttachmentName(dir, originalName);
6490
- const destAbs = (0, import_node_path16.join)(dir, name);
6491
- (0, import_node_fs14.writeFileSync)(destAbs, buf);
6819
+ const destAbs = (0, import_node_path17.join)(dir, name);
6820
+ (0, import_node_fs15.writeFileSync)(destAbs, buf);
6492
6821
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6493
6822
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
6494
6823
  } catch (err) {
@@ -6565,18 +6894,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6565
6894
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
6566
6895
  out.push({
6567
6896
  id: (0, import_node_crypto6.randomUUID)(),
6568
- name: (0, import_node_path16.basename)(rel) || "file",
6897
+ name: (0, import_node_path17.basename)(rel) || "file",
6569
6898
  kind: "file",
6570
6899
  content: `(invalid path: ${rel})`
6571
6900
  });
6572
6901
  continue;
6573
6902
  }
6574
- const name = (0, import_node_path16.basename)(rel);
6903
+ const name = (0, import_node_path17.basename)(rel);
6575
6904
  try {
6576
- const abs = (0, import_node_path16.join)(worktreePath, rel);
6577
- const st = (0, import_node_fs14.statSync)(abs);
6905
+ const abs = (0, import_node_path17.join)(worktreePath, rel);
6906
+ const st = (0, import_node_fs15.statSync)(abs);
6578
6907
  if (!st.isFile()) continue;
6579
- const buf = (0, import_node_fs14.readFileSync)(abs);
6908
+ const buf = (0, import_node_fs15.readFileSync)(abs);
6580
6909
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
6581
6910
  } catch (err) {
6582
6911
  out.push({
@@ -6589,12 +6918,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6589
6918
  }
6590
6919
  return out;
6591
6920
  }
6592
- var import_node_fs14, import_node_path16, import_node_crypto6, IMAGE_EXTENSIONS, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES, IMAGE_HINT_RE, PLACEHOLDER_CONTENT_RE;
6921
+ var import_node_fs15, import_node_path17, import_node_crypto6, IMAGE_EXTENSIONS, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES, IMAGE_HINT_RE, PLACEHOLDER_CONTENT_RE;
6593
6922
  var init_stage_files = __esm({
6594
6923
  "src/composer/stage-files.ts"() {
6595
6924
  "use strict";
6596
- import_node_fs14 = require("fs");
6597
- import_node_path16 = require("path");
6925
+ import_node_fs15 = require("fs");
6926
+ import_node_path17 = require("path");
6598
6927
  import_node_crypto6 = require("crypto");
6599
6928
  init_workspace_scratch();
6600
6929
  IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -6736,17 +7065,17 @@ var init_gh_errors = __esm({
6736
7065
 
6737
7066
  // src/agents/path.ts
6738
7067
  function prependPathDir(env, dir) {
6739
- if (!dir || !(0, import_node_fs15.existsSync)(dir)) return;
7068
+ if (!dir || !(0, import_node_fs16.existsSync)(dir)) return;
6740
7069
  const current = env.PATH ?? "";
6741
- const parts = current.split(import_node_path17.delimiter).filter(Boolean);
7070
+ const parts = current.split(import_node_path18.delimiter).filter(Boolean);
6742
7071
  if (parts.includes(dir)) {
6743
7072
  env.PATH = current;
6744
7073
  return;
6745
7074
  }
6746
- env.PATH = [dir, ...parts].join(import_node_path17.delimiter);
7075
+ env.PATH = [dir, ...parts].join(import_node_path18.delimiter);
6747
7076
  }
6748
7077
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
6749
- return (0, import_node_path17.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
7078
+ return (0, import_node_path18.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6750
7079
  }
6751
7080
  function isConductorBundledCli(filePath) {
6752
7081
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -6755,21 +7084,21 @@ function isConductorBundledCli(filePath) {
6755
7084
  function ensureAgentPath(env = process.env) {
6756
7085
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
6757
7086
  const current = env.PATH ?? "";
6758
- const parts = current.split(import_node_path17.delimiter).filter(Boolean);
7087
+ const parts = current.split(import_node_path18.delimiter).filter(Boolean);
6759
7088
  const seen = new Set(parts);
6760
7089
  const extras = [
6761
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path17.join)(home, rel)),
7090
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path18.join)(home, rel)),
6762
7091
  "/opt/homebrew/bin",
6763
7092
  "/usr/local/bin",
6764
7093
  // Keep after Homebrew/npm so a user-installed CLI still wins.
6765
7094
  conductorBundledBinDir(home)
6766
7095
  ];
6767
7096
  for (const dir of extras.reverse()) {
6768
- if (!dir || seen.has(dir) || !(0, import_node_fs15.existsSync)(dir)) continue;
7097
+ if (!dir || seen.has(dir) || !(0, import_node_fs16.existsSync)(dir)) continue;
6769
7098
  parts.unshift(dir);
6770
7099
  seen.add(dir);
6771
7100
  }
6772
- const next = parts.join(import_node_path17.delimiter);
7101
+ const next = parts.join(import_node_path18.delimiter);
6773
7102
  env.PATH = next;
6774
7103
  return next;
6775
7104
  }
@@ -6777,7 +7106,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
6777
7106
  ensureAgentPath(env);
6778
7107
  const prefix = npmGlobalPrefix(env);
6779
7108
  if (prefix) {
6780
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path17.join)(prefix, "bin");
7109
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path18.join)(prefix, "bin");
6781
7110
  prependPathDir(env, binDir);
6782
7111
  }
6783
7112
  return env.PATH ?? "";
@@ -6798,8 +7127,8 @@ function npmGlobalPrefix(env = process.env) {
6798
7127
  function npmGlobalNodeModules(env = process.env) {
6799
7128
  const prefix = npmGlobalPrefix(env);
6800
7129
  if (!prefix) return null;
6801
- const dir = process.platform === "win32" ? (0, import_node_path17.join)(prefix, "node_modules") : (0, import_node_path17.join)(prefix, "lib", "node_modules");
6802
- return (0, import_node_fs15.existsSync)(dir) ? dir : null;
7130
+ const dir = process.platform === "win32" ? (0, import_node_path18.join)(prefix, "node_modules") : (0, import_node_path18.join)(prefix, "lib", "node_modules");
7131
+ return (0, import_node_fs16.existsSync)(dir) ? dir : null;
6803
7132
  }
6804
7133
  function posixShellSingleQuote(value) {
6805
7134
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -6822,14 +7151,14 @@ function withExportedPath(command, pathValue) {
6822
7151
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
6823
7152
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
6824
7153
  }
6825
- var import_node_fs15, import_node_child_process3, import_node_os4, import_node_path17, EXTRA_BIN_DIRS;
7154
+ var import_node_fs16, import_node_child_process3, import_node_os4, import_node_path18, EXTRA_BIN_DIRS;
6826
7155
  var init_path = __esm({
6827
7156
  "src/agents/path.ts"() {
6828
7157
  "use strict";
6829
- import_node_fs15 = require("fs");
7158
+ import_node_fs16 = require("fs");
6830
7159
  import_node_child_process3 = require("child_process");
6831
7160
  import_node_os4 = require("os");
6832
- import_node_path17 = require("path");
7161
+ import_node_path18 = require("path");
6833
7162
  EXTRA_BIN_DIRS = [
6834
7163
  ".local/bin",
6835
7164
  ".cargo/bin",
@@ -6850,23 +7179,23 @@ var init_path = __esm({
6850
7179
  function githubAgentAuthDir() {
6851
7180
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
6852
7181
  if (override) return override;
6853
- return (0, import_node_path18.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
7182
+ return (0, import_node_path19.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6854
7183
  }
6855
7184
  function githubCredentialStorePath() {
6856
- return (0, import_node_path18.join)(githubAgentAuthDir(), "git-credentials");
7185
+ return (0, import_node_path19.join)(githubAgentAuthDir(), "git-credentials");
6857
7186
  }
6858
7187
  function githubGhConfigDir() {
6859
- return (0, import_node_path18.join)(githubAgentAuthDir(), "gh");
7188
+ return (0, import_node_path19.join)(githubAgentAuthDir(), "gh");
6860
7189
  }
6861
7190
  function writePrivateFile2(file, body) {
6862
- (0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(file), { recursive: true, mode: 448 });
7191
+ (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(file), { recursive: true, mode: 448 });
6863
7192
  try {
6864
- (0, import_node_fs16.chmodSync)((0, import_node_path18.dirname)(file), 448);
7193
+ (0, import_node_fs17.chmodSync)((0, import_node_path19.dirname)(file), 448);
6865
7194
  } catch {
6866
7195
  }
6867
- (0, import_node_fs16.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
7196
+ (0, import_node_fs17.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
6868
7197
  try {
6869
- (0, import_node_fs16.chmodSync)(file, 384);
7198
+ (0, import_node_fs17.chmodSync)(file, 384);
6870
7199
  } catch {
6871
7200
  }
6872
7201
  }
@@ -6891,19 +7220,19 @@ function materializeGithubAgentAuth(token, user) {
6891
7220
  const trimmed = token.trim();
6892
7221
  if (!trimmed) return;
6893
7222
  const root = githubAgentAuthDir();
6894
- (0, import_node_fs16.mkdirSync)(root, { recursive: true, mode: 448 });
7223
+ (0, import_node_fs17.mkdirSync)(root, { recursive: true, mode: 448 });
6895
7224
  try {
6896
- (0, import_node_fs16.chmodSync)(root, 448);
7225
+ (0, import_node_fs17.chmodSync)(root, 448);
6897
7226
  } catch {
6898
7227
  }
6899
7228
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
6900
7229
  const ghDir = githubGhConfigDir();
6901
- (0, import_node_fs16.mkdirSync)(ghDir, { recursive: true, mode: 448 });
6902
- writePrivateFile2((0, import_node_path18.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6903
- writePrivateFile2((0, import_node_path18.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
7230
+ (0, import_node_fs17.mkdirSync)(ghDir, { recursive: true, mode: 448 });
7231
+ writePrivateFile2((0, import_node_path19.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
7232
+ writePrivateFile2((0, import_node_path19.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6904
7233
  }
6905
7234
  function githubAgentAuthReady() {
6906
- return (0, import_node_fs16.existsSync)(githubCredentialStorePath()) && (0, import_node_fs16.existsSync)((0, import_node_path18.join)(githubGhConfigDir(), "hosts.yml"));
7235
+ return (0, import_node_fs17.existsSync)(githubCredentialStorePath()) && (0, import_node_fs17.existsSync)((0, import_node_path19.join)(githubGhConfigDir(), "hosts.yml"));
6907
7236
  }
6908
7237
  function githubCredentialHelperGitConfig() {
6909
7238
  const file = githubCredentialStorePath();
@@ -6918,13 +7247,13 @@ function githubGhConfigEnv() {
6918
7247
  GH_PROMPT_DISABLED: "1"
6919
7248
  };
6920
7249
  }
6921
- var import_node_fs16, import_node_os5, import_node_path18;
7250
+ var import_node_fs17, import_node_os5, import_node_path19;
6922
7251
  var init_github_agent_auth = __esm({
6923
7252
  "src/git/github-agent-auth.ts"() {
6924
7253
  "use strict";
6925
- import_node_fs16 = require("fs");
7254
+ import_node_fs17 = require("fs");
6926
7255
  import_node_os5 = require("os");
6927
- import_node_path18 = require("path");
7256
+ import_node_path19 = require("path");
6928
7257
  }
6929
7258
  });
6930
7259
 
@@ -6933,11 +7262,11 @@ function isIndexLockError(text7) {
6933
7262
  return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text7);
6934
7263
  }
6935
7264
  function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
6936
- const lockPath = (0, import_node_path19.join)(gitDir, "index.lock");
7265
+ const lockPath = (0, import_node_path20.join)(gitDir, "index.lock");
6937
7266
  try {
6938
- if (!(0, import_node_fs17.existsSync)(lockPath)) return null;
6939
- if (now - (0, import_node_fs17.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
6940
- (0, import_node_fs17.unlinkSync)(lockPath);
7267
+ if (!(0, import_node_fs18.existsSync)(lockPath)) return null;
7268
+ if (now - (0, import_node_fs18.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
7269
+ (0, import_node_fs18.unlinkSync)(lockPath);
6941
7270
  return lockPath;
6942
7271
  } catch {
6943
7272
  return null;
@@ -6952,12 +7281,12 @@ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
6952
7281
  }
6953
7282
  return removed;
6954
7283
  }
6955
- var import_node_fs17, import_node_path19, STALE_INDEX_LOCK_MS;
7284
+ var import_node_fs18, import_node_path20, STALE_INDEX_LOCK_MS;
6956
7285
  var init_stale_lock = __esm({
6957
7286
  "src/git/stale-lock.ts"() {
6958
7287
  "use strict";
6959
- import_node_fs17 = require("fs");
6960
- import_node_path19 = require("path");
7288
+ import_node_fs18 = require("fs");
7289
+ import_node_path20 = require("path");
6961
7290
  STALE_INDEX_LOCK_MS = 2e4;
6962
7291
  }
6963
7292
  });
@@ -7098,11 +7427,11 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
7098
7427
  if (gitDir.exitCode !== 0) return;
7099
7428
  const dir = gitDir.stdout.trim();
7100
7429
  if (!dir) return;
7101
- const excludePath = (0, import_node_path20.join)(dir, "info", "exclude");
7102
- (0, import_node_fs18.mkdirSync)((0, import_node_path20.dirname)(excludePath), { recursive: true });
7430
+ const excludePath = (0, import_node_path21.join)(dir, "info", "exclude");
7431
+ (0, import_node_fs19.mkdirSync)((0, import_node_path21.dirname)(excludePath), { recursive: true });
7103
7432
  let body = "";
7104
7433
  try {
7105
- body = (0, import_node_fs18.readFileSync)(excludePath, "utf8");
7434
+ body = (0, import_node_fs19.readFileSync)(excludePath, "utf8");
7106
7435
  } catch {
7107
7436
  body = "";
7108
7437
  }
@@ -7118,7 +7447,7 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
7118
7447
  ` : body;
7119
7448
  const header = body.includes(EXCLUDE_COMMENT) ? "" : `${EXCLUDE_COMMENT}
7120
7449
  `;
7121
- (0, import_node_fs18.writeFileSync)(excludePath, `${prefix}${header}${missing.join("\n")}
7450
+ (0, import_node_fs19.writeFileSync)(excludePath, `${prefix}${header}${missing.join("\n")}
7122
7451
  `, "utf8");
7123
7452
  }
7124
7453
  const listed = await git(["ls-files", "-z", "--", ".sideboard"], worktreePath, {
@@ -7133,12 +7462,12 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
7133
7462
  timeoutMs: 8e3
7134
7463
  });
7135
7464
  }
7136
- var import_node_fs18, import_node_path20, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
7465
+ var import_node_fs19, import_node_path21, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
7137
7466
  var init_worktree_exclude = __esm({
7138
7467
  "src/git/worktree-exclude.ts"() {
7139
7468
  "use strict";
7140
- import_node_fs18 = require("fs");
7141
- import_node_path20 = require("path");
7469
+ import_node_fs19 = require("fs");
7470
+ import_node_path21 = require("path");
7142
7471
  init_run();
7143
7472
  WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
7144
7473
  WORKTREE_CONTEXT_EXCLUDE = ".context/";
@@ -7259,7 +7588,7 @@ async function warmGithubAgentAuth(opts) {
7259
7588
  }
7260
7589
  function normalizeWritableRoot(raw) {
7261
7590
  const trimmed = raw.trim().replace(/\/+$/, "");
7262
- return trimmed && (0, import_node_path21.isAbsolute)(trimmed) ? trimmed : null;
7591
+ return trimmed && (0, import_node_path22.isAbsolute)(trimmed) ? trimmed : null;
7263
7592
  }
7264
7593
  async function resolveCodexGitWritableRoots(cwd) {
7265
7594
  const roots = /* @__PURE__ */ new Set();
@@ -7337,11 +7666,11 @@ function formatGitAuthModeDirective(mode) {
7337
7666
  ].join("\n");
7338
7667
  }
7339
7668
  }
7340
- var import_node_path21, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7669
+ var import_node_path22, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7341
7670
  var init_git_auth_mode = __esm({
7342
7671
  "src/git/git-auth-mode.ts"() {
7343
7672
  "use strict";
7344
- import_node_path21 = require("path");
7673
+ import_node_path22 = require("path");
7345
7674
  init_app_settings();
7346
7675
  init_github_agent_auth();
7347
7676
  init_run();
@@ -8177,7 +8506,7 @@ async function resolveRepoRoot(cwd) {
8177
8506
  }
8178
8507
  function canonicalizeRepoPath(path2) {
8179
8508
  try {
8180
- return (0, import_node_fs19.realpathSync)(path2);
8509
+ return (0, import_node_fs20.realpathSync)(path2);
8181
8510
  } catch {
8182
8511
  return path2.replace(/\/+$/, "");
8183
8512
  }
@@ -9038,8 +9367,8 @@ async function refreshOriginAndMaybeFastForwardMain(repoPath, sourceRef) {
9038
9367
  }
9039
9368
  async function createThreadWorktree(opts) {
9040
9369
  let branchName = `thread/${opts.slug}`;
9041
- const worktreePath = (0, import_node_path22.join)(worktreesRoot(opts.repoPath), opts.slug);
9042
- if ((0, import_node_fs19.existsSync)(worktreePath)) {
9370
+ const worktreePath = (0, import_node_path23.join)(worktreesRoot(opts.repoPath), opts.slug);
9371
+ if ((0, import_node_fs20.existsSync)(worktreePath)) {
9043
9372
  throw new Error(`Worktree already exists at ${worktreePath}`);
9044
9373
  }
9045
9374
  await ensureGhPreferOrigin(opts.repoPath);
@@ -9080,8 +9409,8 @@ ${add.stdout}`;
9080
9409
  async function createExistingBranchWorktree(opts) {
9081
9410
  const branchName = opts.branchName.trim();
9082
9411
  if (!branchName) throw new Error("branch name required");
9083
- const worktreePath = (0, import_node_path22.join)(worktreesRoot(opts.repoPath), opts.slug);
9084
- if ((0, import_node_fs19.existsSync)(worktreePath)) {
9412
+ const worktreePath = (0, import_node_path23.join)(worktreesRoot(opts.repoPath), opts.slug);
9413
+ if ((0, import_node_fs20.existsSync)(worktreePath)) {
9085
9414
  throw new Error(`Worktree already exists at ${worktreePath}`);
9086
9415
  }
9087
9416
  await ensureGhPreferOrigin(opts.repoPath);
@@ -9362,11 +9691,11 @@ async function createOrUpdatePr(worktreePath, opts) {
9362
9691
  const headRef = ghHeadRef(slug, opts.head);
9363
9692
  const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
9364
9693
  const bodyText = clampGithubPrBody(opts.body ?? opts.title);
9365
- const bodyFile = (0, import_node_path22.join)(
9694
+ const bodyFile = (0, import_node_path23.join)(
9366
9695
  (0, import_node_os6.tmpdir)(),
9367
9696
  `sideboard-pr-body-${process.pid}-${(0, import_node_crypto7.randomBytes)(6).toString("hex")}.md`
9368
9697
  );
9369
- (0, import_node_fs19.writeFileSync)(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
9698
+ (0, import_node_fs20.writeFileSync)(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
9370
9699
  `, "utf8");
9371
9700
  const bodyArgs = ["--body-file", bodyFile];
9372
9701
  try {
@@ -9380,7 +9709,7 @@ async function createOrUpdatePr(worktreePath, opts) {
9380
9709
  });
9381
9710
  } finally {
9382
9711
  try {
9383
- (0, import_node_fs19.unlinkSync)(bodyFile);
9712
+ (0, import_node_fs20.unlinkSync)(bodyFile);
9384
9713
  } catch {
9385
9714
  }
9386
9715
  }
@@ -9462,10 +9791,10 @@ function sameRepoPath2(a, b) {
9462
9791
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
9463
9792
  }
9464
9793
  function listLocalThreadBranchSlugs(repoPath) {
9465
- const refsDir = (0, import_node_path22.join)(repoPath, ".git", "refs", "heads", "thread");
9466
- if (!(0, import_node_fs19.existsSync)(refsDir)) return [];
9794
+ const refsDir = (0, import_node_path23.join)(repoPath, ".git", "refs", "heads", "thread");
9795
+ if (!(0, import_node_fs20.existsSync)(refsDir)) return [];
9467
9796
  try {
9468
- return (0, import_node_fs19.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
9797
+ return (0, import_node_fs20.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
9469
9798
  } catch {
9470
9799
  return [];
9471
9800
  }
@@ -9473,8 +9802,8 @@ function listLocalThreadBranchSlugs(repoPath) {
9473
9802
  function collectTakenTeamSlugs(repoPath) {
9474
9803
  const taken = /* @__PURE__ */ new Set();
9475
9804
  const root = worktreesRoot(repoPath);
9476
- if ((0, import_node_fs19.existsSync)(root)) {
9477
- for (const entry of (0, import_node_fs19.readdirSync)(root, { withFileTypes: true })) {
9805
+ if ((0, import_node_fs20.existsSync)(root)) {
9806
+ for (const entry of (0, import_node_fs20.readdirSync)(root, { withFileTypes: true })) {
9478
9807
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
9479
9808
  for (const slug of takenSlugsFromThread({ worktreePath: entry.name })) {
9480
9809
  taken.add(slug);
@@ -9499,20 +9828,20 @@ function allocateTeamSlug(repoPath) {
9499
9828
  const taken = collectTakenTeamSlugs(repoPath);
9500
9829
  for (let attempt = 0; attempt < 32; attempt++) {
9501
9830
  const team = allocateTeamName(taken);
9502
- const path2 = (0, import_node_path22.join)(worktreesRoot(repoPath), team.slug);
9503
- if (!(0, import_node_fs19.existsSync)(path2)) return team;
9831
+ const path2 = (0, import_node_path23.join)(worktreesRoot(repoPath), team.slug);
9832
+ if (!(0, import_node_fs20.existsSync)(path2)) return team;
9504
9833
  taken.add(team.slug);
9505
9834
  }
9506
9835
  throw new Error("No available soccer team worktree directories left");
9507
9836
  }
9508
- var import_node_crypto7, import_node_fs19, import_node_os6, import_node_path22, PR_DETAILS_JSON_FIELDS;
9837
+ var import_node_crypto7, import_node_fs20, import_node_os6, import_node_path23, PR_DETAILS_JSON_FIELDS;
9509
9838
  var init_worktree = __esm({
9510
9839
  "src/git/worktree.ts"() {
9511
9840
  "use strict";
9512
9841
  import_node_crypto7 = require("crypto");
9513
- import_node_fs19 = require("fs");
9842
+ import_node_fs20 = require("fs");
9514
9843
  import_node_os6 = require("os");
9515
- import_node_path22 = require("path");
9844
+ import_node_path23 = require("path");
9516
9845
  init_paths();
9517
9846
  init_thread_store();
9518
9847
  init_teams();
@@ -9565,38 +9894,38 @@ __export(workspaces_exports, {
9565
9894
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
9566
9895
  });
9567
9896
  function workspacesFile() {
9568
- return (0, import_node_path23.join)(appDataDir(), "workspaces.json");
9897
+ return (0, import_node_path24.join)(appDataDir(), "workspaces.json");
9569
9898
  }
9570
9899
  function removedWorkspacesFile() {
9571
- return (0, import_node_path23.join)(appDataDir(), "removed-workspaces.json");
9900
+ return (0, import_node_path24.join)(appDataDir(), "removed-workspaces.json");
9572
9901
  }
9573
9902
  function readAll2() {
9574
9903
  const path2 = workspacesFile();
9575
- if (!(0, import_node_fs20.existsSync)(path2)) return [];
9904
+ if (!(0, import_node_fs21.existsSync)(path2)) return [];
9576
9905
  try {
9577
- const raw = JSON.parse((0, import_node_fs20.readFileSync)(path2, "utf8"));
9906
+ const raw = JSON.parse((0, import_node_fs21.readFileSync)(path2, "utf8"));
9578
9907
  return Array.isArray(raw) ? raw : [];
9579
9908
  } catch {
9580
9909
  return [];
9581
9910
  }
9582
9911
  }
9583
9912
  function writeAll2(list) {
9584
- (0, import_node_fs20.mkdirSync)(appDataDir(), { recursive: true });
9585
- (0, import_node_fs20.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
9913
+ (0, import_node_fs21.mkdirSync)(appDataDir(), { recursive: true });
9914
+ (0, import_node_fs21.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
9586
9915
  }
9587
9916
  function readRemoved() {
9588
9917
  const path2 = removedWorkspacesFile();
9589
- if (!(0, import_node_fs20.existsSync)(path2)) return /* @__PURE__ */ new Set();
9918
+ if (!(0, import_node_fs21.existsSync)(path2)) return /* @__PURE__ */ new Set();
9590
9919
  try {
9591
- const raw = JSON.parse((0, import_node_fs20.readFileSync)(path2, "utf8"));
9920
+ const raw = JSON.parse((0, import_node_fs21.readFileSync)(path2, "utf8"));
9592
9921
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
9593
9922
  } catch {
9594
9923
  return /* @__PURE__ */ new Set();
9595
9924
  }
9596
9925
  }
9597
9926
  function writeRemoved(paths) {
9598
- (0, import_node_fs20.mkdirSync)(appDataDir(), { recursive: true });
9599
- (0, import_node_fs20.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
9927
+ (0, import_node_fs21.mkdirSync)(appDataDir(), { recursive: true });
9928
+ (0, import_node_fs21.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
9600
9929
  }
9601
9930
  function rememberRemoved(repoPath) {
9602
9931
  const next = readRemoved();
@@ -9618,10 +9947,10 @@ function listWorkspaces() {
9618
9947
  }
9619
9948
  function isLinkedWorktreeOf(path2, mainRepo) {
9620
9949
  if (!path2 || path2 === mainRepo) return false;
9621
- const git2 = (0, import_node_path23.join)(path2, ".git");
9950
+ const git2 = (0, import_node_path24.join)(path2, ".git");
9622
9951
  try {
9623
- if (!(0, import_node_fs20.existsSync)(git2) || (0, import_node_fs20.statSync)(git2).isDirectory()) return false;
9624
- const text7 = (0, import_node_fs20.readFileSync)(git2, "utf8");
9952
+ if (!(0, import_node_fs21.existsSync)(git2) || (0, import_node_fs21.statSync)(git2).isDirectory()) return false;
9953
+ const text7 = (0, import_node_fs21.readFileSync)(git2, "utf8");
9625
9954
  const needle = `${mainRepo.replace(/\/+$/, "")}/.git`;
9626
9955
  return text7.includes(needle);
9627
9956
  } catch {
@@ -9630,10 +9959,10 @@ function isLinkedWorktreeOf(path2, mainRepo) {
9630
9959
  }
9631
9960
  function primaryCheckoutFromLinkedWorktree(path2) {
9632
9961
  if (!path2) return null;
9633
- const git2 = (0, import_node_path23.join)(path2, ".git");
9962
+ const git2 = (0, import_node_path24.join)(path2, ".git");
9634
9963
  try {
9635
- if (!(0, import_node_fs20.existsSync)(git2) || (0, import_node_fs20.statSync)(git2).isDirectory()) return null;
9636
- const text7 = (0, import_node_fs20.readFileSync)(git2, "utf8");
9964
+ if (!(0, import_node_fs21.existsSync)(git2) || (0, import_node_fs21.statSync)(git2).isDirectory()) return null;
9965
+ const text7 = (0, import_node_fs21.readFileSync)(git2, "utf8");
9637
9966
  const match = /^\s*gitdir:\s*(.+)$/m.exec(text7);
9638
9967
  if (!match) return null;
9639
9968
  const gitdir = match[1].trim().replace(/\/+$/, "");
@@ -9654,7 +9983,7 @@ function resolveSyncWorkspacePath(path2) {
9654
9983
  async function addWorkspace(repoPath) {
9655
9984
  const root = await resolveRepoRoot(repoPath);
9656
9985
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
9657
- if (!(0, import_node_fs20.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
9986
+ if (!(0, import_node_fs21.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
9658
9987
  forgetRemoved(root);
9659
9988
  await ensureGhPreferOrigin(root);
9660
9989
  const current = readAll2();
@@ -9663,7 +9992,7 @@ async function addWorkspace(repoPath) {
9663
9992
  if (existing && withoutLinked.length === current.length) return existing;
9664
9993
  const next = existing ?? {
9665
9994
  path: root,
9666
- name: (0, import_node_path23.basename)(root),
9995
+ name: (0, import_node_path24.basename)(root),
9667
9996
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9668
9997
  };
9669
9998
  writeAll2(existing ? withoutLinked : [...withoutLinked, next]);
@@ -9691,7 +10020,7 @@ function syncWorkspacesFromThreads(repoPaths) {
9691
10020
  if (!byPath.has(resolved)) {
9692
10021
  byPath.set(
9693
10022
  resolved,
9694
- resolved === w.path ? w : { ...w, path: resolved, name: (0, import_node_path23.basename)(resolved) }
10023
+ resolved === w.path ? w : { ...w, path: resolved, name: (0, import_node_path24.basename)(resolved) }
9695
10024
  );
9696
10025
  }
9697
10026
  }
@@ -9700,10 +10029,10 @@ function syncWorkspacesFromThreads(repoPaths) {
9700
10029
  if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
9701
10030
  continue;
9702
10031
  }
9703
- if (!(0, import_node_fs20.existsSync)(path2)) continue;
10032
+ if (!(0, import_node_fs21.existsSync)(path2)) continue;
9704
10033
  const ws = {
9705
10034
  path: path2,
9706
- name: (0, import_node_path23.basename)(path2),
10035
+ name: (0, import_node_path24.basename)(path2),
9707
10036
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9708
10037
  };
9709
10038
  byPath.set(path2, ws);
@@ -9720,12 +10049,12 @@ function syncWorkspacesFromThreads(repoPaths) {
9720
10049
  if (dirty) writeAll2(next);
9721
10050
  return next.sort((a, b) => a.name.localeCompare(b.name));
9722
10051
  }
9723
- var import_node_fs20, import_node_path23;
10052
+ var import_node_fs21, import_node_path24;
9724
10053
  var init_workspaces = __esm({
9725
10054
  "src/store/workspaces.ts"() {
9726
10055
  "use strict";
9727
- import_node_fs20 = require("fs");
9728
- import_node_path23 = require("path");
10056
+ import_node_fs21 = require("fs");
10057
+ import_node_path24 = require("path");
9729
10058
  init_paths();
9730
10059
  init_global_workspace();
9731
10060
  init_worktree();
@@ -9836,7 +10165,7 @@ function coordinatorTurnReminder(opts) {
9836
10165
  function ensureGlobalCoordinatorCwd(opts) {
9837
10166
  const dir = globalAgentCwd();
9838
10167
  try {
9839
- (0, import_node_fs21.mkdirSync)(dir, { recursive: true });
10168
+ (0, import_node_fs22.mkdirSync)(dir, { recursive: true });
9840
10169
  } catch {
9841
10170
  return dir;
9842
10171
  }
@@ -9844,7 +10173,7 @@ function ensureGlobalCoordinatorCwd(opts) {
9844
10173
  let orchId = opts?.orchestratorThreadId?.trim() || "";
9845
10174
  if (!orchId) {
9846
10175
  try {
9847
- const existing = (0, import_node_fs21.readFileSync)((0, import_node_path24.join)(dir, "AGENTS.md"), "utf8");
10176
+ const existing = (0, import_node_fs22.readFileSync)((0, import_node_path25.join)(dir, "AGENTS.md"), "utf8");
9848
10177
  const m = existing.match(
9849
10178
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
9850
10179
  );
@@ -9889,9 +10218,9 @@ function ensureGlobalCoordinatorCwd(opts) {
9889
10218
  "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). If the user gave a goal (Greptile 5/5, CI green), pass that goal through so they watch-fix-push until it lands \u2014 do not start that loop on a plain push, and do not tell the human to poll. Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
9890
10219
  ].join("\n");
9891
10220
  try {
9892
- (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(dir, "CLAUDE.md"), `${body}
10221
+ (0, import_node_fs22.writeFileSync)((0, import_node_path25.join)(dir, "CLAUDE.md"), `${body}
9893
10222
  `, "utf8");
9894
- (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(dir, "AGENTS.md"), `${body}
10223
+ (0, import_node_fs22.writeFileSync)((0, import_node_path25.join)(dir, "AGENTS.md"), `${body}
9895
10224
  `, "utf8");
9896
10225
  } catch {
9897
10226
  }
@@ -9923,12 +10252,12 @@ function coordinatorSystemPrompt(opts) {
9923
10252
  formatWorkspaceInventory(opts.workspaces)
9924
10253
  ].join("\n");
9925
10254
  }
9926
- var import_node_fs21, import_node_path24, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
10255
+ var import_node_fs22, import_node_path25, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9927
10256
  var init_coordinator_prompt = __esm({
9928
10257
  "src/orchestrator/coordinator-prompt.ts"() {
9929
10258
  "use strict";
9930
- import_node_fs21 = require("fs");
9931
- import_node_path24 = require("path");
10259
+ import_node_fs22 = require("fs");
10260
+ import_node_path25 = require("path");
9932
10261
  init_worktree();
9933
10262
  init_app_settings();
9934
10263
  init_paths();
@@ -9968,7 +10297,7 @@ var init_coordinator_prompt = __esm({
9968
10297
  "- archive_thread / restore_thread \u2014 archive (tears down worktree when last tab) or restore",
9969
10298
  "Setup / run:",
9970
10299
  "- run_setup \u2014 re-run worktree setup (already runs automatically on create when a script exists)",
9971
- "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
10300
+ "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts. run_dev_script returns {url, port, preview} (SIDEBOARD_PORT). preview=url \u2192 tell the worktree agent to open that URL; preview=window \u2192 Electron: the native window is the app (url is renderer/HMR only). Never localhost:3000. list_run_scripts active[].url if already running.",
9972
10301
  "Inspect / review / PRs:",
9973
10302
  "- get_diff \u2014 compact diff summary",
9974
10303
  "- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
@@ -10287,13 +10616,13 @@ var init_api = __esm({
10287
10616
 
10288
10617
  // src/slack/reply-target.ts
10289
10618
  function storePath() {
10290
- return (0, import_node_path25.join)(appDataDir(), "slack-reply-to.json");
10619
+ return (0, import_node_path26.join)(appDataDir(), "slack-reply-to.json");
10291
10620
  }
10292
10621
  function readStore() {
10293
10622
  const path2 = storePath();
10294
- if (!(0, import_node_fs22.existsSync)(path2)) return {};
10623
+ if (!(0, import_node_fs23.existsSync)(path2)) return {};
10295
10624
  try {
10296
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
10625
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs23.readFileSync)(path2, "utf8"));
10297
10626
  return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
10298
10627
  } catch {
10299
10628
  return {};
@@ -10308,12 +10637,12 @@ function setSlackReplyTarget(target) {
10308
10637
  function getSlackReplyTarget(threadId) {
10309
10638
  return readStore()[threadId] ?? null;
10310
10639
  }
10311
- var import_node_fs22, import_node_path25;
10640
+ var import_node_fs23, import_node_path26;
10312
10641
  var init_reply_target = __esm({
10313
10642
  "src/slack/reply-target.ts"() {
10314
10643
  "use strict";
10315
- import_node_fs22 = require("fs");
10316
- import_node_path25 = require("path");
10644
+ import_node_fs23 = require("fs");
10645
+ import_node_path26 = require("path");
10317
10646
  init_paths();
10318
10647
  init_private_file();
10319
10648
  init_secure_file();
@@ -10322,7 +10651,7 @@ var init_reply_target = __esm({
10322
10651
 
10323
10652
  // src/slack/workspaces.ts
10324
10653
  function storePath2() {
10325
- return (0, import_node_path26.join)(appDataDir(), "slack-workspaces.json");
10654
+ return (0, import_node_path27.join)(appDataDir(), "slack-workspaces.json");
10326
10655
  }
10327
10656
  function readStore2() {
10328
10657
  try {
@@ -10429,11 +10758,11 @@ function requireSlackWorkspace(teamId) {
10429
10758
  }
10430
10759
  return ws;
10431
10760
  }
10432
- var import_node_path26;
10761
+ var import_node_path27;
10433
10762
  var init_workspaces2 = __esm({
10434
10763
  "src/slack/workspaces.ts"() {
10435
10764
  "use strict";
10436
- import_node_path26 = require("path");
10765
+ import_node_path27 = require("path");
10437
10766
  init_paths();
10438
10767
  init_secure_file();
10439
10768
  init_api();
@@ -10442,7 +10771,7 @@ var init_workspaces2 = __esm({
10442
10771
 
10443
10772
  // src/slack/outbound-watch.ts
10444
10773
  function storePath3() {
10445
- return (0, import_node_path27.join)(appDataDir(), "slack-outbound-watch.json");
10774
+ return (0, import_node_path28.join)(appDataDir(), "slack-outbound-watch.json");
10446
10775
  }
10447
10776
  function watchId(teamId, channelId, ts) {
10448
10777
  return `${teamId}:${channelId}:${ts}`;
@@ -10455,9 +10784,9 @@ function tsNewer(a, b) {
10455
10784
  }
10456
10785
  function readStore3() {
10457
10786
  const path2 = storePath3();
10458
- if (!(0, import_node_fs23.existsSync)(path2)) return [];
10787
+ if (!(0, import_node_fs24.existsSync)(path2)) return [];
10459
10788
  try {
10460
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs23.readFileSync)(path2, "utf8"));
10789
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf8"));
10461
10790
  return Array.isArray(parsed?.watches) ? parsed.watches : [];
10462
10791
  } catch {
10463
10792
  return [];
@@ -10779,12 +11108,12 @@ async function pollSlackOutboundWatches(opts) {
10779
11108
  }
10780
11109
  if (changed) writeStore2(watches);
10781
11110
  }
10782
- var import_node_fs23, import_node_path27, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
11111
+ var import_node_fs24, import_node_path28, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10783
11112
  var init_outbound_watch = __esm({
10784
11113
  "src/slack/outbound-watch.ts"() {
10785
11114
  "use strict";
10786
- import_node_fs23 = require("fs");
10787
- import_node_path27 = require("path");
11115
+ import_node_fs24 = require("fs");
11116
+ import_node_path28 = require("path");
10788
11117
  init_paths();
10789
11118
  init_private_file();
10790
11119
  init_secure_file();
@@ -10806,7 +11135,7 @@ function traceTurn(phase, extra) {
10806
11135
  try {
10807
11136
  const line = `${JSON.stringify({ t: (/* @__PURE__ */ new Date()).toISOString(), phase, ...extra })}
10808
11137
  `;
10809
- (0, import_node_fs24.appendFileSync)((0, import_node_path28.join)(appDataDir(), "turn-spawn.log"), line);
11138
+ (0, import_node_fs25.appendFileSync)((0, import_node_path29.join)(appDataDir(), "turn-spawn.log"), line);
10810
11139
  } catch {
10811
11140
  }
10812
11141
  }
@@ -10826,12 +11155,12 @@ async function withTimeout(promise, ms, label) {
10826
11155
  if (timer) clearTimeout(timer);
10827
11156
  }
10828
11157
  }
10829
- var import_node_fs24, import_node_path28;
11158
+ var import_node_fs25, import_node_path29;
10830
11159
  var init_turn_trace = __esm({
10831
11160
  "src/agents/turn-trace.ts"() {
10832
11161
  "use strict";
10833
- import_node_fs24 = require("fs");
10834
- import_node_path28 = require("path");
11162
+ import_node_fs25 = require("fs");
11163
+ import_node_path29 = require("path");
10835
11164
  init_paths();
10836
11165
  }
10837
11166
  });
@@ -10840,32 +11169,32 @@ var init_turn_trace = __esm({
10840
11169
  function brightsyConfigPath() {
10841
11170
  const override = process.env.BRIGHTSY_CONFIG?.trim();
10842
11171
  if (override) return override;
10843
- return (0, import_node_path29.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
11172
+ return (0, import_node_path30.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10844
11173
  }
10845
11174
  function loadBrightsyConfig() {
10846
11175
  const path2 = brightsyConfigPath();
10847
- if (!(0, import_node_fs25.existsSync)(path2)) {
11176
+ if (!(0, import_node_fs26.existsSync)(path2)) {
10848
11177
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
10849
11178
  }
10850
- const raw = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf8"));
11179
+ const raw = JSON.parse((0, import_node_fs26.readFileSync)(path2, "utf8"));
10851
11180
  if (!raw.access_token || !raw.account_id) {
10852
11181
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
10853
11182
  }
10854
11183
  return raw;
10855
11184
  }
10856
11185
  function saveBrightsyConfig(cfg) {
10857
- (0, import_node_fs25.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
11186
+ (0, import_node_fs26.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
10858
11187
  `, {
10859
11188
  mode: 384
10860
11189
  });
10861
11190
  }
10862
- var import_node_fs25, import_node_os7, import_node_path29;
11191
+ var import_node_fs26, import_node_os7, import_node_path30;
10863
11192
  var init_config = __esm({
10864
11193
  "src/brightsy/config.ts"() {
10865
11194
  "use strict";
10866
- import_node_fs25 = require("fs");
11195
+ import_node_fs26 = require("fs");
10867
11196
  import_node_os7 = require("os");
10868
- import_node_path29 = require("path");
11197
+ import_node_path30 = require("path");
10869
11198
  }
10870
11199
  });
10871
11200
 
@@ -11167,22 +11496,22 @@ __export(connected_teams_exports, {
11167
11496
  listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
11168
11497
  });
11169
11498
  function storePath4() {
11170
- return (0, import_node_path30.join)(appDataDir(), "brightsy-teams.json");
11499
+ return (0, import_node_path31.join)(appDataDir(), "brightsy-teams.json");
11171
11500
  }
11172
11501
  function readStore4() {
11173
11502
  const path2 = storePath4();
11174
- if (!(0, import_node_fs26.existsSync)(path2)) return [];
11503
+ if (!(0, import_node_fs27.existsSync)(path2)) return [];
11175
11504
  try {
11176
- const parsed = JSON.parse((0, import_node_fs26.readFileSync)(path2, "utf8"));
11505
+ const parsed = JSON.parse((0, import_node_fs27.readFileSync)(path2, "utf8"));
11177
11506
  return Array.isArray(parsed.teams) ? parsed.teams : [];
11178
11507
  } catch {
11179
11508
  return [];
11180
11509
  }
11181
11510
  }
11182
11511
  function writeStore3(teams) {
11183
- (0, import_node_fs26.mkdirSync)(appDataDir(), { recursive: true });
11512
+ (0, import_node_fs27.mkdirSync)(appDataDir(), { recursive: true });
11184
11513
  const path2 = storePath4();
11185
- (0, import_node_fs26.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
11514
+ (0, import_node_fs27.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
11186
11515
  `, {
11187
11516
  mode: 384
11188
11517
  });
@@ -11370,12 +11699,12 @@ function brightsyMcpServerName(slug) {
11370
11699
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
11371
11700
  return `brightsy_${cleaned || "team"}`;
11372
11701
  }
11373
- var import_node_fs26, import_node_path30;
11702
+ var import_node_fs27, import_node_path31;
11374
11703
  var init_connected_teams = __esm({
11375
11704
  "src/brightsy/connected-teams.ts"() {
11376
11705
  "use strict";
11377
- import_node_fs26 = require("fs");
11378
- import_node_path30 = require("path");
11706
+ import_node_fs27 = require("fs");
11707
+ import_node_path31 = require("path");
11379
11708
  init_paths();
11380
11709
  init_accounts();
11381
11710
  init_config();
@@ -11740,11 +12069,11 @@ async function syncCliForTarget(accountId) {
11740
12069
  }
11741
12070
  applyConnectedTeamToCli(team);
11742
12071
  }
11743
- var import_node_fs27, brightsyAdapter;
12072
+ var import_node_fs28, brightsyAdapter;
11744
12073
  var init_brightsy = __esm({
11745
12074
  "src/agents/brightsy.ts"() {
11746
12075
  "use strict";
11747
- import_node_fs27 = require("fs");
12076
+ import_node_fs28 = require("fs");
11748
12077
  init_run();
11749
12078
  init_connected_teams();
11750
12079
  init_config();
@@ -11759,7 +12088,7 @@ var init_brightsy = __esm({
11759
12088
  async detect() {
11760
12089
  const brightsy = resolveAgentExecutable("brightsy");
11761
12090
  if (brightsy !== "brightsy") {
11762
- if (!(0, import_node_fs27.existsSync)(brightsy)) {
12091
+ if (!(0, import_node_fs28.existsSync)(brightsy)) {
11763
12092
  return {
11764
12093
  agent: "brightsy",
11765
12094
  installed: false,
@@ -11943,7 +12272,7 @@ function splitPemCertificates(pem) {
11943
12272
  }
11944
12273
  function readExistingFile(path2) {
11945
12274
  try {
11946
- return (0, import_node_fs28.existsSync)(path2) ? (0, import_node_fs28.readFileSync)(path2, "utf8") : "";
12275
+ return (0, import_node_fs29.existsSync)(path2) ? (0, import_node_fs29.readFileSync)(path2, "utf8") : "";
11947
12276
  } catch {
11948
12277
  return "";
11949
12278
  }
@@ -11975,13 +12304,13 @@ function collectSystemCaPem(io = {}) {
11975
12304
  return "";
11976
12305
  }
11977
12306
  function systemCaBundlePath(io = {}) {
11978
- return (0, import_node_path31.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
12307
+ return (0, import_node_path32.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11979
12308
  }
11980
12309
  function bundleIsFresh(path2, now) {
11981
12310
  try {
11982
- if (!(0, import_node_fs28.existsSync)(path2)) return false;
11983
- if (splitPemCertificates((0, import_node_fs28.readFileSync)(path2, "utf8")).length === 0) return false;
11984
- return now - (0, import_node_fs28.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
12311
+ if (!(0, import_node_fs29.existsSync)(path2)) return false;
12312
+ if (splitPemCertificates((0, import_node_fs29.readFileSync)(path2, "utf8")).length === 0) return false;
12313
+ return now - (0, import_node_fs29.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
11985
12314
  } catch {
11986
12315
  return false;
11987
12316
  }
@@ -12002,11 +12331,11 @@ function materializeSystemCaBundle(io = {}) {
12002
12331
  if (bundleIsFresh(dest, now)) return dest;
12003
12332
  const pem = collectSystemCaPem(io);
12004
12333
  if (splitPemCertificates(pem).length === 0) {
12005
- return (0, import_node_fs28.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
12334
+ return (0, import_node_fs29.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
12006
12335
  }
12007
12336
  try {
12008
- (0, import_node_fs28.mkdirSync)((0, import_node_path31.dirname)(dest), { recursive: true });
12009
- (0, import_node_fs28.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
12337
+ (0, import_node_fs29.mkdirSync)((0, import_node_path32.dirname)(dest), { recursive: true });
12338
+ (0, import_node_fs29.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
12010
12339
  `, { mode: 384 });
12011
12340
  return dest;
12012
12341
  } catch {
@@ -12046,13 +12375,13 @@ function trustSystemCertificates(io = {}) {
12046
12375
  return false;
12047
12376
  }
12048
12377
  }
12049
- var import_node_child_process4, import_node_fs28, import_node_path31, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
12378
+ var import_node_child_process4, import_node_fs29, import_node_path32, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
12050
12379
  var init_system_ca = __esm({
12051
12380
  "src/http/system-ca.ts"() {
12052
12381
  "use strict";
12053
12382
  import_node_child_process4 = require("child_process");
12054
- import_node_fs28 = require("fs");
12055
- import_node_path31 = require("path");
12383
+ import_node_fs29 = require("fs");
12384
+ import_node_path32 = require("path");
12056
12385
  import_node_tls = __toESM(require("tls"), 1);
12057
12386
  init_paths();
12058
12387
  NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
@@ -12078,43 +12407,43 @@ function electronResourcesPath() {
12078
12407
  function packagedCursorRuntimeDir() {
12079
12408
  const resources = electronResourcesPath();
12080
12409
  if (!resources) return null;
12081
- const dir = (0, import_node_path32.join)(resources, "cursor-runtime");
12082
- if (!(0, import_node_fs29.existsSync)((0, import_node_path32.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
12410
+ const dir = (0, import_node_path33.join)(resources, "cursor-runtime");
12411
+ if (!(0, import_node_fs30.existsSync)((0, import_node_path33.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
12083
12412
  return dir;
12084
12413
  }
12085
12414
  function packagedCursorRunnerPath() {
12086
12415
  const dir = packagedCursorRuntimeDir();
12087
- return dir ? (0, import_node_path32.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
12416
+ return dir ? (0, import_node_path33.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
12088
12417
  }
12089
12418
  function packagedMcpDir() {
12090
12419
  const resources = electronResourcesPath();
12091
12420
  if (!resources) return null;
12092
- const dir = (0, import_node_path32.join)(resources, "sideboard-mcp");
12093
- if (!(0, import_node_fs29.existsSync)((0, import_node_path32.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
12421
+ const dir = (0, import_node_path33.join)(resources, "sideboard-mcp");
12422
+ if (!(0, import_node_fs30.existsSync)((0, import_node_path33.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
12094
12423
  return dir;
12095
12424
  }
12096
12425
  function packagedMcpStdioPath() {
12097
12426
  const dir = packagedMcpDir();
12098
- return dir ? (0, import_node_path32.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
12427
+ return dir ? (0, import_node_path33.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
12099
12428
  }
12100
12429
  function packagedBundledNodePath() {
12101
12430
  const resources = electronResourcesPath();
12102
12431
  if (!resources) return null;
12103
- const bin = (0, import_node_path32.join)(resources, "node", "bin", "node");
12104
- if (!(0, import_node_fs29.existsSync)(bin)) return null;
12432
+ const bin = (0, import_node_path33.join)(resources, "node", "bin", "node");
12433
+ if (!(0, import_node_fs30.existsSync)(bin)) return null;
12105
12434
  return bin;
12106
12435
  }
12107
12436
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
12108
12437
  const dir = packagedCursorRuntimeDir();
12109
12438
  if (!dir) return null;
12110
- return (0, import_node_path32.join)(dir, "node_modules", platformPkg, "bin", binName);
12439
+ return (0, import_node_path33.join)(dir, "node_modules", platformPkg, "bin", binName);
12111
12440
  }
12112
- var import_node_fs29, import_node_path32;
12441
+ var import_node_fs30, import_node_path33;
12113
12442
  var init_packaged_runtime = __esm({
12114
12443
  "src/agents/packaged-runtime.ts"() {
12115
12444
  "use strict";
12116
- import_node_fs29 = require("fs");
12117
- import_node_path32 = require("path");
12445
+ import_node_fs30 = require("fs");
12446
+ import_node_path33 = require("path");
12118
12447
  }
12119
12448
  });
12120
12449
 
@@ -12149,7 +12478,7 @@ function unpackedAsarPath(filePath) {
12149
12478
  if (!isAsarPath(filePath)) return null;
12150
12479
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
12151
12480
  if (unpacked === filePath) return null;
12152
- return (0, import_node_fs30.existsSync)(unpacked) ? unpacked : null;
12481
+ return (0, import_node_fs31.existsSync)(unpacked) ? unpacked : null;
12153
12482
  }
12154
12483
  function nodeReadableScriptPath(scriptPath) {
12155
12484
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -12189,37 +12518,37 @@ function pickPreferredNode(candidates) {
12189
12518
  return best;
12190
12519
  }
12191
12520
  function versionDirNodeBins(root, toBin) {
12192
- if (!(0, import_node_fs30.existsSync)(root)) return [];
12521
+ if (!(0, import_node_fs31.existsSync)(root)) return [];
12193
12522
  try {
12194
- return (0, import_node_fs30.readdirSync)(root).map(toBin);
12523
+ return (0, import_node_fs31.readdirSync)(root).map(toBin);
12195
12524
  } catch {
12196
12525
  return [];
12197
12526
  }
12198
12527
  }
12199
12528
  function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
12200
12529
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
12201
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path33.join)(prefix, "opt", `node@${major}`, "bin", "node"))
12530
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path34.join)(prefix, "opt", `node@${major}`, "bin", "node"))
12202
12531
  );
12203
12532
  return [
12204
12533
  ...kegs,
12205
12534
  "/opt/homebrew/bin/node",
12206
12535
  "/usr/local/bin/node",
12207
- (0, import_node_path33.join)(home, ".local/share/fnm/aliases/default/bin/node"),
12208
- (0, import_node_path33.join)(home, ".nvm/current/bin/node"),
12209
- (0, import_node_path33.join)(home, ".volta/bin/node"),
12210
- (0, import_node_path33.join)(home, ".asdf/shims/node"),
12211
- (0, import_node_path33.join)(home, ".local/share/mise/shims/node"),
12536
+ (0, import_node_path34.join)(home, ".local/share/fnm/aliases/default/bin/node"),
12537
+ (0, import_node_path34.join)(home, ".nvm/current/bin/node"),
12538
+ (0, import_node_path34.join)(home, ".volta/bin/node"),
12539
+ (0, import_node_path34.join)(home, ".asdf/shims/node"),
12540
+ (0, import_node_path34.join)(home, ".local/share/mise/shims/node"),
12212
12541
  ...versionDirNodeBins(
12213
- (0, import_node_path33.join)(home, ".nvm", "versions", "node"),
12214
- (name) => (0, import_node_path33.join)(home, ".nvm", "versions", "node", name, "bin", "node")
12542
+ (0, import_node_path34.join)(home, ".nvm", "versions", "node"),
12543
+ (name) => (0, import_node_path34.join)(home, ".nvm", "versions", "node", name, "bin", "node")
12215
12544
  ),
12216
12545
  ...versionDirNodeBins(
12217
- (0, import_node_path33.join)(home, ".local/share/fnm", "node-versions"),
12218
- (name) => (0, import_node_path33.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
12546
+ (0, import_node_path34.join)(home, ".local/share/fnm", "node-versions"),
12547
+ (name) => (0, import_node_path34.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
12219
12548
  ),
12220
12549
  ...versionDirNodeBins(
12221
- (0, import_node_path33.join)(home, ".volta", "tools", "image", "node"),
12222
- (name) => (0, import_node_path33.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
12550
+ (0, import_node_path34.join)(home, ".volta", "tools", "image", "node"),
12551
+ (name) => (0, import_node_path34.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
12223
12552
  )
12224
12553
  ];
12225
12554
  }
@@ -12228,10 +12557,10 @@ function uniqueExistingNodeBins(paths) {
12228
12557
  const out = [];
12229
12558
  for (const raw of paths) {
12230
12559
  const p = raw.trim();
12231
- if (!p || !(0, import_node_fs30.existsSync)(p) || isElectronLikeCommand(p)) continue;
12560
+ if (!p || !(0, import_node_fs31.existsSync)(p) || isElectronLikeCommand(p)) continue;
12232
12561
  let key = p;
12233
12562
  try {
12234
- key = (0, import_node_fs30.realpathSync)(p);
12563
+ key = (0, import_node_fs31.realpathSync)(p);
12235
12564
  } catch {
12236
12565
  continue;
12237
12566
  }
@@ -12311,13 +12640,13 @@ async function resolveNodeLaunch(scriptPath) {
12311
12640
  env: { ELECTRON_RUN_AS_NODE: "1" }
12312
12641
  };
12313
12642
  }
12314
- var import_node_fs30, import_node_os8, import_node_path33, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
12643
+ var import_node_fs31, import_node_os8, import_node_path34, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
12315
12644
  var init_node_launch = __esm({
12316
12645
  "src/agents/node-launch.ts"() {
12317
12646
  "use strict";
12318
- import_node_fs30 = require("fs");
12647
+ import_node_fs31 = require("fs");
12319
12648
  import_node_os8 = require("os");
12320
- import_node_path33 = require("path");
12649
+ import_node_path34 = require("path");
12321
12650
  init_nested_electron_env();
12322
12651
  init_system_ca();
12323
12652
  init_run();
@@ -12420,37 +12749,37 @@ function corePackageDir() {
12420
12749
  try {
12421
12750
  const url = import_meta.url;
12422
12751
  if (typeof url === "string" && url.length > 0) {
12423
- return (0, import_node_path34.dirname)((0, import_node_url.fileURLToPath)(url));
12752
+ return (0, import_node_path35.dirname)((0, import_node_url.fileURLToPath)(url));
12424
12753
  }
12425
12754
  } catch {
12426
12755
  }
12427
12756
  try {
12428
- const req = (0, import_node_module.createRequire)((0, import_node_path34.join)(process.cwd(), "package.json"));
12429
- return (0, import_node_path34.dirname)(req.resolve("@sideboard-ai/core"));
12757
+ const req = (0, import_node_module.createRequire)((0, import_node_path35.join)(process.cwd(), "package.json"));
12758
+ return (0, import_node_path35.dirname)(req.resolve("@sideboard-ai/core"));
12430
12759
  } catch {
12431
12760
  return process.cwd();
12432
12761
  }
12433
12762
  }
12434
12763
  function findSideboardMcpJsEntry() {
12435
12764
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
12436
- if (override && (0, import_node_fs31.existsSync)(override)) return override;
12765
+ if (override && (0, import_node_fs32.existsSync)(override)) return override;
12437
12766
  const packaged = packagedMcpStdioPath();
12438
12767
  if (packaged) return packaged;
12439
12768
  let dir = corePackageDir();
12440
12769
  for (let i = 0; i < 10; i++) {
12441
12770
  const candidates = [
12442
- (0, import_node_path34.join)(dir, "mcp/run-stdio.js"),
12443
- (0, import_node_path34.join)(dir, "mcp/run-stdio.cjs"),
12444
- (0, import_node_path34.join)(dir, "dist/mcp/run-stdio.js"),
12445
- (0, import_node_path34.join)(dir, "dist/mcp/run-stdio.cjs"),
12446
- (0, import_node_path34.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
12447
- (0, import_node_path34.join)(dir, "packages/cli/dist/index.js"),
12448
- (0, import_node_path34.join)(dir, "cli/dist/index.js")
12771
+ (0, import_node_path35.join)(dir, "mcp/run-stdio.js"),
12772
+ (0, import_node_path35.join)(dir, "mcp/run-stdio.cjs"),
12773
+ (0, import_node_path35.join)(dir, "dist/mcp/run-stdio.js"),
12774
+ (0, import_node_path35.join)(dir, "dist/mcp/run-stdio.cjs"),
12775
+ (0, import_node_path35.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
12776
+ (0, import_node_path35.join)(dir, "packages/cli/dist/index.js"),
12777
+ (0, import_node_path35.join)(dir, "cli/dist/index.js")
12449
12778
  ];
12450
12779
  for (const p of candidates) {
12451
- if ((0, import_node_fs31.existsSync)(p) && !isAsarPath(p)) return p;
12780
+ if ((0, import_node_fs32.existsSync)(p) && !isAsarPath(p)) return p;
12452
12781
  }
12453
- const parent = (0, import_node_path34.dirname)(dir);
12782
+ const parent = (0, import_node_path35.dirname)(dir);
12454
12783
  if (parent === dir) break;
12455
12784
  dir = parent;
12456
12785
  }
@@ -12613,22 +12942,22 @@ function writeMcpServersConfig(servers, extraServers) {
12613
12942
  }
12614
12943
  }
12615
12944
  if (Object.keys(mcpServers).length === 0) return null;
12616
- const dir = (0, import_node_fs31.mkdtempSync)((0, import_node_path34.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12617
- const cfgPath = (0, import_node_path34.join)(dir, "mcp.json");
12618
- (0, import_node_fs31.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12945
+ const dir = (0, import_node_fs32.mkdtempSync)((0, import_node_path35.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12946
+ const cfgPath = (0, import_node_path35.join)(dir, "mcp.json");
12947
+ (0, import_node_fs32.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12619
12948
  return cfgPath;
12620
12949
  }
12621
12950
  async function writeInjectedMcpConfig(opts) {
12622
12951
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
12623
12952
  }
12624
- var import_node_fs31, import_node_module, import_node_os9, import_node_path34, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
12953
+ var import_node_fs32, import_node_module, import_node_os9, import_node_path35, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
12625
12954
  var init_injected_mcp = __esm({
12626
12955
  "src/agents/injected-mcp.ts"() {
12627
12956
  "use strict";
12628
- import_node_fs31 = require("fs");
12957
+ import_node_fs32 = require("fs");
12629
12958
  import_node_module = require("module");
12630
12959
  import_node_os9 = require("os");
12631
- import_node_path34 = require("path");
12960
+ import_node_path35 = require("path");
12632
12961
  import_node_url = require("url");
12633
12962
  init_run();
12634
12963
  init_config();
@@ -12673,10 +13002,10 @@ var init_injected_mcp = __esm({
12673
13002
 
12674
13003
  // src/agents/user-mcp-config.ts
12675
13004
  function userCursorMcpConfigPath() {
12676
- return (0, import_node_path35.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
13005
+ return (0, import_node_path36.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12677
13006
  }
12678
13007
  function userClaudeMcpConfigPath() {
12679
- return (0, import_node_path35.join)((0, import_node_os10.homedir)(), ".claude.json");
13008
+ return (0, import_node_path36.join)((0, import_node_os10.homedir)(), ".claude.json");
12680
13009
  }
12681
13010
  function asObject(value) {
12682
13011
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -12703,16 +13032,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
12703
13032
  }
12704
13033
  function writeMergedMcpServersJson(configPath, sideboard) {
12705
13034
  let existing = {};
12706
- if ((0, import_node_fs32.existsSync)(configPath)) {
13035
+ if ((0, import_node_fs33.existsSync)(configPath)) {
12707
13036
  try {
12708
- existing = JSON.parse((0, import_node_fs32.readFileSync)(configPath, "utf8"));
13037
+ existing = JSON.parse((0, import_node_fs33.readFileSync)(configPath, "utf8"));
12709
13038
  } catch {
12710
13039
  existing = {};
12711
13040
  }
12712
13041
  }
12713
13042
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
12714
- (0, import_node_fs32.mkdirSync)((0, import_node_path35.dirname)(configPath), { recursive: true });
12715
- (0, import_node_fs32.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
13043
+ (0, import_node_fs33.mkdirSync)((0, import_node_path36.dirname)(configPath), { recursive: true });
13044
+ (0, import_node_fs33.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
12716
13045
  `);
12717
13046
  }
12718
13047
  function launchFromResolved(server) {
@@ -12730,19 +13059,19 @@ async function registerPackagedUserMcpClients() {
12730
13059
  const cursor = userCursorMcpConfigPath();
12731
13060
  writeMergedMcpServersJson(cursor, launch);
12732
13061
  const claude = userClaudeMcpConfigPath();
12733
- if ((0, import_node_fs32.existsSync)(claude)) {
13062
+ if ((0, import_node_fs33.existsSync)(claude)) {
12734
13063
  writeMergedMcpServersJson(claude, launch);
12735
13064
  return { cursor, claude };
12736
13065
  }
12737
13066
  return { cursor };
12738
13067
  }
12739
- var import_node_fs32, import_node_os10, import_node_path35;
13068
+ var import_node_fs33, import_node_os10, import_node_path36;
12740
13069
  var init_user_mcp_config = __esm({
12741
13070
  "src/agents/user-mcp-config.ts"() {
12742
13071
  "use strict";
12743
- import_node_fs32 = require("fs");
13072
+ import_node_fs33 = require("fs");
12744
13073
  import_node_os10 = require("os");
12745
- import_node_path35 = require("path");
13074
+ import_node_path36 = require("path");
12746
13075
  init_paths();
12747
13076
  init_injected_mcp();
12748
13077
  }
@@ -12768,27 +13097,27 @@ function listMcpNamesFromCodexToml(text7) {
12768
13097
  return [];
12769
13098
  }
12770
13099
  }
12771
- function readJsonObject(path2) {
13100
+ function readJsonObject2(path2) {
12772
13101
  try {
12773
- return JSON.parse((0, import_node_fs33.readFileSync)(path2, "utf8"));
13102
+ return JSON.parse((0, import_node_fs34.readFileSync)(path2, "utf8"));
12774
13103
  } catch {
12775
13104
  return {};
12776
13105
  }
12777
13106
  }
12778
13107
  function readText(path2) {
12779
13108
  try {
12780
- return (0, import_node_fs33.readFileSync)(path2, "utf8");
13109
+ return (0, import_node_fs34.readFileSync)(path2, "utf8");
12781
13110
  } catch {
12782
13111
  return "";
12783
13112
  }
12784
13113
  }
12785
13114
  function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
12786
- return [(0, import_node_path36.join)(home, ".codex", "config.toml"), (0, import_node_path36.join)(home, ".config", "codex", "config.toml")];
13115
+ return [(0, import_node_path37.join)(home, ".codex", "config.toml"), (0, import_node_path37.join)(home, ".config", "codex", "config.toml")];
12787
13116
  }
12788
13117
  function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
12789
13118
  return [
12790
- (0, import_node_path36.join)(home, ".config", "opencode", "opencode.json"),
12791
- (0, import_node_path36.join)(home, ".config", "opencode", "opencode.jsonc")
13119
+ (0, import_node_path37.join)(home, ".config", "opencode", "opencode.json"),
13120
+ (0, import_node_path37.join)(home, ".config", "opencode", "opencode.jsonc")
12792
13121
  ];
12793
13122
  }
12794
13123
  function userMcpNamesToDisable(opts) {
@@ -12810,7 +13139,7 @@ function userMcpNamesToDisable(opts) {
12810
13139
  function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
12811
13140
  const names = [];
12812
13141
  for (const path2 of userCodexConfigPaths(home)) {
12813
- if (!(0, import_node_fs33.existsSync)(path2)) continue;
13142
+ if (!(0, import_node_fs34.existsSync)(path2)) continue;
12814
13143
  names.push(...listMcpNamesFromCodexToml(readText(path2)));
12815
13144
  }
12816
13145
  return names;
@@ -12818,15 +13147,15 @@ function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
12818
13147
  function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
12819
13148
  const names = [];
12820
13149
  for (const path2 of userOpencodeConfigPaths(home)) {
12821
- if (!(0, import_node_fs33.existsSync)(path2)) continue;
12822
- names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
13150
+ if (!(0, import_node_fs34.existsSync)(path2)) continue;
13151
+ names.push(...listMcpNamesFromJsonMap(readJsonObject2(path2), "mcp"));
12823
13152
  }
12824
13153
  return names;
12825
13154
  }
12826
13155
  function userClaudeMcpConfigObject(home = (0, import_node_os11.homedir)()) {
12827
- const claudePath = home === (0, import_node_os11.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path36.join)(home, ".claude.json");
12828
- if (!(0, import_node_fs33.existsSync)(claudePath)) return {};
12829
- return asObject2(asObject2(readJsonObject(claudePath)).mcpServers);
13156
+ const claudePath = home === (0, import_node_os11.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path37.join)(home, ".claude.json");
13157
+ if (!(0, import_node_fs34.existsSync)(claudePath)) return {};
13158
+ return asObject2(asObject2(readJsonObject2(claudePath)).mcpServers);
12830
13159
  }
12831
13160
  function listUserClaudeMcpServerEntries(home = (0, import_node_os11.homedir)()) {
12832
13161
  const out = {};
@@ -12858,13 +13187,13 @@ function toCodexUnattendedAppsArgs() {
12858
13187
  "features.plugins=false"
12859
13188
  ];
12860
13189
  }
12861
- var import_node_fs33, import_node_os11, import_node_path36, import_smol_toml2;
13190
+ var import_node_fs34, import_node_os11, import_node_path37, import_smol_toml2;
12862
13191
  var init_orch_mcp_isolation = __esm({
12863
13192
  "src/agents/orch-mcp-isolation.ts"() {
12864
13193
  "use strict";
12865
- import_node_fs33 = require("fs");
13194
+ import_node_fs34 = require("fs");
12866
13195
  import_node_os11 = require("os");
12867
- import_node_path36 = require("path");
13196
+ import_node_path37 = require("path");
12868
13197
  import_smol_toml2 = require("smol-toml");
12869
13198
  init_user_mcp_config();
12870
13199
  }
@@ -12981,6 +13310,87 @@ function claudeResultErrorDetail(obj) {
12981
13310
  }
12982
13311
  return "Claude turn failed";
12983
13312
  }
13313
+ function toolResultContent(block) {
13314
+ if (typeof block.content === "string") return block.content;
13315
+ if (Array.isArray(block.content)) {
13316
+ return block.content.map(
13317
+ (c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
13318
+ ).join("");
13319
+ }
13320
+ if (block.content != null) return JSON.stringify(block.content);
13321
+ return void 0;
13322
+ }
13323
+ function skillToolEventsFromBody(text7, parentId) {
13324
+ const command = skillCommandFromBody(text7) ?? "skill";
13325
+ const id = `skill-${command}`;
13326
+ return [
13327
+ withEventParentId(
13328
+ { type: "tool_use", id, name: "Skill", input: { skill: command } },
13329
+ parentId
13330
+ ),
13331
+ withEventParentId({ type: "tool_result", id, content: text7 }, parentId)
13332
+ ];
13333
+ }
13334
+ function compactToolEventsFromBody(text7, parentId) {
13335
+ const id = "compact-summary";
13336
+ return [
13337
+ withEventParentId(
13338
+ { type: "tool_use", id, name: "Compact", input: { trigger: "injected" } },
13339
+ parentId
13340
+ ),
13341
+ withEventParentId({ type: "tool_result", id, content: text7 }, parentId)
13342
+ ];
13343
+ }
13344
+ function eventsFromInjectedUserText(text7, parentId) {
13345
+ if (looksLikeSkillBody(text7)) return skillToolEventsFromBody(text7, parentId);
13346
+ if (looksLikeConversationSummary(text7)) return compactToolEventsFromBody(text7, parentId);
13347
+ return [];
13348
+ }
13349
+ function eventsFromUserContent(content, parentId) {
13350
+ if (typeof content === "string" && content.trim()) {
13351
+ return eventsFromInjectedUserText(content, parentId);
13352
+ }
13353
+ if (!Array.isArray(content) || content.length === 0) return [];
13354
+ const out = [];
13355
+ const textBlocks = [];
13356
+ for (const block of content) {
13357
+ if (!block?.type) continue;
13358
+ if (block.type === "tool_use" && block.id && block.name) {
13359
+ out.push(
13360
+ withEventParentId(
13361
+ {
13362
+ type: "tool_use",
13363
+ id: block.id,
13364
+ name: block.name,
13365
+ input: block.input
13366
+ },
13367
+ parentId
13368
+ )
13369
+ );
13370
+ continue;
13371
+ }
13372
+ if (block.type === "tool_result" && block.tool_use_id) {
13373
+ out.push(
13374
+ withEventParentId(
13375
+ {
13376
+ type: "tool_result",
13377
+ id: block.tool_use_id,
13378
+ content: toolResultContent(block),
13379
+ isError: Boolean(block.is_error)
13380
+ },
13381
+ parentId
13382
+ )
13383
+ );
13384
+ continue;
13385
+ }
13386
+ if (block.type === "text" && block.text) textBlocks.push(block.text);
13387
+ }
13388
+ if (out.length > 0) return out;
13389
+ for (const text7 of textBlocks) {
13390
+ out.push(...eventsFromInjectedUserText(text7, parentId));
13391
+ }
13392
+ return out;
13393
+ }
12984
13394
  function eventsFromContentBlocks(blocks, parentId) {
12985
13395
  if (!blocks?.length) return [];
12986
13396
  const out = [];
@@ -13009,15 +13419,12 @@ function eventsFromContentBlocks(blocks, parentId) {
13009
13419
  continue;
13010
13420
  }
13011
13421
  if (block.type === "tool_result" && block.tool_use_id) {
13012
- const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
13013
- (c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
13014
- ).join("") : block.content != null ? JSON.stringify(block.content) : void 0;
13015
13422
  out.push(
13016
13423
  withEventParentId(
13017
13424
  {
13018
13425
  type: "tool_result",
13019
13426
  id: block.tool_use_id,
13020
- content,
13427
+ content: toolResultContent(block),
13021
13428
  isError: Boolean(block.is_error)
13022
13429
  },
13023
13430
  parentId
@@ -13227,11 +13634,11 @@ function parseIssuesJson(raw) {
13227
13634
  }
13228
13635
  return [];
13229
13636
  }
13230
- var import_node_fs34, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
13637
+ var import_node_fs35, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
13231
13638
  var init_claude = __esm({
13232
13639
  "src/agents/claude.ts"() {
13233
13640
  "use strict";
13234
- import_node_fs34 = require("fs");
13641
+ import_node_fs35 = require("fs");
13235
13642
  init_run();
13236
13643
  init_app_settings();
13237
13644
  init_claude_mcp();
@@ -13271,7 +13678,7 @@ var init_claude = __esm({
13271
13678
  async detect() {
13272
13679
  const claude = resolveClaudeExecutable();
13273
13680
  if (claude !== "claude") {
13274
- if (!(0, import_node_fs34.existsSync)(claude)) {
13681
+ if (!(0, import_node_fs35.existsSync)(claude)) {
13275
13682
  return {
13276
13683
  agent: "claude",
13277
13684
  installed: false,
@@ -13420,7 +13827,10 @@ var init_claude = __esm({
13420
13827
  if (obj.type === "assistant" || obj.type === "user") {
13421
13828
  const parentId = claudeParentToolUseId(obj);
13422
13829
  const message = obj.message;
13423
- const events = eventsFromContentBlocks(message?.content, parentId);
13830
+ const events = obj.type === "user" ? eventsFromUserContent(message?.content, parentId) : eventsFromContentBlocks(
13831
+ Array.isArray(message?.content) ? message.content : void 0,
13832
+ parentId
13833
+ );
13424
13834
  if (obj.type === "assistant") {
13425
13835
  const usage = usageFromClaude(message?.usage);
13426
13836
  if (usage) events.push({ type: "usage", data: usage, scope: "request" });
@@ -13539,7 +13949,7 @@ async function listCodexModels() {
13539
13949
  if (codex === "codex") {
13540
13950
  const which = await run("which", ["codex"], { reject: false });
13541
13951
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
13542
- } else if (!(0, import_node_fs35.existsSync)(codex)) {
13952
+ } else if (!(0, import_node_fs36.existsSync)(codex)) {
13543
13953
  return FALLBACK_CODEX_MODELS;
13544
13954
  }
13545
13955
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -13574,12 +13984,12 @@ function usageFromCodex(usage) {
13574
13984
  }
13575
13985
  function codexConfigHasNetworkAccess() {
13576
13986
  const candidates = [
13577
- (0, import_node_path37.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13578
- (0, import_node_path37.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13987
+ (0, import_node_path38.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13988
+ (0, import_node_path38.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13579
13989
  ];
13580
13990
  for (const path2 of candidates) {
13581
- if (!(0, import_node_fs35.existsSync)(path2)) continue;
13582
- const text7 = (0, import_node_fs35.readFileSync)(path2, "utf8");
13991
+ if (!(0, import_node_fs36.existsSync)(path2)) continue;
13992
+ const text7 = (0, import_node_fs36.readFileSync)(path2, "utf8");
13583
13993
  if (/network_access\s*=\s*true/.test(text7)) return true;
13584
13994
  }
13585
13995
  return false;
@@ -13611,21 +14021,21 @@ function asRecord2(value) {
13611
14021
  return void 0;
13612
14022
  }
13613
14023
  function codexLooksAuthenticated() {
13614
- const authPath = (0, import_node_path37.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13615
- if (!(0, import_node_fs35.existsSync)(authPath)) return false;
14024
+ const authPath = (0, import_node_path38.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
14025
+ if (!(0, import_node_fs36.existsSync)(authPath)) return false;
13616
14026
  try {
13617
- return (0, import_node_fs35.statSync)(authPath).size > 2;
14027
+ return (0, import_node_fs36.statSync)(authPath).size > 2;
13618
14028
  } catch {
13619
14029
  return false;
13620
14030
  }
13621
14031
  }
13622
- var import_node_fs35, import_node_os12, import_node_path37, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
14032
+ var import_node_fs36, import_node_os12, import_node_path38, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13623
14033
  var init_codex = __esm({
13624
14034
  "src/agents/codex.ts"() {
13625
14035
  "use strict";
13626
- import_node_fs35 = require("fs");
14036
+ import_node_fs36 = require("fs");
13627
14037
  import_node_os12 = require("os");
13628
- import_node_path37 = require("path");
14038
+ import_node_path38 = require("path");
13629
14039
  init_run();
13630
14040
  init_app_settings();
13631
14041
  init_global_workspace();
@@ -13651,7 +14061,7 @@ var init_codex = __esm({
13651
14061
  async detect() {
13652
14062
  const codex = resolveAgentExecutable("codex");
13653
14063
  if (codex !== "codex") {
13654
- if (!(0, import_node_fs35.existsSync)(codex)) {
14064
+ if (!(0, import_node_fs36.existsSync)(codex)) {
13655
14065
  return {
13656
14066
  agent: "codex",
13657
14067
  installed: false,
@@ -13928,18 +14338,18 @@ var init_codex = __esm({
13928
14338
  // src/agents/cursor-sdk-resolve.ts
13929
14339
  function thisModuleFile() {
13930
14340
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
13931
- if (cjsDir) return (0, import_node_path38.join)(cjsDir, "cursor-sdk-resolve.js");
14341
+ if (cjsDir) return (0, import_node_path39.join)(cjsDir, "cursor-sdk-resolve.js");
13932
14342
  try {
13933
14343
  return (0, import_node_url2.fileURLToPath)(import_meta2.url);
13934
14344
  } catch {
13935
- return (0, import_node_path38.join)(process.cwd(), "package.json");
14345
+ return (0, import_node_path39.join)(process.cwd(), "package.json");
13936
14346
  }
13937
14347
  }
13938
14348
  function packageRootLooksLikeSdk(dir) {
13939
14349
  try {
13940
- const raw = (0, import_node_fs36.readFileSync)((0, import_node_path38.join)(dir, "package.json"), "utf8");
14350
+ const raw = (0, import_node_fs37.readFileSync)((0, import_node_path39.join)(dir, "package.json"), "utf8");
13941
14351
  const pkg = JSON.parse(raw);
13942
- return pkg.name === "@cursor/sdk" && (0, import_node_fs36.existsSync)(dir);
14352
+ return pkg.name === "@cursor/sdk" && (0, import_node_fs37.existsSync)(dir);
13943
14353
  } catch {
13944
14354
  return false;
13945
14355
  }
@@ -13948,7 +14358,7 @@ function resolvedPackageRoot(fromFile) {
13948
14358
  try {
13949
14359
  const req = (0, import_node_module2.createRequire)(fromFile);
13950
14360
  const pkgJson = req.resolve("@cursor/sdk/package.json");
13951
- const root = (0, import_node_path38.dirname)(pkgJson);
14361
+ const root = (0, import_node_path39.dirname)(pkgJson);
13952
14362
  return packageRootLooksLikeSdk(root) ? root : null;
13953
14363
  } catch {
13954
14364
  return null;
@@ -13962,10 +14372,10 @@ function resolveCursorSdkRoot(opts) {
13962
14372
  }
13963
14373
  const globalNm = npmGlobalNodeModules(env);
13964
14374
  if (globalNm) {
13965
- const globalRoot = (0, import_node_path38.join)(globalNm, "@cursor/sdk");
14375
+ const globalRoot = (0, import_node_path39.join)(globalNm, "@cursor/sdk");
13966
14376
  if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
13967
14377
  }
13968
- const cwdPkg = (0, import_node_path38.join)(process.cwd(), "package.json");
14378
+ const cwdPkg = (0, import_node_path39.join)(process.cwd(), "package.json");
13969
14379
  return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
13970
14380
  }
13971
14381
  function isCursorSdkInstalled(opts) {
@@ -13981,13 +14391,13 @@ function exportTarget(value) {
13981
14391
  }
13982
14392
  function cursorSdkEsmEntry(root) {
13983
14393
  try {
13984
- const pkg = JSON.parse((0, import_node_fs36.readFileSync)((0, import_node_path38.join)(root, "package.json"), "utf8"));
14394
+ const pkg = JSON.parse((0, import_node_fs37.readFileSync)((0, import_node_path39.join)(root, "package.json"), "utf8"));
13985
14395
  const exp = pkg.exports;
13986
14396
  const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
13987
14397
  const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
13988
14398
  if (!rel) return null;
13989
- const entry = (0, import_node_path38.join)(root, rel);
13990
- return (0, import_node_fs36.existsSync)(entry) ? entry : null;
14399
+ const entry = (0, import_node_path39.join)(root, rel);
14400
+ return (0, import_node_fs37.existsSync)(entry) ? entry : null;
13991
14401
  } catch {
13992
14402
  return null;
13993
14403
  }
@@ -14003,7 +14413,7 @@ async function importCursorSdk(opts) {
14003
14413
  try {
14004
14414
  let entry = cursorSdkEsmEntry(root);
14005
14415
  if (!entry) {
14006
- const req = (0, import_node_module2.createRequire)((0, import_node_path38.join)(root, "package.json"));
14416
+ const req = (0, import_node_module2.createRequire)((0, import_node_path39.join)(root, "package.json"));
14007
14417
  entry = req.resolve("@cursor/sdk");
14008
14418
  }
14009
14419
  return unwrapCursorSdkModule(await import((0, import_node_url2.pathToFileURL)(entry).href));
@@ -14015,8 +14425,8 @@ function cursorSdkPlatformRipgrepPackage() {
14015
14425
  return `@cursor/sdk-${process.platform}-${process.arch}`;
14016
14426
  }
14017
14427
  function nodeModulesDirForPackageRoot(packageRoot) {
14018
- const parent = (0, import_node_path38.dirname)(packageRoot);
14019
- return (0, import_node_path38.basename)(parent).startsWith("@") ? (0, import_node_path38.dirname)(parent) : parent;
14428
+ const parent = (0, import_node_path39.dirname)(packageRoot);
14429
+ return (0, import_node_path39.basename)(parent).startsWith("@") ? (0, import_node_path39.dirname)(parent) : parent;
14020
14430
  }
14021
14431
  function cursorSdkRipgrepCandidate(opts) {
14022
14432
  const root = resolveCursorSdkRoot(opts);
@@ -14024,18 +14434,18 @@ function cursorSdkRipgrepCandidate(opts) {
14024
14434
  const nm = nodeModulesDirForPackageRoot(root);
14025
14435
  const pkg = cursorSdkPlatformRipgrepPackage();
14026
14436
  const bin = process.platform === "win32" ? "rg.exe" : "rg";
14027
- const sibling = (0, import_node_path38.join)(nm, pkg, "bin", bin);
14028
- if ((0, import_node_fs36.existsSync)(sibling)) return sibling;
14029
- const nested = (0, import_node_path38.join)(root, "node_modules", pkg, "bin", bin);
14030
- return (0, import_node_fs36.existsSync)(nested) ? nested : null;
14437
+ const sibling = (0, import_node_path39.join)(nm, pkg, "bin", bin);
14438
+ if ((0, import_node_fs37.existsSync)(sibling)) return sibling;
14439
+ const nested = (0, import_node_path39.join)(root, "node_modules", pkg, "bin", bin);
14440
+ return (0, import_node_fs37.existsSync)(nested) ? nested : null;
14031
14441
  }
14032
- var import_node_fs36, import_node_module2, import_node_path38, import_node_url2, import_meta2, CURSOR_SDK_INSTALL_HINT;
14442
+ var import_node_fs37, import_node_module2, import_node_path39, import_node_url2, import_meta2, CURSOR_SDK_INSTALL_HINT;
14033
14443
  var init_cursor_sdk_resolve = __esm({
14034
14444
  "src/agents/cursor-sdk-resolve.ts"() {
14035
14445
  "use strict";
14036
- import_node_fs36 = require("fs");
14446
+ import_node_fs37 = require("fs");
14037
14447
  import_node_module2 = require("module");
14038
- import_node_path38 = require("path");
14448
+ import_node_path39 = require("path");
14039
14449
  import_node_url2 = require("url");
14040
14450
  init_path();
14041
14451
  import_meta2 = {};
@@ -14269,21 +14679,21 @@ function platformRipgrepPackage() {
14269
14679
  }
14270
14680
  function usableRipgrepPath(candidate) {
14271
14681
  const raw = candidate?.trim();
14272
- if (!raw || !(0, import_node_path39.isAbsolute)(raw)) return null;
14682
+ if (!raw || !(0, import_node_path40.isAbsolute)(raw)) return null;
14273
14683
  const readable = nodeReadableScriptPath(raw);
14274
- if (!(0, import_node_fs37.existsSync)(readable) || isAsarPath(readable)) return null;
14684
+ if (!(0, import_node_fs38.existsSync)(readable) || isAsarPath(readable)) return null;
14275
14685
  return readable;
14276
14686
  }
14277
14687
  function walkForBundledRipgrep(startFile) {
14278
14688
  if (!startFile) return null;
14279
14689
  const pkg = platformRipgrepPackage();
14280
14690
  const name = rgBinaryName();
14281
- let dir = (0, import_node_path39.dirname)((0, import_node_path39.resolve)(startFile));
14282
- const root = (0, import_node_path39.parse)(dir).root;
14691
+ let dir = (0, import_node_path40.dirname)((0, import_node_path40.resolve)(startFile));
14692
+ const root = (0, import_node_path40.parse)(dir).root;
14283
14693
  while (dir !== root) {
14284
- const hit = usableRipgrepPath((0, import_node_path39.join)(dir, "node_modules", pkg, "bin", name));
14694
+ const hit = usableRipgrepPath((0, import_node_path40.join)(dir, "node_modules", pkg, "bin", name));
14285
14695
  if (hit) return hit;
14286
- const next = (0, import_node_path39.dirname)(dir);
14696
+ const next = (0, import_node_path40.dirname)(dir);
14287
14697
  if (next === dir) break;
14288
14698
  dir = next;
14289
14699
  }
@@ -14293,7 +14703,7 @@ function requireResolveBundledRipgrep(fromFile) {
14293
14703
  try {
14294
14704
  const req = (0, import_node_module3.createRequire)(fromFile);
14295
14705
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
14296
- return usableRipgrepPath((0, import_node_path39.join)((0, import_node_path39.dirname)(pkgJson), "bin", rgBinaryName()));
14706
+ return usableRipgrepPath((0, import_node_path40.join)((0, import_node_path40.dirname)(pkgJson), "bin", rgBinaryName()));
14297
14707
  } catch {
14298
14708
  return null;
14299
14709
  }
@@ -14315,13 +14725,13 @@ function cursorRipgrepEnv(opts) {
14315
14725
  const path2 = resolveCursorRipgrepPath(opts);
14316
14726
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
14317
14727
  }
14318
- var import_node_fs37, import_node_module3, import_node_path39, RIPGREP_ENV;
14728
+ var import_node_fs38, import_node_module3, import_node_path40, RIPGREP_ENV;
14319
14729
  var init_cursor_ripgrep = __esm({
14320
14730
  "src/agents/cursor-ripgrep.ts"() {
14321
14731
  "use strict";
14322
- import_node_fs37 = require("fs");
14732
+ import_node_fs38 = require("fs");
14323
14733
  import_node_module3 = require("module");
14324
- import_node_path39 = require("path");
14734
+ import_node_path40 = require("path");
14325
14735
  init_cursor_sdk_resolve();
14326
14736
  init_node_launch();
14327
14737
  init_packaged_runtime();
@@ -14373,11 +14783,11 @@ function entryDir() {
14373
14783
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
14374
14784
  if (cjsDir) return cjsDir;
14375
14785
  try {
14376
- return (0, import_node_path40.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
14786
+ return (0, import_node_path41.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
14377
14787
  } catch {
14378
14788
  try {
14379
14789
  const req = (0, import_node_module4.createRequire)(process.cwd() + "/");
14380
- return (0, import_node_path40.dirname)(req.resolve("@sideboard-ai/core"));
14790
+ return (0, import_node_path41.dirname)(req.resolve("@sideboard-ai/core"));
14381
14791
  } catch {
14382
14792
  return process.cwd();
14383
14793
  }
@@ -14388,27 +14798,27 @@ function cursorRunnerPath() {
14388
14798
  if (packaged) return packaged;
14389
14799
  const root = entryDir();
14390
14800
  const candidates = [
14391
- (0, import_node_path40.join)(root, "agents", "cursor-runner.js"),
14392
- (0, import_node_path40.join)(root, "agents", "cursor-runner.cjs"),
14801
+ (0, import_node_path41.join)(root, "agents", "cursor-runner.js"),
14802
+ (0, import_node_path41.join)(root, "agents", "cursor-runner.cjs"),
14393
14803
  // If somehow resolved from package root instead of dist/
14394
- (0, import_node_path40.join)(root, "dist", "agents", "cursor-runner.js"),
14395
- (0, import_node_path40.join)(root, "dist", "agents", "cursor-runner.cjs"),
14804
+ (0, import_node_path41.join)(root, "dist", "agents", "cursor-runner.js"),
14805
+ (0, import_node_path41.join)(root, "dist", "agents", "cursor-runner.cjs"),
14396
14806
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
14397
- (0, import_node_path40.join)(root, "cursor-runner.ts"),
14398
- (0, import_node_path40.join)(root, "src", "agents", "cursor-runner.ts")
14807
+ (0, import_node_path41.join)(root, "cursor-runner.ts"),
14808
+ (0, import_node_path41.join)(root, "src", "agents", "cursor-runner.ts")
14399
14809
  ];
14400
14810
  for (const candidate of candidates) {
14401
- if ((0, import_node_fs38.existsSync)(candidate)) return candidate;
14811
+ if ((0, import_node_fs39.existsSync)(candidate)) return candidate;
14402
14812
  }
14403
14813
  return candidates[0];
14404
14814
  }
14405
- var import_node_fs38, import_node_module4, import_node_path40, import_node_url3, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14815
+ var import_node_fs39, import_node_module4, import_node_path41, import_node_url3, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14406
14816
  var init_cursor = __esm({
14407
14817
  "src/agents/cursor.ts"() {
14408
14818
  "use strict";
14409
- import_node_fs38 = require("fs");
14819
+ import_node_fs39 = require("fs");
14410
14820
  import_node_module4 = require("module");
14411
- import_node_path40 = require("path");
14821
+ import_node_path41 = require("path");
14412
14822
  import_node_url3 = require("url");
14413
14823
  init_run();
14414
14824
  init_app_settings();
@@ -14570,7 +14980,7 @@ async function listOpencodeModels() {
14570
14980
  if (opencode === "opencode") {
14571
14981
  const which = await run("which", ["opencode"], { reject: false });
14572
14982
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
14573
- } else if (!(0, import_node_fs39.existsSync)(opencode)) {
14983
+ } else if (!(0, import_node_fs40.existsSync)(opencode)) {
14574
14984
  return FALLBACK_OPENCODE_MODELS;
14575
14985
  }
14576
14986
  const listed = await run(opencode, ["models"], { reject: false });
@@ -14600,11 +15010,11 @@ function usageFromOpencode(tokens) {
14600
15010
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
14601
15011
  };
14602
15012
  }
14603
- var import_node_fs39, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
15013
+ var import_node_fs40, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14604
15014
  var init_opencode = __esm({
14605
15015
  "src/agents/opencode.ts"() {
14606
15016
  "use strict";
14607
- import_node_fs39 = require("fs");
15017
+ import_node_fs40 = require("fs");
14608
15018
  init_run();
14609
15019
  init_app_settings();
14610
15020
  init_global_workspace();
@@ -14632,7 +15042,7 @@ var init_opencode = __esm({
14632
15042
  async detect() {
14633
15043
  const opencode = resolveAgentExecutable("opencode");
14634
15044
  if (opencode !== "opencode") {
14635
- if (!(0, import_node_fs39.existsSync)(opencode)) {
15045
+ if (!(0, import_node_fs40.existsSync)(opencode)) {
14636
15046
  return {
14637
15047
  agent: "opencode",
14638
15048
  installed: false,
@@ -15351,14 +15761,14 @@ function accessTokenFromCredentialsJson(raw) {
15351
15761
  }
15352
15762
  }
15353
15763
  function claudeCredentialsPath() {
15354
- const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path41.join)((0, import_node_os13.homedir)(), ".claude");
15355
- return (0, import_node_path41.join)(root, ".credentials.json");
15764
+ const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path42.join)((0, import_node_os13.homedir)(), ".claude");
15765
+ return (0, import_node_path42.join)(root, ".credentials.json");
15356
15766
  }
15357
15767
  async function readFileAccessToken() {
15358
15768
  const path2 = claudeCredentialsPath();
15359
- if (!(0, import_node_fs40.existsSync)(path2)) return null;
15769
+ if (!(0, import_node_fs41.existsSync)(path2)) return null;
15360
15770
  try {
15361
- return accessTokenFromCredentialsJson((0, import_node_fs40.readFileSync)(path2, "utf8"));
15771
+ return accessTokenFromCredentialsJson((0, import_node_fs41.readFileSync)(path2, "utf8"));
15362
15772
  } catch {
15363
15773
  return null;
15364
15774
  }
@@ -15462,13 +15872,13 @@ async function getClaudePlanUsage(opts = {}) {
15462
15872
  })();
15463
15873
  return inflight;
15464
15874
  }
15465
- var import_node_fs40, import_node_os13, import_node_path41, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
15875
+ var import_node_fs41, import_node_os13, import_node_path42, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
15466
15876
  var init_claude_usage_client = __esm({
15467
15877
  "src/agents/claude-usage-client.ts"() {
15468
15878
  "use strict";
15469
- import_node_fs40 = require("fs");
15879
+ import_node_fs41 = require("fs");
15470
15880
  import_node_os13 = require("os");
15471
- import_node_path41 = require("path");
15881
+ import_node_path42 = require("path");
15472
15882
  init_run();
15473
15883
  init_fetch();
15474
15884
  init_app_settings();
@@ -15597,13 +16007,14 @@ async function installNpmGlobalPackage(opts) {
15597
16007
  exitCode: 0,
15598
16008
  stdout: result.stdout,
15599
16009
  stderr: result.stderr,
15600
- message: binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
16010
+ // Library-only packages (`@cursor/sdk`) have no CLI to look for.
16011
+ message: !opts.cliBin ? `Installed ${opts.npmPackage}` : binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
15601
16012
  };
15602
16013
  }
15603
16014
  async function resolveExistingCli(agent) {
15604
16015
  if (agent === "cursor") return null;
15605
16016
  const exe = resolveAgentExecutable(agent);
15606
- if ((exe.includes("/") || exe.includes("\\")) && (0, import_node_fs41.existsSync)(exe)) return exe;
16017
+ if ((exe.includes("/") || exe.includes("\\")) && (0, import_node_fs42.existsSync)(exe)) return exe;
15607
16018
  enrichPathWithNpmGlobalBin();
15608
16019
  return whichOnPath(CLI_BIN[agent]);
15609
16020
  }
@@ -15676,11 +16087,11 @@ async function loginAgent(agent) {
15676
16087
  message: `Opened Terminal to run: ${prepared}`
15677
16088
  };
15678
16089
  }
15679
- var import_node_fs41, SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
16090
+ var import_node_fs42, SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
15680
16091
  var init_install = __esm({
15681
16092
  "src/agents/install.ts"() {
15682
16093
  "use strict";
15683
- import_node_fs41 = require("fs");
16094
+ import_node_fs42 = require("fs");
15684
16095
  init_run();
15685
16096
  init_app_settings();
15686
16097
  init_path();
@@ -15868,7 +16279,7 @@ function isAgentHostEnvKey(key) {
15868
16279
  }
15869
16280
  function stripHostToolingPath(pathValue) {
15870
16281
  if (!pathValue?.trim()) return "";
15871
- return pathValue.split(import_node_path42.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path42.delimiter);
16282
+ return pathValue.split(import_node_path43.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path43.delimiter);
15872
16283
  }
15873
16284
  function sanitizeAgentHostEnv(env, cwd) {
15874
16285
  for (const key of Object.keys(env)) {
@@ -15882,11 +16293,11 @@ function sanitizeAgentHostEnv(env, cwd) {
15882
16293
  }
15883
16294
  return env;
15884
16295
  }
15885
- var import_node_path42, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
16296
+ var import_node_path43, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15886
16297
  var init_agent_host_env = __esm({
15887
16298
  "src/hook/agent-host-env.ts"() {
15888
16299
  "use strict";
15889
- import_node_path42 = require("path");
16300
+ import_node_path43 = require("path");
15890
16301
  DROP_EXACT = /* @__PURE__ */ new Set([
15891
16302
  "NODE_PATH",
15892
16303
  "NODE_ENV_ELECTRON_VITE",
@@ -15925,15 +16336,15 @@ var init_agent_host_env = __esm({
15925
16336
 
15926
16337
  // src/hook/worktree-pkg-cache.ts
15927
16338
  function worktreePkgCacheRoot(worktreePath) {
15928
- return (0, import_node_path43.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
16339
+ return (0, import_node_path44.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15929
16340
  }
15930
16341
  function worktreePkgCacheEnv(worktreePath) {
15931
16342
  const root = worktreePkgCacheRoot(worktreePath);
15932
- const store = (0, import_node_path43.join)(root, "pnpm-store");
15933
- const pnpmCache = (0, import_node_path43.join)(root, "pnpm");
15934
- const npmCache = (0, import_node_path43.join)(root, "npm");
15935
- const nodeGyp = (0, import_node_path43.join)(root, "node-gyp");
15936
- const electron = (0, import_node_path43.join)(root, "electron");
16343
+ const store = (0, import_node_path44.join)(root, "pnpm-store");
16344
+ const pnpmCache = (0, import_node_path44.join)(root, "pnpm");
16345
+ const npmCache = (0, import_node_path44.join)(root, "npm");
16346
+ const nodeGyp = (0, import_node_path44.join)(root, "node-gyp");
16347
+ const electron = (0, import_node_path44.join)(root, "electron");
15937
16348
  return {
15938
16349
  npm_config_store_dir: store,
15939
16350
  PNPM_STORE_DIR: store,
@@ -15955,8 +16366,8 @@ function fillGroup(env, keys, values) {
15955
16366
  }
15956
16367
  }
15957
16368
  function ensureWorktreePkgCacheDirs(worktreePath) {
15958
- if (!(0, import_node_fs42.existsSync)(worktreePath)) return;
15959
- (0, import_node_fs42.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
16369
+ if (!(0, import_node_fs43.existsSync)(worktreePath)) return;
16370
+ (0, import_node_fs43.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15960
16371
  }
15961
16372
  function applyWorktreePkgCacheEnv(env, worktreePath) {
15962
16373
  const cwd = worktreePath.trim();
@@ -15969,12 +16380,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15969
16380
  fillGroup(env, ["electron_config_cache"], next);
15970
16381
  ensureWorktreePkgCacheDirs(cwd);
15971
16382
  }
15972
- var import_node_fs42, import_node_path43, WORKTREE_PKG_CACHE_REL;
16383
+ var import_node_fs43, import_node_path44, WORKTREE_PKG_CACHE_REL;
15973
16384
  var init_worktree_pkg_cache = __esm({
15974
16385
  "src/hook/worktree-pkg-cache.ts"() {
15975
16386
  "use strict";
15976
- import_node_fs42 = require("fs");
15977
- import_node_path43 = require("path");
16387
+ import_node_fs43 = require("fs");
16388
+ import_node_path44 = require("path");
15978
16389
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15979
16390
  }
15980
16391
  });
@@ -17215,21 +17626,21 @@ function shouldRefreshReviewRequestTemplate(content) {
17215
17626
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
17216
17627
  }
17217
17628
  function readTextIfPresent(abs) {
17218
- if (!(0, import_node_fs43.existsSync)(abs)) return null;
17629
+ if (!(0, import_node_fs44.existsSync)(abs)) return null;
17219
17630
  try {
17220
- const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
17631
+ const content = (0, import_node_fs44.readFileSync)(abs, "utf8");
17221
17632
  return content.trim() ? content : null;
17222
17633
  } catch {
17223
17634
  return null;
17224
17635
  }
17225
17636
  }
17226
17637
  function readLocalGuidelines(worktreePath) {
17227
- const localAbs = (0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH);
17638
+ const localAbs = (0, import_node_path45.join)(worktreePath, REVIEW_REQUEST_PATH);
17228
17639
  const localContent = readTextIfPresent(localAbs);
17229
17640
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
17230
17641
  return { path: REVIEW_REQUEST_PATH, content: localContent };
17231
17642
  }
17232
- const legacyAbs = (0, import_node_path44.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17643
+ const legacyAbs = (0, import_node_path45.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17233
17644
  const legacyContent = readTextIfPresent(legacyAbs);
17234
17645
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
17235
17646
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -17253,27 +17664,27 @@ function contextGuidelines(content, source) {
17253
17664
  };
17254
17665
  }
17255
17666
  function writeContextGuidelines(worktreePath, content) {
17256
- const abs = (0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH);
17257
- (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
17667
+ const abs = (0, import_node_path45.join)(worktreePath, CONTEXT_REVIEW_PATH);
17668
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
17258
17669
  const body = content.endsWith("\n") ? content : `${content}
17259
17670
  `;
17260
- (0, import_node_fs43.writeFileSync)(abs, body, "utf8");
17671
+ (0, import_node_fs44.writeFileSync)(abs, body, "utf8");
17261
17672
  return body;
17262
17673
  }
17263
17674
  function readSideboardReview(worktreePath, repoPath) {
17264
- const fromWorktree = readTextIfPresent((0, import_node_path44.join)(worktreePath, REPO_REVIEW_PATH));
17675
+ const fromWorktree = readTextIfPresent((0, import_node_path45.join)(worktreePath, REPO_REVIEW_PATH));
17265
17676
  if (fromWorktree) return fromWorktree;
17266
17677
  const repo = repoPath?.replace(/\/+$/, "");
17267
17678
  const wt = worktreePath.replace(/\/+$/, "");
17268
17679
  if (!repo || repo === wt) return null;
17269
- return readTextIfPresent((0, import_node_path44.join)(repo, REPO_REVIEW_PATH));
17680
+ return readTextIfPresent((0, import_node_path45.join)(repo, REPO_REVIEW_PATH));
17270
17681
  }
17271
17682
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
17272
- const skillContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_SKILL_PATH));
17683
+ const skillContent = readTextIfPresent((0, import_node_path45.join)(worktreePath, REVIEW_SKILL_PATH));
17273
17684
  if (skillContent) {
17274
17685
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
17275
17686
  }
17276
- const contextContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH));
17687
+ const contextContent = readTextIfPresent((0, import_node_path45.join)(worktreePath, CONTEXT_REVIEW_PATH));
17277
17688
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
17278
17689
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
17279
17690
  }
@@ -17311,7 +17722,7 @@ function buildReviewRequestAttachment(content, opts) {
17311
17722
  };
17312
17723
  }
17313
17724
  function readExistingReviewRequestFile(worktreePath) {
17314
- return readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
17725
+ return readTextIfPresent((0, import_node_path45.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path45.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path45.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path45.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path45.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
17315
17726
  }
17316
17727
  async function requestReview(threadRef, send2) {
17317
17728
  const from = findThreadByRef(threadRef);
@@ -17338,13 +17749,13 @@ async function requestReview(threadRef, send2) {
17338
17749
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
17339
17750
  return { tab: started, from };
17340
17751
  }
17341
- var import_node_crypto9, import_node_fs43, import_node_path44, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
17752
+ var import_node_crypto9, import_node_fs44, import_node_path45, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
17342
17753
  var init_request_review = __esm({
17343
17754
  "src/review/request-review.ts"() {
17344
17755
  "use strict";
17345
17756
  import_node_crypto9 = require("crypto");
17346
- import_node_fs43 = require("fs");
17347
- import_node_path44 = require("path");
17757
+ import_node_fs44 = require("fs");
17758
+ import_node_path45 = require("path");
17348
17759
  init_global_workspace();
17349
17760
  init_chat_tabs();
17350
17761
  init_thread_store();
@@ -17370,9 +17781,9 @@ function matchSimpleGlob(pattern, name) {
17370
17781
  return new RegExp(`^${escaped}$`).test(name);
17371
17782
  }
17372
17783
  function readWorktreeInclude(repoPath) {
17373
- const path2 = (0, import_node_path45.join)(repoPath, ".worktreeinclude");
17374
- if (!(0, import_node_fs44.existsSync)(path2)) return [];
17375
- return (0, import_node_fs44.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17784
+ const path2 = (0, import_node_path46.join)(repoPath, ".worktreeinclude");
17785
+ if (!(0, import_node_fs45.existsSync)(path2)) return [];
17786
+ return (0, import_node_fs45.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17376
17787
  }
17377
17788
  function resolveFilesToCopy(repoPath) {
17378
17789
  const fromInclude = readWorktreeInclude(repoPath);
@@ -17382,10 +17793,10 @@ function resolveFilesToCopy(repoPath) {
17382
17793
  if (settings?.fileIncludeGlobs?.length) {
17383
17794
  const matched = [];
17384
17795
  try {
17385
- for (const entry of (0, import_node_fs44.readdirSync)(repoPath, { withFileTypes: true })) {
17796
+ for (const entry of (0, import_node_fs45.readdirSync)(repoPath, { withFileTypes: true })) {
17386
17797
  if (!entry.isFile()) continue;
17387
17798
  for (const glob of settings.fileIncludeGlobs) {
17388
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path45.basename)(glob), entry.name)) {
17799
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path46.basename)(glob), entry.name)) {
17389
17800
  matched.push(entry.name);
17390
17801
  break;
17391
17802
  }
@@ -17397,7 +17808,7 @@ function resolveFilesToCopy(repoPath) {
17397
17808
  }
17398
17809
  const defaults = [];
17399
17810
  try {
17400
- for (const entry of (0, import_node_fs44.readdirSync)(repoPath, { withFileTypes: true })) {
17811
+ for (const entry of (0, import_node_fs45.readdirSync)(repoPath, { withFileTypes: true })) {
17401
17812
  if (entry.isFile() && entry.name.startsWith(".env")) {
17402
17813
  defaults.push(entry.name);
17403
17814
  }
@@ -17411,11 +17822,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
17411
17822
  const patterns = resolveFilesToCopy(repoPath);
17412
17823
  const copied = [];
17413
17824
  for (const rel of patterns) {
17414
- const src = (0, import_node_path45.join)(repoPath, rel);
17415
- if (!(0, import_node_fs44.existsSync)(src)) continue;
17416
- const dest = (0, import_node_path45.join)(worktreePath, rel);
17417
- (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
17418
- (0, import_node_fs44.copyFileSync)(src, dest);
17825
+ const src = (0, import_node_path46.join)(repoPath, rel);
17826
+ if (!(0, import_node_fs45.existsSync)(src)) continue;
17827
+ const dest = (0, import_node_path46.join)(worktreePath, rel);
17828
+ (0, import_node_fs45.mkdirSync)((0, import_node_path46.dirname)(dest), { recursive: true });
17829
+ (0, import_node_fs45.copyFileSync)(src, dest);
17419
17830
  copied.push(rel);
17420
17831
  }
17421
17832
  return copied;
@@ -17450,7 +17861,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
17450
17861
  const env = stripNestedElectronEnv({
17451
17862
  ...baseEnv ?? process.env
17452
17863
  });
17453
- const name = opts.workspaceName ?? (0, import_node_path45.basename)(opts.worktreePath);
17864
+ const name = opts.workspaceName ?? (0, import_node_path46.basename)(opts.worktreePath);
17454
17865
  const ports = opts.ports ?? [];
17455
17866
  const primary = ports[0];
17456
17867
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -17785,14 +18196,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
17785
18196
  throw err;
17786
18197
  }
17787
18198
  }
17788
- var import_node_fs44, import_node_child_process5, import_node_net, import_node_path45, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
18199
+ var import_node_fs45, import_node_child_process5, import_node_net, import_node_path46, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17789
18200
  var init_conductor = __esm({
17790
18201
  "src/hook/conductor.ts"() {
17791
18202
  "use strict";
17792
- import_node_fs44 = require("fs");
18203
+ import_node_fs45 = require("fs");
17793
18204
  import_node_child_process5 = require("child_process");
17794
18205
  import_node_net = require("net");
17795
- import_node_path45 = require("path");
18206
+ import_node_path46 = require("path");
17796
18207
  import_execa4 = require("execa");
17797
18208
  import_node_readline3 = require("readline");
17798
18209
  init_settings();
@@ -17820,9 +18231,9 @@ async function findOrphanWorktrees(repoPaths) {
17820
18231
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17821
18232
  );
17822
18233
  const homeRoot = sideboardWorkspacesDir();
17823
- if ((0, import_node_fs45.existsSync)(homeRoot)) {
18234
+ if ((0, import_node_fs46.existsSync)(homeRoot)) {
17824
18235
  try {
17825
- for (const entry of (0, import_node_fs45.readdirSync)(homeRoot, { withFileTypes: true })) {
18236
+ for (const entry of (0, import_node_fs46.readdirSync)(homeRoot, { withFileTypes: true })) {
17826
18237
  if (!entry.isDirectory()) continue;
17827
18238
  void entry;
17828
18239
  }
@@ -17832,7 +18243,7 @@ async function findOrphanWorktrees(repoPaths) {
17832
18243
  const orphans = [];
17833
18244
  const seen = /* @__PURE__ */ new Set();
17834
18245
  for (const repoPath of repos) {
17835
- if (!repoPath || !(0, import_node_fs45.existsSync)(repoPath)) continue;
18246
+ if (!repoPath || !(0, import_node_fs46.existsSync)(repoPath)) continue;
17836
18247
  try {
17837
18248
  const wts = await listWorktrees(repoPath);
17838
18249
  for (const wt of wts) {
@@ -17843,7 +18254,7 @@ async function findOrphanWorktrees(repoPaths) {
17843
18254
  seen.add(path2);
17844
18255
  let mtimeMs = 0;
17845
18256
  try {
17846
- mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
18257
+ mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
17847
18258
  } catch {
17848
18259
  mtimeMs = 0;
17849
18260
  }
@@ -17853,16 +18264,16 @@ async function findOrphanWorktrees(repoPaths) {
17853
18264
  }
17854
18265
  try {
17855
18266
  const root = worktreesRoot(repoPath);
17856
- if ((0, import_node_fs45.existsSync)(root)) {
17857
- for (const entry of (0, import_node_fs45.readdirSync)(root, { withFileTypes: true })) {
18267
+ if ((0, import_node_fs46.existsSync)(root)) {
18268
+ for (const entry of (0, import_node_fs46.readdirSync)(root, { withFileTypes: true })) {
17858
18269
  if (!entry.isDirectory()) continue;
17859
- const path2 = (0, import_node_path46.join)(root, entry.name).replace(/\/$/, "");
18270
+ const path2 = (0, import_node_path47.join)(root, entry.name).replace(/\/$/, "");
17860
18271
  if (known.has(path2) || seen.has(path2)) continue;
17861
- if (!(0, import_node_fs45.existsSync)((0, import_node_path46.join)(path2, ".git"))) continue;
18272
+ if (!(0, import_node_fs46.existsSync)((0, import_node_path47.join)(path2, ".git"))) continue;
17862
18273
  seen.add(path2);
17863
18274
  let mtimeMs = 0;
17864
18275
  try {
17865
- mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
18276
+ mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
17866
18277
  } catch {
17867
18278
  mtimeMs = Date.now();
17868
18279
  }
@@ -17923,12 +18334,12 @@ function worktreeCleanupSettings() {
17923
18334
  autoCleanupOrphans: a.autoCleanupOrphans
17924
18335
  };
17925
18336
  }
17926
- var import_node_fs45, import_node_path46;
18337
+ var import_node_fs46, import_node_path47;
17927
18338
  var init_orphan_cleanup = __esm({
17928
18339
  "src/git/orphan-cleanup.ts"() {
17929
18340
  "use strict";
17930
- import_node_fs45 = require("fs");
17931
- import_node_path46 = require("path");
18341
+ import_node_fs46 = require("fs");
18342
+ import_node_path47 = require("path");
17932
18343
  init_worktree();
17933
18344
  init_thread_store();
17934
18345
  init_paths();
@@ -18103,12 +18514,12 @@ async function cloneRepoIntoSideboard(opts) {
18103
18514
  if (!url) throw new Error("Clone URL is required");
18104
18515
  let name = opts.name?.trim();
18105
18516
  if (!name) {
18106
- const leaf = (0, import_node_path47.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18517
+ const leaf = (0, import_node_path48.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18107
18518
  name = leaf || "repo";
18108
18519
  }
18109
18520
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
18110
- const dest = (0, import_node_path47.join)(sideboardReposDir(), name);
18111
- if ((0, import_node_fs46.existsSync)(dest)) {
18521
+ const dest = (0, import_node_path48.join)(sideboardReposDir(), name);
18522
+ if ((0, import_node_fs47.existsSync)(dest)) {
18112
18523
  const repoPath2 = await resolveRepoRoot(dest);
18113
18524
  const workspace2 = await ensureWorkspace(repoPath2);
18114
18525
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -18123,12 +18534,12 @@ async function cloneRepoIntoSideboard(opts) {
18123
18534
  const workspace = await ensureWorkspace(repoPath);
18124
18535
  return { repoPath, workspace };
18125
18536
  }
18126
- var import_node_fs46, import_node_path47, import_execa6;
18537
+ var import_node_fs47, import_node_path48, import_execa6;
18127
18538
  var init_clone_repo = __esm({
18128
18539
  "src/git/clone-repo.ts"() {
18129
18540
  "use strict";
18130
- import_node_fs46 = require("fs");
18131
- import_node_path47 = require("path");
18541
+ import_node_fs47 = require("fs");
18542
+ import_node_path48 = require("path");
18132
18543
  import_execa6 = require("execa");
18133
18544
  init_paths();
18134
18545
  init_workspaces();
@@ -18249,24 +18660,24 @@ function jobTreeAlive(pid) {
18249
18660
  return jobAlive(pid) || processGroupAlive(pid);
18250
18661
  }
18251
18662
  function readIntFile(file) {
18252
- if (!(0, import_node_fs47.existsSync)(file)) return null;
18253
- const n = Number.parseInt((0, import_node_fs47.readFileSync)(file, "utf8").trim(), 10);
18663
+ if (!(0, import_node_fs48.existsSync)(file)) return null;
18664
+ const n = Number.parseInt((0, import_node_fs48.readFileSync)(file, "utf8").trim(), 10);
18254
18665
  return Number.isInteger(n) ? n : null;
18255
18666
  }
18256
18667
  function jobDir(root, id, legacy = false) {
18257
- return (0, import_node_path48.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18668
+ return (0, import_node_path49.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18258
18669
  }
18259
18670
  function resolveJobDir(root, id) {
18260
18671
  const modern = jobDir(root, id, false);
18261
- if ((0, import_node_fs47.existsSync)(modern)) return modern;
18672
+ if ((0, import_node_fs48.existsSync)(modern)) return modern;
18262
18673
  const legacy = jobDir(root, id, true);
18263
- if ((0, import_node_fs47.existsSync)(legacy)) return legacy;
18674
+ if ((0, import_node_fs48.existsSync)(legacy)) return legacy;
18264
18675
  return modern;
18265
18676
  }
18266
18677
  function listJobIdsIn(root, rel) {
18267
- const dir = (0, import_node_path48.join)(root, rel);
18268
- if (!(0, import_node_fs47.existsSync)(dir)) return [];
18269
- return (0, import_node_fs47.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
18678
+ const dir = (0, import_node_path49.join)(root, rel);
18679
+ if (!(0, import_node_fs48.existsSync)(dir)) return [];
18680
+ return (0, import_node_fs48.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
18270
18681
  }
18271
18682
  function listRunningDetachedJobs(worktreePath) {
18272
18683
  const root = worktreePath.trim();
@@ -18278,7 +18689,7 @@ function listRunningDetachedJobs(worktreePath) {
18278
18689
  const running = [];
18279
18690
  for (const id of ids) {
18280
18691
  const dir = resolveJobDir(root, id);
18281
- const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18692
+ const pid = readIntFile((0, import_node_path49.join)(dir, "pid"));
18282
18693
  if (jobTreeAlive(pid)) running.push(id);
18283
18694
  }
18284
18695
  return running.sort();
@@ -18361,8 +18772,8 @@ function planJobContinue(opts) {
18361
18772
  return { action: "none" };
18362
18773
  }
18363
18774
  function tailProgress(logFile, maxLines = 12) {
18364
- if (!(0, import_node_fs47.existsSync)(logFile)) return "(no log yet)";
18365
- const lines = (0, import_node_fs47.readFileSync)(logFile, "utf8").split("\n");
18775
+ if (!(0, import_node_fs48.existsSync)(logFile)) return "(no log yet)";
18776
+ const lines = (0, import_node_fs48.readFileSync)(logFile, "utf8").split("\n");
18366
18777
  return lines.slice(-maxLines).join("\n");
18367
18778
  }
18368
18779
  function lastProgressLine(progress) {
@@ -18370,8 +18781,8 @@ function lastProgressLine(progress) {
18370
18781
  return last ? last.slice(0, 72) : void 0;
18371
18782
  }
18372
18783
  function readLogLines(file) {
18373
- if (!(0, import_node_fs47.existsSync)(file)) return [];
18374
- const lines = (0, import_node_fs47.readFileSync)(file, "utf8").split("\n");
18784
+ if (!(0, import_node_fs48.existsSync)(file)) return [];
18785
+ const lines = (0, import_node_fs48.readFileSync)(file, "utf8").split("\n");
18375
18786
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
18376
18787
  return lines;
18377
18788
  }
@@ -18382,15 +18793,15 @@ function takeDelta(logFile, cursorFile) {
18382
18793
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
18383
18794
  }
18384
18795
  function snapshotJob(dir) {
18385
- const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18796
+ const pid = readIntFile((0, import_node_path49.join)(dir, "pid"));
18386
18797
  const running = jobTreeAlive(pid);
18387
18798
  return {
18388
18799
  pid,
18389
18800
  running,
18390
- exitCode: readIntFile((0, import_node_path48.join)(dir, "exit")),
18391
- log: (0, import_node_path48.join)(dir, "log"),
18392
- cursor: (0, import_node_path48.join)(dir, "present.cursor"),
18393
- progress: tailProgress((0, import_node_path48.join)(dir, "log"))
18801
+ exitCode: readIntFile((0, import_node_path49.join)(dir, "exit")),
18802
+ log: (0, import_node_path49.join)(dir, "log"),
18803
+ cursor: (0, import_node_path49.join)(dir, "present.cursor"),
18804
+ progress: tailProgress((0, import_node_path49.join)(dir, "log"))
18394
18805
  };
18395
18806
  }
18396
18807
  function toResult(id, snap, extra) {
@@ -18399,8 +18810,8 @@ function toResult(id, snap, extra) {
18399
18810
  const stillRunning = snap.running && !ok;
18400
18811
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
18401
18812
  try {
18402
- (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(snap.cursor), { recursive: true });
18403
- (0, import_node_fs47.writeFileSync)(snap.cursor, `${nextCursor}
18813
+ (0, import_node_fs48.mkdirSync)((0, import_node_path49.dirname)(snap.cursor), { recursive: true });
18814
+ (0, import_node_fs48.writeFileSync)(snap.cursor, `${nextCursor}
18404
18815
  `);
18405
18816
  } catch {
18406
18817
  }
@@ -18429,7 +18840,7 @@ async function waitForDetachedJob(cwd, id, opts) {
18429
18840
  const dir = resolveJobDir(root, jobId);
18430
18841
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
18431
18842
  const sleep2 = opts?.sleep ?? sleepMs;
18432
- if (!(0, import_node_fs47.existsSync)(dir)) {
18843
+ if (!(0, import_node_fs48.existsSync)(dir)) {
18433
18844
  return {
18434
18845
  stillRunning: false,
18435
18846
  ok: false,
@@ -18475,10 +18886,10 @@ function killProcessTree(pid, signal) {
18475
18886
  }
18476
18887
  function appendJobLog(logFile, line) {
18477
18888
  try {
18478
- (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(logFile), { recursive: true });
18889
+ (0, import_node_fs48.mkdirSync)((0, import_node_path49.dirname)(logFile), { recursive: true });
18479
18890
  const body = line.endsWith("\n") ? line : `${line}
18480
18891
  `;
18481
- (0, import_node_fs47.appendFileSync)(logFile, body);
18892
+ (0, import_node_fs48.appendFileSync)(logFile, body);
18482
18893
  } catch {
18483
18894
  }
18484
18895
  }
@@ -18488,7 +18899,7 @@ async function stopDetachedJob(cwd, id, opts) {
18488
18899
  const dir = resolveJobDir(root, jobId);
18489
18900
  const sleep2 = opts?.sleep ?? sleepMs;
18490
18901
  const why = opts?.reason?.trim() ?? "";
18491
- if (!(0, import_node_fs47.existsSync)(dir)) {
18902
+ if (!(0, import_node_fs48.existsSync)(dir)) {
18492
18903
  return {
18493
18904
  stillRunning: false,
18494
18905
  ok: false,
@@ -18524,10 +18935,10 @@ async function stopDetachedJob(cwd, id, opts) {
18524
18935
  killProcessTree(targetPid, "SIGKILL");
18525
18936
  await sleep2(100);
18526
18937
  }
18527
- const exitFile = (0, import_node_path48.join)(dir, "exit");
18528
- if (!(0, import_node_fs47.existsSync)(exitFile)) {
18938
+ const exitFile = (0, import_node_path49.join)(dir, "exit");
18939
+ if (!(0, import_node_fs48.existsSync)(exitFile)) {
18529
18940
  try {
18530
- (0, import_node_fs47.writeFileSync)(exitFile, "1\n");
18941
+ (0, import_node_fs48.writeFileSync)(exitFile, "1\n");
18531
18942
  } catch {
18532
18943
  }
18533
18944
  }
@@ -18547,12 +18958,12 @@ async function stopDetachedJob(cwd, id, opts) {
18547
18958
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
18548
18959
  };
18549
18960
  }
18550
- var import_node_fs47, import_node_path48, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
18961
+ var import_node_fs48, import_node_path49, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
18551
18962
  var init_wait_for_job = __esm({
18552
18963
  "src/mcp/wait-for-job.ts"() {
18553
18964
  "use strict";
18554
- import_node_fs47 = require("fs");
18555
- import_node_path48 = require("path");
18965
+ import_node_fs48 = require("fs");
18966
+ import_node_path49 = require("path");
18556
18967
  init_workspace_scratch();
18557
18968
  init_wait_for_turn();
18558
18969
  MAX_JOB_CONTINUES = 8;
@@ -20097,7 +20508,7 @@ function reuseLiveThread(input, repoPath, match) {
20097
20508
  }
20098
20509
  async function createThread(input, _onSetupLine) {
20099
20510
  const repoPath = await resolveRepoRoot(input.repoPath);
20100
- if (!(0, import_node_fs48.existsSync)(repoPath)) {
20511
+ if (!(0, import_node_fs49.existsSync)(repoPath)) {
20101
20512
  throw new Error(`Repo not found: ${repoPath}`);
20102
20513
  }
20103
20514
  const reused = reuseLiveThread(input, repoPath, {
@@ -20282,11 +20693,11 @@ async function listLinearIssues(agent, repoPath) {
20282
20693
  }
20283
20694
  return adapter.listLinearIssues(repoPath);
20284
20695
  }
20285
- var import_node_fs48;
20696
+ var import_node_fs49;
20286
20697
  var init_create = __esm({
20287
20698
  "src/threads/create.ts"() {
20288
20699
  "use strict";
20289
- import_node_fs48 = require("fs");
20700
+ import_node_fs49 = require("fs");
20290
20701
  init_detect();
20291
20702
  init_worktree();
20292
20703
  init_home_board();
@@ -20438,20 +20849,20 @@ function writeTurnLive(threadId, progress) {
20438
20849
  const path2 = threadLivePath(threadId);
20439
20850
  const tmp = `${path2}.${process.pid}.tmp`;
20440
20851
  try {
20441
- (0, import_node_fs49.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20442
- (0, import_node_fs49.renameSync)(tmp, path2);
20852
+ (0, import_node_fs50.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20853
+ (0, import_node_fs50.renameSync)(tmp, path2);
20443
20854
  } catch {
20444
20855
  try {
20445
- (0, import_node_fs49.unlinkSync)(tmp);
20856
+ (0, import_node_fs50.unlinkSync)(tmp);
20446
20857
  } catch {
20447
20858
  }
20448
20859
  }
20449
20860
  }
20450
20861
  function readTurnLive(threadId) {
20451
20862
  const path2 = threadLivePath(threadId);
20452
- if (!(0, import_node_fs49.existsSync)(path2)) return null;
20863
+ if (!(0, import_node_fs50.existsSync)(path2)) return null;
20453
20864
  try {
20454
- const raw = JSON.parse((0, import_node_fs49.readFileSync)(path2, "utf8"));
20865
+ const raw = JSON.parse((0, import_node_fs50.readFileSync)(path2, "utf8"));
20455
20866
  if (!raw || typeof raw.summary !== "string") return null;
20456
20867
  return raw;
20457
20868
  } catch {
@@ -20463,17 +20874,17 @@ function clearTurnLive(threadId) {
20463
20874
  if (buf?.timer) clearTimeout(buf.timer);
20464
20875
  buffers.delete(threadId);
20465
20876
  const path2 = threadLivePath(threadId);
20466
- if (!(0, import_node_fs49.existsSync)(path2)) return;
20877
+ if (!(0, import_node_fs50.existsSync)(path2)) return;
20467
20878
  try {
20468
- (0, import_node_fs49.unlinkSync)(path2);
20879
+ (0, import_node_fs50.unlinkSync)(path2);
20469
20880
  } catch {
20470
20881
  }
20471
20882
  }
20472
- var import_node_fs49, buffers, FLUSH_MS, MAX_PARTS;
20883
+ var import_node_fs50, buffers, FLUSH_MS, MAX_PARTS;
20473
20884
  var init_turn_live = __esm({
20474
20885
  "src/store/turn-live.ts"() {
20475
20886
  "use strict";
20476
- import_node_fs49 = require("fs");
20887
+ import_node_fs50 = require("fs");
20477
20888
  init_message_parts();
20478
20889
  init_paths();
20479
20890
  buffers = /* @__PURE__ */ new Map();
@@ -20717,7 +21128,7 @@ var init_quota_failover = __esm({
20717
21128
  // src/threads/adopt.ts
20718
21129
  function thisModuleFile2() {
20719
21130
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
20720
- return cjsFile || process.argv[1] || (0, import_node_path49.join)(process.cwd(), "package.json");
21131
+ return cjsFile || process.argv[1] || (0, import_node_path50.join)(process.cwd(), "package.json");
20721
21132
  }
20722
21133
  function openReadonlySqlite(file) {
20723
21134
  const req = (0, import_node_module5.createRequire)(thisModuleFile2());
@@ -20735,21 +21146,21 @@ function mapAgentType(raw) {
20735
21146
  return null;
20736
21147
  }
20737
21148
  function resolveConductorCursorAgentId(workspacePath) {
20738
- if (!workspacePath || !(0, import_node_fs50.existsSync)(CURSOR_SDK_STORE)) return null;
21149
+ if (!workspacePath || !(0, import_node_fs51.existsSync)(CURSOR_SDK_STORE)) return null;
20739
21150
  const normalized = workspacePath.replace(/\/$/, "");
20740
21151
  let best = null;
20741
21152
  let hashes;
20742
21153
  try {
20743
- hashes = (0, import_node_fs50.readdirSync)(CURSOR_SDK_STORE);
21154
+ hashes = (0, import_node_fs51.readdirSync)(CURSOR_SDK_STORE);
20744
21155
  } catch {
20745
21156
  return null;
20746
21157
  }
20747
21158
  for (const hash of hashes) {
20748
- const agentsFile = (0, import_node_path49.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20749
- if (!(0, import_node_fs50.existsSync)(agentsFile)) continue;
21159
+ const agentsFile = (0, import_node_path50.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
21160
+ if (!(0, import_node_fs51.existsSync)(agentsFile)) continue;
20750
21161
  let text7;
20751
21162
  try {
20752
- text7 = (0, import_node_fs50.readFileSync)(agentsFile, "utf8");
21163
+ text7 = (0, import_node_fs51.readFileSync)(agentsFile, "utf8");
20753
21164
  } catch {
20754
21165
  continue;
20755
21166
  }
@@ -20773,7 +21184,7 @@ function resolveConductorCursorAgentId(workspacePath) {
20773
21184
  return best?.agentId ?? null;
20774
21185
  }
20775
21186
  async function adoptThread(input) {
20776
- if (!(0, import_node_fs50.existsSync)(input.worktreePath)) {
21187
+ if (!(0, import_node_fs51.existsSync)(input.worktreePath)) {
20777
21188
  throw new Error(`Worktree not found: ${input.worktreePath}`);
20778
21189
  }
20779
21190
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -20802,18 +21213,18 @@ function conductorDbPath() {
20802
21213
  return CONDUCTOR_DB;
20803
21214
  }
20804
21215
  function listConductorWorkspaces() {
20805
- if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
21216
+ if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
20806
21217
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20807
21218
  }
20808
- const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20809
- const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
21219
+ const tmp = (0, import_node_fs51.mkdtempSync)((0, import_node_path50.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
21220
+ const snapshot = (0, import_node_path50.join)(tmp, "conductor.db");
20810
21221
  try {
20811
- (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
21222
+ (0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
20812
21223
  for (const suffix of ["-wal", "-shm"]) {
20813
21224
  const src = `${CONDUCTOR_DB}${suffix}`;
20814
- if ((0, import_node_fs50.existsSync)(src)) {
21225
+ if ((0, import_node_fs51.existsSync)(src)) {
20815
21226
  try {
20816
- (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
21227
+ (0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
20817
21228
  } catch {
20818
21229
  }
20819
21230
  }
@@ -20889,22 +21300,22 @@ function listConductorWorkspaces() {
20889
21300
  db.close();
20890
21301
  }
20891
21302
  } finally {
20892
- (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
21303
+ (0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
20893
21304
  }
20894
21305
  }
20895
21306
  function importConductorWorkspace(workspaceId) {
20896
- if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
21307
+ if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
20897
21308
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20898
21309
  }
20899
- const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20900
- const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
21310
+ const tmp = (0, import_node_fs51.mkdtempSync)((0, import_node_path50.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
21311
+ const snapshot = (0, import_node_path50.join)(tmp, "conductor.db");
20901
21312
  try {
20902
- (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
21313
+ (0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
20903
21314
  for (const suffix of ["-wal", "-shm"]) {
20904
21315
  const src = `${CONDUCTOR_DB}${suffix}`;
20905
- if ((0, import_node_fs50.existsSync)(src)) {
21316
+ if ((0, import_node_fs51.existsSync)(src)) {
20906
21317
  try {
20907
- (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
21318
+ (0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
20908
21319
  } catch {
20909
21320
  }
20910
21321
  }
@@ -20922,7 +21333,7 @@ function importConductorWorkspace(workspaceId) {
20922
21333
  ).get(workspaceId);
20923
21334
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
20924
21335
  const worktreePath = String(row.workspacePath);
20925
- if (!(0, import_node_fs50.existsSync)(worktreePath)) {
21336
+ if (!(0, import_node_fs51.existsSync)(worktreePath)) {
20926
21337
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
20927
21338
  }
20928
21339
  let sessionId = null;
@@ -20985,31 +21396,31 @@ function importConductorWorkspace(workspaceId) {
20985
21396
  db.close();
20986
21397
  }
20987
21398
  } finally {
20988
- (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
21399
+ (0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
20989
21400
  }
20990
21401
  }
20991
21402
  async function importConductorWorkspaceAsync(workspaceId) {
20992
21403
  return importConductorWorkspace(workspaceId);
20993
21404
  }
20994
- var import_node_child_process6, import_node_fs50, import_node_os14, import_node_path49, import_node_module5, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
21405
+ var import_node_child_process6, import_node_fs51, import_node_os14, import_node_path50, import_node_module5, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
20995
21406
  var init_adopt = __esm({
20996
21407
  "src/threads/adopt.ts"() {
20997
21408
  "use strict";
20998
21409
  import_node_child_process6 = require("child_process");
20999
- import_node_fs50 = require("fs");
21410
+ import_node_fs51 = require("fs");
21000
21411
  import_node_os14 = require("os");
21001
- import_node_path49 = require("path");
21412
+ import_node_path50 = require("path");
21002
21413
  import_node_module5 = require("module");
21003
21414
  init_worktree();
21004
21415
  init_thread_store();
21005
- CONDUCTOR_APP_SUPPORT = (0, import_node_path49.join)(
21416
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path50.join)(
21006
21417
  process.env.HOME ?? "",
21007
21418
  "Library",
21008
21419
  "Application Support",
21009
21420
  "com.conductor.app"
21010
21421
  );
21011
- CONDUCTOR_DB = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
21012
- CURSOR_SDK_STORE = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
21422
+ CONDUCTOR_DB = (0, import_node_path50.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
21423
+ CURSOR_SDK_STORE = (0, import_node_path50.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
21013
21424
  }
21014
21425
  });
21015
21426
 
@@ -21076,7 +21487,7 @@ async function openStackLayer(input, _onSetupLine) {
21076
21487
  let createdWorktree = false;
21077
21488
  const trees = await listWorktrees(repoPath);
21078
21489
  const checkedOut = trees.find((w) => w.branch === branchName);
21079
- if (checkedOut?.path && (0, import_node_fs51.existsSync)(checkedOut.path)) {
21490
+ if (checkedOut?.path && (0, import_node_fs52.existsSync)(checkedOut.path)) {
21080
21491
  if (input.reuseExistingWorktree !== false) {
21081
21492
  worktreePath = checkedOut.path;
21082
21493
  } else {
@@ -21218,7 +21629,7 @@ async function initStackFromThread(input, onSetupLine) {
21218
21629
  async function createPrStack(input, onSetupLine) {
21219
21630
  await requireAgent(input.agent);
21220
21631
  const repoPath = await resolveRepoRoot(input.repoPath);
21221
- if (!(0, import_node_fs51.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21632
+ if (!(0, import_node_fs52.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21222
21633
  if (!input.branches.length) throw new Error("At least one branch name required");
21223
21634
  const status = await detectGhStack(repoPath);
21224
21635
  if (!status.available) throw new Error(status.reason);
@@ -21285,7 +21696,7 @@ async function createPrStack(input, onSetupLine) {
21285
21696
  }
21286
21697
  }
21287
21698
  const claimed = new Set(threads.map((t) => t.worktreePath));
21288
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs51.existsSync)(bootstrap.worktreePath)) {
21699
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs52.existsSync)(bootstrap.worktreePath)) {
21289
21700
  try {
21290
21701
  await removeWorktree(repoPath, bootstrap.worktreePath, {
21291
21702
  deleteBranch: bootstrap.branchName
@@ -21305,11 +21716,11 @@ function stackAgentDefaultsFrom(input) {
21305
21716
  planMode: input.planMode
21306
21717
  };
21307
21718
  }
21308
- var import_node_fs51;
21719
+ var import_node_fs52;
21309
21720
  var init_stack_layers = __esm({
21310
21721
  "src/threads/stack-layers.ts"() {
21311
21722
  "use strict";
21312
- import_node_fs51 = require("fs");
21723
+ import_node_fs52 = require("fs");
21313
21724
  init_detect();
21314
21725
  init_run();
21315
21726
  init_stack();
@@ -21322,7 +21733,7 @@ var init_stack_layers = __esm({
21322
21733
 
21323
21734
  // src/diff/diff.ts
21324
21735
  async function inspectGitWorktree(worktreePath) {
21325
- if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) return "missing_worktree";
21736
+ if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) return "missing_worktree";
21326
21737
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
21327
21738
  reject: false
21328
21739
  });
@@ -21330,7 +21741,7 @@ async function inspectGitWorktree(worktreePath) {
21330
21741
  return "ok";
21331
21742
  }
21332
21743
  async function initializeGitRepository(worktreePath) {
21333
- if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) {
21744
+ if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) {
21334
21745
  throw new Error("Worktree not found");
21335
21746
  }
21336
21747
  const status = await inspectGitWorktree(worktreePath);
@@ -21464,11 +21875,11 @@ new file mode 100644
21464
21875
  };
21465
21876
  }
21466
21877
  async function untrackedPatch(worktreePath, path2, maxHunk) {
21467
- const abs = (0, import_node_path50.join)(worktreePath, path2);
21878
+ const abs = (0, import_node_path51.join)(worktreePath, path2);
21468
21879
  try {
21469
- const st = (0, import_node_fs52.statSync)(abs);
21880
+ const st = (0, import_node_fs53.statSync)(abs);
21470
21881
  if (st.isFile() && st.size > maxHunk) {
21471
- const buf = (0, import_node_fs52.readFileSync)(abs).subarray(0, maxHunk);
21882
+ const buf = (0, import_node_fs53.readFileSync)(abs).subarray(0, maxHunk);
21472
21883
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
21473
21884
  }
21474
21885
  } catch {
@@ -21935,9 +22346,9 @@ async function getDiff(worktreePath, repoPath, opts) {
21935
22346
  }
21936
22347
  function statWorktreePath(worktreePath, relativePath) {
21937
22348
  assertSafeRelativePath(relativePath);
21938
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21939
- if (!(0, import_node_fs52.existsSync)(abs)) return "missing";
21940
- const st = (0, import_node_fs52.statSync)(abs);
22349
+ const abs = (0, import_node_path51.join)(worktreePath, relativePath);
22350
+ if (!(0, import_node_fs53.existsSync)(abs)) return "missing";
22351
+ const st = (0, import_node_fs53.statSync)(abs);
21941
22352
  if (st.isDirectory()) return "dir";
21942
22353
  if (st.isFile()) return "file";
21943
22354
  return "missing";
@@ -21966,8 +22377,8 @@ function isImageRelativePath(relativePath) {
21966
22377
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21967
22378
  assertSafeRelativePath(relativePath);
21968
22379
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
21969
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21970
- const st = (0, import_node_fs52.statSync)(abs);
22380
+ const abs = (0, import_node_path51.join)(worktreePath, relativePath);
22381
+ const st = (0, import_node_fs53.statSync)(abs);
21971
22382
  if (!st.isFile()) {
21972
22383
  throw new Error(`Not a file: ${relativePath}`);
21973
22384
  }
@@ -21976,7 +22387,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21976
22387
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
21977
22388
  );
21978
22389
  }
21979
- const buf = (0, import_node_fs52.readFileSync)(abs);
22390
+ const buf = (0, import_node_fs53.readFileSync)(abs);
21980
22391
  return {
21981
22392
  path: relativePath,
21982
22393
  contentBase64: buf.toString("base64"),
@@ -21986,12 +22397,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21986
22397
  function readWorktreeFile(worktreePath, relativePath, opts) {
21987
22398
  assertSafeRelativePath(relativePath);
21988
22399
  const maxBytes = opts?.maxBytes ?? 2e5;
21989
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21990
- const st = (0, import_node_fs52.statSync)(abs);
22400
+ const abs = (0, import_node_path51.join)(worktreePath, relativePath);
22401
+ const st = (0, import_node_fs53.statSync)(abs);
21991
22402
  if (!st.isFile()) {
21992
22403
  throw new Error(`Not a file: ${relativePath}`);
21993
22404
  }
21994
- const buf = (0, import_node_fs52.readFileSync)(abs);
22405
+ const buf = (0, import_node_fs53.readFileSync)(abs);
21995
22406
  if (isImageRelativePath(relativePath)) {
21996
22407
  const maxImageBytes = Math.max(maxBytes, 15e6);
21997
22408
  const truncated2 = buf.length > maxImageBytes;
@@ -22034,9 +22445,9 @@ function assertSafeRelativePath(relativePath) {
22034
22445
  }
22035
22446
  function writeWorktreeFile(worktreePath, relativePath, content) {
22036
22447
  assertSafeRelativePath(relativePath);
22037
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
22038
- (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
22039
- (0, import_node_fs52.writeFileSync)(abs, content, "utf8");
22448
+ const abs = (0, import_node_path51.join)(worktreePath, relativePath);
22449
+ (0, import_node_fs53.mkdirSync)((0, import_node_path51.dirname)(abs), { recursive: true });
22450
+ (0, import_node_fs53.writeFileSync)(abs, content, "utf8");
22040
22451
  return { path: relativePath };
22041
22452
  }
22042
22453
  async function getWorktreeDirtyStat(worktreePath) {
@@ -22076,12 +22487,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
22076
22487
  truncated: full.files.length > maxFiles
22077
22488
  };
22078
22489
  }
22079
- var import_node_fs52, import_node_path50, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
22490
+ var import_node_fs53, import_node_path51, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
22080
22491
  var init_diff = __esm({
22081
22492
  "src/diff/diff.ts"() {
22082
22493
  "use strict";
22083
- import_node_fs52 = require("fs");
22084
- import_node_path50 = require("path");
22494
+ import_node_fs53 = require("fs");
22495
+ import_node_path51 = require("path");
22085
22496
  init_run();
22086
22497
  init_worktree();
22087
22498
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -22438,7 +22849,7 @@ function parseFrontmatter(content) {
22438
22849
  }
22439
22850
  function readSkill(skillMd, source) {
22440
22851
  try {
22441
- const content = (0, import_node_fs53.readFileSync)(skillMd, "utf8");
22852
+ const content = (0, import_node_fs54.readFileSync)(skillMd, "utf8");
22442
22853
  const { name: fmName, description } = parseFrontmatter(content);
22443
22854
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
22444
22855
  const name = fmName || dirName;
@@ -22457,19 +22868,19 @@ function readSkill(skillMd, source) {
22457
22868
  }
22458
22869
  }
22459
22870
  function scanSkillsDir(dir, source, out) {
22460
- if (!(0, import_node_fs53.existsSync)(dir)) return;
22871
+ if (!(0, import_node_fs54.existsSync)(dir)) return;
22461
22872
  let entries;
22462
22873
  try {
22463
- entries = (0, import_node_fs53.readdirSync)(dir);
22874
+ entries = (0, import_node_fs54.readdirSync)(dir);
22464
22875
  } catch {
22465
22876
  return;
22466
22877
  }
22467
22878
  for (const entry of entries) {
22468
22879
  if (entry.startsWith(".")) continue;
22469
- const skillMd = (0, import_node_path51.join)(dir, entry, "SKILL.md");
22470
- if (!(0, import_node_fs53.existsSync)(skillMd)) continue;
22880
+ const skillMd = (0, import_node_path52.join)(dir, entry, "SKILL.md");
22881
+ if (!(0, import_node_fs54.existsSync)(skillMd)) continue;
22471
22882
  try {
22472
- if (!(0, import_node_fs53.statSync)(skillMd).isFile()) continue;
22883
+ if (!(0, import_node_fs54.statSync)(skillMd).isFile()) continue;
22473
22884
  } catch {
22474
22885
  continue;
22475
22886
  }
@@ -22478,24 +22889,24 @@ function scanSkillsDir(dir, source, out) {
22478
22889
  }
22479
22890
  }
22480
22891
  function scanClaudePluginSkills(pluginsRoot, out) {
22481
- if (!(0, import_node_fs53.existsSync)(pluginsRoot)) return;
22892
+ if (!(0, import_node_fs54.existsSync)(pluginsRoot)) return;
22482
22893
  const walk = (dir, depth, lookingForSkillsDir) => {
22483
22894
  if (depth > 7) return;
22484
22895
  let entries;
22485
22896
  try {
22486
- entries = (0, import_node_fs53.readdirSync)(dir);
22897
+ entries = (0, import_node_fs54.readdirSync)(dir);
22487
22898
  } catch {
22488
22899
  return;
22489
22900
  }
22490
22901
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
22491
- const skill = readSkill((0, import_node_path51.join)(dir, "SKILL.md"), "cli");
22902
+ const skill = readSkill((0, import_node_path52.join)(dir, "SKILL.md"), "cli");
22492
22903
  if (skill) out.push(skill);
22493
22904
  }
22494
22905
  for (const entry of entries) {
22495
22906
  if (entry === "node_modules" || entry === ".git") continue;
22496
- const full = (0, import_node_path51.join)(dir, entry);
22907
+ const full = (0, import_node_path52.join)(dir, entry);
22497
22908
  try {
22498
- if (!(0, import_node_fs53.statSync)(full).isDirectory()) continue;
22909
+ if (!(0, import_node_fs54.statSync)(full).isDirectory()) continue;
22499
22910
  } catch {
22500
22911
  continue;
22501
22912
  }
@@ -22513,17 +22924,17 @@ function discoverSkills(worktreePath) {
22513
22924
  const home = (0, import_node_os15.homedir)();
22514
22925
  const collected = [];
22515
22926
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
22516
- scanSkillsDir((0, import_node_path51.join)(worktreePath, rel), "workspace", collected);
22927
+ scanSkillsDir((0, import_node_path52.join)(worktreePath, rel), "workspace", collected);
22517
22928
  }
22518
22929
  for (const abs of [
22519
- (0, import_node_path51.join)(home, ".claude/skills"),
22520
- (0, import_node_path51.join)(home, ".cursor/skills"),
22521
- (0, import_node_path51.join)(home, ".sideboard/skills"),
22522
- (0, import_node_path51.join)(home, ".brightsy/skills")
22930
+ (0, import_node_path52.join)(home, ".claude/skills"),
22931
+ (0, import_node_path52.join)(home, ".cursor/skills"),
22932
+ (0, import_node_path52.join)(home, ".sideboard/skills"),
22933
+ (0, import_node_path52.join)(home, ".brightsy/skills")
22523
22934
  ]) {
22524
22935
  scanSkillsDir(abs, "user", collected);
22525
22936
  }
22526
- scanClaudePluginSkills((0, import_node_path51.join)(home, ".claude/plugins"), collected);
22937
+ scanClaudePluginSkills((0, import_node_path52.join)(home, ".claude/plugins"), collected);
22527
22938
  collected.push(...bundledSkills());
22528
22939
  const rank = {
22529
22940
  workspace: 0,
@@ -22549,7 +22960,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22549
22960
  \u2026(truncated)` : body;
22550
22961
  }
22551
22962
  }
22552
- const raw = (0, import_node_fs53.readFileSync)(skillPath, "utf8");
22963
+ const raw = (0, import_node_fs54.readFileSync)(skillPath, "utf8");
22553
22964
  if (raw.startsWith("---")) {
22554
22965
  const end = raw.indexOf("\n---", 3);
22555
22966
  if (end >= 0) {
@@ -22563,13 +22974,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22563
22974
 
22564
22975
  \u2026(truncated)` : raw;
22565
22976
  }
22566
- var import_node_fs53, import_node_os15, import_node_path51, BUNDLED_SKILL_PREFIX;
22977
+ var import_node_fs54, import_node_os15, import_node_path52, BUNDLED_SKILL_PREFIX;
22567
22978
  var init_discover = __esm({
22568
22979
  "src/skills/discover.ts"() {
22569
22980
  "use strict";
22570
- import_node_fs53 = require("fs");
22981
+ import_node_fs54 = require("fs");
22571
22982
  import_node_os15 = require("os");
22572
- import_node_path51 = require("path");
22983
+ import_node_path52 = require("path");
22573
22984
  init_long_running();
22574
22985
  BUNDLED_SKILL_PREFIX = "bundled:";
22575
22986
  }
@@ -22724,7 +23135,7 @@ function compiledModuleDir() {
22724
23135
  try {
22725
23136
  const url = import_meta4.url;
22726
23137
  if (typeof url === "string" && url.length > 0) {
22727
- return (0, import_node_path52.dirname)((0, import_node_url4.fileURLToPath)(url));
23138
+ return (0, import_node_path53.dirname)((0, import_node_url4.fileURLToPath)(url));
22728
23139
  }
22729
23140
  } catch {
22730
23141
  }
@@ -22732,8 +23143,8 @@ function compiledModuleDir() {
22732
23143
  }
22733
23144
  function detachedJobScriptIn(dir) {
22734
23145
  for (const name of DETACHED_JOB_FILENAMES) {
22735
- const script = (0, import_node_path52.join)(dir, "scripts", name);
22736
- if ((0, import_node_fs54.existsSync)(script)) return script;
23146
+ const script = (0, import_node_path53.join)(dir, "scripts", name);
23147
+ if ((0, import_node_fs55.existsSync)(script)) return script;
22737
23148
  }
22738
23149
  return null;
22739
23150
  }
@@ -22750,7 +23161,7 @@ function resolveDetachedJobScript() {
22750
23161
  for (let i = 0; i < 8; i++) {
22751
23162
  const candidate = detachedJobScriptIn(dir);
22752
23163
  if (candidate) return candidate;
22753
- const parent = (0, import_node_path52.dirname)(dir);
23164
+ const parent = (0, import_node_path53.dirname)(dir);
22754
23165
  if (parent === dir) break;
22755
23166
  dir = parent;
22756
23167
  }
@@ -22761,12 +23172,12 @@ function formatDetachedJobInvoke(scriptPath) {
22761
23172
  if (resolved) return `node ${JSON.stringify(resolved)}`;
22762
23173
  return "node scripts/detached-job.cjs";
22763
23174
  }
22764
- var import_node_fs54, import_node_path52, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
23175
+ var import_node_fs55, import_node_path53, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
22765
23176
  var init_detached_job_path = __esm({
22766
23177
  "src/skills/detached-job-path.ts"() {
22767
23178
  "use strict";
22768
- import_node_fs54 = require("fs");
22769
- import_node_path52 = require("path");
23179
+ import_node_fs55 = require("fs");
23180
+ import_node_path53 = require("path");
22770
23181
  import_node_url4 = require("url");
22771
23182
  init_packaged_runtime();
22772
23183
  import_meta4 = {};
@@ -22801,6 +23212,34 @@ function formatRenameBranchDirective(thread, opts) {
22801
23212
  }
22802
23213
  return lines.join("\n");
22803
23214
  }
23215
+ function localhostPreviewUrl(port) {
23216
+ return `http://localhost:${port}`;
23217
+ }
23218
+ function describeLiveDevRun(run2) {
23219
+ const url = localhostPreviewUrl(run2.port);
23220
+ if (run2.preview === "window") {
23221
+ return `${run2.scriptName} Electron window (renderer ${url})`;
23222
+ }
23223
+ return `${run2.scriptName} ${url}`;
23224
+ }
23225
+ function formatDevAccessHint(runs) {
23226
+ const live = (runs ?? []).filter(
23227
+ (r) => Number.isFinite(r.port) && r.port > 0
23228
+ );
23229
+ if (live.length === 1) {
23230
+ const r = live[0];
23231
+ const url = localhostPreviewUrl(r.port);
23232
+ if (r.preview === "window") {
23233
+ return `This worktree's Dev app is the Electron window (${r.scriptName}). Renderer origin ${url} \u2014 curl to confirm Vite; do not open it in a browser (no preload/IPC). Do not guess :3000.`;
23234
+ }
23235
+ return `This worktree's Dev app is ${url} (${r.scriptName}). Open that URL (browser, curl, Playwright) \u2014 do not guess :3000.`;
23236
+ }
23237
+ if (live.length > 1) {
23238
+ const bits = live.map(describeLiveDevRun).join("; ");
23239
+ return `This worktree's Dev apps: ${bits}. preview=url \u2192 open the URL; preview=window \u2192 Electron window is the app. Do not guess :3000.`;
23240
+ }
23241
+ return "To open the project Dev app: MCP `run_dev_script` (same as the desktop Dev button) returns `{url, port, preview}` (`SIDEBOARD_PORT`, not 3000). preview=url \u2192 open that URL (browser, curl, Playwright). preview=window \u2192 Electron: the native window is the app; url is renderer/HMR only (no preload/IPC in a browser). If already running, `list_run_scripts` `active[].url`. `stop_dev_script` to stop.";
23242
+ }
22804
23243
  function formatWorktreeDirective(thread, opts) {
22805
23244
  const worktree = normPath3(thread.worktreePath);
22806
23245
  const repo = normPath3(thread.repoPath);
@@ -22848,6 +23287,8 @@ function formatWorktreeDirective(thread, opts) {
22848
23287
  '- Sideboard git buttons send short phrases ("Commit and push.", "Ready for review.", "Merge PR.", \u2026) with their meaning attached \u2014 act on them without asking for clarification. If the user gives a goal (Greptile 5/5, CI green, until checks pass), you get the watch-fix-push playbook with that request.'
22849
23288
  );
22850
23289
  lines.push("");
23290
+ lines.push(formatDevAccessHint(opts?.activeRuns));
23291
+ lines.push("");
22851
23292
  lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
22852
23293
  return lines.join("\n");
22853
23294
  }
@@ -22948,9 +23389,9 @@ function formatPrGateDirective() {
22948
23389
  }
22949
23390
  function formatProcessGuideDirective(opts) {
22950
23391
  const worktree = opts?.worktreePath?.trim();
22951
- const hasGraphSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22952
- const hasReviewSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/review/SKILL.md"));
22953
- const hasInstallSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
23392
+ const hasGraphSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path54.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
23393
+ const hasReviewSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path54.join)(worktree, ".claude/skills/review/SKILL.md"));
23394
+ const hasInstallSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path54.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22954
23395
  return [
22955
23396
  "Process guides (recurring work only):",
22956
23397
  hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
@@ -22970,12 +23411,12 @@ function formatLongRunningDirective(opts) {
22970
23411
  "- Hanging, no useful output, or the wrong thing \u2192 `stop_job` (or the helper with `stop <id>`). Do not stop a pack/test/deploy that is clearly making progress.",
22971
23412
  "- Stay in the loop until stillRunning is false (or you stopped it). ok \u2192 finish the task. failed / stopped \u2192 read the log, fix or narrow the command, start once.",
22972
23413
  "State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available).",
22973
- "Project Dev / run scripts (`.sideboard` `[scripts.run.*]`, same as the desktop Dev button): use MCP `list_run_scripts` / `run_dev_script` / `stop_dev_script` \u2014 logs and Stop live in the thread UI. Do not detached-job or shell-spawn that same command."
23414
+ "Project Dev / run scripts (`.sideboard` `[scripts.run.*]`, same as the desktop Dev button): use MCP `list_run_scripts` / `run_dev_script` / `stop_dev_script` \u2014 logs and Stop live in the thread UI. Do not detached-job or shell-spawn that same command. `run_dev_script` returns `{url, port, preview}` (`SIDEBOARD_PORT`). preview=url \u2192 open that URL; preview=window \u2192 Electron window is the app (url is renderer/HMR only). Never guess :3000."
22974
23415
  ].join("\n");
22975
23416
  }
22976
23417
  function formatLongRunningReminder(opts) {
22977
23418
  const invoke = formatDetachedJobInvoke(opts?.scriptPath);
22978
- return `Long jobs: \`${invoke} start <id> -- <cmd>\`, loop wait_for_job (or detached-job wait). The log pane updates from wait JSON; present_artifact type=log is optional. stop_job if hanging or wrong. Do not say you will let the user know later \u2014 stay in the turn. Project Dev button: list_run_scripts / run_dev_script / stop_dev_script (UI-connected \u2014 not detached-job).`;
23419
+ return `Long jobs: \`${invoke} start <id> -- <cmd>\`, loop wait_for_job (or detached-job wait). The log pane updates from wait JSON; present_artifact type=log is optional. stop_job if hanging or wrong. Do not say you will let the user know later \u2014 stay in the turn. Project Dev button: list_run_scripts / run_dev_script / stop_dev_script (UI-connected \u2014 not detached-job). ${formatDevAccessHint(opts?.activeRuns)}`;
22979
23420
  }
22980
23421
  function formatArtifactDirective() {
22981
23422
  return [
@@ -22987,14 +23428,14 @@ function formatArtifactDirective() {
22987
23428
  ].join("\n");
22988
23429
  }
22989
23430
  function formatUiReminder() {
22990
- return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable. Dev / preview: run_dev_script (same as the Dev button); stop_dev_script to stop.";
23431
+ return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable. Dev / preview: run_dev_script (same as the Dev button) returns {url, port, preview} (SIDEBOARD_PORT \u2014 never guess :3000). preview=url \u2192 open url; preview=window \u2192 Electron window is the app, url is renderer/HMR only. list_run_scripts active[].url if already running; stop_dev_script to stop.";
22991
23432
  }
22992
- var import_node_fs55, import_node_path53, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
23433
+ var import_node_fs56, import_node_path54, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22993
23434
  var init_instructions = __esm({
22994
23435
  "src/agents/instructions.ts"() {
22995
23436
  "use strict";
22996
- import_node_fs55 = require("fs");
22997
- import_node_path53 = require("path");
23437
+ import_node_fs56 = require("fs");
23438
+ import_node_path54 = require("path");
22998
23439
  init_git_auth_mode();
22999
23440
  init_branch_prefix();
23000
23441
  init_worktree_labels();
@@ -23380,40 +23821,40 @@ __export(plan_file_exports, {
23380
23821
  writePlanFile: () => writePlanFile
23381
23822
  });
23382
23823
  function ensureAttachmentsGitignore(worktreePath) {
23383
- const gitignoreAbs = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23384
- if ((0, import_node_fs56.existsSync)(gitignoreAbs)) return;
23385
- (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(gitignoreAbs), { recursive: true });
23386
- (0, import_node_fs56.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23824
+ const gitignoreAbs = (0, import_node_path55.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23825
+ if ((0, import_node_fs57.existsSync)(gitignoreAbs)) return;
23826
+ (0, import_node_fs57.mkdirSync)((0, import_node_path55.dirname)(gitignoreAbs), { recursive: true });
23827
+ (0, import_node_fs57.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23387
23828
  }
23388
23829
  function planFileAbs(worktreePath) {
23389
- return (0, import_node_path54.join)(worktreePath, PLAN_FILE_REL);
23830
+ return (0, import_node_path55.join)(worktreePath, PLAN_FILE_REL);
23390
23831
  }
23391
23832
  function readTextIfPresent2(abs) {
23392
- if (!(0, import_node_fs56.existsSync)(abs)) return null;
23833
+ if (!(0, import_node_fs57.existsSync)(abs)) return null;
23393
23834
  try {
23394
- const content = (0, import_node_fs56.readFileSync)(abs, "utf8");
23835
+ const content = (0, import_node_fs57.readFileSync)(abs, "utf8");
23395
23836
  return content.trim() ? content : null;
23396
23837
  } catch {
23397
23838
  return null;
23398
23839
  }
23399
23840
  }
23400
23841
  function readPlanFile(worktreePath) {
23401
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path54.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path54.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23842
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path55.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path55.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23402
23843
  }
23403
23844
  function writePlanFile(worktreePath, content) {
23404
23845
  ensureAttachmentsGitignore(worktreePath);
23405
23846
  const abs = planFileAbs(worktreePath);
23406
- (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(abs), { recursive: true });
23847
+ (0, import_node_fs57.mkdirSync)((0, import_node_path55.dirname)(abs), { recursive: true });
23407
23848
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23408
- (0, import_node_fs56.writeFileSync)(abs, body, "utf8");
23849
+ (0, import_node_fs57.writeFileSync)(abs, body, "utf8");
23409
23850
  return PLAN_FILE_REL;
23410
23851
  }
23411
- var import_node_fs56, import_node_path54;
23852
+ var import_node_fs57, import_node_path55;
23412
23853
  var init_plan_file = __esm({
23413
23854
  "src/plan/plan-file.ts"() {
23414
23855
  "use strict";
23415
- import_node_fs56 = require("fs");
23416
- import_node_path54 = require("path");
23856
+ import_node_fs57 = require("fs");
23857
+ import_node_path55 = require("path");
23417
23858
  init_workspace_scratch();
23418
23859
  init_plan_present();
23419
23860
  init_plan_present();
@@ -23475,9 +23916,9 @@ function recoverFinishedCursorRun(opts) {
23475
23916
  return best;
23476
23917
  }
23477
23918
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23478
- if (!(0, import_node_fs57.existsSync)(runsPath)) return null;
23919
+ if (!(0, import_node_fs58.existsSync)(runsPath)) return null;
23479
23920
  try {
23480
- const lines = (0, import_node_fs57.readFileSync)(runsPath, "utf8").split("\n");
23921
+ const lines = (0, import_node_fs58.readFileSync)(runsPath, "utf8").split("\n");
23481
23922
  let best = null;
23482
23923
  for (const line of lines) {
23483
23924
  const trimmed = line.trim();
@@ -23503,11 +23944,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23503
23944
  return null;
23504
23945
  }
23505
23946
  }
23506
- var import_node_fs57;
23947
+ var import_node_fs58;
23507
23948
  var init_cursor_recover = __esm({
23508
23949
  "src/agents/cursor-recover.ts"() {
23509
23950
  "use strict";
23510
- import_node_fs57 = require("fs");
23951
+ import_node_fs58 = require("fs");
23511
23952
  init_cursor_store();
23512
23953
  }
23513
23954
  });
@@ -23661,14 +24102,14 @@ async function startOrchestration(opts) {
23661
24102
  }
23662
24103
  return updated;
23663
24104
  }
23664
- var import_node_events, import_node_crypto12, import_node_fs58, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
24105
+ var import_node_events, import_node_crypto12, import_node_fs59, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
23665
24106
  var init_orchestrator = __esm({
23666
24107
  "src/orchestrator/orchestrator.ts"() {
23667
24108
  "use strict";
23668
24109
  import_node_events = require("events");
23669
24110
  init_outbound_watch();
23670
24111
  import_node_crypto12 = require("crypto");
23671
- import_node_fs58 = require("fs");
24112
+ import_node_fs59 = require("fs");
23672
24113
  init_error_detail();
23673
24114
  init_run();
23674
24115
  init_stale_lock();
@@ -23680,6 +24121,7 @@ var init_orchestrator = __esm({
23680
24121
  init_agent_git_actions();
23681
24122
  init_pr_merge_archive();
23682
24123
  init_conductor();
24124
+ init_dev_preview();
23683
24125
  init_setup_log();
23684
24126
  init_orphan_cleanup();
23685
24127
  init_history_cleanup();
@@ -23845,7 +24287,7 @@ var init_orchestrator = __esm({
23845
24287
  this.lightReconcileAt.set(repoPath, Date.now());
23846
24288
  for (const thread of listThreads()) {
23847
24289
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
23848
- if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
24290
+ if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
23849
24291
  setStatus(thread.id, "broken", "Worktree missing on disk");
23850
24292
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23851
24293
  }
@@ -23874,7 +24316,7 @@ var init_orchestrator = __esm({
23874
24316
  }
23875
24317
  continue;
23876
24318
  }
23877
- if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
24319
+ if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
23878
24320
  setStatus(thread.id, "broken", "Worktree missing on disk");
23879
24321
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23880
24322
  continue;
@@ -24561,8 +25003,13 @@ var init_orchestrator = __esm({
24561
25003
  SLACK_REPLY_FORMATTING
24562
25004
  ].join("\n") : null
24563
25005
  ].filter(Boolean).join("\n") : null;
25006
+ const worktreeActiveRuns = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && thread.worktreePath ? annotateDevAccessRuns(
25007
+ mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath)).activeRuns,
25008
+ listRunScripts(thread.worktreePath, thread.repoPath),
25009
+ thread.worktreePath
25010
+ ) : [];
24564
25011
  const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
24565
- const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder() : null;
25012
+ const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder({ activeRuns: worktreeActiveRuns }) : null;
24566
25013
  const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
24567
25014
  const optionalServicesReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatOptionalServicesReminder(loadAppSettings().integrations) : null;
24568
25015
  const issueTicket = issueTicketFromThread(thread, resolveEffectiveIssueSource());
@@ -24622,7 +25069,14 @@ var init_orchestrator = __esm({
24622
25069
  8e3,
24623
25070
  "resolveGithubRepoSlug"
24624
25071
  ).catch(() => null),
24625
- gitAuthMode
25072
+ gitAuthMode,
25073
+ activeRuns: annotateDevAccessRuns(
25074
+ mergeWorktreeActiveRuns(
25075
+ threadsSharingWorktree(fresh.worktreePath)
25076
+ ).activeRuns,
25077
+ listRunScripts(fresh.worktreePath, fresh.repoPath),
25078
+ fresh.worktreePath
25079
+ )
24626
25080
  });
24627
25081
  const artifactDirective = isBrightsy ? null : formatArtifactDirective();
24628
25082
  const longRunningDirective = isBrightsy || isOrchestration ? null : formatLongRunningDirective();
@@ -25204,7 +25658,8 @@ var init_orchestrator = __esm({
25204
25658
  }
25205
25659
  return this.waitForDesktopRunScript(thread.id, request, op, scriptName);
25206
25660
  }
25207
- async waitForDesktopRunScript(threadId, request, op, scriptName) {
25661
+ async waitForDesktopRunScript(threadId, initialRequest, op, scriptName) {
25662
+ let request = initialRequest;
25208
25663
  const deadline = Date.now() + this.runScriptAdoptTimeoutMs;
25209
25664
  while (Date.now() < deadline) {
25210
25665
  const latest = readThread(threadId);
@@ -25228,6 +25683,15 @@ var init_orchestrator = __esm({
25228
25683
  }
25229
25684
  } else if (fulfilled) {
25230
25685
  return null;
25686
+ } else if (requestGone) {
25687
+ const coversThisStop = req?.op === "stop" && (req.scriptName == null || req.scriptName === (scriptName ?? null));
25688
+ if (req && coversThisStop) {
25689
+ request = req;
25690
+ continue;
25691
+ }
25692
+ throw new Error(
25693
+ req?.op === "start" ? "Stop was replaced by a newer start request before desktop applied it." : "Stop was replaced by another run-script request before desktop applied it."
25694
+ );
25231
25695
  }
25232
25696
  await new Promise((r) => setTimeout(r, 40));
25233
25697
  }
@@ -26165,7 +26629,7 @@ var init_orchestrator = __esm({
26165
26629
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
26166
26630
  return restored2;
26167
26631
  }
26168
- if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
26632
+ if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
26169
26633
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
26170
26634
  throw new Error(
26171
26635
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -26502,6 +26966,7 @@ __export(index_exports, {
26502
26966
  abletimeMcpUrl: () => abletimeMcpUrl,
26503
26967
  abletimeToolUsesPm: () => abletimeToolUsesPm,
26504
26968
  ackSlackInboundSeen: () => ackSlackInboundSeen,
26969
+ activeRunPreview: () => activeRunPreview,
26505
26970
  addBoardPin: () => addBoardPin,
26506
26971
  addPrStackLayer: () => addPrStackLayer,
26507
26972
  addStackLayerFromThread: () => addStackLayerFromThread,
@@ -26517,6 +26982,7 @@ __export(index_exports, {
26517
26982
  allocatePortRange: () => allocatePortRange,
26518
26983
  allocateTeamName: () => allocateTeamName,
26519
26984
  allocateTeamSlug: () => allocateTeamSlug,
26985
+ annotateDevAccessRuns: () => annotateDevAccessRuns,
26520
26986
  appDataDir: () => appDataDir,
26521
26987
  appSettingsPath: () => appSettingsPath,
26522
26988
  appendIndexedGitConfig: () => appendIndexedGitConfig,
@@ -26581,6 +27047,7 @@ __export(index_exports, {
26581
27047
  clampGithubPrBody: () => clampGithubPrBody,
26582
27048
  clampHistoryMaxCount: () => clampHistoryMaxCount,
26583
27049
  clampHistoryMaxDays: () => clampHistoryMaxDays,
27050
+ classifyRunScriptPreview: () => classifyRunScriptPreview,
26584
27051
  classifyWorktreeColumn: () => classifyWorktreeColumn,
26585
27052
  claudeAdapter: () => claudeAdapter,
26586
27053
  claudeChromeEnabled: () => claudeChromeEnabled,
@@ -26600,6 +27067,7 @@ __export(index_exports, {
26600
27067
  codexUnattendedGitConfigArgs: () => codexUnattendedGitConfigArgs,
26601
27068
  coerceOrchestratorAgent: () => coerceOrchestratorAgent,
26602
27069
  collectTakenTeamSlugs: () => collectTakenTeamSlugs,
27070
+ commandLooksLikeElectron: () => commandLooksLikeElectron,
26603
27071
  commentAbleTimeTask: () => commentAbleTimeTask,
26604
27072
  commentGitHubIssue: () => commentGitHubIssue,
26605
27073
  commentLinearIssue: () => commentLinearIssue,
@@ -26722,6 +27190,7 @@ __export(index_exports, {
26722
27190
  formatClaudeUsageResetClock: () => formatClaudeUsageResetClock,
26723
27191
  formatClaudeUsageTooltip: () => formatClaudeUsageTooltip,
26724
27192
  formatDetachedJobInvoke: () => formatDetachedJobInvoke,
27193
+ formatDevAccessHint: () => formatDevAccessHint,
26725
27194
  formatFetchError: () => formatFetchError,
26726
27195
  formatGhLandError: () => formatGhLandError,
26727
27196
  formatGitAuthModeDirective: () => formatGitAuthModeDirective,
@@ -26848,7 +27317,10 @@ __export(index_exports, {
26848
27317
  isBrightsyConnected: () => isBrightsyConnected,
26849
27318
  isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
26850
27319
  isCloudCoordinatorThread: () => isCloudCoordinatorThread,
27320
+ isCompactToolName: () => isCompactToolName,
26851
27321
  isConductorBundledCli: () => isConductorBundledCli,
27322
+ isContextCompactDone: () => isContextCompactDone,
27323
+ isContextCompactInProgress: () => isContextCompactInProgress,
26852
27324
  isCowboyThread: () => isCowboyThread,
26853
27325
  isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
26854
27326
  isCursorAutoModel: () => isCursorAutoModel,
@@ -26886,6 +27358,7 @@ __export(index_exports, {
26886
27358
  isSetupLastError: () => isSetupLastError,
26887
27359
  isShellToolName: () => isShellToolName,
26888
27360
  isSideboardScratchPath: () => isSideboardScratchPath,
27361
+ isSkillToolName: () => isSkillToolName,
26889
27362
  isSlackCoordinatorThread: () => isSlackCoordinatorThread,
26890
27363
  isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
26891
27364
  isSlackOAuthCancelled: () => isSlackOAuthCancelled,
@@ -26956,8 +27429,11 @@ __export(index_exports, {
26956
27429
  loadHomeBoardInputs: () => loadHomeBoardInputs,
26957
27430
  loadRepoSettings: () => loadRepoSettings,
26958
27431
  loadWorkspaceSettings: () => loadWorkspaceSettings,
27432
+ localhostPreviewUrl: () => localhostPreviewUrl,
26959
27433
  locksDir: () => locksDir,
26960
27434
  loginAgent: () => loginAgent,
27435
+ looksLikeConversationSummary: () => looksLikeConversationSummary,
27436
+ looksLikeSkillBody: () => looksLikeSkillBody,
26961
27437
  lookupSoccerTeam: () => lookupSoccerTeam,
26962
27438
  mapAbleTimeTask: () => mapAbleTimeTask,
26963
27439
  markPrReady: () => markPrReady,
@@ -27010,6 +27486,7 @@ __export(index_exports, {
27010
27486
  parseAbleTimeOAuthCallbackUrl: () => parseAbleTimeOAuthCallbackUrl,
27011
27487
  parseClaudeUsagePayload: () => parseClaudeUsagePayload,
27012
27488
  parseCursorRunnerLine: () => parseCursorRunnerLine,
27489
+ parseDevPreview: () => parseDevPreview,
27013
27490
  parseDurationMs: () => parseDurationMs,
27014
27491
  parseForceStopMessage: () => parseForceStopMessage,
27015
27492
  parseGhStackViewJson: () => parseGhStackViewJson,
@@ -27031,6 +27508,7 @@ __export(index_exports, {
27031
27508
  planHistoryAgePurge: () => planHistoryAgePurge,
27032
27509
  planHistoryRetention: () => planHistoryRetention,
27033
27510
  planQuestionsSignature: () => planQuestionsSignature,
27511
+ pnpmFilterPackage: () => pnpmFilterPackage,
27034
27512
  pollSlackOutboundWatches: () => pollSlackOutboundWatches,
27035
27513
  posixShellSingleQuote: () => posixShellSingleQuote,
27036
27514
  preferredCursorCostCents: () => preferredCursorCostCents,
@@ -27128,6 +27606,7 @@ __export(index_exports, {
27128
27606
  runCloudConnect: () => runCloudConnect,
27129
27607
  runConventionSetup: () => runConventionSetup,
27130
27608
  runCursorWorktreeSetup: () => runCursorWorktreeSetup,
27609
+ runScriptPreview: () => runScriptPreview,
27131
27610
  runSetupScript: () => runSetupScript,
27132
27611
  runSlackListen: () => runSlackListen,
27133
27612
  runSlackRelayClient: () => runSlackRelayClient,
@@ -27162,6 +27641,9 @@ __export(index_exports, {
27162
27641
  sideboardMcpProfile: () => sideboardMcpProfile,
27163
27642
  sideboardReposDir: () => sideboardReposDir,
27164
27643
  sideboardWorkspacesDir: () => sideboardWorkspacesDir,
27644
+ skillCommandFromBody: () => skillCommandFromBody,
27645
+ skillCommandFromInput: () => skillCommandFromInput,
27646
+ skillNameFromFrontmatter: () => skillNameFromFrontmatter,
27165
27647
  slackAppLevelToken: () => slackAppLevelToken,
27166
27648
  slackArchiveUrl: () => slackArchiveUrl,
27167
27649
  slackCoordinatorSourceRef: () => slackCoordinatorSourceRef,
@@ -27276,8 +27758,8 @@ init_paths();
27276
27758
  init_app_settings();
27277
27759
 
27278
27760
  // src/store/agent-done-sound.ts
27279
- var import_node_fs8 = require("fs");
27280
- var import_node_path9 = require("path");
27761
+ var import_node_fs9 = require("fs");
27762
+ var import_node_path10 = require("path");
27281
27763
  init_paths();
27282
27764
  var AGENT_DONE_CUSTOM_SOUND_MAX_BYTES = 5 * 1024 * 1024;
27283
27765
  var AUDIO_EXT_MIME = {
@@ -27291,8 +27773,8 @@ var AUDIO_EXT_MIME = {
27291
27773
  };
27292
27774
  var AGENT_DONE_CUSTOM_SOUND_EXTENSIONS = Object.keys(AUDIO_EXT_MIME);
27293
27775
  function agentDoneSoundsDir() {
27294
- const dir = (0, import_node_path9.join)(appDataDir(), "sounds");
27295
- (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
27776
+ const dir = (0, import_node_path10.join)(appDataDir(), "sounds");
27777
+ (0, import_node_fs9.mkdirSync)(dir, { recursive: true });
27296
27778
  return dir;
27297
27779
  }
27298
27780
  function normalizeExt(ext) {
@@ -27300,50 +27782,50 @@ function normalizeExt(ext) {
27300
27782
  return e.startsWith(".") ? e : `.${e}`;
27301
27783
  }
27302
27784
  function agentDoneCustomSoundMime(extOrPath) {
27303
- const ext = normalizeExt((0, import_node_path9.extname)(extOrPath) || extOrPath);
27785
+ const ext = normalizeExt((0, import_node_path10.extname)(extOrPath) || extOrPath);
27304
27786
  return AUDIO_EXT_MIME[ext] ?? null;
27305
27787
  }
27306
27788
  function findAgentDoneCustomSoundPath() {
27307
27789
  const dir = agentDoneSoundsDir();
27308
- for (const name of (0, import_node_fs8.readdirSync)(dir)) {
27790
+ for (const name of (0, import_node_fs9.readdirSync)(dir)) {
27309
27791
  if (!name.startsWith("agent-done.")) continue;
27310
- const full = (0, import_node_path9.join)(dir, name);
27311
- if ((0, import_node_fs8.existsSync)(full) && agentDoneCustomSoundMime(name)) return full;
27792
+ const full = (0, import_node_path10.join)(dir, name);
27793
+ if ((0, import_node_fs9.existsSync)(full) && agentDoneCustomSoundMime(name)) return full;
27312
27794
  }
27313
27795
  return null;
27314
27796
  }
27315
27797
  function clearAgentDoneCustomSoundFile() {
27316
27798
  const dir = agentDoneSoundsDir();
27317
- for (const name of (0, import_node_fs8.readdirSync)(dir)) {
27799
+ for (const name of (0, import_node_fs9.readdirSync)(dir)) {
27318
27800
  if (!name.startsWith("agent-done.")) continue;
27319
27801
  try {
27320
- (0, import_node_fs8.unlinkSync)((0, import_node_path9.join)(dir, name));
27802
+ (0, import_node_fs9.unlinkSync)((0, import_node_path10.join)(dir, name));
27321
27803
  } catch {
27322
27804
  }
27323
27805
  }
27324
27806
  }
27325
27807
  function importAgentDoneCustomSound(sourcePath) {
27326
27808
  const trimmed = sourcePath.trim();
27327
- if (!trimmed || !(0, import_node_fs8.existsSync)(trimmed)) {
27809
+ if (!trimmed || !(0, import_node_fs9.existsSync)(trimmed)) {
27328
27810
  throw new Error("Sound file not found");
27329
27811
  }
27330
- const ext = normalizeExt((0, import_node_path9.extname)(trimmed));
27812
+ const ext = normalizeExt((0, import_node_path10.extname)(trimmed));
27331
27813
  const mime = AUDIO_EXT_MIME[ext];
27332
27814
  if (!mime) {
27333
27815
  throw new Error(
27334
27816
  `Unsupported audio type (use ${AGENT_DONE_CUSTOM_SOUND_EXTENSIONS.join(", ")})`
27335
27817
  );
27336
27818
  }
27337
- const data = (0, import_node_fs8.readFileSync)(trimmed);
27819
+ const data = (0, import_node_fs9.readFileSync)(trimmed);
27338
27820
  if (data.byteLength === 0) throw new Error("Sound file is empty");
27339
27821
  if (data.byteLength > AGENT_DONE_CUSTOM_SOUND_MAX_BYTES) {
27340
27822
  throw new Error("Sound file is too large (max 5 MB)");
27341
27823
  }
27342
27824
  clearAgentDoneCustomSoundFile();
27343
- const dest = (0, import_node_path9.join)(agentDoneSoundsDir(), `agent-done${ext}`);
27344
- (0, import_node_fs8.copyFileSync)(trimmed, dest);
27825
+ const dest = (0, import_node_path10.join)(agentDoneSoundsDir(), `agent-done${ext}`);
27826
+ (0, import_node_fs9.copyFileSync)(trimmed, dest);
27345
27827
  return {
27346
- name: (0, import_node_path9.basename)(trimmed),
27828
+ name: (0, import_node_path10.basename)(trimmed),
27347
27829
  path: dest,
27348
27830
  mime
27349
27831
  };
@@ -27353,10 +27835,10 @@ function readAgentDoneCustomSound(displayName2) {
27353
27835
  if (!path2) return null;
27354
27836
  const mime = agentDoneCustomSoundMime(path2);
27355
27837
  if (!mime) return null;
27356
- const data = (0, import_node_fs8.readFileSync)(path2);
27838
+ const data = (0, import_node_fs9.readFileSync)(path2);
27357
27839
  if (data.byteLength === 0) return null;
27358
27840
  return {
27359
- name: displayName2?.trim() || (0, import_node_path9.basename)(path2),
27841
+ name: displayName2?.trim() || (0, import_node_path10.basename)(path2),
27360
27842
  mime,
27361
27843
  dataBase64: data.toString("base64")
27362
27844
  };
@@ -29450,6 +29932,7 @@ init_instructions();
29450
29932
  init_turn_input();
29451
29933
  init_detect();
29452
29934
  init_settings();
29935
+ init_dev_preview();
29453
29936
  init_conductor();
29454
29937
  init_convention_setup();
29455
29938
  init_cursor_worktrees();
@@ -29789,7 +30272,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
29789
30272
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29790
30273
  var import_zod9 = require("zod");
29791
30274
  var import_node_crypto16 = require("crypto");
29792
- var import_node_path57 = require("path");
30275
+ var import_node_path58 = require("path");
29793
30276
  init_orchestrator();
29794
30277
  init_worktree();
29795
30278
  init_global_workspace();
@@ -29823,6 +30306,8 @@ function resolveRunScriptThreadRef(ref) {
29823
30306
  }
29824
30307
 
29825
30308
  // src/mcp/server.ts
30309
+ init_dev_preview();
30310
+ init_instructions();
29826
30311
  init_wait_for_turn();
29827
30312
  init_wait_for_job();
29828
30313
  init_message_parts();
@@ -31526,27 +32011,27 @@ init_gh_errors();
31526
32011
  init_git_auth_mode();
31527
32012
 
31528
32013
  // src/board/load-home-board.ts
31529
- var import_node_fs60 = require("fs");
31530
- var import_node_path56 = require("path");
32014
+ var import_node_fs61 = require("fs");
32015
+ var import_node_path57 = require("path");
31531
32016
  init_worktree();
31532
32017
  init_paths();
31533
32018
 
31534
32019
  // src/board/board-pins.ts
31535
32020
  var import_node_crypto15 = require("crypto");
31536
- var import_node_fs59 = require("fs");
31537
- var import_node_path55 = require("path");
32021
+ var import_node_fs60 = require("fs");
32022
+ var import_node_path56 = require("path");
31538
32023
  init_paths();
31539
32024
  init_home_board();
31540
32025
  var FILE = "home-board-pins.json";
31541
32026
  var VERSION = 1;
31542
32027
  function pinsFile() {
31543
- return (0, import_node_path55.join)(appDataDir(), FILE);
32028
+ return (0, import_node_path56.join)(appDataDir(), FILE);
31544
32029
  }
31545
32030
  function readDisk() {
31546
32031
  const path2 = pinsFile();
31547
- if (!(0, import_node_fs59.existsSync)(path2)) return [];
32032
+ if (!(0, import_node_fs60.existsSync)(path2)) return [];
31548
32033
  try {
31549
- const raw = JSON.parse((0, import_node_fs59.readFileSync)(path2, "utf8"));
32034
+ const raw = JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
31550
32035
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
31551
32036
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
31552
32037
  } catch {
@@ -31554,8 +32039,8 @@ function readDisk() {
31554
32039
  }
31555
32040
  }
31556
32041
  function writeDisk(items) {
31557
- (0, import_node_fs59.mkdirSync)(appDataDir(), { recursive: true });
31558
- (0, import_node_fs59.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
32042
+ (0, import_node_fs60.mkdirSync)(appDataDir(), { recursive: true });
32043
+ (0, import_node_fs60.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
31559
32044
  }
31560
32045
  function listBoardPins() {
31561
32046
  return readDisk();
@@ -31607,7 +32092,7 @@ function replaceBoardPins(items) {
31607
32092
  }
31608
32093
  function clearBoardPins() {
31609
32094
  try {
31610
- (0, import_node_fs59.unlinkSync)(pinsFile());
32095
+ (0, import_node_fs60.unlinkSync)(pinsFile());
31611
32096
  } catch {
31612
32097
  }
31613
32098
  }
@@ -31624,7 +32109,7 @@ function homeBoardWorkspaceKey(workspaces) {
31624
32109
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
31625
32110
  }
31626
32111
  function cacheFile() {
31627
- return (0, import_node_path56.join)(appDataDir(), "home-board-cache.json");
32112
+ return (0, import_node_path57.join)(appDataDir(), "home-board-cache.json");
31628
32113
  }
31629
32114
  function emptyInputs() {
31630
32115
  return {
@@ -31650,9 +32135,9 @@ function shouldCacheHomeBoardInputs(inputs) {
31650
32135
  }
31651
32136
  function readDiskCache() {
31652
32137
  const path2 = cacheFile();
31653
- if (!(0, import_node_fs60.existsSync)(path2)) return null;
32138
+ if (!(0, import_node_fs61.existsSync)(path2)) return null;
31654
32139
  try {
31655
- const raw = JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
32140
+ const raw = JSON.parse((0, import_node_fs61.readFileSync)(path2, "utf8"));
31656
32141
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
31657
32142
  return null;
31658
32143
  }
@@ -31666,14 +32151,14 @@ function readDiskCache() {
31666
32151
  }
31667
32152
  function writeDiskCache(entry) {
31668
32153
  try {
31669
- (0, import_node_fs60.mkdirSync)(appDataDir(), { recursive: true });
31670
- (0, import_node_fs60.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
32154
+ (0, import_node_fs61.mkdirSync)(appDataDir(), { recursive: true });
32155
+ (0, import_node_fs61.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31671
32156
  } catch {
31672
32157
  }
31673
32158
  }
31674
32159
  function deleteDiskCache() {
31675
32160
  try {
31676
- (0, import_node_fs60.unlinkSync)(cacheFile());
32161
+ (0, import_node_fs61.unlinkSync)(cacheFile());
31677
32162
  } catch {
31678
32163
  }
31679
32164
  }
@@ -31957,6 +32442,9 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
31957
32442
  return { ok: false, text: `create_thread failed: ${message}` };
31958
32443
  }
31959
32444
  }
32445
+ function previewHint(preview) {
32446
+ return preview === "window" ? "Electron: the native window is the app. url is the renderer/HMR origin only \u2014 do not open it in a browser (no preload/IPC)." : "Open url in a browser, curl, or Playwright to use the app.";
32447
+ }
31960
32448
  async function startMcpServer() {
31961
32449
  const orch = getOrchestrator();
31962
32450
  try {
@@ -32023,7 +32511,7 @@ async function startMcpServer() {
32023
32511
  async () => {
32024
32512
  const threads = orch.getThreads(true);
32025
32513
  const lines = threads.map((t) => {
32026
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path57.basename)(t.repoPath) || t.repoPath;
32514
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path58.basename)(t.repoPath) || t.repoPath;
32027
32515
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
32028
32516
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
32029
32517
  const preview = lastMessagePreview(t.messages, 80);
@@ -32280,15 +32768,27 @@ async function startMcpServer() {
32280
32768
  );
32281
32769
  server.tool(
32282
32770
  "list_run_scripts",
32283
- "List .sideboard/.conductor run scripts for this thread (same menu as the desktop Dev button) and which are active. Worktree turns may omit ref (uses cwd).",
32771
+ "List .sideboard/.conductor run scripts for this thread (same menu as the desktop Dev button) and which are active. Each script and active run includes preview: url (open http://localhost:<SIDEBOARD_PORT>) or window (Electron: native window is the app; url is renderer/HMR only). Never guess :3000. Worktree turns may omit ref (uses cwd).",
32284
32772
  {
32285
32773
  ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd).")
32286
32774
  },
32287
32775
  async ({ ref }) => {
32288
32776
  try {
32289
32777
  const threadRef = resolveRunScriptThreadRef(ref);
32290
- const scripts = orch.listThreadRunScripts(threadRef);
32291
- const active = orch.getActiveRuns(threadRef);
32778
+ const worktreePath = orch.getThread(threadRef)?.worktreePath ?? "";
32779
+ const scripts = orch.listThreadRunScripts(threadRef).map((script) => ({
32780
+ ...script,
32781
+ preview: runScriptPreview(script, worktreePath)
32782
+ }));
32783
+ const active = orch.getActiveRuns(threadRef).map((run2) => {
32784
+ const preview = activeRunPreview(run2.scriptName, scripts, worktreePath);
32785
+ return {
32786
+ ...run2,
32787
+ url: localhostPreviewUrl(run2.port),
32788
+ preview,
32789
+ hint: previewHint(preview)
32790
+ };
32791
+ });
32292
32792
  return mcpJson({ scripts, active, ref: threadRef });
32293
32793
  } catch (err) {
32294
32794
  const message = err instanceof Error ? err.message : String(err);
@@ -32298,7 +32798,7 @@ async function startMcpServer() {
32298
32798
  );
32299
32799
  server.tool(
32300
32800
  "run_dev_script",
32301
- "Start a .sideboard/.conductor run script (same as the desktop Dev / play button). Logs and Stop appear in the thread UI \u2014 do not detached-job or shell-spawn the same command. Returns the allocated port. Worktree turns may omit ref (uses cwd). Omit name for the default script.",
32801
+ "Start a .sideboard/.conductor run script (same as the desktop Dev / play button). Logs and Stop appear in the thread UI \u2014 do not detached-job or shell-spawn the same command. Returns {port, ports, url, preview}. preview=url \u2192 open url (browser, curl, Playwright). preview=window \u2192 Electron: the native window is the app; url is renderer/HMR only (no preload/IPC in a browser). The port is allocated SIDEBOARD_PORT, not 3000. Worktree turns may omit ref (uses cwd). Omit name for the default script.",
32302
32802
  {
32303
32803
  ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
32304
32804
  name: import_zod9.z.string().optional().describe("Script name from list_run_scripts (default script if omitted).")
@@ -32307,11 +32807,16 @@ async function startMcpServer() {
32307
32807
  try {
32308
32808
  const threadRef = resolveRunScriptThreadRef(ref);
32309
32809
  const result = await orch.startDev(threadRef, name);
32810
+ const worktreePath = orch.getThread(threadRef)?.worktreePath ?? "";
32811
+ const scripts = orch.listThreadRunScripts(threadRef);
32812
+ const preview = activeRunPreview(result.scriptName, scripts, worktreePath);
32310
32813
  return mcpJson({
32311
32814
  port: result.port,
32312
32815
  scriptName: result.scriptName,
32313
32816
  ports: result.ports,
32314
- url: `http://localhost:${result.port}`,
32817
+ url: localhostPreviewUrl(result.port),
32818
+ preview,
32819
+ hint: previewHint(preview),
32315
32820
  ref: threadRef
32316
32821
  });
32317
32822
  } catch (err) {
@@ -35024,9 +35529,9 @@ var import_node_http4 = require("http");
35024
35529
  var import_ws3 = require("ws");
35025
35530
 
35026
35531
  // src/slack/relay-static.ts
35027
- var import_node_fs61 = require("fs");
35532
+ var import_node_fs62 = require("fs");
35028
35533
  var import_promises = require("fs/promises");
35029
- var import_node_path58 = __toESM(require("path"), 1);
35534
+ var import_node_path59 = __toESM(require("path"), 1);
35030
35535
  var TYPES = {
35031
35536
  ".css": "text/css; charset=utf-8",
35032
35537
  ".html": "text/html; charset=utf-8",
@@ -35057,9 +35562,9 @@ function resolveStaticPath(root, requestUrl) {
35057
35562
  return null;
35058
35563
  }
35059
35564
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
35060
- const rootResolved = import_node_path58.default.resolve(root);
35061
- const candidate = import_node_path58.default.resolve(rootResolved, `.${pathname}`);
35062
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path58.default.sep)) {
35565
+ const rootResolved = import_node_path59.default.resolve(root);
35566
+ const candidate = import_node_path59.default.resolve(rootResolved, `.${pathname}`);
35567
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path59.default.sep)) {
35063
35568
  return null;
35064
35569
  }
35065
35570
  return candidate;
@@ -35073,7 +35578,7 @@ async function fileSize(file) {
35073
35578
  }
35074
35579
  }
35075
35580
  function sendFile(req, res, file, size) {
35076
- const ext = import_node_path58.default.extname(file).toLowerCase();
35581
+ const ext = import_node_path59.default.extname(file).toLowerCase();
35077
35582
  res.writeHead(200, {
35078
35583
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
35079
35584
  "Content-Length": size,
@@ -35083,7 +35588,7 @@ function sendFile(req, res, file, size) {
35083
35588
  res.end();
35084
35589
  return true;
35085
35590
  }
35086
- (0, import_node_fs61.createReadStream)(file).pipe(res);
35591
+ (0, import_node_fs62.createReadStream)(file).pipe(res);
35087
35592
  return true;
35088
35593
  }
35089
35594
  async function tryServeStatic(req, res, root) {
@@ -35092,7 +35597,7 @@ async function tryServeStatic(req, res, root) {
35092
35597
  if (!candidate) return false;
35093
35598
  const direct = await fileSize(candidate);
35094
35599
  if (direct != null) return sendFile(req, res, candidate, direct);
35095
- const asIndex = import_node_path58.default.join(candidate, "index.html");
35600
+ const asIndex = import_node_path59.default.join(candidate, "index.html");
35096
35601
  const indexSize = await fileSize(asIndex);
35097
35602
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
35098
35603
  return false;
@@ -35472,6 +35977,7 @@ init_outbound_watch();
35472
35977
  abletimeMcpUrl,
35473
35978
  abletimeToolUsesPm,
35474
35979
  ackSlackInboundSeen,
35980
+ activeRunPreview,
35475
35981
  addBoardPin,
35476
35982
  addPrStackLayer,
35477
35983
  addStackLayerFromThread,
@@ -35487,6 +35993,7 @@ init_outbound_watch();
35487
35993
  allocatePortRange,
35488
35994
  allocateTeamName,
35489
35995
  allocateTeamSlug,
35996
+ annotateDevAccessRuns,
35490
35997
  appDataDir,
35491
35998
  appSettingsPath,
35492
35999
  appendIndexedGitConfig,
@@ -35551,6 +36058,7 @@ init_outbound_watch();
35551
36058
  clampGithubPrBody,
35552
36059
  clampHistoryMaxCount,
35553
36060
  clampHistoryMaxDays,
36061
+ classifyRunScriptPreview,
35554
36062
  classifyWorktreeColumn,
35555
36063
  claudeAdapter,
35556
36064
  claudeChromeEnabled,
@@ -35570,6 +36078,7 @@ init_outbound_watch();
35570
36078
  codexUnattendedGitConfigArgs,
35571
36079
  coerceOrchestratorAgent,
35572
36080
  collectTakenTeamSlugs,
36081
+ commandLooksLikeElectron,
35573
36082
  commentAbleTimeTask,
35574
36083
  commentGitHubIssue,
35575
36084
  commentLinearIssue,
@@ -35692,6 +36201,7 @@ init_outbound_watch();
35692
36201
  formatClaudeUsageResetClock,
35693
36202
  formatClaudeUsageTooltip,
35694
36203
  formatDetachedJobInvoke,
36204
+ formatDevAccessHint,
35695
36205
  formatFetchError,
35696
36206
  formatGhLandError,
35697
36207
  formatGitAuthModeDirective,
@@ -35818,7 +36328,10 @@ init_outbound_watch();
35818
36328
  isBrightsyConnected,
35819
36329
  isBrightsyNdjsonLine,
35820
36330
  isCloudCoordinatorThread,
36331
+ isCompactToolName,
35821
36332
  isConductorBundledCli,
36333
+ isContextCompactDone,
36334
+ isContextCompactInProgress,
35822
36335
  isCowboyThread,
35823
36336
  isCursorApiKeyConfigured,
35824
36337
  isCursorAutoModel,
@@ -35856,6 +36369,7 @@ init_outbound_watch();
35856
36369
  isSetupLastError,
35857
36370
  isShellToolName,
35858
36371
  isSideboardScratchPath,
36372
+ isSkillToolName,
35859
36373
  isSlackCoordinatorThread,
35860
36374
  isSlackExternalReplyPrompt,
35861
36375
  isSlackOAuthCancelled,
@@ -35926,8 +36440,11 @@ init_outbound_watch();
35926
36440
  loadHomeBoardInputs,
35927
36441
  loadRepoSettings,
35928
36442
  loadWorkspaceSettings,
36443
+ localhostPreviewUrl,
35929
36444
  locksDir,
35930
36445
  loginAgent,
36446
+ looksLikeConversationSummary,
36447
+ looksLikeSkillBody,
35931
36448
  lookupSoccerTeam,
35932
36449
  mapAbleTimeTask,
35933
36450
  markPrReady,
@@ -35980,6 +36497,7 @@ init_outbound_watch();
35980
36497
  parseAbleTimeOAuthCallbackUrl,
35981
36498
  parseClaudeUsagePayload,
35982
36499
  parseCursorRunnerLine,
36500
+ parseDevPreview,
35983
36501
  parseDurationMs,
35984
36502
  parseForceStopMessage,
35985
36503
  parseGhStackViewJson,
@@ -36001,6 +36519,7 @@ init_outbound_watch();
36001
36519
  planHistoryAgePurge,
36002
36520
  planHistoryRetention,
36003
36521
  planQuestionsSignature,
36522
+ pnpmFilterPackage,
36004
36523
  pollSlackOutboundWatches,
36005
36524
  posixShellSingleQuote,
36006
36525
  preferredCursorCostCents,
@@ -36098,6 +36617,7 @@ init_outbound_watch();
36098
36617
  runCloudConnect,
36099
36618
  runConventionSetup,
36100
36619
  runCursorWorktreeSetup,
36620
+ runScriptPreview,
36101
36621
  runSetupScript,
36102
36622
  runSlackListen,
36103
36623
  runSlackRelayClient,
@@ -36132,6 +36652,9 @@ init_outbound_watch();
36132
36652
  sideboardMcpProfile,
36133
36653
  sideboardReposDir,
36134
36654
  sideboardWorkspacesDir,
36655
+ skillCommandFromBody,
36656
+ skillCommandFromInput,
36657
+ skillNameFromFrontmatter,
36135
36658
  slackAppLevelToken,
36136
36659
  slackArchiveUrl,
36137
36660
  slackCoordinatorSourceRef,