@sideboard-ai/core 0.1.227 → 0.1.229

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 (44) hide show
  1. package/dist/{abletime-D6773P33.js → abletime-BGVOCEOU.js} +4 -4
  2. package/dist/{abletime-BF253OZT.js → abletime-WZNDTRVL.js} +4 -4
  3. package/dist/{abletime-oauth-KQPVVBKA.js → abletime-oauth-6M5GWEPX.js} +3 -3
  4. package/dist/{abletime-oauth-H4672PRH.js → abletime-oauth-ZLU2EYRK.js} +3 -3
  5. package/dist/{abletime-rest-DAFPXZ7H.js → abletime-rest-F7XG5NGY.js} +3 -3
  6. package/dist/{abletime-rest-OPEVV3XC.js → abletime-rest-WNHIATB3.js} +3 -3
  7. package/dist/{agents-DV5UROWB.js → agents-B7G4BQTS.js} +4 -4
  8. package/dist/{agents-QQ77D7VT.js → agents-ZKP7QNXA.js} +4 -4
  9. package/dist/{app-settings-5RQMQKSB.js → app-settings-KBL2G7M4.js} +7 -1
  10. package/dist/{app-settings-V2BBCX2H.js → app-settings-UXWCPDEA.js} +7 -1
  11. package/dist/{chunk-FUDJ6NFM.js → chunk-6HKGCUDN.js} +117 -62
  12. package/dist/{chunk-N2VST3NL.js → chunk-7YKXBFQE.js} +2 -2
  13. package/dist/{chunk-KTZESHYH.js → chunk-AMMRFFB7.js} +1 -1
  14. package/dist/{chunk-HSYE5ID6.js → chunk-AS4UN7QL.js} +5 -5
  15. package/dist/{chunk-3NWUHXU3.js → chunk-C774RJJA.js} +3 -3
  16. package/dist/{chunk-NFWPDEN4.js → chunk-F3GT6DQW.js} +1 -1
  17. package/dist/{chunk-CLI5DVU4.js → chunk-GHRZNPBK.js} +2 -2
  18. package/dist/{chunk-EWHJNJHV.js → chunk-I5NC7DWO.js} +38 -0
  19. package/dist/{chunk-VUW3VKLW.js → chunk-LULHFLPU.js} +17 -4
  20. package/dist/{chunk-646I442S.js → chunk-MVLXDYN5.js} +5 -5
  21. package/dist/{chunk-P2EAAM3H.js → chunk-N7UXGM3Y.js} +2 -2
  22. package/dist/{chunk-RRW2XWAY.js → chunk-P6ZM5QJW.js} +2 -2
  23. package/dist/{chunk-THLVCXLF.js → chunk-RGNPPRZZ.js} +3 -3
  24. package/dist/{chunk-Y5JES2VV.js → chunk-RZTRWN2V.js} +38 -0
  25. package/dist/{chunk-SOGGKYFV.js → chunk-SWNEA5OZ.js} +3 -3
  26. package/dist/{chunk-SQHRPJ7P.js → chunk-T7Y5ULHM.js} +14 -4
  27. package/dist/{chunk-I2HOATRJ.js → chunk-UHT6OS7V.js} +129 -62
  28. package/dist/{coordinator-prompt-JLMQVORO.js → coordinator-prompt-DZMMCDRW.js} +3 -3
  29. package/dist/{coordinator-prompt-VZ7OSRLD.js → coordinator-prompt-RL3GKIAQ.js} +3 -3
  30. package/dist/{global-workspace-QPSJEXGR.js → global-workspace-G3QEVRGZ.js} +3 -3
  31. package/dist/{global-workspace-3FDAUNN2.js → global-workspace-QW4OXCLJ.js} +3 -3
  32. package/dist/index.cjs +927 -658
  33. package/dist/index.d.cts +89 -3
  34. package/dist/index.d.ts +89 -3
  35. package/dist/index.js +206 -67
  36. package/dist/mcp/run-stdio.cjs +224 -84
  37. package/dist/mcp/run-stdio.js +86 -50
  38. package/dist/{orchestrator-CWOSAYAE.js → orchestrator-GKAHLGXT.js} +5 -5
  39. package/dist/{orchestrator-VKPHI64Q.js → orchestrator-X4VFA5WW.js} +5 -5
  40. package/dist/{workspaces-76W7IEKR.js → workspaces-77C5XQEY.js} +3 -3
  41. package/dist/{workspaces-TDBA64II.js → workspaces-WXRPLT2N.js} +3 -3
  42. package/dist/{worktree-I573UOPD.js → worktree-L6FJXFUC.js} +2 -2
  43. package/dist/{worktree-7V67XTEO.js → worktree-P67WAJKH.js} +2 -2
  44. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1214,12 +1214,14 @@ var init_issue_source_labels = __esm({
1214
1214
  // src/store/app-settings.ts
1215
1215
  var app_settings_exports = {};
1216
1216
  __export(app_settings_exports, {
1217
+ AGENT_DONE_SOUNDS: () => AGENT_DONE_SOUNDS,
1217
1218
  FOLLOW_UP_BEHAVIORS: () => FOLLOW_UP_BEHAVIORS,
1218
1219
  GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
1219
1220
  HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
1220
1221
  ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
1221
1222
  PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
1222
1223
  USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
1224
+ agentDoneSound: () => agentDoneSound,
1223
1225
  appSettingsPath: () => appSettingsPath,
1224
1226
  applyAppEnvironment: () => applyAppEnvironment,
1225
1227
  autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
@@ -1267,6 +1269,7 @@ __export(app_settings_exports, {
1267
1269
  historyMaxCount: () => historyMaxCount,
1268
1270
  historyMaxDays: () => historyMaxDays,
1269
1271
  isAbleTimeConnected: () => isAbleTimeConnected,
1272
+ isAgentDoneSound: () => isAgentDoneSound,
1270
1273
  isIssueSourceConnected: () => isIssueSourceConnected,
1271
1274
  isLinearConnected: () => isLinearConnected,
1272
1275
  isUsageOnLimit: () => isUsageOnLimit,
@@ -1308,6 +1311,9 @@ __export(app_settings_exports, {
1308
1311
  usageOnLimit: () => usageOnLimit,
1309
1312
  writeViewerContext: () => writeViewerContext
1310
1313
  });
1314
+ function isAgentDoneSound(value) {
1315
+ return AGENT_DONE_SOUNDS.includes(value);
1316
+ }
1311
1317
  function emptyPublicIntegrations() {
1312
1318
  return {
1313
1319
  hasLinearApiKey: false,
@@ -1738,6 +1744,13 @@ function normalizeAdvanced(raw) {
1738
1744
  if (source.followUpBehavior === "queue" || source.followUpBehavior === "steer") {
1739
1745
  out.followUpBehavior = source.followUpBehavior;
1740
1746
  }
1747
+ if (isAgentDoneSound(source.agentDoneSound)) {
1748
+ out.agentDoneSound = source.agentDoneSound;
1749
+ }
1750
+ if (typeof source.agentDoneCustomSoundName === "string") {
1751
+ const name = source.agentDoneCustomSoundName.trim();
1752
+ if (name) out.agentDoneCustomSoundName = name.slice(0, 200);
1753
+ }
1741
1754
  return out;
1742
1755
  }
1743
1756
  function normalizeSettings(raw) {
@@ -2648,6 +2661,16 @@ function updateAdvancedSettings(patch) {
2648
2661
  if (patch.followUpBehavior === "queue" || patch.followUpBehavior === "steer") {
2649
2662
  advanced.followUpBehavior = patch.followUpBehavior;
2650
2663
  }
2664
+ if (isAgentDoneSound(patch.agentDoneSound)) {
2665
+ advanced.agentDoneSound = patch.agentDoneSound;
2666
+ }
2667
+ if (patch.agentDoneCustomSoundName === null || patch.agentDoneCustomSoundName === "") {
2668
+ delete advanced.agentDoneCustomSoundName;
2669
+ } else if (typeof patch.agentDoneCustomSoundName === "string") {
2670
+ const name = patch.agentDoneCustomSoundName.trim();
2671
+ if (name) advanced.agentDoneCustomSoundName = name.slice(0, 200);
2672
+ else delete advanced.agentDoneCustomSoundName;
2673
+ }
2651
2674
  return saveAppSettings({ ...current, advanced });
2652
2675
  }
2653
2676
  function autoRenameBranchEnabled(settings = loadAppSettings()) {
@@ -2715,6 +2738,9 @@ function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
2715
2738
  function followUpBehavior(settings = loadAppSettings()) {
2716
2739
  return settings.advanced.followUpBehavior === "queue" ? "queue" : "steer";
2717
2740
  }
2741
+ function agentDoneSound(settings = loadAppSettings()) {
2742
+ return isAgentDoneSound(settings.advanced.agentDoneSound) ? settings.advanced.agentDoneSound : "none";
2743
+ }
2718
2744
  function maxConcurrentAgents(settings = loadAppSettings()) {
2719
2745
  const n = settings.advanced.maxConcurrent;
2720
2746
  if (typeof n === "number" && Number.isFinite(n)) {
@@ -2802,7 +2828,7 @@ function childEnvWithAppSettings(extra) {
2802
2828
  function harnessEnvKey(harness) {
2803
2829
  return HARNESS_ENV_KEYS[harness];
2804
2830
  }
2805
- 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, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
2831
+ 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;
2806
2832
  var init_app_settings = __esm({
2807
2833
  "src/store/app-settings.ts"() {
2808
2834
  "use strict";
@@ -2839,6 +2865,18 @@ var init_app_settings = __esm({
2839
2865
  ]);
2840
2866
  GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
2841
2867
  FOLLOW_UP_BEHAVIORS = ["steer", "queue"];
2868
+ AGENT_DONE_SOUNDS = [
2869
+ "none",
2870
+ "goal",
2871
+ "bell",
2872
+ "level",
2873
+ "coin",
2874
+ "fanfare",
2875
+ "magic",
2876
+ "rooster",
2877
+ "whistle",
2878
+ "custom"
2879
+ ];
2842
2880
  CLOUD_CONNECT_AGENTS = /* @__PURE__ */ new Set([
2843
2881
  "claude",
2844
2882
  "codex",
@@ -2883,7 +2921,7 @@ function setCaffeinateHoldHooks(next) {
2883
2921
  hooks = next;
2884
2922
  }
2885
2923
  function caffeinateHoldPath() {
2886
- return (0, import_node_path9.join)(appDataDir(), "caffeinate-hold.json");
2924
+ return (0, import_node_path10.join)(appDataDir(), "caffeinate-hold.json");
2887
2925
  }
2888
2926
  function processAlive(pid) {
2889
2927
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -2917,9 +2955,9 @@ function uniqueIds(ids) {
2917
2955
  }
2918
2956
  function readHold() {
2919
2957
  const path2 = caffeinateHoldPath();
2920
- if (!(0, import_node_fs8.existsSync)(path2)) return null;
2958
+ if (!(0, import_node_fs9.existsSync)(path2)) return null;
2921
2959
  try {
2922
- const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path2, "utf8"));
2960
+ const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path2, "utf8"));
2923
2961
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
2924
2962
  return {
2925
2963
  pid: parsed.pid,
@@ -2941,7 +2979,7 @@ function writeHold(pid, threadIds) {
2941
2979
  }
2942
2980
  function clearHold() {
2943
2981
  try {
2944
- (0, import_node_fs8.unlinkSync)(caffeinateHoldPath());
2982
+ (0, import_node_fs9.unlinkSync)(caffeinateHoldPath());
2945
2983
  } catch {
2946
2984
  }
2947
2985
  }
@@ -3026,13 +3064,13 @@ function releaseCaffeinateHoldForThread(threadId) {
3026
3064
  }
3027
3065
  return setCaffeinateHold(false, { threadId: id });
3028
3066
  }
3029
- var import_node_child_process2, import_node_fs8, import_node_path9, hooks;
3067
+ var import_node_child_process2, import_node_fs9, import_node_path10, hooks;
3030
3068
  var init_caffeinate_hold = __esm({
3031
3069
  "src/store/caffeinate-hold.ts"() {
3032
3070
  "use strict";
3033
3071
  import_node_child_process2 = require("child_process");
3034
- import_node_fs8 = require("fs");
3035
- import_node_path9 = require("path");
3072
+ import_node_fs9 = require("fs");
3073
+ import_node_path10 = require("path");
3036
3074
  init_paths();
3037
3075
  init_private_file();
3038
3076
  hooks = {};
@@ -3041,13 +3079,13 @@ var init_caffeinate_hold = __esm({
3041
3079
 
3042
3080
  // src/agents/cursor-store.ts
3043
3081
  function cursorSdkStoreDir(threadId) {
3044
- const root = (0, import_node_path10.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
3082
+ const root = (0, import_node_path11.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
3045
3083
  const id = sanitizeCursorStoreSegment(threadId);
3046
3084
  if (!id) return root;
3047
- return (0, import_node_path10.join)(root, "threads", id);
3085
+ return (0, import_node_path11.join)(root, "threads", id);
3048
3086
  }
3049
3087
  function cursorSdkRunsNdjsonPath(threadId) {
3050
- return (0, import_node_path10.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
3088
+ return (0, import_node_path11.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
3051
3089
  }
3052
3090
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
3053
3091
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -3060,11 +3098,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
3060
3098
  function sanitizeCursorStoreSegment(threadId) {
3061
3099
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
3062
3100
  }
3063
- var import_node_path10, CURSOR_SDK_STORE_DIR;
3101
+ var import_node_path11, CURSOR_SDK_STORE_DIR;
3064
3102
  var init_cursor_store = __esm({
3065
3103
  "src/agents/cursor-store.ts"() {
3066
3104
  "use strict";
3067
- import_node_path10 = require("path");
3105
+ import_node_path11 = require("path");
3068
3106
  init_paths();
3069
3107
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
3070
3108
  }
@@ -3174,7 +3212,7 @@ function createEmptyThread(partial) {
3174
3212
  }
3175
3213
  async function withThreadLock(id, fn) {
3176
3214
  const lockPath = threadLockPath(id);
3177
- (0, import_node_fs9.writeFileSync)(lockPath, "", { flag: "a" });
3215
+ (0, import_node_fs10.writeFileSync)(lockPath, "", { flag: "a" });
3178
3216
  let release;
3179
3217
  try {
3180
3218
  release = await import_proper_lockfile.default.lock(lockPath, {
@@ -3195,7 +3233,7 @@ function cacheForDir() {
3195
3233
  }
3196
3234
  function fileMtimeMs(path2) {
3197
3235
  try {
3198
- return (0, import_node_fs9.statSync)(path2).mtimeMs;
3236
+ return (0, import_node_fs10.statSync)(path2).mtimeMs;
3199
3237
  } catch {
3200
3238
  return null;
3201
3239
  }
@@ -3228,7 +3266,7 @@ function readThread(id) {
3228
3266
  const cache2 = cacheForDir();
3229
3267
  const cached = cache2.byId.get(id);
3230
3268
  if (cached && cache2.mtimeMs.get(id) === mtimeMs) return cached;
3231
- const raw = (0, import_node_fs9.readFileSync)(path2, "utf8");
3269
+ const raw = (0, import_node_fs10.readFileSync)(path2, "utf8");
3232
3270
  const thread = normalizeThread(JSON.parse(raw));
3233
3271
  rememberThread(thread, mtimeMs);
3234
3272
  return thread;
@@ -3237,8 +3275,8 @@ function writeThread(thread, opts) {
3237
3275
  const path2 = threadFilePath(idPath(thread.id));
3238
3276
  const tmp = `${path2}.${process.pid}.tmp`;
3239
3277
  const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
3240
- (0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
3241
- (0, import_node_fs9.renameSync)(tmp, path2);
3278
+ (0, import_node_fs10.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
3279
+ (0, import_node_fs10.renameSync)(tmp, path2);
3242
3280
  const mtimeMs = fileMtimeMs(path2) ?? Date.now();
3243
3281
  rememberThread(next, mtimeMs);
3244
3282
  selfWriteMtimes.set(thread.id, mtimeMs);
@@ -3252,12 +3290,12 @@ function idPath(id) {
3252
3290
  return id;
3253
3291
  }
3254
3292
  function isThreadRecordFile(nameOrPath) {
3255
- const name = (0, import_node_path11.basename)(nameOrPath);
3293
+ const name = (0, import_node_path12.basename)(nameOrPath);
3256
3294
  return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
3257
3295
  }
3258
3296
  function listThreads(opts) {
3259
3297
  const cache2 = cacheForDir();
3260
- const files = (0, import_node_fs9.readdirSync)(threadsDir()).filter(isThreadRecordFile);
3298
+ const files = (0, import_node_fs10.readdirSync)(threadsDir()).filter(isThreadRecordFile);
3261
3299
  const seen = /* @__PURE__ */ new Set();
3262
3300
  for (const f of files) {
3263
3301
  const id = f.replace(/\.json$/, "");
@@ -3280,16 +3318,16 @@ function listThreads(opts) {
3280
3318
  function deleteThreadRecord(id) {
3281
3319
  forgetThread(id);
3282
3320
  const path2 = threadFilePath(id);
3283
- if ((0, import_node_fs9.existsSync)(path2)) (0, import_node_fs9.unlinkSync)(path2);
3321
+ if ((0, import_node_fs10.existsSync)(path2)) (0, import_node_fs10.unlinkSync)(path2);
3284
3322
  const lock = threadLockPath(id);
3285
- if ((0, import_node_fs9.existsSync)(lock)) {
3323
+ if ((0, import_node_fs10.existsSync)(lock)) {
3286
3324
  try {
3287
- (0, import_node_fs9.unlinkSync)(lock);
3325
+ (0, import_node_fs10.unlinkSync)(lock);
3288
3326
  } catch {
3289
3327
  }
3290
3328
  }
3291
3329
  try {
3292
- (0, import_node_fs9.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
3330
+ (0, import_node_fs10.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
3293
3331
  } catch {
3294
3332
  }
3295
3333
  }
@@ -3319,13 +3357,13 @@ function findThreadByRef(ref) {
3319
3357
  (t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
3320
3358
  ) ?? null;
3321
3359
  }
3322
- var import_node_crypto3, import_node_fs9, import_node_path11, import_proper_lockfile, listCache, selfWriteMtimes;
3360
+ var import_node_crypto3, import_node_fs10, import_node_path12, import_proper_lockfile, listCache, selfWriteMtimes;
3323
3361
  var init_thread_store = __esm({
3324
3362
  "src/store/thread-store.ts"() {
3325
3363
  "use strict";
3326
3364
  import_node_crypto3 = require("crypto");
3327
- import_node_fs9 = require("fs");
3328
- import_node_path11 = require("path");
3365
+ import_node_fs10 = require("fs");
3366
+ import_node_path12 = require("path");
3329
3367
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
3330
3368
  init_thinking_effort();
3331
3369
  init_cursor_store();
@@ -3810,6 +3848,13 @@ function toolDescription(name, input) {
3810
3848
  if (/stop_job$/i.test(name)) {
3811
3849
  return str(input?.id) ? `Stop ${str(input?.id)}` : "Stop job";
3812
3850
  }
3851
+ if (/list_run_scripts$/i.test(name)) return "List run scripts";
3852
+ if (/run_dev_script$/i.test(name)) {
3853
+ return str(input?.name) ? `Start ${str(input?.name)}` : "Start Dev script";
3854
+ }
3855
+ if (/stop_dev_script$/i.test(name)) {
3856
+ return str(input?.name) ? `Stop ${str(input?.name)}` : "Stop Dev script";
3857
+ }
3813
3858
  if (isSubagentToolName(name)) {
3814
3859
  const desc = str(input?.description);
3815
3860
  const sub = asRecord(input?.subagentType);
@@ -5790,7 +5835,7 @@ function materialize(mem) {
5790
5835
  };
5791
5836
  }
5792
5837
  function setupLogPath(threadId) {
5793
- return (0, import_node_path12.join)(threadsDir(), `${threadId}.setup.log.json`);
5838
+ return (0, import_node_path13.join)(threadsDir(), `${threadId}.setup.log.json`);
5794
5839
  }
5795
5840
  function setupLogKeyForWorktree(worktreePath) {
5796
5841
  const norm = normalizeWorktreePath(worktreePath);
@@ -5816,7 +5861,7 @@ function persistNow(threadId) {
5816
5861
  const mem = memory.get(threadId);
5817
5862
  if (!mem) return;
5818
5863
  try {
5819
- (0, import_node_fs10.writeFileSync)(
5864
+ (0, import_node_fs11.writeFileSync)(
5820
5865
  setupLogPath(threadId),
5821
5866
  `${JSON.stringify(materialize(mem))}
5822
5867
  `,
@@ -5837,9 +5882,9 @@ function schedulePersist(threadId) {
5837
5882
  }
5838
5883
  function loadFromDisk(threadId) {
5839
5884
  const path2 = setupLogPath(threadId);
5840
- if (!(0, import_node_fs10.existsSync)(path2)) return null;
5885
+ if (!(0, import_node_fs11.existsSync)(path2)) return null;
5841
5886
  try {
5842
- const raw = JSON.parse((0, import_node_fs10.readFileSync)(path2, "utf8"));
5887
+ const raw = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
5843
5888
  return {
5844
5889
  output: typeof raw.output === "string" ? raw.output : "",
5845
5890
  running: Boolean(raw.running),
@@ -5895,13 +5940,13 @@ function finishSetupLog(threadId, exitCode, source) {
5895
5940
  persistNow(threadId);
5896
5941
  return materialize(mem);
5897
5942
  }
5898
- var import_node_crypto4, import_node_fs10, import_node_path12, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
5943
+ var import_node_crypto4, import_node_fs11, import_node_path13, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
5899
5944
  var init_setup_log = __esm({
5900
5945
  "src/store/setup-log.ts"() {
5901
5946
  "use strict";
5902
5947
  import_node_crypto4 = require("crypto");
5903
- import_node_fs10 = require("fs");
5904
- import_node_path12 = require("path");
5948
+ import_node_fs11 = require("fs");
5949
+ import_node_path13 = require("path");
5905
5950
  init_worktree_labels();
5906
5951
  init_paths();
5907
5952
  EMPTY = {
@@ -5919,7 +5964,7 @@ var init_setup_log = __esm({
5919
5964
 
5920
5965
  // src/store/schedules.ts
5921
5966
  function schedulesPath() {
5922
- return (0, import_node_path13.join)(appDataDir(), "schedules.json");
5967
+ return (0, import_node_path14.join)(appDataDir(), "schedules.json");
5923
5968
  }
5924
5969
  function parseDurationMs(every) {
5925
5970
  const m = every.trim().match(DURATION_RE);
@@ -6025,9 +6070,9 @@ function normalizeTask(raw) {
6025
6070
  }
6026
6071
  function readAll() {
6027
6072
  const path2 = schedulesPath();
6028
- if (!(0, import_node_fs11.existsSync)(path2)) return [];
6073
+ if (!(0, import_node_fs12.existsSync)(path2)) return [];
6029
6074
  try {
6030
- const parsed = JSON.parse((0, import_node_fs11.readFileSync)(path2, "utf8"));
6075
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path2, "utf8"));
6031
6076
  if (!Array.isArray(parsed)) return [];
6032
6077
  return parsed.map((row) => {
6033
6078
  try {
@@ -6142,13 +6187,13 @@ function recordScheduleRun(id, result) {
6142
6187
  writeAll(rows);
6143
6188
  return next;
6144
6189
  }
6145
- var import_node_crypto5, import_node_fs11, import_node_path13, import_croner, DURATION_RE, UNIT_MS;
6190
+ var import_node_crypto5, import_node_fs12, import_node_path14, import_croner, DURATION_RE, UNIT_MS;
6146
6191
  var init_schedules = __esm({
6147
6192
  "src/store/schedules.ts"() {
6148
6193
  "use strict";
6149
6194
  import_node_crypto5 = require("crypto");
6150
- import_node_fs11 = require("fs");
6151
- import_node_path13 = require("path");
6195
+ import_node_fs12 = require("fs");
6196
+ import_node_path14 = require("path");
6152
6197
  import_croner = require("croner");
6153
6198
  init_orchestrator_capable();
6154
6199
  init_paths();
@@ -6165,22 +6210,22 @@ var init_schedules = __esm({
6165
6210
 
6166
6211
  // src/store/desktop-host.ts
6167
6212
  function desktopHostPidPath() {
6168
- return (0, import_node_path14.join)(appDataDir(), "desktop-host.pid");
6213
+ return (0, import_node_path15.join)(appDataDir(), "desktop-host.pid");
6169
6214
  }
6170
6215
  function claimDesktopHost(pid = process.pid) {
6171
- (0, import_node_fs12.writeFileSync)(desktopHostPidPath(), `${pid}
6216
+ (0, import_node_fs13.writeFileSync)(desktopHostPidPath(), `${pid}
6172
6217
  `, "utf8");
6173
6218
  }
6174
6219
  function releaseDesktopHost(pid = process.pid) {
6175
6220
  if (readDesktopHostPid() !== pid) return;
6176
6221
  try {
6177
- (0, import_node_fs12.unlinkSync)(desktopHostPidPath());
6222
+ (0, import_node_fs13.unlinkSync)(desktopHostPidPath());
6178
6223
  } catch {
6179
6224
  }
6180
6225
  }
6181
6226
  function readDesktopHostPid() {
6182
6227
  try {
6183
- const pid = Number.parseInt((0, import_node_fs12.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
6228
+ const pid = Number.parseInt((0, import_node_fs13.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
6184
6229
  if (!Number.isFinite(pid) || pid <= 0) return null;
6185
6230
  return pid;
6186
6231
  } catch {
@@ -6206,12 +6251,12 @@ function thisProcessShouldDrainAgentQueues() {
6206
6251
  if (isThisProcessDesktopHost()) return true;
6207
6252
  return !isDesktopHostAlive();
6208
6253
  }
6209
- var import_node_fs12, import_node_path14;
6254
+ var import_node_fs13, import_node_path15;
6210
6255
  var init_desktop_host = __esm({
6211
6256
  "src/store/desktop-host.ts"() {
6212
6257
  "use strict";
6213
- import_node_fs12 = require("fs");
6214
- import_node_path14 = require("path");
6258
+ import_node_fs13 = require("fs");
6259
+ import_node_path15 = require("path");
6215
6260
  init_paths();
6216
6261
  }
6217
6262
  });
@@ -6278,7 +6323,7 @@ var init_workspace_scratch = __esm({
6278
6323
 
6279
6324
  // src/composer/stage-files.ts
6280
6325
  function fileExtension(filePath) {
6281
- const base = (0, import_node_path15.basename)(filePath).toLowerCase();
6326
+ const base = (0, import_node_path16.basename)(filePath).toLowerCase();
6282
6327
  return base.includes(".") ? base.split(".").pop() || "" : "";
6283
6328
  }
6284
6329
  function isImageFilePath(filePath) {
@@ -6288,22 +6333,22 @@ function imageMimeType(filePath) {
6288
6333
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
6289
6334
  }
6290
6335
  function ensureAttachmentsDir(worktreePath) {
6291
- const dir = (0, import_node_path15.join)(worktreePath, ATTACHMENTS_DIR);
6292
- (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
6293
- const gi = (0, import_node_path15.join)(dir, ".gitignore");
6294
- if (!(0, import_node_fs13.existsSync)(gi)) {
6295
- (0, import_node_fs13.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
6336
+ const dir = (0, import_node_path16.join)(worktreePath, ATTACHMENTS_DIR);
6337
+ (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
6338
+ const gi = (0, import_node_path16.join)(dir, ".gitignore");
6339
+ if (!(0, import_node_fs14.existsSync)(gi)) {
6340
+ (0, import_node_fs14.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
6296
6341
  }
6297
6342
  return dir;
6298
6343
  }
6299
6344
  function uniqueAttachmentName(dir, originalName) {
6300
6345
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
6301
- if (!(0, import_node_fs13.existsSync)((0, import_node_path15.join)(dir, safe))) return safe;
6302
- const ext = (0, import_node_path15.extname)(safe);
6346
+ if (!(0, import_node_fs14.existsSync)((0, import_node_path16.join)(dir, safe))) return safe;
6347
+ const ext = (0, import_node_path16.extname)(safe);
6303
6348
  const stem = ext ? safe.slice(0, -ext.length) : safe;
6304
6349
  for (let i = 1; i < 1e4; i++) {
6305
6350
  const candidate = `${stem}-${i}${ext}`;
6306
- if (!(0, import_node_fs13.existsSync)((0, import_node_path15.join)(dir, candidate))) return candidate;
6351
+ if (!(0, import_node_fs14.existsSync)((0, import_node_path16.join)(dir, candidate))) return candidate;
6307
6352
  }
6308
6353
  return `${stem}-${(0, import_node_crypto6.randomUUID)()}${ext}`;
6309
6354
  }
@@ -6355,9 +6400,9 @@ function attachmentFromBuffer(name, buf, opts) {
6355
6400
  };
6356
6401
  }
6357
6402
  function attachmentFromAbsolutePath(absolutePath) {
6358
- const name = (0, import_node_path15.basename)(absolutePath);
6403
+ const name = (0, import_node_path16.basename)(absolutePath);
6359
6404
  try {
6360
- const st = (0, import_node_fs13.statSync)(absolutePath);
6405
+ const st = (0, import_node_fs14.statSync)(absolutePath);
6361
6406
  if (!st.isFile()) {
6362
6407
  return {
6363
6408
  id: (0, import_node_crypto6.randomUUID)(),
@@ -6366,7 +6411,7 @@ function attachmentFromAbsolutePath(absolutePath) {
6366
6411
  content: `(not a file: ${absolutePath})`
6367
6412
  };
6368
6413
  }
6369
- const buf = (0, import_node_fs13.readFileSync)(absolutePath);
6414
+ const buf = (0, import_node_fs14.readFileSync)(absolutePath);
6370
6415
  return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
6371
6416
  } catch (err) {
6372
6417
  return {
@@ -6382,15 +6427,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
6382
6427
  const dir = ensureAttachmentsDir(worktreePath);
6383
6428
  const out = [];
6384
6429
  for (const abs of absolutePaths) {
6385
- const originalName = (0, import_node_path15.basename)(abs);
6430
+ const originalName = (0, import_node_path16.basename)(abs);
6386
6431
  try {
6387
- const st = (0, import_node_fs13.statSync)(abs);
6432
+ const st = (0, import_node_fs14.statSync)(abs);
6388
6433
  if (!st.isFile()) continue;
6389
6434
  const name = uniqueAttachmentName(dir, originalName);
6390
- const destAbs = (0, import_node_path15.join)(dir, name);
6391
- (0, import_node_fs13.copyFileSync)(abs, destAbs);
6435
+ const destAbs = (0, import_node_path16.join)(dir, name);
6436
+ (0, import_node_fs14.copyFileSync)(abs, destAbs);
6392
6437
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6393
- const buf = (0, import_node_fs13.readFileSync)(destAbs);
6438
+ const buf = (0, import_node_fs14.readFileSync)(destAbs);
6394
6439
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
6395
6440
  } catch (err) {
6396
6441
  out.push({
@@ -6412,8 +6457,8 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
6412
6457
  try {
6413
6458
  const buf = Buffer.from(item.dataBase64, "base64");
6414
6459
  const name = uniqueAttachmentName(dir, originalName);
6415
- const destAbs = (0, import_node_path15.join)(dir, name);
6416
- (0, import_node_fs13.writeFileSync)(destAbs, buf);
6460
+ const destAbs = (0, import_node_path16.join)(dir, name);
6461
+ (0, import_node_fs14.writeFileSync)(destAbs, buf);
6417
6462
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6418
6463
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
6419
6464
  } catch (err) {
@@ -6490,18 +6535,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6490
6535
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
6491
6536
  out.push({
6492
6537
  id: (0, import_node_crypto6.randomUUID)(),
6493
- name: (0, import_node_path15.basename)(rel) || "file",
6538
+ name: (0, import_node_path16.basename)(rel) || "file",
6494
6539
  kind: "file",
6495
6540
  content: `(invalid path: ${rel})`
6496
6541
  });
6497
6542
  continue;
6498
6543
  }
6499
- const name = (0, import_node_path15.basename)(rel);
6544
+ const name = (0, import_node_path16.basename)(rel);
6500
6545
  try {
6501
- const abs = (0, import_node_path15.join)(worktreePath, rel);
6502
- const st = (0, import_node_fs13.statSync)(abs);
6546
+ const abs = (0, import_node_path16.join)(worktreePath, rel);
6547
+ const st = (0, import_node_fs14.statSync)(abs);
6503
6548
  if (!st.isFile()) continue;
6504
- const buf = (0, import_node_fs13.readFileSync)(abs);
6549
+ const buf = (0, import_node_fs14.readFileSync)(abs);
6505
6550
  out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
6506
6551
  } catch (err) {
6507
6552
  out.push({
@@ -6514,12 +6559,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6514
6559
  }
6515
6560
  return out;
6516
6561
  }
6517
- var import_node_fs13, import_node_path15, import_node_crypto6, IMAGE_EXTENSIONS, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES, IMAGE_HINT_RE, PLACEHOLDER_CONTENT_RE;
6562
+ 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;
6518
6563
  var init_stage_files = __esm({
6519
6564
  "src/composer/stage-files.ts"() {
6520
6565
  "use strict";
6521
- import_node_fs13 = require("fs");
6522
- import_node_path15 = require("path");
6566
+ import_node_fs14 = require("fs");
6567
+ import_node_path16 = require("path");
6523
6568
  import_node_crypto6 = require("crypto");
6524
6569
  init_workspace_scratch();
6525
6570
  IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -6661,17 +6706,17 @@ var init_gh_errors = __esm({
6661
6706
 
6662
6707
  // src/agents/path.ts
6663
6708
  function prependPathDir(env, dir) {
6664
- if (!dir || !(0, import_node_fs14.existsSync)(dir)) return;
6709
+ if (!dir || !(0, import_node_fs15.existsSync)(dir)) return;
6665
6710
  const current = env.PATH ?? "";
6666
- const parts = current.split(import_node_path16.delimiter).filter(Boolean);
6711
+ const parts = current.split(import_node_path17.delimiter).filter(Boolean);
6667
6712
  if (parts.includes(dir)) {
6668
6713
  env.PATH = current;
6669
6714
  return;
6670
6715
  }
6671
- env.PATH = [dir, ...parts].join(import_node_path16.delimiter);
6716
+ env.PATH = [dir, ...parts].join(import_node_path17.delimiter);
6672
6717
  }
6673
6718
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
6674
- return (0, import_node_path16.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6719
+ return (0, import_node_path17.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6675
6720
  }
6676
6721
  function isConductorBundledCli(filePath) {
6677
6722
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -6680,21 +6725,21 @@ function isConductorBundledCli(filePath) {
6680
6725
  function ensureAgentPath(env = process.env) {
6681
6726
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
6682
6727
  const current = env.PATH ?? "";
6683
- const parts = current.split(import_node_path16.delimiter).filter(Boolean);
6728
+ const parts = current.split(import_node_path17.delimiter).filter(Boolean);
6684
6729
  const seen = new Set(parts);
6685
6730
  const extras = [
6686
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path16.join)(home, rel)),
6731
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path17.join)(home, rel)),
6687
6732
  "/opt/homebrew/bin",
6688
6733
  "/usr/local/bin",
6689
6734
  // Keep after Homebrew/npm so a user-installed CLI still wins.
6690
6735
  conductorBundledBinDir(home)
6691
6736
  ];
6692
6737
  for (const dir of extras.reverse()) {
6693
- if (!dir || seen.has(dir) || !(0, import_node_fs14.existsSync)(dir)) continue;
6738
+ if (!dir || seen.has(dir) || !(0, import_node_fs15.existsSync)(dir)) continue;
6694
6739
  parts.unshift(dir);
6695
6740
  seen.add(dir);
6696
6741
  }
6697
- const next = parts.join(import_node_path16.delimiter);
6742
+ const next = parts.join(import_node_path17.delimiter);
6698
6743
  env.PATH = next;
6699
6744
  return next;
6700
6745
  }
@@ -6708,7 +6753,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
6708
6753
  stdio: ["ignore", "pipe", "ignore"]
6709
6754
  }).trim().split(/\r?\n/).find(Boolean);
6710
6755
  if (prefix) {
6711
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path16.join)(prefix, "bin");
6756
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path17.join)(prefix, "bin");
6712
6757
  prependPathDir(env, binDir);
6713
6758
  }
6714
6759
  } catch {
@@ -6736,14 +6781,14 @@ function withExportedPath(command, pathValue) {
6736
6781
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
6737
6782
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
6738
6783
  }
6739
- var import_node_fs14, import_node_child_process3, import_node_os4, import_node_path16, EXTRA_BIN_DIRS;
6784
+ var import_node_fs15, import_node_child_process3, import_node_os4, import_node_path17, EXTRA_BIN_DIRS;
6740
6785
  var init_path = __esm({
6741
6786
  "src/agents/path.ts"() {
6742
6787
  "use strict";
6743
- import_node_fs14 = require("fs");
6788
+ import_node_fs15 = require("fs");
6744
6789
  import_node_child_process3 = require("child_process");
6745
6790
  import_node_os4 = require("os");
6746
- import_node_path16 = require("path");
6791
+ import_node_path17 = require("path");
6747
6792
  EXTRA_BIN_DIRS = [
6748
6793
  ".local/bin",
6749
6794
  ".cargo/bin",
@@ -6764,23 +6809,23 @@ var init_path = __esm({
6764
6809
  function githubAgentAuthDir() {
6765
6810
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
6766
6811
  if (override) return override;
6767
- return (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6812
+ return (0, import_node_path18.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6768
6813
  }
6769
6814
  function githubCredentialStorePath() {
6770
- return (0, import_node_path17.join)(githubAgentAuthDir(), "git-credentials");
6815
+ return (0, import_node_path18.join)(githubAgentAuthDir(), "git-credentials");
6771
6816
  }
6772
6817
  function githubGhConfigDir() {
6773
- return (0, import_node_path17.join)(githubAgentAuthDir(), "gh");
6818
+ return (0, import_node_path18.join)(githubAgentAuthDir(), "gh");
6774
6819
  }
6775
6820
  function writePrivateFile2(file, body) {
6776
- (0, import_node_fs15.mkdirSync)((0, import_node_path17.dirname)(file), { recursive: true, mode: 448 });
6821
+ (0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(file), { recursive: true, mode: 448 });
6777
6822
  try {
6778
- (0, import_node_fs15.chmodSync)((0, import_node_path17.dirname)(file), 448);
6823
+ (0, import_node_fs16.chmodSync)((0, import_node_path18.dirname)(file), 448);
6779
6824
  } catch {
6780
6825
  }
6781
- (0, import_node_fs15.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
6826
+ (0, import_node_fs16.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
6782
6827
  try {
6783
- (0, import_node_fs15.chmodSync)(file, 384);
6828
+ (0, import_node_fs16.chmodSync)(file, 384);
6784
6829
  } catch {
6785
6830
  }
6786
6831
  }
@@ -6805,19 +6850,19 @@ function materializeGithubAgentAuth(token, user) {
6805
6850
  const trimmed = token.trim();
6806
6851
  if (!trimmed) return;
6807
6852
  const root = githubAgentAuthDir();
6808
- (0, import_node_fs15.mkdirSync)(root, { recursive: true, mode: 448 });
6853
+ (0, import_node_fs16.mkdirSync)(root, { recursive: true, mode: 448 });
6809
6854
  try {
6810
- (0, import_node_fs15.chmodSync)(root, 448);
6855
+ (0, import_node_fs16.chmodSync)(root, 448);
6811
6856
  } catch {
6812
6857
  }
6813
6858
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
6814
6859
  const ghDir = githubGhConfigDir();
6815
- (0, import_node_fs15.mkdirSync)(ghDir, { recursive: true, mode: 448 });
6816
- writePrivateFile2((0, import_node_path17.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6817
- writePrivateFile2((0, import_node_path17.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6860
+ (0, import_node_fs16.mkdirSync)(ghDir, { recursive: true, mode: 448 });
6861
+ writePrivateFile2((0, import_node_path18.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6862
+ writePrivateFile2((0, import_node_path18.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6818
6863
  }
6819
6864
  function githubAgentAuthReady() {
6820
- return (0, import_node_fs15.existsSync)(githubCredentialStorePath()) && (0, import_node_fs15.existsSync)((0, import_node_path17.join)(githubGhConfigDir(), "hosts.yml"));
6865
+ return (0, import_node_fs16.existsSync)(githubCredentialStorePath()) && (0, import_node_fs16.existsSync)((0, import_node_path18.join)(githubGhConfigDir(), "hosts.yml"));
6821
6866
  }
6822
6867
  function githubCredentialHelperGitConfig() {
6823
6868
  const file = githubCredentialStorePath();
@@ -6832,13 +6877,13 @@ function githubGhConfigEnv() {
6832
6877
  GH_PROMPT_DISABLED: "1"
6833
6878
  };
6834
6879
  }
6835
- var import_node_fs15, import_node_os5, import_node_path17;
6880
+ var import_node_fs16, import_node_os5, import_node_path18;
6836
6881
  var init_github_agent_auth = __esm({
6837
6882
  "src/git/github-agent-auth.ts"() {
6838
6883
  "use strict";
6839
- import_node_fs15 = require("fs");
6884
+ import_node_fs16 = require("fs");
6840
6885
  import_node_os5 = require("os");
6841
- import_node_path17 = require("path");
6886
+ import_node_path18 = require("path");
6842
6887
  }
6843
6888
  });
6844
6889
 
@@ -6847,11 +6892,11 @@ function isIndexLockError(text7) {
6847
6892
  return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text7);
6848
6893
  }
6849
6894
  function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
6850
- const lockPath = (0, import_node_path18.join)(gitDir, "index.lock");
6895
+ const lockPath = (0, import_node_path19.join)(gitDir, "index.lock");
6851
6896
  try {
6852
- if (!(0, import_node_fs16.existsSync)(lockPath)) return null;
6853
- if (now - (0, import_node_fs16.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
6854
- (0, import_node_fs16.unlinkSync)(lockPath);
6897
+ if (!(0, import_node_fs17.existsSync)(lockPath)) return null;
6898
+ if (now - (0, import_node_fs17.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
6899
+ (0, import_node_fs17.unlinkSync)(lockPath);
6855
6900
  return lockPath;
6856
6901
  } catch {
6857
6902
  return null;
@@ -6866,12 +6911,12 @@ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
6866
6911
  }
6867
6912
  return removed;
6868
6913
  }
6869
- var import_node_fs16, import_node_path18, STALE_INDEX_LOCK_MS;
6914
+ var import_node_fs17, import_node_path19, STALE_INDEX_LOCK_MS;
6870
6915
  var init_stale_lock = __esm({
6871
6916
  "src/git/stale-lock.ts"() {
6872
6917
  "use strict";
6873
- import_node_fs16 = require("fs");
6874
- import_node_path18 = require("path");
6918
+ import_node_fs17 = require("fs");
6919
+ import_node_path19 = require("path");
6875
6920
  STALE_INDEX_LOCK_MS = 2e4;
6876
6921
  }
6877
6922
  });
@@ -7012,11 +7057,11 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
7012
7057
  if (gitDir.exitCode !== 0) return;
7013
7058
  const dir = gitDir.stdout.trim();
7014
7059
  if (!dir) return;
7015
- const excludePath = (0, import_node_path19.join)(dir, "info", "exclude");
7016
- (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(excludePath), { recursive: true });
7060
+ const excludePath = (0, import_node_path20.join)(dir, "info", "exclude");
7061
+ (0, import_node_fs18.mkdirSync)((0, import_node_path20.dirname)(excludePath), { recursive: true });
7017
7062
  let body = "";
7018
7063
  try {
7019
- body = (0, import_node_fs17.readFileSync)(excludePath, "utf8");
7064
+ body = (0, import_node_fs18.readFileSync)(excludePath, "utf8");
7020
7065
  } catch {
7021
7066
  body = "";
7022
7067
  }
@@ -7032,7 +7077,7 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
7032
7077
  ` : body;
7033
7078
  const header = body.includes(EXCLUDE_COMMENT) ? "" : `${EXCLUDE_COMMENT}
7034
7079
  `;
7035
- (0, import_node_fs17.writeFileSync)(excludePath, `${prefix}${header}${missing.join("\n")}
7080
+ (0, import_node_fs18.writeFileSync)(excludePath, `${prefix}${header}${missing.join("\n")}
7036
7081
  `, "utf8");
7037
7082
  }
7038
7083
  const listed = await git(["ls-files", "-z", "--", ".sideboard"], worktreePath, {
@@ -7047,12 +7092,12 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
7047
7092
  timeoutMs: 8e3
7048
7093
  });
7049
7094
  }
7050
- var import_node_fs17, import_node_path19, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
7095
+ var import_node_fs18, import_node_path20, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
7051
7096
  var init_worktree_exclude = __esm({
7052
7097
  "src/git/worktree-exclude.ts"() {
7053
7098
  "use strict";
7054
- import_node_fs17 = require("fs");
7055
- import_node_path19 = require("path");
7099
+ import_node_fs18 = require("fs");
7100
+ import_node_path20 = require("path");
7056
7101
  init_run();
7057
7102
  WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
7058
7103
  WORKTREE_CONTEXT_EXCLUDE = ".context/";
@@ -7173,7 +7218,7 @@ async function warmGithubAgentAuth(opts) {
7173
7218
  }
7174
7219
  function normalizeWritableRoot(raw) {
7175
7220
  const trimmed = raw.trim().replace(/\/+$/, "");
7176
- return trimmed && (0, import_node_path20.isAbsolute)(trimmed) ? trimmed : null;
7221
+ return trimmed && (0, import_node_path21.isAbsolute)(trimmed) ? trimmed : null;
7177
7222
  }
7178
7223
  async function resolveCodexGitWritableRoots(cwd) {
7179
7224
  const roots = /* @__PURE__ */ new Set();
@@ -7251,11 +7296,11 @@ function formatGitAuthModeDirective(mode) {
7251
7296
  ].join("\n");
7252
7297
  }
7253
7298
  }
7254
- var import_node_path20, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7299
+ var import_node_path21, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7255
7300
  var init_git_auth_mode = __esm({
7256
7301
  "src/git/git-auth-mode.ts"() {
7257
7302
  "use strict";
7258
- import_node_path20 = require("path");
7303
+ import_node_path21 = require("path");
7259
7304
  init_app_settings();
7260
7305
  init_github_agent_auth();
7261
7306
  init_run();
@@ -8091,7 +8136,7 @@ async function resolveRepoRoot(cwd) {
8091
8136
  }
8092
8137
  function canonicalizeRepoPath(path2) {
8093
8138
  try {
8094
- return (0, import_node_fs18.realpathSync)(path2);
8139
+ return (0, import_node_fs19.realpathSync)(path2);
8095
8140
  } catch {
8096
8141
  return path2.replace(/\/+$/, "");
8097
8142
  }
@@ -8952,8 +8997,8 @@ async function refreshOriginAndMaybeFastForwardMain(repoPath, sourceRef) {
8952
8997
  }
8953
8998
  async function createThreadWorktree(opts) {
8954
8999
  let branchName = `thread/${opts.slug}`;
8955
- const worktreePath = (0, import_node_path21.join)(worktreesRoot(opts.repoPath), opts.slug);
8956
- if ((0, import_node_fs18.existsSync)(worktreePath)) {
9000
+ const worktreePath = (0, import_node_path22.join)(worktreesRoot(opts.repoPath), opts.slug);
9001
+ if ((0, import_node_fs19.existsSync)(worktreePath)) {
8957
9002
  throw new Error(`Worktree already exists at ${worktreePath}`);
8958
9003
  }
8959
9004
  await ensureGhPreferOrigin(opts.repoPath);
@@ -8994,8 +9039,8 @@ ${add.stdout}`;
8994
9039
  async function createExistingBranchWorktree(opts) {
8995
9040
  const branchName = opts.branchName.trim();
8996
9041
  if (!branchName) throw new Error("branch name required");
8997
- const worktreePath = (0, import_node_path21.join)(worktreesRoot(opts.repoPath), opts.slug);
8998
- if ((0, import_node_fs18.existsSync)(worktreePath)) {
9042
+ const worktreePath = (0, import_node_path22.join)(worktreesRoot(opts.repoPath), opts.slug);
9043
+ if ((0, import_node_fs19.existsSync)(worktreePath)) {
8999
9044
  throw new Error(`Worktree already exists at ${worktreePath}`);
9000
9045
  }
9001
9046
  await ensureGhPreferOrigin(opts.repoPath);
@@ -9276,11 +9321,11 @@ async function createOrUpdatePr(worktreePath, opts) {
9276
9321
  const headRef = ghHeadRef(slug, opts.head);
9277
9322
  const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
9278
9323
  const bodyText = clampGithubPrBody(opts.body ?? opts.title);
9279
- const bodyFile = (0, import_node_path21.join)(
9324
+ const bodyFile = (0, import_node_path22.join)(
9280
9325
  (0, import_node_os6.tmpdir)(),
9281
9326
  `sideboard-pr-body-${process.pid}-${(0, import_node_crypto7.randomBytes)(6).toString("hex")}.md`
9282
9327
  );
9283
- (0, import_node_fs18.writeFileSync)(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
9328
+ (0, import_node_fs19.writeFileSync)(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
9284
9329
  `, "utf8");
9285
9330
  const bodyArgs = ["--body-file", bodyFile];
9286
9331
  try {
@@ -9294,7 +9339,7 @@ async function createOrUpdatePr(worktreePath, opts) {
9294
9339
  });
9295
9340
  } finally {
9296
9341
  try {
9297
- (0, import_node_fs18.unlinkSync)(bodyFile);
9342
+ (0, import_node_fs19.unlinkSync)(bodyFile);
9298
9343
  } catch {
9299
9344
  }
9300
9345
  }
@@ -9376,10 +9421,10 @@ function sameRepoPath2(a, b) {
9376
9421
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
9377
9422
  }
9378
9423
  function listLocalThreadBranchSlugs(repoPath) {
9379
- const refsDir = (0, import_node_path21.join)(repoPath, ".git", "refs", "heads", "thread");
9380
- if (!(0, import_node_fs18.existsSync)(refsDir)) return [];
9424
+ const refsDir = (0, import_node_path22.join)(repoPath, ".git", "refs", "heads", "thread");
9425
+ if (!(0, import_node_fs19.existsSync)(refsDir)) return [];
9381
9426
  try {
9382
- return (0, import_node_fs18.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
9427
+ return (0, import_node_fs19.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
9383
9428
  } catch {
9384
9429
  return [];
9385
9430
  }
@@ -9387,8 +9432,8 @@ function listLocalThreadBranchSlugs(repoPath) {
9387
9432
  function collectTakenTeamSlugs(repoPath) {
9388
9433
  const taken = /* @__PURE__ */ new Set();
9389
9434
  const root = worktreesRoot(repoPath);
9390
- if ((0, import_node_fs18.existsSync)(root)) {
9391
- for (const entry of (0, import_node_fs18.readdirSync)(root, { withFileTypes: true })) {
9435
+ if ((0, import_node_fs19.existsSync)(root)) {
9436
+ for (const entry of (0, import_node_fs19.readdirSync)(root, { withFileTypes: true })) {
9392
9437
  if (entry.isDirectory() && entry.name !== ".DS_Store") {
9393
9438
  for (const slug of takenSlugsFromThread({ worktreePath: entry.name })) {
9394
9439
  taken.add(slug);
@@ -9413,20 +9458,20 @@ function allocateTeamSlug(repoPath) {
9413
9458
  const taken = collectTakenTeamSlugs(repoPath);
9414
9459
  for (let attempt = 0; attempt < 32; attempt++) {
9415
9460
  const team = allocateTeamName(taken);
9416
- const path2 = (0, import_node_path21.join)(worktreesRoot(repoPath), team.slug);
9417
- if (!(0, import_node_fs18.existsSync)(path2)) return team;
9461
+ const path2 = (0, import_node_path22.join)(worktreesRoot(repoPath), team.slug);
9462
+ if (!(0, import_node_fs19.existsSync)(path2)) return team;
9418
9463
  taken.add(team.slug);
9419
9464
  }
9420
9465
  throw new Error("No available soccer team worktree directories left");
9421
9466
  }
9422
- var import_node_crypto7, import_node_fs18, import_node_os6, import_node_path21, PR_DETAILS_JSON_FIELDS;
9467
+ var import_node_crypto7, import_node_fs19, import_node_os6, import_node_path22, PR_DETAILS_JSON_FIELDS;
9423
9468
  var init_worktree = __esm({
9424
9469
  "src/git/worktree.ts"() {
9425
9470
  "use strict";
9426
9471
  import_node_crypto7 = require("crypto");
9427
- import_node_fs18 = require("fs");
9472
+ import_node_fs19 = require("fs");
9428
9473
  import_node_os6 = require("os");
9429
- import_node_path21 = require("path");
9474
+ import_node_path22 = require("path");
9430
9475
  init_paths();
9431
9476
  init_thread_store();
9432
9477
  init_teams();
@@ -9479,38 +9524,38 @@ __export(workspaces_exports, {
9479
9524
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
9480
9525
  });
9481
9526
  function workspacesFile() {
9482
- return (0, import_node_path22.join)(appDataDir(), "workspaces.json");
9527
+ return (0, import_node_path23.join)(appDataDir(), "workspaces.json");
9483
9528
  }
9484
9529
  function removedWorkspacesFile() {
9485
- return (0, import_node_path22.join)(appDataDir(), "removed-workspaces.json");
9530
+ return (0, import_node_path23.join)(appDataDir(), "removed-workspaces.json");
9486
9531
  }
9487
9532
  function readAll2() {
9488
9533
  const path2 = workspacesFile();
9489
- if (!(0, import_node_fs19.existsSync)(path2)) return [];
9534
+ if (!(0, import_node_fs20.existsSync)(path2)) return [];
9490
9535
  try {
9491
- const raw = JSON.parse((0, import_node_fs19.readFileSync)(path2, "utf8"));
9536
+ const raw = JSON.parse((0, import_node_fs20.readFileSync)(path2, "utf8"));
9492
9537
  return Array.isArray(raw) ? raw : [];
9493
9538
  } catch {
9494
9539
  return [];
9495
9540
  }
9496
9541
  }
9497
9542
  function writeAll2(list) {
9498
- (0, import_node_fs19.mkdirSync)(appDataDir(), { recursive: true });
9499
- (0, import_node_fs19.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
9543
+ (0, import_node_fs20.mkdirSync)(appDataDir(), { recursive: true });
9544
+ (0, import_node_fs20.writeFileSync)(workspacesFile(), JSON.stringify(list, null, 2), "utf8");
9500
9545
  }
9501
9546
  function readRemoved() {
9502
9547
  const path2 = removedWorkspacesFile();
9503
- if (!(0, import_node_fs19.existsSync)(path2)) return /* @__PURE__ */ new Set();
9548
+ if (!(0, import_node_fs20.existsSync)(path2)) return /* @__PURE__ */ new Set();
9504
9549
  try {
9505
- const raw = JSON.parse((0, import_node_fs19.readFileSync)(path2, "utf8"));
9550
+ const raw = JSON.parse((0, import_node_fs20.readFileSync)(path2, "utf8"));
9506
9551
  return new Set(Array.isArray(raw) ? raw.filter((p) => typeof p === "string") : []);
9507
9552
  } catch {
9508
9553
  return /* @__PURE__ */ new Set();
9509
9554
  }
9510
9555
  }
9511
9556
  function writeRemoved(paths) {
9512
- (0, import_node_fs19.mkdirSync)(appDataDir(), { recursive: true });
9513
- (0, import_node_fs19.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
9557
+ (0, import_node_fs20.mkdirSync)(appDataDir(), { recursive: true });
9558
+ (0, import_node_fs20.writeFileSync)(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
9514
9559
  }
9515
9560
  function rememberRemoved(repoPath) {
9516
9561
  const next = readRemoved();
@@ -9532,10 +9577,10 @@ function listWorkspaces() {
9532
9577
  }
9533
9578
  function isLinkedWorktreeOf(path2, mainRepo) {
9534
9579
  if (!path2 || path2 === mainRepo) return false;
9535
- const git2 = (0, import_node_path22.join)(path2, ".git");
9580
+ const git2 = (0, import_node_path23.join)(path2, ".git");
9536
9581
  try {
9537
- if (!(0, import_node_fs19.existsSync)(git2) || (0, import_node_fs19.statSync)(git2).isDirectory()) return false;
9538
- const text7 = (0, import_node_fs19.readFileSync)(git2, "utf8");
9582
+ if (!(0, import_node_fs20.existsSync)(git2) || (0, import_node_fs20.statSync)(git2).isDirectory()) return false;
9583
+ const text7 = (0, import_node_fs20.readFileSync)(git2, "utf8");
9539
9584
  const needle = `${mainRepo.replace(/\/+$/, "")}/.git`;
9540
9585
  return text7.includes(needle);
9541
9586
  } catch {
@@ -9544,10 +9589,10 @@ function isLinkedWorktreeOf(path2, mainRepo) {
9544
9589
  }
9545
9590
  function primaryCheckoutFromLinkedWorktree(path2) {
9546
9591
  if (!path2) return null;
9547
- const git2 = (0, import_node_path22.join)(path2, ".git");
9592
+ const git2 = (0, import_node_path23.join)(path2, ".git");
9548
9593
  try {
9549
- if (!(0, import_node_fs19.existsSync)(git2) || (0, import_node_fs19.statSync)(git2).isDirectory()) return null;
9550
- const text7 = (0, import_node_fs19.readFileSync)(git2, "utf8");
9594
+ if (!(0, import_node_fs20.existsSync)(git2) || (0, import_node_fs20.statSync)(git2).isDirectory()) return null;
9595
+ const text7 = (0, import_node_fs20.readFileSync)(git2, "utf8");
9551
9596
  const match = /^\s*gitdir:\s*(.+)$/m.exec(text7);
9552
9597
  if (!match) return null;
9553
9598
  const gitdir = match[1].trim().replace(/\/+$/, "");
@@ -9568,7 +9613,7 @@ function resolveSyncWorkspacePath(path2) {
9568
9613
  async function addWorkspace(repoPath) {
9569
9614
  const root = await resolveRepoRoot(repoPath);
9570
9615
  if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
9571
- if (!(0, import_node_fs19.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
9616
+ if (!(0, import_node_fs20.existsSync)(root)) throw new Error(`Repo not found: ${root}`);
9572
9617
  forgetRemoved(root);
9573
9618
  await ensureGhPreferOrigin(root);
9574
9619
  const current = readAll2();
@@ -9577,7 +9622,7 @@ async function addWorkspace(repoPath) {
9577
9622
  if (existing && withoutLinked.length === current.length) return existing;
9578
9623
  const next = existing ?? {
9579
9624
  path: root,
9580
- name: (0, import_node_path22.basename)(root),
9625
+ name: (0, import_node_path23.basename)(root),
9581
9626
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9582
9627
  };
9583
9628
  writeAll2(existing ? withoutLinked : [...withoutLinked, next]);
@@ -9605,7 +9650,7 @@ function syncWorkspacesFromThreads(repoPaths) {
9605
9650
  if (!byPath.has(resolved)) {
9606
9651
  byPath.set(
9607
9652
  resolved,
9608
- resolved === w.path ? w : { ...w, path: resolved, name: (0, import_node_path22.basename)(resolved) }
9653
+ resolved === w.path ? w : { ...w, path: resolved, name: (0, import_node_path23.basename)(resolved) }
9609
9654
  );
9610
9655
  }
9611
9656
  }
@@ -9614,10 +9659,10 @@ function syncWorkspacesFromThreads(repoPaths) {
9614
9659
  if (!path2 || path2 === "/" || isGlobalRepoPath(path2) || byPath.has(path2) || removed.has(path2)) {
9615
9660
  continue;
9616
9661
  }
9617
- if (!(0, import_node_fs19.existsSync)(path2)) continue;
9662
+ if (!(0, import_node_fs20.existsSync)(path2)) continue;
9618
9663
  const ws = {
9619
9664
  path: path2,
9620
- name: (0, import_node_path22.basename)(path2),
9665
+ name: (0, import_node_path23.basename)(path2),
9621
9666
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9622
9667
  };
9623
9668
  byPath.set(path2, ws);
@@ -9634,12 +9679,12 @@ function syncWorkspacesFromThreads(repoPaths) {
9634
9679
  if (dirty) writeAll2(next);
9635
9680
  return next.sort((a, b) => a.name.localeCompare(b.name));
9636
9681
  }
9637
- var import_node_fs19, import_node_path22;
9682
+ var import_node_fs20, import_node_path23;
9638
9683
  var init_workspaces = __esm({
9639
9684
  "src/store/workspaces.ts"() {
9640
9685
  "use strict";
9641
- import_node_fs19 = require("fs");
9642
- import_node_path22 = require("path");
9686
+ import_node_fs20 = require("fs");
9687
+ import_node_path23 = require("path");
9643
9688
  init_paths();
9644
9689
  init_global_workspace();
9645
9690
  init_worktree();
@@ -9750,7 +9795,7 @@ function coordinatorTurnReminder(opts) {
9750
9795
  function ensureGlobalCoordinatorCwd(opts) {
9751
9796
  const dir = globalAgentCwd();
9752
9797
  try {
9753
- (0, import_node_fs20.mkdirSync)(dir, { recursive: true });
9798
+ (0, import_node_fs21.mkdirSync)(dir, { recursive: true });
9754
9799
  } catch {
9755
9800
  return dir;
9756
9801
  }
@@ -9758,7 +9803,7 @@ function ensureGlobalCoordinatorCwd(opts) {
9758
9803
  let orchId = opts?.orchestratorThreadId?.trim() || "";
9759
9804
  if (!orchId) {
9760
9805
  try {
9761
- const existing = (0, import_node_fs20.readFileSync)((0, import_node_path23.join)(dir, "AGENTS.md"), "utf8");
9806
+ const existing = (0, import_node_fs21.readFileSync)((0, import_node_path24.join)(dir, "AGENTS.md"), "utf8");
9762
9807
  const m = existing.match(
9763
9808
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
9764
9809
  );
@@ -9803,9 +9848,9 @@ function ensureGlobalCoordinatorCwd(opts) {
9803
9848
  "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."
9804
9849
  ].join("\n");
9805
9850
  try {
9806
- (0, import_node_fs20.writeFileSync)((0, import_node_path23.join)(dir, "CLAUDE.md"), `${body}
9851
+ (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(dir, "CLAUDE.md"), `${body}
9807
9852
  `, "utf8");
9808
- (0, import_node_fs20.writeFileSync)((0, import_node_path23.join)(dir, "AGENTS.md"), `${body}
9853
+ (0, import_node_fs21.writeFileSync)((0, import_node_path24.join)(dir, "AGENTS.md"), `${body}
9809
9854
  `, "utf8");
9810
9855
  } catch {
9811
9856
  }
@@ -9837,12 +9882,12 @@ function coordinatorSystemPrompt(opts) {
9837
9882
  formatWorkspaceInventory(opts.workspaces)
9838
9883
  ].join("\n");
9839
9884
  }
9840
- var import_node_fs20, import_node_path23, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9885
+ var import_node_fs21, import_node_path24, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9841
9886
  var init_coordinator_prompt = __esm({
9842
9887
  "src/orchestrator/coordinator-prompt.ts"() {
9843
9888
  "use strict";
9844
- import_node_fs20 = require("fs");
9845
- import_node_path23 = require("path");
9889
+ import_node_fs21 = require("fs");
9890
+ import_node_path24 = require("path");
9846
9891
  init_worktree();
9847
9892
  init_app_settings();
9848
9893
  init_paths();
@@ -10201,13 +10246,13 @@ var init_api = __esm({
10201
10246
 
10202
10247
  // src/slack/reply-target.ts
10203
10248
  function storePath() {
10204
- return (0, import_node_path24.join)(appDataDir(), "slack-reply-to.json");
10249
+ return (0, import_node_path25.join)(appDataDir(), "slack-reply-to.json");
10205
10250
  }
10206
10251
  function readStore() {
10207
10252
  const path2 = storePath();
10208
- if (!(0, import_node_fs21.existsSync)(path2)) return {};
10253
+ if (!(0, import_node_fs22.existsSync)(path2)) return {};
10209
10254
  try {
10210
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs21.readFileSync)(path2, "utf8"));
10255
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
10211
10256
  return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
10212
10257
  } catch {
10213
10258
  return {};
@@ -10222,12 +10267,12 @@ function setSlackReplyTarget(target) {
10222
10267
  function getSlackReplyTarget(threadId) {
10223
10268
  return readStore()[threadId] ?? null;
10224
10269
  }
10225
- var import_node_fs21, import_node_path24;
10270
+ var import_node_fs22, import_node_path25;
10226
10271
  var init_reply_target = __esm({
10227
10272
  "src/slack/reply-target.ts"() {
10228
10273
  "use strict";
10229
- import_node_fs21 = require("fs");
10230
- import_node_path24 = require("path");
10274
+ import_node_fs22 = require("fs");
10275
+ import_node_path25 = require("path");
10231
10276
  init_paths();
10232
10277
  init_private_file();
10233
10278
  init_secure_file();
@@ -10236,7 +10281,7 @@ var init_reply_target = __esm({
10236
10281
 
10237
10282
  // src/slack/workspaces.ts
10238
10283
  function storePath2() {
10239
- return (0, import_node_path25.join)(appDataDir(), "slack-workspaces.json");
10284
+ return (0, import_node_path26.join)(appDataDir(), "slack-workspaces.json");
10240
10285
  }
10241
10286
  function readStore2() {
10242
10287
  try {
@@ -10343,11 +10388,11 @@ function requireSlackWorkspace(teamId) {
10343
10388
  }
10344
10389
  return ws;
10345
10390
  }
10346
- var import_node_path25;
10391
+ var import_node_path26;
10347
10392
  var init_workspaces2 = __esm({
10348
10393
  "src/slack/workspaces.ts"() {
10349
10394
  "use strict";
10350
- import_node_path25 = require("path");
10395
+ import_node_path26 = require("path");
10351
10396
  init_paths();
10352
10397
  init_secure_file();
10353
10398
  init_api();
@@ -10356,7 +10401,7 @@ var init_workspaces2 = __esm({
10356
10401
 
10357
10402
  // src/slack/outbound-watch.ts
10358
10403
  function storePath3() {
10359
- return (0, import_node_path26.join)(appDataDir(), "slack-outbound-watch.json");
10404
+ return (0, import_node_path27.join)(appDataDir(), "slack-outbound-watch.json");
10360
10405
  }
10361
10406
  function watchId(teamId, channelId, ts) {
10362
10407
  return `${teamId}:${channelId}:${ts}`;
@@ -10369,9 +10414,9 @@ function tsNewer(a, b) {
10369
10414
  }
10370
10415
  function readStore3() {
10371
10416
  const path2 = storePath3();
10372
- if (!(0, import_node_fs22.existsSync)(path2)) return [];
10417
+ if (!(0, import_node_fs23.existsSync)(path2)) return [];
10373
10418
  try {
10374
- const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
10419
+ const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs23.readFileSync)(path2, "utf8"));
10375
10420
  return Array.isArray(parsed?.watches) ? parsed.watches : [];
10376
10421
  } catch {
10377
10422
  return [];
@@ -10693,12 +10738,12 @@ async function pollSlackOutboundWatches(opts) {
10693
10738
  }
10694
10739
  if (changed) writeStore2(watches);
10695
10740
  }
10696
- var import_node_fs22, import_node_path26, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10741
+ var import_node_fs23, import_node_path27, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10697
10742
  var init_outbound_watch = __esm({
10698
10743
  "src/slack/outbound-watch.ts"() {
10699
10744
  "use strict";
10700
- import_node_fs22 = require("fs");
10701
- import_node_path26 = require("path");
10745
+ import_node_fs23 = require("fs");
10746
+ import_node_path27 = require("path");
10702
10747
  init_paths();
10703
10748
  init_private_file();
10704
10749
  init_secure_file();
@@ -10720,7 +10765,7 @@ function traceTurn(phase, extra) {
10720
10765
  try {
10721
10766
  const line = `${JSON.stringify({ t: (/* @__PURE__ */ new Date()).toISOString(), phase, ...extra })}
10722
10767
  `;
10723
- (0, import_node_fs23.appendFileSync)((0, import_node_path27.join)(appDataDir(), "turn-spawn.log"), line);
10768
+ (0, import_node_fs24.appendFileSync)((0, import_node_path28.join)(appDataDir(), "turn-spawn.log"), line);
10724
10769
  } catch {
10725
10770
  }
10726
10771
  }
@@ -10740,12 +10785,12 @@ async function withTimeout(promise, ms, label) {
10740
10785
  if (timer) clearTimeout(timer);
10741
10786
  }
10742
10787
  }
10743
- var import_node_fs23, import_node_path27;
10788
+ var import_node_fs24, import_node_path28;
10744
10789
  var init_turn_trace = __esm({
10745
10790
  "src/agents/turn-trace.ts"() {
10746
10791
  "use strict";
10747
- import_node_fs23 = require("fs");
10748
- import_node_path27 = require("path");
10792
+ import_node_fs24 = require("fs");
10793
+ import_node_path28 = require("path");
10749
10794
  init_paths();
10750
10795
  }
10751
10796
  });
@@ -10754,32 +10799,32 @@ var init_turn_trace = __esm({
10754
10799
  function brightsyConfigPath() {
10755
10800
  const override = process.env.BRIGHTSY_CONFIG?.trim();
10756
10801
  if (override) return override;
10757
- return (0, import_node_path28.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10802
+ return (0, import_node_path29.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10758
10803
  }
10759
10804
  function loadBrightsyConfig() {
10760
10805
  const path2 = brightsyConfigPath();
10761
- if (!(0, import_node_fs24.existsSync)(path2)) {
10806
+ if (!(0, import_node_fs25.existsSync)(path2)) {
10762
10807
  throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
10763
10808
  }
10764
- const raw = JSON.parse((0, import_node_fs24.readFileSync)(path2, "utf8"));
10809
+ const raw = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf8"));
10765
10810
  if (!raw.access_token || !raw.account_id) {
10766
10811
  throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
10767
10812
  }
10768
10813
  return raw;
10769
10814
  }
10770
10815
  function saveBrightsyConfig(cfg) {
10771
- (0, import_node_fs24.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
10816
+ (0, import_node_fs25.writeFileSync)(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
10772
10817
  `, {
10773
10818
  mode: 384
10774
10819
  });
10775
10820
  }
10776
- var import_node_fs24, import_node_os7, import_node_path28;
10821
+ var import_node_fs25, import_node_os7, import_node_path29;
10777
10822
  var init_config = __esm({
10778
10823
  "src/brightsy/config.ts"() {
10779
10824
  "use strict";
10780
- import_node_fs24 = require("fs");
10825
+ import_node_fs25 = require("fs");
10781
10826
  import_node_os7 = require("os");
10782
- import_node_path28 = require("path");
10827
+ import_node_path29 = require("path");
10783
10828
  }
10784
10829
  });
10785
10830
 
@@ -11081,22 +11126,22 @@ __export(connected_teams_exports, {
11081
11126
  listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
11082
11127
  });
11083
11128
  function storePath4() {
11084
- return (0, import_node_path29.join)(appDataDir(), "brightsy-teams.json");
11129
+ return (0, import_node_path30.join)(appDataDir(), "brightsy-teams.json");
11085
11130
  }
11086
11131
  function readStore4() {
11087
11132
  const path2 = storePath4();
11088
- if (!(0, import_node_fs25.existsSync)(path2)) return [];
11133
+ if (!(0, import_node_fs26.existsSync)(path2)) return [];
11089
11134
  try {
11090
- const parsed = JSON.parse((0, import_node_fs25.readFileSync)(path2, "utf8"));
11135
+ const parsed = JSON.parse((0, import_node_fs26.readFileSync)(path2, "utf8"));
11091
11136
  return Array.isArray(parsed.teams) ? parsed.teams : [];
11092
11137
  } catch {
11093
11138
  return [];
11094
11139
  }
11095
11140
  }
11096
11141
  function writeStore3(teams) {
11097
- (0, import_node_fs25.mkdirSync)(appDataDir(), { recursive: true });
11142
+ (0, import_node_fs26.mkdirSync)(appDataDir(), { recursive: true });
11098
11143
  const path2 = storePath4();
11099
- (0, import_node_fs25.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
11144
+ (0, import_node_fs26.writeFileSync)(path2, `${JSON.stringify({ teams }, null, 2)}
11100
11145
  `, {
11101
11146
  mode: 384
11102
11147
  });
@@ -11284,12 +11329,12 @@ function brightsyMcpServerName(slug) {
11284
11329
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
11285
11330
  return `brightsy_${cleaned || "team"}`;
11286
11331
  }
11287
- var import_node_fs25, import_node_path29;
11332
+ var import_node_fs26, import_node_path30;
11288
11333
  var init_connected_teams = __esm({
11289
11334
  "src/brightsy/connected-teams.ts"() {
11290
11335
  "use strict";
11291
- import_node_fs25 = require("fs");
11292
- import_node_path29 = require("path");
11336
+ import_node_fs26 = require("fs");
11337
+ import_node_path30 = require("path");
11293
11338
  init_paths();
11294
11339
  init_accounts();
11295
11340
  init_config();
@@ -11654,11 +11699,11 @@ async function syncCliForTarget(accountId) {
11654
11699
  }
11655
11700
  applyConnectedTeamToCli(team);
11656
11701
  }
11657
- var import_node_fs26, brightsyAdapter;
11702
+ var import_node_fs27, brightsyAdapter;
11658
11703
  var init_brightsy = __esm({
11659
11704
  "src/agents/brightsy.ts"() {
11660
11705
  "use strict";
11661
- import_node_fs26 = require("fs");
11706
+ import_node_fs27 = require("fs");
11662
11707
  init_run();
11663
11708
  init_connected_teams();
11664
11709
  init_config();
@@ -11673,7 +11718,7 @@ var init_brightsy = __esm({
11673
11718
  async detect() {
11674
11719
  const brightsy = resolveAgentExecutable("brightsy");
11675
11720
  if (brightsy !== "brightsy") {
11676
- if (!(0, import_node_fs26.existsSync)(brightsy)) {
11721
+ if (!(0, import_node_fs27.existsSync)(brightsy)) {
11677
11722
  return {
11678
11723
  agent: "brightsy",
11679
11724
  installed: false,
@@ -11816,6 +11861,9 @@ var init_profile = __esm({
11816
11861
  "present_files",
11817
11862
  "wait_for_job",
11818
11863
  "stop_job",
11864
+ "list_run_scripts",
11865
+ "run_dev_script",
11866
+ "stop_dev_script",
11819
11867
  "get_viewer_context",
11820
11868
  "update_viewer_context"
11821
11869
  ];
@@ -11854,7 +11902,7 @@ function splitPemCertificates(pem) {
11854
11902
  }
11855
11903
  function readExistingFile(path2) {
11856
11904
  try {
11857
- return (0, import_node_fs27.existsSync)(path2) ? (0, import_node_fs27.readFileSync)(path2, "utf8") : "";
11905
+ return (0, import_node_fs28.existsSync)(path2) ? (0, import_node_fs28.readFileSync)(path2, "utf8") : "";
11858
11906
  } catch {
11859
11907
  return "";
11860
11908
  }
@@ -11886,13 +11934,13 @@ function collectSystemCaPem(io = {}) {
11886
11934
  return "";
11887
11935
  }
11888
11936
  function systemCaBundlePath(io = {}) {
11889
- return (0, import_node_path30.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11937
+ return (0, import_node_path31.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11890
11938
  }
11891
11939
  function bundleIsFresh(path2, now) {
11892
11940
  try {
11893
- if (!(0, import_node_fs27.existsSync)(path2)) return false;
11894
- if (splitPemCertificates((0, import_node_fs27.readFileSync)(path2, "utf8")).length === 0) return false;
11895
- return now - (0, import_node_fs27.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
11941
+ if (!(0, import_node_fs28.existsSync)(path2)) return false;
11942
+ if (splitPemCertificates((0, import_node_fs28.readFileSync)(path2, "utf8")).length === 0) return false;
11943
+ return now - (0, import_node_fs28.statSync)(path2).mtimeMs < BUNDLE_MAX_AGE_MS;
11896
11944
  } catch {
11897
11945
  return false;
11898
11946
  }
@@ -11913,11 +11961,11 @@ function materializeSystemCaBundle(io = {}) {
11913
11961
  if (bundleIsFresh(dest, now)) return dest;
11914
11962
  const pem = collectSystemCaPem(io);
11915
11963
  if (splitPemCertificates(pem).length === 0) {
11916
- return (0, import_node_fs27.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
11964
+ return (0, import_node_fs28.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
11917
11965
  }
11918
11966
  try {
11919
- (0, import_node_fs27.mkdirSync)((0, import_node_path30.dirname)(dest), { recursive: true });
11920
- (0, import_node_fs27.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
11967
+ (0, import_node_fs28.mkdirSync)((0, import_node_path31.dirname)(dest), { recursive: true });
11968
+ (0, import_node_fs28.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
11921
11969
  `, { mode: 384 });
11922
11970
  return dest;
11923
11971
  } catch {
@@ -11957,13 +12005,13 @@ function trustSystemCertificates(io = {}) {
11957
12005
  return false;
11958
12006
  }
11959
12007
  }
11960
- var import_node_child_process4, import_node_fs27, import_node_path30, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
12008
+ 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;
11961
12009
  var init_system_ca = __esm({
11962
12010
  "src/http/system-ca.ts"() {
11963
12011
  "use strict";
11964
12012
  import_node_child_process4 = require("child_process");
11965
- import_node_fs27 = require("fs");
11966
- import_node_path30 = require("path");
12013
+ import_node_fs28 = require("fs");
12014
+ import_node_path31 = require("path");
11967
12015
  import_node_tls = __toESM(require("tls"), 1);
11968
12016
  init_paths();
11969
12017
  NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
@@ -11989,43 +12037,43 @@ function electronResourcesPath() {
11989
12037
  function packagedCursorRuntimeDir() {
11990
12038
  const resources = electronResourcesPath();
11991
12039
  if (!resources) return null;
11992
- const dir = (0, import_node_path31.join)(resources, "cursor-runtime");
11993
- if (!(0, import_node_fs28.existsSync)((0, import_node_path31.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
12040
+ const dir = (0, import_node_path32.join)(resources, "cursor-runtime");
12041
+ if (!(0, import_node_fs29.existsSync)((0, import_node_path32.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11994
12042
  return dir;
11995
12043
  }
11996
12044
  function packagedCursorRunnerPath() {
11997
12045
  const dir = packagedCursorRuntimeDir();
11998
- return dir ? (0, import_node_path31.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
12046
+ return dir ? (0, import_node_path32.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11999
12047
  }
12000
12048
  function packagedMcpDir() {
12001
12049
  const resources = electronResourcesPath();
12002
12050
  if (!resources) return null;
12003
- const dir = (0, import_node_path31.join)(resources, "sideboard-mcp");
12004
- if (!(0, import_node_fs28.existsSync)((0, import_node_path31.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
12051
+ const dir = (0, import_node_path32.join)(resources, "sideboard-mcp");
12052
+ if (!(0, import_node_fs29.existsSync)((0, import_node_path32.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
12005
12053
  return dir;
12006
12054
  }
12007
12055
  function packagedMcpStdioPath() {
12008
12056
  const dir = packagedMcpDir();
12009
- return dir ? (0, import_node_path31.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
12057
+ return dir ? (0, import_node_path32.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
12010
12058
  }
12011
12059
  function packagedBundledNodePath() {
12012
12060
  const resources = electronResourcesPath();
12013
12061
  if (!resources) return null;
12014
- const bin = (0, import_node_path31.join)(resources, "node", "bin", "node");
12015
- if (!(0, import_node_fs28.existsSync)(bin)) return null;
12062
+ const bin = (0, import_node_path32.join)(resources, "node", "bin", "node");
12063
+ if (!(0, import_node_fs29.existsSync)(bin)) return null;
12016
12064
  return bin;
12017
12065
  }
12018
12066
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
12019
12067
  const dir = packagedCursorRuntimeDir();
12020
12068
  if (!dir) return null;
12021
- return (0, import_node_path31.join)(dir, "node_modules", platformPkg, "bin", binName);
12069
+ return (0, import_node_path32.join)(dir, "node_modules", platformPkg, "bin", binName);
12022
12070
  }
12023
- var import_node_fs28, import_node_path31;
12071
+ var import_node_fs29, import_node_path32;
12024
12072
  var init_packaged_runtime = __esm({
12025
12073
  "src/agents/packaged-runtime.ts"() {
12026
12074
  "use strict";
12027
- import_node_fs28 = require("fs");
12028
- import_node_path31 = require("path");
12075
+ import_node_fs29 = require("fs");
12076
+ import_node_path32 = require("path");
12029
12077
  }
12030
12078
  });
12031
12079
 
@@ -12060,7 +12108,7 @@ function unpackedAsarPath(filePath) {
12060
12108
  if (!isAsarPath(filePath)) return null;
12061
12109
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
12062
12110
  if (unpacked === filePath) return null;
12063
- return (0, import_node_fs29.existsSync)(unpacked) ? unpacked : null;
12111
+ return (0, import_node_fs30.existsSync)(unpacked) ? unpacked : null;
12064
12112
  }
12065
12113
  function nodeReadableScriptPath(scriptPath) {
12066
12114
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -12100,37 +12148,37 @@ function pickPreferredNode(candidates) {
12100
12148
  return best;
12101
12149
  }
12102
12150
  function versionDirNodeBins(root, toBin) {
12103
- if (!(0, import_node_fs29.existsSync)(root)) return [];
12151
+ if (!(0, import_node_fs30.existsSync)(root)) return [];
12104
12152
  try {
12105
- return (0, import_node_fs29.readdirSync)(root).map(toBin);
12153
+ return (0, import_node_fs30.readdirSync)(root).map(toBin);
12106
12154
  } catch {
12107
12155
  return [];
12108
12156
  }
12109
12157
  }
12110
12158
  function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
12111
12159
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
12112
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path32.join)(prefix, "opt", `node@${major}`, "bin", "node"))
12160
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path33.join)(prefix, "opt", `node@${major}`, "bin", "node"))
12113
12161
  );
12114
12162
  return [
12115
12163
  ...kegs,
12116
12164
  "/opt/homebrew/bin/node",
12117
12165
  "/usr/local/bin/node",
12118
- (0, import_node_path32.join)(home, ".local/share/fnm/aliases/default/bin/node"),
12119
- (0, import_node_path32.join)(home, ".nvm/current/bin/node"),
12120
- (0, import_node_path32.join)(home, ".volta/bin/node"),
12121
- (0, import_node_path32.join)(home, ".asdf/shims/node"),
12122
- (0, import_node_path32.join)(home, ".local/share/mise/shims/node"),
12166
+ (0, import_node_path33.join)(home, ".local/share/fnm/aliases/default/bin/node"),
12167
+ (0, import_node_path33.join)(home, ".nvm/current/bin/node"),
12168
+ (0, import_node_path33.join)(home, ".volta/bin/node"),
12169
+ (0, import_node_path33.join)(home, ".asdf/shims/node"),
12170
+ (0, import_node_path33.join)(home, ".local/share/mise/shims/node"),
12123
12171
  ...versionDirNodeBins(
12124
- (0, import_node_path32.join)(home, ".nvm", "versions", "node"),
12125
- (name) => (0, import_node_path32.join)(home, ".nvm", "versions", "node", name, "bin", "node")
12172
+ (0, import_node_path33.join)(home, ".nvm", "versions", "node"),
12173
+ (name) => (0, import_node_path33.join)(home, ".nvm", "versions", "node", name, "bin", "node")
12126
12174
  ),
12127
12175
  ...versionDirNodeBins(
12128
- (0, import_node_path32.join)(home, ".local/share/fnm", "node-versions"),
12129
- (name) => (0, import_node_path32.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
12176
+ (0, import_node_path33.join)(home, ".local/share/fnm", "node-versions"),
12177
+ (name) => (0, import_node_path33.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
12130
12178
  ),
12131
12179
  ...versionDirNodeBins(
12132
- (0, import_node_path32.join)(home, ".volta", "tools", "image", "node"),
12133
- (name) => (0, import_node_path32.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
12180
+ (0, import_node_path33.join)(home, ".volta", "tools", "image", "node"),
12181
+ (name) => (0, import_node_path33.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
12134
12182
  )
12135
12183
  ];
12136
12184
  }
@@ -12139,10 +12187,10 @@ function uniqueExistingNodeBins(paths) {
12139
12187
  const out = [];
12140
12188
  for (const raw of paths) {
12141
12189
  const p = raw.trim();
12142
- if (!p || !(0, import_node_fs29.existsSync)(p) || isElectronLikeCommand(p)) continue;
12190
+ if (!p || !(0, import_node_fs30.existsSync)(p) || isElectronLikeCommand(p)) continue;
12143
12191
  let key = p;
12144
12192
  try {
12145
- key = (0, import_node_fs29.realpathSync)(p);
12193
+ key = (0, import_node_fs30.realpathSync)(p);
12146
12194
  } catch {
12147
12195
  continue;
12148
12196
  }
@@ -12222,13 +12270,13 @@ async function resolveNodeLaunch(scriptPath) {
12222
12270
  env: { ELECTRON_RUN_AS_NODE: "1" }
12223
12271
  };
12224
12272
  }
12225
- var import_node_fs29, import_node_os8, import_node_path32, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
12273
+ var import_node_fs30, import_node_os8, import_node_path33, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
12226
12274
  var init_node_launch = __esm({
12227
12275
  "src/agents/node-launch.ts"() {
12228
12276
  "use strict";
12229
- import_node_fs29 = require("fs");
12277
+ import_node_fs30 = require("fs");
12230
12278
  import_node_os8 = require("os");
12231
- import_node_path32 = require("path");
12279
+ import_node_path33 = require("path");
12232
12280
  init_nested_electron_env();
12233
12281
  init_system_ca();
12234
12282
  init_run();
@@ -12331,37 +12379,37 @@ function corePackageDir() {
12331
12379
  try {
12332
12380
  const url = import_meta.url;
12333
12381
  if (typeof url === "string" && url.length > 0) {
12334
- return (0, import_node_path33.dirname)((0, import_node_url.fileURLToPath)(url));
12382
+ return (0, import_node_path34.dirname)((0, import_node_url.fileURLToPath)(url));
12335
12383
  }
12336
12384
  } catch {
12337
12385
  }
12338
12386
  try {
12339
- const req = (0, import_node_module.createRequire)((0, import_node_path33.join)(process.cwd(), "package.json"));
12340
- return (0, import_node_path33.dirname)(req.resolve("@sideboard-ai/core"));
12387
+ const req = (0, import_node_module.createRequire)((0, import_node_path34.join)(process.cwd(), "package.json"));
12388
+ return (0, import_node_path34.dirname)(req.resolve("@sideboard-ai/core"));
12341
12389
  } catch {
12342
12390
  return process.cwd();
12343
12391
  }
12344
12392
  }
12345
12393
  function findSideboardMcpJsEntry() {
12346
12394
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
12347
- if (override && (0, import_node_fs30.existsSync)(override)) return override;
12395
+ if (override && (0, import_node_fs31.existsSync)(override)) return override;
12348
12396
  const packaged = packagedMcpStdioPath();
12349
12397
  if (packaged) return packaged;
12350
12398
  let dir = corePackageDir();
12351
12399
  for (let i = 0; i < 10; i++) {
12352
12400
  const candidates = [
12353
- (0, import_node_path33.join)(dir, "mcp/run-stdio.js"),
12354
- (0, import_node_path33.join)(dir, "mcp/run-stdio.cjs"),
12355
- (0, import_node_path33.join)(dir, "dist/mcp/run-stdio.js"),
12356
- (0, import_node_path33.join)(dir, "dist/mcp/run-stdio.cjs"),
12357
- (0, import_node_path33.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
12358
- (0, import_node_path33.join)(dir, "packages/cli/dist/index.js"),
12359
- (0, import_node_path33.join)(dir, "cli/dist/index.js")
12401
+ (0, import_node_path34.join)(dir, "mcp/run-stdio.js"),
12402
+ (0, import_node_path34.join)(dir, "mcp/run-stdio.cjs"),
12403
+ (0, import_node_path34.join)(dir, "dist/mcp/run-stdio.js"),
12404
+ (0, import_node_path34.join)(dir, "dist/mcp/run-stdio.cjs"),
12405
+ (0, import_node_path34.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
12406
+ (0, import_node_path34.join)(dir, "packages/cli/dist/index.js"),
12407
+ (0, import_node_path34.join)(dir, "cli/dist/index.js")
12360
12408
  ];
12361
12409
  for (const p of candidates) {
12362
- if ((0, import_node_fs30.existsSync)(p) && !isAsarPath(p)) return p;
12410
+ if ((0, import_node_fs31.existsSync)(p) && !isAsarPath(p)) return p;
12363
12411
  }
12364
- const parent = (0, import_node_path33.dirname)(dir);
12412
+ const parent = (0, import_node_path34.dirname)(dir);
12365
12413
  if (parent === dir) break;
12366
12414
  dir = parent;
12367
12415
  }
@@ -12524,22 +12572,22 @@ function writeMcpServersConfig(servers, extraServers) {
12524
12572
  }
12525
12573
  }
12526
12574
  if (Object.keys(mcpServers).length === 0) return null;
12527
- const dir = (0, import_node_fs30.mkdtempSync)((0, import_node_path33.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12528
- const cfgPath = (0, import_node_path33.join)(dir, "mcp.json");
12529
- (0, import_node_fs30.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12575
+ const dir = (0, import_node_fs31.mkdtempSync)((0, import_node_path34.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12576
+ const cfgPath = (0, import_node_path34.join)(dir, "mcp.json");
12577
+ (0, import_node_fs31.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12530
12578
  return cfgPath;
12531
12579
  }
12532
12580
  async function writeInjectedMcpConfig(opts) {
12533
12581
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
12534
12582
  }
12535
- var import_node_fs30, import_node_module, import_node_os9, import_node_path33, 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;
12583
+ 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;
12536
12584
  var init_injected_mcp = __esm({
12537
12585
  "src/agents/injected-mcp.ts"() {
12538
12586
  "use strict";
12539
- import_node_fs30 = require("fs");
12587
+ import_node_fs31 = require("fs");
12540
12588
  import_node_module = require("module");
12541
12589
  import_node_os9 = require("os");
12542
- import_node_path33 = require("path");
12590
+ import_node_path34 = require("path");
12543
12591
  import_node_url = require("url");
12544
12592
  init_run();
12545
12593
  init_config();
@@ -12564,6 +12612,9 @@ var init_injected_mcp = __esm({
12564
12612
  "mcp__sideboard__present_plan",
12565
12613
  "mcp__sideboard__wait_for_job",
12566
12614
  "mcp__sideboard__stop_job",
12615
+ "mcp__sideboard__list_run_scripts",
12616
+ "mcp__sideboard__run_dev_script",
12617
+ "mcp__sideboard__stop_dev_script",
12567
12618
  "mcp__sideboard__get_viewer_context",
12568
12619
  "mcp__sideboard__update_viewer_context"
12569
12620
  ];
@@ -12581,10 +12632,10 @@ var init_injected_mcp = __esm({
12581
12632
 
12582
12633
  // src/agents/user-mcp-config.ts
12583
12634
  function userCursorMcpConfigPath() {
12584
- return (0, import_node_path34.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12635
+ return (0, import_node_path35.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12585
12636
  }
12586
12637
  function userClaudeMcpConfigPath() {
12587
- return (0, import_node_path34.join)((0, import_node_os10.homedir)(), ".claude.json");
12638
+ return (0, import_node_path35.join)((0, import_node_os10.homedir)(), ".claude.json");
12588
12639
  }
12589
12640
  function asObject(value) {
12590
12641
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -12611,16 +12662,16 @@ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
12611
12662
  }
12612
12663
  function writeMergedMcpServersJson(configPath, sideboard) {
12613
12664
  let existing = {};
12614
- if ((0, import_node_fs31.existsSync)(configPath)) {
12665
+ if ((0, import_node_fs32.existsSync)(configPath)) {
12615
12666
  try {
12616
- existing = JSON.parse((0, import_node_fs31.readFileSync)(configPath, "utf8"));
12667
+ existing = JSON.parse((0, import_node_fs32.readFileSync)(configPath, "utf8"));
12617
12668
  } catch {
12618
12669
  existing = {};
12619
12670
  }
12620
12671
  }
12621
12672
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
12622
- (0, import_node_fs31.mkdirSync)((0, import_node_path34.dirname)(configPath), { recursive: true });
12623
- (0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
12673
+ (0, import_node_fs32.mkdirSync)((0, import_node_path35.dirname)(configPath), { recursive: true });
12674
+ (0, import_node_fs32.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
12624
12675
  `);
12625
12676
  }
12626
12677
  function launchFromResolved(server) {
@@ -12638,19 +12689,19 @@ async function registerPackagedUserMcpClients() {
12638
12689
  const cursor = userCursorMcpConfigPath();
12639
12690
  writeMergedMcpServersJson(cursor, launch);
12640
12691
  const claude = userClaudeMcpConfigPath();
12641
- if ((0, import_node_fs31.existsSync)(claude)) {
12692
+ if ((0, import_node_fs32.existsSync)(claude)) {
12642
12693
  writeMergedMcpServersJson(claude, launch);
12643
12694
  return { cursor, claude };
12644
12695
  }
12645
12696
  return { cursor };
12646
12697
  }
12647
- var import_node_fs31, import_node_os10, import_node_path34;
12698
+ var import_node_fs32, import_node_os10, import_node_path35;
12648
12699
  var init_user_mcp_config = __esm({
12649
12700
  "src/agents/user-mcp-config.ts"() {
12650
12701
  "use strict";
12651
- import_node_fs31 = require("fs");
12702
+ import_node_fs32 = require("fs");
12652
12703
  import_node_os10 = require("os");
12653
- import_node_path34 = require("path");
12704
+ import_node_path35 = require("path");
12654
12705
  init_paths();
12655
12706
  init_injected_mcp();
12656
12707
  }
@@ -12678,25 +12729,25 @@ function listMcpNamesFromCodexToml(text7) {
12678
12729
  }
12679
12730
  function readJsonObject(path2) {
12680
12731
  try {
12681
- return JSON.parse((0, import_node_fs32.readFileSync)(path2, "utf8"));
12732
+ return JSON.parse((0, import_node_fs33.readFileSync)(path2, "utf8"));
12682
12733
  } catch {
12683
12734
  return {};
12684
12735
  }
12685
12736
  }
12686
12737
  function readText(path2) {
12687
12738
  try {
12688
- return (0, import_node_fs32.readFileSync)(path2, "utf8");
12739
+ return (0, import_node_fs33.readFileSync)(path2, "utf8");
12689
12740
  } catch {
12690
12741
  return "";
12691
12742
  }
12692
12743
  }
12693
12744
  function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
12694
- return [(0, import_node_path35.join)(home, ".codex", "config.toml"), (0, import_node_path35.join)(home, ".config", "codex", "config.toml")];
12745
+ return [(0, import_node_path36.join)(home, ".codex", "config.toml"), (0, import_node_path36.join)(home, ".config", "codex", "config.toml")];
12695
12746
  }
12696
12747
  function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
12697
12748
  return [
12698
- (0, import_node_path35.join)(home, ".config", "opencode", "opencode.json"),
12699
- (0, import_node_path35.join)(home, ".config", "opencode", "opencode.jsonc")
12749
+ (0, import_node_path36.join)(home, ".config", "opencode", "opencode.json"),
12750
+ (0, import_node_path36.join)(home, ".config", "opencode", "opencode.jsonc")
12700
12751
  ];
12701
12752
  }
12702
12753
  function userMcpNamesToDisable(opts) {
@@ -12718,7 +12769,7 @@ function userMcpNamesToDisable(opts) {
12718
12769
  function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
12719
12770
  const names = [];
12720
12771
  for (const path2 of userCodexConfigPaths(home)) {
12721
- if (!(0, import_node_fs32.existsSync)(path2)) continue;
12772
+ if (!(0, import_node_fs33.existsSync)(path2)) continue;
12722
12773
  names.push(...listMcpNamesFromCodexToml(readText(path2)));
12723
12774
  }
12724
12775
  return names;
@@ -12726,14 +12777,14 @@ function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
12726
12777
  function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
12727
12778
  const names = [];
12728
12779
  for (const path2 of userOpencodeConfigPaths(home)) {
12729
- if (!(0, import_node_fs32.existsSync)(path2)) continue;
12780
+ if (!(0, import_node_fs33.existsSync)(path2)) continue;
12730
12781
  names.push(...listMcpNamesFromJsonMap(readJsonObject(path2), "mcp"));
12731
12782
  }
12732
12783
  return names;
12733
12784
  }
12734
12785
  function userClaudeMcpConfigObject(home = (0, import_node_os11.homedir)()) {
12735
- const claudePath = home === (0, import_node_os11.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path35.join)(home, ".claude.json");
12736
- if (!(0, import_node_fs32.existsSync)(claudePath)) return {};
12786
+ const claudePath = home === (0, import_node_os11.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path36.join)(home, ".claude.json");
12787
+ if (!(0, import_node_fs33.existsSync)(claudePath)) return {};
12737
12788
  return asObject2(asObject2(readJsonObject(claudePath)).mcpServers);
12738
12789
  }
12739
12790
  function listUserClaudeMcpServerEntries(home = (0, import_node_os11.homedir)()) {
@@ -12766,13 +12817,13 @@ function toCodexUnattendedAppsArgs() {
12766
12817
  "features.plugins=false"
12767
12818
  ];
12768
12819
  }
12769
- var import_node_fs32, import_node_os11, import_node_path35, import_smol_toml2;
12820
+ var import_node_fs33, import_node_os11, import_node_path36, import_smol_toml2;
12770
12821
  var init_orch_mcp_isolation = __esm({
12771
12822
  "src/agents/orch-mcp-isolation.ts"() {
12772
12823
  "use strict";
12773
- import_node_fs32 = require("fs");
12824
+ import_node_fs33 = require("fs");
12774
12825
  import_node_os11 = require("os");
12775
- import_node_path35 = require("path");
12826
+ import_node_path36 = require("path");
12776
12827
  import_smol_toml2 = require("smol-toml");
12777
12828
  init_user_mcp_config();
12778
12829
  }
@@ -13135,11 +13186,11 @@ function parseIssuesJson(raw) {
13135
13186
  }
13136
13187
  return [];
13137
13188
  }
13138
- var import_node_fs33, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
13189
+ var import_node_fs34, BASE_ALLOWED_TOOLS, CLAUDE_PRINT_BG_WAIT_CEILING_MS, CLAUDE_CHROME_ALLOWED_TOOLS, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
13139
13190
  var init_claude = __esm({
13140
13191
  "src/agents/claude.ts"() {
13141
13192
  "use strict";
13142
- import_node_fs33 = require("fs");
13193
+ import_node_fs34 = require("fs");
13143
13194
  init_run();
13144
13195
  init_app_settings();
13145
13196
  init_claude_mcp();
@@ -13179,7 +13230,7 @@ var init_claude = __esm({
13179
13230
  async detect() {
13180
13231
  const claude = resolveClaudeExecutable();
13181
13232
  if (claude !== "claude") {
13182
- if (!(0, import_node_fs33.existsSync)(claude)) {
13233
+ if (!(0, import_node_fs34.existsSync)(claude)) {
13183
13234
  return {
13184
13235
  agent: "claude",
13185
13236
  installed: false,
@@ -13447,7 +13498,7 @@ async function listCodexModels() {
13447
13498
  if (codex === "codex") {
13448
13499
  const which = await run("which", ["codex"], { reject: false });
13449
13500
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
13450
- } else if (!(0, import_node_fs34.existsSync)(codex)) {
13501
+ } else if (!(0, import_node_fs35.existsSync)(codex)) {
13451
13502
  return FALLBACK_CODEX_MODELS;
13452
13503
  }
13453
13504
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -13482,12 +13533,12 @@ function usageFromCodex(usage) {
13482
13533
  }
13483
13534
  function codexConfigHasNetworkAccess() {
13484
13535
  const candidates = [
13485
- (0, import_node_path36.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13486
- (0, import_node_path36.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13536
+ (0, import_node_path37.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13537
+ (0, import_node_path37.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13487
13538
  ];
13488
13539
  for (const path2 of candidates) {
13489
- if (!(0, import_node_fs34.existsSync)(path2)) continue;
13490
- const text7 = (0, import_node_fs34.readFileSync)(path2, "utf8");
13540
+ if (!(0, import_node_fs35.existsSync)(path2)) continue;
13541
+ const text7 = (0, import_node_fs35.readFileSync)(path2, "utf8");
13491
13542
  if (/network_access\s*=\s*true/.test(text7)) return true;
13492
13543
  }
13493
13544
  return false;
@@ -13519,21 +13570,21 @@ function asRecord2(value) {
13519
13570
  return void 0;
13520
13571
  }
13521
13572
  function codexLooksAuthenticated() {
13522
- const authPath = (0, import_node_path36.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13523
- if (!(0, import_node_fs34.existsSync)(authPath)) return false;
13573
+ const authPath = (0, import_node_path37.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13574
+ if (!(0, import_node_fs35.existsSync)(authPath)) return false;
13524
13575
  try {
13525
- return (0, import_node_fs34.statSync)(authPath).size > 2;
13576
+ return (0, import_node_fs35.statSync)(authPath).size > 2;
13526
13577
  } catch {
13527
13578
  return false;
13528
13579
  }
13529
13580
  }
13530
- var import_node_fs34, import_node_os12, import_node_path36, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13581
+ var import_node_fs35, import_node_os12, import_node_path37, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13531
13582
  var init_codex = __esm({
13532
13583
  "src/agents/codex.ts"() {
13533
13584
  "use strict";
13534
- import_node_fs34 = require("fs");
13585
+ import_node_fs35 = require("fs");
13535
13586
  import_node_os12 = require("os");
13536
- import_node_path36 = require("path");
13587
+ import_node_path37 = require("path");
13537
13588
  init_run();
13538
13589
  init_app_settings();
13539
13590
  init_global_workspace();
@@ -13559,7 +13610,7 @@ var init_codex = __esm({
13559
13610
  async detect() {
13560
13611
  const codex = resolveAgentExecutable("codex");
13561
13612
  if (codex !== "codex") {
13562
- if (!(0, import_node_fs34.existsSync)(codex)) {
13613
+ if (!(0, import_node_fs35.existsSync)(codex)) {
13563
13614
  return {
13564
13615
  agent: "codex",
13565
13616
  installed: false,
@@ -14059,21 +14110,21 @@ function platformRipgrepPackage() {
14059
14110
  }
14060
14111
  function usableRipgrepPath(candidate) {
14061
14112
  const raw = candidate?.trim();
14062
- if (!raw || !(0, import_node_path37.isAbsolute)(raw)) return null;
14113
+ if (!raw || !(0, import_node_path38.isAbsolute)(raw)) return null;
14063
14114
  const readable = nodeReadableScriptPath(raw);
14064
- if (!(0, import_node_fs35.existsSync)(readable) || isAsarPath(readable)) return null;
14115
+ if (!(0, import_node_fs36.existsSync)(readable) || isAsarPath(readable)) return null;
14065
14116
  return readable;
14066
14117
  }
14067
14118
  function walkForBundledRipgrep(startFile) {
14068
14119
  if (!startFile) return null;
14069
14120
  const pkg = platformRipgrepPackage();
14070
14121
  const name = rgBinaryName();
14071
- let dir = (0, import_node_path37.dirname)((0, import_node_path37.resolve)(startFile));
14072
- const root = (0, import_node_path37.parse)(dir).root;
14122
+ let dir = (0, import_node_path38.dirname)((0, import_node_path38.resolve)(startFile));
14123
+ const root = (0, import_node_path38.parse)(dir).root;
14073
14124
  while (dir !== root) {
14074
- const hit = usableRipgrepPath((0, import_node_path37.join)(dir, "node_modules", pkg, "bin", name));
14125
+ const hit = usableRipgrepPath((0, import_node_path38.join)(dir, "node_modules", pkg, "bin", name));
14075
14126
  if (hit) return hit;
14076
- const next = (0, import_node_path37.dirname)(dir);
14127
+ const next = (0, import_node_path38.dirname)(dir);
14077
14128
  if (next === dir) break;
14078
14129
  dir = next;
14079
14130
  }
@@ -14083,7 +14134,7 @@ function requireResolveBundledRipgrep(fromFile) {
14083
14134
  try {
14084
14135
  const req = (0, import_node_module2.createRequire)(fromFile);
14085
14136
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
14086
- return usableRipgrepPath((0, import_node_path37.join)((0, import_node_path37.dirname)(pkgJson), "bin", rgBinaryName()));
14137
+ return usableRipgrepPath((0, import_node_path38.join)((0, import_node_path38.dirname)(pkgJson), "bin", rgBinaryName()));
14087
14138
  } catch {
14088
14139
  return null;
14089
14140
  }
@@ -14105,13 +14156,13 @@ function cursorRipgrepEnv(opts) {
14105
14156
  const path2 = resolveCursorRipgrepPath(opts);
14106
14157
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
14107
14158
  }
14108
- var import_node_fs35, import_node_module2, import_node_path37, RIPGREP_ENV;
14159
+ var import_node_fs36, import_node_module2, import_node_path38, RIPGREP_ENV;
14109
14160
  var init_cursor_ripgrep = __esm({
14110
14161
  "src/agents/cursor-ripgrep.ts"() {
14111
14162
  "use strict";
14112
- import_node_fs35 = require("fs");
14163
+ import_node_fs36 = require("fs");
14113
14164
  import_node_module2 = require("module");
14114
- import_node_path37 = require("path");
14165
+ import_node_path38 = require("path");
14115
14166
  init_node_launch();
14116
14167
  init_packaged_runtime();
14117
14168
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -14160,11 +14211,11 @@ function entryDir() {
14160
14211
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
14161
14212
  if (cjsDir) return cjsDir;
14162
14213
  try {
14163
- return (0, import_node_path38.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
14214
+ return (0, import_node_path39.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
14164
14215
  } catch {
14165
14216
  try {
14166
14217
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
14167
- return (0, import_node_path38.dirname)(req.resolve("@sideboard-ai/core"));
14218
+ return (0, import_node_path39.dirname)(req.resolve("@sideboard-ai/core"));
14168
14219
  } catch {
14169
14220
  return process.cwd();
14170
14221
  }
@@ -14175,27 +14226,27 @@ function cursorRunnerPath() {
14175
14226
  if (packaged) return packaged;
14176
14227
  const root = entryDir();
14177
14228
  const candidates = [
14178
- (0, import_node_path38.join)(root, "agents", "cursor-runner.js"),
14179
- (0, import_node_path38.join)(root, "agents", "cursor-runner.cjs"),
14229
+ (0, import_node_path39.join)(root, "agents", "cursor-runner.js"),
14230
+ (0, import_node_path39.join)(root, "agents", "cursor-runner.cjs"),
14180
14231
  // If somehow resolved from package root instead of dist/
14181
- (0, import_node_path38.join)(root, "dist", "agents", "cursor-runner.js"),
14182
- (0, import_node_path38.join)(root, "dist", "agents", "cursor-runner.cjs"),
14232
+ (0, import_node_path39.join)(root, "dist", "agents", "cursor-runner.js"),
14233
+ (0, import_node_path39.join)(root, "dist", "agents", "cursor-runner.cjs"),
14183
14234
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
14184
- (0, import_node_path38.join)(root, "cursor-runner.ts"),
14185
- (0, import_node_path38.join)(root, "src", "agents", "cursor-runner.ts")
14235
+ (0, import_node_path39.join)(root, "cursor-runner.ts"),
14236
+ (0, import_node_path39.join)(root, "src", "agents", "cursor-runner.ts")
14186
14237
  ];
14187
14238
  for (const candidate of candidates) {
14188
- if ((0, import_node_fs36.existsSync)(candidate)) return candidate;
14239
+ if ((0, import_node_fs37.existsSync)(candidate)) return candidate;
14189
14240
  }
14190
14241
  return candidates[0];
14191
14242
  }
14192
- var import_node_fs36, import_node_module3, import_node_path38, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14243
+ var import_node_fs37, import_node_module3, import_node_path39, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14193
14244
  var init_cursor = __esm({
14194
14245
  "src/agents/cursor.ts"() {
14195
14246
  "use strict";
14196
- import_node_fs36 = require("fs");
14247
+ import_node_fs37 = require("fs");
14197
14248
  import_node_module3 = require("module");
14198
- import_node_path38 = require("path");
14249
+ import_node_path39 = require("path");
14199
14250
  import_node_url2 = require("url");
14200
14251
  import_sdk = require("@cursor/sdk");
14201
14252
  init_run();
@@ -14347,7 +14398,7 @@ async function listOpencodeModels() {
14347
14398
  if (opencode === "opencode") {
14348
14399
  const which = await run("which", ["opencode"], { reject: false });
14349
14400
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
14350
- } else if (!(0, import_node_fs37.existsSync)(opencode)) {
14401
+ } else if (!(0, import_node_fs38.existsSync)(opencode)) {
14351
14402
  return FALLBACK_OPENCODE_MODELS;
14352
14403
  }
14353
14404
  const listed = await run(opencode, ["models"], { reject: false });
@@ -14377,11 +14428,11 @@ function usageFromOpencode(tokens) {
14377
14428
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
14378
14429
  };
14379
14430
  }
14380
- var import_node_fs37, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14431
+ var import_node_fs38, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14381
14432
  var init_opencode = __esm({
14382
14433
  "src/agents/opencode.ts"() {
14383
14434
  "use strict";
14384
- import_node_fs37 = require("fs");
14435
+ import_node_fs38 = require("fs");
14385
14436
  init_run();
14386
14437
  init_app_settings();
14387
14438
  init_global_workspace();
@@ -14409,7 +14460,7 @@ var init_opencode = __esm({
14409
14460
  async detect() {
14410
14461
  const opencode = resolveAgentExecutable("opencode");
14411
14462
  if (opencode !== "opencode") {
14412
- if (!(0, import_node_fs37.existsSync)(opencode)) {
14463
+ if (!(0, import_node_fs38.existsSync)(opencode)) {
14413
14464
  return {
14414
14465
  agent: "opencode",
14415
14466
  installed: false,
@@ -15128,14 +15179,14 @@ function accessTokenFromCredentialsJson(raw) {
15128
15179
  }
15129
15180
  }
15130
15181
  function claudeCredentialsPath() {
15131
- const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path39.join)((0, import_node_os13.homedir)(), ".claude");
15132
- return (0, import_node_path39.join)(root, ".credentials.json");
15182
+ const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path40.join)((0, import_node_os13.homedir)(), ".claude");
15183
+ return (0, import_node_path40.join)(root, ".credentials.json");
15133
15184
  }
15134
15185
  async function readFileAccessToken() {
15135
15186
  const path2 = claudeCredentialsPath();
15136
- if (!(0, import_node_fs38.existsSync)(path2)) return null;
15187
+ if (!(0, import_node_fs39.existsSync)(path2)) return null;
15137
15188
  try {
15138
- return accessTokenFromCredentialsJson((0, import_node_fs38.readFileSync)(path2, "utf8"));
15189
+ return accessTokenFromCredentialsJson((0, import_node_fs39.readFileSync)(path2, "utf8"));
15139
15190
  } catch {
15140
15191
  return null;
15141
15192
  }
@@ -15239,13 +15290,13 @@ async function getClaudePlanUsage(opts = {}) {
15239
15290
  })();
15240
15291
  return inflight;
15241
15292
  }
15242
- var import_node_fs38, import_node_os13, import_node_path39, 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;
15293
+ var import_node_fs39, import_node_os13, import_node_path40, 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;
15243
15294
  var init_claude_usage_client = __esm({
15244
15295
  "src/agents/claude-usage-client.ts"() {
15245
15296
  "use strict";
15246
- import_node_fs38 = require("fs");
15297
+ import_node_fs39 = require("fs");
15247
15298
  import_node_os13 = require("os");
15248
- import_node_path39 = require("path");
15299
+ import_node_path40 = require("path");
15249
15300
  init_run();
15250
15301
  init_fetch();
15251
15302
  init_app_settings();
@@ -15613,7 +15664,7 @@ function isAgentHostEnvKey(key) {
15613
15664
  }
15614
15665
  function stripHostToolingPath(pathValue) {
15615
15666
  if (!pathValue?.trim()) return "";
15616
- return pathValue.split(import_node_path40.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path40.delimiter);
15667
+ return pathValue.split(import_node_path41.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path41.delimiter);
15617
15668
  }
15618
15669
  function sanitizeAgentHostEnv(env, cwd) {
15619
15670
  for (const key of Object.keys(env)) {
@@ -15627,11 +15678,11 @@ function sanitizeAgentHostEnv(env, cwd) {
15627
15678
  }
15628
15679
  return env;
15629
15680
  }
15630
- var import_node_path40, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15681
+ var import_node_path41, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15631
15682
  var init_agent_host_env = __esm({
15632
15683
  "src/hook/agent-host-env.ts"() {
15633
15684
  "use strict";
15634
- import_node_path40 = require("path");
15685
+ import_node_path41 = require("path");
15635
15686
  DROP_EXACT = /* @__PURE__ */ new Set([
15636
15687
  "NODE_PATH",
15637
15688
  "NODE_ENV_ELECTRON_VITE",
@@ -15670,15 +15721,15 @@ var init_agent_host_env = __esm({
15670
15721
 
15671
15722
  // src/hook/worktree-pkg-cache.ts
15672
15723
  function worktreePkgCacheRoot(worktreePath) {
15673
- return (0, import_node_path41.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15724
+ return (0, import_node_path42.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15674
15725
  }
15675
15726
  function worktreePkgCacheEnv(worktreePath) {
15676
15727
  const root = worktreePkgCacheRoot(worktreePath);
15677
- const store = (0, import_node_path41.join)(root, "pnpm-store");
15678
- const pnpmCache = (0, import_node_path41.join)(root, "pnpm");
15679
- const npmCache = (0, import_node_path41.join)(root, "npm");
15680
- const nodeGyp = (0, import_node_path41.join)(root, "node-gyp");
15681
- const electron = (0, import_node_path41.join)(root, "electron");
15728
+ const store = (0, import_node_path42.join)(root, "pnpm-store");
15729
+ const pnpmCache = (0, import_node_path42.join)(root, "pnpm");
15730
+ const npmCache = (0, import_node_path42.join)(root, "npm");
15731
+ const nodeGyp = (0, import_node_path42.join)(root, "node-gyp");
15732
+ const electron = (0, import_node_path42.join)(root, "electron");
15682
15733
  return {
15683
15734
  npm_config_store_dir: store,
15684
15735
  PNPM_STORE_DIR: store,
@@ -15700,8 +15751,8 @@ function fillGroup(env, keys, values) {
15700
15751
  }
15701
15752
  }
15702
15753
  function ensureWorktreePkgCacheDirs(worktreePath) {
15703
- if (!(0, import_node_fs39.existsSync)(worktreePath)) return;
15704
- (0, import_node_fs39.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15754
+ if (!(0, import_node_fs40.existsSync)(worktreePath)) return;
15755
+ (0, import_node_fs40.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15705
15756
  }
15706
15757
  function applyWorktreePkgCacheEnv(env, worktreePath) {
15707
15758
  const cwd = worktreePath.trim();
@@ -15714,12 +15765,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15714
15765
  fillGroup(env, ["electron_config_cache"], next);
15715
15766
  ensureWorktreePkgCacheDirs(cwd);
15716
15767
  }
15717
- var import_node_fs39, import_node_path41, WORKTREE_PKG_CACHE_REL;
15768
+ var import_node_fs40, import_node_path42, WORKTREE_PKG_CACHE_REL;
15718
15769
  var init_worktree_pkg_cache = __esm({
15719
15770
  "src/hook/worktree-pkg-cache.ts"() {
15720
15771
  "use strict";
15721
- import_node_fs39 = require("fs");
15722
- import_node_path41 = require("path");
15772
+ import_node_fs40 = require("fs");
15773
+ import_node_path42 = require("path");
15723
15774
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15724
15775
  }
15725
15776
  });
@@ -16960,21 +17011,21 @@ function shouldRefreshReviewRequestTemplate(content) {
16960
17011
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
16961
17012
  }
16962
17013
  function readTextIfPresent(abs) {
16963
- if (!(0, import_node_fs40.existsSync)(abs)) return null;
17014
+ if (!(0, import_node_fs41.existsSync)(abs)) return null;
16964
17015
  try {
16965
- const content = (0, import_node_fs40.readFileSync)(abs, "utf8");
17016
+ const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
16966
17017
  return content.trim() ? content : null;
16967
17018
  } catch {
16968
17019
  return null;
16969
17020
  }
16970
17021
  }
16971
17022
  function readLocalGuidelines(worktreePath) {
16972
- const localAbs = (0, import_node_path42.join)(worktreePath, REVIEW_REQUEST_PATH);
17023
+ const localAbs = (0, import_node_path43.join)(worktreePath, REVIEW_REQUEST_PATH);
16973
17024
  const localContent = readTextIfPresent(localAbs);
16974
17025
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
16975
17026
  return { path: REVIEW_REQUEST_PATH, content: localContent };
16976
17027
  }
16977
- const legacyAbs = (0, import_node_path42.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17028
+ const legacyAbs = (0, import_node_path43.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16978
17029
  const legacyContent = readTextIfPresent(legacyAbs);
16979
17030
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
16980
17031
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -16998,27 +17049,27 @@ function contextGuidelines(content, source) {
16998
17049
  };
16999
17050
  }
17000
17051
  function writeContextGuidelines(worktreePath, content) {
17001
- const abs = (0, import_node_path42.join)(worktreePath, CONTEXT_REVIEW_PATH);
17002
- (0, import_node_fs40.mkdirSync)((0, import_node_path42.dirname)(abs), { recursive: true });
17052
+ const abs = (0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH);
17053
+ (0, import_node_fs41.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
17003
17054
  const body = content.endsWith("\n") ? content : `${content}
17004
17055
  `;
17005
- (0, import_node_fs40.writeFileSync)(abs, body, "utf8");
17056
+ (0, import_node_fs41.writeFileSync)(abs, body, "utf8");
17006
17057
  return body;
17007
17058
  }
17008
17059
  function readSideboardReview(worktreePath, repoPath) {
17009
- const fromWorktree = readTextIfPresent((0, import_node_path42.join)(worktreePath, REPO_REVIEW_PATH));
17060
+ const fromWorktree = readTextIfPresent((0, import_node_path43.join)(worktreePath, REPO_REVIEW_PATH));
17010
17061
  if (fromWorktree) return fromWorktree;
17011
17062
  const repo = repoPath?.replace(/\/+$/, "");
17012
17063
  const wt = worktreePath.replace(/\/+$/, "");
17013
17064
  if (!repo || repo === wt) return null;
17014
- return readTextIfPresent((0, import_node_path42.join)(repo, REPO_REVIEW_PATH));
17065
+ return readTextIfPresent((0, import_node_path43.join)(repo, REPO_REVIEW_PATH));
17015
17066
  }
17016
17067
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
17017
- const skillContent = readTextIfPresent((0, import_node_path42.join)(worktreePath, REVIEW_SKILL_PATH));
17068
+ const skillContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_SKILL_PATH));
17018
17069
  if (skillContent) {
17019
17070
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
17020
17071
  }
17021
- const contextContent = readTextIfPresent((0, import_node_path42.join)(worktreePath, CONTEXT_REVIEW_PATH));
17072
+ const contextContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH));
17022
17073
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
17023
17074
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
17024
17075
  }
@@ -17056,7 +17107,7 @@ function buildReviewRequestAttachment(content, opts) {
17056
17107
  };
17057
17108
  }
17058
17109
  function readExistingReviewRequestFile(worktreePath) {
17059
- return readTextIfPresent((0, import_node_path42.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path42.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
17110
+ return readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
17060
17111
  }
17061
17112
  async function requestReview(threadRef, send2) {
17062
17113
  const from = findThreadByRef(threadRef);
@@ -17083,13 +17134,13 @@ async function requestReview(threadRef, send2) {
17083
17134
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
17084
17135
  return { tab: started, from };
17085
17136
  }
17086
- var import_node_crypto9, import_node_fs40, import_node_path42, 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;
17137
+ var import_node_crypto9, import_node_fs41, import_node_path43, 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;
17087
17138
  var init_request_review = __esm({
17088
17139
  "src/review/request-review.ts"() {
17089
17140
  "use strict";
17090
17141
  import_node_crypto9 = require("crypto");
17091
- import_node_fs40 = require("fs");
17092
- import_node_path42 = require("path");
17142
+ import_node_fs41 = require("fs");
17143
+ import_node_path43 = require("path");
17093
17144
  init_global_workspace();
17094
17145
  init_chat_tabs();
17095
17146
  init_thread_store();
@@ -17115,9 +17166,9 @@ function matchSimpleGlob(pattern, name) {
17115
17166
  return new RegExp(`^${escaped}$`).test(name);
17116
17167
  }
17117
17168
  function readWorktreeInclude(repoPath) {
17118
- const path2 = (0, import_node_path43.join)(repoPath, ".worktreeinclude");
17119
- if (!(0, import_node_fs41.existsSync)(path2)) return [];
17120
- return (0, import_node_fs41.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17169
+ const path2 = (0, import_node_path44.join)(repoPath, ".worktreeinclude");
17170
+ if (!(0, import_node_fs42.existsSync)(path2)) return [];
17171
+ return (0, import_node_fs42.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17121
17172
  }
17122
17173
  function resolveFilesToCopy(repoPath) {
17123
17174
  const fromInclude = readWorktreeInclude(repoPath);
@@ -17127,10 +17178,10 @@ function resolveFilesToCopy(repoPath) {
17127
17178
  if (settings?.fileIncludeGlobs?.length) {
17128
17179
  const matched = [];
17129
17180
  try {
17130
- for (const entry of (0, import_node_fs41.readdirSync)(repoPath, { withFileTypes: true })) {
17181
+ for (const entry of (0, import_node_fs42.readdirSync)(repoPath, { withFileTypes: true })) {
17131
17182
  if (!entry.isFile()) continue;
17132
17183
  for (const glob of settings.fileIncludeGlobs) {
17133
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path43.basename)(glob), entry.name)) {
17184
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path44.basename)(glob), entry.name)) {
17134
17185
  matched.push(entry.name);
17135
17186
  break;
17136
17187
  }
@@ -17142,7 +17193,7 @@ function resolveFilesToCopy(repoPath) {
17142
17193
  }
17143
17194
  const defaults = [];
17144
17195
  try {
17145
- for (const entry of (0, import_node_fs41.readdirSync)(repoPath, { withFileTypes: true })) {
17196
+ for (const entry of (0, import_node_fs42.readdirSync)(repoPath, { withFileTypes: true })) {
17146
17197
  if (entry.isFile() && entry.name.startsWith(".env")) {
17147
17198
  defaults.push(entry.name);
17148
17199
  }
@@ -17156,11 +17207,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
17156
17207
  const patterns = resolveFilesToCopy(repoPath);
17157
17208
  const copied = [];
17158
17209
  for (const rel of patterns) {
17159
- const src = (0, import_node_path43.join)(repoPath, rel);
17160
- if (!(0, import_node_fs41.existsSync)(src)) continue;
17161
- const dest = (0, import_node_path43.join)(worktreePath, rel);
17162
- (0, import_node_fs41.mkdirSync)((0, import_node_path43.dirname)(dest), { recursive: true });
17163
- (0, import_node_fs41.copyFileSync)(src, dest);
17210
+ const src = (0, import_node_path44.join)(repoPath, rel);
17211
+ if (!(0, import_node_fs42.existsSync)(src)) continue;
17212
+ const dest = (0, import_node_path44.join)(worktreePath, rel);
17213
+ (0, import_node_fs42.mkdirSync)((0, import_node_path44.dirname)(dest), { recursive: true });
17214
+ (0, import_node_fs42.copyFileSync)(src, dest);
17164
17215
  copied.push(rel);
17165
17216
  }
17166
17217
  return copied;
@@ -17195,7 +17246,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
17195
17246
  const env = stripNestedElectronEnv({
17196
17247
  ...baseEnv ?? process.env
17197
17248
  });
17198
- const name = opts.workspaceName ?? (0, import_node_path43.basename)(opts.worktreePath);
17249
+ const name = opts.workspaceName ?? (0, import_node_path44.basename)(opts.worktreePath);
17199
17250
  const ports = opts.ports ?? [];
17200
17251
  const primary = ports[0];
17201
17252
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -17421,70 +17472,112 @@ function getRunScript(worktreePath, repoPath, name) {
17421
17472
  function getRunMode(worktreePath, repoPath) {
17422
17473
  return loadWorkspaceSettings(worktreePath, repoPath)?.runMode ?? "concurrent";
17423
17474
  }
17424
- async function allocatePort() {
17475
+ async function reservePort() {
17425
17476
  return new Promise((resolve, reject) => {
17426
17477
  const server = (0, import_node_net.createServer)();
17478
+ let released = false;
17479
+ const release = () => new Promise((res) => {
17480
+ if (released) {
17481
+ res();
17482
+ return;
17483
+ }
17484
+ released = true;
17485
+ server.close(() => res());
17486
+ });
17427
17487
  server.listen(0, "127.0.0.1", () => {
17428
17488
  const addr = server.address();
17429
17489
  if (!addr || typeof addr === "string") {
17430
- server.close();
17431
- reject(new Error("Failed to allocate port"));
17490
+ void release().then(() => reject(new Error("Failed to allocate port")));
17432
17491
  return;
17433
17492
  }
17434
- const port = addr.port;
17435
- server.close((err) => err ? reject(err) : resolve(port));
17493
+ resolve({ port: addr.port, release });
17436
17494
  });
17437
17495
  server.on("error", reject);
17438
17496
  });
17439
17497
  }
17440
- async function allocatePortRange(size = PORT_RANGE_SIZE) {
17441
- const base = await allocatePort();
17442
- const ports = [base];
17443
- for (let i = 1; i < size; i++) {
17444
- const candidate = base + i;
17445
- const free = await new Promise((resolve) => {
17446
- const server = (0, import_node_net.createServer)();
17447
- server.once("error", () => resolve(false));
17448
- server.listen(candidate, "127.0.0.1", () => {
17449
- server.close(() => resolve(true));
17450
- });
17498
+ async function allocatePort() {
17499
+ const held = await reservePort();
17500
+ await held.release();
17501
+ return held.port;
17502
+ }
17503
+ async function tryReservePort(port) {
17504
+ return new Promise((resolve) => {
17505
+ const server = (0, import_node_net.createServer)();
17506
+ let released = false;
17507
+ const release = () => new Promise((res) => {
17508
+ if (released) {
17509
+ res();
17510
+ return;
17511
+ }
17512
+ released = true;
17513
+ server.close(() => res());
17451
17514
  });
17452
- if (free) {
17453
- ports.push(candidate);
17454
- } else {
17455
- ports.push(await allocatePort());
17515
+ server.once("error", () => resolve(null));
17516
+ server.listen(port, "127.0.0.1", () => {
17517
+ resolve({ port, release });
17518
+ });
17519
+ });
17520
+ }
17521
+ async function reservePortRange(size = PORT_RANGE_SIZE) {
17522
+ const held = [await reservePort()];
17523
+ const base = held[0].port;
17524
+ try {
17525
+ for (let i = 1; i < size; i++) {
17526
+ const candidate = base + i;
17527
+ const next = await tryReservePort(candidate);
17528
+ if (next) {
17529
+ held.push(next);
17530
+ } else {
17531
+ held.push(await reservePort());
17532
+ }
17456
17533
  }
17534
+ return held;
17535
+ } catch (err) {
17536
+ await Promise.all(held.map((h) => h.release()));
17537
+ throw err;
17457
17538
  }
17539
+ }
17540
+ async function allocatePortRange(size = PORT_RANGE_SIZE) {
17541
+ const held = await reservePortRange(size);
17542
+ const ports = held.map((h) => h.port);
17543
+ await Promise.all(held.map((h) => h.release()));
17458
17544
  return ports;
17459
17545
  }
17460
17546
  async function startDevServer(repoPath, worktreePath, onLine, opts) {
17461
17547
  const script = getRunScript(worktreePath, repoPath, opts?.scriptName);
17462
17548
  if (!script) return null;
17463
- const ports = await allocatePortRange(PORT_RANGE_SIZE);
17464
- const handle = await spawnWorkspaceScript(script.command, {
17465
- worktreePath,
17466
- repoPath,
17467
- ports,
17468
- defaultBranch: opts?.defaultBranch,
17469
- onLine
17470
- });
17471
- return {
17472
- pid: handle.pid,
17473
- port: ports[0],
17474
- ports,
17475
- scriptName: script.name,
17476
- kill: handle.kill,
17477
- done: handle.done
17478
- };
17549
+ const held = await reservePortRange(PORT_RANGE_SIZE);
17550
+ const ports = held.map((h) => h.port);
17551
+ try {
17552
+ await Promise.all(held.map((h) => h.release()));
17553
+ const handle = await spawnWorkspaceScript(script.command, {
17554
+ worktreePath,
17555
+ repoPath,
17556
+ ports,
17557
+ defaultBranch: opts?.defaultBranch,
17558
+ onLine
17559
+ });
17560
+ return {
17561
+ pid: handle.pid,
17562
+ port: ports[0],
17563
+ ports,
17564
+ scriptName: script.name,
17565
+ kill: handle.kill,
17566
+ done: handle.done
17567
+ };
17568
+ } catch (err) {
17569
+ await Promise.all(held.map((h) => h.release()));
17570
+ throw err;
17571
+ }
17479
17572
  }
17480
- var import_node_fs41, import_node_child_process5, import_node_net, import_node_path43, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17573
+ var import_node_fs42, import_node_child_process5, import_node_net, import_node_path44, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17481
17574
  var init_conductor = __esm({
17482
17575
  "src/hook/conductor.ts"() {
17483
17576
  "use strict";
17484
- import_node_fs41 = require("fs");
17577
+ import_node_fs42 = require("fs");
17485
17578
  import_node_child_process5 = require("child_process");
17486
17579
  import_node_net = require("net");
17487
- import_node_path43 = require("path");
17580
+ import_node_path44 = require("path");
17488
17581
  import_execa4 = require("execa");
17489
17582
  import_node_readline3 = require("readline");
17490
17583
  init_settings();
@@ -17512,9 +17605,9 @@ async function findOrphanWorktrees(repoPaths) {
17512
17605
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17513
17606
  );
17514
17607
  const homeRoot = sideboardWorkspacesDir();
17515
- if ((0, import_node_fs42.existsSync)(homeRoot)) {
17608
+ if ((0, import_node_fs43.existsSync)(homeRoot)) {
17516
17609
  try {
17517
- for (const entry of (0, import_node_fs42.readdirSync)(homeRoot, { withFileTypes: true })) {
17610
+ for (const entry of (0, import_node_fs43.readdirSync)(homeRoot, { withFileTypes: true })) {
17518
17611
  if (!entry.isDirectory()) continue;
17519
17612
  void entry;
17520
17613
  }
@@ -17524,7 +17617,7 @@ async function findOrphanWorktrees(repoPaths) {
17524
17617
  const orphans = [];
17525
17618
  const seen = /* @__PURE__ */ new Set();
17526
17619
  for (const repoPath of repos) {
17527
- if (!repoPath || !(0, import_node_fs42.existsSync)(repoPath)) continue;
17620
+ if (!repoPath || !(0, import_node_fs43.existsSync)(repoPath)) continue;
17528
17621
  try {
17529
17622
  const wts = await listWorktrees(repoPath);
17530
17623
  for (const wt of wts) {
@@ -17535,7 +17628,7 @@ async function findOrphanWorktrees(repoPaths) {
17535
17628
  seen.add(path2);
17536
17629
  let mtimeMs = 0;
17537
17630
  try {
17538
- mtimeMs = (0, import_node_fs42.statSync)(path2).mtimeMs;
17631
+ mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17539
17632
  } catch {
17540
17633
  mtimeMs = 0;
17541
17634
  }
@@ -17545,16 +17638,16 @@ async function findOrphanWorktrees(repoPaths) {
17545
17638
  }
17546
17639
  try {
17547
17640
  const root = worktreesRoot(repoPath);
17548
- if ((0, import_node_fs42.existsSync)(root)) {
17549
- for (const entry of (0, import_node_fs42.readdirSync)(root, { withFileTypes: true })) {
17641
+ if ((0, import_node_fs43.existsSync)(root)) {
17642
+ for (const entry of (0, import_node_fs43.readdirSync)(root, { withFileTypes: true })) {
17550
17643
  if (!entry.isDirectory()) continue;
17551
- const path2 = (0, import_node_path44.join)(root, entry.name).replace(/\/$/, "");
17644
+ const path2 = (0, import_node_path45.join)(root, entry.name).replace(/\/$/, "");
17552
17645
  if (known.has(path2) || seen.has(path2)) continue;
17553
- if (!(0, import_node_fs42.existsSync)((0, import_node_path44.join)(path2, ".git"))) continue;
17646
+ if (!(0, import_node_fs43.existsSync)((0, import_node_path45.join)(path2, ".git"))) continue;
17554
17647
  seen.add(path2);
17555
17648
  let mtimeMs = 0;
17556
17649
  try {
17557
- mtimeMs = (0, import_node_fs42.statSync)(path2).mtimeMs;
17650
+ mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17558
17651
  } catch {
17559
17652
  mtimeMs = Date.now();
17560
17653
  }
@@ -17615,12 +17708,12 @@ function worktreeCleanupSettings() {
17615
17708
  autoCleanupOrphans: a.autoCleanupOrphans
17616
17709
  };
17617
17710
  }
17618
- var import_node_fs42, import_node_path44;
17711
+ var import_node_fs43, import_node_path45;
17619
17712
  var init_orphan_cleanup = __esm({
17620
17713
  "src/git/orphan-cleanup.ts"() {
17621
17714
  "use strict";
17622
- import_node_fs42 = require("fs");
17623
- import_node_path44 = require("path");
17715
+ import_node_fs43 = require("fs");
17716
+ import_node_path45 = require("path");
17624
17717
  init_worktree();
17625
17718
  init_thread_store();
17626
17719
  init_paths();
@@ -17795,12 +17888,12 @@ async function cloneRepoIntoSideboard(opts) {
17795
17888
  if (!url) throw new Error("Clone URL is required");
17796
17889
  let name = opts.name?.trim();
17797
17890
  if (!name) {
17798
- const leaf = (0, import_node_path45.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17891
+ const leaf = (0, import_node_path46.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17799
17892
  name = leaf || "repo";
17800
17893
  }
17801
17894
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
17802
- const dest = (0, import_node_path45.join)(sideboardReposDir(), name);
17803
- if ((0, import_node_fs43.existsSync)(dest)) {
17895
+ const dest = (0, import_node_path46.join)(sideboardReposDir(), name);
17896
+ if ((0, import_node_fs44.existsSync)(dest)) {
17804
17897
  const repoPath2 = await resolveRepoRoot(dest);
17805
17898
  const workspace2 = await ensureWorkspace(repoPath2);
17806
17899
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -17815,12 +17908,12 @@ async function cloneRepoIntoSideboard(opts) {
17815
17908
  const workspace = await ensureWorkspace(repoPath);
17816
17909
  return { repoPath, workspace };
17817
17910
  }
17818
- var import_node_fs43, import_node_path45, import_execa6;
17911
+ var import_node_fs44, import_node_path46, import_execa6;
17819
17912
  var init_clone_repo = __esm({
17820
17913
  "src/git/clone-repo.ts"() {
17821
17914
  "use strict";
17822
- import_node_fs43 = require("fs");
17823
- import_node_path45 = require("path");
17915
+ import_node_fs44 = require("fs");
17916
+ import_node_path46 = require("path");
17824
17917
  import_execa6 = require("execa");
17825
17918
  init_paths();
17826
17919
  init_workspaces();
@@ -17941,24 +18034,24 @@ function jobTreeAlive(pid) {
17941
18034
  return jobAlive(pid) || processGroupAlive(pid);
17942
18035
  }
17943
18036
  function readIntFile(file) {
17944
- if (!(0, import_node_fs44.existsSync)(file)) return null;
17945
- const n = Number.parseInt((0, import_node_fs44.readFileSync)(file, "utf8").trim(), 10);
18037
+ if (!(0, import_node_fs45.existsSync)(file)) return null;
18038
+ const n = Number.parseInt((0, import_node_fs45.readFileSync)(file, "utf8").trim(), 10);
17946
18039
  return Number.isInteger(n) ? n : null;
17947
18040
  }
17948
18041
  function jobDir(root, id, legacy = false) {
17949
- return (0, import_node_path46.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18042
+ return (0, import_node_path47.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
17950
18043
  }
17951
18044
  function resolveJobDir(root, id) {
17952
18045
  const modern = jobDir(root, id, false);
17953
- if ((0, import_node_fs44.existsSync)(modern)) return modern;
18046
+ if ((0, import_node_fs45.existsSync)(modern)) return modern;
17954
18047
  const legacy = jobDir(root, id, true);
17955
- if ((0, import_node_fs44.existsSync)(legacy)) return legacy;
18048
+ if ((0, import_node_fs45.existsSync)(legacy)) return legacy;
17956
18049
  return modern;
17957
18050
  }
17958
18051
  function listJobIdsIn(root, rel) {
17959
- const dir = (0, import_node_path46.join)(root, rel);
17960
- if (!(0, import_node_fs44.existsSync)(dir)) return [];
17961
- return (0, import_node_fs44.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
18052
+ const dir = (0, import_node_path47.join)(root, rel);
18053
+ if (!(0, import_node_fs45.existsSync)(dir)) return [];
18054
+ return (0, import_node_fs45.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
17962
18055
  }
17963
18056
  function listRunningDetachedJobs(worktreePath) {
17964
18057
  const root = worktreePath.trim();
@@ -17970,7 +18063,7 @@ function listRunningDetachedJobs(worktreePath) {
17970
18063
  const running = [];
17971
18064
  for (const id of ids) {
17972
18065
  const dir = resolveJobDir(root, id);
17973
- const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
18066
+ const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
17974
18067
  if (jobTreeAlive(pid)) running.push(id);
17975
18068
  }
17976
18069
  return running.sort();
@@ -18053,8 +18146,8 @@ function planJobContinue(opts) {
18053
18146
  return { action: "none" };
18054
18147
  }
18055
18148
  function tailProgress(logFile, maxLines = 12) {
18056
- if (!(0, import_node_fs44.existsSync)(logFile)) return "(no log yet)";
18057
- const lines = (0, import_node_fs44.readFileSync)(logFile, "utf8").split("\n");
18149
+ if (!(0, import_node_fs45.existsSync)(logFile)) return "(no log yet)";
18150
+ const lines = (0, import_node_fs45.readFileSync)(logFile, "utf8").split("\n");
18058
18151
  return lines.slice(-maxLines).join("\n");
18059
18152
  }
18060
18153
  function lastProgressLine(progress) {
@@ -18062,8 +18155,8 @@ function lastProgressLine(progress) {
18062
18155
  return last ? last.slice(0, 72) : void 0;
18063
18156
  }
18064
18157
  function readLogLines(file) {
18065
- if (!(0, import_node_fs44.existsSync)(file)) return [];
18066
- const lines = (0, import_node_fs44.readFileSync)(file, "utf8").split("\n");
18158
+ if (!(0, import_node_fs45.existsSync)(file)) return [];
18159
+ const lines = (0, import_node_fs45.readFileSync)(file, "utf8").split("\n");
18067
18160
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
18068
18161
  return lines;
18069
18162
  }
@@ -18074,15 +18167,15 @@ function takeDelta(logFile, cursorFile) {
18074
18167
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
18075
18168
  }
18076
18169
  function snapshotJob(dir) {
18077
- const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
18170
+ const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18078
18171
  const running = jobTreeAlive(pid);
18079
18172
  return {
18080
18173
  pid,
18081
18174
  running,
18082
- exitCode: readIntFile((0, import_node_path46.join)(dir, "exit")),
18083
- log: (0, import_node_path46.join)(dir, "log"),
18084
- cursor: (0, import_node_path46.join)(dir, "present.cursor"),
18085
- progress: tailProgress((0, import_node_path46.join)(dir, "log"))
18175
+ exitCode: readIntFile((0, import_node_path47.join)(dir, "exit")),
18176
+ log: (0, import_node_path47.join)(dir, "log"),
18177
+ cursor: (0, import_node_path47.join)(dir, "present.cursor"),
18178
+ progress: tailProgress((0, import_node_path47.join)(dir, "log"))
18086
18179
  };
18087
18180
  }
18088
18181
  function toResult(id, snap, extra) {
@@ -18091,8 +18184,8 @@ function toResult(id, snap, extra) {
18091
18184
  const stillRunning = snap.running && !ok;
18092
18185
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
18093
18186
  try {
18094
- (0, import_node_fs44.mkdirSync)((0, import_node_path46.dirname)(snap.cursor), { recursive: true });
18095
- (0, import_node_fs44.writeFileSync)(snap.cursor, `${nextCursor}
18187
+ (0, import_node_fs45.mkdirSync)((0, import_node_path47.dirname)(snap.cursor), { recursive: true });
18188
+ (0, import_node_fs45.writeFileSync)(snap.cursor, `${nextCursor}
18096
18189
  `);
18097
18190
  } catch {
18098
18191
  }
@@ -18121,7 +18214,7 @@ async function waitForDetachedJob(cwd, id, opts) {
18121
18214
  const dir = resolveJobDir(root, jobId);
18122
18215
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
18123
18216
  const sleep2 = opts?.sleep ?? sleepMs;
18124
- if (!(0, import_node_fs44.existsSync)(dir)) {
18217
+ if (!(0, import_node_fs45.existsSync)(dir)) {
18125
18218
  return {
18126
18219
  stillRunning: false,
18127
18220
  ok: false,
@@ -18167,10 +18260,10 @@ function killProcessTree(pid, signal) {
18167
18260
  }
18168
18261
  function appendJobLog(logFile, line) {
18169
18262
  try {
18170
- (0, import_node_fs44.mkdirSync)((0, import_node_path46.dirname)(logFile), { recursive: true });
18263
+ (0, import_node_fs45.mkdirSync)((0, import_node_path47.dirname)(logFile), { recursive: true });
18171
18264
  const body = line.endsWith("\n") ? line : `${line}
18172
18265
  `;
18173
- (0, import_node_fs44.appendFileSync)(logFile, body);
18266
+ (0, import_node_fs45.appendFileSync)(logFile, body);
18174
18267
  } catch {
18175
18268
  }
18176
18269
  }
@@ -18180,7 +18273,7 @@ async function stopDetachedJob(cwd, id, opts) {
18180
18273
  const dir = resolveJobDir(root, jobId);
18181
18274
  const sleep2 = opts?.sleep ?? sleepMs;
18182
18275
  const why = opts?.reason?.trim() ?? "";
18183
- if (!(0, import_node_fs44.existsSync)(dir)) {
18276
+ if (!(0, import_node_fs45.existsSync)(dir)) {
18184
18277
  return {
18185
18278
  stillRunning: false,
18186
18279
  ok: false,
@@ -18216,10 +18309,10 @@ async function stopDetachedJob(cwd, id, opts) {
18216
18309
  killProcessTree(targetPid, "SIGKILL");
18217
18310
  await sleep2(100);
18218
18311
  }
18219
- const exitFile = (0, import_node_path46.join)(dir, "exit");
18220
- if (!(0, import_node_fs44.existsSync)(exitFile)) {
18312
+ const exitFile = (0, import_node_path47.join)(dir, "exit");
18313
+ if (!(0, import_node_fs45.existsSync)(exitFile)) {
18221
18314
  try {
18222
- (0, import_node_fs44.writeFileSync)(exitFile, "1\n");
18315
+ (0, import_node_fs45.writeFileSync)(exitFile, "1\n");
18223
18316
  } catch {
18224
18317
  }
18225
18318
  }
@@ -18239,12 +18332,12 @@ async function stopDetachedJob(cwd, id, opts) {
18239
18332
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
18240
18333
  };
18241
18334
  }
18242
- var import_node_fs44, import_node_path46, 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;
18335
+ var import_node_fs45, import_node_path47, 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;
18243
18336
  var init_wait_for_job = __esm({
18244
18337
  "src/mcp/wait-for-job.ts"() {
18245
18338
  "use strict";
18246
- import_node_fs44 = require("fs");
18247
- import_node_path46 = require("path");
18339
+ import_node_fs45 = require("fs");
18340
+ import_node_path47 = require("path");
18248
18341
  init_workspace_scratch();
18249
18342
  init_wait_for_turn();
18250
18343
  MAX_JOB_CONTINUES = 8;
@@ -19789,7 +19882,7 @@ function reuseLiveThread(input, repoPath, match) {
19789
19882
  }
19790
19883
  async function createThread(input, _onSetupLine) {
19791
19884
  const repoPath = await resolveRepoRoot(input.repoPath);
19792
- if (!(0, import_node_fs45.existsSync)(repoPath)) {
19885
+ if (!(0, import_node_fs46.existsSync)(repoPath)) {
19793
19886
  throw new Error(`Repo not found: ${repoPath}`);
19794
19887
  }
19795
19888
  const reused = reuseLiveThread(input, repoPath, {
@@ -19974,11 +20067,11 @@ async function listLinearIssues(agent, repoPath) {
19974
20067
  }
19975
20068
  return adapter.listLinearIssues(repoPath);
19976
20069
  }
19977
- var import_node_fs45;
20070
+ var import_node_fs46;
19978
20071
  var init_create = __esm({
19979
20072
  "src/threads/create.ts"() {
19980
20073
  "use strict";
19981
- import_node_fs45 = require("fs");
20074
+ import_node_fs46 = require("fs");
19982
20075
  init_detect();
19983
20076
  init_worktree();
19984
20077
  init_home_board();
@@ -20130,20 +20223,20 @@ function writeTurnLive(threadId, progress) {
20130
20223
  const path2 = threadLivePath(threadId);
20131
20224
  const tmp = `${path2}.${process.pid}.tmp`;
20132
20225
  try {
20133
- (0, import_node_fs46.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20134
- (0, import_node_fs46.renameSync)(tmp, path2);
20226
+ (0, import_node_fs47.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20227
+ (0, import_node_fs47.renameSync)(tmp, path2);
20135
20228
  } catch {
20136
20229
  try {
20137
- (0, import_node_fs46.unlinkSync)(tmp);
20230
+ (0, import_node_fs47.unlinkSync)(tmp);
20138
20231
  } catch {
20139
20232
  }
20140
20233
  }
20141
20234
  }
20142
20235
  function readTurnLive(threadId) {
20143
20236
  const path2 = threadLivePath(threadId);
20144
- if (!(0, import_node_fs46.existsSync)(path2)) return null;
20237
+ if (!(0, import_node_fs47.existsSync)(path2)) return null;
20145
20238
  try {
20146
- const raw = JSON.parse((0, import_node_fs46.readFileSync)(path2, "utf8"));
20239
+ const raw = JSON.parse((0, import_node_fs47.readFileSync)(path2, "utf8"));
20147
20240
  if (!raw || typeof raw.summary !== "string") return null;
20148
20241
  return raw;
20149
20242
  } catch {
@@ -20155,17 +20248,17 @@ function clearTurnLive(threadId) {
20155
20248
  if (buf?.timer) clearTimeout(buf.timer);
20156
20249
  buffers.delete(threadId);
20157
20250
  const path2 = threadLivePath(threadId);
20158
- if (!(0, import_node_fs46.existsSync)(path2)) return;
20251
+ if (!(0, import_node_fs47.existsSync)(path2)) return;
20159
20252
  try {
20160
- (0, import_node_fs46.unlinkSync)(path2);
20253
+ (0, import_node_fs47.unlinkSync)(path2);
20161
20254
  } catch {
20162
20255
  }
20163
20256
  }
20164
- var import_node_fs46, buffers, FLUSH_MS, MAX_PARTS;
20257
+ var import_node_fs47, buffers, FLUSH_MS, MAX_PARTS;
20165
20258
  var init_turn_live = __esm({
20166
20259
  "src/store/turn-live.ts"() {
20167
20260
  "use strict";
20168
- import_node_fs46 = require("fs");
20261
+ import_node_fs47 = require("fs");
20169
20262
  init_message_parts();
20170
20263
  init_paths();
20171
20264
  buffers = /* @__PURE__ */ new Map();
@@ -20409,7 +20502,7 @@ var init_quota_failover = __esm({
20409
20502
  // src/threads/adopt.ts
20410
20503
  function thisModuleFile() {
20411
20504
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
20412
- return cjsFile || process.argv[1] || (0, import_node_path47.join)(process.cwd(), "package.json");
20505
+ return cjsFile || process.argv[1] || (0, import_node_path48.join)(process.cwd(), "package.json");
20413
20506
  }
20414
20507
  function openReadonlySqlite(file) {
20415
20508
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -20427,21 +20520,21 @@ function mapAgentType(raw) {
20427
20520
  return null;
20428
20521
  }
20429
20522
  function resolveConductorCursorAgentId(workspacePath) {
20430
- if (!workspacePath || !(0, import_node_fs47.existsSync)(CURSOR_SDK_STORE)) return null;
20523
+ if (!workspacePath || !(0, import_node_fs48.existsSync)(CURSOR_SDK_STORE)) return null;
20431
20524
  const normalized = workspacePath.replace(/\/$/, "");
20432
20525
  let best = null;
20433
20526
  let hashes;
20434
20527
  try {
20435
- hashes = (0, import_node_fs47.readdirSync)(CURSOR_SDK_STORE);
20528
+ hashes = (0, import_node_fs48.readdirSync)(CURSOR_SDK_STORE);
20436
20529
  } catch {
20437
20530
  return null;
20438
20531
  }
20439
20532
  for (const hash of hashes) {
20440
- const agentsFile = (0, import_node_path47.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20441
- if (!(0, import_node_fs47.existsSync)(agentsFile)) continue;
20533
+ const agentsFile = (0, import_node_path48.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20534
+ if (!(0, import_node_fs48.existsSync)(agentsFile)) continue;
20442
20535
  let text7;
20443
20536
  try {
20444
- text7 = (0, import_node_fs47.readFileSync)(agentsFile, "utf8");
20537
+ text7 = (0, import_node_fs48.readFileSync)(agentsFile, "utf8");
20445
20538
  } catch {
20446
20539
  continue;
20447
20540
  }
@@ -20465,7 +20558,7 @@ function resolveConductorCursorAgentId(workspacePath) {
20465
20558
  return best?.agentId ?? null;
20466
20559
  }
20467
20560
  async function adoptThread(input) {
20468
- if (!(0, import_node_fs47.existsSync)(input.worktreePath)) {
20561
+ if (!(0, import_node_fs48.existsSync)(input.worktreePath)) {
20469
20562
  throw new Error(`Worktree not found: ${input.worktreePath}`);
20470
20563
  }
20471
20564
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -20494,18 +20587,18 @@ function conductorDbPath() {
20494
20587
  return CONDUCTOR_DB;
20495
20588
  }
20496
20589
  function listConductorWorkspaces() {
20497
- if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
20590
+ if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20498
20591
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20499
20592
  }
20500
- const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20501
- const snapshot = (0, import_node_path47.join)(tmp, "conductor.db");
20593
+ const tmp = (0, import_node_fs48.mkdtempSync)((0, import_node_path48.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20594
+ const snapshot = (0, import_node_path48.join)(tmp, "conductor.db");
20502
20595
  try {
20503
- (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
20596
+ (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20504
20597
  for (const suffix of ["-wal", "-shm"]) {
20505
20598
  const src = `${CONDUCTOR_DB}${suffix}`;
20506
- if ((0, import_node_fs47.existsSync)(src)) {
20599
+ if ((0, import_node_fs48.existsSync)(src)) {
20507
20600
  try {
20508
- (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
20601
+ (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20509
20602
  } catch {
20510
20603
  }
20511
20604
  }
@@ -20581,22 +20674,22 @@ function listConductorWorkspaces() {
20581
20674
  db.close();
20582
20675
  }
20583
20676
  } finally {
20584
- (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
20677
+ (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20585
20678
  }
20586
20679
  }
20587
20680
  function importConductorWorkspace(workspaceId) {
20588
- if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
20681
+ if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20589
20682
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20590
20683
  }
20591
- const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20592
- const snapshot = (0, import_node_path47.join)(tmp, "conductor.db");
20684
+ const tmp = (0, import_node_fs48.mkdtempSync)((0, import_node_path48.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20685
+ const snapshot = (0, import_node_path48.join)(tmp, "conductor.db");
20593
20686
  try {
20594
- (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
20687
+ (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20595
20688
  for (const suffix of ["-wal", "-shm"]) {
20596
20689
  const src = `${CONDUCTOR_DB}${suffix}`;
20597
- if ((0, import_node_fs47.existsSync)(src)) {
20690
+ if ((0, import_node_fs48.existsSync)(src)) {
20598
20691
  try {
20599
- (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
20692
+ (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20600
20693
  } catch {
20601
20694
  }
20602
20695
  }
@@ -20614,7 +20707,7 @@ function importConductorWorkspace(workspaceId) {
20614
20707
  ).get(workspaceId);
20615
20708
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
20616
20709
  const worktreePath = String(row.workspacePath);
20617
- if (!(0, import_node_fs47.existsSync)(worktreePath)) {
20710
+ if (!(0, import_node_fs48.existsSync)(worktreePath)) {
20618
20711
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
20619
20712
  }
20620
20713
  let sessionId = null;
@@ -20677,31 +20770,31 @@ function importConductorWorkspace(workspaceId) {
20677
20770
  db.close();
20678
20771
  }
20679
20772
  } finally {
20680
- (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
20773
+ (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20681
20774
  }
20682
20775
  }
20683
20776
  async function importConductorWorkspaceAsync(workspaceId) {
20684
20777
  return importConductorWorkspace(workspaceId);
20685
20778
  }
20686
- var import_node_child_process6, import_node_fs47, import_node_os14, import_node_path47, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
20779
+ var import_node_child_process6, import_node_fs48, import_node_os14, import_node_path48, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
20687
20780
  var init_adopt = __esm({
20688
20781
  "src/threads/adopt.ts"() {
20689
20782
  "use strict";
20690
20783
  import_node_child_process6 = require("child_process");
20691
- import_node_fs47 = require("fs");
20784
+ import_node_fs48 = require("fs");
20692
20785
  import_node_os14 = require("os");
20693
- import_node_path47 = require("path");
20786
+ import_node_path48 = require("path");
20694
20787
  import_node_module4 = require("module");
20695
20788
  init_worktree();
20696
20789
  init_thread_store();
20697
- CONDUCTOR_APP_SUPPORT = (0, import_node_path47.join)(
20790
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path48.join)(
20698
20791
  process.env.HOME ?? "",
20699
20792
  "Library",
20700
20793
  "Application Support",
20701
20794
  "com.conductor.app"
20702
20795
  );
20703
- CONDUCTOR_DB = (0, import_node_path47.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20704
- CURSOR_SDK_STORE = (0, import_node_path47.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20796
+ CONDUCTOR_DB = (0, import_node_path48.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20797
+ CURSOR_SDK_STORE = (0, import_node_path48.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20705
20798
  }
20706
20799
  });
20707
20800
 
@@ -20768,7 +20861,7 @@ async function openStackLayer(input, _onSetupLine) {
20768
20861
  let createdWorktree = false;
20769
20862
  const trees = await listWorktrees(repoPath);
20770
20863
  const checkedOut = trees.find((w) => w.branch === branchName);
20771
- if (checkedOut?.path && (0, import_node_fs48.existsSync)(checkedOut.path)) {
20864
+ if (checkedOut?.path && (0, import_node_fs49.existsSync)(checkedOut.path)) {
20772
20865
  if (input.reuseExistingWorktree !== false) {
20773
20866
  worktreePath = checkedOut.path;
20774
20867
  } else {
@@ -20910,7 +21003,7 @@ async function initStackFromThread(input, onSetupLine) {
20910
21003
  async function createPrStack(input, onSetupLine) {
20911
21004
  await requireAgent(input.agent);
20912
21005
  const repoPath = await resolveRepoRoot(input.repoPath);
20913
- if (!(0, import_node_fs48.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21006
+ if (!(0, import_node_fs49.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
20914
21007
  if (!input.branches.length) throw new Error("At least one branch name required");
20915
21008
  const status = await detectGhStack(repoPath);
20916
21009
  if (!status.available) throw new Error(status.reason);
@@ -20977,7 +21070,7 @@ async function createPrStack(input, onSetupLine) {
20977
21070
  }
20978
21071
  }
20979
21072
  const claimed = new Set(threads.map((t) => t.worktreePath));
20980
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs48.existsSync)(bootstrap.worktreePath)) {
21073
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs49.existsSync)(bootstrap.worktreePath)) {
20981
21074
  try {
20982
21075
  await removeWorktree(repoPath, bootstrap.worktreePath, {
20983
21076
  deleteBranch: bootstrap.branchName
@@ -20997,11 +21090,11 @@ function stackAgentDefaultsFrom(input) {
20997
21090
  planMode: input.planMode
20998
21091
  };
20999
21092
  }
21000
- var import_node_fs48;
21093
+ var import_node_fs49;
21001
21094
  var init_stack_layers = __esm({
21002
21095
  "src/threads/stack-layers.ts"() {
21003
21096
  "use strict";
21004
- import_node_fs48 = require("fs");
21097
+ import_node_fs49 = require("fs");
21005
21098
  init_detect();
21006
21099
  init_run();
21007
21100
  init_stack();
@@ -21014,7 +21107,7 @@ var init_stack_layers = __esm({
21014
21107
 
21015
21108
  // src/diff/diff.ts
21016
21109
  async function inspectGitWorktree(worktreePath) {
21017
- if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) return "missing_worktree";
21110
+ if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) return "missing_worktree";
21018
21111
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
21019
21112
  reject: false
21020
21113
  });
@@ -21022,7 +21115,7 @@ async function inspectGitWorktree(worktreePath) {
21022
21115
  return "ok";
21023
21116
  }
21024
21117
  async function initializeGitRepository(worktreePath) {
21025
- if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) {
21118
+ if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) {
21026
21119
  throw new Error("Worktree not found");
21027
21120
  }
21028
21121
  const status = await inspectGitWorktree(worktreePath);
@@ -21156,11 +21249,11 @@ new file mode 100644
21156
21249
  };
21157
21250
  }
21158
21251
  async function untrackedPatch(worktreePath, path2, maxHunk) {
21159
- const abs = (0, import_node_path48.join)(worktreePath, path2);
21252
+ const abs = (0, import_node_path49.join)(worktreePath, path2);
21160
21253
  try {
21161
- const st = (0, import_node_fs49.statSync)(abs);
21254
+ const st = (0, import_node_fs50.statSync)(abs);
21162
21255
  if (st.isFile() && st.size > maxHunk) {
21163
- const buf = (0, import_node_fs49.readFileSync)(abs).subarray(0, maxHunk);
21256
+ const buf = (0, import_node_fs50.readFileSync)(abs).subarray(0, maxHunk);
21164
21257
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
21165
21258
  }
21166
21259
  } catch {
@@ -21627,9 +21720,9 @@ async function getDiff(worktreePath, repoPath, opts) {
21627
21720
  }
21628
21721
  function statWorktreePath(worktreePath, relativePath) {
21629
21722
  assertSafeRelativePath(relativePath);
21630
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21631
- if (!(0, import_node_fs49.existsSync)(abs)) return "missing";
21632
- const st = (0, import_node_fs49.statSync)(abs);
21723
+ const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21724
+ if (!(0, import_node_fs50.existsSync)(abs)) return "missing";
21725
+ const st = (0, import_node_fs50.statSync)(abs);
21633
21726
  if (st.isDirectory()) return "dir";
21634
21727
  if (st.isFile()) return "file";
21635
21728
  return "missing";
@@ -21658,8 +21751,8 @@ function isImageRelativePath(relativePath) {
21658
21751
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21659
21752
  assertSafeRelativePath(relativePath);
21660
21753
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
21661
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21662
- const st = (0, import_node_fs49.statSync)(abs);
21754
+ const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21755
+ const st = (0, import_node_fs50.statSync)(abs);
21663
21756
  if (!st.isFile()) {
21664
21757
  throw new Error(`Not a file: ${relativePath}`);
21665
21758
  }
@@ -21668,7 +21761,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21668
21761
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
21669
21762
  );
21670
21763
  }
21671
- const buf = (0, import_node_fs49.readFileSync)(abs);
21764
+ const buf = (0, import_node_fs50.readFileSync)(abs);
21672
21765
  return {
21673
21766
  path: relativePath,
21674
21767
  contentBase64: buf.toString("base64"),
@@ -21678,12 +21771,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21678
21771
  function readWorktreeFile(worktreePath, relativePath, opts) {
21679
21772
  assertSafeRelativePath(relativePath);
21680
21773
  const maxBytes = opts?.maxBytes ?? 2e5;
21681
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21682
- const st = (0, import_node_fs49.statSync)(abs);
21774
+ const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21775
+ const st = (0, import_node_fs50.statSync)(abs);
21683
21776
  if (!st.isFile()) {
21684
21777
  throw new Error(`Not a file: ${relativePath}`);
21685
21778
  }
21686
- const buf = (0, import_node_fs49.readFileSync)(abs);
21779
+ const buf = (0, import_node_fs50.readFileSync)(abs);
21687
21780
  if (isImageRelativePath(relativePath)) {
21688
21781
  const maxImageBytes = Math.max(maxBytes, 15e6);
21689
21782
  const truncated2 = buf.length > maxImageBytes;
@@ -21726,9 +21819,9 @@ function assertSafeRelativePath(relativePath) {
21726
21819
  }
21727
21820
  function writeWorktreeFile(worktreePath, relativePath, content) {
21728
21821
  assertSafeRelativePath(relativePath);
21729
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21730
- (0, import_node_fs49.mkdirSync)((0, import_node_path48.dirname)(abs), { recursive: true });
21731
- (0, import_node_fs49.writeFileSync)(abs, content, "utf8");
21822
+ const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21823
+ (0, import_node_fs50.mkdirSync)((0, import_node_path49.dirname)(abs), { recursive: true });
21824
+ (0, import_node_fs50.writeFileSync)(abs, content, "utf8");
21732
21825
  return { path: relativePath };
21733
21826
  }
21734
21827
  async function getWorktreeDirtyStat(worktreePath) {
@@ -21768,12 +21861,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
21768
21861
  truncated: full.files.length > maxFiles
21769
21862
  };
21770
21863
  }
21771
- var import_node_fs49, import_node_path48, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21864
+ var import_node_fs50, import_node_path49, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21772
21865
  var init_diff = __esm({
21773
21866
  "src/diff/diff.ts"() {
21774
21867
  "use strict";
21775
- import_node_fs49 = require("fs");
21776
- import_node_path48 = require("path");
21868
+ import_node_fs50 = require("fs");
21869
+ import_node_path49 = require("path");
21777
21870
  init_run();
21778
21871
  init_worktree();
21779
21872
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -22130,7 +22223,7 @@ function parseFrontmatter(content) {
22130
22223
  }
22131
22224
  function readSkill(skillMd, source) {
22132
22225
  try {
22133
- const content = (0, import_node_fs50.readFileSync)(skillMd, "utf8");
22226
+ const content = (0, import_node_fs51.readFileSync)(skillMd, "utf8");
22134
22227
  const { name: fmName, description } = parseFrontmatter(content);
22135
22228
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
22136
22229
  const name = fmName || dirName;
@@ -22149,19 +22242,19 @@ function readSkill(skillMd, source) {
22149
22242
  }
22150
22243
  }
22151
22244
  function scanSkillsDir(dir, source, out) {
22152
- if (!(0, import_node_fs50.existsSync)(dir)) return;
22245
+ if (!(0, import_node_fs51.existsSync)(dir)) return;
22153
22246
  let entries;
22154
22247
  try {
22155
- entries = (0, import_node_fs50.readdirSync)(dir);
22248
+ entries = (0, import_node_fs51.readdirSync)(dir);
22156
22249
  } catch {
22157
22250
  return;
22158
22251
  }
22159
22252
  for (const entry of entries) {
22160
22253
  if (entry.startsWith(".")) continue;
22161
- const skillMd = (0, import_node_path49.join)(dir, entry, "SKILL.md");
22162
- if (!(0, import_node_fs50.existsSync)(skillMd)) continue;
22254
+ const skillMd = (0, import_node_path50.join)(dir, entry, "SKILL.md");
22255
+ if (!(0, import_node_fs51.existsSync)(skillMd)) continue;
22163
22256
  try {
22164
- if (!(0, import_node_fs50.statSync)(skillMd).isFile()) continue;
22257
+ if (!(0, import_node_fs51.statSync)(skillMd).isFile()) continue;
22165
22258
  } catch {
22166
22259
  continue;
22167
22260
  }
@@ -22170,24 +22263,24 @@ function scanSkillsDir(dir, source, out) {
22170
22263
  }
22171
22264
  }
22172
22265
  function scanClaudePluginSkills(pluginsRoot, out) {
22173
- if (!(0, import_node_fs50.existsSync)(pluginsRoot)) return;
22266
+ if (!(0, import_node_fs51.existsSync)(pluginsRoot)) return;
22174
22267
  const walk = (dir, depth, lookingForSkillsDir) => {
22175
22268
  if (depth > 7) return;
22176
22269
  let entries;
22177
22270
  try {
22178
- entries = (0, import_node_fs50.readdirSync)(dir);
22271
+ entries = (0, import_node_fs51.readdirSync)(dir);
22179
22272
  } catch {
22180
22273
  return;
22181
22274
  }
22182
22275
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
22183
- const skill = readSkill((0, import_node_path49.join)(dir, "SKILL.md"), "cli");
22276
+ const skill = readSkill((0, import_node_path50.join)(dir, "SKILL.md"), "cli");
22184
22277
  if (skill) out.push(skill);
22185
22278
  }
22186
22279
  for (const entry of entries) {
22187
22280
  if (entry === "node_modules" || entry === ".git") continue;
22188
- const full = (0, import_node_path49.join)(dir, entry);
22281
+ const full = (0, import_node_path50.join)(dir, entry);
22189
22282
  try {
22190
- if (!(0, import_node_fs50.statSync)(full).isDirectory()) continue;
22283
+ if (!(0, import_node_fs51.statSync)(full).isDirectory()) continue;
22191
22284
  } catch {
22192
22285
  continue;
22193
22286
  }
@@ -22205,17 +22298,17 @@ function discoverSkills(worktreePath) {
22205
22298
  const home = (0, import_node_os15.homedir)();
22206
22299
  const collected = [];
22207
22300
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
22208
- scanSkillsDir((0, import_node_path49.join)(worktreePath, rel), "workspace", collected);
22301
+ scanSkillsDir((0, import_node_path50.join)(worktreePath, rel), "workspace", collected);
22209
22302
  }
22210
22303
  for (const abs of [
22211
- (0, import_node_path49.join)(home, ".claude/skills"),
22212
- (0, import_node_path49.join)(home, ".cursor/skills"),
22213
- (0, import_node_path49.join)(home, ".sideboard/skills"),
22214
- (0, import_node_path49.join)(home, ".brightsy/skills")
22304
+ (0, import_node_path50.join)(home, ".claude/skills"),
22305
+ (0, import_node_path50.join)(home, ".cursor/skills"),
22306
+ (0, import_node_path50.join)(home, ".sideboard/skills"),
22307
+ (0, import_node_path50.join)(home, ".brightsy/skills")
22215
22308
  ]) {
22216
22309
  scanSkillsDir(abs, "user", collected);
22217
22310
  }
22218
- scanClaudePluginSkills((0, import_node_path49.join)(home, ".claude/plugins"), collected);
22311
+ scanClaudePluginSkills((0, import_node_path50.join)(home, ".claude/plugins"), collected);
22219
22312
  collected.push(...bundledSkills());
22220
22313
  const rank = {
22221
22314
  workspace: 0,
@@ -22241,7 +22334,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22241
22334
  \u2026(truncated)` : body;
22242
22335
  }
22243
22336
  }
22244
- const raw = (0, import_node_fs50.readFileSync)(skillPath, "utf8");
22337
+ const raw = (0, import_node_fs51.readFileSync)(skillPath, "utf8");
22245
22338
  if (raw.startsWith("---")) {
22246
22339
  const end = raw.indexOf("\n---", 3);
22247
22340
  if (end >= 0) {
@@ -22255,13 +22348,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22255
22348
 
22256
22349
  \u2026(truncated)` : raw;
22257
22350
  }
22258
- var import_node_fs50, import_node_os15, import_node_path49, BUNDLED_SKILL_PREFIX;
22351
+ var import_node_fs51, import_node_os15, import_node_path50, BUNDLED_SKILL_PREFIX;
22259
22352
  var init_discover = __esm({
22260
22353
  "src/skills/discover.ts"() {
22261
22354
  "use strict";
22262
- import_node_fs50 = require("fs");
22355
+ import_node_fs51 = require("fs");
22263
22356
  import_node_os15 = require("os");
22264
- import_node_path49 = require("path");
22357
+ import_node_path50 = require("path");
22265
22358
  init_long_running();
22266
22359
  BUNDLED_SKILL_PREFIX = "bundled:";
22267
22360
  }
@@ -22416,7 +22509,7 @@ function compiledModuleDir() {
22416
22509
  try {
22417
22510
  const url = import_meta3.url;
22418
22511
  if (typeof url === "string" && url.length > 0) {
22419
- return (0, import_node_path50.dirname)((0, import_node_url3.fileURLToPath)(url));
22512
+ return (0, import_node_path51.dirname)((0, import_node_url3.fileURLToPath)(url));
22420
22513
  }
22421
22514
  } catch {
22422
22515
  }
@@ -22424,8 +22517,8 @@ function compiledModuleDir() {
22424
22517
  }
22425
22518
  function detachedJobScriptIn(dir) {
22426
22519
  for (const name of DETACHED_JOB_FILENAMES) {
22427
- const script = (0, import_node_path50.join)(dir, "scripts", name);
22428
- if ((0, import_node_fs51.existsSync)(script)) return script;
22520
+ const script = (0, import_node_path51.join)(dir, "scripts", name);
22521
+ if ((0, import_node_fs52.existsSync)(script)) return script;
22429
22522
  }
22430
22523
  return null;
22431
22524
  }
@@ -22442,7 +22535,7 @@ function resolveDetachedJobScript() {
22442
22535
  for (let i = 0; i < 8; i++) {
22443
22536
  const candidate = detachedJobScriptIn(dir);
22444
22537
  if (candidate) return candidate;
22445
- const parent = (0, import_node_path50.dirname)(dir);
22538
+ const parent = (0, import_node_path51.dirname)(dir);
22446
22539
  if (parent === dir) break;
22447
22540
  dir = parent;
22448
22541
  }
@@ -22453,12 +22546,12 @@ function formatDetachedJobInvoke(scriptPath) {
22453
22546
  if (resolved) return `node ${JSON.stringify(resolved)}`;
22454
22547
  return "node scripts/detached-job.cjs";
22455
22548
  }
22456
- var import_node_fs51, import_node_path50, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
22549
+ var import_node_fs52, import_node_path51, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
22457
22550
  var init_detached_job_path = __esm({
22458
22551
  "src/skills/detached-job-path.ts"() {
22459
22552
  "use strict";
22460
- import_node_fs51 = require("fs");
22461
- import_node_path50 = require("path");
22553
+ import_node_fs52 = require("fs");
22554
+ import_node_path51 = require("path");
22462
22555
  import_node_url3 = require("url");
22463
22556
  init_packaged_runtime();
22464
22557
  import_meta3 = {};
@@ -22640,9 +22733,9 @@ function formatPrGateDirective() {
22640
22733
  }
22641
22734
  function formatProcessGuideDirective(opts) {
22642
22735
  const worktree = opts?.worktreePath?.trim();
22643
- const hasGraphSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22644
- const hasReviewSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/review/SKILL.md"));
22645
- const hasInstallSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22736
+ const hasGraphSkill = !!worktree && (0, import_node_fs53.existsSync)((0, import_node_path52.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22737
+ const hasReviewSkill = !!worktree && (0, import_node_fs53.existsSync)((0, import_node_path52.join)(worktree, ".claude/skills/review/SKILL.md"));
22738
+ const hasInstallSkill = !!worktree && (0, import_node_fs53.existsSync)((0, import_node_path52.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22646
22739
  return [
22647
22740
  "Process guides (recurring work only):",
22648
22741
  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,
@@ -22661,12 +22754,13 @@ function formatLongRunningDirective(opts) {
22661
22754
  "- Loop Sideboard MCP `wait_for_job` (returns in ~45s). The desktop opens a `type=log` pane from wait/stop (and shell detached-job JSON) automatically \u2014 you may still `present_artifact` with `artifact_id=<id>` for a custom title. stillRunning \u2192 wait again. Shell fallback: the same helper with `wait <id>`.",
22662
22755
  "- 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.",
22663
22756
  "- 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.",
22664
- "State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
22757
+ "State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available).",
22758
+ "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."
22665
22759
  ].join("\n");
22666
22760
  }
22667
22761
  function formatLongRunningReminder(opts) {
22668
22762
  const invoke = formatDetachedJobInvoke(opts?.scriptPath);
22669
- 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.`;
22763
+ 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).`;
22670
22764
  }
22671
22765
  function formatArtifactDirective() {
22672
22766
  return [
@@ -22678,14 +22772,14 @@ function formatArtifactDirective() {
22678
22772
  ].join("\n");
22679
22773
  }
22680
22774
  function formatUiReminder() {
22681
- 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.";
22775
+ 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.";
22682
22776
  }
22683
- var import_node_fs52, import_node_path51, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22777
+ var import_node_fs53, import_node_path52, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22684
22778
  var init_instructions = __esm({
22685
22779
  "src/agents/instructions.ts"() {
22686
22780
  "use strict";
22687
- import_node_fs52 = require("fs");
22688
- import_node_path51 = require("path");
22781
+ import_node_fs53 = require("fs");
22782
+ import_node_path52 = require("path");
22689
22783
  init_git_auth_mode();
22690
22784
  init_branch_prefix();
22691
22785
  init_worktree_labels();
@@ -23071,40 +23165,40 @@ __export(plan_file_exports, {
23071
23165
  writePlanFile: () => writePlanFile
23072
23166
  });
23073
23167
  function ensureAttachmentsGitignore(worktreePath) {
23074
- const gitignoreAbs = (0, import_node_path52.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23075
- if ((0, import_node_fs53.existsSync)(gitignoreAbs)) return;
23076
- (0, import_node_fs53.mkdirSync)((0, import_node_path52.dirname)(gitignoreAbs), { recursive: true });
23077
- (0, import_node_fs53.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23168
+ const gitignoreAbs = (0, import_node_path53.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23169
+ if ((0, import_node_fs54.existsSync)(gitignoreAbs)) return;
23170
+ (0, import_node_fs54.mkdirSync)((0, import_node_path53.dirname)(gitignoreAbs), { recursive: true });
23171
+ (0, import_node_fs54.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23078
23172
  }
23079
23173
  function planFileAbs(worktreePath) {
23080
- return (0, import_node_path52.join)(worktreePath, PLAN_FILE_REL);
23174
+ return (0, import_node_path53.join)(worktreePath, PLAN_FILE_REL);
23081
23175
  }
23082
23176
  function readTextIfPresent2(abs) {
23083
- if (!(0, import_node_fs53.existsSync)(abs)) return null;
23177
+ if (!(0, import_node_fs54.existsSync)(abs)) return null;
23084
23178
  try {
23085
- const content = (0, import_node_fs53.readFileSync)(abs, "utf8");
23179
+ const content = (0, import_node_fs54.readFileSync)(abs, "utf8");
23086
23180
  return content.trim() ? content : null;
23087
23181
  } catch {
23088
23182
  return null;
23089
23183
  }
23090
23184
  }
23091
23185
  function readPlanFile(worktreePath) {
23092
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path52.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path52.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23186
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path53.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path53.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23093
23187
  }
23094
23188
  function writePlanFile(worktreePath, content) {
23095
23189
  ensureAttachmentsGitignore(worktreePath);
23096
23190
  const abs = planFileAbs(worktreePath);
23097
- (0, import_node_fs53.mkdirSync)((0, import_node_path52.dirname)(abs), { recursive: true });
23191
+ (0, import_node_fs54.mkdirSync)((0, import_node_path53.dirname)(abs), { recursive: true });
23098
23192
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23099
- (0, import_node_fs53.writeFileSync)(abs, body, "utf8");
23193
+ (0, import_node_fs54.writeFileSync)(abs, body, "utf8");
23100
23194
  return PLAN_FILE_REL;
23101
23195
  }
23102
- var import_node_fs53, import_node_path52;
23196
+ var import_node_fs54, import_node_path53;
23103
23197
  var init_plan_file = __esm({
23104
23198
  "src/plan/plan-file.ts"() {
23105
23199
  "use strict";
23106
- import_node_fs53 = require("fs");
23107
- import_node_path52 = require("path");
23200
+ import_node_fs54 = require("fs");
23201
+ import_node_path53 = require("path");
23108
23202
  init_workspace_scratch();
23109
23203
  init_plan_present();
23110
23204
  init_plan_present();
@@ -23166,9 +23260,9 @@ function recoverFinishedCursorRun(opts) {
23166
23260
  return best;
23167
23261
  }
23168
23262
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23169
- if (!(0, import_node_fs54.existsSync)(runsPath)) return null;
23263
+ if (!(0, import_node_fs55.existsSync)(runsPath)) return null;
23170
23264
  try {
23171
- const lines = (0, import_node_fs54.readFileSync)(runsPath, "utf8").split("\n");
23265
+ const lines = (0, import_node_fs55.readFileSync)(runsPath, "utf8").split("\n");
23172
23266
  let best = null;
23173
23267
  for (const line of lines) {
23174
23268
  const trimmed = line.trim();
@@ -23194,11 +23288,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23194
23288
  return null;
23195
23289
  }
23196
23290
  }
23197
- var import_node_fs54;
23291
+ var import_node_fs55;
23198
23292
  var init_cursor_recover = __esm({
23199
23293
  "src/agents/cursor-recover.ts"() {
23200
23294
  "use strict";
23201
- import_node_fs54 = require("fs");
23295
+ import_node_fs55 = require("fs");
23202
23296
  init_cursor_store();
23203
23297
  }
23204
23298
  });
@@ -23351,13 +23445,13 @@ async function startOrchestration(opts) {
23351
23445
  }
23352
23446
  return updated;
23353
23447
  }
23354
- var import_node_events, import_node_fs55, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
23448
+ var import_node_events, import_node_fs56, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
23355
23449
  var init_orchestrator = __esm({
23356
23450
  "src/orchestrator/orchestrator.ts"() {
23357
23451
  "use strict";
23358
23452
  import_node_events = require("events");
23359
23453
  init_outbound_watch();
23360
- import_node_fs55 = require("fs");
23454
+ import_node_fs56 = require("fs");
23361
23455
  init_error_detail();
23362
23456
  init_run();
23363
23457
  init_stale_lock();
@@ -23455,6 +23549,8 @@ var init_orchestrator = __esm({
23455
23549
  /** Auto-continues after a worktree turn ended while a detached job still runs. */
23456
23550
  jobContinueCount = /* @__PURE__ */ new Map();
23457
23551
  jobContinueNudged = /* @__PURE__ */ new Set();
23552
+ /** In-flight startDev per worktree run key — agent MCP + UI Start must not double-spawn. */
23553
+ startingDev = /* @__PURE__ */ new Map();
23458
23554
  maxConcurrent;
23459
23555
  runningCount = 0;
23460
23556
  constructor(opts) {
@@ -23523,7 +23619,7 @@ var init_orchestrator = __esm({
23523
23619
  this.lightReconcileAt.set(repoPath, Date.now());
23524
23620
  for (const thread of listThreads()) {
23525
23621
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
23526
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
23622
+ if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23527
23623
  setStatus(thread.id, "broken", "Worktree missing on disk");
23528
23624
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23529
23625
  }
@@ -23552,7 +23648,7 @@ var init_orchestrator = __esm({
23552
23648
  }
23553
23649
  continue;
23554
23650
  }
23555
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
23651
+ if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23556
23652
  setStatus(thread.id, "broken", "Worktree missing on disk");
23557
23653
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23558
23654
  continue;
@@ -24672,9 +24768,20 @@ var init_orchestrator = __esm({
24672
24768
  "No run script found for this worktree. Add [scripts.run.*] in the worktree\u2019s .sideboard/settings.toml or .conductor/settings.toml (or settings.local.toml on the main repo)."
24673
24769
  );
24674
24770
  }
24771
+ const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
24772
+ const inFlight = this.startingDev.get(runKey);
24773
+ if (inFlight) return inFlight;
24774
+ const start = this.startDevUnlocked(thread, resolvedName, scriptName, scripts, runKey);
24775
+ this.startingDev.set(runKey, start);
24776
+ try {
24777
+ return await start;
24778
+ } finally {
24779
+ this.startingDev.delete(runKey);
24780
+ }
24781
+ }
24782
+ async startDevUnlocked(thread, resolvedName, scriptName, scripts, runKey) {
24675
24783
  const siblings = threadsSharingWorktree(thread.worktreePath);
24676
24784
  const shared = mergeWorktreeActiveRuns(siblings);
24677
- const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
24678
24785
  const existing = this.processes.get(runKey) ?? siblings.map((t) => this.processes.get(`${t.id}:run:${resolvedName}`)).find(Boolean);
24679
24786
  const active = shared.activeRuns.find((r) => r.scriptName === resolvedName);
24680
24787
  if (existing && active) {
@@ -24686,6 +24793,14 @@ var init_orchestrator = __esm({
24686
24793
  return { port: shared.devPort, scriptName: resolvedName, ports: [shared.devPort] };
24687
24794
  }
24688
24795
  }
24796
+ if (active && !existing) {
24797
+ killListenersOnPorts(collectActiveRunPorts([active]));
24798
+ this.syncWorktreeRuns(
24799
+ thread.worktreePath,
24800
+ shared.activeRuns.filter((r) => r.scriptName !== resolvedName),
24801
+ shared.devPort === active.port ? null : shared.devPort
24802
+ );
24803
+ }
24689
24804
  const mode = getRunMode(thread.worktreePath, thread.repoPath);
24690
24805
  if (mode === "nonconcurrent") {
24691
24806
  const here = normalizeWorktreePath(thread.worktreePath);
@@ -24734,6 +24849,7 @@ var init_orchestrator = __esm({
24734
24849
  kill: handle.kill
24735
24850
  });
24736
24851
  }
24852
+ const latestShared = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
24737
24853
  const run2 = {
24738
24854
  scriptName: resolvedName,
24739
24855
  port: handle.port,
@@ -24741,13 +24857,13 @@ var init_orchestrator = __esm({
24741
24857
  startedAt
24742
24858
  };
24743
24859
  const nextRuns = [
24744
- ...shared.activeRuns.filter((r) => r.scriptName !== resolvedName),
24860
+ ...latestShared.activeRuns.filter((r) => r.scriptName !== resolvedName),
24745
24861
  run2
24746
24862
  ];
24747
24863
  this.syncWorktreeRuns(
24748
24864
  thread.worktreePath,
24749
24865
  nextRuns,
24750
- isDefault ? handle.port : shared.devPort
24866
+ isDefault ? handle.port : latestShared.devPort
24751
24867
  );
24752
24868
  this.emit({
24753
24869
  type: "dev_server_started",
@@ -25686,7 +25802,7 @@ var init_orchestrator = __esm({
25686
25802
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
25687
25803
  return restored2;
25688
25804
  }
25689
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
25805
+ if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
25690
25806
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
25691
25807
  throw new Error(
25692
25808
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -25901,6 +26017,9 @@ __export(index_exports, {
25901
26017
  ABLETIME_ORG_KEY_PREFIX: () => ABLETIME_ORG_KEY_PREFIX,
25902
26018
  ABLETIME_PAT_PREFIX: () => ABLETIME_PAT_PREFIX,
25903
26019
  ABLETIME_PM_TOOL_NAMES: () => ABLETIME_PM_TOOL_NAMES,
26020
+ AGENT_DONE_CUSTOM_SOUND_EXTENSIONS: () => AGENT_DONE_CUSTOM_SOUND_EXTENSIONS,
26021
+ AGENT_DONE_CUSTOM_SOUND_MAX_BYTES: () => AGENT_DONE_CUSTOM_SOUND_MAX_BYTES,
26022
+ AGENT_DONE_SOUNDS: () => AGENT_DONE_SOUNDS,
25904
26023
  AGENT_GIT_ACTIONS: () => AGENT_GIT_ACTIONS,
25905
26024
  AGENT_RUNNER_MAX_OLD_SPACE_MB: () => AGENT_RUNNER_MAX_OLD_SPACE_MB,
25906
26025
  ATTACHMENTS_DIR: () => ATTACHMENTS_DIR,
@@ -26023,6 +26142,9 @@ __export(index_exports, {
26023
26142
  addStackLayerFromThread: () => addStackLayerFromThread,
26024
26143
  addWorkspace: () => addWorkspace,
26025
26144
  adoptThread: () => adoptThread,
26145
+ agentDoneCustomSoundMime: () => agentDoneCustomSoundMime,
26146
+ agentDoneSound: () => agentDoneSound,
26147
+ agentDoneSoundsDir: () => agentDoneSoundsDir,
26026
26148
  agentGitPrompt: () => agentGitPrompt,
26027
26149
  alignQueueAttachments: () => alignQueueAttachments,
26028
26150
  allAdapters: () => allAdapters,
@@ -26101,6 +26223,7 @@ __export(index_exports, {
26101
26223
  claudeUserSettingsPath: () => claudeUserSettingsPath,
26102
26224
  cleanupArchivedHistory: () => cleanupArchivedHistory,
26103
26225
  cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
26226
+ clearAgentDoneCustomSoundFile: () => clearAgentDoneCustomSoundFile,
26104
26227
  clearBoardPins: () => clearBoardPins,
26105
26228
  clearHomeBoardCache: () => clearHomeBoardCache,
26106
26229
  clipAgentEventForPaint: () => clipAgentEventForPaint,
@@ -26203,6 +26326,7 @@ __export(index_exports, {
26203
26326
  fetchOriginForWorktree: () => fetchOriginForWorktree,
26204
26327
  fetchPrHead: () => fetchPrHead,
26205
26328
  finalizeParts: () => finalizeParts,
26329
+ findAgentDoneCustomSoundPath: () => findAgentDoneCustomSoundPath,
26206
26330
  findConventionSetup: () => findConventionSetup,
26207
26331
  findInvalidCacheControlTtlOrder: () => findInvalidCacheControlTtlOrder,
26208
26332
  findLastBrightsyContextSummary: () => findLastBrightsyContextSummary,
@@ -26337,6 +26461,7 @@ __export(index_exports, {
26337
26461
  historyMaxDays: () => historyMaxDays,
26338
26462
  hottestClaudeWindow: () => hottestClaudeWindow,
26339
26463
  httpFetch: () => httpFetch,
26464
+ importAgentDoneCustomSound: () => importAgentDoneCustomSound,
26340
26465
  importConductorWorkspace: () => importConductorWorkspace,
26341
26466
  importConductorWorkspaceAsync: () => importConductorWorkspaceAsync,
26342
26467
  initPrStack: () => initPrStack,
@@ -26352,6 +26477,7 @@ __export(index_exports, {
26352
26477
  isAbleTimeConnected: () => isAbleTimeConnected,
26353
26478
  isAbleTimeOAuthCancelled: () => isAbleTimeOAuthCancelled,
26354
26479
  isAbleTimeRejectedCredential: () => isAbleTimeRejectedCredential,
26480
+ isAgentDoneSound: () => isAgentDoneSound,
26355
26481
  isAskUserToolName: () => isAskUserToolName,
26356
26482
  isBrightsyConnected: () => isBrightsyConnected,
26357
26483
  isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
@@ -26543,6 +26669,7 @@ __export(index_exports, {
26543
26669
  primaryCheckoutFromLinkedWorktree: () => primaryCheckoutFromLinkedWorktree,
26544
26670
  promptMentionsBrightsy: () => promptMentionsBrightsy,
26545
26671
  pushBranch: () => pushBranch,
26672
+ readAgentDoneCustomSound: () => readAgentDoneCustomSound,
26546
26673
  readExistingReviewRequestFile: () => readExistingReviewRequestFile,
26547
26674
  readKeychainVaultKey: () => readKeychainVaultKey,
26548
26675
  readPlanFile: () => readPlanFile,
@@ -26569,6 +26696,8 @@ __export(index_exports, {
26569
26696
  requestOccupancy: () => requestOccupancy,
26570
26697
  requestReview: () => requestReview,
26571
26698
  requireAgent: () => requireAgent,
26699
+ reservePort: () => reservePort,
26700
+ reservePortRange: () => reservePortRange,
26572
26701
  resetGhStackDetectCache: () => resetGhStackDetectCache,
26573
26702
  resetGithubAgentTokenMemo: () => resetGithubAgentTokenMemo,
26574
26703
  resolveAbleTimeOAuthHost: () => resolveAbleTimeOAuthHost,
@@ -26772,6 +26901,95 @@ module.exports = __toCommonJS(index_exports);
26772
26901
  init_thinking_effort();
26773
26902
  init_paths();
26774
26903
  init_app_settings();
26904
+
26905
+ // src/store/agent-done-sound.ts
26906
+ var import_node_fs8 = require("fs");
26907
+ var import_node_path9 = require("path");
26908
+ init_paths();
26909
+ var AGENT_DONE_CUSTOM_SOUND_MAX_BYTES = 5 * 1024 * 1024;
26910
+ var AUDIO_EXT_MIME = {
26911
+ ".mp3": "audio/mpeg",
26912
+ ".wav": "audio/wav",
26913
+ ".ogg": "audio/ogg",
26914
+ ".m4a": "audio/mp4",
26915
+ ".aac": "audio/aac",
26916
+ ".caf": "audio/x-caf",
26917
+ ".flac": "audio/flac"
26918
+ };
26919
+ var AGENT_DONE_CUSTOM_SOUND_EXTENSIONS = Object.keys(AUDIO_EXT_MIME);
26920
+ function agentDoneSoundsDir() {
26921
+ const dir = (0, import_node_path9.join)(appDataDir(), "sounds");
26922
+ (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
26923
+ return dir;
26924
+ }
26925
+ function normalizeExt(ext) {
26926
+ const e = ext.trim().toLowerCase();
26927
+ return e.startsWith(".") ? e : `.${e}`;
26928
+ }
26929
+ function agentDoneCustomSoundMime(extOrPath) {
26930
+ const ext = normalizeExt((0, import_node_path9.extname)(extOrPath) || extOrPath);
26931
+ return AUDIO_EXT_MIME[ext] ?? null;
26932
+ }
26933
+ function findAgentDoneCustomSoundPath() {
26934
+ const dir = agentDoneSoundsDir();
26935
+ for (const name of (0, import_node_fs8.readdirSync)(dir)) {
26936
+ if (!name.startsWith("agent-done.")) continue;
26937
+ const full = (0, import_node_path9.join)(dir, name);
26938
+ if ((0, import_node_fs8.existsSync)(full) && agentDoneCustomSoundMime(name)) return full;
26939
+ }
26940
+ return null;
26941
+ }
26942
+ function clearAgentDoneCustomSoundFile() {
26943
+ const dir = agentDoneSoundsDir();
26944
+ for (const name of (0, import_node_fs8.readdirSync)(dir)) {
26945
+ if (!name.startsWith("agent-done.")) continue;
26946
+ try {
26947
+ (0, import_node_fs8.unlinkSync)((0, import_node_path9.join)(dir, name));
26948
+ } catch {
26949
+ }
26950
+ }
26951
+ }
26952
+ function importAgentDoneCustomSound(sourcePath) {
26953
+ const trimmed = sourcePath.trim();
26954
+ if (!trimmed || !(0, import_node_fs8.existsSync)(trimmed)) {
26955
+ throw new Error("Sound file not found");
26956
+ }
26957
+ const ext = normalizeExt((0, import_node_path9.extname)(trimmed));
26958
+ const mime = AUDIO_EXT_MIME[ext];
26959
+ if (!mime) {
26960
+ throw new Error(
26961
+ `Unsupported audio type (use ${AGENT_DONE_CUSTOM_SOUND_EXTENSIONS.join(", ")})`
26962
+ );
26963
+ }
26964
+ const data = (0, import_node_fs8.readFileSync)(trimmed);
26965
+ if (data.byteLength === 0) throw new Error("Sound file is empty");
26966
+ if (data.byteLength > AGENT_DONE_CUSTOM_SOUND_MAX_BYTES) {
26967
+ throw new Error("Sound file is too large (max 5 MB)");
26968
+ }
26969
+ clearAgentDoneCustomSoundFile();
26970
+ const dest = (0, import_node_path9.join)(agentDoneSoundsDir(), `agent-done${ext}`);
26971
+ (0, import_node_fs8.copyFileSync)(trimmed, dest);
26972
+ return {
26973
+ name: (0, import_node_path9.basename)(trimmed),
26974
+ path: dest,
26975
+ mime
26976
+ };
26977
+ }
26978
+ function readAgentDoneCustomSound(displayName2) {
26979
+ const path2 = findAgentDoneCustomSoundPath();
26980
+ if (!path2) return null;
26981
+ const mime = agentDoneCustomSoundMime(path2);
26982
+ if (!mime) return null;
26983
+ const data = (0, import_node_fs8.readFileSync)(path2);
26984
+ if (data.byteLength === 0) return null;
26985
+ return {
26986
+ name: displayName2?.trim() || (0, import_node_path9.basename)(path2),
26987
+ mime,
26988
+ dataBase64: data.toString("base64")
26989
+ };
26990
+ }
26991
+
26992
+ // src/index.ts
26775
26993
  init_caffeinate_hold();
26776
26994
  init_secure_file();
26777
26995
  init_thread_store();
@@ -29189,7 +29407,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
29189
29407
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29190
29408
  var import_zod9 = require("zod");
29191
29409
  var import_node_crypto15 = require("crypto");
29192
- var import_node_path55 = require("path");
29410
+ var import_node_path56 = require("path");
29193
29411
  init_orchestrator();
29194
29412
  init_worktree();
29195
29413
  init_global_workspace();
@@ -29206,6 +29424,23 @@ function mcpArchiveBlockedReason(thread) {
29206
29424
 
29207
29425
  // src/mcp/server.ts
29208
29426
  init_profile();
29427
+
29428
+ // src/mcp/run-script-ref.ts
29429
+ init_chat_tabs();
29430
+ function resolveRunScriptThreadRef(ref) {
29431
+ const explicit = ref?.trim();
29432
+ if (explicit) return explicit;
29433
+ const siblings = threadsSharingWorktree(process.cwd());
29434
+ const thread = siblings[0];
29435
+ if (!thread) {
29436
+ throw new Error(
29437
+ "No Sideboard thread for this cwd. Pass ref (thread id), or call from a worktree chat."
29438
+ );
29439
+ }
29440
+ return thread.id;
29441
+ }
29442
+
29443
+ // src/mcp/server.ts
29209
29444
  init_wait_for_turn();
29210
29445
  init_wait_for_job();
29211
29446
  init_message_parts();
@@ -30909,27 +31144,27 @@ init_gh_errors();
30909
31144
  init_git_auth_mode();
30910
31145
 
30911
31146
  // src/board/load-home-board.ts
30912
- var import_node_fs57 = require("fs");
30913
- var import_node_path54 = require("path");
31147
+ var import_node_fs58 = require("fs");
31148
+ var import_node_path55 = require("path");
30914
31149
  init_worktree();
30915
31150
  init_paths();
30916
31151
 
30917
31152
  // src/board/board-pins.ts
30918
31153
  var import_node_crypto14 = require("crypto");
30919
- var import_node_fs56 = require("fs");
30920
- var import_node_path53 = require("path");
31154
+ var import_node_fs57 = require("fs");
31155
+ var import_node_path54 = require("path");
30921
31156
  init_paths();
30922
31157
  init_home_board();
30923
31158
  var FILE = "home-board-pins.json";
30924
31159
  var VERSION = 1;
30925
31160
  function pinsFile() {
30926
- return (0, import_node_path53.join)(appDataDir(), FILE);
31161
+ return (0, import_node_path54.join)(appDataDir(), FILE);
30927
31162
  }
30928
31163
  function readDisk() {
30929
31164
  const path2 = pinsFile();
30930
- if (!(0, import_node_fs56.existsSync)(path2)) return [];
31165
+ if (!(0, import_node_fs57.existsSync)(path2)) return [];
30931
31166
  try {
30932
- const raw = JSON.parse((0, import_node_fs56.readFileSync)(path2, "utf8"));
31167
+ const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
30933
31168
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
30934
31169
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
30935
31170
  } catch {
@@ -30937,8 +31172,8 @@ function readDisk() {
30937
31172
  }
30938
31173
  }
30939
31174
  function writeDisk(items) {
30940
- (0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
30941
- (0, import_node_fs56.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
31175
+ (0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
31176
+ (0, import_node_fs57.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
30942
31177
  }
30943
31178
  function listBoardPins() {
30944
31179
  return readDisk();
@@ -30990,7 +31225,7 @@ function replaceBoardPins(items) {
30990
31225
  }
30991
31226
  function clearBoardPins() {
30992
31227
  try {
30993
- (0, import_node_fs56.unlinkSync)(pinsFile());
31228
+ (0, import_node_fs57.unlinkSync)(pinsFile());
30994
31229
  } catch {
30995
31230
  }
30996
31231
  }
@@ -31007,7 +31242,7 @@ function homeBoardWorkspaceKey(workspaces) {
31007
31242
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
31008
31243
  }
31009
31244
  function cacheFile() {
31010
- return (0, import_node_path54.join)(appDataDir(), "home-board-cache.json");
31245
+ return (0, import_node_path55.join)(appDataDir(), "home-board-cache.json");
31011
31246
  }
31012
31247
  function emptyInputs() {
31013
31248
  return {
@@ -31033,9 +31268,9 @@ function shouldCacheHomeBoardInputs(inputs) {
31033
31268
  }
31034
31269
  function readDiskCache() {
31035
31270
  const path2 = cacheFile();
31036
- if (!(0, import_node_fs57.existsSync)(path2)) return null;
31271
+ if (!(0, import_node_fs58.existsSync)(path2)) return null;
31037
31272
  try {
31038
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
31273
+ const raw = JSON.parse((0, import_node_fs58.readFileSync)(path2, "utf8"));
31039
31274
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
31040
31275
  return null;
31041
31276
  }
@@ -31049,14 +31284,14 @@ function readDiskCache() {
31049
31284
  }
31050
31285
  function writeDiskCache(entry) {
31051
31286
  try {
31052
- (0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
31053
- (0, import_node_fs57.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31287
+ (0, import_node_fs58.mkdirSync)(appDataDir(), { recursive: true });
31288
+ (0, import_node_fs58.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31054
31289
  } catch {
31055
31290
  }
31056
31291
  }
31057
31292
  function deleteDiskCache() {
31058
31293
  try {
31059
- (0, import_node_fs57.unlinkSync)(cacheFile());
31294
+ (0, import_node_fs58.unlinkSync)(cacheFile());
31060
31295
  } catch {
31061
31296
  }
31062
31297
  }
@@ -31406,7 +31641,7 @@ async function startMcpServer() {
31406
31641
  async () => {
31407
31642
  const threads = orch.getThreads(true);
31408
31643
  const lines = threads.map((t) => {
31409
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path55.basename)(t.repoPath) || t.repoPath;
31644
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path56.basename)(t.repoPath) || t.repoPath;
31410
31645
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
31411
31646
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
31412
31647
  const preview = lastMessagePreview(t.messages, 80);
@@ -31654,13 +31889,73 @@ async function startMcpServer() {
31654
31889
  "Stop a detached job you started with detached-job.cjs when it is hanging, producing no useful output, buffering forever, or doing the wrong thing (wrong project, infinite watch, huge dump). Do not stop a pack/test/deploy that is clearly making progress. The type=log pane updates to status=failed with the last delta. Then decide the next step.",
31655
31890
  {
31656
31891
  id: import_zod9.z.string().describe("Detached job id (same kebab-case id passed to detached-job.cjs start)"),
31657
- reason: import_zod9.z.string().optional().describe("Why you are stopping (hanging, no progress, wrong output, already have the error)")
31892
+ reason: import_zod9.z.string().optional().describe("Why you are stopping (hanging, no progress, wrong output, already have the answer)")
31658
31893
  },
31659
31894
  async ({ id, reason }) => {
31660
31895
  const result = await stopDetachedJob(process.cwd(), id, { reason });
31661
31896
  return mcpJson(result);
31662
31897
  }
31663
31898
  );
31899
+ server.tool(
31900
+ "list_run_scripts",
31901
+ "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).",
31902
+ {
31903
+ ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd).")
31904
+ },
31905
+ async ({ ref }) => {
31906
+ try {
31907
+ const threadRef = resolveRunScriptThreadRef(ref);
31908
+ const scripts = orch.listThreadRunScripts(threadRef);
31909
+ const active = orch.getActiveRuns(threadRef);
31910
+ return mcpJson({ scripts, active, ref: threadRef });
31911
+ } catch (err) {
31912
+ const message = err instanceof Error ? err.message : String(err);
31913
+ return { content: [{ type: "text", text: message }], isError: true };
31914
+ }
31915
+ }
31916
+ );
31917
+ server.tool(
31918
+ "run_dev_script",
31919
+ "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.",
31920
+ {
31921
+ ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
31922
+ name: import_zod9.z.string().optional().describe("Script name from list_run_scripts (default script if omitted).")
31923
+ },
31924
+ async ({ ref, name }) => {
31925
+ try {
31926
+ const threadRef = resolveRunScriptThreadRef(ref);
31927
+ const result = await orch.startDev(threadRef, name);
31928
+ return mcpJson({
31929
+ port: result.port,
31930
+ scriptName: result.scriptName,
31931
+ ports: result.ports,
31932
+ url: `http://localhost:${result.port}`,
31933
+ ref: threadRef
31934
+ });
31935
+ } catch (err) {
31936
+ const message = err instanceof Error ? err.message : String(err);
31937
+ return { content: [{ type: "text", text: message }], isError: true };
31938
+ }
31939
+ }
31940
+ );
31941
+ server.tool(
31942
+ "stop_dev_script",
31943
+ "Stop a run script started with run_dev_script or the desktop Dev button (same as UI Stop). Omit name to stop all scripts on this worktree. Worktree turns may omit ref (uses cwd).",
31944
+ {
31945
+ ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
31946
+ name: import_zod9.z.string().optional().describe("Script name to stop; omit to stop all active scripts.")
31947
+ },
31948
+ async ({ ref, name }) => {
31949
+ try {
31950
+ const threadRef = resolveRunScriptThreadRef(ref);
31951
+ orch.stopDev(threadRef, name);
31952
+ return mcpJson({ ok: true, ref: threadRef, stopped: name ?? "all" });
31953
+ } catch (err) {
31954
+ const message = err instanceof Error ? err.message : String(err);
31955
+ return { content: [{ type: "text", text: message }], isError: true };
31956
+ }
31957
+ }
31958
+ );
31664
31959
  if (!worktreeProfile) {
31665
31960
  registerSlackTools(server);
31666
31961
  registerConnectedIssueVendorTools(server);
@@ -32139,45 +32434,6 @@ async function startMcpServer() {
32139
32434
  }
32140
32435
  }
32141
32436
  );
32142
- server.tool(
32143
- "run_dev_script",
32144
- "Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
32145
- {
32146
- ref: import_zod9.z.string(),
32147
- name: import_zod9.z.string().optional()
32148
- },
32149
- async ({ ref, name }) => {
32150
- const result = await orch.startDev(ref, name);
32151
- return mcpJson({
32152
- port: result.port,
32153
- scriptName: result.scriptName,
32154
- ports: result.ports,
32155
- url: `http://localhost:${result.port}`
32156
- });
32157
- }
32158
- );
32159
- server.tool(
32160
- "list_run_scripts",
32161
- "List named run scripts available for a thread",
32162
- { ref: import_zod9.z.string() },
32163
- async ({ ref }) => {
32164
- const scripts = orch.listThreadRunScripts(ref);
32165
- const active = orch.getActiveRuns(ref);
32166
- return mcpJson({ scripts, active });
32167
- }
32168
- );
32169
- server.tool(
32170
- "stop_dev_script",
32171
- "Stop a running script for a thread (all scripts if name omitted)",
32172
- {
32173
- ref: import_zod9.z.string(),
32174
- name: import_zod9.z.string().optional()
32175
- },
32176
- async ({ ref, name }) => {
32177
- orch.stopDev(ref, name);
32178
- return { content: [{ type: "text", text: "ok" }] };
32179
- }
32180
- );
32181
32437
  server.tool(
32182
32438
  "run_setup",
32183
32439
  "Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
@@ -34386,9 +34642,9 @@ var import_node_http4 = require("http");
34386
34642
  var import_ws3 = require("ws");
34387
34643
 
34388
34644
  // src/slack/relay-static.ts
34389
- var import_node_fs58 = require("fs");
34645
+ var import_node_fs59 = require("fs");
34390
34646
  var import_promises = require("fs/promises");
34391
- var import_node_path56 = __toESM(require("path"), 1);
34647
+ var import_node_path57 = __toESM(require("path"), 1);
34392
34648
  var TYPES = {
34393
34649
  ".css": "text/css; charset=utf-8",
34394
34650
  ".html": "text/html; charset=utf-8",
@@ -34419,9 +34675,9 @@ function resolveStaticPath(root, requestUrl) {
34419
34675
  return null;
34420
34676
  }
34421
34677
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
34422
- const rootResolved = import_node_path56.default.resolve(root);
34423
- const candidate = import_node_path56.default.resolve(rootResolved, `.${pathname}`);
34424
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path56.default.sep)) {
34678
+ const rootResolved = import_node_path57.default.resolve(root);
34679
+ const candidate = import_node_path57.default.resolve(rootResolved, `.${pathname}`);
34680
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path57.default.sep)) {
34425
34681
  return null;
34426
34682
  }
34427
34683
  return candidate;
@@ -34435,7 +34691,7 @@ async function fileSize(file) {
34435
34691
  }
34436
34692
  }
34437
34693
  function sendFile(req, res, file, size) {
34438
- const ext = import_node_path56.default.extname(file).toLowerCase();
34694
+ const ext = import_node_path57.default.extname(file).toLowerCase();
34439
34695
  res.writeHead(200, {
34440
34696
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
34441
34697
  "Content-Length": size,
@@ -34445,7 +34701,7 @@ function sendFile(req, res, file, size) {
34445
34701
  res.end();
34446
34702
  return true;
34447
34703
  }
34448
- (0, import_node_fs58.createReadStream)(file).pipe(res);
34704
+ (0, import_node_fs59.createReadStream)(file).pipe(res);
34449
34705
  return true;
34450
34706
  }
34451
34707
  async function tryServeStatic(req, res, root) {
@@ -34454,7 +34710,7 @@ async function tryServeStatic(req, res, root) {
34454
34710
  if (!candidate) return false;
34455
34711
  const direct = await fileSize(candidate);
34456
34712
  if (direct != null) return sendFile(req, res, candidate, direct);
34457
- const asIndex = import_node_path56.default.join(candidate, "index.html");
34713
+ const asIndex = import_node_path57.default.join(candidate, "index.html");
34458
34714
  const indexSize = await fileSize(asIndex);
34459
34715
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
34460
34716
  return false;
@@ -34712,6 +34968,9 @@ init_outbound_watch();
34712
34968
  ABLETIME_ORG_KEY_PREFIX,
34713
34969
  ABLETIME_PAT_PREFIX,
34714
34970
  ABLETIME_PM_TOOL_NAMES,
34971
+ AGENT_DONE_CUSTOM_SOUND_EXTENSIONS,
34972
+ AGENT_DONE_CUSTOM_SOUND_MAX_BYTES,
34973
+ AGENT_DONE_SOUNDS,
34715
34974
  AGENT_GIT_ACTIONS,
34716
34975
  AGENT_RUNNER_MAX_OLD_SPACE_MB,
34717
34976
  ATTACHMENTS_DIR,
@@ -34834,6 +35093,9 @@ init_outbound_watch();
34834
35093
  addStackLayerFromThread,
34835
35094
  addWorkspace,
34836
35095
  adoptThread,
35096
+ agentDoneCustomSoundMime,
35097
+ agentDoneSound,
35098
+ agentDoneSoundsDir,
34837
35099
  agentGitPrompt,
34838
35100
  alignQueueAttachments,
34839
35101
  allAdapters,
@@ -34912,6 +35174,7 @@ init_outbound_watch();
34912
35174
  claudeUserSettingsPath,
34913
35175
  cleanupArchivedHistory,
34914
35176
  cleanupOrphanWorktrees,
35177
+ clearAgentDoneCustomSoundFile,
34915
35178
  clearBoardPins,
34916
35179
  clearHomeBoardCache,
34917
35180
  clipAgentEventForPaint,
@@ -35014,6 +35277,7 @@ init_outbound_watch();
35014
35277
  fetchOriginForWorktree,
35015
35278
  fetchPrHead,
35016
35279
  finalizeParts,
35280
+ findAgentDoneCustomSoundPath,
35017
35281
  findConventionSetup,
35018
35282
  findInvalidCacheControlTtlOrder,
35019
35283
  findLastBrightsyContextSummary,
@@ -35148,6 +35412,7 @@ init_outbound_watch();
35148
35412
  historyMaxDays,
35149
35413
  hottestClaudeWindow,
35150
35414
  httpFetch,
35415
+ importAgentDoneCustomSound,
35151
35416
  importConductorWorkspace,
35152
35417
  importConductorWorkspaceAsync,
35153
35418
  initPrStack,
@@ -35163,6 +35428,7 @@ init_outbound_watch();
35163
35428
  isAbleTimeConnected,
35164
35429
  isAbleTimeOAuthCancelled,
35165
35430
  isAbleTimeRejectedCredential,
35431
+ isAgentDoneSound,
35166
35432
  isAskUserToolName,
35167
35433
  isBrightsyConnected,
35168
35434
  isBrightsyNdjsonLine,
@@ -35354,6 +35620,7 @@ init_outbound_watch();
35354
35620
  primaryCheckoutFromLinkedWorktree,
35355
35621
  promptMentionsBrightsy,
35356
35622
  pushBranch,
35623
+ readAgentDoneCustomSound,
35357
35624
  readExistingReviewRequestFile,
35358
35625
  readKeychainVaultKey,
35359
35626
  readPlanFile,
@@ -35380,6 +35647,8 @@ init_outbound_watch();
35380
35647
  requestOccupancy,
35381
35648
  requestReview,
35382
35649
  requireAgent,
35650
+ reservePort,
35651
+ reservePortRange,
35383
35652
  resetGhStackDetectCache,
35384
35653
  resetGithubAgentTokenMemo,
35385
35654
  resolveAbleTimeOAuthHost,