@sideboard-ai/core 0.1.228 → 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-WHYJL7CP.js → chunk-6HKGCUDN.js} +24 -22
  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-72XUASTH.js → chunk-UHT6OS7V.js} +24 -23
  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 +820 -619
  33. package/dist/index.d.cts +68 -2
  34. package/dist/index.d.ts +68 -2
  35. package/dist/index.js +202 -67
  36. package/dist/mcp/run-stdio.cjs +131 -44
  37. package/dist/mcp/run-stdio.js +86 -50
  38. package/dist/{orchestrator-6XEWQWSM.js → orchestrator-GKAHLGXT.js} +5 -5
  39. package/dist/{orchestrator-QUJORSTA.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;
@@ -17519,14 +17570,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
17519
17570
  throw err;
17520
17571
  }
17521
17572
  }
17522
- 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;
17523
17574
  var init_conductor = __esm({
17524
17575
  "src/hook/conductor.ts"() {
17525
17576
  "use strict";
17526
- import_node_fs41 = require("fs");
17577
+ import_node_fs42 = require("fs");
17527
17578
  import_node_child_process5 = require("child_process");
17528
17579
  import_node_net = require("net");
17529
- import_node_path43 = require("path");
17580
+ import_node_path44 = require("path");
17530
17581
  import_execa4 = require("execa");
17531
17582
  import_node_readline3 = require("readline");
17532
17583
  init_settings();
@@ -17554,9 +17605,9 @@ async function findOrphanWorktrees(repoPaths) {
17554
17605
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17555
17606
  );
17556
17607
  const homeRoot = sideboardWorkspacesDir();
17557
- if ((0, import_node_fs42.existsSync)(homeRoot)) {
17608
+ if ((0, import_node_fs43.existsSync)(homeRoot)) {
17558
17609
  try {
17559
- 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 })) {
17560
17611
  if (!entry.isDirectory()) continue;
17561
17612
  void entry;
17562
17613
  }
@@ -17566,7 +17617,7 @@ async function findOrphanWorktrees(repoPaths) {
17566
17617
  const orphans = [];
17567
17618
  const seen = /* @__PURE__ */ new Set();
17568
17619
  for (const repoPath of repos) {
17569
- if (!repoPath || !(0, import_node_fs42.existsSync)(repoPath)) continue;
17620
+ if (!repoPath || !(0, import_node_fs43.existsSync)(repoPath)) continue;
17570
17621
  try {
17571
17622
  const wts = await listWorktrees(repoPath);
17572
17623
  for (const wt of wts) {
@@ -17577,7 +17628,7 @@ async function findOrphanWorktrees(repoPaths) {
17577
17628
  seen.add(path2);
17578
17629
  let mtimeMs = 0;
17579
17630
  try {
17580
- mtimeMs = (0, import_node_fs42.statSync)(path2).mtimeMs;
17631
+ mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17581
17632
  } catch {
17582
17633
  mtimeMs = 0;
17583
17634
  }
@@ -17587,16 +17638,16 @@ async function findOrphanWorktrees(repoPaths) {
17587
17638
  }
17588
17639
  try {
17589
17640
  const root = worktreesRoot(repoPath);
17590
- if ((0, import_node_fs42.existsSync)(root)) {
17591
- 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 })) {
17592
17643
  if (!entry.isDirectory()) continue;
17593
- const path2 = (0, import_node_path44.join)(root, entry.name).replace(/\/$/, "");
17644
+ const path2 = (0, import_node_path45.join)(root, entry.name).replace(/\/$/, "");
17594
17645
  if (known.has(path2) || seen.has(path2)) continue;
17595
- 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;
17596
17647
  seen.add(path2);
17597
17648
  let mtimeMs = 0;
17598
17649
  try {
17599
- mtimeMs = (0, import_node_fs42.statSync)(path2).mtimeMs;
17650
+ mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17600
17651
  } catch {
17601
17652
  mtimeMs = Date.now();
17602
17653
  }
@@ -17657,12 +17708,12 @@ function worktreeCleanupSettings() {
17657
17708
  autoCleanupOrphans: a.autoCleanupOrphans
17658
17709
  };
17659
17710
  }
17660
- var import_node_fs42, import_node_path44;
17711
+ var import_node_fs43, import_node_path45;
17661
17712
  var init_orphan_cleanup = __esm({
17662
17713
  "src/git/orphan-cleanup.ts"() {
17663
17714
  "use strict";
17664
- import_node_fs42 = require("fs");
17665
- import_node_path44 = require("path");
17715
+ import_node_fs43 = require("fs");
17716
+ import_node_path45 = require("path");
17666
17717
  init_worktree();
17667
17718
  init_thread_store();
17668
17719
  init_paths();
@@ -17837,12 +17888,12 @@ async function cloneRepoIntoSideboard(opts) {
17837
17888
  if (!url) throw new Error("Clone URL is required");
17838
17889
  let name = opts.name?.trim();
17839
17890
  if (!name) {
17840
- const leaf = (0, import_node_path45.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17891
+ const leaf = (0, import_node_path46.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17841
17892
  name = leaf || "repo";
17842
17893
  }
17843
17894
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
17844
- const dest = (0, import_node_path45.join)(sideboardReposDir(), name);
17845
- 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)) {
17846
17897
  const repoPath2 = await resolveRepoRoot(dest);
17847
17898
  const workspace2 = await ensureWorkspace(repoPath2);
17848
17899
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -17857,12 +17908,12 @@ async function cloneRepoIntoSideboard(opts) {
17857
17908
  const workspace = await ensureWorkspace(repoPath);
17858
17909
  return { repoPath, workspace };
17859
17910
  }
17860
- var import_node_fs43, import_node_path45, import_execa6;
17911
+ var import_node_fs44, import_node_path46, import_execa6;
17861
17912
  var init_clone_repo = __esm({
17862
17913
  "src/git/clone-repo.ts"() {
17863
17914
  "use strict";
17864
- import_node_fs43 = require("fs");
17865
- import_node_path45 = require("path");
17915
+ import_node_fs44 = require("fs");
17916
+ import_node_path46 = require("path");
17866
17917
  import_execa6 = require("execa");
17867
17918
  init_paths();
17868
17919
  init_workspaces();
@@ -17983,24 +18034,24 @@ function jobTreeAlive(pid) {
17983
18034
  return jobAlive(pid) || processGroupAlive(pid);
17984
18035
  }
17985
18036
  function readIntFile(file) {
17986
- if (!(0, import_node_fs44.existsSync)(file)) return null;
17987
- 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);
17988
18039
  return Number.isInteger(n) ? n : null;
17989
18040
  }
17990
18041
  function jobDir(root, id, legacy = false) {
17991
- 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);
17992
18043
  }
17993
18044
  function resolveJobDir(root, id) {
17994
18045
  const modern = jobDir(root, id, false);
17995
- if ((0, import_node_fs44.existsSync)(modern)) return modern;
18046
+ if ((0, import_node_fs45.existsSync)(modern)) return modern;
17996
18047
  const legacy = jobDir(root, id, true);
17997
- if ((0, import_node_fs44.existsSync)(legacy)) return legacy;
18048
+ if ((0, import_node_fs45.existsSync)(legacy)) return legacy;
17998
18049
  return modern;
17999
18050
  }
18000
18051
  function listJobIdsIn(root, rel) {
18001
- const dir = (0, import_node_path46.join)(root, rel);
18002
- if (!(0, import_node_fs44.existsSync)(dir)) return [];
18003
- 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);
18004
18055
  }
18005
18056
  function listRunningDetachedJobs(worktreePath) {
18006
18057
  const root = worktreePath.trim();
@@ -18012,7 +18063,7 @@ function listRunningDetachedJobs(worktreePath) {
18012
18063
  const running = [];
18013
18064
  for (const id of ids) {
18014
18065
  const dir = resolveJobDir(root, id);
18015
- const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
18066
+ const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18016
18067
  if (jobTreeAlive(pid)) running.push(id);
18017
18068
  }
18018
18069
  return running.sort();
@@ -18095,8 +18146,8 @@ function planJobContinue(opts) {
18095
18146
  return { action: "none" };
18096
18147
  }
18097
18148
  function tailProgress(logFile, maxLines = 12) {
18098
- if (!(0, import_node_fs44.existsSync)(logFile)) return "(no log yet)";
18099
- 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");
18100
18151
  return lines.slice(-maxLines).join("\n");
18101
18152
  }
18102
18153
  function lastProgressLine(progress) {
@@ -18104,8 +18155,8 @@ function lastProgressLine(progress) {
18104
18155
  return last ? last.slice(0, 72) : void 0;
18105
18156
  }
18106
18157
  function readLogLines(file) {
18107
- if (!(0, import_node_fs44.existsSync)(file)) return [];
18108
- 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");
18109
18160
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
18110
18161
  return lines;
18111
18162
  }
@@ -18116,15 +18167,15 @@ function takeDelta(logFile, cursorFile) {
18116
18167
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
18117
18168
  }
18118
18169
  function snapshotJob(dir) {
18119
- const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
18170
+ const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18120
18171
  const running = jobTreeAlive(pid);
18121
18172
  return {
18122
18173
  pid,
18123
18174
  running,
18124
- exitCode: readIntFile((0, import_node_path46.join)(dir, "exit")),
18125
- log: (0, import_node_path46.join)(dir, "log"),
18126
- cursor: (0, import_node_path46.join)(dir, "present.cursor"),
18127
- 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"))
18128
18179
  };
18129
18180
  }
18130
18181
  function toResult(id, snap, extra) {
@@ -18133,8 +18184,8 @@ function toResult(id, snap, extra) {
18133
18184
  const stillRunning = snap.running && !ok;
18134
18185
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
18135
18186
  try {
18136
- (0, import_node_fs44.mkdirSync)((0, import_node_path46.dirname)(snap.cursor), { recursive: true });
18137
- (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}
18138
18189
  `);
18139
18190
  } catch {
18140
18191
  }
@@ -18163,7 +18214,7 @@ async function waitForDetachedJob(cwd, id, opts) {
18163
18214
  const dir = resolveJobDir(root, jobId);
18164
18215
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
18165
18216
  const sleep2 = opts?.sleep ?? sleepMs;
18166
- if (!(0, import_node_fs44.existsSync)(dir)) {
18217
+ if (!(0, import_node_fs45.existsSync)(dir)) {
18167
18218
  return {
18168
18219
  stillRunning: false,
18169
18220
  ok: false,
@@ -18209,10 +18260,10 @@ function killProcessTree(pid, signal) {
18209
18260
  }
18210
18261
  function appendJobLog(logFile, line) {
18211
18262
  try {
18212
- (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 });
18213
18264
  const body = line.endsWith("\n") ? line : `${line}
18214
18265
  `;
18215
- (0, import_node_fs44.appendFileSync)(logFile, body);
18266
+ (0, import_node_fs45.appendFileSync)(logFile, body);
18216
18267
  } catch {
18217
18268
  }
18218
18269
  }
@@ -18222,7 +18273,7 @@ async function stopDetachedJob(cwd, id, opts) {
18222
18273
  const dir = resolveJobDir(root, jobId);
18223
18274
  const sleep2 = opts?.sleep ?? sleepMs;
18224
18275
  const why = opts?.reason?.trim() ?? "";
18225
- if (!(0, import_node_fs44.existsSync)(dir)) {
18276
+ if (!(0, import_node_fs45.existsSync)(dir)) {
18226
18277
  return {
18227
18278
  stillRunning: false,
18228
18279
  ok: false,
@@ -18258,10 +18309,10 @@ async function stopDetachedJob(cwd, id, opts) {
18258
18309
  killProcessTree(targetPid, "SIGKILL");
18259
18310
  await sleep2(100);
18260
18311
  }
18261
- const exitFile = (0, import_node_path46.join)(dir, "exit");
18262
- 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)) {
18263
18314
  try {
18264
- (0, import_node_fs44.writeFileSync)(exitFile, "1\n");
18315
+ (0, import_node_fs45.writeFileSync)(exitFile, "1\n");
18265
18316
  } catch {
18266
18317
  }
18267
18318
  }
@@ -18281,12 +18332,12 @@ async function stopDetachedJob(cwd, id, opts) {
18281
18332
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
18282
18333
  };
18283
18334
  }
18284
- 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;
18285
18336
  var init_wait_for_job = __esm({
18286
18337
  "src/mcp/wait-for-job.ts"() {
18287
18338
  "use strict";
18288
- import_node_fs44 = require("fs");
18289
- import_node_path46 = require("path");
18339
+ import_node_fs45 = require("fs");
18340
+ import_node_path47 = require("path");
18290
18341
  init_workspace_scratch();
18291
18342
  init_wait_for_turn();
18292
18343
  MAX_JOB_CONTINUES = 8;
@@ -19831,7 +19882,7 @@ function reuseLiveThread(input, repoPath, match) {
19831
19882
  }
19832
19883
  async function createThread(input, _onSetupLine) {
19833
19884
  const repoPath = await resolveRepoRoot(input.repoPath);
19834
- if (!(0, import_node_fs45.existsSync)(repoPath)) {
19885
+ if (!(0, import_node_fs46.existsSync)(repoPath)) {
19835
19886
  throw new Error(`Repo not found: ${repoPath}`);
19836
19887
  }
19837
19888
  const reused = reuseLiveThread(input, repoPath, {
@@ -20016,11 +20067,11 @@ async function listLinearIssues(agent, repoPath) {
20016
20067
  }
20017
20068
  return adapter.listLinearIssues(repoPath);
20018
20069
  }
20019
- var import_node_fs45;
20070
+ var import_node_fs46;
20020
20071
  var init_create = __esm({
20021
20072
  "src/threads/create.ts"() {
20022
20073
  "use strict";
20023
- import_node_fs45 = require("fs");
20074
+ import_node_fs46 = require("fs");
20024
20075
  init_detect();
20025
20076
  init_worktree();
20026
20077
  init_home_board();
@@ -20172,20 +20223,20 @@ function writeTurnLive(threadId, progress) {
20172
20223
  const path2 = threadLivePath(threadId);
20173
20224
  const tmp = `${path2}.${process.pid}.tmp`;
20174
20225
  try {
20175
- (0, import_node_fs46.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20176
- (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);
20177
20228
  } catch {
20178
20229
  try {
20179
- (0, import_node_fs46.unlinkSync)(tmp);
20230
+ (0, import_node_fs47.unlinkSync)(tmp);
20180
20231
  } catch {
20181
20232
  }
20182
20233
  }
20183
20234
  }
20184
20235
  function readTurnLive(threadId) {
20185
20236
  const path2 = threadLivePath(threadId);
20186
- if (!(0, import_node_fs46.existsSync)(path2)) return null;
20237
+ if (!(0, import_node_fs47.existsSync)(path2)) return null;
20187
20238
  try {
20188
- const raw = JSON.parse((0, import_node_fs46.readFileSync)(path2, "utf8"));
20239
+ const raw = JSON.parse((0, import_node_fs47.readFileSync)(path2, "utf8"));
20189
20240
  if (!raw || typeof raw.summary !== "string") return null;
20190
20241
  return raw;
20191
20242
  } catch {
@@ -20197,17 +20248,17 @@ function clearTurnLive(threadId) {
20197
20248
  if (buf?.timer) clearTimeout(buf.timer);
20198
20249
  buffers.delete(threadId);
20199
20250
  const path2 = threadLivePath(threadId);
20200
- if (!(0, import_node_fs46.existsSync)(path2)) return;
20251
+ if (!(0, import_node_fs47.existsSync)(path2)) return;
20201
20252
  try {
20202
- (0, import_node_fs46.unlinkSync)(path2);
20253
+ (0, import_node_fs47.unlinkSync)(path2);
20203
20254
  } catch {
20204
20255
  }
20205
20256
  }
20206
- var import_node_fs46, buffers, FLUSH_MS, MAX_PARTS;
20257
+ var import_node_fs47, buffers, FLUSH_MS, MAX_PARTS;
20207
20258
  var init_turn_live = __esm({
20208
20259
  "src/store/turn-live.ts"() {
20209
20260
  "use strict";
20210
- import_node_fs46 = require("fs");
20261
+ import_node_fs47 = require("fs");
20211
20262
  init_message_parts();
20212
20263
  init_paths();
20213
20264
  buffers = /* @__PURE__ */ new Map();
@@ -20451,7 +20502,7 @@ var init_quota_failover = __esm({
20451
20502
  // src/threads/adopt.ts
20452
20503
  function thisModuleFile() {
20453
20504
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
20454
- 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");
20455
20506
  }
20456
20507
  function openReadonlySqlite(file) {
20457
20508
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -20469,21 +20520,21 @@ function mapAgentType(raw) {
20469
20520
  return null;
20470
20521
  }
20471
20522
  function resolveConductorCursorAgentId(workspacePath) {
20472
- 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;
20473
20524
  const normalized = workspacePath.replace(/\/$/, "");
20474
20525
  let best = null;
20475
20526
  let hashes;
20476
20527
  try {
20477
- hashes = (0, import_node_fs47.readdirSync)(CURSOR_SDK_STORE);
20528
+ hashes = (0, import_node_fs48.readdirSync)(CURSOR_SDK_STORE);
20478
20529
  } catch {
20479
20530
  return null;
20480
20531
  }
20481
20532
  for (const hash of hashes) {
20482
- const agentsFile = (0, import_node_path47.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20483
- 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;
20484
20535
  let text7;
20485
20536
  try {
20486
- text7 = (0, import_node_fs47.readFileSync)(agentsFile, "utf8");
20537
+ text7 = (0, import_node_fs48.readFileSync)(agentsFile, "utf8");
20487
20538
  } catch {
20488
20539
  continue;
20489
20540
  }
@@ -20507,7 +20558,7 @@ function resolveConductorCursorAgentId(workspacePath) {
20507
20558
  return best?.agentId ?? null;
20508
20559
  }
20509
20560
  async function adoptThread(input) {
20510
- if (!(0, import_node_fs47.existsSync)(input.worktreePath)) {
20561
+ if (!(0, import_node_fs48.existsSync)(input.worktreePath)) {
20511
20562
  throw new Error(`Worktree not found: ${input.worktreePath}`);
20512
20563
  }
20513
20564
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -20536,18 +20587,18 @@ function conductorDbPath() {
20536
20587
  return CONDUCTOR_DB;
20537
20588
  }
20538
20589
  function listConductorWorkspaces() {
20539
- if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
20590
+ if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20540
20591
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20541
20592
  }
20542
- const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20543
- 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");
20544
20595
  try {
20545
- (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
20596
+ (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20546
20597
  for (const suffix of ["-wal", "-shm"]) {
20547
20598
  const src = `${CONDUCTOR_DB}${suffix}`;
20548
- if ((0, import_node_fs47.existsSync)(src)) {
20599
+ if ((0, import_node_fs48.existsSync)(src)) {
20549
20600
  try {
20550
- (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
20601
+ (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20551
20602
  } catch {
20552
20603
  }
20553
20604
  }
@@ -20623,22 +20674,22 @@ function listConductorWorkspaces() {
20623
20674
  db.close();
20624
20675
  }
20625
20676
  } finally {
20626
- (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
20677
+ (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20627
20678
  }
20628
20679
  }
20629
20680
  function importConductorWorkspace(workspaceId) {
20630
- if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
20681
+ if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20631
20682
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20632
20683
  }
20633
- const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20634
- 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");
20635
20686
  try {
20636
- (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
20687
+ (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20637
20688
  for (const suffix of ["-wal", "-shm"]) {
20638
20689
  const src = `${CONDUCTOR_DB}${suffix}`;
20639
- if ((0, import_node_fs47.existsSync)(src)) {
20690
+ if ((0, import_node_fs48.existsSync)(src)) {
20640
20691
  try {
20641
- (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
20692
+ (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20642
20693
  } catch {
20643
20694
  }
20644
20695
  }
@@ -20656,7 +20707,7 @@ function importConductorWorkspace(workspaceId) {
20656
20707
  ).get(workspaceId);
20657
20708
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
20658
20709
  const worktreePath = String(row.workspacePath);
20659
- if (!(0, import_node_fs47.existsSync)(worktreePath)) {
20710
+ if (!(0, import_node_fs48.existsSync)(worktreePath)) {
20660
20711
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
20661
20712
  }
20662
20713
  let sessionId = null;
@@ -20719,31 +20770,31 @@ function importConductorWorkspace(workspaceId) {
20719
20770
  db.close();
20720
20771
  }
20721
20772
  } finally {
20722
- (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
20773
+ (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20723
20774
  }
20724
20775
  }
20725
20776
  async function importConductorWorkspaceAsync(workspaceId) {
20726
20777
  return importConductorWorkspace(workspaceId);
20727
20778
  }
20728
- 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;
20729
20780
  var init_adopt = __esm({
20730
20781
  "src/threads/adopt.ts"() {
20731
20782
  "use strict";
20732
20783
  import_node_child_process6 = require("child_process");
20733
- import_node_fs47 = require("fs");
20784
+ import_node_fs48 = require("fs");
20734
20785
  import_node_os14 = require("os");
20735
- import_node_path47 = require("path");
20786
+ import_node_path48 = require("path");
20736
20787
  import_node_module4 = require("module");
20737
20788
  init_worktree();
20738
20789
  init_thread_store();
20739
- CONDUCTOR_APP_SUPPORT = (0, import_node_path47.join)(
20790
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path48.join)(
20740
20791
  process.env.HOME ?? "",
20741
20792
  "Library",
20742
20793
  "Application Support",
20743
20794
  "com.conductor.app"
20744
20795
  );
20745
- CONDUCTOR_DB = (0, import_node_path47.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20746
- 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");
20747
20798
  }
20748
20799
  });
20749
20800
 
@@ -20810,7 +20861,7 @@ async function openStackLayer(input, _onSetupLine) {
20810
20861
  let createdWorktree = false;
20811
20862
  const trees = await listWorktrees(repoPath);
20812
20863
  const checkedOut = trees.find((w) => w.branch === branchName);
20813
- if (checkedOut?.path && (0, import_node_fs48.existsSync)(checkedOut.path)) {
20864
+ if (checkedOut?.path && (0, import_node_fs49.existsSync)(checkedOut.path)) {
20814
20865
  if (input.reuseExistingWorktree !== false) {
20815
20866
  worktreePath = checkedOut.path;
20816
20867
  } else {
@@ -20952,7 +21003,7 @@ async function initStackFromThread(input, onSetupLine) {
20952
21003
  async function createPrStack(input, onSetupLine) {
20953
21004
  await requireAgent(input.agent);
20954
21005
  const repoPath = await resolveRepoRoot(input.repoPath);
20955
- 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}`);
20956
21007
  if (!input.branches.length) throw new Error("At least one branch name required");
20957
21008
  const status = await detectGhStack(repoPath);
20958
21009
  if (!status.available) throw new Error(status.reason);
@@ -21019,7 +21070,7 @@ async function createPrStack(input, onSetupLine) {
21019
21070
  }
21020
21071
  }
21021
21072
  const claimed = new Set(threads.map((t) => t.worktreePath));
21022
- 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)) {
21023
21074
  try {
21024
21075
  await removeWorktree(repoPath, bootstrap.worktreePath, {
21025
21076
  deleteBranch: bootstrap.branchName
@@ -21039,11 +21090,11 @@ function stackAgentDefaultsFrom(input) {
21039
21090
  planMode: input.planMode
21040
21091
  };
21041
21092
  }
21042
- var import_node_fs48;
21093
+ var import_node_fs49;
21043
21094
  var init_stack_layers = __esm({
21044
21095
  "src/threads/stack-layers.ts"() {
21045
21096
  "use strict";
21046
- import_node_fs48 = require("fs");
21097
+ import_node_fs49 = require("fs");
21047
21098
  init_detect();
21048
21099
  init_run();
21049
21100
  init_stack();
@@ -21056,7 +21107,7 @@ var init_stack_layers = __esm({
21056
21107
 
21057
21108
  // src/diff/diff.ts
21058
21109
  async function inspectGitWorktree(worktreePath) {
21059
- if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) return "missing_worktree";
21110
+ if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) return "missing_worktree";
21060
21111
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
21061
21112
  reject: false
21062
21113
  });
@@ -21064,7 +21115,7 @@ async function inspectGitWorktree(worktreePath) {
21064
21115
  return "ok";
21065
21116
  }
21066
21117
  async function initializeGitRepository(worktreePath) {
21067
- if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) {
21118
+ if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) {
21068
21119
  throw new Error("Worktree not found");
21069
21120
  }
21070
21121
  const status = await inspectGitWorktree(worktreePath);
@@ -21198,11 +21249,11 @@ new file mode 100644
21198
21249
  };
21199
21250
  }
21200
21251
  async function untrackedPatch(worktreePath, path2, maxHunk) {
21201
- const abs = (0, import_node_path48.join)(worktreePath, path2);
21252
+ const abs = (0, import_node_path49.join)(worktreePath, path2);
21202
21253
  try {
21203
- const st = (0, import_node_fs49.statSync)(abs);
21254
+ const st = (0, import_node_fs50.statSync)(abs);
21204
21255
  if (st.isFile() && st.size > maxHunk) {
21205
- const buf = (0, import_node_fs49.readFileSync)(abs).subarray(0, maxHunk);
21256
+ const buf = (0, import_node_fs50.readFileSync)(abs).subarray(0, maxHunk);
21206
21257
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
21207
21258
  }
21208
21259
  } catch {
@@ -21669,9 +21720,9 @@ async function getDiff(worktreePath, repoPath, opts) {
21669
21720
  }
21670
21721
  function statWorktreePath(worktreePath, relativePath) {
21671
21722
  assertSafeRelativePath(relativePath);
21672
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21673
- if (!(0, import_node_fs49.existsSync)(abs)) return "missing";
21674
- 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);
21675
21726
  if (st.isDirectory()) return "dir";
21676
21727
  if (st.isFile()) return "file";
21677
21728
  return "missing";
@@ -21700,8 +21751,8 @@ function isImageRelativePath(relativePath) {
21700
21751
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21701
21752
  assertSafeRelativePath(relativePath);
21702
21753
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
21703
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21704
- 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);
21705
21756
  if (!st.isFile()) {
21706
21757
  throw new Error(`Not a file: ${relativePath}`);
21707
21758
  }
@@ -21710,7 +21761,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21710
21761
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
21711
21762
  );
21712
21763
  }
21713
- const buf = (0, import_node_fs49.readFileSync)(abs);
21764
+ const buf = (0, import_node_fs50.readFileSync)(abs);
21714
21765
  return {
21715
21766
  path: relativePath,
21716
21767
  contentBase64: buf.toString("base64"),
@@ -21720,12 +21771,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21720
21771
  function readWorktreeFile(worktreePath, relativePath, opts) {
21721
21772
  assertSafeRelativePath(relativePath);
21722
21773
  const maxBytes = opts?.maxBytes ?? 2e5;
21723
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21724
- 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);
21725
21776
  if (!st.isFile()) {
21726
21777
  throw new Error(`Not a file: ${relativePath}`);
21727
21778
  }
21728
- const buf = (0, import_node_fs49.readFileSync)(abs);
21779
+ const buf = (0, import_node_fs50.readFileSync)(abs);
21729
21780
  if (isImageRelativePath(relativePath)) {
21730
21781
  const maxImageBytes = Math.max(maxBytes, 15e6);
21731
21782
  const truncated2 = buf.length > maxImageBytes;
@@ -21768,9 +21819,9 @@ function assertSafeRelativePath(relativePath) {
21768
21819
  }
21769
21820
  function writeWorktreeFile(worktreePath, relativePath, content) {
21770
21821
  assertSafeRelativePath(relativePath);
21771
- const abs = (0, import_node_path48.join)(worktreePath, relativePath);
21772
- (0, import_node_fs49.mkdirSync)((0, import_node_path48.dirname)(abs), { recursive: true });
21773
- (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");
21774
21825
  return { path: relativePath };
21775
21826
  }
21776
21827
  async function getWorktreeDirtyStat(worktreePath) {
@@ -21810,12 +21861,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
21810
21861
  truncated: full.files.length > maxFiles
21811
21862
  };
21812
21863
  }
21813
- 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;
21814
21865
  var init_diff = __esm({
21815
21866
  "src/diff/diff.ts"() {
21816
21867
  "use strict";
21817
- import_node_fs49 = require("fs");
21818
- import_node_path48 = require("path");
21868
+ import_node_fs50 = require("fs");
21869
+ import_node_path49 = require("path");
21819
21870
  init_run();
21820
21871
  init_worktree();
21821
21872
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -22172,7 +22223,7 @@ function parseFrontmatter(content) {
22172
22223
  }
22173
22224
  function readSkill(skillMd, source) {
22174
22225
  try {
22175
- const content = (0, import_node_fs50.readFileSync)(skillMd, "utf8");
22226
+ const content = (0, import_node_fs51.readFileSync)(skillMd, "utf8");
22176
22227
  const { name: fmName, description } = parseFrontmatter(content);
22177
22228
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
22178
22229
  const name = fmName || dirName;
@@ -22191,19 +22242,19 @@ function readSkill(skillMd, source) {
22191
22242
  }
22192
22243
  }
22193
22244
  function scanSkillsDir(dir, source, out) {
22194
- if (!(0, import_node_fs50.existsSync)(dir)) return;
22245
+ if (!(0, import_node_fs51.existsSync)(dir)) return;
22195
22246
  let entries;
22196
22247
  try {
22197
- entries = (0, import_node_fs50.readdirSync)(dir);
22248
+ entries = (0, import_node_fs51.readdirSync)(dir);
22198
22249
  } catch {
22199
22250
  return;
22200
22251
  }
22201
22252
  for (const entry of entries) {
22202
22253
  if (entry.startsWith(".")) continue;
22203
- const skillMd = (0, import_node_path49.join)(dir, entry, "SKILL.md");
22204
- 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;
22205
22256
  try {
22206
- if (!(0, import_node_fs50.statSync)(skillMd).isFile()) continue;
22257
+ if (!(0, import_node_fs51.statSync)(skillMd).isFile()) continue;
22207
22258
  } catch {
22208
22259
  continue;
22209
22260
  }
@@ -22212,24 +22263,24 @@ function scanSkillsDir(dir, source, out) {
22212
22263
  }
22213
22264
  }
22214
22265
  function scanClaudePluginSkills(pluginsRoot, out) {
22215
- if (!(0, import_node_fs50.existsSync)(pluginsRoot)) return;
22266
+ if (!(0, import_node_fs51.existsSync)(pluginsRoot)) return;
22216
22267
  const walk = (dir, depth, lookingForSkillsDir) => {
22217
22268
  if (depth > 7) return;
22218
22269
  let entries;
22219
22270
  try {
22220
- entries = (0, import_node_fs50.readdirSync)(dir);
22271
+ entries = (0, import_node_fs51.readdirSync)(dir);
22221
22272
  } catch {
22222
22273
  return;
22223
22274
  }
22224
22275
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
22225
- 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");
22226
22277
  if (skill) out.push(skill);
22227
22278
  }
22228
22279
  for (const entry of entries) {
22229
22280
  if (entry === "node_modules" || entry === ".git") continue;
22230
- const full = (0, import_node_path49.join)(dir, entry);
22281
+ const full = (0, import_node_path50.join)(dir, entry);
22231
22282
  try {
22232
- if (!(0, import_node_fs50.statSync)(full).isDirectory()) continue;
22283
+ if (!(0, import_node_fs51.statSync)(full).isDirectory()) continue;
22233
22284
  } catch {
22234
22285
  continue;
22235
22286
  }
@@ -22247,17 +22298,17 @@ function discoverSkills(worktreePath) {
22247
22298
  const home = (0, import_node_os15.homedir)();
22248
22299
  const collected = [];
22249
22300
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
22250
- scanSkillsDir((0, import_node_path49.join)(worktreePath, rel), "workspace", collected);
22301
+ scanSkillsDir((0, import_node_path50.join)(worktreePath, rel), "workspace", collected);
22251
22302
  }
22252
22303
  for (const abs of [
22253
- (0, import_node_path49.join)(home, ".claude/skills"),
22254
- (0, import_node_path49.join)(home, ".cursor/skills"),
22255
- (0, import_node_path49.join)(home, ".sideboard/skills"),
22256
- (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")
22257
22308
  ]) {
22258
22309
  scanSkillsDir(abs, "user", collected);
22259
22310
  }
22260
- scanClaudePluginSkills((0, import_node_path49.join)(home, ".claude/plugins"), collected);
22311
+ scanClaudePluginSkills((0, import_node_path50.join)(home, ".claude/plugins"), collected);
22261
22312
  collected.push(...bundledSkills());
22262
22313
  const rank = {
22263
22314
  workspace: 0,
@@ -22283,7 +22334,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22283
22334
  \u2026(truncated)` : body;
22284
22335
  }
22285
22336
  }
22286
- const raw = (0, import_node_fs50.readFileSync)(skillPath, "utf8");
22337
+ const raw = (0, import_node_fs51.readFileSync)(skillPath, "utf8");
22287
22338
  if (raw.startsWith("---")) {
22288
22339
  const end = raw.indexOf("\n---", 3);
22289
22340
  if (end >= 0) {
@@ -22297,13 +22348,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22297
22348
 
22298
22349
  \u2026(truncated)` : raw;
22299
22350
  }
22300
- 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;
22301
22352
  var init_discover = __esm({
22302
22353
  "src/skills/discover.ts"() {
22303
22354
  "use strict";
22304
- import_node_fs50 = require("fs");
22355
+ import_node_fs51 = require("fs");
22305
22356
  import_node_os15 = require("os");
22306
- import_node_path49 = require("path");
22357
+ import_node_path50 = require("path");
22307
22358
  init_long_running();
22308
22359
  BUNDLED_SKILL_PREFIX = "bundled:";
22309
22360
  }
@@ -22458,7 +22509,7 @@ function compiledModuleDir() {
22458
22509
  try {
22459
22510
  const url = import_meta3.url;
22460
22511
  if (typeof url === "string" && url.length > 0) {
22461
- 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));
22462
22513
  }
22463
22514
  } catch {
22464
22515
  }
@@ -22466,8 +22517,8 @@ function compiledModuleDir() {
22466
22517
  }
22467
22518
  function detachedJobScriptIn(dir) {
22468
22519
  for (const name of DETACHED_JOB_FILENAMES) {
22469
- const script = (0, import_node_path50.join)(dir, "scripts", name);
22470
- 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;
22471
22522
  }
22472
22523
  return null;
22473
22524
  }
@@ -22484,7 +22535,7 @@ function resolveDetachedJobScript() {
22484
22535
  for (let i = 0; i < 8; i++) {
22485
22536
  const candidate = detachedJobScriptIn(dir);
22486
22537
  if (candidate) return candidate;
22487
- const parent = (0, import_node_path50.dirname)(dir);
22538
+ const parent = (0, import_node_path51.dirname)(dir);
22488
22539
  if (parent === dir) break;
22489
22540
  dir = parent;
22490
22541
  }
@@ -22495,12 +22546,12 @@ function formatDetachedJobInvoke(scriptPath) {
22495
22546
  if (resolved) return `node ${JSON.stringify(resolved)}`;
22496
22547
  return "node scripts/detached-job.cjs";
22497
22548
  }
22498
- 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;
22499
22550
  var init_detached_job_path = __esm({
22500
22551
  "src/skills/detached-job-path.ts"() {
22501
22552
  "use strict";
22502
- import_node_fs51 = require("fs");
22503
- import_node_path50 = require("path");
22553
+ import_node_fs52 = require("fs");
22554
+ import_node_path51 = require("path");
22504
22555
  import_node_url3 = require("url");
22505
22556
  init_packaged_runtime();
22506
22557
  import_meta3 = {};
@@ -22682,9 +22733,9 @@ function formatPrGateDirective() {
22682
22733
  }
22683
22734
  function formatProcessGuideDirective(opts) {
22684
22735
  const worktree = opts?.worktreePath?.trim();
22685
- const hasGraphSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22686
- const hasReviewSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path51.join)(worktree, ".claude/skills/review/SKILL.md"));
22687
- 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"));
22688
22739
  return [
22689
22740
  "Process guides (recurring work only):",
22690
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,
@@ -22703,12 +22754,13 @@ function formatLongRunningDirective(opts) {
22703
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>`.",
22704
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.",
22705
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.",
22706
- "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."
22707
22759
  ].join("\n");
22708
22760
  }
22709
22761
  function formatLongRunningReminder(opts) {
22710
22762
  const invoke = formatDetachedJobInvoke(opts?.scriptPath);
22711
- 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).`;
22712
22764
  }
22713
22765
  function formatArtifactDirective() {
22714
22766
  return [
@@ -22720,14 +22772,14 @@ function formatArtifactDirective() {
22720
22772
  ].join("\n");
22721
22773
  }
22722
22774
  function formatUiReminder() {
22723
- 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.";
22724
22776
  }
22725
- 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;
22726
22778
  var init_instructions = __esm({
22727
22779
  "src/agents/instructions.ts"() {
22728
22780
  "use strict";
22729
- import_node_fs52 = require("fs");
22730
- import_node_path51 = require("path");
22781
+ import_node_fs53 = require("fs");
22782
+ import_node_path52 = require("path");
22731
22783
  init_git_auth_mode();
22732
22784
  init_branch_prefix();
22733
22785
  init_worktree_labels();
@@ -23113,40 +23165,40 @@ __export(plan_file_exports, {
23113
23165
  writePlanFile: () => writePlanFile
23114
23166
  });
23115
23167
  function ensureAttachmentsGitignore(worktreePath) {
23116
- const gitignoreAbs = (0, import_node_path52.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23117
- if ((0, import_node_fs53.existsSync)(gitignoreAbs)) return;
23118
- (0, import_node_fs53.mkdirSync)((0, import_node_path52.dirname)(gitignoreAbs), { recursive: true });
23119
- (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");
23120
23172
  }
23121
23173
  function planFileAbs(worktreePath) {
23122
- return (0, import_node_path52.join)(worktreePath, PLAN_FILE_REL);
23174
+ return (0, import_node_path53.join)(worktreePath, PLAN_FILE_REL);
23123
23175
  }
23124
23176
  function readTextIfPresent2(abs) {
23125
- if (!(0, import_node_fs53.existsSync)(abs)) return null;
23177
+ if (!(0, import_node_fs54.existsSync)(abs)) return null;
23126
23178
  try {
23127
- const content = (0, import_node_fs53.readFileSync)(abs, "utf8");
23179
+ const content = (0, import_node_fs54.readFileSync)(abs, "utf8");
23128
23180
  return content.trim() ? content : null;
23129
23181
  } catch {
23130
23182
  return null;
23131
23183
  }
23132
23184
  }
23133
23185
  function readPlanFile(worktreePath) {
23134
- 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));
23135
23187
  }
23136
23188
  function writePlanFile(worktreePath, content) {
23137
23189
  ensureAttachmentsGitignore(worktreePath);
23138
23190
  const abs = planFileAbs(worktreePath);
23139
- (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 });
23140
23192
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23141
- (0, import_node_fs53.writeFileSync)(abs, body, "utf8");
23193
+ (0, import_node_fs54.writeFileSync)(abs, body, "utf8");
23142
23194
  return PLAN_FILE_REL;
23143
23195
  }
23144
- var import_node_fs53, import_node_path52;
23196
+ var import_node_fs54, import_node_path53;
23145
23197
  var init_plan_file = __esm({
23146
23198
  "src/plan/plan-file.ts"() {
23147
23199
  "use strict";
23148
- import_node_fs53 = require("fs");
23149
- import_node_path52 = require("path");
23200
+ import_node_fs54 = require("fs");
23201
+ import_node_path53 = require("path");
23150
23202
  init_workspace_scratch();
23151
23203
  init_plan_present();
23152
23204
  init_plan_present();
@@ -23208,9 +23260,9 @@ function recoverFinishedCursorRun(opts) {
23208
23260
  return best;
23209
23261
  }
23210
23262
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23211
- if (!(0, import_node_fs54.existsSync)(runsPath)) return null;
23263
+ if (!(0, import_node_fs55.existsSync)(runsPath)) return null;
23212
23264
  try {
23213
- const lines = (0, import_node_fs54.readFileSync)(runsPath, "utf8").split("\n");
23265
+ const lines = (0, import_node_fs55.readFileSync)(runsPath, "utf8").split("\n");
23214
23266
  let best = null;
23215
23267
  for (const line of lines) {
23216
23268
  const trimmed = line.trim();
@@ -23236,11 +23288,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23236
23288
  return null;
23237
23289
  }
23238
23290
  }
23239
- var import_node_fs54;
23291
+ var import_node_fs55;
23240
23292
  var init_cursor_recover = __esm({
23241
23293
  "src/agents/cursor-recover.ts"() {
23242
23294
  "use strict";
23243
- import_node_fs54 = require("fs");
23295
+ import_node_fs55 = require("fs");
23244
23296
  init_cursor_store();
23245
23297
  }
23246
23298
  });
@@ -23393,13 +23445,13 @@ async function startOrchestration(opts) {
23393
23445
  }
23394
23446
  return updated;
23395
23447
  }
23396
- 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;
23397
23449
  var init_orchestrator = __esm({
23398
23450
  "src/orchestrator/orchestrator.ts"() {
23399
23451
  "use strict";
23400
23452
  import_node_events = require("events");
23401
23453
  init_outbound_watch();
23402
- import_node_fs55 = require("fs");
23454
+ import_node_fs56 = require("fs");
23403
23455
  init_error_detail();
23404
23456
  init_run();
23405
23457
  init_stale_lock();
@@ -23567,7 +23619,7 @@ var init_orchestrator = __esm({
23567
23619
  this.lightReconcileAt.set(repoPath, Date.now());
23568
23620
  for (const thread of listThreads()) {
23569
23621
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
23570
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
23622
+ if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23571
23623
  setStatus(thread.id, "broken", "Worktree missing on disk");
23572
23624
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23573
23625
  }
@@ -23596,7 +23648,7 @@ var init_orchestrator = __esm({
23596
23648
  }
23597
23649
  continue;
23598
23650
  }
23599
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
23651
+ if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23600
23652
  setStatus(thread.id, "broken", "Worktree missing on disk");
23601
23653
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23602
23654
  continue;
@@ -25750,7 +25802,7 @@ var init_orchestrator = __esm({
25750
25802
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
25751
25803
  return restored2;
25752
25804
  }
25753
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
25805
+ if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
25754
25806
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
25755
25807
  throw new Error(
25756
25808
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -25965,6 +26017,9 @@ __export(index_exports, {
25965
26017
  ABLETIME_ORG_KEY_PREFIX: () => ABLETIME_ORG_KEY_PREFIX,
25966
26018
  ABLETIME_PAT_PREFIX: () => ABLETIME_PAT_PREFIX,
25967
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,
25968
26023
  AGENT_GIT_ACTIONS: () => AGENT_GIT_ACTIONS,
25969
26024
  AGENT_RUNNER_MAX_OLD_SPACE_MB: () => AGENT_RUNNER_MAX_OLD_SPACE_MB,
25970
26025
  ATTACHMENTS_DIR: () => ATTACHMENTS_DIR,
@@ -26087,6 +26142,9 @@ __export(index_exports, {
26087
26142
  addStackLayerFromThread: () => addStackLayerFromThread,
26088
26143
  addWorkspace: () => addWorkspace,
26089
26144
  adoptThread: () => adoptThread,
26145
+ agentDoneCustomSoundMime: () => agentDoneCustomSoundMime,
26146
+ agentDoneSound: () => agentDoneSound,
26147
+ agentDoneSoundsDir: () => agentDoneSoundsDir,
26090
26148
  agentGitPrompt: () => agentGitPrompt,
26091
26149
  alignQueueAttachments: () => alignQueueAttachments,
26092
26150
  allAdapters: () => allAdapters,
@@ -26165,6 +26223,7 @@ __export(index_exports, {
26165
26223
  claudeUserSettingsPath: () => claudeUserSettingsPath,
26166
26224
  cleanupArchivedHistory: () => cleanupArchivedHistory,
26167
26225
  cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
26226
+ clearAgentDoneCustomSoundFile: () => clearAgentDoneCustomSoundFile,
26168
26227
  clearBoardPins: () => clearBoardPins,
26169
26228
  clearHomeBoardCache: () => clearHomeBoardCache,
26170
26229
  clipAgentEventForPaint: () => clipAgentEventForPaint,
@@ -26267,6 +26326,7 @@ __export(index_exports, {
26267
26326
  fetchOriginForWorktree: () => fetchOriginForWorktree,
26268
26327
  fetchPrHead: () => fetchPrHead,
26269
26328
  finalizeParts: () => finalizeParts,
26329
+ findAgentDoneCustomSoundPath: () => findAgentDoneCustomSoundPath,
26270
26330
  findConventionSetup: () => findConventionSetup,
26271
26331
  findInvalidCacheControlTtlOrder: () => findInvalidCacheControlTtlOrder,
26272
26332
  findLastBrightsyContextSummary: () => findLastBrightsyContextSummary,
@@ -26401,6 +26461,7 @@ __export(index_exports, {
26401
26461
  historyMaxDays: () => historyMaxDays,
26402
26462
  hottestClaudeWindow: () => hottestClaudeWindow,
26403
26463
  httpFetch: () => httpFetch,
26464
+ importAgentDoneCustomSound: () => importAgentDoneCustomSound,
26404
26465
  importConductorWorkspace: () => importConductorWorkspace,
26405
26466
  importConductorWorkspaceAsync: () => importConductorWorkspaceAsync,
26406
26467
  initPrStack: () => initPrStack,
@@ -26416,6 +26477,7 @@ __export(index_exports, {
26416
26477
  isAbleTimeConnected: () => isAbleTimeConnected,
26417
26478
  isAbleTimeOAuthCancelled: () => isAbleTimeOAuthCancelled,
26418
26479
  isAbleTimeRejectedCredential: () => isAbleTimeRejectedCredential,
26480
+ isAgentDoneSound: () => isAgentDoneSound,
26419
26481
  isAskUserToolName: () => isAskUserToolName,
26420
26482
  isBrightsyConnected: () => isBrightsyConnected,
26421
26483
  isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
@@ -26607,6 +26669,7 @@ __export(index_exports, {
26607
26669
  primaryCheckoutFromLinkedWorktree: () => primaryCheckoutFromLinkedWorktree,
26608
26670
  promptMentionsBrightsy: () => promptMentionsBrightsy,
26609
26671
  pushBranch: () => pushBranch,
26672
+ readAgentDoneCustomSound: () => readAgentDoneCustomSound,
26610
26673
  readExistingReviewRequestFile: () => readExistingReviewRequestFile,
26611
26674
  readKeychainVaultKey: () => readKeychainVaultKey,
26612
26675
  readPlanFile: () => readPlanFile,
@@ -26838,6 +26901,95 @@ module.exports = __toCommonJS(index_exports);
26838
26901
  init_thinking_effort();
26839
26902
  init_paths();
26840
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
26841
26993
  init_caffeinate_hold();
26842
26994
  init_secure_file();
26843
26995
  init_thread_store();
@@ -29255,7 +29407,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
29255
29407
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29256
29408
  var import_zod9 = require("zod");
29257
29409
  var import_node_crypto15 = require("crypto");
29258
- var import_node_path55 = require("path");
29410
+ var import_node_path56 = require("path");
29259
29411
  init_orchestrator();
29260
29412
  init_worktree();
29261
29413
  init_global_workspace();
@@ -29272,6 +29424,23 @@ function mcpArchiveBlockedReason(thread) {
29272
29424
 
29273
29425
  // src/mcp/server.ts
29274
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
29275
29444
  init_wait_for_turn();
29276
29445
  init_wait_for_job();
29277
29446
  init_message_parts();
@@ -30975,27 +31144,27 @@ init_gh_errors();
30975
31144
  init_git_auth_mode();
30976
31145
 
30977
31146
  // src/board/load-home-board.ts
30978
- var import_node_fs57 = require("fs");
30979
- var import_node_path54 = require("path");
31147
+ var import_node_fs58 = require("fs");
31148
+ var import_node_path55 = require("path");
30980
31149
  init_worktree();
30981
31150
  init_paths();
30982
31151
 
30983
31152
  // src/board/board-pins.ts
30984
31153
  var import_node_crypto14 = require("crypto");
30985
- var import_node_fs56 = require("fs");
30986
- var import_node_path53 = require("path");
31154
+ var import_node_fs57 = require("fs");
31155
+ var import_node_path54 = require("path");
30987
31156
  init_paths();
30988
31157
  init_home_board();
30989
31158
  var FILE = "home-board-pins.json";
30990
31159
  var VERSION = 1;
30991
31160
  function pinsFile() {
30992
- return (0, import_node_path53.join)(appDataDir(), FILE);
31161
+ return (0, import_node_path54.join)(appDataDir(), FILE);
30993
31162
  }
30994
31163
  function readDisk() {
30995
31164
  const path2 = pinsFile();
30996
- if (!(0, import_node_fs56.existsSync)(path2)) return [];
31165
+ if (!(0, import_node_fs57.existsSync)(path2)) return [];
30997
31166
  try {
30998
- const raw = JSON.parse((0, import_node_fs56.readFileSync)(path2, "utf8"));
31167
+ const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
30999
31168
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
31000
31169
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
31001
31170
  } catch {
@@ -31003,8 +31172,8 @@ function readDisk() {
31003
31172
  }
31004
31173
  }
31005
31174
  function writeDisk(items) {
31006
- (0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
31007
- (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");
31008
31177
  }
31009
31178
  function listBoardPins() {
31010
31179
  return readDisk();
@@ -31056,7 +31225,7 @@ function replaceBoardPins(items) {
31056
31225
  }
31057
31226
  function clearBoardPins() {
31058
31227
  try {
31059
- (0, import_node_fs56.unlinkSync)(pinsFile());
31228
+ (0, import_node_fs57.unlinkSync)(pinsFile());
31060
31229
  } catch {
31061
31230
  }
31062
31231
  }
@@ -31073,7 +31242,7 @@ function homeBoardWorkspaceKey(workspaces) {
31073
31242
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
31074
31243
  }
31075
31244
  function cacheFile() {
31076
- return (0, import_node_path54.join)(appDataDir(), "home-board-cache.json");
31245
+ return (0, import_node_path55.join)(appDataDir(), "home-board-cache.json");
31077
31246
  }
31078
31247
  function emptyInputs() {
31079
31248
  return {
@@ -31099,9 +31268,9 @@ function shouldCacheHomeBoardInputs(inputs) {
31099
31268
  }
31100
31269
  function readDiskCache() {
31101
31270
  const path2 = cacheFile();
31102
- if (!(0, import_node_fs57.existsSync)(path2)) return null;
31271
+ if (!(0, import_node_fs58.existsSync)(path2)) return null;
31103
31272
  try {
31104
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
31273
+ const raw = JSON.parse((0, import_node_fs58.readFileSync)(path2, "utf8"));
31105
31274
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
31106
31275
  return null;
31107
31276
  }
@@ -31115,14 +31284,14 @@ function readDiskCache() {
31115
31284
  }
31116
31285
  function writeDiskCache(entry) {
31117
31286
  try {
31118
- (0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
31119
- (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");
31120
31289
  } catch {
31121
31290
  }
31122
31291
  }
31123
31292
  function deleteDiskCache() {
31124
31293
  try {
31125
- (0, import_node_fs57.unlinkSync)(cacheFile());
31294
+ (0, import_node_fs58.unlinkSync)(cacheFile());
31126
31295
  } catch {
31127
31296
  }
31128
31297
  }
@@ -31472,7 +31641,7 @@ async function startMcpServer() {
31472
31641
  async () => {
31473
31642
  const threads = orch.getThreads(true);
31474
31643
  const lines = threads.map((t) => {
31475
- 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;
31476
31645
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
31477
31646
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
31478
31647
  const preview = lastMessagePreview(t.messages, 80);
@@ -31720,13 +31889,73 @@ async function startMcpServer() {
31720
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.",
31721
31890
  {
31722
31891
  id: import_zod9.z.string().describe("Detached job id (same kebab-case id passed to detached-job.cjs start)"),
31723
- 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)")
31724
31893
  },
31725
31894
  async ({ id, reason }) => {
31726
31895
  const result = await stopDetachedJob(process.cwd(), id, { reason });
31727
31896
  return mcpJson(result);
31728
31897
  }
31729
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
+ );
31730
31959
  if (!worktreeProfile) {
31731
31960
  registerSlackTools(server);
31732
31961
  registerConnectedIssueVendorTools(server);
@@ -32205,45 +32434,6 @@ async function startMcpServer() {
32205
32434
  }
32206
32435
  }
32207
32436
  );
32208
- server.tool(
32209
- "run_dev_script",
32210
- "Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
32211
- {
32212
- ref: import_zod9.z.string(),
32213
- name: import_zod9.z.string().optional()
32214
- },
32215
- async ({ ref, name }) => {
32216
- const result = await orch.startDev(ref, name);
32217
- return mcpJson({
32218
- port: result.port,
32219
- scriptName: result.scriptName,
32220
- ports: result.ports,
32221
- url: `http://localhost:${result.port}`
32222
- });
32223
- }
32224
- );
32225
- server.tool(
32226
- "list_run_scripts",
32227
- "List named run scripts available for a thread",
32228
- { ref: import_zod9.z.string() },
32229
- async ({ ref }) => {
32230
- const scripts = orch.listThreadRunScripts(ref);
32231
- const active = orch.getActiveRuns(ref);
32232
- return mcpJson({ scripts, active });
32233
- }
32234
- );
32235
- server.tool(
32236
- "stop_dev_script",
32237
- "Stop a running script for a thread (all scripts if name omitted)",
32238
- {
32239
- ref: import_zod9.z.string(),
32240
- name: import_zod9.z.string().optional()
32241
- },
32242
- async ({ ref, name }) => {
32243
- orch.stopDev(ref, name);
32244
- return { content: [{ type: "text", text: "ok" }] };
32245
- }
32246
- );
32247
32437
  server.tool(
32248
32438
  "run_setup",
32249
32439
  "Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
@@ -34452,9 +34642,9 @@ var import_node_http4 = require("http");
34452
34642
  var import_ws3 = require("ws");
34453
34643
 
34454
34644
  // src/slack/relay-static.ts
34455
- var import_node_fs58 = require("fs");
34645
+ var import_node_fs59 = require("fs");
34456
34646
  var import_promises = require("fs/promises");
34457
- var import_node_path56 = __toESM(require("path"), 1);
34647
+ var import_node_path57 = __toESM(require("path"), 1);
34458
34648
  var TYPES = {
34459
34649
  ".css": "text/css; charset=utf-8",
34460
34650
  ".html": "text/html; charset=utf-8",
@@ -34485,9 +34675,9 @@ function resolveStaticPath(root, requestUrl) {
34485
34675
  return null;
34486
34676
  }
34487
34677
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
34488
- const rootResolved = import_node_path56.default.resolve(root);
34489
- const candidate = import_node_path56.default.resolve(rootResolved, `.${pathname}`);
34490
- 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)) {
34491
34681
  return null;
34492
34682
  }
34493
34683
  return candidate;
@@ -34501,7 +34691,7 @@ async function fileSize(file) {
34501
34691
  }
34502
34692
  }
34503
34693
  function sendFile(req, res, file, size) {
34504
- const ext = import_node_path56.default.extname(file).toLowerCase();
34694
+ const ext = import_node_path57.default.extname(file).toLowerCase();
34505
34695
  res.writeHead(200, {
34506
34696
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
34507
34697
  "Content-Length": size,
@@ -34511,7 +34701,7 @@ function sendFile(req, res, file, size) {
34511
34701
  res.end();
34512
34702
  return true;
34513
34703
  }
34514
- (0, import_node_fs58.createReadStream)(file).pipe(res);
34704
+ (0, import_node_fs59.createReadStream)(file).pipe(res);
34515
34705
  return true;
34516
34706
  }
34517
34707
  async function tryServeStatic(req, res, root) {
@@ -34520,7 +34710,7 @@ async function tryServeStatic(req, res, root) {
34520
34710
  if (!candidate) return false;
34521
34711
  const direct = await fileSize(candidate);
34522
34712
  if (direct != null) return sendFile(req, res, candidate, direct);
34523
- const asIndex = import_node_path56.default.join(candidate, "index.html");
34713
+ const asIndex = import_node_path57.default.join(candidate, "index.html");
34524
34714
  const indexSize = await fileSize(asIndex);
34525
34715
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
34526
34716
  return false;
@@ -34778,6 +34968,9 @@ init_outbound_watch();
34778
34968
  ABLETIME_ORG_KEY_PREFIX,
34779
34969
  ABLETIME_PAT_PREFIX,
34780
34970
  ABLETIME_PM_TOOL_NAMES,
34971
+ AGENT_DONE_CUSTOM_SOUND_EXTENSIONS,
34972
+ AGENT_DONE_CUSTOM_SOUND_MAX_BYTES,
34973
+ AGENT_DONE_SOUNDS,
34781
34974
  AGENT_GIT_ACTIONS,
34782
34975
  AGENT_RUNNER_MAX_OLD_SPACE_MB,
34783
34976
  ATTACHMENTS_DIR,
@@ -34900,6 +35093,9 @@ init_outbound_watch();
34900
35093
  addStackLayerFromThread,
34901
35094
  addWorkspace,
34902
35095
  adoptThread,
35096
+ agentDoneCustomSoundMime,
35097
+ agentDoneSound,
35098
+ agentDoneSoundsDir,
34903
35099
  agentGitPrompt,
34904
35100
  alignQueueAttachments,
34905
35101
  allAdapters,
@@ -34978,6 +35174,7 @@ init_outbound_watch();
34978
35174
  claudeUserSettingsPath,
34979
35175
  cleanupArchivedHistory,
34980
35176
  cleanupOrphanWorktrees,
35177
+ clearAgentDoneCustomSoundFile,
34981
35178
  clearBoardPins,
34982
35179
  clearHomeBoardCache,
34983
35180
  clipAgentEventForPaint,
@@ -35080,6 +35277,7 @@ init_outbound_watch();
35080
35277
  fetchOriginForWorktree,
35081
35278
  fetchPrHead,
35082
35279
  finalizeParts,
35280
+ findAgentDoneCustomSoundPath,
35083
35281
  findConventionSetup,
35084
35282
  findInvalidCacheControlTtlOrder,
35085
35283
  findLastBrightsyContextSummary,
@@ -35214,6 +35412,7 @@ init_outbound_watch();
35214
35412
  historyMaxDays,
35215
35413
  hottestClaudeWindow,
35216
35414
  httpFetch,
35415
+ importAgentDoneCustomSound,
35217
35416
  importConductorWorkspace,
35218
35417
  importConductorWorkspaceAsync,
35219
35418
  initPrStack,
@@ -35229,6 +35428,7 @@ init_outbound_watch();
35229
35428
  isAbleTimeConnected,
35230
35429
  isAbleTimeOAuthCancelled,
35231
35430
  isAbleTimeRejectedCredential,
35431
+ isAgentDoneSound,
35232
35432
  isAskUserToolName,
35233
35433
  isBrightsyConnected,
35234
35434
  isBrightsyNdjsonLine,
@@ -35420,6 +35620,7 @@ init_outbound_watch();
35420
35620
  primaryCheckoutFromLinkedWorktree,
35421
35621
  promptMentionsBrightsy,
35422
35622
  pushBranch,
35623
+ readAgentDoneCustomSound,
35423
35624
  readExistingReviewRequestFile,
35424
35625
  readKeychainVaultKey,
35425
35626
  readPlanFile,