@sideboard-ai/core 0.1.232 → 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-LLMG6OVS.js → chunk-BGHDWCAV.js} +19 -19
  11. package/dist/{chunk-SZJZEFTY.js → chunk-DD67JWTN.js} +1 -1
  12. package/dist/{chunk-7BZ7DSBN.js → chunk-NLETJP7Z.js} +17 -17
  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 +490 -326
  27. package/dist/index.d.cts +19 -3
  28. package/dist/index.d.ts +19 -3
  29. package/dist/index.js +27 -8
  30. package/dist/mcp/run-stdio.cjs +418 -302
  31. package/dist/mcp/run-stdio.js +7 -7
  32. package/dist/{orchestrator-FTHJKPIX.js → orchestrator-BXALNM4M.js} +8 -8
  33. package/dist/{orchestrator-RJX4OKYC.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
package/dist/index.cjs CHANGED
@@ -6775,6 +6775,14 @@ function ensureAgentPath(env = process.env) {
6775
6775
  }
6776
6776
  function enrichPathWithNpmGlobalBin(env = process.env) {
6777
6777
  ensureAgentPath(env);
6778
+ const prefix = npmGlobalPrefix(env);
6779
+ if (prefix) {
6780
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path17.join)(prefix, "bin");
6781
+ prependPathDir(env, binDir);
6782
+ }
6783
+ return env.PATH ?? "";
6784
+ }
6785
+ function npmGlobalPrefix(env = process.env) {
6778
6786
  try {
6779
6787
  const prefix = (0, import_node_child_process3.execFileSync)("npm", ["prefix", "-g"], {
6780
6788
  encoding: "utf8",
@@ -6782,13 +6790,16 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
6782
6790
  timeout: 8e3,
6783
6791
  stdio: ["ignore", "pipe", "ignore"]
6784
6792
  }).trim().split(/\r?\n/).find(Boolean);
6785
- if (prefix) {
6786
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path17.join)(prefix, "bin");
6787
- prependPathDir(env, binDir);
6788
- }
6793
+ return prefix || null;
6789
6794
  } catch {
6795
+ return null;
6790
6796
  }
6791
- return env.PATH ?? "";
6797
+ }
6798
+ function npmGlobalNodeModules(env = process.env) {
6799
+ const prefix = npmGlobalPrefix(env);
6800
+ if (!prefix) return null;
6801
+ const dir = process.platform === "win32" ? (0, import_node_path17.join)(prefix, "node_modules") : (0, import_node_path17.join)(prefix, "lib", "node_modules");
6802
+ return (0, import_node_fs15.existsSync)(dir) ? dir : null;
6792
6803
  }
6793
6804
  function posixShellSingleQuote(value) {
6794
6805
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -13914,6 +13925,95 @@ var init_codex = __esm({
13914
13925
  }
13915
13926
  });
13916
13927
 
13928
+ // src/agents/cursor-sdk-resolve.ts
13929
+ function thisModuleFile() {
13930
+ const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
13931
+ if (cjsDir) return (0, import_node_path38.join)(cjsDir, "cursor-sdk-resolve.js");
13932
+ try {
13933
+ return (0, import_node_url2.fileURLToPath)(import_meta2.url);
13934
+ } catch {
13935
+ return (0, import_node_path38.join)(process.cwd(), "package.json");
13936
+ }
13937
+ }
13938
+ function packageRootLooksLikeSdk(dir) {
13939
+ try {
13940
+ const raw = (0, import_node_fs36.readFileSync)((0, import_node_path38.join)(dir, "package.json"), "utf8");
13941
+ const pkg = JSON.parse(raw);
13942
+ return pkg.name === "@cursor/sdk" && (0, import_node_fs36.existsSync)(dir);
13943
+ } catch {
13944
+ return false;
13945
+ }
13946
+ }
13947
+ function resolvedPackageRoot(fromFile) {
13948
+ try {
13949
+ const req = (0, import_node_module2.createRequire)(fromFile);
13950
+ const pkgJson = req.resolve("@cursor/sdk/package.json");
13951
+ const root = (0, import_node_path38.dirname)(pkgJson);
13952
+ return packageRootLooksLikeSdk(root) ? root : null;
13953
+ } catch {
13954
+ return null;
13955
+ }
13956
+ }
13957
+ function resolveCursorSdkRoot(opts) {
13958
+ const env = opts?.env ?? process.env;
13959
+ const override = env.SIDEBOARD_CURSOR_SDK?.trim();
13960
+ if (override) {
13961
+ return packageRootLooksLikeSdk(override) ? override : null;
13962
+ }
13963
+ const globalNm = npmGlobalNodeModules(env);
13964
+ if (globalNm) {
13965
+ const globalRoot = (0, import_node_path38.join)(globalNm, "@cursor/sdk");
13966
+ if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
13967
+ }
13968
+ const cwdPkg = (0, import_node_path38.join)(process.cwd(), "package.json");
13969
+ return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
13970
+ }
13971
+ function isCursorSdkInstalled(opts) {
13972
+ return Boolean(resolveCursorSdkRoot(opts));
13973
+ }
13974
+ async function importCursorSdk(opts) {
13975
+ const root = resolveCursorSdkRoot(opts);
13976
+ if (!root) return null;
13977
+ try {
13978
+ const req = (0, import_node_module2.createRequire)((0, import_node_path38.join)(root, "package.json"));
13979
+ const entry = req.resolve("@cursor/sdk");
13980
+ return await import((0, import_node_url2.pathToFileURL)(entry).href);
13981
+ } catch {
13982
+ return null;
13983
+ }
13984
+ }
13985
+ function cursorSdkPlatformRipgrepPackage() {
13986
+ return `@cursor/sdk-${process.platform}-${process.arch}`;
13987
+ }
13988
+ function nodeModulesDirForPackageRoot(packageRoot) {
13989
+ const parent = (0, import_node_path38.dirname)(packageRoot);
13990
+ return (0, import_node_path38.basename)(parent).startsWith("@") ? (0, import_node_path38.dirname)(parent) : parent;
13991
+ }
13992
+ function cursorSdkRipgrepCandidate(opts) {
13993
+ const root = resolveCursorSdkRoot(opts);
13994
+ if (!root) return null;
13995
+ const nm = nodeModulesDirForPackageRoot(root);
13996
+ const pkg = cursorSdkPlatformRipgrepPackage();
13997
+ const bin = process.platform === "win32" ? "rg.exe" : "rg";
13998
+ const sibling = (0, import_node_path38.join)(nm, pkg, "bin", bin);
13999
+ if ((0, import_node_fs36.existsSync)(sibling)) return sibling;
14000
+ const nested = (0, import_node_path38.join)(root, "node_modules", pkg, "bin", bin);
14001
+ return (0, import_node_fs36.existsSync)(nested) ? nested : null;
14002
+ }
14003
+ var import_node_fs36, import_node_module2, import_node_path38, import_node_url2, import_meta2, CURSOR_SDK_INSTALL_HINT;
14004
+ var init_cursor_sdk_resolve = __esm({
14005
+ "src/agents/cursor-sdk-resolve.ts"() {
14006
+ "use strict";
14007
+ import_node_fs36 = require("fs");
14008
+ import_node_module2 = require("module");
14009
+ import_node_path38 = require("path");
14010
+ import_node_url2 = require("url");
14011
+ init_path();
14012
+ import_meta2 = {};
14013
+ 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.";
14014
+ }
14015
+ });
14016
+
13917
14017
  // src/agents/cursor-events.ts
13918
14018
  function usageFromCursor(usage) {
13919
14019
  if (!usage) return null;
@@ -14140,21 +14240,21 @@ function platformRipgrepPackage() {
14140
14240
  }
14141
14241
  function usableRipgrepPath(candidate) {
14142
14242
  const raw = candidate?.trim();
14143
- if (!raw || !(0, import_node_path38.isAbsolute)(raw)) return null;
14243
+ if (!raw || !(0, import_node_path39.isAbsolute)(raw)) return null;
14144
14244
  const readable = nodeReadableScriptPath(raw);
14145
- if (!(0, import_node_fs36.existsSync)(readable) || isAsarPath(readable)) return null;
14245
+ if (!(0, import_node_fs37.existsSync)(readable) || isAsarPath(readable)) return null;
14146
14246
  return readable;
14147
14247
  }
14148
14248
  function walkForBundledRipgrep(startFile) {
14149
14249
  if (!startFile) return null;
14150
14250
  const pkg = platformRipgrepPackage();
14151
14251
  const name = rgBinaryName();
14152
- let dir = (0, import_node_path38.dirname)((0, import_node_path38.resolve)(startFile));
14153
- const root = (0, import_node_path38.parse)(dir).root;
14252
+ let dir = (0, import_node_path39.dirname)((0, import_node_path39.resolve)(startFile));
14253
+ const root = (0, import_node_path39.parse)(dir).root;
14154
14254
  while (dir !== root) {
14155
- const hit = usableRipgrepPath((0, import_node_path38.join)(dir, "node_modules", pkg, "bin", name));
14255
+ const hit = usableRipgrepPath((0, import_node_path39.join)(dir, "node_modules", pkg, "bin", name));
14156
14256
  if (hit) return hit;
14157
- const next = (0, import_node_path38.dirname)(dir);
14257
+ const next = (0, import_node_path39.dirname)(dir);
14158
14258
  if (next === dir) break;
14159
14259
  dir = next;
14160
14260
  }
@@ -14162,9 +14262,9 @@ function walkForBundledRipgrep(startFile) {
14162
14262
  }
14163
14263
  function requireResolveBundledRipgrep(fromFile) {
14164
14264
  try {
14165
- const req = (0, import_node_module2.createRequire)(fromFile);
14265
+ const req = (0, import_node_module3.createRequire)(fromFile);
14166
14266
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
14167
- return usableRipgrepPath((0, import_node_path38.join)((0, import_node_path38.dirname)(pkgJson), "bin", rgBinaryName()));
14267
+ return usableRipgrepPath((0, import_node_path39.join)((0, import_node_path39.dirname)(pkgJson), "bin", rgBinaryName()));
14168
14268
  } catch {
14169
14269
  return null;
14170
14270
  }
@@ -14180,19 +14280,20 @@ function resolveCursorRipgrepPath(opts) {
14180
14280
  const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
14181
14281
  // eslint-disable-next-line camelcase
14182
14282
  (typeof __filename !== "undefined" ? __filename : "");
14183
- return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
14283
+ return walkForBundledRipgrep(start) ?? usableRipgrepPath(cursorSdkRipgrepCandidate({ env })) ?? requireResolveBundledRipgrep(start);
14184
14284
  }
14185
14285
  function cursorRipgrepEnv(opts) {
14186
14286
  const path2 = resolveCursorRipgrepPath(opts);
14187
14287
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
14188
14288
  }
14189
- var import_node_fs36, import_node_module2, import_node_path38, RIPGREP_ENV;
14289
+ var import_node_fs37, import_node_module3, import_node_path39, RIPGREP_ENV;
14190
14290
  var init_cursor_ripgrep = __esm({
14191
14291
  "src/agents/cursor-ripgrep.ts"() {
14192
14292
  "use strict";
14193
- import_node_fs36 = require("fs");
14194
- import_node_module2 = require("module");
14195
- import_node_path38 = require("path");
14293
+ import_node_fs37 = require("fs");
14294
+ import_node_module3 = require("module");
14295
+ import_node_path39 = require("path");
14296
+ init_cursor_sdk_resolve();
14196
14297
  init_node_launch();
14197
14298
  init_packaged_runtime();
14198
14299
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -14223,8 +14324,10 @@ async function listCursorModels() {
14223
14324
  }
14224
14325
  const apiKey = resolveCursorApiKey();
14225
14326
  if (!apiKey) return FALLBACK_CURSOR_MODELS;
14327
+ const sdk = await importCursorSdk();
14328
+ if (!sdk) return FALLBACK_CURSOR_MODELS;
14226
14329
  try {
14227
- const listed = await import_sdk.Cursor.models.list({ apiKey });
14330
+ const listed = await sdk.Cursor.models.list({ apiKey });
14228
14331
  const models = listed.map((m) => ({
14229
14332
  id: m.id,
14230
14333
  displayName: m.displayName || m.id,
@@ -14241,11 +14344,11 @@ function entryDir() {
14241
14344
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
14242
14345
  if (cjsDir) return cjsDir;
14243
14346
  try {
14244
- return (0, import_node_path39.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
14347
+ return (0, import_node_path40.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
14245
14348
  } catch {
14246
14349
  try {
14247
- const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
14248
- return (0, import_node_path39.dirname)(req.resolve("@sideboard-ai/core"));
14350
+ const req = (0, import_node_module4.createRequire)(process.cwd() + "/");
14351
+ return (0, import_node_path40.dirname)(req.resolve("@sideboard-ai/core"));
14249
14352
  } catch {
14250
14353
  return process.cwd();
14251
14354
  }
@@ -14256,32 +14359,32 @@ function cursorRunnerPath() {
14256
14359
  if (packaged) return packaged;
14257
14360
  const root = entryDir();
14258
14361
  const candidates = [
14259
- (0, import_node_path39.join)(root, "agents", "cursor-runner.js"),
14260
- (0, import_node_path39.join)(root, "agents", "cursor-runner.cjs"),
14362
+ (0, import_node_path40.join)(root, "agents", "cursor-runner.js"),
14363
+ (0, import_node_path40.join)(root, "agents", "cursor-runner.cjs"),
14261
14364
  // If somehow resolved from package root instead of dist/
14262
- (0, import_node_path39.join)(root, "dist", "agents", "cursor-runner.js"),
14263
- (0, import_node_path39.join)(root, "dist", "agents", "cursor-runner.cjs"),
14365
+ (0, import_node_path40.join)(root, "dist", "agents", "cursor-runner.js"),
14366
+ (0, import_node_path40.join)(root, "dist", "agents", "cursor-runner.cjs"),
14264
14367
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
14265
- (0, import_node_path39.join)(root, "cursor-runner.ts"),
14266
- (0, import_node_path39.join)(root, "src", "agents", "cursor-runner.ts")
14368
+ (0, import_node_path40.join)(root, "cursor-runner.ts"),
14369
+ (0, import_node_path40.join)(root, "src", "agents", "cursor-runner.ts")
14267
14370
  ];
14268
14371
  for (const candidate of candidates) {
14269
- if ((0, import_node_fs37.existsSync)(candidate)) return candidate;
14372
+ if ((0, import_node_fs38.existsSync)(candidate)) return candidate;
14270
14373
  }
14271
14374
  return candidates[0];
14272
14375
  }
14273
- var import_node_fs37, import_node_module3, import_node_path39, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14376
+ var import_node_fs38, import_node_module4, import_node_path40, import_node_url3, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14274
14377
  var init_cursor = __esm({
14275
14378
  "src/agents/cursor.ts"() {
14276
14379
  "use strict";
14277
- import_node_fs37 = require("fs");
14278
- import_node_module3 = require("module");
14279
- import_node_path39 = require("path");
14280
- import_node_url2 = require("url");
14281
- import_sdk = require("@cursor/sdk");
14380
+ import_node_fs38 = require("fs");
14381
+ import_node_module4 = require("module");
14382
+ import_node_path40 = require("path");
14383
+ import_node_url3 = require("url");
14282
14384
  init_run();
14283
14385
  init_app_settings();
14284
14386
  init_global_workspace();
14387
+ init_cursor_sdk_resolve();
14285
14388
  init_cursor_events();
14286
14389
  init_injected_mcp();
14287
14390
  init_cursor_ripgrep();
@@ -14289,7 +14392,7 @@ var init_cursor = __esm({
14289
14392
  init_packaged_runtime();
14290
14393
  init_turn_input();
14291
14394
  init_cursor_events();
14292
- import_meta2 = {};
14395
+ import_meta3 = {};
14293
14396
  FALLBACK_CURSOR_MODELS = [
14294
14397
  { id: "default", displayName: "Auto" },
14295
14398
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -14300,6 +14403,16 @@ var init_cursor = __esm({
14300
14403
  cursorAdapter = {
14301
14404
  kind: "cursor",
14302
14405
  async detect() {
14406
+ if (!isCursorSdkInstalled()) {
14407
+ return {
14408
+ agent: "cursor",
14409
+ installed: false,
14410
+ authenticated: false,
14411
+ linearMcp: false,
14412
+ warnings: [],
14413
+ reason: CURSOR_SDK_INSTALL_HINT
14414
+ };
14415
+ }
14303
14416
  const apiKey = resolveCursorApiKey();
14304
14417
  if (!apiKey) {
14305
14418
  return {
@@ -14428,7 +14541,7 @@ async function listOpencodeModels() {
14428
14541
  if (opencode === "opencode") {
14429
14542
  const which = await run("which", ["opencode"], { reject: false });
14430
14543
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
14431
- } else if (!(0, import_node_fs38.existsSync)(opencode)) {
14544
+ } else if (!(0, import_node_fs39.existsSync)(opencode)) {
14432
14545
  return FALLBACK_OPENCODE_MODELS;
14433
14546
  }
14434
14547
  const listed = await run(opencode, ["models"], { reject: false });
@@ -14458,11 +14571,11 @@ function usageFromOpencode(tokens) {
14458
14571
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
14459
14572
  };
14460
14573
  }
14461
- var import_node_fs38, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14574
+ var import_node_fs39, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14462
14575
  var init_opencode = __esm({
14463
14576
  "src/agents/opencode.ts"() {
14464
14577
  "use strict";
14465
- import_node_fs38 = require("fs");
14578
+ import_node_fs39 = require("fs");
14466
14579
  init_run();
14467
14580
  init_app_settings();
14468
14581
  init_global_workspace();
@@ -14490,7 +14603,7 @@ var init_opencode = __esm({
14490
14603
  async detect() {
14491
14604
  const opencode = resolveAgentExecutable("opencode");
14492
14605
  if (opencode !== "opencode") {
14493
- if (!(0, import_node_fs38.existsSync)(opencode)) {
14606
+ if (!(0, import_node_fs39.existsSync)(opencode)) {
14494
14607
  return {
14495
14608
  agent: "opencode",
14496
14609
  installed: false,
@@ -15209,14 +15322,14 @@ function accessTokenFromCredentialsJson(raw) {
15209
15322
  }
15210
15323
  }
15211
15324
  function claudeCredentialsPath() {
15212
- const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path40.join)((0, import_node_os13.homedir)(), ".claude");
15213
- return (0, import_node_path40.join)(root, ".credentials.json");
15325
+ const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path41.join)((0, import_node_os13.homedir)(), ".claude");
15326
+ return (0, import_node_path41.join)(root, ".credentials.json");
15214
15327
  }
15215
15328
  async function readFileAccessToken() {
15216
15329
  const path2 = claudeCredentialsPath();
15217
- if (!(0, import_node_fs39.existsSync)(path2)) return null;
15330
+ if (!(0, import_node_fs40.existsSync)(path2)) return null;
15218
15331
  try {
15219
- return accessTokenFromCredentialsJson((0, import_node_fs39.readFileSync)(path2, "utf8"));
15332
+ return accessTokenFromCredentialsJson((0, import_node_fs40.readFileSync)(path2, "utf8"));
15220
15333
  } catch {
15221
15334
  return null;
15222
15335
  }
@@ -15320,13 +15433,13 @@ async function getClaudePlanUsage(opts = {}) {
15320
15433
  })();
15321
15434
  return inflight;
15322
15435
  }
15323
- var import_node_fs39, import_node_os13, import_node_path40, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
15436
+ var import_node_fs40, import_node_os13, import_node_path41, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
15324
15437
  var init_claude_usage_client = __esm({
15325
15438
  "src/agents/claude-usage-client.ts"() {
15326
15439
  "use strict";
15327
- import_node_fs39 = require("fs");
15440
+ import_node_fs40 = require("fs");
15328
15441
  import_node_os13 = require("os");
15329
- import_node_path40 = require("path");
15442
+ import_node_path41 = require("path");
15330
15443
  init_run();
15331
15444
  init_fetch();
15332
15445
  init_app_settings();
@@ -15422,16 +15535,6 @@ async function whichOnPath(bin) {
15422
15535
  }
15423
15536
  async function installNpmGlobalPackage(opts) {
15424
15537
  enrichPathWithNpmGlobalBin();
15425
- if (opts.cliBin) {
15426
- const existing = await whichOnPath(opts.cliBin);
15427
- if (existing) {
15428
- return {
15429
- ok: true,
15430
- command: existing,
15431
- message: isConductorBundledCli(existing) ? `Using Conductor\u2019s ${opts.cliBin} at ${existing}. No extra install \u2014 Log in only if auth is missing.` : `Already on PATH: ${existing}`
15432
- };
15433
- }
15434
- }
15435
15538
  const result = await run("npm", ["install", "-g", opts.npmPackage], { reject: false });
15436
15539
  const ok = result.exitCode === 0;
15437
15540
  if (!ok) {
@@ -15468,6 +15571,33 @@ async function installNpmGlobalPackage(opts) {
15468
15571
  message: binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
15469
15572
  };
15470
15573
  }
15574
+ async function resolveExistingCli(agent) {
15575
+ if (agent === "cursor") return null;
15576
+ const exe = resolveAgentExecutable(agent);
15577
+ if ((exe.includes("/") || exe.includes("\\")) && (0, import_node_fs41.existsSync)(exe)) return exe;
15578
+ enrichPathWithNpmGlobalBin();
15579
+ return whichOnPath(CLI_BIN[agent]);
15580
+ }
15581
+ async function runVendorUpdate(existing, updateArgs) {
15582
+ const result = await run(existing, updateArgs, {
15583
+ reject: false,
15584
+ timeoutMs: 12e4
15585
+ });
15586
+ const command = `${existing} ${updateArgs.join(" ")}`;
15587
+ const ok = result.exitCode === 0;
15588
+ const detail = result.stdout.trim() || result.stderr.trim() || `exit ${result.exitCode}`;
15589
+ return {
15590
+ ok,
15591
+ command,
15592
+ exitCode: result.exitCode,
15593
+ stdout: result.stdout,
15594
+ stderr: result.stderr,
15595
+ message: ok ? isConductorBundledCli(existing) ? `Updated Conductor\u2019s CLI at ${existing}. ${detail}` : `Updated ${command}. ${detail}` : `Update failed (${command}): ${detail}`
15596
+ };
15597
+ }
15598
+ function isCurlInstaller(command) {
15599
+ return /curl\s| \|\s*bash/.test(command);
15600
+ }
15471
15601
  async function installAgent(agent) {
15472
15602
  const info = getAgentSetupInfo(agent);
15473
15603
  if (info.kind === "bundled-sdk" || info.kind === "api-key") {
@@ -15479,21 +15609,25 @@ async function installAgent(agent) {
15479
15609
  if (!info.installCommand) {
15480
15610
  return { ok: false, message: `No install command for ${agent}` };
15481
15611
  }
15482
- if (/curl\s| \|\s*bash/.test(info.installCommand) || !info.npmPackage) {
15483
- await openInSystemTerminal(info.installCommand);
15484
- return {
15485
- ok: true,
15486
- openedTerminal: true,
15487
- command: info.installCommand,
15488
- message: `Opened Terminal to run: ${info.installCommand}`
15489
- };
15612
+ const existing = await resolveExistingCli(agent);
15613
+ if (existing && info.updateArgs?.length) {
15614
+ return runVendorUpdate(existing, info.updateArgs);
15490
15615
  }
15491
- const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
15492
- return installNpmGlobalPackage({
15493
- npmPackage: info.npmPackage,
15494
- installCommand: info.installCommand,
15495
- cliBin
15496
- });
15616
+ if (info.npmPackage && !isCurlInstaller(info.installCommand)) {
15617
+ const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
15618
+ return installNpmGlobalPackage({
15619
+ npmPackage: info.npmPackage,
15620
+ installCommand: info.installCommand,
15621
+ cliBin
15622
+ });
15623
+ }
15624
+ await openInSystemTerminal(info.installCommand);
15625
+ return {
15626
+ ok: true,
15627
+ openedTerminal: true,
15628
+ command: info.installCommand,
15629
+ message: `Opened Terminal to run: ${info.installCommand}`
15630
+ };
15497
15631
  }
15498
15632
  async function loginAgent(agent) {
15499
15633
  const info = getAgentSetupInfo(agent);
@@ -15513,10 +15647,11 @@ async function loginAgent(agent) {
15513
15647
  message: `Opened Terminal to run: ${prepared}`
15514
15648
  };
15515
15649
  }
15516
- var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
15650
+ var import_node_fs41, SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
15517
15651
  var init_install = __esm({
15518
15652
  "src/agents/install.ts"() {
15519
15653
  "use strict";
15654
+ import_node_fs41 = require("fs");
15520
15655
  init_run();
15521
15656
  init_app_settings();
15522
15657
  init_path();
@@ -15528,7 +15663,8 @@ var init_install = __esm({
15528
15663
  docsUrl: "https://code.claude.com/docs/en/install",
15529
15664
  installCommand: "npm install -g @anthropic-ai/claude-code",
15530
15665
  loginCommand: "claude auth login",
15531
- npmPackage: "@anthropic-ai/claude-code"
15666
+ npmPackage: "@anthropic-ai/claude-code",
15667
+ updateArgs: ["update"]
15532
15668
  },
15533
15669
  codex: {
15534
15670
  agent: "codex",
@@ -15537,7 +15673,8 @@ var init_install = __esm({
15537
15673
  docsUrl: "https://github.com/openai/codex",
15538
15674
  installCommand: "npm install -g @openai/codex",
15539
15675
  loginCommand: "codex login",
15540
- npmPackage: "@openai/codex"
15676
+ npmPackage: "@openai/codex",
15677
+ updateArgs: ["update"]
15541
15678
  },
15542
15679
  opencode: {
15543
15680
  agent: "opencode",
@@ -15547,20 +15684,22 @@ var init_install = __esm({
15547
15684
  // Prefer the official installer; npm package name is opencode-ai.
15548
15685
  installCommand: "curl -fsSL https://opencode.ai/install | bash",
15549
15686
  loginCommand: "opencode auth login",
15550
- npmPackage: "opencode-ai@latest"
15687
+ npmPackage: "opencode-ai@latest",
15688
+ updateArgs: ["upgrade"]
15551
15689
  },
15552
15690
  cursor: {
15553
15691
  agent: "cursor",
15554
- kind: "bundled-sdk",
15555
- summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
15556
- docsUrl: "https://cursor.com/dashboard/integrations",
15557
- installCommand: null,
15558
- loginCommand: null
15692
+ kind: "cli",
15693
+ summary: "Install (or update) @cursor/sdk with npm \u2014 Sideboard does not pin it in the app. Then add a CURSOR_API_KEY.",
15694
+ docsUrl: "https://www.npmjs.com/package/@cursor/sdk",
15695
+ installCommand: "npm install -g @cursor/sdk",
15696
+ loginCommand: null,
15697
+ npmPackage: "@cursor/sdk"
15559
15698
  },
15560
15699
  brightsy: {
15561
15700
  agent: "brightsy",
15562
15701
  kind: "cli",
15563
- summary: "Install the Brightsy CLI, then run `brightsy login`.",
15702
+ summary: "Install (or update) the Brightsy CLI with npm, then run `brightsy login`.",
15564
15703
  docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
15565
15704
  installCommand: "npm install -g @brightsy/cli",
15566
15705
  loginCommand: "brightsy login",
@@ -15586,6 +15725,7 @@ var init_install = __esm({
15586
15725
  var agents_exports = {};
15587
15726
  __export(agents_exports, {
15588
15727
  CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
15728
+ CURSOR_SDK_INSTALL_HINT: () => CURSOR_SDK_INSTALL_HINT,
15589
15729
  ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
15590
15730
  PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
15591
15731
  allAdapters: () => allAdapters,
@@ -15619,6 +15759,7 @@ __export(agents_exports, {
15619
15759
  isConductorBundledCli: () => isConductorBundledCli,
15620
15760
  isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
15621
15761
  isCursorAutoModel: () => isCursorAutoModel,
15762
+ isCursorSdkInstalled: () => isCursorSdkInstalled,
15622
15763
  isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
15623
15764
  isSessionQuotaLimit: () => isSessionQuotaLimit,
15624
15765
  listAgentSetupInfo: () => listAgentSetupInfo,
@@ -15629,6 +15770,8 @@ __export(agents_exports, {
15629
15770
  listOpencodeModels: () => listOpencodeModels,
15630
15771
  loginAgent: () => loginAgent,
15631
15772
  mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
15773
+ npmGlobalNodeModules: () => npmGlobalNodeModules,
15774
+ npmGlobalPrefix: () => npmGlobalPrefix,
15632
15775
  openInSystemTerminal: () => openInSystemTerminal,
15633
15776
  opencodeAdapter: () => opencodeAdapter,
15634
15777
  parseClaudeUsagePayload: () => parseClaudeUsagePayload,
@@ -15640,6 +15783,7 @@ __export(agents_exports, {
15640
15783
  prepareTerminalCommand: () => prepareTerminalCommand,
15641
15784
  resolveCommandBinarySync: () => resolveCommandBinarySync,
15642
15785
  resolveCursorModelId: () => resolveCursorModelId,
15786
+ resolveCursorSdkRoot: () => resolveCursorSdkRoot,
15643
15787
  resolveLoginCommand: () => resolveLoginCommand,
15644
15788
  resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
15645
15789
  turnCostUsdFromCursorUsage: () => turnCostUsdFromCursorUsage,
@@ -15676,6 +15820,7 @@ var init_agents = __esm({
15676
15820
  init_claude_usage_client();
15677
15821
  init_orchestrator_capable();
15678
15822
  init_path();
15823
+ init_cursor_sdk_resolve();
15679
15824
  init_install();
15680
15825
  adapters = {
15681
15826
  claude: claudeAdapter,
@@ -15694,7 +15839,7 @@ function isAgentHostEnvKey(key) {
15694
15839
  }
15695
15840
  function stripHostToolingPath(pathValue) {
15696
15841
  if (!pathValue?.trim()) return "";
15697
- return pathValue.split(import_node_path41.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path41.delimiter);
15842
+ return pathValue.split(import_node_path42.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path42.delimiter);
15698
15843
  }
15699
15844
  function sanitizeAgentHostEnv(env, cwd) {
15700
15845
  for (const key of Object.keys(env)) {
@@ -15708,11 +15853,11 @@ function sanitizeAgentHostEnv(env, cwd) {
15708
15853
  }
15709
15854
  return env;
15710
15855
  }
15711
- var import_node_path41, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15856
+ var import_node_path42, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15712
15857
  var init_agent_host_env = __esm({
15713
15858
  "src/hook/agent-host-env.ts"() {
15714
15859
  "use strict";
15715
- import_node_path41 = require("path");
15860
+ import_node_path42 = require("path");
15716
15861
  DROP_EXACT = /* @__PURE__ */ new Set([
15717
15862
  "NODE_PATH",
15718
15863
  "NODE_ENV_ELECTRON_VITE",
@@ -15751,15 +15896,15 @@ var init_agent_host_env = __esm({
15751
15896
 
15752
15897
  // src/hook/worktree-pkg-cache.ts
15753
15898
  function worktreePkgCacheRoot(worktreePath) {
15754
- return (0, import_node_path42.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15899
+ return (0, import_node_path43.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15755
15900
  }
15756
15901
  function worktreePkgCacheEnv(worktreePath) {
15757
15902
  const root = worktreePkgCacheRoot(worktreePath);
15758
- const store = (0, import_node_path42.join)(root, "pnpm-store");
15759
- const pnpmCache = (0, import_node_path42.join)(root, "pnpm");
15760
- const npmCache = (0, import_node_path42.join)(root, "npm");
15761
- const nodeGyp = (0, import_node_path42.join)(root, "node-gyp");
15762
- const electron = (0, import_node_path42.join)(root, "electron");
15903
+ const store = (0, import_node_path43.join)(root, "pnpm-store");
15904
+ const pnpmCache = (0, import_node_path43.join)(root, "pnpm");
15905
+ const npmCache = (0, import_node_path43.join)(root, "npm");
15906
+ const nodeGyp = (0, import_node_path43.join)(root, "node-gyp");
15907
+ const electron = (0, import_node_path43.join)(root, "electron");
15763
15908
  return {
15764
15909
  npm_config_store_dir: store,
15765
15910
  PNPM_STORE_DIR: store,
@@ -15781,8 +15926,8 @@ function fillGroup(env, keys, values) {
15781
15926
  }
15782
15927
  }
15783
15928
  function ensureWorktreePkgCacheDirs(worktreePath) {
15784
- if (!(0, import_node_fs40.existsSync)(worktreePath)) return;
15785
- (0, import_node_fs40.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15929
+ if (!(0, import_node_fs42.existsSync)(worktreePath)) return;
15930
+ (0, import_node_fs42.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15786
15931
  }
15787
15932
  function applyWorktreePkgCacheEnv(env, worktreePath) {
15788
15933
  const cwd = worktreePath.trim();
@@ -15795,12 +15940,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15795
15940
  fillGroup(env, ["electron_config_cache"], next);
15796
15941
  ensureWorktreePkgCacheDirs(cwd);
15797
15942
  }
15798
- var import_node_fs40, import_node_path42, WORKTREE_PKG_CACHE_REL;
15943
+ var import_node_fs42, import_node_path43, WORKTREE_PKG_CACHE_REL;
15799
15944
  var init_worktree_pkg_cache = __esm({
15800
15945
  "src/hook/worktree-pkg-cache.ts"() {
15801
15946
  "use strict";
15802
- import_node_fs40 = require("fs");
15803
- import_node_path42 = require("path");
15947
+ import_node_fs42 = require("fs");
15948
+ import_node_path43 = require("path");
15804
15949
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15805
15950
  }
15806
15951
  });
@@ -17041,21 +17186,21 @@ function shouldRefreshReviewRequestTemplate(content) {
17041
17186
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
17042
17187
  }
17043
17188
  function readTextIfPresent(abs) {
17044
- if (!(0, import_node_fs41.existsSync)(abs)) return null;
17189
+ if (!(0, import_node_fs43.existsSync)(abs)) return null;
17045
17190
  try {
17046
- const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
17191
+ const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
17047
17192
  return content.trim() ? content : null;
17048
17193
  } catch {
17049
17194
  return null;
17050
17195
  }
17051
17196
  }
17052
17197
  function readLocalGuidelines(worktreePath) {
17053
- const localAbs = (0, import_node_path43.join)(worktreePath, REVIEW_REQUEST_PATH);
17198
+ const localAbs = (0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH);
17054
17199
  const localContent = readTextIfPresent(localAbs);
17055
17200
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
17056
17201
  return { path: REVIEW_REQUEST_PATH, content: localContent };
17057
17202
  }
17058
- const legacyAbs = (0, import_node_path43.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17203
+ const legacyAbs = (0, import_node_path44.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17059
17204
  const legacyContent = readTextIfPresent(legacyAbs);
17060
17205
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
17061
17206
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -17079,27 +17224,27 @@ function contextGuidelines(content, source) {
17079
17224
  };
17080
17225
  }
17081
17226
  function writeContextGuidelines(worktreePath, content) {
17082
- const abs = (0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH);
17083
- (0, import_node_fs41.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
17227
+ const abs = (0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH);
17228
+ (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
17084
17229
  const body = content.endsWith("\n") ? content : `${content}
17085
17230
  `;
17086
- (0, import_node_fs41.writeFileSync)(abs, body, "utf8");
17231
+ (0, import_node_fs43.writeFileSync)(abs, body, "utf8");
17087
17232
  return body;
17088
17233
  }
17089
17234
  function readSideboardReview(worktreePath, repoPath) {
17090
- const fromWorktree = readTextIfPresent((0, import_node_path43.join)(worktreePath, REPO_REVIEW_PATH));
17235
+ const fromWorktree = readTextIfPresent((0, import_node_path44.join)(worktreePath, REPO_REVIEW_PATH));
17091
17236
  if (fromWorktree) return fromWorktree;
17092
17237
  const repo = repoPath?.replace(/\/+$/, "");
17093
17238
  const wt = worktreePath.replace(/\/+$/, "");
17094
17239
  if (!repo || repo === wt) return null;
17095
- return readTextIfPresent((0, import_node_path43.join)(repo, REPO_REVIEW_PATH));
17240
+ return readTextIfPresent((0, import_node_path44.join)(repo, REPO_REVIEW_PATH));
17096
17241
  }
17097
17242
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
17098
- const skillContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_SKILL_PATH));
17243
+ const skillContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_SKILL_PATH));
17099
17244
  if (skillContent) {
17100
17245
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
17101
17246
  }
17102
- const contextContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH));
17247
+ const contextContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH));
17103
17248
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
17104
17249
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
17105
17250
  }
@@ -17137,7 +17282,7 @@ function buildReviewRequestAttachment(content, opts) {
17137
17282
  };
17138
17283
  }
17139
17284
  function readExistingReviewRequestFile(worktreePath) {
17140
- return readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path43.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
17285
+ return readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path44.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
17141
17286
  }
17142
17287
  async function requestReview(threadRef, send2) {
17143
17288
  const from = findThreadByRef(threadRef);
@@ -17164,13 +17309,13 @@ async function requestReview(threadRef, send2) {
17164
17309
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
17165
17310
  return { tab: started, from };
17166
17311
  }
17167
- var import_node_crypto9, import_node_fs41, import_node_path43, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
17312
+ var import_node_crypto9, import_node_fs43, import_node_path44, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
17168
17313
  var init_request_review = __esm({
17169
17314
  "src/review/request-review.ts"() {
17170
17315
  "use strict";
17171
17316
  import_node_crypto9 = require("crypto");
17172
- import_node_fs41 = require("fs");
17173
- import_node_path43 = require("path");
17317
+ import_node_fs43 = require("fs");
17318
+ import_node_path44 = require("path");
17174
17319
  init_global_workspace();
17175
17320
  init_chat_tabs();
17176
17321
  init_thread_store();
@@ -17196,9 +17341,9 @@ function matchSimpleGlob(pattern, name) {
17196
17341
  return new RegExp(`^${escaped}$`).test(name);
17197
17342
  }
17198
17343
  function readWorktreeInclude(repoPath) {
17199
- const path2 = (0, import_node_path44.join)(repoPath, ".worktreeinclude");
17200
- if (!(0, import_node_fs42.existsSync)(path2)) return [];
17201
- return (0, import_node_fs42.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17344
+ const path2 = (0, import_node_path45.join)(repoPath, ".worktreeinclude");
17345
+ if (!(0, import_node_fs44.existsSync)(path2)) return [];
17346
+ return (0, import_node_fs44.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17202
17347
  }
17203
17348
  function resolveFilesToCopy(repoPath) {
17204
17349
  const fromInclude = readWorktreeInclude(repoPath);
@@ -17208,10 +17353,10 @@ function resolveFilesToCopy(repoPath) {
17208
17353
  if (settings?.fileIncludeGlobs?.length) {
17209
17354
  const matched = [];
17210
17355
  try {
17211
- for (const entry of (0, import_node_fs42.readdirSync)(repoPath, { withFileTypes: true })) {
17356
+ for (const entry of (0, import_node_fs44.readdirSync)(repoPath, { withFileTypes: true })) {
17212
17357
  if (!entry.isFile()) continue;
17213
17358
  for (const glob of settings.fileIncludeGlobs) {
17214
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path44.basename)(glob), entry.name)) {
17359
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path45.basename)(glob), entry.name)) {
17215
17360
  matched.push(entry.name);
17216
17361
  break;
17217
17362
  }
@@ -17223,7 +17368,7 @@ function resolveFilesToCopy(repoPath) {
17223
17368
  }
17224
17369
  const defaults = [];
17225
17370
  try {
17226
- for (const entry of (0, import_node_fs42.readdirSync)(repoPath, { withFileTypes: true })) {
17371
+ for (const entry of (0, import_node_fs44.readdirSync)(repoPath, { withFileTypes: true })) {
17227
17372
  if (entry.isFile() && entry.name.startsWith(".env")) {
17228
17373
  defaults.push(entry.name);
17229
17374
  }
@@ -17237,11 +17382,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
17237
17382
  const patterns = resolveFilesToCopy(repoPath);
17238
17383
  const copied = [];
17239
17384
  for (const rel of patterns) {
17240
- const src = (0, import_node_path44.join)(repoPath, rel);
17241
- if (!(0, import_node_fs42.existsSync)(src)) continue;
17242
- const dest = (0, import_node_path44.join)(worktreePath, rel);
17243
- (0, import_node_fs42.mkdirSync)((0, import_node_path44.dirname)(dest), { recursive: true });
17244
- (0, import_node_fs42.copyFileSync)(src, dest);
17385
+ const src = (0, import_node_path45.join)(repoPath, rel);
17386
+ if (!(0, import_node_fs44.existsSync)(src)) continue;
17387
+ const dest = (0, import_node_path45.join)(worktreePath, rel);
17388
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
17389
+ (0, import_node_fs44.copyFileSync)(src, dest);
17245
17390
  copied.push(rel);
17246
17391
  }
17247
17392
  return copied;
@@ -17276,7 +17421,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
17276
17421
  const env = stripNestedElectronEnv({
17277
17422
  ...baseEnv ?? process.env
17278
17423
  });
17279
- const name = opts.workspaceName ?? (0, import_node_path44.basename)(opts.worktreePath);
17424
+ const name = opts.workspaceName ?? (0, import_node_path45.basename)(opts.worktreePath);
17280
17425
  const ports = opts.ports ?? [];
17281
17426
  const primary = ports[0];
17282
17427
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -17611,14 +17756,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
17611
17756
  throw err;
17612
17757
  }
17613
17758
  }
17614
- var import_node_fs42, import_node_child_process5, import_node_net, import_node_path44, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17759
+ var import_node_fs44, import_node_child_process5, import_node_net, import_node_path45, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17615
17760
  var init_conductor = __esm({
17616
17761
  "src/hook/conductor.ts"() {
17617
17762
  "use strict";
17618
- import_node_fs42 = require("fs");
17763
+ import_node_fs44 = require("fs");
17619
17764
  import_node_child_process5 = require("child_process");
17620
17765
  import_node_net = require("net");
17621
- import_node_path44 = require("path");
17766
+ import_node_path45 = require("path");
17622
17767
  import_execa4 = require("execa");
17623
17768
  import_node_readline3 = require("readline");
17624
17769
  init_settings();
@@ -17646,9 +17791,9 @@ async function findOrphanWorktrees(repoPaths) {
17646
17791
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17647
17792
  );
17648
17793
  const homeRoot = sideboardWorkspacesDir();
17649
- if ((0, import_node_fs43.existsSync)(homeRoot)) {
17794
+ if ((0, import_node_fs45.existsSync)(homeRoot)) {
17650
17795
  try {
17651
- for (const entry of (0, import_node_fs43.readdirSync)(homeRoot, { withFileTypes: true })) {
17796
+ for (const entry of (0, import_node_fs45.readdirSync)(homeRoot, { withFileTypes: true })) {
17652
17797
  if (!entry.isDirectory()) continue;
17653
17798
  void entry;
17654
17799
  }
@@ -17658,7 +17803,7 @@ async function findOrphanWorktrees(repoPaths) {
17658
17803
  const orphans = [];
17659
17804
  const seen = /* @__PURE__ */ new Set();
17660
17805
  for (const repoPath of repos) {
17661
- if (!repoPath || !(0, import_node_fs43.existsSync)(repoPath)) continue;
17806
+ if (!repoPath || !(0, import_node_fs45.existsSync)(repoPath)) continue;
17662
17807
  try {
17663
17808
  const wts = await listWorktrees(repoPath);
17664
17809
  for (const wt of wts) {
@@ -17669,7 +17814,7 @@ async function findOrphanWorktrees(repoPaths) {
17669
17814
  seen.add(path2);
17670
17815
  let mtimeMs = 0;
17671
17816
  try {
17672
- mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17817
+ mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
17673
17818
  } catch {
17674
17819
  mtimeMs = 0;
17675
17820
  }
@@ -17679,16 +17824,16 @@ async function findOrphanWorktrees(repoPaths) {
17679
17824
  }
17680
17825
  try {
17681
17826
  const root = worktreesRoot(repoPath);
17682
- if ((0, import_node_fs43.existsSync)(root)) {
17683
- for (const entry of (0, import_node_fs43.readdirSync)(root, { withFileTypes: true })) {
17827
+ if ((0, import_node_fs45.existsSync)(root)) {
17828
+ for (const entry of (0, import_node_fs45.readdirSync)(root, { withFileTypes: true })) {
17684
17829
  if (!entry.isDirectory()) continue;
17685
- const path2 = (0, import_node_path45.join)(root, entry.name).replace(/\/$/, "");
17830
+ const path2 = (0, import_node_path46.join)(root, entry.name).replace(/\/$/, "");
17686
17831
  if (known.has(path2) || seen.has(path2)) continue;
17687
- if (!(0, import_node_fs43.existsSync)((0, import_node_path45.join)(path2, ".git"))) continue;
17832
+ if (!(0, import_node_fs45.existsSync)((0, import_node_path46.join)(path2, ".git"))) continue;
17688
17833
  seen.add(path2);
17689
17834
  let mtimeMs = 0;
17690
17835
  try {
17691
- mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17836
+ mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
17692
17837
  } catch {
17693
17838
  mtimeMs = Date.now();
17694
17839
  }
@@ -17749,12 +17894,12 @@ function worktreeCleanupSettings() {
17749
17894
  autoCleanupOrphans: a.autoCleanupOrphans
17750
17895
  };
17751
17896
  }
17752
- var import_node_fs43, import_node_path45;
17897
+ var import_node_fs45, import_node_path46;
17753
17898
  var init_orphan_cleanup = __esm({
17754
17899
  "src/git/orphan-cleanup.ts"() {
17755
17900
  "use strict";
17756
- import_node_fs43 = require("fs");
17757
- import_node_path45 = require("path");
17901
+ import_node_fs45 = require("fs");
17902
+ import_node_path46 = require("path");
17758
17903
  init_worktree();
17759
17904
  init_thread_store();
17760
17905
  init_paths();
@@ -17929,12 +18074,12 @@ async function cloneRepoIntoSideboard(opts) {
17929
18074
  if (!url) throw new Error("Clone URL is required");
17930
18075
  let name = opts.name?.trim();
17931
18076
  if (!name) {
17932
- const leaf = (0, import_node_path46.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18077
+ const leaf = (0, import_node_path47.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17933
18078
  name = leaf || "repo";
17934
18079
  }
17935
18080
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
17936
- const dest = (0, import_node_path46.join)(sideboardReposDir(), name);
17937
- if ((0, import_node_fs44.existsSync)(dest)) {
18081
+ const dest = (0, import_node_path47.join)(sideboardReposDir(), name);
18082
+ if ((0, import_node_fs46.existsSync)(dest)) {
17938
18083
  const repoPath2 = await resolveRepoRoot(dest);
17939
18084
  const workspace2 = await ensureWorkspace(repoPath2);
17940
18085
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -17949,12 +18094,12 @@ async function cloneRepoIntoSideboard(opts) {
17949
18094
  const workspace = await ensureWorkspace(repoPath);
17950
18095
  return { repoPath, workspace };
17951
18096
  }
17952
- var import_node_fs44, import_node_path46, import_execa6;
18097
+ var import_node_fs46, import_node_path47, import_execa6;
17953
18098
  var init_clone_repo = __esm({
17954
18099
  "src/git/clone-repo.ts"() {
17955
18100
  "use strict";
17956
- import_node_fs44 = require("fs");
17957
- import_node_path46 = require("path");
18101
+ import_node_fs46 = require("fs");
18102
+ import_node_path47 = require("path");
17958
18103
  import_execa6 = require("execa");
17959
18104
  init_paths();
17960
18105
  init_workspaces();
@@ -18075,24 +18220,24 @@ function jobTreeAlive(pid) {
18075
18220
  return jobAlive(pid) || processGroupAlive(pid);
18076
18221
  }
18077
18222
  function readIntFile(file) {
18078
- if (!(0, import_node_fs45.existsSync)(file)) return null;
18079
- const n = Number.parseInt((0, import_node_fs45.readFileSync)(file, "utf8").trim(), 10);
18223
+ if (!(0, import_node_fs47.existsSync)(file)) return null;
18224
+ const n = Number.parseInt((0, import_node_fs47.readFileSync)(file, "utf8").trim(), 10);
18080
18225
  return Number.isInteger(n) ? n : null;
18081
18226
  }
18082
18227
  function jobDir(root, id, legacy = false) {
18083
- return (0, import_node_path47.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18228
+ return (0, import_node_path48.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18084
18229
  }
18085
18230
  function resolveJobDir(root, id) {
18086
18231
  const modern = jobDir(root, id, false);
18087
- if ((0, import_node_fs45.existsSync)(modern)) return modern;
18232
+ if ((0, import_node_fs47.existsSync)(modern)) return modern;
18088
18233
  const legacy = jobDir(root, id, true);
18089
- if ((0, import_node_fs45.existsSync)(legacy)) return legacy;
18234
+ if ((0, import_node_fs47.existsSync)(legacy)) return legacy;
18090
18235
  return modern;
18091
18236
  }
18092
18237
  function listJobIdsIn(root, rel) {
18093
- const dir = (0, import_node_path47.join)(root, rel);
18094
- if (!(0, import_node_fs45.existsSync)(dir)) return [];
18095
- return (0, import_node_fs45.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
18238
+ const dir = (0, import_node_path48.join)(root, rel);
18239
+ if (!(0, import_node_fs47.existsSync)(dir)) return [];
18240
+ return (0, import_node_fs47.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
18096
18241
  }
18097
18242
  function listRunningDetachedJobs(worktreePath) {
18098
18243
  const root = worktreePath.trim();
@@ -18104,7 +18249,7 @@ function listRunningDetachedJobs(worktreePath) {
18104
18249
  const running = [];
18105
18250
  for (const id of ids) {
18106
18251
  const dir = resolveJobDir(root, id);
18107
- const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18252
+ const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18108
18253
  if (jobTreeAlive(pid)) running.push(id);
18109
18254
  }
18110
18255
  return running.sort();
@@ -18187,8 +18332,8 @@ function planJobContinue(opts) {
18187
18332
  return { action: "none" };
18188
18333
  }
18189
18334
  function tailProgress(logFile, maxLines = 12) {
18190
- if (!(0, import_node_fs45.existsSync)(logFile)) return "(no log yet)";
18191
- const lines = (0, import_node_fs45.readFileSync)(logFile, "utf8").split("\n");
18335
+ if (!(0, import_node_fs47.existsSync)(logFile)) return "(no log yet)";
18336
+ const lines = (0, import_node_fs47.readFileSync)(logFile, "utf8").split("\n");
18192
18337
  return lines.slice(-maxLines).join("\n");
18193
18338
  }
18194
18339
  function lastProgressLine(progress) {
@@ -18196,8 +18341,8 @@ function lastProgressLine(progress) {
18196
18341
  return last ? last.slice(0, 72) : void 0;
18197
18342
  }
18198
18343
  function readLogLines(file) {
18199
- if (!(0, import_node_fs45.existsSync)(file)) return [];
18200
- const lines = (0, import_node_fs45.readFileSync)(file, "utf8").split("\n");
18344
+ if (!(0, import_node_fs47.existsSync)(file)) return [];
18345
+ const lines = (0, import_node_fs47.readFileSync)(file, "utf8").split("\n");
18201
18346
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
18202
18347
  return lines;
18203
18348
  }
@@ -18208,15 +18353,15 @@ function takeDelta(logFile, cursorFile) {
18208
18353
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
18209
18354
  }
18210
18355
  function snapshotJob(dir) {
18211
- const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18356
+ const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18212
18357
  const running = jobTreeAlive(pid);
18213
18358
  return {
18214
18359
  pid,
18215
18360
  running,
18216
- exitCode: readIntFile((0, import_node_path47.join)(dir, "exit")),
18217
- log: (0, import_node_path47.join)(dir, "log"),
18218
- cursor: (0, import_node_path47.join)(dir, "present.cursor"),
18219
- progress: tailProgress((0, import_node_path47.join)(dir, "log"))
18361
+ exitCode: readIntFile((0, import_node_path48.join)(dir, "exit")),
18362
+ log: (0, import_node_path48.join)(dir, "log"),
18363
+ cursor: (0, import_node_path48.join)(dir, "present.cursor"),
18364
+ progress: tailProgress((0, import_node_path48.join)(dir, "log"))
18220
18365
  };
18221
18366
  }
18222
18367
  function toResult(id, snap, extra) {
@@ -18225,8 +18370,8 @@ function toResult(id, snap, extra) {
18225
18370
  const stillRunning = snap.running && !ok;
18226
18371
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
18227
18372
  try {
18228
- (0, import_node_fs45.mkdirSync)((0, import_node_path47.dirname)(snap.cursor), { recursive: true });
18229
- (0, import_node_fs45.writeFileSync)(snap.cursor, `${nextCursor}
18373
+ (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(snap.cursor), { recursive: true });
18374
+ (0, import_node_fs47.writeFileSync)(snap.cursor, `${nextCursor}
18230
18375
  `);
18231
18376
  } catch {
18232
18377
  }
@@ -18255,7 +18400,7 @@ async function waitForDetachedJob(cwd, id, opts) {
18255
18400
  const dir = resolveJobDir(root, jobId);
18256
18401
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
18257
18402
  const sleep2 = opts?.sleep ?? sleepMs;
18258
- if (!(0, import_node_fs45.existsSync)(dir)) {
18403
+ if (!(0, import_node_fs47.existsSync)(dir)) {
18259
18404
  return {
18260
18405
  stillRunning: false,
18261
18406
  ok: false,
@@ -18301,10 +18446,10 @@ function killProcessTree(pid, signal) {
18301
18446
  }
18302
18447
  function appendJobLog(logFile, line) {
18303
18448
  try {
18304
- (0, import_node_fs45.mkdirSync)((0, import_node_path47.dirname)(logFile), { recursive: true });
18449
+ (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(logFile), { recursive: true });
18305
18450
  const body = line.endsWith("\n") ? line : `${line}
18306
18451
  `;
18307
- (0, import_node_fs45.appendFileSync)(logFile, body);
18452
+ (0, import_node_fs47.appendFileSync)(logFile, body);
18308
18453
  } catch {
18309
18454
  }
18310
18455
  }
@@ -18314,7 +18459,7 @@ async function stopDetachedJob(cwd, id, opts) {
18314
18459
  const dir = resolveJobDir(root, jobId);
18315
18460
  const sleep2 = opts?.sleep ?? sleepMs;
18316
18461
  const why = opts?.reason?.trim() ?? "";
18317
- if (!(0, import_node_fs45.existsSync)(dir)) {
18462
+ if (!(0, import_node_fs47.existsSync)(dir)) {
18318
18463
  return {
18319
18464
  stillRunning: false,
18320
18465
  ok: false,
@@ -18350,10 +18495,10 @@ async function stopDetachedJob(cwd, id, opts) {
18350
18495
  killProcessTree(targetPid, "SIGKILL");
18351
18496
  await sleep2(100);
18352
18497
  }
18353
- const exitFile = (0, import_node_path47.join)(dir, "exit");
18354
- if (!(0, import_node_fs45.existsSync)(exitFile)) {
18498
+ const exitFile = (0, import_node_path48.join)(dir, "exit");
18499
+ if (!(0, import_node_fs47.existsSync)(exitFile)) {
18355
18500
  try {
18356
- (0, import_node_fs45.writeFileSync)(exitFile, "1\n");
18501
+ (0, import_node_fs47.writeFileSync)(exitFile, "1\n");
18357
18502
  } catch {
18358
18503
  }
18359
18504
  }
@@ -18373,12 +18518,12 @@ async function stopDetachedJob(cwd, id, opts) {
18373
18518
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
18374
18519
  };
18375
18520
  }
18376
- var import_node_fs45, import_node_path47, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
18521
+ var import_node_fs47, import_node_path48, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
18377
18522
  var init_wait_for_job = __esm({
18378
18523
  "src/mcp/wait-for-job.ts"() {
18379
18524
  "use strict";
18380
- import_node_fs45 = require("fs");
18381
- import_node_path47 = require("path");
18525
+ import_node_fs47 = require("fs");
18526
+ import_node_path48 = require("path");
18382
18527
  init_workspace_scratch();
18383
18528
  init_wait_for_turn();
18384
18529
  MAX_JOB_CONTINUES = 8;
@@ -19923,7 +20068,7 @@ function reuseLiveThread(input, repoPath, match) {
19923
20068
  }
19924
20069
  async function createThread(input, _onSetupLine) {
19925
20070
  const repoPath = await resolveRepoRoot(input.repoPath);
19926
- if (!(0, import_node_fs46.existsSync)(repoPath)) {
20071
+ if (!(0, import_node_fs48.existsSync)(repoPath)) {
19927
20072
  throw new Error(`Repo not found: ${repoPath}`);
19928
20073
  }
19929
20074
  const reused = reuseLiveThread(input, repoPath, {
@@ -20108,11 +20253,11 @@ async function listLinearIssues(agent, repoPath) {
20108
20253
  }
20109
20254
  return adapter.listLinearIssues(repoPath);
20110
20255
  }
20111
- var import_node_fs46;
20256
+ var import_node_fs48;
20112
20257
  var init_create = __esm({
20113
20258
  "src/threads/create.ts"() {
20114
20259
  "use strict";
20115
- import_node_fs46 = require("fs");
20260
+ import_node_fs48 = require("fs");
20116
20261
  init_detect();
20117
20262
  init_worktree();
20118
20263
  init_home_board();
@@ -20264,20 +20409,20 @@ function writeTurnLive(threadId, progress) {
20264
20409
  const path2 = threadLivePath(threadId);
20265
20410
  const tmp = `${path2}.${process.pid}.tmp`;
20266
20411
  try {
20267
- (0, import_node_fs47.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20268
- (0, import_node_fs47.renameSync)(tmp, path2);
20412
+ (0, import_node_fs49.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20413
+ (0, import_node_fs49.renameSync)(tmp, path2);
20269
20414
  } catch {
20270
20415
  try {
20271
- (0, import_node_fs47.unlinkSync)(tmp);
20416
+ (0, import_node_fs49.unlinkSync)(tmp);
20272
20417
  } catch {
20273
20418
  }
20274
20419
  }
20275
20420
  }
20276
20421
  function readTurnLive(threadId) {
20277
20422
  const path2 = threadLivePath(threadId);
20278
- if (!(0, import_node_fs47.existsSync)(path2)) return null;
20423
+ if (!(0, import_node_fs49.existsSync)(path2)) return null;
20279
20424
  try {
20280
- const raw = JSON.parse((0, import_node_fs47.readFileSync)(path2, "utf8"));
20425
+ const raw = JSON.parse((0, import_node_fs49.readFileSync)(path2, "utf8"));
20281
20426
  if (!raw || typeof raw.summary !== "string") return null;
20282
20427
  return raw;
20283
20428
  } catch {
@@ -20289,17 +20434,17 @@ function clearTurnLive(threadId) {
20289
20434
  if (buf?.timer) clearTimeout(buf.timer);
20290
20435
  buffers.delete(threadId);
20291
20436
  const path2 = threadLivePath(threadId);
20292
- if (!(0, import_node_fs47.existsSync)(path2)) return;
20437
+ if (!(0, import_node_fs49.existsSync)(path2)) return;
20293
20438
  try {
20294
- (0, import_node_fs47.unlinkSync)(path2);
20439
+ (0, import_node_fs49.unlinkSync)(path2);
20295
20440
  } catch {
20296
20441
  }
20297
20442
  }
20298
- var import_node_fs47, buffers, FLUSH_MS, MAX_PARTS;
20443
+ var import_node_fs49, buffers, FLUSH_MS, MAX_PARTS;
20299
20444
  var init_turn_live = __esm({
20300
20445
  "src/store/turn-live.ts"() {
20301
20446
  "use strict";
20302
- import_node_fs47 = require("fs");
20447
+ import_node_fs49 = require("fs");
20303
20448
  init_message_parts();
20304
20449
  init_paths();
20305
20450
  buffers = /* @__PURE__ */ new Map();
@@ -20541,12 +20686,12 @@ var init_quota_failover = __esm({
20541
20686
  });
20542
20687
 
20543
20688
  // src/threads/adopt.ts
20544
- function thisModuleFile() {
20689
+ function thisModuleFile2() {
20545
20690
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
20546
- return cjsFile || process.argv[1] || (0, import_node_path48.join)(process.cwd(), "package.json");
20691
+ return cjsFile || process.argv[1] || (0, import_node_path49.join)(process.cwd(), "package.json");
20547
20692
  }
20548
20693
  function openReadonlySqlite(file) {
20549
- const req = (0, import_node_module4.createRequire)(thisModuleFile());
20694
+ const req = (0, import_node_module5.createRequire)(thisModuleFile2());
20550
20695
  const Database = req("better-sqlite3");
20551
20696
  return new Database(file, { readonly: true, fileMustExist: true });
20552
20697
  }
@@ -20561,21 +20706,21 @@ function mapAgentType(raw) {
20561
20706
  return null;
20562
20707
  }
20563
20708
  function resolveConductorCursorAgentId(workspacePath) {
20564
- if (!workspacePath || !(0, import_node_fs48.existsSync)(CURSOR_SDK_STORE)) return null;
20709
+ if (!workspacePath || !(0, import_node_fs50.existsSync)(CURSOR_SDK_STORE)) return null;
20565
20710
  const normalized = workspacePath.replace(/\/$/, "");
20566
20711
  let best = null;
20567
20712
  let hashes;
20568
20713
  try {
20569
- hashes = (0, import_node_fs48.readdirSync)(CURSOR_SDK_STORE);
20714
+ hashes = (0, import_node_fs50.readdirSync)(CURSOR_SDK_STORE);
20570
20715
  } catch {
20571
20716
  return null;
20572
20717
  }
20573
20718
  for (const hash of hashes) {
20574
- const agentsFile = (0, import_node_path48.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20575
- if (!(0, import_node_fs48.existsSync)(agentsFile)) continue;
20719
+ const agentsFile = (0, import_node_path49.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20720
+ if (!(0, import_node_fs50.existsSync)(agentsFile)) continue;
20576
20721
  let text7;
20577
20722
  try {
20578
- text7 = (0, import_node_fs48.readFileSync)(agentsFile, "utf8");
20723
+ text7 = (0, import_node_fs50.readFileSync)(agentsFile, "utf8");
20579
20724
  } catch {
20580
20725
  continue;
20581
20726
  }
@@ -20599,7 +20744,7 @@ function resolveConductorCursorAgentId(workspacePath) {
20599
20744
  return best?.agentId ?? null;
20600
20745
  }
20601
20746
  async function adoptThread(input) {
20602
- if (!(0, import_node_fs48.existsSync)(input.worktreePath)) {
20747
+ if (!(0, import_node_fs50.existsSync)(input.worktreePath)) {
20603
20748
  throw new Error(`Worktree not found: ${input.worktreePath}`);
20604
20749
  }
20605
20750
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -20628,18 +20773,18 @@ function conductorDbPath() {
20628
20773
  return CONDUCTOR_DB;
20629
20774
  }
20630
20775
  function listConductorWorkspaces() {
20631
- if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20776
+ if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
20632
20777
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20633
20778
  }
20634
- const tmp = (0, import_node_fs48.mkdtempSync)((0, import_node_path48.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20635
- const snapshot = (0, import_node_path48.join)(tmp, "conductor.db");
20779
+ const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20780
+ const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
20636
20781
  try {
20637
- (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20782
+ (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
20638
20783
  for (const suffix of ["-wal", "-shm"]) {
20639
20784
  const src = `${CONDUCTOR_DB}${suffix}`;
20640
- if ((0, import_node_fs48.existsSync)(src)) {
20785
+ if ((0, import_node_fs50.existsSync)(src)) {
20641
20786
  try {
20642
- (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20787
+ (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
20643
20788
  } catch {
20644
20789
  }
20645
20790
  }
@@ -20715,22 +20860,22 @@ function listConductorWorkspaces() {
20715
20860
  db.close();
20716
20861
  }
20717
20862
  } finally {
20718
- (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20863
+ (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
20719
20864
  }
20720
20865
  }
20721
20866
  function importConductorWorkspace(workspaceId) {
20722
- if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20867
+ if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
20723
20868
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20724
20869
  }
20725
- const tmp = (0, import_node_fs48.mkdtempSync)((0, import_node_path48.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20726
- const snapshot = (0, import_node_path48.join)(tmp, "conductor.db");
20870
+ const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20871
+ const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
20727
20872
  try {
20728
- (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20873
+ (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
20729
20874
  for (const suffix of ["-wal", "-shm"]) {
20730
20875
  const src = `${CONDUCTOR_DB}${suffix}`;
20731
- if ((0, import_node_fs48.existsSync)(src)) {
20876
+ if ((0, import_node_fs50.existsSync)(src)) {
20732
20877
  try {
20733
- (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20878
+ (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
20734
20879
  } catch {
20735
20880
  }
20736
20881
  }
@@ -20748,7 +20893,7 @@ function importConductorWorkspace(workspaceId) {
20748
20893
  ).get(workspaceId);
20749
20894
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
20750
20895
  const worktreePath = String(row.workspacePath);
20751
- if (!(0, import_node_fs48.existsSync)(worktreePath)) {
20896
+ if (!(0, import_node_fs50.existsSync)(worktreePath)) {
20752
20897
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
20753
20898
  }
20754
20899
  let sessionId = null;
@@ -20811,31 +20956,31 @@ function importConductorWorkspace(workspaceId) {
20811
20956
  db.close();
20812
20957
  }
20813
20958
  } finally {
20814
- (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20959
+ (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
20815
20960
  }
20816
20961
  }
20817
20962
  async function importConductorWorkspaceAsync(workspaceId) {
20818
20963
  return importConductorWorkspace(workspaceId);
20819
20964
  }
20820
- var import_node_child_process6, import_node_fs48, import_node_os14, import_node_path48, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
20965
+ var import_node_child_process6, import_node_fs50, import_node_os14, import_node_path49, import_node_module5, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
20821
20966
  var init_adopt = __esm({
20822
20967
  "src/threads/adopt.ts"() {
20823
20968
  "use strict";
20824
20969
  import_node_child_process6 = require("child_process");
20825
- import_node_fs48 = require("fs");
20970
+ import_node_fs50 = require("fs");
20826
20971
  import_node_os14 = require("os");
20827
- import_node_path48 = require("path");
20828
- import_node_module4 = require("module");
20972
+ import_node_path49 = require("path");
20973
+ import_node_module5 = require("module");
20829
20974
  init_worktree();
20830
20975
  init_thread_store();
20831
- CONDUCTOR_APP_SUPPORT = (0, import_node_path48.join)(
20976
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path49.join)(
20832
20977
  process.env.HOME ?? "",
20833
20978
  "Library",
20834
20979
  "Application Support",
20835
20980
  "com.conductor.app"
20836
20981
  );
20837
- CONDUCTOR_DB = (0, import_node_path48.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20838
- CURSOR_SDK_STORE = (0, import_node_path48.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20982
+ CONDUCTOR_DB = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20983
+ CURSOR_SDK_STORE = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20839
20984
  }
20840
20985
  });
20841
20986
 
@@ -20902,7 +21047,7 @@ async function openStackLayer(input, _onSetupLine) {
20902
21047
  let createdWorktree = false;
20903
21048
  const trees = await listWorktrees(repoPath);
20904
21049
  const checkedOut = trees.find((w) => w.branch === branchName);
20905
- if (checkedOut?.path && (0, import_node_fs49.existsSync)(checkedOut.path)) {
21050
+ if (checkedOut?.path && (0, import_node_fs51.existsSync)(checkedOut.path)) {
20906
21051
  if (input.reuseExistingWorktree !== false) {
20907
21052
  worktreePath = checkedOut.path;
20908
21053
  } else {
@@ -21044,7 +21189,7 @@ async function initStackFromThread(input, onSetupLine) {
21044
21189
  async function createPrStack(input, onSetupLine) {
21045
21190
  await requireAgent(input.agent);
21046
21191
  const repoPath = await resolveRepoRoot(input.repoPath);
21047
- if (!(0, import_node_fs49.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21192
+ if (!(0, import_node_fs51.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21048
21193
  if (!input.branches.length) throw new Error("At least one branch name required");
21049
21194
  const status = await detectGhStack(repoPath);
21050
21195
  if (!status.available) throw new Error(status.reason);
@@ -21111,7 +21256,7 @@ async function createPrStack(input, onSetupLine) {
21111
21256
  }
21112
21257
  }
21113
21258
  const claimed = new Set(threads.map((t) => t.worktreePath));
21114
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs49.existsSync)(bootstrap.worktreePath)) {
21259
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs51.existsSync)(bootstrap.worktreePath)) {
21115
21260
  try {
21116
21261
  await removeWorktree(repoPath, bootstrap.worktreePath, {
21117
21262
  deleteBranch: bootstrap.branchName
@@ -21131,11 +21276,11 @@ function stackAgentDefaultsFrom(input) {
21131
21276
  planMode: input.planMode
21132
21277
  };
21133
21278
  }
21134
- var import_node_fs49;
21279
+ var import_node_fs51;
21135
21280
  var init_stack_layers = __esm({
21136
21281
  "src/threads/stack-layers.ts"() {
21137
21282
  "use strict";
21138
- import_node_fs49 = require("fs");
21283
+ import_node_fs51 = require("fs");
21139
21284
  init_detect();
21140
21285
  init_run();
21141
21286
  init_stack();
@@ -21148,7 +21293,7 @@ var init_stack_layers = __esm({
21148
21293
 
21149
21294
  // src/diff/diff.ts
21150
21295
  async function inspectGitWorktree(worktreePath) {
21151
- if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) return "missing_worktree";
21296
+ if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) return "missing_worktree";
21152
21297
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
21153
21298
  reject: false
21154
21299
  });
@@ -21156,7 +21301,7 @@ async function inspectGitWorktree(worktreePath) {
21156
21301
  return "ok";
21157
21302
  }
21158
21303
  async function initializeGitRepository(worktreePath) {
21159
- if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) {
21304
+ if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) {
21160
21305
  throw new Error("Worktree not found");
21161
21306
  }
21162
21307
  const status = await inspectGitWorktree(worktreePath);
@@ -21290,11 +21435,11 @@ new file mode 100644
21290
21435
  };
21291
21436
  }
21292
21437
  async function untrackedPatch(worktreePath, path2, maxHunk) {
21293
- const abs = (0, import_node_path49.join)(worktreePath, path2);
21438
+ const abs = (0, import_node_path50.join)(worktreePath, path2);
21294
21439
  try {
21295
- const st = (0, import_node_fs50.statSync)(abs);
21440
+ const st = (0, import_node_fs52.statSync)(abs);
21296
21441
  if (st.isFile() && st.size > maxHunk) {
21297
- const buf = (0, import_node_fs50.readFileSync)(abs).subarray(0, maxHunk);
21442
+ const buf = (0, import_node_fs52.readFileSync)(abs).subarray(0, maxHunk);
21298
21443
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
21299
21444
  }
21300
21445
  } catch {
@@ -21761,9 +21906,9 @@ async function getDiff(worktreePath, repoPath, opts) {
21761
21906
  }
21762
21907
  function statWorktreePath(worktreePath, relativePath) {
21763
21908
  assertSafeRelativePath(relativePath);
21764
- const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21765
- if (!(0, import_node_fs50.existsSync)(abs)) return "missing";
21766
- const st = (0, import_node_fs50.statSync)(abs);
21909
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21910
+ if (!(0, import_node_fs52.existsSync)(abs)) return "missing";
21911
+ const st = (0, import_node_fs52.statSync)(abs);
21767
21912
  if (st.isDirectory()) return "dir";
21768
21913
  if (st.isFile()) return "file";
21769
21914
  return "missing";
@@ -21792,8 +21937,8 @@ function isImageRelativePath(relativePath) {
21792
21937
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21793
21938
  assertSafeRelativePath(relativePath);
21794
21939
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
21795
- const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21796
- const st = (0, import_node_fs50.statSync)(abs);
21940
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21941
+ const st = (0, import_node_fs52.statSync)(abs);
21797
21942
  if (!st.isFile()) {
21798
21943
  throw new Error(`Not a file: ${relativePath}`);
21799
21944
  }
@@ -21802,7 +21947,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21802
21947
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
21803
21948
  );
21804
21949
  }
21805
- const buf = (0, import_node_fs50.readFileSync)(abs);
21950
+ const buf = (0, import_node_fs52.readFileSync)(abs);
21806
21951
  return {
21807
21952
  path: relativePath,
21808
21953
  contentBase64: buf.toString("base64"),
@@ -21812,12 +21957,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21812
21957
  function readWorktreeFile(worktreePath, relativePath, opts) {
21813
21958
  assertSafeRelativePath(relativePath);
21814
21959
  const maxBytes = opts?.maxBytes ?? 2e5;
21815
- const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21816
- const st = (0, import_node_fs50.statSync)(abs);
21960
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21961
+ const st = (0, import_node_fs52.statSync)(abs);
21817
21962
  if (!st.isFile()) {
21818
21963
  throw new Error(`Not a file: ${relativePath}`);
21819
21964
  }
21820
- const buf = (0, import_node_fs50.readFileSync)(abs);
21965
+ const buf = (0, import_node_fs52.readFileSync)(abs);
21821
21966
  if (isImageRelativePath(relativePath)) {
21822
21967
  const maxImageBytes = Math.max(maxBytes, 15e6);
21823
21968
  const truncated2 = buf.length > maxImageBytes;
@@ -21860,9 +22005,9 @@ function assertSafeRelativePath(relativePath) {
21860
22005
  }
21861
22006
  function writeWorktreeFile(worktreePath, relativePath, content) {
21862
22007
  assertSafeRelativePath(relativePath);
21863
- const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21864
- (0, import_node_fs50.mkdirSync)((0, import_node_path49.dirname)(abs), { recursive: true });
21865
- (0, import_node_fs50.writeFileSync)(abs, content, "utf8");
22008
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
22009
+ (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
22010
+ (0, import_node_fs52.writeFileSync)(abs, content, "utf8");
21866
22011
  return { path: relativePath };
21867
22012
  }
21868
22013
  async function getWorktreeDirtyStat(worktreePath) {
@@ -21902,12 +22047,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
21902
22047
  truncated: full.files.length > maxFiles
21903
22048
  };
21904
22049
  }
21905
- var import_node_fs50, import_node_path49, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
22050
+ var import_node_fs52, import_node_path50, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21906
22051
  var init_diff = __esm({
21907
22052
  "src/diff/diff.ts"() {
21908
22053
  "use strict";
21909
- import_node_fs50 = require("fs");
21910
- import_node_path49 = require("path");
22054
+ import_node_fs52 = require("fs");
22055
+ import_node_path50 = require("path");
21911
22056
  init_run();
21912
22057
  init_worktree();
21913
22058
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -22264,7 +22409,7 @@ function parseFrontmatter(content) {
22264
22409
  }
22265
22410
  function readSkill(skillMd, source) {
22266
22411
  try {
22267
- const content = (0, import_node_fs51.readFileSync)(skillMd, "utf8");
22412
+ const content = (0, import_node_fs53.readFileSync)(skillMd, "utf8");
22268
22413
  const { name: fmName, description } = parseFrontmatter(content);
22269
22414
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
22270
22415
  const name = fmName || dirName;
@@ -22283,19 +22428,19 @@ function readSkill(skillMd, source) {
22283
22428
  }
22284
22429
  }
22285
22430
  function scanSkillsDir(dir, source, out) {
22286
- if (!(0, import_node_fs51.existsSync)(dir)) return;
22431
+ if (!(0, import_node_fs53.existsSync)(dir)) return;
22287
22432
  let entries;
22288
22433
  try {
22289
- entries = (0, import_node_fs51.readdirSync)(dir);
22434
+ entries = (0, import_node_fs53.readdirSync)(dir);
22290
22435
  } catch {
22291
22436
  return;
22292
22437
  }
22293
22438
  for (const entry of entries) {
22294
22439
  if (entry.startsWith(".")) continue;
22295
- const skillMd = (0, import_node_path50.join)(dir, entry, "SKILL.md");
22296
- if (!(0, import_node_fs51.existsSync)(skillMd)) continue;
22440
+ const skillMd = (0, import_node_path51.join)(dir, entry, "SKILL.md");
22441
+ if (!(0, import_node_fs53.existsSync)(skillMd)) continue;
22297
22442
  try {
22298
- if (!(0, import_node_fs51.statSync)(skillMd).isFile()) continue;
22443
+ if (!(0, import_node_fs53.statSync)(skillMd).isFile()) continue;
22299
22444
  } catch {
22300
22445
  continue;
22301
22446
  }
@@ -22304,24 +22449,24 @@ function scanSkillsDir(dir, source, out) {
22304
22449
  }
22305
22450
  }
22306
22451
  function scanClaudePluginSkills(pluginsRoot, out) {
22307
- if (!(0, import_node_fs51.existsSync)(pluginsRoot)) return;
22452
+ if (!(0, import_node_fs53.existsSync)(pluginsRoot)) return;
22308
22453
  const walk = (dir, depth, lookingForSkillsDir) => {
22309
22454
  if (depth > 7) return;
22310
22455
  let entries;
22311
22456
  try {
22312
- entries = (0, import_node_fs51.readdirSync)(dir);
22457
+ entries = (0, import_node_fs53.readdirSync)(dir);
22313
22458
  } catch {
22314
22459
  return;
22315
22460
  }
22316
22461
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
22317
- const skill = readSkill((0, import_node_path50.join)(dir, "SKILL.md"), "cli");
22462
+ const skill = readSkill((0, import_node_path51.join)(dir, "SKILL.md"), "cli");
22318
22463
  if (skill) out.push(skill);
22319
22464
  }
22320
22465
  for (const entry of entries) {
22321
22466
  if (entry === "node_modules" || entry === ".git") continue;
22322
- const full = (0, import_node_path50.join)(dir, entry);
22467
+ const full = (0, import_node_path51.join)(dir, entry);
22323
22468
  try {
22324
- if (!(0, import_node_fs51.statSync)(full).isDirectory()) continue;
22469
+ if (!(0, import_node_fs53.statSync)(full).isDirectory()) continue;
22325
22470
  } catch {
22326
22471
  continue;
22327
22472
  }
@@ -22339,17 +22484,17 @@ function discoverSkills(worktreePath) {
22339
22484
  const home = (0, import_node_os15.homedir)();
22340
22485
  const collected = [];
22341
22486
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
22342
- scanSkillsDir((0, import_node_path50.join)(worktreePath, rel), "workspace", collected);
22487
+ scanSkillsDir((0, import_node_path51.join)(worktreePath, rel), "workspace", collected);
22343
22488
  }
22344
22489
  for (const abs of [
22345
- (0, import_node_path50.join)(home, ".claude/skills"),
22346
- (0, import_node_path50.join)(home, ".cursor/skills"),
22347
- (0, import_node_path50.join)(home, ".sideboard/skills"),
22348
- (0, import_node_path50.join)(home, ".brightsy/skills")
22490
+ (0, import_node_path51.join)(home, ".claude/skills"),
22491
+ (0, import_node_path51.join)(home, ".cursor/skills"),
22492
+ (0, import_node_path51.join)(home, ".sideboard/skills"),
22493
+ (0, import_node_path51.join)(home, ".brightsy/skills")
22349
22494
  ]) {
22350
22495
  scanSkillsDir(abs, "user", collected);
22351
22496
  }
22352
- scanClaudePluginSkills((0, import_node_path50.join)(home, ".claude/plugins"), collected);
22497
+ scanClaudePluginSkills((0, import_node_path51.join)(home, ".claude/plugins"), collected);
22353
22498
  collected.push(...bundledSkills());
22354
22499
  const rank = {
22355
22500
  workspace: 0,
@@ -22375,7 +22520,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22375
22520
  \u2026(truncated)` : body;
22376
22521
  }
22377
22522
  }
22378
- const raw = (0, import_node_fs51.readFileSync)(skillPath, "utf8");
22523
+ const raw = (0, import_node_fs53.readFileSync)(skillPath, "utf8");
22379
22524
  if (raw.startsWith("---")) {
22380
22525
  const end = raw.indexOf("\n---", 3);
22381
22526
  if (end >= 0) {
@@ -22389,13 +22534,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22389
22534
 
22390
22535
  \u2026(truncated)` : raw;
22391
22536
  }
22392
- var import_node_fs51, import_node_os15, import_node_path50, BUNDLED_SKILL_PREFIX;
22537
+ var import_node_fs53, import_node_os15, import_node_path51, BUNDLED_SKILL_PREFIX;
22393
22538
  var init_discover = __esm({
22394
22539
  "src/skills/discover.ts"() {
22395
22540
  "use strict";
22396
- import_node_fs51 = require("fs");
22541
+ import_node_fs53 = require("fs");
22397
22542
  import_node_os15 = require("os");
22398
- import_node_path50 = require("path");
22543
+ import_node_path51 = require("path");
22399
22544
  init_long_running();
22400
22545
  BUNDLED_SKILL_PREFIX = "bundled:";
22401
22546
  }
@@ -22548,9 +22693,9 @@ function compiledModuleDir() {
22548
22693
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
22549
22694
  if (cjsDir) return cjsDir;
22550
22695
  try {
22551
- const url = import_meta3.url;
22696
+ const url = import_meta4.url;
22552
22697
  if (typeof url === "string" && url.length > 0) {
22553
- return (0, import_node_path51.dirname)((0, import_node_url3.fileURLToPath)(url));
22698
+ return (0, import_node_path52.dirname)((0, import_node_url4.fileURLToPath)(url));
22554
22699
  }
22555
22700
  } catch {
22556
22701
  }
@@ -22558,8 +22703,8 @@ function compiledModuleDir() {
22558
22703
  }
22559
22704
  function detachedJobScriptIn(dir) {
22560
22705
  for (const name of DETACHED_JOB_FILENAMES) {
22561
- const script = (0, import_node_path51.join)(dir, "scripts", name);
22562
- if ((0, import_node_fs52.existsSync)(script)) return script;
22706
+ const script = (0, import_node_path52.join)(dir, "scripts", name);
22707
+ if ((0, import_node_fs54.existsSync)(script)) return script;
22563
22708
  }
22564
22709
  return null;
22565
22710
  }
@@ -22576,7 +22721,7 @@ function resolveDetachedJobScript() {
22576
22721
  for (let i = 0; i < 8; i++) {
22577
22722
  const candidate = detachedJobScriptIn(dir);
22578
22723
  if (candidate) return candidate;
22579
- const parent = (0, import_node_path51.dirname)(dir);
22724
+ const parent = (0, import_node_path52.dirname)(dir);
22580
22725
  if (parent === dir) break;
22581
22726
  dir = parent;
22582
22727
  }
@@ -22587,15 +22732,15 @@ function formatDetachedJobInvoke(scriptPath) {
22587
22732
  if (resolved) return `node ${JSON.stringify(resolved)}`;
22588
22733
  return "node scripts/detached-job.cjs";
22589
22734
  }
22590
- var import_node_fs52, import_node_path51, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
22735
+ var import_node_fs54, import_node_path52, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
22591
22736
  var init_detached_job_path = __esm({
22592
22737
  "src/skills/detached-job-path.ts"() {
22593
22738
  "use strict";
22594
- import_node_fs52 = require("fs");
22595
- import_node_path51 = require("path");
22596
- import_node_url3 = require("url");
22739
+ import_node_fs54 = require("fs");
22740
+ import_node_path52 = require("path");
22741
+ import_node_url4 = require("url");
22597
22742
  init_packaged_runtime();
22598
- import_meta3 = {};
22743
+ import_meta4 = {};
22599
22744
  DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
22600
22745
  }
22601
22746
  });
@@ -22774,9 +22919,9 @@ function formatPrGateDirective() {
22774
22919
  }
22775
22920
  function formatProcessGuideDirective(opts) {
22776
22921
  const worktree = opts?.worktreePath?.trim();
22777
- const hasGraphSkill = !!worktree && (0, import_node_fs53.existsSync)((0, import_node_path52.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22778
- const hasReviewSkill = !!worktree && (0, import_node_fs53.existsSync)((0, import_node_path52.join)(worktree, ".claude/skills/review/SKILL.md"));
22779
- const hasInstallSkill = !!worktree && (0, import_node_fs53.existsSync)((0, import_node_path52.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22922
+ const hasGraphSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22923
+ const hasReviewSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/review/SKILL.md"));
22924
+ const hasInstallSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22780
22925
  return [
22781
22926
  "Process guides (recurring work only):",
22782
22927
  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,
@@ -22815,12 +22960,12 @@ function formatArtifactDirective() {
22815
22960
  function formatUiReminder() {
22816
22961
  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.";
22817
22962
  }
22818
- var import_node_fs53, import_node_path52, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22963
+ var import_node_fs55, import_node_path53, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22819
22964
  var init_instructions = __esm({
22820
22965
  "src/agents/instructions.ts"() {
22821
22966
  "use strict";
22822
- import_node_fs53 = require("fs");
22823
- import_node_path52 = require("path");
22967
+ import_node_fs55 = require("fs");
22968
+ import_node_path53 = require("path");
22824
22969
  init_git_auth_mode();
22825
22970
  init_branch_prefix();
22826
22971
  init_worktree_labels();
@@ -23206,40 +23351,40 @@ __export(plan_file_exports, {
23206
23351
  writePlanFile: () => writePlanFile
23207
23352
  });
23208
23353
  function ensureAttachmentsGitignore(worktreePath) {
23209
- const gitignoreAbs = (0, import_node_path53.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23210
- if ((0, import_node_fs54.existsSync)(gitignoreAbs)) return;
23211
- (0, import_node_fs54.mkdirSync)((0, import_node_path53.dirname)(gitignoreAbs), { recursive: true });
23212
- (0, import_node_fs54.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23354
+ const gitignoreAbs = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23355
+ if ((0, import_node_fs56.existsSync)(gitignoreAbs)) return;
23356
+ (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(gitignoreAbs), { recursive: true });
23357
+ (0, import_node_fs56.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23213
23358
  }
23214
23359
  function planFileAbs(worktreePath) {
23215
- return (0, import_node_path53.join)(worktreePath, PLAN_FILE_REL);
23360
+ return (0, import_node_path54.join)(worktreePath, PLAN_FILE_REL);
23216
23361
  }
23217
23362
  function readTextIfPresent2(abs) {
23218
- if (!(0, import_node_fs54.existsSync)(abs)) return null;
23363
+ if (!(0, import_node_fs56.existsSync)(abs)) return null;
23219
23364
  try {
23220
- const content = (0, import_node_fs54.readFileSync)(abs, "utf8");
23365
+ const content = (0, import_node_fs56.readFileSync)(abs, "utf8");
23221
23366
  return content.trim() ? content : null;
23222
23367
  } catch {
23223
23368
  return null;
23224
23369
  }
23225
23370
  }
23226
23371
  function readPlanFile(worktreePath) {
23227
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path53.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path53.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23372
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path54.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path54.join)(worktreePath, LEGACY_PLAN_FILE_REL));
23228
23373
  }
23229
23374
  function writePlanFile(worktreePath, content) {
23230
23375
  ensureAttachmentsGitignore(worktreePath);
23231
23376
  const abs = planFileAbs(worktreePath);
23232
- (0, import_node_fs54.mkdirSync)((0, import_node_path53.dirname)(abs), { recursive: true });
23377
+ (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(abs), { recursive: true });
23233
23378
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23234
- (0, import_node_fs54.writeFileSync)(abs, body, "utf8");
23379
+ (0, import_node_fs56.writeFileSync)(abs, body, "utf8");
23235
23380
  return PLAN_FILE_REL;
23236
23381
  }
23237
- var import_node_fs54, import_node_path53;
23382
+ var import_node_fs56, import_node_path54;
23238
23383
  var init_plan_file = __esm({
23239
23384
  "src/plan/plan-file.ts"() {
23240
23385
  "use strict";
23241
- import_node_fs54 = require("fs");
23242
- import_node_path53 = require("path");
23386
+ import_node_fs56 = require("fs");
23387
+ import_node_path54 = require("path");
23243
23388
  init_workspace_scratch();
23244
23389
  init_plan_present();
23245
23390
  init_plan_present();
@@ -23301,9 +23446,9 @@ function recoverFinishedCursorRun(opts) {
23301
23446
  return best;
23302
23447
  }
23303
23448
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23304
- if (!(0, import_node_fs55.existsSync)(runsPath)) return null;
23449
+ if (!(0, import_node_fs57.existsSync)(runsPath)) return null;
23305
23450
  try {
23306
- const lines = (0, import_node_fs55.readFileSync)(runsPath, "utf8").split("\n");
23451
+ const lines = (0, import_node_fs57.readFileSync)(runsPath, "utf8").split("\n");
23307
23452
  let best = null;
23308
23453
  for (const line of lines) {
23309
23454
  const trimmed = line.trim();
@@ -23329,11 +23474,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23329
23474
  return null;
23330
23475
  }
23331
23476
  }
23332
- var import_node_fs55;
23477
+ var import_node_fs57;
23333
23478
  var init_cursor_recover = __esm({
23334
23479
  "src/agents/cursor-recover.ts"() {
23335
23480
  "use strict";
23336
- import_node_fs55 = require("fs");
23481
+ import_node_fs57 = require("fs");
23337
23482
  init_cursor_store();
23338
23483
  }
23339
23484
  });
@@ -23487,14 +23632,14 @@ async function startOrchestration(opts) {
23487
23632
  }
23488
23633
  return updated;
23489
23634
  }
23490
- var import_node_events, import_node_crypto12, import_node_fs56, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
23635
+ var import_node_events, import_node_crypto12, import_node_fs58, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
23491
23636
  var init_orchestrator = __esm({
23492
23637
  "src/orchestrator/orchestrator.ts"() {
23493
23638
  "use strict";
23494
23639
  import_node_events = require("events");
23495
23640
  init_outbound_watch();
23496
23641
  import_node_crypto12 = require("crypto");
23497
- import_node_fs56 = require("fs");
23642
+ import_node_fs58 = require("fs");
23498
23643
  init_error_detail();
23499
23644
  init_run();
23500
23645
  init_stale_lock();
@@ -23671,7 +23816,7 @@ var init_orchestrator = __esm({
23671
23816
  this.lightReconcileAt.set(repoPath, Date.now());
23672
23817
  for (const thread of listThreads()) {
23673
23818
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
23674
- if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23819
+ if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
23675
23820
  setStatus(thread.id, "broken", "Worktree missing on disk");
23676
23821
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23677
23822
  }
@@ -23700,7 +23845,7 @@ var init_orchestrator = __esm({
23700
23845
  }
23701
23846
  continue;
23702
23847
  }
23703
- if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23848
+ if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
23704
23849
  setStatus(thread.id, "broken", "Worktree missing on disk");
23705
23850
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23706
23851
  continue;
@@ -25991,7 +26136,7 @@ var init_orchestrator = __esm({
25991
26136
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
25992
26137
  return restored2;
25993
26138
  }
25994
- if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
26139
+ if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
25995
26140
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
25996
26141
  throw new Error(
25997
26142
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -26236,6 +26381,7 @@ __export(index_exports, {
26236
26381
  CONTEXT_REVIEW_PATH: () => CONTEXT_REVIEW_PATH,
26237
26382
  CONVENTION_SETUP_RELPATHS: () => CONVENTION_SETUP_RELPATHS,
26238
26383
  COORDINATOR_TOOL_PLAYBOOK: () => COORDINATOR_TOOL_PLAYBOOK,
26384
+ CURSOR_SDK_INSTALL_HINT: () => CURSOR_SDK_INSTALL_HINT,
26239
26385
  DEFAULT_ABLETIME_HOST: () => DEFAULT_ABLETIME_HOST,
26240
26386
  DEFAULT_WORKTREE_SORT: () => DEFAULT_WORKTREE_SORT,
26241
26387
  DETACHED_JOBS_DIR: () => DETACHED_JOBS_DIR,
@@ -26677,6 +26823,7 @@ __export(index_exports, {
26677
26823
  isCowboyThread: () => isCowboyThread,
26678
26824
  isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
26679
26825
  isCursorAutoModel: () => isCursorAutoModel,
26826
+ isCursorSdkInstalled: () => isCursorSdkInstalled,
26680
26827
  isDefaultishSourceRef: () => isDefaultishSourceRef,
26681
26828
  isDesktopHostAlive: () => isDesktopHostAlive,
26682
26829
  isDirty: () => isDirty,
@@ -26816,6 +26963,8 @@ __export(index_exports, {
26816
26963
  normalizeThread: () => normalizeThread,
26817
26964
  normalizeTurnInput: () => normalizeTurnInput,
26818
26965
  normalizeWorktreePath: () => normalizeWorktreePath,
26966
+ npmGlobalNodeModules: () => npmGlobalNodeModules,
26967
+ npmGlobalPrefix: () => npmGlobalPrefix,
26819
26968
  openInSystemTerminal: () => openInSystemTerminal,
26820
26969
  openPrStackLayers: () => openPrStackLayers,
26821
26970
  openStackLayer: () => openStackLayer,
@@ -26904,6 +27053,7 @@ __export(index_exports, {
26904
27053
  resolveConductorCursorAgentId: () => resolveConductorCursorAgentId,
26905
27054
  resolveCreateFirstPrompt: () => resolveCreateFirstPrompt,
26906
27055
  resolveCursorModelId: () => resolveCursorModelId,
27056
+ resolveCursorSdkRoot: () => resolveCursorSdkRoot,
26907
27057
  resolveDefaultBranch: () => resolveDefaultBranch,
26908
27058
  resolveDetachedJobScript: () => resolveDetachedJobScript,
26909
27059
  resolveDiffBaseRef: () => resolveDiffBaseRef,
@@ -29243,6 +29393,15 @@ async function installOptionalServiceCli(id) {
29243
29393
  message: `${spec.label} has no CLI to install. Use the HTTP API with the stored token.`
29244
29394
  };
29245
29395
  }
29396
+ enrichPathWithNpmGlobalBin();
29397
+ const existing = await whichOnPath(spec.cli);
29398
+ if (existing) {
29399
+ return {
29400
+ ok: true,
29401
+ command: existing,
29402
+ message: `Already on PATH: ${existing}`
29403
+ };
29404
+ }
29246
29405
  return installNpmGlobalPackage({
29247
29406
  npmPackage: spec.npmPackage,
29248
29407
  installCommand: `npm install -g ${spec.npmPackage}`,
@@ -29601,7 +29760,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
29601
29760
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29602
29761
  var import_zod9 = require("zod");
29603
29762
  var import_node_crypto16 = require("crypto");
29604
- var import_node_path56 = require("path");
29763
+ var import_node_path57 = require("path");
29605
29764
  init_orchestrator();
29606
29765
  init_worktree();
29607
29766
  init_global_workspace();
@@ -31338,27 +31497,27 @@ init_gh_errors();
31338
31497
  init_git_auth_mode();
31339
31498
 
31340
31499
  // src/board/load-home-board.ts
31341
- var import_node_fs58 = require("fs");
31342
- var import_node_path55 = require("path");
31500
+ var import_node_fs60 = require("fs");
31501
+ var import_node_path56 = require("path");
31343
31502
  init_worktree();
31344
31503
  init_paths();
31345
31504
 
31346
31505
  // src/board/board-pins.ts
31347
31506
  var import_node_crypto15 = require("crypto");
31348
- var import_node_fs57 = require("fs");
31349
- var import_node_path54 = require("path");
31507
+ var import_node_fs59 = require("fs");
31508
+ var import_node_path55 = require("path");
31350
31509
  init_paths();
31351
31510
  init_home_board();
31352
31511
  var FILE = "home-board-pins.json";
31353
31512
  var VERSION = 1;
31354
31513
  function pinsFile() {
31355
- return (0, import_node_path54.join)(appDataDir(), FILE);
31514
+ return (0, import_node_path55.join)(appDataDir(), FILE);
31356
31515
  }
31357
31516
  function readDisk() {
31358
31517
  const path2 = pinsFile();
31359
- if (!(0, import_node_fs57.existsSync)(path2)) return [];
31518
+ if (!(0, import_node_fs59.existsSync)(path2)) return [];
31360
31519
  try {
31361
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
31520
+ const raw = JSON.parse((0, import_node_fs59.readFileSync)(path2, "utf8"));
31362
31521
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
31363
31522
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
31364
31523
  } catch {
@@ -31366,8 +31525,8 @@ function readDisk() {
31366
31525
  }
31367
31526
  }
31368
31527
  function writeDisk(items) {
31369
- (0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
31370
- (0, import_node_fs57.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
31528
+ (0, import_node_fs59.mkdirSync)(appDataDir(), { recursive: true });
31529
+ (0, import_node_fs59.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
31371
31530
  }
31372
31531
  function listBoardPins() {
31373
31532
  return readDisk();
@@ -31419,7 +31578,7 @@ function replaceBoardPins(items) {
31419
31578
  }
31420
31579
  function clearBoardPins() {
31421
31580
  try {
31422
- (0, import_node_fs57.unlinkSync)(pinsFile());
31581
+ (0, import_node_fs59.unlinkSync)(pinsFile());
31423
31582
  } catch {
31424
31583
  }
31425
31584
  }
@@ -31436,7 +31595,7 @@ function homeBoardWorkspaceKey(workspaces) {
31436
31595
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
31437
31596
  }
31438
31597
  function cacheFile() {
31439
- return (0, import_node_path55.join)(appDataDir(), "home-board-cache.json");
31598
+ return (0, import_node_path56.join)(appDataDir(), "home-board-cache.json");
31440
31599
  }
31441
31600
  function emptyInputs() {
31442
31601
  return {
@@ -31462,9 +31621,9 @@ function shouldCacheHomeBoardInputs(inputs) {
31462
31621
  }
31463
31622
  function readDiskCache() {
31464
31623
  const path2 = cacheFile();
31465
- if (!(0, import_node_fs58.existsSync)(path2)) return null;
31624
+ if (!(0, import_node_fs60.existsSync)(path2)) return null;
31466
31625
  try {
31467
- const raw = JSON.parse((0, import_node_fs58.readFileSync)(path2, "utf8"));
31626
+ const raw = JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
31468
31627
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
31469
31628
  return null;
31470
31629
  }
@@ -31478,14 +31637,14 @@ function readDiskCache() {
31478
31637
  }
31479
31638
  function writeDiskCache(entry) {
31480
31639
  try {
31481
- (0, import_node_fs58.mkdirSync)(appDataDir(), { recursive: true });
31482
- (0, import_node_fs58.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31640
+ (0, import_node_fs60.mkdirSync)(appDataDir(), { recursive: true });
31641
+ (0, import_node_fs60.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31483
31642
  } catch {
31484
31643
  }
31485
31644
  }
31486
31645
  function deleteDiskCache() {
31487
31646
  try {
31488
- (0, import_node_fs58.unlinkSync)(cacheFile());
31647
+ (0, import_node_fs60.unlinkSync)(cacheFile());
31489
31648
  } catch {
31490
31649
  }
31491
31650
  }
@@ -31835,7 +31994,7 @@ async function startMcpServer() {
31835
31994
  async () => {
31836
31995
  const threads = orch.getThreads(true);
31837
31996
  const lines = threads.map((t) => {
31838
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path56.basename)(t.repoPath) || t.repoPath;
31997
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path57.basename)(t.repoPath) || t.repoPath;
31839
31998
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
31840
31999
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
31841
32000
  const preview = lastMessagePreview(t.messages, 80);
@@ -34836,9 +34995,9 @@ var import_node_http4 = require("http");
34836
34995
  var import_ws3 = require("ws");
34837
34996
 
34838
34997
  // src/slack/relay-static.ts
34839
- var import_node_fs59 = require("fs");
34998
+ var import_node_fs61 = require("fs");
34840
34999
  var import_promises = require("fs/promises");
34841
- var import_node_path57 = __toESM(require("path"), 1);
35000
+ var import_node_path58 = __toESM(require("path"), 1);
34842
35001
  var TYPES = {
34843
35002
  ".css": "text/css; charset=utf-8",
34844
35003
  ".html": "text/html; charset=utf-8",
@@ -34869,9 +35028,9 @@ function resolveStaticPath(root, requestUrl) {
34869
35028
  return null;
34870
35029
  }
34871
35030
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
34872
- const rootResolved = import_node_path57.default.resolve(root);
34873
- const candidate = import_node_path57.default.resolve(rootResolved, `.${pathname}`);
34874
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path57.default.sep)) {
35031
+ const rootResolved = import_node_path58.default.resolve(root);
35032
+ const candidate = import_node_path58.default.resolve(rootResolved, `.${pathname}`);
35033
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path58.default.sep)) {
34875
35034
  return null;
34876
35035
  }
34877
35036
  return candidate;
@@ -34885,7 +35044,7 @@ async function fileSize(file) {
34885
35044
  }
34886
35045
  }
34887
35046
  function sendFile(req, res, file, size) {
34888
- const ext = import_node_path57.default.extname(file).toLowerCase();
35047
+ const ext = import_node_path58.default.extname(file).toLowerCase();
34889
35048
  res.writeHead(200, {
34890
35049
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
34891
35050
  "Content-Length": size,
@@ -34895,7 +35054,7 @@ function sendFile(req, res, file, size) {
34895
35054
  res.end();
34896
35055
  return true;
34897
35056
  }
34898
- (0, import_node_fs59.createReadStream)(file).pipe(res);
35057
+ (0, import_node_fs61.createReadStream)(file).pipe(res);
34899
35058
  return true;
34900
35059
  }
34901
35060
  async function tryServeStatic(req, res, root) {
@@ -34904,7 +35063,7 @@ async function tryServeStatic(req, res, root) {
34904
35063
  if (!candidate) return false;
34905
35064
  const direct = await fileSize(candidate);
34906
35065
  if (direct != null) return sendFile(req, res, candidate, direct);
34907
- const asIndex = import_node_path57.default.join(candidate, "index.html");
35066
+ const asIndex = import_node_path58.default.join(candidate, "index.html");
34908
35067
  const indexSize = await fileSize(asIndex);
34909
35068
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
34910
35069
  return false;
@@ -35192,6 +35351,7 @@ init_outbound_watch();
35192
35351
  CONTEXT_REVIEW_PATH,
35193
35352
  CONVENTION_SETUP_RELPATHS,
35194
35353
  COORDINATOR_TOOL_PLAYBOOK,
35354
+ CURSOR_SDK_INSTALL_HINT,
35195
35355
  DEFAULT_ABLETIME_HOST,
35196
35356
  DEFAULT_WORKTREE_SORT,
35197
35357
  DETACHED_JOBS_DIR,
@@ -35633,6 +35793,7 @@ init_outbound_watch();
35633
35793
  isCowboyThread,
35634
35794
  isCursorApiKeyConfigured,
35635
35795
  isCursorAutoModel,
35796
+ isCursorSdkInstalled,
35636
35797
  isDefaultishSourceRef,
35637
35798
  isDesktopHostAlive,
35638
35799
  isDirty,
@@ -35772,6 +35933,8 @@ init_outbound_watch();
35772
35933
  normalizeThread,
35773
35934
  normalizeTurnInput,
35774
35935
  normalizeWorktreePath,
35936
+ npmGlobalNodeModules,
35937
+ npmGlobalPrefix,
35775
35938
  openInSystemTerminal,
35776
35939
  openPrStackLayers,
35777
35940
  openStackLayer,
@@ -35860,6 +36023,7 @@ init_outbound_watch();
35860
36023
  resolveConductorCursorAgentId,
35861
36024
  resolveCreateFirstPrompt,
35862
36025
  resolveCursorModelId,
36026
+ resolveCursorSdkRoot,
35863
36027
  resolveDefaultBranch,
35864
36028
  resolveDetachedJobScript,
35865
36029
  resolveDiffBaseRef,