@sideboard-ai/core 0.1.231 → 0.1.233

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 (42) hide show
  1. package/dist/agents/cursor-runner.cjs +167 -62
  2. package/dist/agents/cursor-runner.js +16 -9
  3. package/dist/{agents-ENAQHQRZ.js → agents-J2CUJHPC.js} +16 -6
  4. package/dist/{agents-TCTEAK6M.js → agents-LDYMFW6N.js} +17 -7
  5. package/dist/{chunk-TQBUXKIB.js → chunk-26T43LBM.js} +97 -11
  6. package/dist/{chunk-PO4M4JAJ.js → chunk-2P4XKWV2.js} +1 -1
  7. package/dist/{chunk-ABOBTSO6.js → chunk-2UG25RMK.js} +18 -5
  8. package/dist/{chunk-4CZ25DO2.js → chunk-4VFOJZPS.js} +2 -2
  9. package/dist/{chunk-N5TX66CD.js → chunk-7H2CVVLF.js} +2 -2
  10. package/dist/{chunk-HZLZ34FK.js → chunk-BGHDWCAV.js} +69 -30
  11. package/dist/{chunk-SZJZEFTY.js → chunk-DD67JWTN.js} +1 -1
  12. package/dist/{chunk-JJRRLCCS.js → chunk-NLETJP7Z.js} +64 -30
  13. package/dist/{chunk-FA4CPYCY.js → chunk-PZQNE5X4.js} +81 -41
  14. package/dist/{chunk-HVUVQXZ2.js → chunk-QVN2WOKJ.js} +18 -5
  15. package/dist/{chunk-HZFLKVGC.js → chunk-S2OEFXST.js} +1 -1
  16. package/dist/{chunk-SXFRXNBM.js → chunk-SPAMHHJH.js} +1 -1
  17. package/dist/{chunk-ZXJMAKEP.js → chunk-TNVJPFHM.js} +5 -5
  18. package/dist/{chunk-UNTOZA3C.js → chunk-TWXSZYR2.js} +1 -1
  19. package/dist/{chunk-6L25K7BE.js → chunk-TXMFBL3X.js} +195 -73
  20. package/dist/{connected-teams-PIBQTOJU.js → connected-teams-JUJAQZZE.js} +2 -2
  21. package/dist/{connected-teams-RVD3PFAG.js → connected-teams-KQUDU7LZ.js} +2 -2
  22. package/dist/{coordinator-prompt-YKLXQTWH.js → coordinator-prompt-CE7MN6QY.js} +4 -4
  23. package/dist/{coordinator-prompt-DFXYTM6D.js → coordinator-prompt-IGDMFKCD.js} +4 -4
  24. package/dist/{global-workspace-EYZKYHAO.js → global-workspace-7WH24UFO.js} +4 -4
  25. package/dist/{global-workspace-4SPANNJT.js → global-workspace-NCIC2Y2U.js} +4 -4
  26. package/dist/index.cjs +542 -337
  27. package/dist/index.d.cts +32 -4
  28. package/dist/index.d.ts +32 -4
  29. package/dist/index.js +31 -8
  30. package/dist/mcp/run-stdio.cjs +465 -315
  31. package/dist/mcp/run-stdio.js +7 -7
  32. package/dist/{orchestrator-ZT3SJVKF.js → orchestrator-BXALNM4M.js} +8 -8
  33. package/dist/{orchestrator-HMJPNUN5.js → orchestrator-NLZMHTLX.js} +7 -7
  34. package/dist/{run-UEQM4JMZ.js → run-PCX5QWR4.js} +1 -1
  35. package/dist/{run-QDZCTP4Y.js → run-TB7RBII2.js} +1 -1
  36. package/dist/{workspaces-73Y7IJY2.js → workspaces-H2TRFDE2.js} +4 -4
  37. package/dist/{workspaces-FQCSCTNH.js → workspaces-NSQZSDQD.js} +4 -4
  38. package/dist/{worktree-DOPRKG7K.js → worktree-FMIX4BRV.js} +3 -3
  39. package/dist/{worktree-36VEFUJN.js → worktree-W7BSI4GU.js} +3 -3
  40. package/dist/{worktree-exclude-K7QK4RI5.js → worktree-exclude-5N2KTYIT.js} +2 -2
  41. package/dist/{worktree-exclude-L32WEBX6.js → worktree-exclude-RXZPTCNH.js} +2 -2
  42. package/package.json +2 -2
@@ -2034,6 +2034,14 @@ function ensureAgentPath(env = process.env) {
2034
2034
  }
2035
2035
  function enrichPathWithNpmGlobalBin(env = process.env) {
2036
2036
  ensureAgentPath(env);
2037
+ const prefix = npmGlobalPrefix(env);
2038
+ if (prefix) {
2039
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
2040
+ prependPathDir(env, binDir);
2041
+ }
2042
+ return env.PATH ?? "";
2043
+ }
2044
+ function npmGlobalPrefix(env = process.env) {
2037
2045
  try {
2038
2046
  const prefix = (0, import_node_child_process3.execFileSync)("npm", ["prefix", "-g"], {
2039
2047
  encoding: "utf8",
@@ -2041,13 +2049,16 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
2041
2049
  timeout: 8e3,
2042
2050
  stdio: ["ignore", "pipe", "ignore"]
2043
2051
  }).trim().split(/\r?\n/).find(Boolean);
2044
- if (prefix) {
2045
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
2046
- prependPathDir(env, binDir);
2047
- }
2052
+ return prefix || null;
2048
2053
  } catch {
2054
+ return null;
2049
2055
  }
2050
- return env.PATH ?? "";
2056
+ }
2057
+ function npmGlobalNodeModules(env = process.env) {
2058
+ const prefix = npmGlobalPrefix(env);
2059
+ if (!prefix) return null;
2060
+ const dir = process.platform === "win32" ? (0, import_node_path13.join)(prefix, "node_modules") : (0, import_node_path13.join)(prefix, "lib", "node_modules");
2061
+ return (0, import_node_fs11.existsSync)(dir) ? dir : null;
2051
2062
  }
2052
2063
  var import_node_fs11, import_node_child_process3, import_node_os3, import_node_path13, EXTRA_BIN_DIRS;
2053
2064
  var init_path = __esm({
@@ -12005,6 +12016,95 @@ var init_codex = __esm({
12005
12016
  }
12006
12017
  });
12007
12018
 
12019
+ // src/agents/cursor-sdk-resolve.ts
12020
+ function thisModuleFile() {
12021
+ const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12022
+ if (cjsDir) return (0, import_node_path33.join)(cjsDir, "cursor-sdk-resolve.js");
12023
+ try {
12024
+ return (0, import_node_url2.fileURLToPath)(import_meta2.url);
12025
+ } catch {
12026
+ return (0, import_node_path33.join)(process.cwd(), "package.json");
12027
+ }
12028
+ }
12029
+ function packageRootLooksLikeSdk(dir) {
12030
+ try {
12031
+ const raw = (0, import_node_fs31.readFileSync)((0, import_node_path33.join)(dir, "package.json"), "utf8");
12032
+ const pkg = JSON.parse(raw);
12033
+ return pkg.name === "@cursor/sdk" && (0, import_node_fs31.existsSync)(dir);
12034
+ } catch {
12035
+ return false;
12036
+ }
12037
+ }
12038
+ function resolvedPackageRoot(fromFile) {
12039
+ try {
12040
+ const req = (0, import_node_module2.createRequire)(fromFile);
12041
+ const pkgJson = req.resolve("@cursor/sdk/package.json");
12042
+ const root = (0, import_node_path33.dirname)(pkgJson);
12043
+ return packageRootLooksLikeSdk(root) ? root : null;
12044
+ } catch {
12045
+ return null;
12046
+ }
12047
+ }
12048
+ function resolveCursorSdkRoot(opts) {
12049
+ const env = opts?.env ?? process.env;
12050
+ const override = env.SIDEBOARD_CURSOR_SDK?.trim();
12051
+ if (override) {
12052
+ return packageRootLooksLikeSdk(override) ? override : null;
12053
+ }
12054
+ const globalNm = npmGlobalNodeModules(env);
12055
+ if (globalNm) {
12056
+ const globalRoot = (0, import_node_path33.join)(globalNm, "@cursor/sdk");
12057
+ if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
12058
+ }
12059
+ const cwdPkg = (0, import_node_path33.join)(process.cwd(), "package.json");
12060
+ return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
12061
+ }
12062
+ function isCursorSdkInstalled(opts) {
12063
+ return Boolean(resolveCursorSdkRoot(opts));
12064
+ }
12065
+ async function importCursorSdk(opts) {
12066
+ const root = resolveCursorSdkRoot(opts);
12067
+ if (!root) return null;
12068
+ try {
12069
+ const req = (0, import_node_module2.createRequire)((0, import_node_path33.join)(root, "package.json"));
12070
+ const entry = req.resolve("@cursor/sdk");
12071
+ return await import((0, import_node_url2.pathToFileURL)(entry).href);
12072
+ } catch {
12073
+ return null;
12074
+ }
12075
+ }
12076
+ function cursorSdkPlatformRipgrepPackage() {
12077
+ return `@cursor/sdk-${process.platform}-${process.arch}`;
12078
+ }
12079
+ function nodeModulesDirForPackageRoot(packageRoot) {
12080
+ const parent = (0, import_node_path33.dirname)(packageRoot);
12081
+ return (0, import_node_path33.basename)(parent).startsWith("@") ? (0, import_node_path33.dirname)(parent) : parent;
12082
+ }
12083
+ function cursorSdkRipgrepCandidate(opts) {
12084
+ const root = resolveCursorSdkRoot(opts);
12085
+ if (!root) return null;
12086
+ const nm = nodeModulesDirForPackageRoot(root);
12087
+ const pkg = cursorSdkPlatformRipgrepPackage();
12088
+ const bin = process.platform === "win32" ? "rg.exe" : "rg";
12089
+ const sibling = (0, import_node_path33.join)(nm, pkg, "bin", bin);
12090
+ if ((0, import_node_fs31.existsSync)(sibling)) return sibling;
12091
+ const nested = (0, import_node_path33.join)(root, "node_modules", pkg, "bin", bin);
12092
+ return (0, import_node_fs31.existsSync)(nested) ? nested : null;
12093
+ }
12094
+ var import_node_fs31, import_node_module2, import_node_path33, import_node_url2, import_meta2, CURSOR_SDK_INSTALL_HINT;
12095
+ var init_cursor_sdk_resolve = __esm({
12096
+ "src/agents/cursor-sdk-resolve.ts"() {
12097
+ "use strict";
12098
+ import_node_fs31 = require("fs");
12099
+ import_node_module2 = require("module");
12100
+ import_node_path33 = require("path");
12101
+ import_node_url2 = require("url");
12102
+ init_path();
12103
+ import_meta2 = {};
12104
+ CURSOR_SDK_INSTALL_HINT = "Cursor SDK is not installed. Settings \u2192 Agents \u2192 Cursor \u2192 Install (`npm i -g @cursor/sdk`). Sideboard does not ship the SDK \u2014 update it anytime without a new Sideboard build.";
12105
+ }
12106
+ });
12107
+
12008
12108
  // src/agents/cursor-events.ts
12009
12109
  function parseCursorRunnerLine(line) {
12010
12110
  const trimmed = line.trim();
@@ -12039,21 +12139,21 @@ function platformRipgrepPackage() {
12039
12139
  }
12040
12140
  function usableRipgrepPath(candidate) {
12041
12141
  const raw = candidate?.trim();
12042
- if (!raw || !(0, import_node_path33.isAbsolute)(raw)) return null;
12142
+ if (!raw || !(0, import_node_path34.isAbsolute)(raw)) return null;
12043
12143
  const readable = nodeReadableScriptPath(raw);
12044
- if (!(0, import_node_fs31.existsSync)(readable) || isAsarPath(readable)) return null;
12144
+ if (!(0, import_node_fs32.existsSync)(readable) || isAsarPath(readable)) return null;
12045
12145
  return readable;
12046
12146
  }
12047
12147
  function walkForBundledRipgrep(startFile) {
12048
12148
  if (!startFile) return null;
12049
12149
  const pkg = platformRipgrepPackage();
12050
12150
  const name = rgBinaryName();
12051
- let dir = (0, import_node_path33.dirname)((0, import_node_path33.resolve)(startFile));
12052
- const root = (0, import_node_path33.parse)(dir).root;
12151
+ let dir = (0, import_node_path34.dirname)((0, import_node_path34.resolve)(startFile));
12152
+ const root = (0, import_node_path34.parse)(dir).root;
12053
12153
  while (dir !== root) {
12054
- const hit = usableRipgrepPath((0, import_node_path33.join)(dir, "node_modules", pkg, "bin", name));
12154
+ const hit = usableRipgrepPath((0, import_node_path34.join)(dir, "node_modules", pkg, "bin", name));
12055
12155
  if (hit) return hit;
12056
- const next = (0, import_node_path33.dirname)(dir);
12156
+ const next = (0, import_node_path34.dirname)(dir);
12057
12157
  if (next === dir) break;
12058
12158
  dir = next;
12059
12159
  }
@@ -12061,9 +12161,9 @@ function walkForBundledRipgrep(startFile) {
12061
12161
  }
12062
12162
  function requireResolveBundledRipgrep(fromFile) {
12063
12163
  try {
12064
- const req = (0, import_node_module2.createRequire)(fromFile);
12164
+ const req = (0, import_node_module3.createRequire)(fromFile);
12065
12165
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
12066
- return usableRipgrepPath((0, import_node_path33.join)((0, import_node_path33.dirname)(pkgJson), "bin", rgBinaryName()));
12166
+ return usableRipgrepPath((0, import_node_path34.join)((0, import_node_path34.dirname)(pkgJson), "bin", rgBinaryName()));
12067
12167
  } catch {
12068
12168
  return null;
12069
12169
  }
@@ -12079,19 +12179,20 @@ function resolveCursorRipgrepPath(opts) {
12079
12179
  const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
12080
12180
  // eslint-disable-next-line camelcase
12081
12181
  (typeof __filename !== "undefined" ? __filename : "");
12082
- return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
12182
+ return walkForBundledRipgrep(start) ?? usableRipgrepPath(cursorSdkRipgrepCandidate({ env })) ?? requireResolveBundledRipgrep(start);
12083
12183
  }
12084
12184
  function cursorRipgrepEnv(opts) {
12085
12185
  const path = resolveCursorRipgrepPath(opts);
12086
12186
  return path ? { [RIPGREP_ENV]: path } : {};
12087
12187
  }
12088
- var import_node_fs31, import_node_module2, import_node_path33, RIPGREP_ENV;
12188
+ var import_node_fs32, import_node_module3, import_node_path34, RIPGREP_ENV;
12089
12189
  var init_cursor_ripgrep = __esm({
12090
12190
  "src/agents/cursor-ripgrep.ts"() {
12091
12191
  "use strict";
12092
- import_node_fs31 = require("fs");
12093
- import_node_module2 = require("module");
12094
- import_node_path33 = require("path");
12192
+ import_node_fs32 = require("fs");
12193
+ import_node_module3 = require("module");
12194
+ import_node_path34 = require("path");
12195
+ init_cursor_sdk_resolve();
12095
12196
  init_node_launch();
12096
12197
  init_packaged_runtime();
12097
12198
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -12114,8 +12215,10 @@ async function listCursorModels() {
12114
12215
  }
12115
12216
  const apiKey = resolveCursorApiKey();
12116
12217
  if (!apiKey) return FALLBACK_CURSOR_MODELS;
12218
+ const sdk = await importCursorSdk();
12219
+ if (!sdk) return FALLBACK_CURSOR_MODELS;
12117
12220
  try {
12118
- const listed = await import_sdk.Cursor.models.list({ apiKey });
12221
+ const listed = await sdk.Cursor.models.list({ apiKey });
12119
12222
  const models = listed.map((m) => ({
12120
12223
  id: m.id,
12121
12224
  displayName: m.displayName || m.id,
@@ -12132,11 +12235,11 @@ function entryDir() {
12132
12235
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12133
12236
  if (cjsDir) return cjsDir;
12134
12237
  try {
12135
- return (0, import_node_path34.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12238
+ return (0, import_node_path35.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
12136
12239
  } catch {
12137
12240
  try {
12138
- const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
12139
- return (0, import_node_path34.dirname)(req.resolve("@sideboard-ai/core"));
12241
+ const req = (0, import_node_module4.createRequire)(process.cwd() + "/");
12242
+ return (0, import_node_path35.dirname)(req.resolve("@sideboard-ai/core"));
12140
12243
  } catch {
12141
12244
  return process.cwd();
12142
12245
  }
@@ -12147,32 +12250,32 @@ function cursorRunnerPath() {
12147
12250
  if (packaged) return packaged;
12148
12251
  const root = entryDir();
12149
12252
  const candidates = [
12150
- (0, import_node_path34.join)(root, "agents", "cursor-runner.js"),
12151
- (0, import_node_path34.join)(root, "agents", "cursor-runner.cjs"),
12253
+ (0, import_node_path35.join)(root, "agents", "cursor-runner.js"),
12254
+ (0, import_node_path35.join)(root, "agents", "cursor-runner.cjs"),
12152
12255
  // If somehow resolved from package root instead of dist/
12153
- (0, import_node_path34.join)(root, "dist", "agents", "cursor-runner.js"),
12154
- (0, import_node_path34.join)(root, "dist", "agents", "cursor-runner.cjs"),
12256
+ (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.js"),
12257
+ (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.cjs"),
12155
12258
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
12156
- (0, import_node_path34.join)(root, "cursor-runner.ts"),
12157
- (0, import_node_path34.join)(root, "src", "agents", "cursor-runner.ts")
12259
+ (0, import_node_path35.join)(root, "cursor-runner.ts"),
12260
+ (0, import_node_path35.join)(root, "src", "agents", "cursor-runner.ts")
12158
12261
  ];
12159
12262
  for (const candidate of candidates) {
12160
- if ((0, import_node_fs32.existsSync)(candidate)) return candidate;
12263
+ if ((0, import_node_fs33.existsSync)(candidate)) return candidate;
12161
12264
  }
12162
12265
  return candidates[0];
12163
12266
  }
12164
- var import_node_fs32, import_node_module3, import_node_path34, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12267
+ var import_node_fs33, import_node_module4, import_node_path35, import_node_url3, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12165
12268
  var init_cursor = __esm({
12166
12269
  "src/agents/cursor.ts"() {
12167
12270
  "use strict";
12168
- import_node_fs32 = require("fs");
12169
- import_node_module3 = require("module");
12170
- import_node_path34 = require("path");
12171
- import_node_url2 = require("url");
12172
- import_sdk = require("@cursor/sdk");
12271
+ import_node_fs33 = require("fs");
12272
+ import_node_module4 = require("module");
12273
+ import_node_path35 = require("path");
12274
+ import_node_url3 = require("url");
12173
12275
  init_run();
12174
12276
  init_app_settings();
12175
12277
  init_global_workspace();
12278
+ init_cursor_sdk_resolve();
12176
12279
  init_cursor_events();
12177
12280
  init_injected_mcp();
12178
12281
  init_cursor_ripgrep();
@@ -12180,7 +12283,7 @@ var init_cursor = __esm({
12180
12283
  init_packaged_runtime();
12181
12284
  init_turn_input();
12182
12285
  init_cursor_events();
12183
- import_meta2 = {};
12286
+ import_meta3 = {};
12184
12287
  FALLBACK_CURSOR_MODELS = [
12185
12288
  { id: "default", displayName: "Auto" },
12186
12289
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -12191,6 +12294,16 @@ var init_cursor = __esm({
12191
12294
  cursorAdapter = {
12192
12295
  kind: "cursor",
12193
12296
  async detect() {
12297
+ if (!isCursorSdkInstalled()) {
12298
+ return {
12299
+ agent: "cursor",
12300
+ installed: false,
12301
+ authenticated: false,
12302
+ linearMcp: false,
12303
+ warnings: [],
12304
+ reason: CURSOR_SDK_INSTALL_HINT
12305
+ };
12306
+ }
12194
12307
  const apiKey = resolveCursorApiKey();
12195
12308
  if (!apiKey) {
12196
12309
  return {
@@ -12319,7 +12432,7 @@ async function listOpencodeModels() {
12319
12432
  if (opencode === "opencode") {
12320
12433
  const which = await run("which", ["opencode"], { reject: false });
12321
12434
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
12322
- } else if (!(0, import_node_fs33.existsSync)(opencode)) {
12435
+ } else if (!(0, import_node_fs34.existsSync)(opencode)) {
12323
12436
  return FALLBACK_OPENCODE_MODELS;
12324
12437
  }
12325
12438
  const listed = await run(opencode, ["models"], { reject: false });
@@ -12349,11 +12462,11 @@ function usageFromOpencode(tokens) {
12349
12462
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
12350
12463
  };
12351
12464
  }
12352
- var import_node_fs33, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12465
+ var import_node_fs34, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12353
12466
  var init_opencode = __esm({
12354
12467
  "src/agents/opencode.ts"() {
12355
12468
  "use strict";
12356
- import_node_fs33 = require("fs");
12469
+ import_node_fs34 = require("fs");
12357
12470
  init_run();
12358
12471
  init_app_settings();
12359
12472
  init_global_workspace();
@@ -12381,7 +12494,7 @@ var init_opencode = __esm({
12381
12494
  async detect() {
12382
12495
  const opencode = resolveAgentExecutable("opencode");
12383
12496
  if (opencode !== "opencode") {
12384
- if (!(0, import_node_fs33.existsSync)(opencode)) {
12497
+ if (!(0, import_node_fs34.existsSync)(opencode)) {
12385
12498
  return {
12386
12499
  agent: "opencode",
12387
12500
  installed: false,
@@ -12868,13 +12981,13 @@ var init_claude_usage = __esm({
12868
12981
  });
12869
12982
 
12870
12983
  // src/agents/claude-usage-client.ts
12871
- var import_node_fs34, import_node_os13, import_node_path35, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
12984
+ var import_node_fs35, import_node_os13, import_node_path36, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
12872
12985
  var init_claude_usage_client = __esm({
12873
12986
  "src/agents/claude-usage-client.ts"() {
12874
12987
  "use strict";
12875
- import_node_fs34 = require("fs");
12988
+ import_node_fs35 = require("fs");
12876
12989
  import_node_os13 = require("os");
12877
- import_node_path35 = require("path");
12990
+ import_node_path36 = require("path");
12878
12991
  init_run();
12879
12992
  init_fetch();
12880
12993
  init_app_settings();
@@ -12885,9 +12998,11 @@ var init_claude_usage_client = __esm({
12885
12998
  });
12886
12999
 
12887
13000
  // src/agents/install.ts
13001
+ var import_node_fs36;
12888
13002
  var init_install = __esm({
12889
13003
  "src/agents/install.ts"() {
12890
13004
  "use strict";
13005
+ import_node_fs36 = require("fs");
12891
13006
  init_run();
12892
13007
  init_app_settings();
12893
13008
  init_path();
@@ -12922,6 +13037,7 @@ var init_agents = __esm({
12922
13037
  init_claude_usage_client();
12923
13038
  init_orchestrator_capable();
12924
13039
  init_path();
13040
+ init_cursor_sdk_resolve();
12925
13041
  init_install();
12926
13042
  adapters = {
12927
13043
  claude: claudeAdapter,
@@ -12940,7 +13056,7 @@ function isAgentHostEnvKey(key) {
12940
13056
  }
12941
13057
  function stripHostToolingPath(pathValue) {
12942
13058
  if (!pathValue?.trim()) return "";
12943
- return pathValue.split(import_node_path36.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path36.delimiter);
13059
+ return pathValue.split(import_node_path37.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path37.delimiter);
12944
13060
  }
12945
13061
  function sanitizeAgentHostEnv(env, cwd) {
12946
13062
  for (const key of Object.keys(env)) {
@@ -12954,11 +13070,11 @@ function sanitizeAgentHostEnv(env, cwd) {
12954
13070
  }
12955
13071
  return env;
12956
13072
  }
12957
- var import_node_path36, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
13073
+ var import_node_path37, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
12958
13074
  var init_agent_host_env = __esm({
12959
13075
  "src/hook/agent-host-env.ts"() {
12960
13076
  "use strict";
12961
- import_node_path36 = require("path");
13077
+ import_node_path37 = require("path");
12962
13078
  DROP_EXACT = /* @__PURE__ */ new Set([
12963
13079
  "NODE_PATH",
12964
13080
  "NODE_ENV_ELECTRON_VITE",
@@ -12997,15 +13113,15 @@ var init_agent_host_env = __esm({
12997
13113
 
12998
13114
  // src/hook/worktree-pkg-cache.ts
12999
13115
  function worktreePkgCacheRoot(worktreePath) {
13000
- return (0, import_node_path37.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13116
+ return (0, import_node_path38.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13001
13117
  }
13002
13118
  function worktreePkgCacheEnv(worktreePath) {
13003
13119
  const root = worktreePkgCacheRoot(worktreePath);
13004
- const store = (0, import_node_path37.join)(root, "pnpm-store");
13005
- const pnpmCache = (0, import_node_path37.join)(root, "pnpm");
13006
- const npmCache = (0, import_node_path37.join)(root, "npm");
13007
- const nodeGyp = (0, import_node_path37.join)(root, "node-gyp");
13008
- const electron = (0, import_node_path37.join)(root, "electron");
13120
+ const store = (0, import_node_path38.join)(root, "pnpm-store");
13121
+ const pnpmCache = (0, import_node_path38.join)(root, "pnpm");
13122
+ const npmCache = (0, import_node_path38.join)(root, "npm");
13123
+ const nodeGyp = (0, import_node_path38.join)(root, "node-gyp");
13124
+ const electron = (0, import_node_path38.join)(root, "electron");
13009
13125
  return {
13010
13126
  npm_config_store_dir: store,
13011
13127
  PNPM_STORE_DIR: store,
@@ -13027,8 +13143,8 @@ function fillGroup(env, keys, values) {
13027
13143
  }
13028
13144
  }
13029
13145
  function ensureWorktreePkgCacheDirs(worktreePath) {
13030
- if (!(0, import_node_fs35.existsSync)(worktreePath)) return;
13031
- (0, import_node_fs35.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13146
+ if (!(0, import_node_fs37.existsSync)(worktreePath)) return;
13147
+ (0, import_node_fs37.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13032
13148
  }
13033
13149
  function applyWorktreePkgCacheEnv(env, worktreePath) {
13034
13150
  const cwd = worktreePath.trim();
@@ -13041,12 +13157,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
13041
13157
  fillGroup(env, ["electron_config_cache"], next);
13042
13158
  ensureWorktreePkgCacheDirs(cwd);
13043
13159
  }
13044
- var import_node_fs35, import_node_path37, WORKTREE_PKG_CACHE_REL;
13160
+ var import_node_fs37, import_node_path38, WORKTREE_PKG_CACHE_REL;
13045
13161
  var init_worktree_pkg_cache = __esm({
13046
13162
  "src/hook/worktree-pkg-cache.ts"() {
13047
13163
  "use strict";
13048
- import_node_fs35 = require("fs");
13049
- import_node_path37 = require("path");
13164
+ import_node_fs37 = require("fs");
13165
+ import_node_path38 = require("path");
13050
13166
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
13051
13167
  }
13052
13168
  });
@@ -14244,21 +14360,21 @@ function shouldRefreshReviewRequestTemplate(content) {
14244
14360
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
14245
14361
  }
14246
14362
  function readTextIfPresent(abs) {
14247
- if (!(0, import_node_fs36.existsSync)(abs)) return null;
14363
+ if (!(0, import_node_fs38.existsSync)(abs)) return null;
14248
14364
  try {
14249
- const content = (0, import_node_fs36.readFileSync)(abs, "utf8");
14365
+ const content = (0, import_node_fs38.readFileSync)(abs, "utf8");
14250
14366
  return content.trim() ? content : null;
14251
14367
  } catch {
14252
14368
  return null;
14253
14369
  }
14254
14370
  }
14255
14371
  function readLocalGuidelines(worktreePath) {
14256
- const localAbs = (0, import_node_path38.join)(worktreePath, REVIEW_REQUEST_PATH);
14372
+ const localAbs = (0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH);
14257
14373
  const localContent = readTextIfPresent(localAbs);
14258
14374
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14259
14375
  return { path: REVIEW_REQUEST_PATH, content: localContent };
14260
14376
  }
14261
- const legacyAbs = (0, import_node_path38.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14377
+ const legacyAbs = (0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14262
14378
  const legacyContent = readTextIfPresent(legacyAbs);
14263
14379
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
14264
14380
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -14282,27 +14398,27 @@ function contextGuidelines(content, source) {
14282
14398
  };
14283
14399
  }
14284
14400
  function writeContextGuidelines(worktreePath, content) {
14285
- const abs = (0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH);
14286
- (0, import_node_fs36.mkdirSync)((0, import_node_path38.dirname)(abs), { recursive: true });
14401
+ const abs = (0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH);
14402
+ (0, import_node_fs38.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
14287
14403
  const body = content.endsWith("\n") ? content : `${content}
14288
14404
  `;
14289
- (0, import_node_fs36.writeFileSync)(abs, body, "utf8");
14405
+ (0, import_node_fs38.writeFileSync)(abs, body, "utf8");
14290
14406
  return body;
14291
14407
  }
14292
14408
  function readSideboardReview(worktreePath, repoPath) {
14293
- const fromWorktree = readTextIfPresent((0, import_node_path38.join)(worktreePath, REPO_REVIEW_PATH));
14409
+ const fromWorktree = readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH));
14294
14410
  if (fromWorktree) return fromWorktree;
14295
14411
  const repo = repoPath?.replace(/\/+$/, "");
14296
14412
  const wt = worktreePath.replace(/\/+$/, "");
14297
14413
  if (!repo || repo === wt) return null;
14298
- return readTextIfPresent((0, import_node_path38.join)(repo, REPO_REVIEW_PATH));
14414
+ return readTextIfPresent((0, import_node_path39.join)(repo, REPO_REVIEW_PATH));
14299
14415
  }
14300
14416
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
14301
- const skillContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_SKILL_PATH));
14417
+ const skillContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH));
14302
14418
  if (skillContent) {
14303
14419
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
14304
14420
  }
14305
- const contextContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH));
14421
+ const contextContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH));
14306
14422
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
14307
14423
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
14308
14424
  }
@@ -14357,13 +14473,13 @@ async function requestReview(threadRef, send) {
14357
14473
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
14358
14474
  return { tab: started, from };
14359
14475
  }
14360
- var import_node_crypto7, import_node_fs36, import_node_path38, 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;
14476
+ var import_node_crypto7, import_node_fs38, import_node_path39, 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;
14361
14477
  var init_request_review = __esm({
14362
14478
  "src/review/request-review.ts"() {
14363
14479
  "use strict";
14364
14480
  import_node_crypto7 = require("crypto");
14365
- import_node_fs36 = require("fs");
14366
- import_node_path38 = require("path");
14481
+ import_node_fs38 = require("fs");
14482
+ import_node_path39 = require("path");
14367
14483
  init_global_workspace();
14368
14484
  init_chat_tabs();
14369
14485
  init_thread_store();
@@ -14389,9 +14505,9 @@ function matchSimpleGlob(pattern, name) {
14389
14505
  return new RegExp(`^${escaped}$`).test(name);
14390
14506
  }
14391
14507
  function readWorktreeInclude(repoPath) {
14392
- const path = (0, import_node_path39.join)(repoPath, ".worktreeinclude");
14393
- if (!(0, import_node_fs37.existsSync)(path)) return [];
14394
- return (0, import_node_fs37.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14508
+ const path = (0, import_node_path40.join)(repoPath, ".worktreeinclude");
14509
+ if (!(0, import_node_fs39.existsSync)(path)) return [];
14510
+ return (0, import_node_fs39.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14395
14511
  }
14396
14512
  function resolveFilesToCopy(repoPath) {
14397
14513
  const fromInclude = readWorktreeInclude(repoPath);
@@ -14401,10 +14517,10 @@ function resolveFilesToCopy(repoPath) {
14401
14517
  if (settings?.fileIncludeGlobs?.length) {
14402
14518
  const matched = [];
14403
14519
  try {
14404
- for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
14520
+ for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
14405
14521
  if (!entry.isFile()) continue;
14406
14522
  for (const glob of settings.fileIncludeGlobs) {
14407
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path39.basename)(glob), entry.name)) {
14523
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path40.basename)(glob), entry.name)) {
14408
14524
  matched.push(entry.name);
14409
14525
  break;
14410
14526
  }
@@ -14416,7 +14532,7 @@ function resolveFilesToCopy(repoPath) {
14416
14532
  }
14417
14533
  const defaults = [];
14418
14534
  try {
14419
- for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
14535
+ for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
14420
14536
  if (entry.isFile() && entry.name.startsWith(".env")) {
14421
14537
  defaults.push(entry.name);
14422
14538
  }
@@ -14430,11 +14546,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
14430
14546
  const patterns = resolveFilesToCopy(repoPath);
14431
14547
  const copied = [];
14432
14548
  for (const rel of patterns) {
14433
- const src = (0, import_node_path39.join)(repoPath, rel);
14434
- if (!(0, import_node_fs37.existsSync)(src)) continue;
14435
- const dest = (0, import_node_path39.join)(worktreePath, rel);
14436
- (0, import_node_fs37.mkdirSync)((0, import_node_path39.dirname)(dest), { recursive: true });
14437
- (0, import_node_fs37.copyFileSync)(src, dest);
14549
+ const src = (0, import_node_path40.join)(repoPath, rel);
14550
+ if (!(0, import_node_fs39.existsSync)(src)) continue;
14551
+ const dest = (0, import_node_path40.join)(worktreePath, rel);
14552
+ (0, import_node_fs39.mkdirSync)((0, import_node_path40.dirname)(dest), { recursive: true });
14553
+ (0, import_node_fs39.copyFileSync)(src, dest);
14438
14554
  copied.push(rel);
14439
14555
  }
14440
14556
  return copied;
@@ -14469,7 +14585,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
14469
14585
  const env = stripNestedElectronEnv({
14470
14586
  ...baseEnv ?? process.env
14471
14587
  });
14472
- const name = opts.workspaceName ?? (0, import_node_path39.basename)(opts.worktreePath);
14588
+ const name = opts.workspaceName ?? (0, import_node_path40.basename)(opts.worktreePath);
14473
14589
  const ports = opts.ports ?? [];
14474
14590
  const primary = ports[0];
14475
14591
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -14500,7 +14616,17 @@ function pipeLines(stream, onLine) {
14500
14616
  const rl = (0, import_node_readline3.createInterface)({ input: stream });
14501
14617
  rl.on("line", onLine);
14502
14618
  }
14619
+ function killableListenerPids(raw, selfPid = process.pid) {
14620
+ const pids = [];
14621
+ for (const token of raw.trim().split(/\s+/)) {
14622
+ const pid = Number(token);
14623
+ if (!Number.isFinite(pid) || pid <= 0 || pid === selfPid) continue;
14624
+ pids.push(pid);
14625
+ }
14626
+ return pids;
14627
+ }
14503
14628
  function killListenersOnPorts(ports) {
14629
+ const selfPid = process.pid;
14504
14630
  for (const port of ports) {
14505
14631
  if (!Number.isFinite(port) || port <= 0) continue;
14506
14632
  try {
@@ -14510,7 +14636,7 @@ function killListenersOnPorts(ports) {
14510
14636
  [
14511
14637
  "-NoProfile",
14512
14638
  "-Command",
14513
- `Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
14639
+ `Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | Where-Object { $_.OwningProcess -ne ${selfPid} } | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
14514
14640
  ],
14515
14641
  { stdio: "ignore", timeout: 3e3 }
14516
14642
  );
@@ -14526,9 +14652,7 @@ function killListenersOnPorts(ports) {
14526
14652
  } catch {
14527
14653
  continue;
14528
14654
  }
14529
- for (const token of raw.trim().split(/\s+/)) {
14530
- const pid = Number(token);
14531
- if (!Number.isFinite(pid) || pid <= 0) continue;
14655
+ for (const pid of killableListenerPids(raw, selfPid)) {
14532
14656
  try {
14533
14657
  process.kill(pid, "SIGTERM");
14534
14658
  } catch {
@@ -14581,6 +14705,9 @@ async function spawnWorkspaceScript(command, opts) {
14581
14705
  );
14582
14706
  } catch {
14583
14707
  }
14708
+ if (opts.heldPorts?.length) {
14709
+ await Promise.all(opts.heldPorts.map((h) => h.release()));
14710
+ }
14584
14711
  const shell = process.platform === "darwin" ? "zsh" : "bash";
14585
14712
  const child = (0, import_execa4.execa)(shell, ["-lc", command], {
14586
14713
  cwd: opts.worktreePath,
@@ -14761,11 +14888,11 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
14761
14888
  const held = await reservePortRange(PORT_RANGE_SIZE);
14762
14889
  const ports = held.map((h) => h.port);
14763
14890
  try {
14764
- await Promise.all(held.map((h) => h.release()));
14765
14891
  const handle = await spawnWorkspaceScript(script.command, {
14766
14892
  worktreePath,
14767
14893
  repoPath,
14768
14894
  ports,
14895
+ heldPorts: held,
14769
14896
  defaultBranch: opts?.defaultBranch,
14770
14897
  onLine
14771
14898
  });
@@ -14782,14 +14909,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
14782
14909
  throw err;
14783
14910
  }
14784
14911
  }
14785
- var import_node_fs37, import_node_child_process4, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
14912
+ var import_node_fs39, import_node_child_process4, import_node_net, import_node_path40, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
14786
14913
  var init_conductor = __esm({
14787
14914
  "src/hook/conductor.ts"() {
14788
14915
  "use strict";
14789
- import_node_fs37 = require("fs");
14916
+ import_node_fs39 = require("fs");
14790
14917
  import_node_child_process4 = require("child_process");
14791
14918
  import_node_net = require("net");
14792
- import_node_path39 = require("path");
14919
+ import_node_path40 = require("path");
14793
14920
  import_execa4 = require("execa");
14794
14921
  import_node_readline3 = require("readline");
14795
14922
  init_settings();
@@ -14839,7 +14966,7 @@ function materialize(mem) {
14839
14966
  };
14840
14967
  }
14841
14968
  function setupLogPath(threadId) {
14842
- return (0, import_node_path40.join)(threadsDir(), `${threadId}.setup.log.json`);
14969
+ return (0, import_node_path41.join)(threadsDir(), `${threadId}.setup.log.json`);
14843
14970
  }
14844
14971
  function setupLogKeyForWorktree(worktreePath) {
14845
14972
  const norm = normalizeWorktreePath(worktreePath);
@@ -14857,7 +14984,7 @@ function persistNow(threadId) {
14857
14984
  const mem = memory.get(threadId);
14858
14985
  if (!mem) return;
14859
14986
  try {
14860
- (0, import_node_fs38.writeFileSync)(
14987
+ (0, import_node_fs40.writeFileSync)(
14861
14988
  setupLogPath(threadId),
14862
14989
  `${JSON.stringify(materialize(mem))}
14863
14990
  `,
@@ -14878,9 +15005,9 @@ function schedulePersist(threadId) {
14878
15005
  }
14879
15006
  function loadFromDisk(threadId) {
14880
15007
  const path = setupLogPath(threadId);
14881
- if (!(0, import_node_fs38.existsSync)(path)) return null;
15008
+ if (!(0, import_node_fs40.existsSync)(path)) return null;
14882
15009
  try {
14883
- const raw = JSON.parse((0, import_node_fs38.readFileSync)(path, "utf8"));
15010
+ const raw = JSON.parse((0, import_node_fs40.readFileSync)(path, "utf8"));
14884
15011
  return {
14885
15012
  output: typeof raw.output === "string" ? raw.output : "",
14886
15013
  running: Boolean(raw.running),
@@ -14936,13 +15063,13 @@ function finishSetupLog(threadId, exitCode, source) {
14936
15063
  persistNow(threadId);
14937
15064
  return materialize(mem);
14938
15065
  }
14939
- var import_node_crypto8, import_node_fs38, import_node_path40, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
15066
+ var import_node_crypto8, import_node_fs40, import_node_path41, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
14940
15067
  var init_setup_log = __esm({
14941
15068
  "src/store/setup-log.ts"() {
14942
15069
  "use strict";
14943
15070
  import_node_crypto8 = require("crypto");
14944
- import_node_fs38 = require("fs");
14945
- import_node_path40 = require("path");
15071
+ import_node_fs40 = require("fs");
15072
+ import_node_path41 = require("path");
14946
15073
  init_worktree_labels();
14947
15074
  init_paths();
14948
15075
  EMPTY = {
@@ -14969,9 +15096,9 @@ async function findOrphanWorktrees(repoPaths) {
14969
15096
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
14970
15097
  );
14971
15098
  const homeRoot = sideboardWorkspacesDir();
14972
- if ((0, import_node_fs39.existsSync)(homeRoot)) {
15099
+ if ((0, import_node_fs41.existsSync)(homeRoot)) {
14973
15100
  try {
14974
- for (const entry of (0, import_node_fs39.readdirSync)(homeRoot, { withFileTypes: true })) {
15101
+ for (const entry of (0, import_node_fs41.readdirSync)(homeRoot, { withFileTypes: true })) {
14975
15102
  if (!entry.isDirectory()) continue;
14976
15103
  void entry;
14977
15104
  }
@@ -14981,7 +15108,7 @@ async function findOrphanWorktrees(repoPaths) {
14981
15108
  const orphans = [];
14982
15109
  const seen = /* @__PURE__ */ new Set();
14983
15110
  for (const repoPath of repos) {
14984
- if (!repoPath || !(0, import_node_fs39.existsSync)(repoPath)) continue;
15111
+ if (!repoPath || !(0, import_node_fs41.existsSync)(repoPath)) continue;
14985
15112
  try {
14986
15113
  const wts = await listWorktrees(repoPath);
14987
15114
  for (const wt of wts) {
@@ -14992,7 +15119,7 @@ async function findOrphanWorktrees(repoPaths) {
14992
15119
  seen.add(path);
14993
15120
  let mtimeMs = 0;
14994
15121
  try {
14995
- mtimeMs = (0, import_node_fs39.statSync)(path).mtimeMs;
15122
+ mtimeMs = (0, import_node_fs41.statSync)(path).mtimeMs;
14996
15123
  } catch {
14997
15124
  mtimeMs = 0;
14998
15125
  }
@@ -15002,16 +15129,16 @@ async function findOrphanWorktrees(repoPaths) {
15002
15129
  }
15003
15130
  try {
15004
15131
  const root = worktreesRoot(repoPath);
15005
- if ((0, import_node_fs39.existsSync)(root)) {
15006
- for (const entry of (0, import_node_fs39.readdirSync)(root, { withFileTypes: true })) {
15132
+ if ((0, import_node_fs41.existsSync)(root)) {
15133
+ for (const entry of (0, import_node_fs41.readdirSync)(root, { withFileTypes: true })) {
15007
15134
  if (!entry.isDirectory()) continue;
15008
- const path = (0, import_node_path41.join)(root, entry.name).replace(/\/$/, "");
15135
+ const path = (0, import_node_path42.join)(root, entry.name).replace(/\/$/, "");
15009
15136
  if (known.has(path) || seen.has(path)) continue;
15010
- if (!(0, import_node_fs39.existsSync)((0, import_node_path41.join)(path, ".git"))) continue;
15137
+ if (!(0, import_node_fs41.existsSync)((0, import_node_path42.join)(path, ".git"))) continue;
15011
15138
  seen.add(path);
15012
15139
  let mtimeMs = 0;
15013
15140
  try {
15014
- mtimeMs = (0, import_node_fs39.statSync)(path).mtimeMs;
15141
+ mtimeMs = (0, import_node_fs41.statSync)(path).mtimeMs;
15015
15142
  } catch {
15016
15143
  mtimeMs = Date.now();
15017
15144
  }
@@ -15063,12 +15190,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
15063
15190
  const elapsed = Date.now() - Date.parse(last);
15064
15191
  return elapsed >= intervalHours * 36e5;
15065
15192
  }
15066
- var import_node_fs39, import_node_path41;
15193
+ var import_node_fs41, import_node_path42;
15067
15194
  var init_orphan_cleanup = __esm({
15068
15195
  "src/git/orphan-cleanup.ts"() {
15069
15196
  "use strict";
15070
- import_node_fs39 = require("fs");
15071
- import_node_path41 = require("path");
15197
+ import_node_fs41 = require("fs");
15198
+ import_node_path42 = require("path");
15072
15199
  init_worktree();
15073
15200
  init_thread_store();
15074
15201
  init_paths();
@@ -15243,12 +15370,12 @@ async function cloneRepoIntoSideboard(opts) {
15243
15370
  if (!url) throw new Error("Clone URL is required");
15244
15371
  let name = opts.name?.trim();
15245
15372
  if (!name) {
15246
- const leaf = (0, import_node_path42.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15373
+ const leaf = (0, import_node_path43.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15247
15374
  name = leaf || "repo";
15248
15375
  }
15249
15376
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
15250
- const dest = (0, import_node_path42.join)(sideboardReposDir(), name);
15251
- if ((0, import_node_fs40.existsSync)(dest)) {
15377
+ const dest = (0, import_node_path43.join)(sideboardReposDir(), name);
15378
+ if ((0, import_node_fs42.existsSync)(dest)) {
15252
15379
  const repoPath2 = await resolveRepoRoot(dest);
15253
15380
  const workspace2 = await ensureWorkspace(repoPath2);
15254
15381
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -15263,12 +15390,12 @@ async function cloneRepoIntoSideboard(opts) {
15263
15390
  const workspace = await ensureWorkspace(repoPath);
15264
15391
  return { repoPath, workspace };
15265
15392
  }
15266
- var import_node_fs40, import_node_path42, import_execa6;
15393
+ var import_node_fs42, import_node_path43, import_execa6;
15267
15394
  var init_clone_repo = __esm({
15268
15395
  "src/git/clone-repo.ts"() {
15269
15396
  "use strict";
15270
- import_node_fs40 = require("fs");
15271
- import_node_path42 = require("path");
15397
+ import_node_fs42 = require("fs");
15398
+ import_node_path43 = require("path");
15272
15399
  import_execa6 = require("execa");
15273
15400
  init_paths();
15274
15401
  init_workspaces2();
@@ -15277,8 +15404,8 @@ var init_clone_repo = __esm({
15277
15404
  });
15278
15405
 
15279
15406
  // src/types/thread.ts
15280
- function isUnclaimedRunScriptRequest(req) {
15281
- return Boolean(req && !req.claimedAt && !req.fulfilledAt && !req.error);
15407
+ function isAdoptableRunScriptRequest(req) {
15408
+ return Boolean(req && !req.fulfilledAt && !req.error);
15282
15409
  }
15283
15410
  var init_thread = __esm({
15284
15411
  "src/types/thread.ts"() {
@@ -15288,11 +15415,11 @@ var init_thread = __esm({
15288
15415
 
15289
15416
  // src/store/desktop-host.ts
15290
15417
  function desktopHostPidPath() {
15291
- return (0, import_node_path43.join)(appDataDir(), "desktop-host.pid");
15418
+ return (0, import_node_path44.join)(appDataDir(), "desktop-host.pid");
15292
15419
  }
15293
15420
  function readDesktopHostPid() {
15294
15421
  try {
15295
- const pid = Number.parseInt((0, import_node_fs41.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
15422
+ const pid = Number.parseInt((0, import_node_fs43.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
15296
15423
  if (!Number.isFinite(pid) || pid <= 0) return null;
15297
15424
  return pid;
15298
15425
  } catch {
@@ -15318,12 +15445,12 @@ function thisProcessShouldDrainAgentQueues() {
15318
15445
  if (isThisProcessDesktopHost()) return true;
15319
15446
  return !isDesktopHostAlive();
15320
15447
  }
15321
- var import_node_fs41, import_node_path43;
15448
+ var import_node_fs43, import_node_path44;
15322
15449
  var init_desktop_host = __esm({
15323
15450
  "src/store/desktop-host.ts"() {
15324
15451
  "use strict";
15325
- import_node_fs41 = require("fs");
15326
- import_node_path43 = require("path");
15452
+ import_node_fs43 = require("fs");
15453
+ import_node_path44 = require("path");
15327
15454
  init_paths();
15328
15455
  }
15329
15456
  });
@@ -15441,24 +15568,24 @@ function jobTreeAlive(pid) {
15441
15568
  return jobAlive(pid) || processGroupAlive(pid);
15442
15569
  }
15443
15570
  function readIntFile(file) {
15444
- if (!(0, import_node_fs42.existsSync)(file)) return null;
15445
- const n = Number.parseInt((0, import_node_fs42.readFileSync)(file, "utf8").trim(), 10);
15571
+ if (!(0, import_node_fs44.existsSync)(file)) return null;
15572
+ const n = Number.parseInt((0, import_node_fs44.readFileSync)(file, "utf8").trim(), 10);
15446
15573
  return Number.isInteger(n) ? n : null;
15447
15574
  }
15448
15575
  function jobDir(root, id, legacy = false) {
15449
- return (0, import_node_path44.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15576
+ return (0, import_node_path45.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15450
15577
  }
15451
15578
  function resolveJobDir(root, id) {
15452
15579
  const modern = jobDir(root, id, false);
15453
- if ((0, import_node_fs42.existsSync)(modern)) return modern;
15580
+ if ((0, import_node_fs44.existsSync)(modern)) return modern;
15454
15581
  const legacy = jobDir(root, id, true);
15455
- if ((0, import_node_fs42.existsSync)(legacy)) return legacy;
15582
+ if ((0, import_node_fs44.existsSync)(legacy)) return legacy;
15456
15583
  return modern;
15457
15584
  }
15458
15585
  function listJobIdsIn(root, rel) {
15459
- const dir = (0, import_node_path44.join)(root, rel);
15460
- if (!(0, import_node_fs42.existsSync)(dir)) return [];
15461
- return (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15586
+ const dir = (0, import_node_path45.join)(root, rel);
15587
+ if (!(0, import_node_fs44.existsSync)(dir)) return [];
15588
+ return (0, import_node_fs44.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15462
15589
  }
15463
15590
  function listRunningDetachedJobs(worktreePath) {
15464
15591
  const root = worktreePath.trim();
@@ -15470,7 +15597,7 @@ function listRunningDetachedJobs(worktreePath) {
15470
15597
  const running = [];
15471
15598
  for (const id of ids) {
15472
15599
  const dir = resolveJobDir(root, id);
15473
- const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
15600
+ const pid = readIntFile((0, import_node_path45.join)(dir, "pid"));
15474
15601
  if (jobTreeAlive(pid)) running.push(id);
15475
15602
  }
15476
15603
  return running.sort();
@@ -15553,8 +15680,8 @@ function planJobContinue(opts) {
15553
15680
  return { action: "none" };
15554
15681
  }
15555
15682
  function tailProgress(logFile, maxLines = 12) {
15556
- if (!(0, import_node_fs42.existsSync)(logFile)) return "(no log yet)";
15557
- const lines = (0, import_node_fs42.readFileSync)(logFile, "utf8").split("\n");
15683
+ if (!(0, import_node_fs44.existsSync)(logFile)) return "(no log yet)";
15684
+ const lines = (0, import_node_fs44.readFileSync)(logFile, "utf8").split("\n");
15558
15685
  return lines.slice(-maxLines).join("\n");
15559
15686
  }
15560
15687
  function lastProgressLine(progress) {
@@ -15562,8 +15689,8 @@ function lastProgressLine(progress) {
15562
15689
  return last ? last.slice(0, 72) : void 0;
15563
15690
  }
15564
15691
  function readLogLines(file) {
15565
- if (!(0, import_node_fs42.existsSync)(file)) return [];
15566
- const lines = (0, import_node_fs42.readFileSync)(file, "utf8").split("\n");
15692
+ if (!(0, import_node_fs44.existsSync)(file)) return [];
15693
+ const lines = (0, import_node_fs44.readFileSync)(file, "utf8").split("\n");
15567
15694
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
15568
15695
  return lines;
15569
15696
  }
@@ -15574,15 +15701,15 @@ function takeDelta(logFile, cursorFile) {
15574
15701
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
15575
15702
  }
15576
15703
  function snapshotJob(dir) {
15577
- const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
15704
+ const pid = readIntFile((0, import_node_path45.join)(dir, "pid"));
15578
15705
  const running = jobTreeAlive(pid);
15579
15706
  return {
15580
15707
  pid,
15581
15708
  running,
15582
- exitCode: readIntFile((0, import_node_path44.join)(dir, "exit")),
15583
- log: (0, import_node_path44.join)(dir, "log"),
15584
- cursor: (0, import_node_path44.join)(dir, "present.cursor"),
15585
- progress: tailProgress((0, import_node_path44.join)(dir, "log"))
15709
+ exitCode: readIntFile((0, import_node_path45.join)(dir, "exit")),
15710
+ log: (0, import_node_path45.join)(dir, "log"),
15711
+ cursor: (0, import_node_path45.join)(dir, "present.cursor"),
15712
+ progress: tailProgress((0, import_node_path45.join)(dir, "log"))
15586
15713
  };
15587
15714
  }
15588
15715
  function toResult(id, snap, extra) {
@@ -15591,8 +15718,8 @@ function toResult(id, snap, extra) {
15591
15718
  const stillRunning = snap.running && !ok;
15592
15719
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
15593
15720
  try {
15594
- (0, import_node_fs42.mkdirSync)((0, import_node_path44.dirname)(snap.cursor), { recursive: true });
15595
- (0, import_node_fs42.writeFileSync)(snap.cursor, `${nextCursor}
15721
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(snap.cursor), { recursive: true });
15722
+ (0, import_node_fs44.writeFileSync)(snap.cursor, `${nextCursor}
15596
15723
  `);
15597
15724
  } catch {
15598
15725
  }
@@ -15621,7 +15748,7 @@ async function waitForDetachedJob(cwd, id, opts) {
15621
15748
  const dir = resolveJobDir(root, jobId);
15622
15749
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
15623
15750
  const sleep = opts?.sleep ?? sleepMs;
15624
- if (!(0, import_node_fs42.existsSync)(dir)) {
15751
+ if (!(0, import_node_fs44.existsSync)(dir)) {
15625
15752
  return {
15626
15753
  stillRunning: false,
15627
15754
  ok: false,
@@ -15667,10 +15794,10 @@ function killProcessTree(pid, signal) {
15667
15794
  }
15668
15795
  function appendJobLog(logFile, line) {
15669
15796
  try {
15670
- (0, import_node_fs42.mkdirSync)((0, import_node_path44.dirname)(logFile), { recursive: true });
15797
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(logFile), { recursive: true });
15671
15798
  const body = line.endsWith("\n") ? line : `${line}
15672
15799
  `;
15673
- (0, import_node_fs42.appendFileSync)(logFile, body);
15800
+ (0, import_node_fs44.appendFileSync)(logFile, body);
15674
15801
  } catch {
15675
15802
  }
15676
15803
  }
@@ -15680,7 +15807,7 @@ async function stopDetachedJob(cwd, id, opts) {
15680
15807
  const dir = resolveJobDir(root, jobId);
15681
15808
  const sleep = opts?.sleep ?? sleepMs;
15682
15809
  const why = opts?.reason?.trim() ?? "";
15683
- if (!(0, import_node_fs42.existsSync)(dir)) {
15810
+ if (!(0, import_node_fs44.existsSync)(dir)) {
15684
15811
  return {
15685
15812
  stillRunning: false,
15686
15813
  ok: false,
@@ -15716,10 +15843,10 @@ async function stopDetachedJob(cwd, id, opts) {
15716
15843
  killProcessTree(targetPid, "SIGKILL");
15717
15844
  await sleep(100);
15718
15845
  }
15719
- const exitFile = (0, import_node_path44.join)(dir, "exit");
15720
- if (!(0, import_node_fs42.existsSync)(exitFile)) {
15846
+ const exitFile = (0, import_node_path45.join)(dir, "exit");
15847
+ if (!(0, import_node_fs44.existsSync)(exitFile)) {
15721
15848
  try {
15722
- (0, import_node_fs42.writeFileSync)(exitFile, "1\n");
15849
+ (0, import_node_fs44.writeFileSync)(exitFile, "1\n");
15723
15850
  } catch {
15724
15851
  }
15725
15852
  }
@@ -15739,12 +15866,12 @@ async function stopDetachedJob(cwd, id, opts) {
15739
15866
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
15740
15867
  };
15741
15868
  }
15742
- var import_node_fs42, import_node_path44, 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;
15869
+ var import_node_fs44, import_node_path45, 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;
15743
15870
  var init_wait_for_job = __esm({
15744
15871
  "src/mcp/wait-for-job.ts"() {
15745
15872
  "use strict";
15746
- import_node_fs42 = require("fs");
15747
- import_node_path44 = require("path");
15873
+ import_node_fs44 = require("fs");
15874
+ import_node_path45 = require("path");
15748
15875
  init_workspace_scratch();
15749
15876
  init_wait_for_turn();
15750
15877
  MAX_JOB_CONTINUES = 8;
@@ -17779,7 +17906,7 @@ function reuseLiveThread(input, repoPath, match) {
17779
17906
  }
17780
17907
  async function createThread(input, _onSetupLine) {
17781
17908
  const repoPath = await resolveRepoRoot(input.repoPath);
17782
- if (!(0, import_node_fs43.existsSync)(repoPath)) {
17909
+ if (!(0, import_node_fs45.existsSync)(repoPath)) {
17783
17910
  throw new Error(`Repo not found: ${repoPath}`);
17784
17911
  }
17785
17912
  const reused = reuseLiveThread(input, repoPath, {
@@ -17955,11 +18082,11 @@ async function createThread(input, _onSetupLine) {
17955
18082
  await ensureWorkspace(repoPath);
17956
18083
  return readThread(thread.id) ?? thread;
17957
18084
  }
17958
- var import_node_fs43;
18085
+ var import_node_fs45;
17959
18086
  var init_create = __esm({
17960
18087
  "src/threads/create.ts"() {
17961
18088
  "use strict";
17962
- import_node_fs43 = require("fs");
18089
+ import_node_fs45 = require("fs");
17963
18090
  init_detect();
17964
18091
  init_worktree();
17965
18092
  init_home_board();
@@ -18111,20 +18238,20 @@ function writeTurnLive(threadId, progress) {
18111
18238
  const path = threadLivePath(threadId);
18112
18239
  const tmp = `${path}.${process.pid}.tmp`;
18113
18240
  try {
18114
- (0, import_node_fs44.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
18115
- (0, import_node_fs44.renameSync)(tmp, path);
18241
+ (0, import_node_fs46.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
18242
+ (0, import_node_fs46.renameSync)(tmp, path);
18116
18243
  } catch {
18117
18244
  try {
18118
- (0, import_node_fs44.unlinkSync)(tmp);
18245
+ (0, import_node_fs46.unlinkSync)(tmp);
18119
18246
  } catch {
18120
18247
  }
18121
18248
  }
18122
18249
  }
18123
18250
  function readTurnLive(threadId) {
18124
18251
  const path = threadLivePath(threadId);
18125
- if (!(0, import_node_fs44.existsSync)(path)) return null;
18252
+ if (!(0, import_node_fs46.existsSync)(path)) return null;
18126
18253
  try {
18127
- const raw = JSON.parse((0, import_node_fs44.readFileSync)(path, "utf8"));
18254
+ const raw = JSON.parse((0, import_node_fs46.readFileSync)(path, "utf8"));
18128
18255
  if (!raw || typeof raw.summary !== "string") return null;
18129
18256
  return raw;
18130
18257
  } catch {
@@ -18136,17 +18263,17 @@ function clearTurnLive(threadId) {
18136
18263
  if (buf?.timer) clearTimeout(buf.timer);
18137
18264
  buffers.delete(threadId);
18138
18265
  const path = threadLivePath(threadId);
18139
- if (!(0, import_node_fs44.existsSync)(path)) return;
18266
+ if (!(0, import_node_fs46.existsSync)(path)) return;
18140
18267
  try {
18141
- (0, import_node_fs44.unlinkSync)(path);
18268
+ (0, import_node_fs46.unlinkSync)(path);
18142
18269
  } catch {
18143
18270
  }
18144
18271
  }
18145
- var import_node_fs44, buffers, FLUSH_MS, MAX_PARTS;
18272
+ var import_node_fs46, buffers, FLUSH_MS, MAX_PARTS;
18146
18273
  var init_turn_live = __esm({
18147
18274
  "src/store/turn-live.ts"() {
18148
18275
  "use strict";
18149
- import_node_fs44 = require("fs");
18276
+ import_node_fs46 = require("fs");
18150
18277
  init_message_parts();
18151
18278
  init_paths();
18152
18279
  buffers = /* @__PURE__ */ new Map();
@@ -18385,12 +18512,12 @@ var init_quota_failover = __esm({
18385
18512
  });
18386
18513
 
18387
18514
  // src/threads/adopt.ts
18388
- function thisModuleFile() {
18515
+ function thisModuleFile2() {
18389
18516
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
18390
- return cjsFile || process.argv[1] || (0, import_node_path45.join)(process.cwd(), "package.json");
18517
+ return cjsFile || process.argv[1] || (0, import_node_path46.join)(process.cwd(), "package.json");
18391
18518
  }
18392
18519
  function openReadonlySqlite(file) {
18393
- const req = (0, import_node_module4.createRequire)(thisModuleFile());
18520
+ const req = (0, import_node_module5.createRequire)(thisModuleFile2());
18394
18521
  const Database = req("better-sqlite3");
18395
18522
  return new Database(file, { readonly: true, fileMustExist: true });
18396
18523
  }
@@ -18405,21 +18532,21 @@ function mapAgentType(raw) {
18405
18532
  return null;
18406
18533
  }
18407
18534
  function resolveConductorCursorAgentId(workspacePath) {
18408
- if (!workspacePath || !(0, import_node_fs45.existsSync)(CURSOR_SDK_STORE)) return null;
18535
+ if (!workspacePath || !(0, import_node_fs47.existsSync)(CURSOR_SDK_STORE)) return null;
18409
18536
  const normalized = workspacePath.replace(/\/$/, "");
18410
18537
  let best = null;
18411
18538
  let hashes;
18412
18539
  try {
18413
- hashes = (0, import_node_fs45.readdirSync)(CURSOR_SDK_STORE);
18540
+ hashes = (0, import_node_fs47.readdirSync)(CURSOR_SDK_STORE);
18414
18541
  } catch {
18415
18542
  return null;
18416
18543
  }
18417
18544
  for (const hash of hashes) {
18418
- const agentsFile = (0, import_node_path45.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
18419
- if (!(0, import_node_fs45.existsSync)(agentsFile)) continue;
18545
+ const agentsFile = (0, import_node_path46.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
18546
+ if (!(0, import_node_fs47.existsSync)(agentsFile)) continue;
18420
18547
  let text7;
18421
18548
  try {
18422
- text7 = (0, import_node_fs45.readFileSync)(agentsFile, "utf8");
18549
+ text7 = (0, import_node_fs47.readFileSync)(agentsFile, "utf8");
18423
18550
  } catch {
18424
18551
  continue;
18425
18552
  }
@@ -18443,7 +18570,7 @@ function resolveConductorCursorAgentId(workspacePath) {
18443
18570
  return best?.agentId ?? null;
18444
18571
  }
18445
18572
  async function adoptThread(input) {
18446
- if (!(0, import_node_fs45.existsSync)(input.worktreePath)) {
18573
+ if (!(0, import_node_fs47.existsSync)(input.worktreePath)) {
18447
18574
  throw new Error(`Worktree not found: ${input.worktreePath}`);
18448
18575
  }
18449
18576
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -18469,18 +18596,18 @@ async function adoptThread(input) {
18469
18596
  return thread;
18470
18597
  }
18471
18598
  function listConductorWorkspaces() {
18472
- if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
18599
+ if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
18473
18600
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
18474
18601
  }
18475
- const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18476
- const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
18602
+ const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path46.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18603
+ const snapshot = (0, import_node_path46.join)(tmp, "conductor.db");
18477
18604
  try {
18478
- (0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
18605
+ (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
18479
18606
  for (const suffix of ["-wal", "-shm"]) {
18480
18607
  const src = `${CONDUCTOR_DB}${suffix}`;
18481
- if ((0, import_node_fs45.existsSync)(src)) {
18608
+ if ((0, import_node_fs47.existsSync)(src)) {
18482
18609
  try {
18483
- (0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
18610
+ (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
18484
18611
  } catch {
18485
18612
  }
18486
18613
  }
@@ -18556,22 +18683,22 @@ function listConductorWorkspaces() {
18556
18683
  db.close();
18557
18684
  }
18558
18685
  } finally {
18559
- (0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
18686
+ (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
18560
18687
  }
18561
18688
  }
18562
18689
  function importConductorWorkspace(workspaceId) {
18563
- if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
18690
+ if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
18564
18691
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
18565
18692
  }
18566
- const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18567
- const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
18693
+ const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path46.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18694
+ const snapshot = (0, import_node_path46.join)(tmp, "conductor.db");
18568
18695
  try {
18569
- (0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
18696
+ (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
18570
18697
  for (const suffix of ["-wal", "-shm"]) {
18571
18698
  const src = `${CONDUCTOR_DB}${suffix}`;
18572
- if ((0, import_node_fs45.existsSync)(src)) {
18699
+ if ((0, import_node_fs47.existsSync)(src)) {
18573
18700
  try {
18574
- (0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
18701
+ (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
18575
18702
  } catch {
18576
18703
  }
18577
18704
  }
@@ -18589,7 +18716,7 @@ function importConductorWorkspace(workspaceId) {
18589
18716
  ).get(workspaceId);
18590
18717
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
18591
18718
  const worktreePath = String(row.workspacePath);
18592
- if (!(0, import_node_fs45.existsSync)(worktreePath)) {
18719
+ if (!(0, import_node_fs47.existsSync)(worktreePath)) {
18593
18720
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
18594
18721
  }
18595
18722
  let sessionId = null;
@@ -18652,31 +18779,31 @@ function importConductorWorkspace(workspaceId) {
18652
18779
  db.close();
18653
18780
  }
18654
18781
  } finally {
18655
- (0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
18782
+ (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
18656
18783
  }
18657
18784
  }
18658
18785
  async function importConductorWorkspaceAsync(workspaceId) {
18659
18786
  return importConductorWorkspace(workspaceId);
18660
18787
  }
18661
- var import_node_child_process5, import_node_fs45, import_node_os14, import_node_path45, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
18788
+ var import_node_child_process5, import_node_fs47, import_node_os14, import_node_path46, import_node_module5, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
18662
18789
  var init_adopt = __esm({
18663
18790
  "src/threads/adopt.ts"() {
18664
18791
  "use strict";
18665
18792
  import_node_child_process5 = require("child_process");
18666
- import_node_fs45 = require("fs");
18793
+ import_node_fs47 = require("fs");
18667
18794
  import_node_os14 = require("os");
18668
- import_node_path45 = require("path");
18669
- import_node_module4 = require("module");
18795
+ import_node_path46 = require("path");
18796
+ import_node_module5 = require("module");
18670
18797
  init_worktree();
18671
18798
  init_thread_store();
18672
- CONDUCTOR_APP_SUPPORT = (0, import_node_path45.join)(
18799
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path46.join)(
18673
18800
  process.env.HOME ?? "",
18674
18801
  "Library",
18675
18802
  "Application Support",
18676
18803
  "com.conductor.app"
18677
18804
  );
18678
- CONDUCTOR_DB = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18679
- CURSOR_SDK_STORE = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18805
+ CONDUCTOR_DB = (0, import_node_path46.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18806
+ CURSOR_SDK_STORE = (0, import_node_path46.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18680
18807
  }
18681
18808
  });
18682
18809
 
@@ -18743,7 +18870,7 @@ async function openStackLayer(input, _onSetupLine) {
18743
18870
  let createdWorktree = false;
18744
18871
  const trees = await listWorktrees(repoPath);
18745
18872
  const checkedOut = trees.find((w) => w.branch === branchName);
18746
- if (checkedOut?.path && (0, import_node_fs46.existsSync)(checkedOut.path)) {
18873
+ if (checkedOut?.path && (0, import_node_fs48.existsSync)(checkedOut.path)) {
18747
18874
  if (input.reuseExistingWorktree !== false) {
18748
18875
  worktreePath = checkedOut.path;
18749
18876
  } else {
@@ -18885,7 +19012,7 @@ async function initStackFromThread(input, onSetupLine) {
18885
19012
  async function createPrStack(input, onSetupLine) {
18886
19013
  await requireAgent(input.agent);
18887
19014
  const repoPath = await resolveRepoRoot(input.repoPath);
18888
- if (!(0, import_node_fs46.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
19015
+ if (!(0, import_node_fs48.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
18889
19016
  if (!input.branches.length) throw new Error("At least one branch name required");
18890
19017
  const status = await detectGhStack(repoPath);
18891
19018
  if (!status.available) throw new Error(status.reason);
@@ -18952,7 +19079,7 @@ async function createPrStack(input, onSetupLine) {
18952
19079
  }
18953
19080
  }
18954
19081
  const claimed = new Set(threads.map((t) => t.worktreePath));
18955
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs46.existsSync)(bootstrap.worktreePath)) {
19082
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs48.existsSync)(bootstrap.worktreePath)) {
18956
19083
  try {
18957
19084
  await removeWorktree(repoPath, bootstrap.worktreePath, {
18958
19085
  deleteBranch: bootstrap.branchName
@@ -18962,11 +19089,11 @@ async function createPrStack(input, onSetupLine) {
18962
19089
  }
18963
19090
  return { stack, threads, createdThreadIds };
18964
19091
  }
18965
- var import_node_fs46;
19092
+ var import_node_fs48;
18966
19093
  var init_stack_layers = __esm({
18967
19094
  "src/threads/stack-layers.ts"() {
18968
19095
  "use strict";
18969
- import_node_fs46 = require("fs");
19096
+ import_node_fs48 = require("fs");
18970
19097
  init_detect();
18971
19098
  init_run();
18972
19099
  init_stack();
@@ -18979,7 +19106,7 @@ var init_stack_layers = __esm({
18979
19106
 
18980
19107
  // src/diff/diff.ts
18981
19108
  async function inspectGitWorktree(worktreePath) {
18982
- if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) return "missing_worktree";
19109
+ if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) return "missing_worktree";
18983
19110
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
18984
19111
  reject: false
18985
19112
  });
@@ -18987,7 +19114,7 @@ async function inspectGitWorktree(worktreePath) {
18987
19114
  return "ok";
18988
19115
  }
18989
19116
  async function initializeGitRepository(worktreePath) {
18990
- if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) {
19117
+ if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) {
18991
19118
  throw new Error("Worktree not found");
18992
19119
  }
18993
19120
  const status = await inspectGitWorktree(worktreePath);
@@ -19121,11 +19248,11 @@ new file mode 100644
19121
19248
  };
19122
19249
  }
19123
19250
  async function untrackedPatch(worktreePath, path, maxHunk) {
19124
- const abs = (0, import_node_path46.join)(worktreePath, path);
19251
+ const abs = (0, import_node_path47.join)(worktreePath, path);
19125
19252
  try {
19126
- const st = (0, import_node_fs47.statSync)(abs);
19253
+ const st = (0, import_node_fs49.statSync)(abs);
19127
19254
  if (st.isFile() && st.size > maxHunk) {
19128
- const buf = (0, import_node_fs47.readFileSync)(abs).subarray(0, maxHunk);
19255
+ const buf = (0, import_node_fs49.readFileSync)(abs).subarray(0, maxHunk);
19129
19256
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
19130
19257
  }
19131
19258
  } catch {
@@ -19592,9 +19719,9 @@ async function getDiff(worktreePath, repoPath, opts) {
19592
19719
  }
19593
19720
  function statWorktreePath(worktreePath, relativePath) {
19594
19721
  assertSafeRelativePath(relativePath);
19595
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19596
- if (!(0, import_node_fs47.existsSync)(abs)) return "missing";
19597
- const st = (0, import_node_fs47.statSync)(abs);
19722
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19723
+ if (!(0, import_node_fs49.existsSync)(abs)) return "missing";
19724
+ const st = (0, import_node_fs49.statSync)(abs);
19598
19725
  if (st.isDirectory()) return "dir";
19599
19726
  if (st.isFile()) return "file";
19600
19727
  return "missing";
@@ -19623,8 +19750,8 @@ function isImageRelativePath(relativePath) {
19623
19750
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19624
19751
  assertSafeRelativePath(relativePath);
19625
19752
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
19626
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19627
- const st = (0, import_node_fs47.statSync)(abs);
19753
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19754
+ const st = (0, import_node_fs49.statSync)(abs);
19628
19755
  if (!st.isFile()) {
19629
19756
  throw new Error(`Not a file: ${relativePath}`);
19630
19757
  }
@@ -19633,7 +19760,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19633
19760
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
19634
19761
  );
19635
19762
  }
19636
- const buf = (0, import_node_fs47.readFileSync)(abs);
19763
+ const buf = (0, import_node_fs49.readFileSync)(abs);
19637
19764
  return {
19638
19765
  path: relativePath,
19639
19766
  contentBase64: buf.toString("base64"),
@@ -19643,12 +19770,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19643
19770
  function readWorktreeFile(worktreePath, relativePath, opts) {
19644
19771
  assertSafeRelativePath(relativePath);
19645
19772
  const maxBytes = opts?.maxBytes ?? 2e5;
19646
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19647
- const st = (0, import_node_fs47.statSync)(abs);
19773
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19774
+ const st = (0, import_node_fs49.statSync)(abs);
19648
19775
  if (!st.isFile()) {
19649
19776
  throw new Error(`Not a file: ${relativePath}`);
19650
19777
  }
19651
- const buf = (0, import_node_fs47.readFileSync)(abs);
19778
+ const buf = (0, import_node_fs49.readFileSync)(abs);
19652
19779
  if (isImageRelativePath(relativePath)) {
19653
19780
  const maxImageBytes = Math.max(maxBytes, 15e6);
19654
19781
  const truncated2 = buf.length > maxImageBytes;
@@ -19691,9 +19818,9 @@ function assertSafeRelativePath(relativePath) {
19691
19818
  }
19692
19819
  function writeWorktreeFile(worktreePath, relativePath, content) {
19693
19820
  assertSafeRelativePath(relativePath);
19694
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19695
- (0, import_node_fs47.mkdirSync)((0, import_node_path46.dirname)(abs), { recursive: true });
19696
- (0, import_node_fs47.writeFileSync)(abs, content, "utf8");
19821
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19822
+ (0, import_node_fs49.mkdirSync)((0, import_node_path47.dirname)(abs), { recursive: true });
19823
+ (0, import_node_fs49.writeFileSync)(abs, content, "utf8");
19697
19824
  return { path: relativePath };
19698
19825
  }
19699
19826
  async function getWorktreeDirtyStat(worktreePath) {
@@ -19733,12 +19860,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
19733
19860
  truncated: full.files.length > maxFiles
19734
19861
  };
19735
19862
  }
19736
- var import_node_fs47, import_node_path46, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19863
+ var import_node_fs49, import_node_path47, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19737
19864
  var init_diff = __esm({
19738
19865
  "src/diff/diff.ts"() {
19739
19866
  "use strict";
19740
- import_node_fs47 = require("fs");
19741
- import_node_path46 = require("path");
19867
+ import_node_fs49 = require("fs");
19868
+ import_node_path47 = require("path");
19742
19869
  init_run();
19743
19870
  init_worktree();
19744
19871
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -20095,7 +20222,7 @@ function parseFrontmatter(content) {
20095
20222
  }
20096
20223
  function readSkill(skillMd, source) {
20097
20224
  try {
20098
- const content = (0, import_node_fs48.readFileSync)(skillMd, "utf8");
20225
+ const content = (0, import_node_fs50.readFileSync)(skillMd, "utf8");
20099
20226
  const { name: fmName, description } = parseFrontmatter(content);
20100
20227
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
20101
20228
  const name = fmName || dirName;
@@ -20114,19 +20241,19 @@ function readSkill(skillMd, source) {
20114
20241
  }
20115
20242
  }
20116
20243
  function scanSkillsDir(dir, source, out) {
20117
- if (!(0, import_node_fs48.existsSync)(dir)) return;
20244
+ if (!(0, import_node_fs50.existsSync)(dir)) return;
20118
20245
  let entries;
20119
20246
  try {
20120
- entries = (0, import_node_fs48.readdirSync)(dir);
20247
+ entries = (0, import_node_fs50.readdirSync)(dir);
20121
20248
  } catch {
20122
20249
  return;
20123
20250
  }
20124
20251
  for (const entry of entries) {
20125
20252
  if (entry.startsWith(".")) continue;
20126
- const skillMd = (0, import_node_path47.join)(dir, entry, "SKILL.md");
20127
- if (!(0, import_node_fs48.existsSync)(skillMd)) continue;
20253
+ const skillMd = (0, import_node_path48.join)(dir, entry, "SKILL.md");
20254
+ if (!(0, import_node_fs50.existsSync)(skillMd)) continue;
20128
20255
  try {
20129
- if (!(0, import_node_fs48.statSync)(skillMd).isFile()) continue;
20256
+ if (!(0, import_node_fs50.statSync)(skillMd).isFile()) continue;
20130
20257
  } catch {
20131
20258
  continue;
20132
20259
  }
@@ -20135,24 +20262,24 @@ function scanSkillsDir(dir, source, out) {
20135
20262
  }
20136
20263
  }
20137
20264
  function scanClaudePluginSkills(pluginsRoot, out) {
20138
- if (!(0, import_node_fs48.existsSync)(pluginsRoot)) return;
20265
+ if (!(0, import_node_fs50.existsSync)(pluginsRoot)) return;
20139
20266
  const walk = (dir, depth, lookingForSkillsDir) => {
20140
20267
  if (depth > 7) return;
20141
20268
  let entries;
20142
20269
  try {
20143
- entries = (0, import_node_fs48.readdirSync)(dir);
20270
+ entries = (0, import_node_fs50.readdirSync)(dir);
20144
20271
  } catch {
20145
20272
  return;
20146
20273
  }
20147
20274
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
20148
- const skill = readSkill((0, import_node_path47.join)(dir, "SKILL.md"), "cli");
20275
+ const skill = readSkill((0, import_node_path48.join)(dir, "SKILL.md"), "cli");
20149
20276
  if (skill) out.push(skill);
20150
20277
  }
20151
20278
  for (const entry of entries) {
20152
20279
  if (entry === "node_modules" || entry === ".git") continue;
20153
- const full = (0, import_node_path47.join)(dir, entry);
20280
+ const full = (0, import_node_path48.join)(dir, entry);
20154
20281
  try {
20155
- if (!(0, import_node_fs48.statSync)(full).isDirectory()) continue;
20282
+ if (!(0, import_node_fs50.statSync)(full).isDirectory()) continue;
20156
20283
  } catch {
20157
20284
  continue;
20158
20285
  }
@@ -20170,17 +20297,17 @@ function discoverSkills(worktreePath) {
20170
20297
  const home = (0, import_node_os15.homedir)();
20171
20298
  const collected = [];
20172
20299
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
20173
- scanSkillsDir((0, import_node_path47.join)(worktreePath, rel), "workspace", collected);
20300
+ scanSkillsDir((0, import_node_path48.join)(worktreePath, rel), "workspace", collected);
20174
20301
  }
20175
20302
  for (const abs of [
20176
- (0, import_node_path47.join)(home, ".claude/skills"),
20177
- (0, import_node_path47.join)(home, ".cursor/skills"),
20178
- (0, import_node_path47.join)(home, ".sideboard/skills"),
20179
- (0, import_node_path47.join)(home, ".brightsy/skills")
20303
+ (0, import_node_path48.join)(home, ".claude/skills"),
20304
+ (0, import_node_path48.join)(home, ".cursor/skills"),
20305
+ (0, import_node_path48.join)(home, ".sideboard/skills"),
20306
+ (0, import_node_path48.join)(home, ".brightsy/skills")
20180
20307
  ]) {
20181
20308
  scanSkillsDir(abs, "user", collected);
20182
20309
  }
20183
- scanClaudePluginSkills((0, import_node_path47.join)(home, ".claude/plugins"), collected);
20310
+ scanClaudePluginSkills((0, import_node_path48.join)(home, ".claude/plugins"), collected);
20184
20311
  collected.push(...bundledSkills());
20185
20312
  const rank = {
20186
20313
  workspace: 0,
@@ -20206,7 +20333,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
20206
20333
  \u2026(truncated)` : body;
20207
20334
  }
20208
20335
  }
20209
- const raw = (0, import_node_fs48.readFileSync)(skillPath, "utf8");
20336
+ const raw = (0, import_node_fs50.readFileSync)(skillPath, "utf8");
20210
20337
  if (raw.startsWith("---")) {
20211
20338
  const end = raw.indexOf("\n---", 3);
20212
20339
  if (end >= 0) {
@@ -20220,13 +20347,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
20220
20347
 
20221
20348
  \u2026(truncated)` : raw;
20222
20349
  }
20223
- var import_node_fs48, import_node_os15, import_node_path47, BUNDLED_SKILL_PREFIX;
20350
+ var import_node_fs50, import_node_os15, import_node_path48, BUNDLED_SKILL_PREFIX;
20224
20351
  var init_discover = __esm({
20225
20352
  "src/skills/discover.ts"() {
20226
20353
  "use strict";
20227
- import_node_fs48 = require("fs");
20354
+ import_node_fs50 = require("fs");
20228
20355
  import_node_os15 = require("os");
20229
- import_node_path47 = require("path");
20356
+ import_node_path48 = require("path");
20230
20357
  init_long_running();
20231
20358
  BUNDLED_SKILL_PREFIX = "bundled:";
20232
20359
  }
@@ -20379,9 +20506,9 @@ function compiledModuleDir() {
20379
20506
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
20380
20507
  if (cjsDir) return cjsDir;
20381
20508
  try {
20382
- const url = import_meta3.url;
20509
+ const url = import_meta4.url;
20383
20510
  if (typeof url === "string" && url.length > 0) {
20384
- return (0, import_node_path48.dirname)((0, import_node_url3.fileURLToPath)(url));
20511
+ return (0, import_node_path49.dirname)((0, import_node_url4.fileURLToPath)(url));
20385
20512
  }
20386
20513
  } catch {
20387
20514
  }
@@ -20389,8 +20516,8 @@ function compiledModuleDir() {
20389
20516
  }
20390
20517
  function detachedJobScriptIn(dir) {
20391
20518
  for (const name of DETACHED_JOB_FILENAMES) {
20392
- const script = (0, import_node_path48.join)(dir, "scripts", name);
20393
- if ((0, import_node_fs49.existsSync)(script)) return script;
20519
+ const script = (0, import_node_path49.join)(dir, "scripts", name);
20520
+ if ((0, import_node_fs51.existsSync)(script)) return script;
20394
20521
  }
20395
20522
  return null;
20396
20523
  }
@@ -20407,7 +20534,7 @@ function resolveDetachedJobScript() {
20407
20534
  for (let i = 0; i < 8; i++) {
20408
20535
  const candidate = detachedJobScriptIn(dir);
20409
20536
  if (candidate) return candidate;
20410
- const parent = (0, import_node_path48.dirname)(dir);
20537
+ const parent = (0, import_node_path49.dirname)(dir);
20411
20538
  if (parent === dir) break;
20412
20539
  dir = parent;
20413
20540
  }
@@ -20418,15 +20545,15 @@ function formatDetachedJobInvoke(scriptPath) {
20418
20545
  if (resolved) return `node ${JSON.stringify(resolved)}`;
20419
20546
  return "node scripts/detached-job.cjs";
20420
20547
  }
20421
- var import_node_fs49, import_node_path48, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
20548
+ var import_node_fs51, import_node_path49, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
20422
20549
  var init_detached_job_path = __esm({
20423
20550
  "src/skills/detached-job-path.ts"() {
20424
20551
  "use strict";
20425
- import_node_fs49 = require("fs");
20426
- import_node_path48 = require("path");
20427
- import_node_url3 = require("url");
20552
+ import_node_fs51 = require("fs");
20553
+ import_node_path49 = require("path");
20554
+ import_node_url4 = require("url");
20428
20555
  init_packaged_runtime();
20429
- import_meta3 = {};
20556
+ import_meta4 = {};
20430
20557
  DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
20431
20558
  }
20432
20559
  });
@@ -20583,9 +20710,9 @@ function formatPrGateDirective() {
20583
20710
  }
20584
20711
  function formatProcessGuideDirective(opts) {
20585
20712
  const worktree = opts?.worktreePath?.trim();
20586
- const hasGraphSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
20587
- const hasReviewSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/review/SKILL.md"));
20588
- const hasInstallSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
20713
+ const hasGraphSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path50.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
20714
+ const hasReviewSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path50.join)(worktree, ".claude/skills/review/SKILL.md"));
20715
+ const hasInstallSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path50.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
20589
20716
  return [
20590
20717
  "Process guides (recurring work only):",
20591
20718
  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,
@@ -20624,12 +20751,12 @@ function formatArtifactDirective() {
20624
20751
  function formatUiReminder() {
20625
20752
  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.";
20626
20753
  }
20627
- var import_node_fs50, import_node_path49, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
20754
+ var import_node_fs52, import_node_path50, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
20628
20755
  var init_instructions = __esm({
20629
20756
  "src/agents/instructions.ts"() {
20630
20757
  "use strict";
20631
- import_node_fs50 = require("fs");
20632
- import_node_path49 = require("path");
20758
+ import_node_fs52 = require("fs");
20759
+ import_node_path50 = require("path");
20633
20760
  init_git_auth_mode();
20634
20761
  init_branch_prefix();
20635
20762
  init_worktree_labels();
@@ -20853,40 +20980,40 @@ __export(plan_file_exports, {
20853
20980
  writePlanFile: () => writePlanFile
20854
20981
  });
20855
20982
  function ensureAttachmentsGitignore(worktreePath) {
20856
- const gitignoreAbs = (0, import_node_path50.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20857
- if ((0, import_node_fs51.existsSync)(gitignoreAbs)) return;
20858
- (0, import_node_fs51.mkdirSync)((0, import_node_path50.dirname)(gitignoreAbs), { recursive: true });
20859
- (0, import_node_fs51.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20983
+ const gitignoreAbs = (0, import_node_path51.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20984
+ if ((0, import_node_fs53.existsSync)(gitignoreAbs)) return;
20985
+ (0, import_node_fs53.mkdirSync)((0, import_node_path51.dirname)(gitignoreAbs), { recursive: true });
20986
+ (0, import_node_fs53.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20860
20987
  }
20861
20988
  function planFileAbs(worktreePath) {
20862
- return (0, import_node_path50.join)(worktreePath, PLAN_FILE_REL);
20989
+ return (0, import_node_path51.join)(worktreePath, PLAN_FILE_REL);
20863
20990
  }
20864
20991
  function readTextIfPresent2(abs) {
20865
- if (!(0, import_node_fs51.existsSync)(abs)) return null;
20992
+ if (!(0, import_node_fs53.existsSync)(abs)) return null;
20866
20993
  try {
20867
- const content = (0, import_node_fs51.readFileSync)(abs, "utf8");
20994
+ const content = (0, import_node_fs53.readFileSync)(abs, "utf8");
20868
20995
  return content.trim() ? content : null;
20869
20996
  } catch {
20870
20997
  return null;
20871
20998
  }
20872
20999
  }
20873
21000
  function readPlanFile(worktreePath) {
20874
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path50.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path50.join)(worktreePath, LEGACY_PLAN_FILE_REL));
21001
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path51.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path51.join)(worktreePath, LEGACY_PLAN_FILE_REL));
20875
21002
  }
20876
21003
  function writePlanFile(worktreePath, content) {
20877
21004
  ensureAttachmentsGitignore(worktreePath);
20878
21005
  const abs = planFileAbs(worktreePath);
20879
- (0, import_node_fs51.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
21006
+ (0, import_node_fs53.mkdirSync)((0, import_node_path51.dirname)(abs), { recursive: true });
20880
21007
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
20881
- (0, import_node_fs51.writeFileSync)(abs, body, "utf8");
21008
+ (0, import_node_fs53.writeFileSync)(abs, body, "utf8");
20882
21009
  return PLAN_FILE_REL;
20883
21010
  }
20884
- var import_node_fs51, import_node_path50;
21011
+ var import_node_fs53, import_node_path51;
20885
21012
  var init_plan_file = __esm({
20886
21013
  "src/plan/plan-file.ts"() {
20887
21014
  "use strict";
20888
- import_node_fs51 = require("fs");
20889
- import_node_path50 = require("path");
21015
+ import_node_fs53 = require("fs");
21016
+ import_node_path51 = require("path");
20890
21017
  init_workspace_scratch();
20891
21018
  init_plan_present();
20892
21019
  init_plan_present();
@@ -20946,7 +21073,7 @@ function setCaffeinateHoldHooks(next) {
20946
21073
  hooks = next;
20947
21074
  }
20948
21075
  function caffeinateHoldPath() {
20949
- return (0, import_node_path51.join)(appDataDir(), "caffeinate-hold.json");
21076
+ return (0, import_node_path52.join)(appDataDir(), "caffeinate-hold.json");
20950
21077
  }
20951
21078
  function processAlive(pid) {
20952
21079
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -20980,9 +21107,9 @@ function uniqueIds(ids) {
20980
21107
  }
20981
21108
  function readHold() {
20982
21109
  const path = caffeinateHoldPath();
20983
- if (!(0, import_node_fs52.existsSync)(path)) return null;
21110
+ if (!(0, import_node_fs54.existsSync)(path)) return null;
20984
21111
  try {
20985
- const parsed = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
21112
+ const parsed = JSON.parse((0, import_node_fs54.readFileSync)(path, "utf8"));
20986
21113
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
20987
21114
  return {
20988
21115
  pid: parsed.pid,
@@ -21004,7 +21131,7 @@ function writeHold(pid, threadIds) {
21004
21131
  }
21005
21132
  function clearHold() {
21006
21133
  try {
21007
- (0, import_node_fs52.unlinkSync)(caffeinateHoldPath());
21134
+ (0, import_node_fs54.unlinkSync)(caffeinateHoldPath());
21008
21135
  } catch {
21009
21136
  }
21010
21137
  }
@@ -21089,13 +21216,13 @@ function releaseCaffeinateHoldForThread(threadId) {
21089
21216
  }
21090
21217
  return setCaffeinateHold(false, { threadId: id });
21091
21218
  }
21092
- var import_node_child_process6, import_node_fs52, import_node_path51, hooks;
21219
+ var import_node_child_process6, import_node_fs54, import_node_path52, hooks;
21093
21220
  var init_caffeinate_hold = __esm({
21094
21221
  "src/store/caffeinate-hold.ts"() {
21095
21222
  "use strict";
21096
21223
  import_node_child_process6 = require("child_process");
21097
- import_node_fs52 = require("fs");
21098
- import_node_path51 = require("path");
21224
+ import_node_fs54 = require("fs");
21225
+ import_node_path52 = require("path");
21099
21226
  init_paths();
21100
21227
  init_private_file();
21101
21228
  hooks = {};
@@ -21104,7 +21231,7 @@ var init_caffeinate_hold = __esm({
21104
21231
 
21105
21232
  // src/store/schedules.ts
21106
21233
  function schedulesPath() {
21107
- return (0, import_node_path52.join)(appDataDir(), "schedules.json");
21234
+ return (0, import_node_path53.join)(appDataDir(), "schedules.json");
21108
21235
  }
21109
21236
  function parseDurationMs(every) {
21110
21237
  const m = every.trim().match(DURATION_RE);
@@ -21204,9 +21331,9 @@ function normalizeTask(raw) {
21204
21331
  }
21205
21332
  function readAll2() {
21206
21333
  const path = schedulesPath();
21207
- if (!(0, import_node_fs53.existsSync)(path)) return [];
21334
+ if (!(0, import_node_fs55.existsSync)(path)) return [];
21208
21335
  try {
21209
- const parsed = JSON.parse((0, import_node_fs53.readFileSync)(path, "utf8"));
21336
+ const parsed = JSON.parse((0, import_node_fs55.readFileSync)(path, "utf8"));
21210
21337
  if (!Array.isArray(parsed)) return [];
21211
21338
  return parsed.map((row) => {
21212
21339
  try {
@@ -21318,13 +21445,13 @@ function recordScheduleRun(id, result) {
21318
21445
  writeAll2(rows);
21319
21446
  return next;
21320
21447
  }
21321
- var import_node_crypto11, import_node_fs53, import_node_path52, import_croner, DURATION_RE, UNIT_MS;
21448
+ var import_node_crypto11, import_node_fs55, import_node_path53, import_croner, DURATION_RE, UNIT_MS;
21322
21449
  var init_schedules = __esm({
21323
21450
  "src/store/schedules.ts"() {
21324
21451
  "use strict";
21325
21452
  import_node_crypto11 = require("crypto");
21326
- import_node_fs53 = require("fs");
21327
- import_node_path52 = require("path");
21453
+ import_node_fs55 = require("fs");
21454
+ import_node_path53 = require("path");
21328
21455
  import_croner = require("croner");
21329
21456
  init_orchestrator_capable();
21330
21457
  init_paths();
@@ -21480,9 +21607,9 @@ function recoverFinishedCursorRun(opts) {
21480
21607
  return best;
21481
21608
  }
21482
21609
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
21483
- if (!(0, import_node_fs54.existsSync)(runsPath)) return null;
21610
+ if (!(0, import_node_fs56.existsSync)(runsPath)) return null;
21484
21611
  try {
21485
- const lines = (0, import_node_fs54.readFileSync)(runsPath, "utf8").split("\n");
21612
+ const lines = (0, import_node_fs56.readFileSync)(runsPath, "utf8").split("\n");
21486
21613
  let best = null;
21487
21614
  for (const line of lines) {
21488
21615
  const trimmed = line.trim();
@@ -21508,11 +21635,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
21508
21635
  return null;
21509
21636
  }
21510
21637
  }
21511
- var import_node_fs54;
21638
+ var import_node_fs56;
21512
21639
  var init_cursor_recover = __esm({
21513
21640
  "src/agents/cursor-recover.ts"() {
21514
21641
  "use strict";
21515
- import_node_fs54 = require("fs");
21642
+ import_node_fs56 = require("fs");
21516
21643
  init_cursor_store();
21517
21644
  }
21518
21645
  });
@@ -21666,14 +21793,14 @@ async function startOrchestration(opts) {
21666
21793
  }
21667
21794
  return updated;
21668
21795
  }
21669
- var import_node_events, import_node_crypto12, import_node_fs55, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
21796
+ var import_node_events, import_node_crypto12, import_node_fs57, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
21670
21797
  var init_orchestrator = __esm({
21671
21798
  "src/orchestrator/orchestrator.ts"() {
21672
21799
  "use strict";
21673
21800
  import_node_events = require("events");
21674
21801
  init_outbound_watch();
21675
21802
  import_node_crypto12 = require("crypto");
21676
- import_node_fs55 = require("fs");
21803
+ import_node_fs57 = require("fs");
21677
21804
  init_error_detail();
21678
21805
  init_run();
21679
21806
  init_stale_lock();
@@ -21775,6 +21902,8 @@ var init_orchestrator = __esm({
21775
21902
  jobContinueNudged = /* @__PURE__ */ new Set();
21776
21903
  /** In-flight startDev per worktree run key — agent MCP + UI Start must not double-spawn. */
21777
21904
  startingDev = /* @__PURE__ */ new Map();
21905
+ /** Serialize desktop apply of `runScriptRequest` per thread (start then stop). */
21906
+ applyingRunScriptThreads = /* @__PURE__ */ new Set();
21778
21907
  /**
21779
21908
  * MCP/CLI poll budget while Electron main adopts `runScriptRequest`.
21780
21909
  * Tests shorten this so a missing desktop does not wait 20s.
@@ -21848,7 +21977,7 @@ var init_orchestrator = __esm({
21848
21977
  this.lightReconcileAt.set(repoPath, Date.now());
21849
21978
  for (const thread of listThreads()) {
21850
21979
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
21851
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
21980
+ if (!(0, import_node_fs57.existsSync)(thread.worktreePath)) {
21852
21981
  setStatus(thread.id, "broken", "Worktree missing on disk");
21853
21982
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
21854
21983
  }
@@ -21877,7 +22006,7 @@ var init_orchestrator = __esm({
21877
22006
  }
21878
22007
  continue;
21879
22008
  }
21880
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
22009
+ if (!(0, import_node_fs57.existsSync)(thread.worktreePath)) {
21881
22010
  setStatus(thread.id, "broken", "Worktree missing on disk");
21882
22011
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
21883
22012
  continue;
@@ -21961,11 +22090,19 @@ var init_orchestrator = __esm({
21961
22090
  for (const thread of listThreads()) {
21962
22091
  if (thread.status === "archived") continue;
21963
22092
  const req = thread.runScriptRequest;
21964
- if (!isUnclaimedRunScriptRequest(req) || !req) continue;
21965
- const claimedAt = (/* @__PURE__ */ new Date()).toISOString();
22093
+ if (!isAdoptableRunScriptRequest(req) || !req) continue;
22094
+ if (this.applyingRunScriptThreads.has(thread.id)) continue;
22095
+ const claimedAt = req.claimedAt ?? (/* @__PURE__ */ new Date()).toISOString();
21966
22096
  const claimed = { ...req, claimedAt };
22097
+ this.applyingRunScriptThreads.add(thread.id);
21967
22098
  updateThread(thread.id, { runScriptRequest: claimed });
21968
- void this.applyRunScriptRequest(thread.id, claimed);
22099
+ void this.applyRunScriptRequest(thread.id, claimed).finally(() => {
22100
+ this.applyingRunScriptThreads.delete(thread.id);
22101
+ const latest = readThread(thread.id)?.runScriptRequest;
22102
+ if (latest && latest.requestId !== req.requestId && isAdoptableRunScriptRequest(latest)) {
22103
+ this.adoptPersistedRunScripts();
22104
+ }
22105
+ });
21969
22106
  }
21970
22107
  }
21971
22108
  async applyRunScriptRequest(threadId, req) {
@@ -23221,9 +23358,8 @@ var init_orchestrator = __esm({
23221
23358
  if (fulfilled && !run2) {
23222
23359
  throw new Error("Desktop reported the run script started, but it is not active.");
23223
23360
  }
23224
- } else {
23225
- const gone = scriptName ? !run2 : shared.activeRuns.length === 0;
23226
- if (fulfilled || gone) return null;
23361
+ } else if (fulfilled) {
23362
+ return null;
23227
23363
  }
23228
23364
  await new Promise((r) => setTimeout(r, 40));
23229
23365
  }
@@ -23231,12 +23367,26 @@ var init_orchestrator = __esm({
23231
23367
  op === "start" ? "Desktop did not start the run script in time. Is Sideboard.app running this worktree?" : "Desktop did not stop the run script in time."
23232
23368
  );
23233
23369
  }
23370
+ async awaitStartingDev(worktreePath, scriptName) {
23371
+ const keys = scriptName ? [worktreeRunProcessKey(worktreePath, scriptName)] : [...this.startingDev.keys()].filter((k) => isWorktreeRunProcessKey(k, worktreePath));
23372
+ await Promise.all(
23373
+ keys.map(async (key) => {
23374
+ const pending = this.startingDev.get(key);
23375
+ if (!pending) return;
23376
+ try {
23377
+ await pending;
23378
+ } catch {
23379
+ }
23380
+ })
23381
+ );
23382
+ }
23234
23383
  async stopDev(threadRef, scriptName) {
23235
23384
  const thread = this.requireThread(threadRef);
23236
23385
  if (!this.shouldOwnRunScripts()) {
23237
23386
  await this.requestDesktopRunScript(thread, "stop", scriptName);
23238
23387
  return;
23239
23388
  }
23389
+ await this.awaitStartingDev(thread.worktreePath, scriptName);
23240
23390
  const siblings = threadsSharingWorktree(thread.worktreePath);
23241
23391
  const shared = mergeWorktreeActiveRuns(siblings);
23242
23392
  if (scriptName) {
@@ -24147,7 +24297,7 @@ var init_orchestrator = __esm({
24147
24297
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
24148
24298
  return restored2;
24149
24299
  }
24150
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
24300
+ if (!(0, import_node_fs57.existsSync)(thread.worktreePath)) {
24151
24301
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
24152
24302
  throw new Error(
24153
24303
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -24231,7 +24381,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
24231
24381
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
24232
24382
  var import_zod9 = require("zod");
24233
24383
  var import_node_crypto15 = require("crypto");
24234
- var import_node_path55 = require("path");
24384
+ var import_node_path56 = require("path");
24235
24385
  init_orchestrator();
24236
24386
  init_worktree();
24237
24387
 
@@ -27651,27 +27801,27 @@ init_gh_errors();
27651
27801
  init_git_auth_mode();
27652
27802
 
27653
27803
  // src/board/load-home-board.ts
27654
- var import_node_fs57 = require("fs");
27655
- var import_node_path54 = require("path");
27804
+ var import_node_fs59 = require("fs");
27805
+ var import_node_path55 = require("path");
27656
27806
  init_worktree();
27657
27807
  init_paths();
27658
27808
 
27659
27809
  // src/board/board-pins.ts
27660
27810
  var import_node_crypto14 = require("crypto");
27661
- var import_node_fs56 = require("fs");
27662
- var import_node_path53 = require("path");
27811
+ var import_node_fs58 = require("fs");
27812
+ var import_node_path54 = require("path");
27663
27813
  init_paths();
27664
27814
  init_home_board();
27665
27815
  var FILE = "home-board-pins.json";
27666
27816
  var VERSION = 1;
27667
27817
  function pinsFile() {
27668
- return (0, import_node_path53.join)(appDataDir(), FILE);
27818
+ return (0, import_node_path54.join)(appDataDir(), FILE);
27669
27819
  }
27670
27820
  function readDisk() {
27671
27821
  const path = pinsFile();
27672
- if (!(0, import_node_fs56.existsSync)(path)) return [];
27822
+ if (!(0, import_node_fs58.existsSync)(path)) return [];
27673
27823
  try {
27674
- const raw = JSON.parse((0, import_node_fs56.readFileSync)(path, "utf8"));
27824
+ const raw = JSON.parse((0, import_node_fs58.readFileSync)(path, "utf8"));
27675
27825
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
27676
27826
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
27677
27827
  } catch {
@@ -27679,8 +27829,8 @@ function readDisk() {
27679
27829
  }
27680
27830
  }
27681
27831
  function writeDisk(items) {
27682
- (0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
27683
- (0, import_node_fs56.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
27832
+ (0, import_node_fs58.mkdirSync)(appDataDir(), { recursive: true });
27833
+ (0, import_node_fs58.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
27684
27834
  }
27685
27835
  function listBoardPins() {
27686
27836
  return readDisk();
@@ -27701,7 +27851,7 @@ function homeBoardWorkspaceKey(workspaces) {
27701
27851
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
27702
27852
  }
27703
27853
  function cacheFile() {
27704
- return (0, import_node_path54.join)(appDataDir(), "home-board-cache.json");
27854
+ return (0, import_node_path55.join)(appDataDir(), "home-board-cache.json");
27705
27855
  }
27706
27856
  function emptyInputs() {
27707
27857
  return {
@@ -27727,9 +27877,9 @@ function shouldCacheHomeBoardInputs(inputs) {
27727
27877
  }
27728
27878
  function readDiskCache() {
27729
27879
  const path = cacheFile();
27730
- if (!(0, import_node_fs57.existsSync)(path)) return null;
27880
+ if (!(0, import_node_fs59.existsSync)(path)) return null;
27731
27881
  try {
27732
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(path, "utf8"));
27882
+ const raw = JSON.parse((0, import_node_fs59.readFileSync)(path, "utf8"));
27733
27883
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
27734
27884
  return null;
27735
27885
  }
@@ -27743,8 +27893,8 @@ function readDiskCache() {
27743
27893
  }
27744
27894
  function writeDiskCache(entry) {
27745
27895
  try {
27746
- (0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
27747
- (0, import_node_fs57.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
27896
+ (0, import_node_fs59.mkdirSync)(appDataDir(), { recursive: true });
27897
+ (0, import_node_fs59.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
27748
27898
  } catch {
27749
27899
  }
27750
27900
  }
@@ -28131,7 +28281,7 @@ async function startMcpServer() {
28131
28281
  async () => {
28132
28282
  const threads = orch.getThreads(true);
28133
28283
  const lines = threads.map((t) => {
28134
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path55.basename)(t.repoPath) || t.repoPath;
28284
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path56.basename)(t.repoPath) || t.repoPath;
28135
28285
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
28136
28286
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
28137
28287
  const preview = lastMessagePreview(t.messages, 80);