@sideboard-ai/core 0.1.235 → 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-37JCAVSC.js → agents-JC6DRIT3.js} +9 -9
  10. package/dist/{agents-MOMMKSYV.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-LJWF3VA3.js → chunk-6Q2CFQ4D.js} +74 -30
  23. package/dist/{chunk-WFUDY6PC.js → chunk-A4JGXX2F.js} +155 -24
  24. package/dist/{chunk-EAYXD2IC.js → chunk-ANGPU5JL.js} +282 -14
  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-D4VKJO5C.js → chunk-DYXNBXE3.js} +304 -16
  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-7366AB7E.js → chunk-XMCJDWPA.js} +77 -32
  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 +1219 -707
  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 +1123 -659
  56. package/dist/mcp/run-stdio.js +45 -22
  57. package/dist/{orchestrator-6NPBOBNA.js → orchestrator-AYPDBGIF.js} +10 -10
  58. package/dist/{orchestrator-RKWRI3PJ.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();
@@ -15604,7 +16014,7 @@ async function installNpmGlobalPackage(opts) {
15604
16014
  async function resolveExistingCli(agent) {
15605
16015
  if (agent === "cursor") return null;
15606
16016
  const exe = resolveAgentExecutable(agent);
15607
- 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;
15608
16018
  enrichPathWithNpmGlobalBin();
15609
16019
  return whichOnPath(CLI_BIN[agent]);
15610
16020
  }
@@ -15677,11 +16087,11 @@ async function loginAgent(agent) {
15677
16087
  message: `Opened Terminal to run: ${prepared}`
15678
16088
  };
15679
16089
  }
15680
- var import_node_fs41, SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
16090
+ var import_node_fs42, SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
15681
16091
  var init_install = __esm({
15682
16092
  "src/agents/install.ts"() {
15683
16093
  "use strict";
15684
- import_node_fs41 = require("fs");
16094
+ import_node_fs42 = require("fs");
15685
16095
  init_run();
15686
16096
  init_app_settings();
15687
16097
  init_path();
@@ -15869,7 +16279,7 @@ function isAgentHostEnvKey(key) {
15869
16279
  }
15870
16280
  function stripHostToolingPath(pathValue) {
15871
16281
  if (!pathValue?.trim()) return "";
15872
- 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);
15873
16283
  }
15874
16284
  function sanitizeAgentHostEnv(env, cwd) {
15875
16285
  for (const key of Object.keys(env)) {
@@ -15883,11 +16293,11 @@ function sanitizeAgentHostEnv(env, cwd) {
15883
16293
  }
15884
16294
  return env;
15885
16295
  }
15886
- var import_node_path42, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
16296
+ var import_node_path43, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15887
16297
  var init_agent_host_env = __esm({
15888
16298
  "src/hook/agent-host-env.ts"() {
15889
16299
  "use strict";
15890
- import_node_path42 = require("path");
16300
+ import_node_path43 = require("path");
15891
16301
  DROP_EXACT = /* @__PURE__ */ new Set([
15892
16302
  "NODE_PATH",
15893
16303
  "NODE_ENV_ELECTRON_VITE",
@@ -15926,15 +16336,15 @@ var init_agent_host_env = __esm({
15926
16336
 
15927
16337
  // src/hook/worktree-pkg-cache.ts
15928
16338
  function worktreePkgCacheRoot(worktreePath) {
15929
- return (0, import_node_path43.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
16339
+ return (0, import_node_path44.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15930
16340
  }
15931
16341
  function worktreePkgCacheEnv(worktreePath) {
15932
16342
  const root = worktreePkgCacheRoot(worktreePath);
15933
- const store = (0, import_node_path43.join)(root, "pnpm-store");
15934
- const pnpmCache = (0, import_node_path43.join)(root, "pnpm");
15935
- const npmCache = (0, import_node_path43.join)(root, "npm");
15936
- const nodeGyp = (0, import_node_path43.join)(root, "node-gyp");
15937
- 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");
15938
16348
  return {
15939
16349
  npm_config_store_dir: store,
15940
16350
  PNPM_STORE_DIR: store,
@@ -15956,8 +16366,8 @@ function fillGroup(env, keys, values) {
15956
16366
  }
15957
16367
  }
15958
16368
  function ensureWorktreePkgCacheDirs(worktreePath) {
15959
- if (!(0, import_node_fs42.existsSync)(worktreePath)) return;
15960
- (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 });
15961
16371
  }
15962
16372
  function applyWorktreePkgCacheEnv(env, worktreePath) {
15963
16373
  const cwd = worktreePath.trim();
@@ -15970,12 +16380,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15970
16380
  fillGroup(env, ["electron_config_cache"], next);
15971
16381
  ensureWorktreePkgCacheDirs(cwd);
15972
16382
  }
15973
- var import_node_fs42, import_node_path43, WORKTREE_PKG_CACHE_REL;
16383
+ var import_node_fs43, import_node_path44, WORKTREE_PKG_CACHE_REL;
15974
16384
  var init_worktree_pkg_cache = __esm({
15975
16385
  "src/hook/worktree-pkg-cache.ts"() {
15976
16386
  "use strict";
15977
- import_node_fs42 = require("fs");
15978
- import_node_path43 = require("path");
16387
+ import_node_fs43 = require("fs");
16388
+ import_node_path44 = require("path");
15979
16389
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15980
16390
  }
15981
16391
  });
@@ -17216,21 +17626,21 @@ function shouldRefreshReviewRequestTemplate(content) {
17216
17626
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
17217
17627
  }
17218
17628
  function readTextIfPresent(abs) {
17219
- if (!(0, import_node_fs43.existsSync)(abs)) return null;
17629
+ if (!(0, import_node_fs44.existsSync)(abs)) return null;
17220
17630
  try {
17221
- const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
17631
+ const content = (0, import_node_fs44.readFileSync)(abs, "utf8");
17222
17632
  return content.trim() ? content : null;
17223
17633
  } catch {
17224
17634
  return null;
17225
17635
  }
17226
17636
  }
17227
17637
  function readLocalGuidelines(worktreePath) {
17228
- const localAbs = (0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH);
17638
+ const localAbs = (0, import_node_path45.join)(worktreePath, REVIEW_REQUEST_PATH);
17229
17639
  const localContent = readTextIfPresent(localAbs);
17230
17640
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
17231
17641
  return { path: REVIEW_REQUEST_PATH, content: localContent };
17232
17642
  }
17233
- 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);
17234
17644
  const legacyContent = readTextIfPresent(legacyAbs);
17235
17645
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
17236
17646
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -17254,27 +17664,27 @@ function contextGuidelines(content, source) {
17254
17664
  };
17255
17665
  }
17256
17666
  function writeContextGuidelines(worktreePath, content) {
17257
- const abs = (0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH);
17258
- (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 });
17259
17669
  const body = content.endsWith("\n") ? content : `${content}
17260
17670
  `;
17261
- (0, import_node_fs43.writeFileSync)(abs, body, "utf8");
17671
+ (0, import_node_fs44.writeFileSync)(abs, body, "utf8");
17262
17672
  return body;
17263
17673
  }
17264
17674
  function readSideboardReview(worktreePath, repoPath) {
17265
- 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));
17266
17676
  if (fromWorktree) return fromWorktree;
17267
17677
  const repo = repoPath?.replace(/\/+$/, "");
17268
17678
  const wt = worktreePath.replace(/\/+$/, "");
17269
17679
  if (!repo || repo === wt) return null;
17270
- return readTextIfPresent((0, import_node_path44.join)(repo, REPO_REVIEW_PATH));
17680
+ return readTextIfPresent((0, import_node_path45.join)(repo, REPO_REVIEW_PATH));
17271
17681
  }
17272
17682
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
17273
- 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));
17274
17684
  if (skillContent) {
17275
17685
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
17276
17686
  }
17277
- 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));
17278
17688
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
17279
17689
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
17280
17690
  }
@@ -17312,7 +17722,7 @@ function buildReviewRequestAttachment(content, opts) {
17312
17722
  };
17313
17723
  }
17314
17724
  function readExistingReviewRequestFile(worktreePath) {
17315
- 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));
17316
17726
  }
17317
17727
  async function requestReview(threadRef, send2) {
17318
17728
  const from = findThreadByRef(threadRef);
@@ -17339,13 +17749,13 @@ async function requestReview(threadRef, send2) {
17339
17749
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
17340
17750
  return { tab: started, from };
17341
17751
  }
17342
- 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;
17343
17753
  var init_request_review = __esm({
17344
17754
  "src/review/request-review.ts"() {
17345
17755
  "use strict";
17346
17756
  import_node_crypto9 = require("crypto");
17347
- import_node_fs43 = require("fs");
17348
- import_node_path44 = require("path");
17757
+ import_node_fs44 = require("fs");
17758
+ import_node_path45 = require("path");
17349
17759
  init_global_workspace();
17350
17760
  init_chat_tabs();
17351
17761
  init_thread_store();
@@ -17371,9 +17781,9 @@ function matchSimpleGlob(pattern, name) {
17371
17781
  return new RegExp(`^${escaped}$`).test(name);
17372
17782
  }
17373
17783
  function readWorktreeInclude(repoPath) {
17374
- const path2 = (0, import_node_path45.join)(repoPath, ".worktreeinclude");
17375
- if (!(0, import_node_fs44.existsSync)(path2)) return [];
17376
- 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("#"));
17377
17787
  }
17378
17788
  function resolveFilesToCopy(repoPath) {
17379
17789
  const fromInclude = readWorktreeInclude(repoPath);
@@ -17383,10 +17793,10 @@ function resolveFilesToCopy(repoPath) {
17383
17793
  if (settings?.fileIncludeGlobs?.length) {
17384
17794
  const matched = [];
17385
17795
  try {
17386
- 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 })) {
17387
17797
  if (!entry.isFile()) continue;
17388
17798
  for (const glob of settings.fileIncludeGlobs) {
17389
- 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)) {
17390
17800
  matched.push(entry.name);
17391
17801
  break;
17392
17802
  }
@@ -17398,7 +17808,7 @@ function resolveFilesToCopy(repoPath) {
17398
17808
  }
17399
17809
  const defaults = [];
17400
17810
  try {
17401
- 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 })) {
17402
17812
  if (entry.isFile() && entry.name.startsWith(".env")) {
17403
17813
  defaults.push(entry.name);
17404
17814
  }
@@ -17412,11 +17822,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
17412
17822
  const patterns = resolveFilesToCopy(repoPath);
17413
17823
  const copied = [];
17414
17824
  for (const rel of patterns) {
17415
- const src = (0, import_node_path45.join)(repoPath, rel);
17416
- if (!(0, import_node_fs44.existsSync)(src)) continue;
17417
- const dest = (0, import_node_path45.join)(worktreePath, rel);
17418
- (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
17419
- (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);
17420
17830
  copied.push(rel);
17421
17831
  }
17422
17832
  return copied;
@@ -17451,7 +17861,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
17451
17861
  const env = stripNestedElectronEnv({
17452
17862
  ...baseEnv ?? process.env
17453
17863
  });
17454
- const name = opts.workspaceName ?? (0, import_node_path45.basename)(opts.worktreePath);
17864
+ const name = opts.workspaceName ?? (0, import_node_path46.basename)(opts.worktreePath);
17455
17865
  const ports = opts.ports ?? [];
17456
17866
  const primary = ports[0];
17457
17867
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -17786,14 +18196,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
17786
18196
  throw err;
17787
18197
  }
17788
18198
  }
17789
- 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;
17790
18200
  var init_conductor = __esm({
17791
18201
  "src/hook/conductor.ts"() {
17792
18202
  "use strict";
17793
- import_node_fs44 = require("fs");
18203
+ import_node_fs45 = require("fs");
17794
18204
  import_node_child_process5 = require("child_process");
17795
18205
  import_node_net = require("net");
17796
- import_node_path45 = require("path");
18206
+ import_node_path46 = require("path");
17797
18207
  import_execa4 = require("execa");
17798
18208
  import_node_readline3 = require("readline");
17799
18209
  init_settings();
@@ -17821,9 +18231,9 @@ async function findOrphanWorktrees(repoPaths) {
17821
18231
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17822
18232
  );
17823
18233
  const homeRoot = sideboardWorkspacesDir();
17824
- if ((0, import_node_fs45.existsSync)(homeRoot)) {
18234
+ if ((0, import_node_fs46.existsSync)(homeRoot)) {
17825
18235
  try {
17826
- 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 })) {
17827
18237
  if (!entry.isDirectory()) continue;
17828
18238
  void entry;
17829
18239
  }
@@ -17833,7 +18243,7 @@ async function findOrphanWorktrees(repoPaths) {
17833
18243
  const orphans = [];
17834
18244
  const seen = /* @__PURE__ */ new Set();
17835
18245
  for (const repoPath of repos) {
17836
- if (!repoPath || !(0, import_node_fs45.existsSync)(repoPath)) continue;
18246
+ if (!repoPath || !(0, import_node_fs46.existsSync)(repoPath)) continue;
17837
18247
  try {
17838
18248
  const wts = await listWorktrees(repoPath);
17839
18249
  for (const wt of wts) {
@@ -17844,7 +18254,7 @@ async function findOrphanWorktrees(repoPaths) {
17844
18254
  seen.add(path2);
17845
18255
  let mtimeMs = 0;
17846
18256
  try {
17847
- mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
18257
+ mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
17848
18258
  } catch {
17849
18259
  mtimeMs = 0;
17850
18260
  }
@@ -17854,16 +18264,16 @@ async function findOrphanWorktrees(repoPaths) {
17854
18264
  }
17855
18265
  try {
17856
18266
  const root = worktreesRoot(repoPath);
17857
- if ((0, import_node_fs45.existsSync)(root)) {
17858
- 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 })) {
17859
18269
  if (!entry.isDirectory()) continue;
17860
- const path2 = (0, import_node_path46.join)(root, entry.name).replace(/\/$/, "");
18270
+ const path2 = (0, import_node_path47.join)(root, entry.name).replace(/\/$/, "");
17861
18271
  if (known.has(path2) || seen.has(path2)) continue;
17862
- 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;
17863
18273
  seen.add(path2);
17864
18274
  let mtimeMs = 0;
17865
18275
  try {
17866
- mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
18276
+ mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
17867
18277
  } catch {
17868
18278
  mtimeMs = Date.now();
17869
18279
  }
@@ -17924,12 +18334,12 @@ function worktreeCleanupSettings() {
17924
18334
  autoCleanupOrphans: a.autoCleanupOrphans
17925
18335
  };
17926
18336
  }
17927
- var import_node_fs45, import_node_path46;
18337
+ var import_node_fs46, import_node_path47;
17928
18338
  var init_orphan_cleanup = __esm({
17929
18339
  "src/git/orphan-cleanup.ts"() {
17930
18340
  "use strict";
17931
- import_node_fs45 = require("fs");
17932
- import_node_path46 = require("path");
18341
+ import_node_fs46 = require("fs");
18342
+ import_node_path47 = require("path");
17933
18343
  init_worktree();
17934
18344
  init_thread_store();
17935
18345
  init_paths();
@@ -18104,12 +18514,12 @@ async function cloneRepoIntoSideboard(opts) {
18104
18514
  if (!url) throw new Error("Clone URL is required");
18105
18515
  let name = opts.name?.trim();
18106
18516
  if (!name) {
18107
- const leaf = (0, import_node_path47.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18517
+ const leaf = (0, import_node_path48.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18108
18518
  name = leaf || "repo";
18109
18519
  }
18110
18520
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
18111
- const dest = (0, import_node_path47.join)(sideboardReposDir(), name);
18112
- 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)) {
18113
18523
  const repoPath2 = await resolveRepoRoot(dest);
18114
18524
  const workspace2 = await ensureWorkspace(repoPath2);
18115
18525
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -18124,12 +18534,12 @@ async function cloneRepoIntoSideboard(opts) {
18124
18534
  const workspace = await ensureWorkspace(repoPath);
18125
18535
  return { repoPath, workspace };
18126
18536
  }
18127
- var import_node_fs46, import_node_path47, import_execa6;
18537
+ var import_node_fs47, import_node_path48, import_execa6;
18128
18538
  var init_clone_repo = __esm({
18129
18539
  "src/git/clone-repo.ts"() {
18130
18540
  "use strict";
18131
- import_node_fs46 = require("fs");
18132
- import_node_path47 = require("path");
18541
+ import_node_fs47 = require("fs");
18542
+ import_node_path48 = require("path");
18133
18543
  import_execa6 = require("execa");
18134
18544
  init_paths();
18135
18545
  init_workspaces();
@@ -18250,24 +18660,24 @@ function jobTreeAlive(pid) {
18250
18660
  return jobAlive(pid) || processGroupAlive(pid);
18251
18661
  }
18252
18662
  function readIntFile(file) {
18253
- if (!(0, import_node_fs47.existsSync)(file)) return null;
18254
- 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);
18255
18665
  return Number.isInteger(n) ? n : null;
18256
18666
  }
18257
18667
  function jobDir(root, id, legacy = false) {
18258
- 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);
18259
18669
  }
18260
18670
  function resolveJobDir(root, id) {
18261
18671
  const modern = jobDir(root, id, false);
18262
- if ((0, import_node_fs47.existsSync)(modern)) return modern;
18672
+ if ((0, import_node_fs48.existsSync)(modern)) return modern;
18263
18673
  const legacy = jobDir(root, id, true);
18264
- if ((0, import_node_fs47.existsSync)(legacy)) return legacy;
18674
+ if ((0, import_node_fs48.existsSync)(legacy)) return legacy;
18265
18675
  return modern;
18266
18676
  }
18267
18677
  function listJobIdsIn(root, rel) {
18268
- const dir = (0, import_node_path48.join)(root, rel);
18269
- if (!(0, import_node_fs47.existsSync)(dir)) return [];
18270
- 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);
18271
18681
  }
18272
18682
  function listRunningDetachedJobs(worktreePath) {
18273
18683
  const root = worktreePath.trim();
@@ -18279,7 +18689,7 @@ function listRunningDetachedJobs(worktreePath) {
18279
18689
  const running = [];
18280
18690
  for (const id of ids) {
18281
18691
  const dir = resolveJobDir(root, id);
18282
- const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18692
+ const pid = readIntFile((0, import_node_path49.join)(dir, "pid"));
18283
18693
  if (jobTreeAlive(pid)) running.push(id);
18284
18694
  }
18285
18695
  return running.sort();
@@ -18362,8 +18772,8 @@ function planJobContinue(opts) {
18362
18772
  return { action: "none" };
18363
18773
  }
18364
18774
  function tailProgress(logFile, maxLines = 12) {
18365
- if (!(0, import_node_fs47.existsSync)(logFile)) return "(no log yet)";
18366
- 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");
18367
18777
  return lines.slice(-maxLines).join("\n");
18368
18778
  }
18369
18779
  function lastProgressLine(progress) {
@@ -18371,8 +18781,8 @@ function lastProgressLine(progress) {
18371
18781
  return last ? last.slice(0, 72) : void 0;
18372
18782
  }
18373
18783
  function readLogLines(file) {
18374
- if (!(0, import_node_fs47.existsSync)(file)) return [];
18375
- 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");
18376
18786
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
18377
18787
  return lines;
18378
18788
  }
@@ -18383,15 +18793,15 @@ function takeDelta(logFile, cursorFile) {
18383
18793
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
18384
18794
  }
18385
18795
  function snapshotJob(dir) {
18386
- const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18796
+ const pid = readIntFile((0, import_node_path49.join)(dir, "pid"));
18387
18797
  const running = jobTreeAlive(pid);
18388
18798
  return {
18389
18799
  pid,
18390
18800
  running,
18391
- exitCode: readIntFile((0, import_node_path48.join)(dir, "exit")),
18392
- log: (0, import_node_path48.join)(dir, "log"),
18393
- cursor: (0, import_node_path48.join)(dir, "present.cursor"),
18394
- 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"))
18395
18805
  };
18396
18806
  }
18397
18807
  function toResult(id, snap, extra) {
@@ -18400,8 +18810,8 @@ function toResult(id, snap, extra) {
18400
18810
  const stillRunning = snap.running && !ok;
18401
18811
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
18402
18812
  try {
18403
- (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(snap.cursor), { recursive: true });
18404
- (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}
18405
18815
  `);
18406
18816
  } catch {
18407
18817
  }
@@ -18430,7 +18840,7 @@ async function waitForDetachedJob(cwd, id, opts) {
18430
18840
  const dir = resolveJobDir(root, jobId);
18431
18841
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
18432
18842
  const sleep2 = opts?.sleep ?? sleepMs;
18433
- if (!(0, import_node_fs47.existsSync)(dir)) {
18843
+ if (!(0, import_node_fs48.existsSync)(dir)) {
18434
18844
  return {
18435
18845
  stillRunning: false,
18436
18846
  ok: false,
@@ -18476,10 +18886,10 @@ function killProcessTree(pid, signal) {
18476
18886
  }
18477
18887
  function appendJobLog(logFile, line) {
18478
18888
  try {
18479
- (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 });
18480
18890
  const body = line.endsWith("\n") ? line : `${line}
18481
18891
  `;
18482
- (0, import_node_fs47.appendFileSync)(logFile, body);
18892
+ (0, import_node_fs48.appendFileSync)(logFile, body);
18483
18893
  } catch {
18484
18894
  }
18485
18895
  }
@@ -18489,7 +18899,7 @@ async function stopDetachedJob(cwd, id, opts) {
18489
18899
  const dir = resolveJobDir(root, jobId);
18490
18900
  const sleep2 = opts?.sleep ?? sleepMs;
18491
18901
  const why = opts?.reason?.trim() ?? "";
18492
- if (!(0, import_node_fs47.existsSync)(dir)) {
18902
+ if (!(0, import_node_fs48.existsSync)(dir)) {
18493
18903
  return {
18494
18904
  stillRunning: false,
18495
18905
  ok: false,
@@ -18525,10 +18935,10 @@ async function stopDetachedJob(cwd, id, opts) {
18525
18935
  killProcessTree(targetPid, "SIGKILL");
18526
18936
  await sleep2(100);
18527
18937
  }
18528
- const exitFile = (0, import_node_path48.join)(dir, "exit");
18529
- 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)) {
18530
18940
  try {
18531
- (0, import_node_fs47.writeFileSync)(exitFile, "1\n");
18941
+ (0, import_node_fs48.writeFileSync)(exitFile, "1\n");
18532
18942
  } catch {
18533
18943
  }
18534
18944
  }
@@ -18548,12 +18958,12 @@ async function stopDetachedJob(cwd, id, opts) {
18548
18958
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
18549
18959
  };
18550
18960
  }
18551
- 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;
18552
18962
  var init_wait_for_job = __esm({
18553
18963
  "src/mcp/wait-for-job.ts"() {
18554
18964
  "use strict";
18555
- import_node_fs47 = require("fs");
18556
- import_node_path48 = require("path");
18965
+ import_node_fs48 = require("fs");
18966
+ import_node_path49 = require("path");
18557
18967
  init_workspace_scratch();
18558
18968
  init_wait_for_turn();
18559
18969
  MAX_JOB_CONTINUES = 8;
@@ -20098,7 +20508,7 @@ function reuseLiveThread(input, repoPath, match) {
20098
20508
  }
20099
20509
  async function createThread(input, _onSetupLine) {
20100
20510
  const repoPath = await resolveRepoRoot(input.repoPath);
20101
- if (!(0, import_node_fs48.existsSync)(repoPath)) {
20511
+ if (!(0, import_node_fs49.existsSync)(repoPath)) {
20102
20512
  throw new Error(`Repo not found: ${repoPath}`);
20103
20513
  }
20104
20514
  const reused = reuseLiveThread(input, repoPath, {
@@ -20283,11 +20693,11 @@ async function listLinearIssues(agent, repoPath) {
20283
20693
  }
20284
20694
  return adapter.listLinearIssues(repoPath);
20285
20695
  }
20286
- var import_node_fs48;
20696
+ var import_node_fs49;
20287
20697
  var init_create = __esm({
20288
20698
  "src/threads/create.ts"() {
20289
20699
  "use strict";
20290
- import_node_fs48 = require("fs");
20700
+ import_node_fs49 = require("fs");
20291
20701
  init_detect();
20292
20702
  init_worktree();
20293
20703
  init_home_board();
@@ -20439,20 +20849,20 @@ function writeTurnLive(threadId, progress) {
20439
20849
  const path2 = threadLivePath(threadId);
20440
20850
  const tmp = `${path2}.${process.pid}.tmp`;
20441
20851
  try {
20442
- (0, import_node_fs49.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20443
- (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);
20444
20854
  } catch {
20445
20855
  try {
20446
- (0, import_node_fs49.unlinkSync)(tmp);
20856
+ (0, import_node_fs50.unlinkSync)(tmp);
20447
20857
  } catch {
20448
20858
  }
20449
20859
  }
20450
20860
  }
20451
20861
  function readTurnLive(threadId) {
20452
20862
  const path2 = threadLivePath(threadId);
20453
- if (!(0, import_node_fs49.existsSync)(path2)) return null;
20863
+ if (!(0, import_node_fs50.existsSync)(path2)) return null;
20454
20864
  try {
20455
- const raw = JSON.parse((0, import_node_fs49.readFileSync)(path2, "utf8"));
20865
+ const raw = JSON.parse((0, import_node_fs50.readFileSync)(path2, "utf8"));
20456
20866
  if (!raw || typeof raw.summary !== "string") return null;
20457
20867
  return raw;
20458
20868
  } catch {
@@ -20464,17 +20874,17 @@ function clearTurnLive(threadId) {
20464
20874
  if (buf?.timer) clearTimeout(buf.timer);
20465
20875
  buffers.delete(threadId);
20466
20876
  const path2 = threadLivePath(threadId);
20467
- if (!(0, import_node_fs49.existsSync)(path2)) return;
20877
+ if (!(0, import_node_fs50.existsSync)(path2)) return;
20468
20878
  try {
20469
- (0, import_node_fs49.unlinkSync)(path2);
20879
+ (0, import_node_fs50.unlinkSync)(path2);
20470
20880
  } catch {
20471
20881
  }
20472
20882
  }
20473
- var import_node_fs49, buffers, FLUSH_MS, MAX_PARTS;
20883
+ var import_node_fs50, buffers, FLUSH_MS, MAX_PARTS;
20474
20884
  var init_turn_live = __esm({
20475
20885
  "src/store/turn-live.ts"() {
20476
20886
  "use strict";
20477
- import_node_fs49 = require("fs");
20887
+ import_node_fs50 = require("fs");
20478
20888
  init_message_parts();
20479
20889
  init_paths();
20480
20890
  buffers = /* @__PURE__ */ new Map();
@@ -20718,7 +21128,7 @@ var init_quota_failover = __esm({
20718
21128
  // src/threads/adopt.ts
20719
21129
  function thisModuleFile2() {
20720
21130
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
20721
- 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");
20722
21132
  }
20723
21133
  function openReadonlySqlite(file) {
20724
21134
  const req = (0, import_node_module5.createRequire)(thisModuleFile2());
@@ -20736,21 +21146,21 @@ function mapAgentType(raw) {
20736
21146
  return null;
20737
21147
  }
20738
21148
  function resolveConductorCursorAgentId(workspacePath) {
20739
- 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;
20740
21150
  const normalized = workspacePath.replace(/\/$/, "");
20741
21151
  let best = null;
20742
21152
  let hashes;
20743
21153
  try {
20744
- hashes = (0, import_node_fs50.readdirSync)(CURSOR_SDK_STORE);
21154
+ hashes = (0, import_node_fs51.readdirSync)(CURSOR_SDK_STORE);
20745
21155
  } catch {
20746
21156
  return null;
20747
21157
  }
20748
21158
  for (const hash of hashes) {
20749
- const agentsFile = (0, import_node_path49.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20750
- 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;
20751
21161
  let text7;
20752
21162
  try {
20753
- text7 = (0, import_node_fs50.readFileSync)(agentsFile, "utf8");
21163
+ text7 = (0, import_node_fs51.readFileSync)(agentsFile, "utf8");
20754
21164
  } catch {
20755
21165
  continue;
20756
21166
  }
@@ -20774,7 +21184,7 @@ function resolveConductorCursorAgentId(workspacePath) {
20774
21184
  return best?.agentId ?? null;
20775
21185
  }
20776
21186
  async function adoptThread(input) {
20777
- if (!(0, import_node_fs50.existsSync)(input.worktreePath)) {
21187
+ if (!(0, import_node_fs51.existsSync)(input.worktreePath)) {
20778
21188
  throw new Error(`Worktree not found: ${input.worktreePath}`);
20779
21189
  }
20780
21190
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -20803,18 +21213,18 @@ function conductorDbPath() {
20803
21213
  return CONDUCTOR_DB;
20804
21214
  }
20805
21215
  function listConductorWorkspaces() {
20806
- if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
21216
+ if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
20807
21217
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20808
21218
  }
20809
- const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20810
- 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");
20811
21221
  try {
20812
- (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
21222
+ (0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
20813
21223
  for (const suffix of ["-wal", "-shm"]) {
20814
21224
  const src = `${CONDUCTOR_DB}${suffix}`;
20815
- if ((0, import_node_fs50.existsSync)(src)) {
21225
+ if ((0, import_node_fs51.existsSync)(src)) {
20816
21226
  try {
20817
- (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
21227
+ (0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
20818
21228
  } catch {
20819
21229
  }
20820
21230
  }
@@ -20890,22 +21300,22 @@ function listConductorWorkspaces() {
20890
21300
  db.close();
20891
21301
  }
20892
21302
  } finally {
20893
- (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
21303
+ (0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
20894
21304
  }
20895
21305
  }
20896
21306
  function importConductorWorkspace(workspaceId) {
20897
- if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
21307
+ if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
20898
21308
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20899
21309
  }
20900
- const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20901
- 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");
20902
21312
  try {
20903
- (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
21313
+ (0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
20904
21314
  for (const suffix of ["-wal", "-shm"]) {
20905
21315
  const src = `${CONDUCTOR_DB}${suffix}`;
20906
- if ((0, import_node_fs50.existsSync)(src)) {
21316
+ if ((0, import_node_fs51.existsSync)(src)) {
20907
21317
  try {
20908
- (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
21318
+ (0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
20909
21319
  } catch {
20910
21320
  }
20911
21321
  }
@@ -20923,7 +21333,7 @@ function importConductorWorkspace(workspaceId) {
20923
21333
  ).get(workspaceId);
20924
21334
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
20925
21335
  const worktreePath = String(row.workspacePath);
20926
- if (!(0, import_node_fs50.existsSync)(worktreePath)) {
21336
+ if (!(0, import_node_fs51.existsSync)(worktreePath)) {
20927
21337
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
20928
21338
  }
20929
21339
  let sessionId = null;
@@ -20986,31 +21396,31 @@ function importConductorWorkspace(workspaceId) {
20986
21396
  db.close();
20987
21397
  }
20988
21398
  } finally {
20989
- (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
21399
+ (0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
20990
21400
  }
20991
21401
  }
20992
21402
  async function importConductorWorkspaceAsync(workspaceId) {
20993
21403
  return importConductorWorkspace(workspaceId);
20994
21404
  }
20995
- 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;
20996
21406
  var init_adopt = __esm({
20997
21407
  "src/threads/adopt.ts"() {
20998
21408
  "use strict";
20999
21409
  import_node_child_process6 = require("child_process");
21000
- import_node_fs50 = require("fs");
21410
+ import_node_fs51 = require("fs");
21001
21411
  import_node_os14 = require("os");
21002
- import_node_path49 = require("path");
21412
+ import_node_path50 = require("path");
21003
21413
  import_node_module5 = require("module");
21004
21414
  init_worktree();
21005
21415
  init_thread_store();
21006
- CONDUCTOR_APP_SUPPORT = (0, import_node_path49.join)(
21416
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path50.join)(
21007
21417
  process.env.HOME ?? "",
21008
21418
  "Library",
21009
21419
  "Application Support",
21010
21420
  "com.conductor.app"
21011
21421
  );
21012
- CONDUCTOR_DB = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
21013
- 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");
21014
21424
  }
21015
21425
  });
21016
21426
 
@@ -21077,7 +21487,7 @@ async function openStackLayer(input, _onSetupLine) {
21077
21487
  let createdWorktree = false;
21078
21488
  const trees = await listWorktrees(repoPath);
21079
21489
  const checkedOut = trees.find((w) => w.branch === branchName);
21080
- if (checkedOut?.path && (0, import_node_fs51.existsSync)(checkedOut.path)) {
21490
+ if (checkedOut?.path && (0, import_node_fs52.existsSync)(checkedOut.path)) {
21081
21491
  if (input.reuseExistingWorktree !== false) {
21082
21492
  worktreePath = checkedOut.path;
21083
21493
  } else {
@@ -21219,7 +21629,7 @@ async function initStackFromThread(input, onSetupLine) {
21219
21629
  async function createPrStack(input, onSetupLine) {
21220
21630
  await requireAgent(input.agent);
21221
21631
  const repoPath = await resolveRepoRoot(input.repoPath);
21222
- 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}`);
21223
21633
  if (!input.branches.length) throw new Error("At least one branch name required");
21224
21634
  const status = await detectGhStack(repoPath);
21225
21635
  if (!status.available) throw new Error(status.reason);
@@ -21286,7 +21696,7 @@ async function createPrStack(input, onSetupLine) {
21286
21696
  }
21287
21697
  }
21288
21698
  const claimed = new Set(threads.map((t) => t.worktreePath));
21289
- 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)) {
21290
21700
  try {
21291
21701
  await removeWorktree(repoPath, bootstrap.worktreePath, {
21292
21702
  deleteBranch: bootstrap.branchName
@@ -21306,11 +21716,11 @@ function stackAgentDefaultsFrom(input) {
21306
21716
  planMode: input.planMode
21307
21717
  };
21308
21718
  }
21309
- var import_node_fs51;
21719
+ var import_node_fs52;
21310
21720
  var init_stack_layers = __esm({
21311
21721
  "src/threads/stack-layers.ts"() {
21312
21722
  "use strict";
21313
- import_node_fs51 = require("fs");
21723
+ import_node_fs52 = require("fs");
21314
21724
  init_detect();
21315
21725
  init_run();
21316
21726
  init_stack();
@@ -21323,7 +21733,7 @@ var init_stack_layers = __esm({
21323
21733
 
21324
21734
  // src/diff/diff.ts
21325
21735
  async function inspectGitWorktree(worktreePath) {
21326
- if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) return "missing_worktree";
21736
+ if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) return "missing_worktree";
21327
21737
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
21328
21738
  reject: false
21329
21739
  });
@@ -21331,7 +21741,7 @@ async function inspectGitWorktree(worktreePath) {
21331
21741
  return "ok";
21332
21742
  }
21333
21743
  async function initializeGitRepository(worktreePath) {
21334
- if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) {
21744
+ if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) {
21335
21745
  throw new Error("Worktree not found");
21336
21746
  }
21337
21747
  const status = await inspectGitWorktree(worktreePath);
@@ -21465,11 +21875,11 @@ new file mode 100644
21465
21875
  };
21466
21876
  }
21467
21877
  async function untrackedPatch(worktreePath, path2, maxHunk) {
21468
- const abs = (0, import_node_path50.join)(worktreePath, path2);
21878
+ const abs = (0, import_node_path51.join)(worktreePath, path2);
21469
21879
  try {
21470
- const st = (0, import_node_fs52.statSync)(abs);
21880
+ const st = (0, import_node_fs53.statSync)(abs);
21471
21881
  if (st.isFile() && st.size > maxHunk) {
21472
- const buf = (0, import_node_fs52.readFileSync)(abs).subarray(0, maxHunk);
21882
+ const buf = (0, import_node_fs53.readFileSync)(abs).subarray(0, maxHunk);
21473
21883
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
21474
21884
  }
21475
21885
  } catch {
@@ -21936,9 +22346,9 @@ async function getDiff(worktreePath, repoPath, opts) {
21936
22346
  }
21937
22347
  function statWorktreePath(worktreePath, relativePath) {
21938
22348
  assertSafeRelativePath(relativePath);
21939
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21940
- if (!(0, import_node_fs52.existsSync)(abs)) return "missing";
21941
- 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);
21942
22352
  if (st.isDirectory()) return "dir";
21943
22353
  if (st.isFile()) return "file";
21944
22354
  return "missing";
@@ -21967,8 +22377,8 @@ function isImageRelativePath(relativePath) {
21967
22377
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21968
22378
  assertSafeRelativePath(relativePath);
21969
22379
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
21970
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21971
- 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);
21972
22382
  if (!st.isFile()) {
21973
22383
  throw new Error(`Not a file: ${relativePath}`);
21974
22384
  }
@@ -21977,7 +22387,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21977
22387
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
21978
22388
  );
21979
22389
  }
21980
- const buf = (0, import_node_fs52.readFileSync)(abs);
22390
+ const buf = (0, import_node_fs53.readFileSync)(abs);
21981
22391
  return {
21982
22392
  path: relativePath,
21983
22393
  contentBase64: buf.toString("base64"),
@@ -21987,12 +22397,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21987
22397
  function readWorktreeFile(worktreePath, relativePath, opts) {
21988
22398
  assertSafeRelativePath(relativePath);
21989
22399
  const maxBytes = opts?.maxBytes ?? 2e5;
21990
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21991
- 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);
21992
22402
  if (!st.isFile()) {
21993
22403
  throw new Error(`Not a file: ${relativePath}`);
21994
22404
  }
21995
- const buf = (0, import_node_fs52.readFileSync)(abs);
22405
+ const buf = (0, import_node_fs53.readFileSync)(abs);
21996
22406
  if (isImageRelativePath(relativePath)) {
21997
22407
  const maxImageBytes = Math.max(maxBytes, 15e6);
21998
22408
  const truncated2 = buf.length > maxImageBytes;
@@ -22035,9 +22445,9 @@ function assertSafeRelativePath(relativePath) {
22035
22445
  }
22036
22446
  function writeWorktreeFile(worktreePath, relativePath, content) {
22037
22447
  assertSafeRelativePath(relativePath);
22038
- const abs = (0, import_node_path50.join)(worktreePath, relativePath);
22039
- (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
22040
- (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");
22041
22451
  return { path: relativePath };
22042
22452
  }
22043
22453
  async function getWorktreeDirtyStat(worktreePath) {
@@ -22077,12 +22487,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
22077
22487
  truncated: full.files.length > maxFiles
22078
22488
  };
22079
22489
  }
22080
- 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;
22081
22491
  var init_diff = __esm({
22082
22492
  "src/diff/diff.ts"() {
22083
22493
  "use strict";
22084
- import_node_fs52 = require("fs");
22085
- import_node_path50 = require("path");
22494
+ import_node_fs53 = require("fs");
22495
+ import_node_path51 = require("path");
22086
22496
  init_run();
22087
22497
  init_worktree();
22088
22498
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -22439,7 +22849,7 @@ function parseFrontmatter(content) {
22439
22849
  }
22440
22850
  function readSkill(skillMd, source) {
22441
22851
  try {
22442
- const content = (0, import_node_fs53.readFileSync)(skillMd, "utf8");
22852
+ const content = (0, import_node_fs54.readFileSync)(skillMd, "utf8");
22443
22853
  const { name: fmName, description } = parseFrontmatter(content);
22444
22854
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
22445
22855
  const name = fmName || dirName;
@@ -22458,19 +22868,19 @@ function readSkill(skillMd, source) {
22458
22868
  }
22459
22869
  }
22460
22870
  function scanSkillsDir(dir, source, out) {
22461
- if (!(0, import_node_fs53.existsSync)(dir)) return;
22871
+ if (!(0, import_node_fs54.existsSync)(dir)) return;
22462
22872
  let entries;
22463
22873
  try {
22464
- entries = (0, import_node_fs53.readdirSync)(dir);
22874
+ entries = (0, import_node_fs54.readdirSync)(dir);
22465
22875
  } catch {
22466
22876
  return;
22467
22877
  }
22468
22878
  for (const entry of entries) {
22469
22879
  if (entry.startsWith(".")) continue;
22470
- const skillMd = (0, import_node_path51.join)(dir, entry, "SKILL.md");
22471
- 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;
22472
22882
  try {
22473
- if (!(0, import_node_fs53.statSync)(skillMd).isFile()) continue;
22883
+ if (!(0, import_node_fs54.statSync)(skillMd).isFile()) continue;
22474
22884
  } catch {
22475
22885
  continue;
22476
22886
  }
@@ -22479,24 +22889,24 @@ function scanSkillsDir(dir, source, out) {
22479
22889
  }
22480
22890
  }
22481
22891
  function scanClaudePluginSkills(pluginsRoot, out) {
22482
- if (!(0, import_node_fs53.existsSync)(pluginsRoot)) return;
22892
+ if (!(0, import_node_fs54.existsSync)(pluginsRoot)) return;
22483
22893
  const walk = (dir, depth, lookingForSkillsDir) => {
22484
22894
  if (depth > 7) return;
22485
22895
  let entries;
22486
22896
  try {
22487
- entries = (0, import_node_fs53.readdirSync)(dir);
22897
+ entries = (0, import_node_fs54.readdirSync)(dir);
22488
22898
  } catch {
22489
22899
  return;
22490
22900
  }
22491
22901
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
22492
- 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");
22493
22903
  if (skill) out.push(skill);
22494
22904
  }
22495
22905
  for (const entry of entries) {
22496
22906
  if (entry === "node_modules" || entry === ".git") continue;
22497
- const full = (0, import_node_path51.join)(dir, entry);
22907
+ const full = (0, import_node_path52.join)(dir, entry);
22498
22908
  try {
22499
- if (!(0, import_node_fs53.statSync)(full).isDirectory()) continue;
22909
+ if (!(0, import_node_fs54.statSync)(full).isDirectory()) continue;
22500
22910
  } catch {
22501
22911
  continue;
22502
22912
  }
@@ -22514,17 +22924,17 @@ function discoverSkills(worktreePath) {
22514
22924
  const home = (0, import_node_os15.homedir)();
22515
22925
  const collected = [];
22516
22926
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
22517
- scanSkillsDir((0, import_node_path51.join)(worktreePath, rel), "workspace", collected);
22927
+ scanSkillsDir((0, import_node_path52.join)(worktreePath, rel), "workspace", collected);
22518
22928
  }
22519
22929
  for (const abs of [
22520
- (0, import_node_path51.join)(home, ".claude/skills"),
22521
- (0, import_node_path51.join)(home, ".cursor/skills"),
22522
- (0, import_node_path51.join)(home, ".sideboard/skills"),
22523
- (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")
22524
22934
  ]) {
22525
22935
  scanSkillsDir(abs, "user", collected);
22526
22936
  }
22527
- scanClaudePluginSkills((0, import_node_path51.join)(home, ".claude/plugins"), collected);
22937
+ scanClaudePluginSkills((0, import_node_path52.join)(home, ".claude/plugins"), collected);
22528
22938
  collected.push(...bundledSkills());
22529
22939
  const rank = {
22530
22940
  workspace: 0,
@@ -22550,7 +22960,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22550
22960
  \u2026(truncated)` : body;
22551
22961
  }
22552
22962
  }
22553
- const raw = (0, import_node_fs53.readFileSync)(skillPath, "utf8");
22963
+ const raw = (0, import_node_fs54.readFileSync)(skillPath, "utf8");
22554
22964
  if (raw.startsWith("---")) {
22555
22965
  const end = raw.indexOf("\n---", 3);
22556
22966
  if (end >= 0) {
@@ -22564,13 +22974,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22564
22974
 
22565
22975
  \u2026(truncated)` : raw;
22566
22976
  }
22567
- 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;
22568
22978
  var init_discover = __esm({
22569
22979
  "src/skills/discover.ts"() {
22570
22980
  "use strict";
22571
- import_node_fs53 = require("fs");
22981
+ import_node_fs54 = require("fs");
22572
22982
  import_node_os15 = require("os");
22573
- import_node_path51 = require("path");
22983
+ import_node_path52 = require("path");
22574
22984
  init_long_running();
22575
22985
  BUNDLED_SKILL_PREFIX = "bundled:";
22576
22986
  }
@@ -22725,7 +23135,7 @@ function compiledModuleDir() {
22725
23135
  try {
22726
23136
  const url = import_meta4.url;
22727
23137
  if (typeof url === "string" && url.length > 0) {
22728
- 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));
22729
23139
  }
22730
23140
  } catch {
22731
23141
  }
@@ -22733,8 +23143,8 @@ function compiledModuleDir() {
22733
23143
  }
22734
23144
  function detachedJobScriptIn(dir) {
22735
23145
  for (const name of DETACHED_JOB_FILENAMES) {
22736
- const script = (0, import_node_path52.join)(dir, "scripts", name);
22737
- 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;
22738
23148
  }
22739
23149
  return null;
22740
23150
  }
@@ -22751,7 +23161,7 @@ function resolveDetachedJobScript() {
22751
23161
  for (let i = 0; i < 8; i++) {
22752
23162
  const candidate = detachedJobScriptIn(dir);
22753
23163
  if (candidate) return candidate;
22754
- const parent = (0, import_node_path52.dirname)(dir);
23164
+ const parent = (0, import_node_path53.dirname)(dir);
22755
23165
  if (parent === dir) break;
22756
23166
  dir = parent;
22757
23167
  }
@@ -22762,12 +23172,12 @@ function formatDetachedJobInvoke(scriptPath) {
22762
23172
  if (resolved) return `node ${JSON.stringify(resolved)}`;
22763
23173
  return "node scripts/detached-job.cjs";
22764
23174
  }
22765
- 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;
22766
23176
  var init_detached_job_path = __esm({
22767
23177
  "src/skills/detached-job-path.ts"() {
22768
23178
  "use strict";
22769
- import_node_fs54 = require("fs");
22770
- import_node_path52 = require("path");
23179
+ import_node_fs55 = require("fs");
23180
+ import_node_path53 = require("path");
22771
23181
  import_node_url4 = require("url");
22772
23182
  init_packaged_runtime();
22773
23183
  import_meta4 = {};
@@ -22802,6 +23212,34 @@ function formatRenameBranchDirective(thread, opts) {
22802
23212
  }
22803
23213
  return lines.join("\n");
22804
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
+ }
22805
23243
  function formatWorktreeDirective(thread, opts) {
22806
23244
  const worktree = normPath3(thread.worktreePath);
22807
23245
  const repo = normPath3(thread.repoPath);
@@ -22849,6 +23287,8 @@ function formatWorktreeDirective(thread, opts) {
22849
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.'
22850
23288
  );
22851
23289
  lines.push("");
23290
+ lines.push(formatDevAccessHint(opts?.activeRuns));
23291
+ lines.push("");
22852
23292
  lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
22853
23293
  return lines.join("\n");
22854
23294
  }
@@ -22949,9 +23389,9 @@ function formatPrGateDirective() {
22949
23389
  }
22950
23390
  function formatProcessGuideDirective(opts) {
22951
23391
  const worktree = opts?.worktreePath?.trim();
22952
- const hasGraphSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22953
- const hasReviewSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/review/SKILL.md"));
22954
- 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"));
22955
23395
  return [
22956
23396
  "Process guides (recurring work only):",
22957
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,
@@ -22971,12 +23411,12 @@ function formatLongRunningDirective(opts) {
22971
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.",
22972
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.",
22973
23413
  "State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available).",
22974
- "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."
22975
23415
  ].join("\n");
22976
23416
  }
22977
23417
  function formatLongRunningReminder(opts) {
22978
23418
  const invoke = formatDetachedJobInvoke(opts?.scriptPath);
22979
- 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)}`;
22980
23420
  }
22981
23421
  function formatArtifactDirective() {
22982
23422
  return [
@@ -22988,14 +23428,14 @@ function formatArtifactDirective() {
22988
23428
  ].join("\n");
22989
23429
  }
22990
23430
  function formatUiReminder() {
22991
- 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.";
22992
23432
  }
22993
- 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;
22994
23434
  var init_instructions = __esm({
22995
23435
  "src/agents/instructions.ts"() {
22996
23436
  "use strict";
22997
- import_node_fs55 = require("fs");
22998
- import_node_path53 = require("path");
23437
+ import_node_fs56 = require("fs");
23438
+ import_node_path54 = require("path");
22999
23439
  init_git_auth_mode();
23000
23440
  init_branch_prefix();
23001
23441
  init_worktree_labels();
@@ -23381,40 +23821,40 @@ __export(plan_file_exports, {
23381
23821
  writePlanFile: () => writePlanFile
23382
23822
  });
23383
23823
  function ensureAttachmentsGitignore(worktreePath) {
23384
- const gitignoreAbs = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23385
- if ((0, import_node_fs56.existsSync)(gitignoreAbs)) return;
23386
- (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(gitignoreAbs), { recursive: true });
23387
- (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");
23388
23828
  }
23389
23829
  function planFileAbs(worktreePath) {
23390
- return (0, import_node_path54.join)(worktreePath, PLAN_FILE_REL);
23830
+ return (0, import_node_path55.join)(worktreePath, PLAN_FILE_REL);
23391
23831
  }
23392
23832
  function readTextIfPresent2(abs) {
23393
- if (!(0, import_node_fs56.existsSync)(abs)) return null;
23833
+ if (!(0, import_node_fs57.existsSync)(abs)) return null;
23394
23834
  try {
23395
- const content = (0, import_node_fs56.readFileSync)(abs, "utf8");
23835
+ const content = (0, import_node_fs57.readFileSync)(abs, "utf8");
23396
23836
  return content.trim() ? content : null;
23397
23837
  } catch {
23398
23838
  return null;
23399
23839
  }
23400
23840
  }
23401
23841
  function readPlanFile(worktreePath) {
23402
- 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));
23403
23843
  }
23404
23844
  function writePlanFile(worktreePath, content) {
23405
23845
  ensureAttachmentsGitignore(worktreePath);
23406
23846
  const abs = planFileAbs(worktreePath);
23407
- (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 });
23408
23848
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23409
- (0, import_node_fs56.writeFileSync)(abs, body, "utf8");
23849
+ (0, import_node_fs57.writeFileSync)(abs, body, "utf8");
23410
23850
  return PLAN_FILE_REL;
23411
23851
  }
23412
- var import_node_fs56, import_node_path54;
23852
+ var import_node_fs57, import_node_path55;
23413
23853
  var init_plan_file = __esm({
23414
23854
  "src/plan/plan-file.ts"() {
23415
23855
  "use strict";
23416
- import_node_fs56 = require("fs");
23417
- import_node_path54 = require("path");
23856
+ import_node_fs57 = require("fs");
23857
+ import_node_path55 = require("path");
23418
23858
  init_workspace_scratch();
23419
23859
  init_plan_present();
23420
23860
  init_plan_present();
@@ -23476,9 +23916,9 @@ function recoverFinishedCursorRun(opts) {
23476
23916
  return best;
23477
23917
  }
23478
23918
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23479
- if (!(0, import_node_fs57.existsSync)(runsPath)) return null;
23919
+ if (!(0, import_node_fs58.existsSync)(runsPath)) return null;
23480
23920
  try {
23481
- const lines = (0, import_node_fs57.readFileSync)(runsPath, "utf8").split("\n");
23921
+ const lines = (0, import_node_fs58.readFileSync)(runsPath, "utf8").split("\n");
23482
23922
  let best = null;
23483
23923
  for (const line of lines) {
23484
23924
  const trimmed = line.trim();
@@ -23504,11 +23944,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23504
23944
  return null;
23505
23945
  }
23506
23946
  }
23507
- var import_node_fs57;
23947
+ var import_node_fs58;
23508
23948
  var init_cursor_recover = __esm({
23509
23949
  "src/agents/cursor-recover.ts"() {
23510
23950
  "use strict";
23511
- import_node_fs57 = require("fs");
23951
+ import_node_fs58 = require("fs");
23512
23952
  init_cursor_store();
23513
23953
  }
23514
23954
  });
@@ -23662,14 +24102,14 @@ async function startOrchestration(opts) {
23662
24102
  }
23663
24103
  return updated;
23664
24104
  }
23665
- 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;
23666
24106
  var init_orchestrator = __esm({
23667
24107
  "src/orchestrator/orchestrator.ts"() {
23668
24108
  "use strict";
23669
24109
  import_node_events = require("events");
23670
24110
  init_outbound_watch();
23671
24111
  import_node_crypto12 = require("crypto");
23672
- import_node_fs58 = require("fs");
24112
+ import_node_fs59 = require("fs");
23673
24113
  init_error_detail();
23674
24114
  init_run();
23675
24115
  init_stale_lock();
@@ -23681,6 +24121,7 @@ var init_orchestrator = __esm({
23681
24121
  init_agent_git_actions();
23682
24122
  init_pr_merge_archive();
23683
24123
  init_conductor();
24124
+ init_dev_preview();
23684
24125
  init_setup_log();
23685
24126
  init_orphan_cleanup();
23686
24127
  init_history_cleanup();
@@ -23846,7 +24287,7 @@ var init_orchestrator = __esm({
23846
24287
  this.lightReconcileAt.set(repoPath, Date.now());
23847
24288
  for (const thread of listThreads()) {
23848
24289
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
23849
- if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
24290
+ if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
23850
24291
  setStatus(thread.id, "broken", "Worktree missing on disk");
23851
24292
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23852
24293
  }
@@ -23875,7 +24316,7 @@ var init_orchestrator = __esm({
23875
24316
  }
23876
24317
  continue;
23877
24318
  }
23878
- if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
24319
+ if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
23879
24320
  setStatus(thread.id, "broken", "Worktree missing on disk");
23880
24321
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23881
24322
  continue;
@@ -24562,8 +25003,13 @@ var init_orchestrator = __esm({
24562
25003
  SLACK_REPLY_FORMATTING
24563
25004
  ].join("\n") : null
24564
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
+ ) : [];
24565
25011
  const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
24566
- const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder() : null;
25012
+ const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder({ activeRuns: worktreeActiveRuns }) : null;
24567
25013
  const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
24568
25014
  const optionalServicesReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatOptionalServicesReminder(loadAppSettings().integrations) : null;
24569
25015
  const issueTicket = issueTicketFromThread(thread, resolveEffectiveIssueSource());
@@ -24623,7 +25069,14 @@ var init_orchestrator = __esm({
24623
25069
  8e3,
24624
25070
  "resolveGithubRepoSlug"
24625
25071
  ).catch(() => null),
24626
- gitAuthMode
25072
+ gitAuthMode,
25073
+ activeRuns: annotateDevAccessRuns(
25074
+ mergeWorktreeActiveRuns(
25075
+ threadsSharingWorktree(fresh.worktreePath)
25076
+ ).activeRuns,
25077
+ listRunScripts(fresh.worktreePath, fresh.repoPath),
25078
+ fresh.worktreePath
25079
+ )
24627
25080
  });
24628
25081
  const artifactDirective = isBrightsy ? null : formatArtifactDirective();
24629
25082
  const longRunningDirective = isBrightsy || isOrchestration ? null : formatLongRunningDirective();
@@ -26176,7 +26629,7 @@ var init_orchestrator = __esm({
26176
26629
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
26177
26630
  return restored2;
26178
26631
  }
26179
- if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
26632
+ if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
26180
26633
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
26181
26634
  throw new Error(
26182
26635
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -26513,6 +26966,7 @@ __export(index_exports, {
26513
26966
  abletimeMcpUrl: () => abletimeMcpUrl,
26514
26967
  abletimeToolUsesPm: () => abletimeToolUsesPm,
26515
26968
  ackSlackInboundSeen: () => ackSlackInboundSeen,
26969
+ activeRunPreview: () => activeRunPreview,
26516
26970
  addBoardPin: () => addBoardPin,
26517
26971
  addPrStackLayer: () => addPrStackLayer,
26518
26972
  addStackLayerFromThread: () => addStackLayerFromThread,
@@ -26528,6 +26982,7 @@ __export(index_exports, {
26528
26982
  allocatePortRange: () => allocatePortRange,
26529
26983
  allocateTeamName: () => allocateTeamName,
26530
26984
  allocateTeamSlug: () => allocateTeamSlug,
26985
+ annotateDevAccessRuns: () => annotateDevAccessRuns,
26531
26986
  appDataDir: () => appDataDir,
26532
26987
  appSettingsPath: () => appSettingsPath,
26533
26988
  appendIndexedGitConfig: () => appendIndexedGitConfig,
@@ -26592,6 +27047,7 @@ __export(index_exports, {
26592
27047
  clampGithubPrBody: () => clampGithubPrBody,
26593
27048
  clampHistoryMaxCount: () => clampHistoryMaxCount,
26594
27049
  clampHistoryMaxDays: () => clampHistoryMaxDays,
27050
+ classifyRunScriptPreview: () => classifyRunScriptPreview,
26595
27051
  classifyWorktreeColumn: () => classifyWorktreeColumn,
26596
27052
  claudeAdapter: () => claudeAdapter,
26597
27053
  claudeChromeEnabled: () => claudeChromeEnabled,
@@ -26611,6 +27067,7 @@ __export(index_exports, {
26611
27067
  codexUnattendedGitConfigArgs: () => codexUnattendedGitConfigArgs,
26612
27068
  coerceOrchestratorAgent: () => coerceOrchestratorAgent,
26613
27069
  collectTakenTeamSlugs: () => collectTakenTeamSlugs,
27070
+ commandLooksLikeElectron: () => commandLooksLikeElectron,
26614
27071
  commentAbleTimeTask: () => commentAbleTimeTask,
26615
27072
  commentGitHubIssue: () => commentGitHubIssue,
26616
27073
  commentLinearIssue: () => commentLinearIssue,
@@ -26733,6 +27190,7 @@ __export(index_exports, {
26733
27190
  formatClaudeUsageResetClock: () => formatClaudeUsageResetClock,
26734
27191
  formatClaudeUsageTooltip: () => formatClaudeUsageTooltip,
26735
27192
  formatDetachedJobInvoke: () => formatDetachedJobInvoke,
27193
+ formatDevAccessHint: () => formatDevAccessHint,
26736
27194
  formatFetchError: () => formatFetchError,
26737
27195
  formatGhLandError: () => formatGhLandError,
26738
27196
  formatGitAuthModeDirective: () => formatGitAuthModeDirective,
@@ -26859,7 +27317,10 @@ __export(index_exports, {
26859
27317
  isBrightsyConnected: () => isBrightsyConnected,
26860
27318
  isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
26861
27319
  isCloudCoordinatorThread: () => isCloudCoordinatorThread,
27320
+ isCompactToolName: () => isCompactToolName,
26862
27321
  isConductorBundledCli: () => isConductorBundledCli,
27322
+ isContextCompactDone: () => isContextCompactDone,
27323
+ isContextCompactInProgress: () => isContextCompactInProgress,
26863
27324
  isCowboyThread: () => isCowboyThread,
26864
27325
  isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
26865
27326
  isCursorAutoModel: () => isCursorAutoModel,
@@ -26897,6 +27358,7 @@ __export(index_exports, {
26897
27358
  isSetupLastError: () => isSetupLastError,
26898
27359
  isShellToolName: () => isShellToolName,
26899
27360
  isSideboardScratchPath: () => isSideboardScratchPath,
27361
+ isSkillToolName: () => isSkillToolName,
26900
27362
  isSlackCoordinatorThread: () => isSlackCoordinatorThread,
26901
27363
  isSlackExternalReplyPrompt: () => isSlackExternalReplyPrompt,
26902
27364
  isSlackOAuthCancelled: () => isSlackOAuthCancelled,
@@ -26967,8 +27429,11 @@ __export(index_exports, {
26967
27429
  loadHomeBoardInputs: () => loadHomeBoardInputs,
26968
27430
  loadRepoSettings: () => loadRepoSettings,
26969
27431
  loadWorkspaceSettings: () => loadWorkspaceSettings,
27432
+ localhostPreviewUrl: () => localhostPreviewUrl,
26970
27433
  locksDir: () => locksDir,
26971
27434
  loginAgent: () => loginAgent,
27435
+ looksLikeConversationSummary: () => looksLikeConversationSummary,
27436
+ looksLikeSkillBody: () => looksLikeSkillBody,
26972
27437
  lookupSoccerTeam: () => lookupSoccerTeam,
26973
27438
  mapAbleTimeTask: () => mapAbleTimeTask,
26974
27439
  markPrReady: () => markPrReady,
@@ -27021,6 +27486,7 @@ __export(index_exports, {
27021
27486
  parseAbleTimeOAuthCallbackUrl: () => parseAbleTimeOAuthCallbackUrl,
27022
27487
  parseClaudeUsagePayload: () => parseClaudeUsagePayload,
27023
27488
  parseCursorRunnerLine: () => parseCursorRunnerLine,
27489
+ parseDevPreview: () => parseDevPreview,
27024
27490
  parseDurationMs: () => parseDurationMs,
27025
27491
  parseForceStopMessage: () => parseForceStopMessage,
27026
27492
  parseGhStackViewJson: () => parseGhStackViewJson,
@@ -27042,6 +27508,7 @@ __export(index_exports, {
27042
27508
  planHistoryAgePurge: () => planHistoryAgePurge,
27043
27509
  planHistoryRetention: () => planHistoryRetention,
27044
27510
  planQuestionsSignature: () => planQuestionsSignature,
27511
+ pnpmFilterPackage: () => pnpmFilterPackage,
27045
27512
  pollSlackOutboundWatches: () => pollSlackOutboundWatches,
27046
27513
  posixShellSingleQuote: () => posixShellSingleQuote,
27047
27514
  preferredCursorCostCents: () => preferredCursorCostCents,
@@ -27139,6 +27606,7 @@ __export(index_exports, {
27139
27606
  runCloudConnect: () => runCloudConnect,
27140
27607
  runConventionSetup: () => runConventionSetup,
27141
27608
  runCursorWorktreeSetup: () => runCursorWorktreeSetup,
27609
+ runScriptPreview: () => runScriptPreview,
27142
27610
  runSetupScript: () => runSetupScript,
27143
27611
  runSlackListen: () => runSlackListen,
27144
27612
  runSlackRelayClient: () => runSlackRelayClient,
@@ -27173,6 +27641,9 @@ __export(index_exports, {
27173
27641
  sideboardMcpProfile: () => sideboardMcpProfile,
27174
27642
  sideboardReposDir: () => sideboardReposDir,
27175
27643
  sideboardWorkspacesDir: () => sideboardWorkspacesDir,
27644
+ skillCommandFromBody: () => skillCommandFromBody,
27645
+ skillCommandFromInput: () => skillCommandFromInput,
27646
+ skillNameFromFrontmatter: () => skillNameFromFrontmatter,
27176
27647
  slackAppLevelToken: () => slackAppLevelToken,
27177
27648
  slackArchiveUrl: () => slackArchiveUrl,
27178
27649
  slackCoordinatorSourceRef: () => slackCoordinatorSourceRef,
@@ -27287,8 +27758,8 @@ init_paths();
27287
27758
  init_app_settings();
27288
27759
 
27289
27760
  // src/store/agent-done-sound.ts
27290
- var import_node_fs8 = require("fs");
27291
- var import_node_path9 = require("path");
27761
+ var import_node_fs9 = require("fs");
27762
+ var import_node_path10 = require("path");
27292
27763
  init_paths();
27293
27764
  var AGENT_DONE_CUSTOM_SOUND_MAX_BYTES = 5 * 1024 * 1024;
27294
27765
  var AUDIO_EXT_MIME = {
@@ -27302,8 +27773,8 @@ var AUDIO_EXT_MIME = {
27302
27773
  };
27303
27774
  var AGENT_DONE_CUSTOM_SOUND_EXTENSIONS = Object.keys(AUDIO_EXT_MIME);
27304
27775
  function agentDoneSoundsDir() {
27305
- const dir = (0, import_node_path9.join)(appDataDir(), "sounds");
27306
- (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 });
27307
27778
  return dir;
27308
27779
  }
27309
27780
  function normalizeExt(ext) {
@@ -27311,50 +27782,50 @@ function normalizeExt(ext) {
27311
27782
  return e.startsWith(".") ? e : `.${e}`;
27312
27783
  }
27313
27784
  function agentDoneCustomSoundMime(extOrPath) {
27314
- const ext = normalizeExt((0, import_node_path9.extname)(extOrPath) || extOrPath);
27785
+ const ext = normalizeExt((0, import_node_path10.extname)(extOrPath) || extOrPath);
27315
27786
  return AUDIO_EXT_MIME[ext] ?? null;
27316
27787
  }
27317
27788
  function findAgentDoneCustomSoundPath() {
27318
27789
  const dir = agentDoneSoundsDir();
27319
- for (const name of (0, import_node_fs8.readdirSync)(dir)) {
27790
+ for (const name of (0, import_node_fs9.readdirSync)(dir)) {
27320
27791
  if (!name.startsWith("agent-done.")) continue;
27321
- const full = (0, import_node_path9.join)(dir, name);
27322
- 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;
27323
27794
  }
27324
27795
  return null;
27325
27796
  }
27326
27797
  function clearAgentDoneCustomSoundFile() {
27327
27798
  const dir = agentDoneSoundsDir();
27328
- for (const name of (0, import_node_fs8.readdirSync)(dir)) {
27799
+ for (const name of (0, import_node_fs9.readdirSync)(dir)) {
27329
27800
  if (!name.startsWith("agent-done.")) continue;
27330
27801
  try {
27331
- (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));
27332
27803
  } catch {
27333
27804
  }
27334
27805
  }
27335
27806
  }
27336
27807
  function importAgentDoneCustomSound(sourcePath) {
27337
27808
  const trimmed = sourcePath.trim();
27338
- if (!trimmed || !(0, import_node_fs8.existsSync)(trimmed)) {
27809
+ if (!trimmed || !(0, import_node_fs9.existsSync)(trimmed)) {
27339
27810
  throw new Error("Sound file not found");
27340
27811
  }
27341
- const ext = normalizeExt((0, import_node_path9.extname)(trimmed));
27812
+ const ext = normalizeExt((0, import_node_path10.extname)(trimmed));
27342
27813
  const mime = AUDIO_EXT_MIME[ext];
27343
27814
  if (!mime) {
27344
27815
  throw new Error(
27345
27816
  `Unsupported audio type (use ${AGENT_DONE_CUSTOM_SOUND_EXTENSIONS.join(", ")})`
27346
27817
  );
27347
27818
  }
27348
- const data = (0, import_node_fs8.readFileSync)(trimmed);
27819
+ const data = (0, import_node_fs9.readFileSync)(trimmed);
27349
27820
  if (data.byteLength === 0) throw new Error("Sound file is empty");
27350
27821
  if (data.byteLength > AGENT_DONE_CUSTOM_SOUND_MAX_BYTES) {
27351
27822
  throw new Error("Sound file is too large (max 5 MB)");
27352
27823
  }
27353
27824
  clearAgentDoneCustomSoundFile();
27354
- const dest = (0, import_node_path9.join)(agentDoneSoundsDir(), `agent-done${ext}`);
27355
- (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);
27356
27827
  return {
27357
- name: (0, import_node_path9.basename)(trimmed),
27828
+ name: (0, import_node_path10.basename)(trimmed),
27358
27829
  path: dest,
27359
27830
  mime
27360
27831
  };
@@ -27364,10 +27835,10 @@ function readAgentDoneCustomSound(displayName2) {
27364
27835
  if (!path2) return null;
27365
27836
  const mime = agentDoneCustomSoundMime(path2);
27366
27837
  if (!mime) return null;
27367
- const data = (0, import_node_fs8.readFileSync)(path2);
27838
+ const data = (0, import_node_fs9.readFileSync)(path2);
27368
27839
  if (data.byteLength === 0) return null;
27369
27840
  return {
27370
- name: displayName2?.trim() || (0, import_node_path9.basename)(path2),
27841
+ name: displayName2?.trim() || (0, import_node_path10.basename)(path2),
27371
27842
  mime,
27372
27843
  dataBase64: data.toString("base64")
27373
27844
  };
@@ -29461,6 +29932,7 @@ init_instructions();
29461
29932
  init_turn_input();
29462
29933
  init_detect();
29463
29934
  init_settings();
29935
+ init_dev_preview();
29464
29936
  init_conductor();
29465
29937
  init_convention_setup();
29466
29938
  init_cursor_worktrees();
@@ -29800,7 +30272,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
29800
30272
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29801
30273
  var import_zod9 = require("zod");
29802
30274
  var import_node_crypto16 = require("crypto");
29803
- var import_node_path57 = require("path");
30275
+ var import_node_path58 = require("path");
29804
30276
  init_orchestrator();
29805
30277
  init_worktree();
29806
30278
  init_global_workspace();
@@ -29834,6 +30306,8 @@ function resolveRunScriptThreadRef(ref) {
29834
30306
  }
29835
30307
 
29836
30308
  // src/mcp/server.ts
30309
+ init_dev_preview();
30310
+ init_instructions();
29837
30311
  init_wait_for_turn();
29838
30312
  init_wait_for_job();
29839
30313
  init_message_parts();
@@ -31537,27 +32011,27 @@ init_gh_errors();
31537
32011
  init_git_auth_mode();
31538
32012
 
31539
32013
  // src/board/load-home-board.ts
31540
- var import_node_fs60 = require("fs");
31541
- var import_node_path56 = require("path");
32014
+ var import_node_fs61 = require("fs");
32015
+ var import_node_path57 = require("path");
31542
32016
  init_worktree();
31543
32017
  init_paths();
31544
32018
 
31545
32019
  // src/board/board-pins.ts
31546
32020
  var import_node_crypto15 = require("crypto");
31547
- var import_node_fs59 = require("fs");
31548
- var import_node_path55 = require("path");
32021
+ var import_node_fs60 = require("fs");
32022
+ var import_node_path56 = require("path");
31549
32023
  init_paths();
31550
32024
  init_home_board();
31551
32025
  var FILE = "home-board-pins.json";
31552
32026
  var VERSION = 1;
31553
32027
  function pinsFile() {
31554
- return (0, import_node_path55.join)(appDataDir(), FILE);
32028
+ return (0, import_node_path56.join)(appDataDir(), FILE);
31555
32029
  }
31556
32030
  function readDisk() {
31557
32031
  const path2 = pinsFile();
31558
- if (!(0, import_node_fs59.existsSync)(path2)) return [];
32032
+ if (!(0, import_node_fs60.existsSync)(path2)) return [];
31559
32033
  try {
31560
- const raw = JSON.parse((0, import_node_fs59.readFileSync)(path2, "utf8"));
32034
+ const raw = JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
31561
32035
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
31562
32036
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
31563
32037
  } catch {
@@ -31565,8 +32039,8 @@ function readDisk() {
31565
32039
  }
31566
32040
  }
31567
32041
  function writeDisk(items) {
31568
- (0, import_node_fs59.mkdirSync)(appDataDir(), { recursive: true });
31569
- (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");
31570
32044
  }
31571
32045
  function listBoardPins() {
31572
32046
  return readDisk();
@@ -31618,7 +32092,7 @@ function replaceBoardPins(items) {
31618
32092
  }
31619
32093
  function clearBoardPins() {
31620
32094
  try {
31621
- (0, import_node_fs59.unlinkSync)(pinsFile());
32095
+ (0, import_node_fs60.unlinkSync)(pinsFile());
31622
32096
  } catch {
31623
32097
  }
31624
32098
  }
@@ -31635,7 +32109,7 @@ function homeBoardWorkspaceKey(workspaces) {
31635
32109
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
31636
32110
  }
31637
32111
  function cacheFile() {
31638
- return (0, import_node_path56.join)(appDataDir(), "home-board-cache.json");
32112
+ return (0, import_node_path57.join)(appDataDir(), "home-board-cache.json");
31639
32113
  }
31640
32114
  function emptyInputs() {
31641
32115
  return {
@@ -31661,9 +32135,9 @@ function shouldCacheHomeBoardInputs(inputs) {
31661
32135
  }
31662
32136
  function readDiskCache() {
31663
32137
  const path2 = cacheFile();
31664
- if (!(0, import_node_fs60.existsSync)(path2)) return null;
32138
+ if (!(0, import_node_fs61.existsSync)(path2)) return null;
31665
32139
  try {
31666
- const raw = JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
32140
+ const raw = JSON.parse((0, import_node_fs61.readFileSync)(path2, "utf8"));
31667
32141
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
31668
32142
  return null;
31669
32143
  }
@@ -31677,14 +32151,14 @@ function readDiskCache() {
31677
32151
  }
31678
32152
  function writeDiskCache(entry) {
31679
32153
  try {
31680
- (0, import_node_fs60.mkdirSync)(appDataDir(), { recursive: true });
31681
- (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");
31682
32156
  } catch {
31683
32157
  }
31684
32158
  }
31685
32159
  function deleteDiskCache() {
31686
32160
  try {
31687
- (0, import_node_fs60.unlinkSync)(cacheFile());
32161
+ (0, import_node_fs61.unlinkSync)(cacheFile());
31688
32162
  } catch {
31689
32163
  }
31690
32164
  }
@@ -31968,6 +32442,9 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
31968
32442
  return { ok: false, text: `create_thread failed: ${message}` };
31969
32443
  }
31970
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
+ }
31971
32448
  async function startMcpServer() {
31972
32449
  const orch = getOrchestrator();
31973
32450
  try {
@@ -32034,7 +32511,7 @@ async function startMcpServer() {
32034
32511
  async () => {
32035
32512
  const threads = orch.getThreads(true);
32036
32513
  const lines = threads.map((t) => {
32037
- 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;
32038
32515
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
32039
32516
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
32040
32517
  const preview = lastMessagePreview(t.messages, 80);
@@ -32291,15 +32768,27 @@ async function startMcpServer() {
32291
32768
  );
32292
32769
  server.tool(
32293
32770
  "list_run_scripts",
32294
- "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).",
32295
32772
  {
32296
32773
  ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd).")
32297
32774
  },
32298
32775
  async ({ ref }) => {
32299
32776
  try {
32300
32777
  const threadRef = resolveRunScriptThreadRef(ref);
32301
- const scripts = orch.listThreadRunScripts(threadRef);
32302
- 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
+ });
32303
32792
  return mcpJson({ scripts, active, ref: threadRef });
32304
32793
  } catch (err) {
32305
32794
  const message = err instanceof Error ? err.message : String(err);
@@ -32309,7 +32798,7 @@ async function startMcpServer() {
32309
32798
  );
32310
32799
  server.tool(
32311
32800
  "run_dev_script",
32312
- "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.",
32313
32802
  {
32314
32803
  ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
32315
32804
  name: import_zod9.z.string().optional().describe("Script name from list_run_scripts (default script if omitted).")
@@ -32318,11 +32807,16 @@ async function startMcpServer() {
32318
32807
  try {
32319
32808
  const threadRef = resolveRunScriptThreadRef(ref);
32320
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);
32321
32813
  return mcpJson({
32322
32814
  port: result.port,
32323
32815
  scriptName: result.scriptName,
32324
32816
  ports: result.ports,
32325
- url: `http://localhost:${result.port}`,
32817
+ url: localhostPreviewUrl(result.port),
32818
+ preview,
32819
+ hint: previewHint(preview),
32326
32820
  ref: threadRef
32327
32821
  });
32328
32822
  } catch (err) {
@@ -35035,9 +35529,9 @@ var import_node_http4 = require("http");
35035
35529
  var import_ws3 = require("ws");
35036
35530
 
35037
35531
  // src/slack/relay-static.ts
35038
- var import_node_fs61 = require("fs");
35532
+ var import_node_fs62 = require("fs");
35039
35533
  var import_promises = require("fs/promises");
35040
- var import_node_path58 = __toESM(require("path"), 1);
35534
+ var import_node_path59 = __toESM(require("path"), 1);
35041
35535
  var TYPES = {
35042
35536
  ".css": "text/css; charset=utf-8",
35043
35537
  ".html": "text/html; charset=utf-8",
@@ -35068,9 +35562,9 @@ function resolveStaticPath(root, requestUrl) {
35068
35562
  return null;
35069
35563
  }
35070
35564
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
35071
- const rootResolved = import_node_path58.default.resolve(root);
35072
- const candidate = import_node_path58.default.resolve(rootResolved, `.${pathname}`);
35073
- 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)) {
35074
35568
  return null;
35075
35569
  }
35076
35570
  return candidate;
@@ -35084,7 +35578,7 @@ async function fileSize(file) {
35084
35578
  }
35085
35579
  }
35086
35580
  function sendFile(req, res, file, size) {
35087
- const ext = import_node_path58.default.extname(file).toLowerCase();
35581
+ const ext = import_node_path59.default.extname(file).toLowerCase();
35088
35582
  res.writeHead(200, {
35089
35583
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
35090
35584
  "Content-Length": size,
@@ -35094,7 +35588,7 @@ function sendFile(req, res, file, size) {
35094
35588
  res.end();
35095
35589
  return true;
35096
35590
  }
35097
- (0, import_node_fs61.createReadStream)(file).pipe(res);
35591
+ (0, import_node_fs62.createReadStream)(file).pipe(res);
35098
35592
  return true;
35099
35593
  }
35100
35594
  async function tryServeStatic(req, res, root) {
@@ -35103,7 +35597,7 @@ async function tryServeStatic(req, res, root) {
35103
35597
  if (!candidate) return false;
35104
35598
  const direct = await fileSize(candidate);
35105
35599
  if (direct != null) return sendFile(req, res, candidate, direct);
35106
- const asIndex = import_node_path58.default.join(candidate, "index.html");
35600
+ const asIndex = import_node_path59.default.join(candidate, "index.html");
35107
35601
  const indexSize = await fileSize(asIndex);
35108
35602
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
35109
35603
  return false;
@@ -35483,6 +35977,7 @@ init_outbound_watch();
35483
35977
  abletimeMcpUrl,
35484
35978
  abletimeToolUsesPm,
35485
35979
  ackSlackInboundSeen,
35980
+ activeRunPreview,
35486
35981
  addBoardPin,
35487
35982
  addPrStackLayer,
35488
35983
  addStackLayerFromThread,
@@ -35498,6 +35993,7 @@ init_outbound_watch();
35498
35993
  allocatePortRange,
35499
35994
  allocateTeamName,
35500
35995
  allocateTeamSlug,
35996
+ annotateDevAccessRuns,
35501
35997
  appDataDir,
35502
35998
  appSettingsPath,
35503
35999
  appendIndexedGitConfig,
@@ -35562,6 +36058,7 @@ init_outbound_watch();
35562
36058
  clampGithubPrBody,
35563
36059
  clampHistoryMaxCount,
35564
36060
  clampHistoryMaxDays,
36061
+ classifyRunScriptPreview,
35565
36062
  classifyWorktreeColumn,
35566
36063
  claudeAdapter,
35567
36064
  claudeChromeEnabled,
@@ -35581,6 +36078,7 @@ init_outbound_watch();
35581
36078
  codexUnattendedGitConfigArgs,
35582
36079
  coerceOrchestratorAgent,
35583
36080
  collectTakenTeamSlugs,
36081
+ commandLooksLikeElectron,
35584
36082
  commentAbleTimeTask,
35585
36083
  commentGitHubIssue,
35586
36084
  commentLinearIssue,
@@ -35703,6 +36201,7 @@ init_outbound_watch();
35703
36201
  formatClaudeUsageResetClock,
35704
36202
  formatClaudeUsageTooltip,
35705
36203
  formatDetachedJobInvoke,
36204
+ formatDevAccessHint,
35706
36205
  formatFetchError,
35707
36206
  formatGhLandError,
35708
36207
  formatGitAuthModeDirective,
@@ -35829,7 +36328,10 @@ init_outbound_watch();
35829
36328
  isBrightsyConnected,
35830
36329
  isBrightsyNdjsonLine,
35831
36330
  isCloudCoordinatorThread,
36331
+ isCompactToolName,
35832
36332
  isConductorBundledCli,
36333
+ isContextCompactDone,
36334
+ isContextCompactInProgress,
35833
36335
  isCowboyThread,
35834
36336
  isCursorApiKeyConfigured,
35835
36337
  isCursorAutoModel,
@@ -35867,6 +36369,7 @@ init_outbound_watch();
35867
36369
  isSetupLastError,
35868
36370
  isShellToolName,
35869
36371
  isSideboardScratchPath,
36372
+ isSkillToolName,
35870
36373
  isSlackCoordinatorThread,
35871
36374
  isSlackExternalReplyPrompt,
35872
36375
  isSlackOAuthCancelled,
@@ -35937,8 +36440,11 @@ init_outbound_watch();
35937
36440
  loadHomeBoardInputs,
35938
36441
  loadRepoSettings,
35939
36442
  loadWorkspaceSettings,
36443
+ localhostPreviewUrl,
35940
36444
  locksDir,
35941
36445
  loginAgent,
36446
+ looksLikeConversationSummary,
36447
+ looksLikeSkillBody,
35942
36448
  lookupSoccerTeam,
35943
36449
  mapAbleTimeTask,
35944
36450
  markPrReady,
@@ -35991,6 +36497,7 @@ init_outbound_watch();
35991
36497
  parseAbleTimeOAuthCallbackUrl,
35992
36498
  parseClaudeUsagePayload,
35993
36499
  parseCursorRunnerLine,
36500
+ parseDevPreview,
35994
36501
  parseDurationMs,
35995
36502
  parseForceStopMessage,
35996
36503
  parseGhStackViewJson,
@@ -36012,6 +36519,7 @@ init_outbound_watch();
36012
36519
  planHistoryAgePurge,
36013
36520
  planHistoryRetention,
36014
36521
  planQuestionsSignature,
36522
+ pnpmFilterPackage,
36015
36523
  pollSlackOutboundWatches,
36016
36524
  posixShellSingleQuote,
36017
36525
  preferredCursorCostCents,
@@ -36109,6 +36617,7 @@ init_outbound_watch();
36109
36617
  runCloudConnect,
36110
36618
  runConventionSetup,
36111
36619
  runCursorWorktreeSetup,
36620
+ runScriptPreview,
36112
36621
  runSetupScript,
36113
36622
  runSlackListen,
36114
36623
  runSlackRelayClient,
@@ -36143,6 +36652,9 @@ init_outbound_watch();
36143
36652
  sideboardMcpProfile,
36144
36653
  sideboardReposDir,
36145
36654
  sideboardWorkspacesDir,
36655
+ skillCommandFromBody,
36656
+ skillCommandFromInput,
36657
+ skillNameFromFrontmatter,
36146
36658
  slackAppLevelToken,
36147
36659
  slackArchiveUrl,
36148
36660
  slackCoordinatorSourceRef,