@sideboard-ai/core 0.1.232 → 0.1.234

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 +207 -62
  2. package/dist/agents/cursor-runner.js +24 -10
  3. package/dist/{agents-TCTEAK6M.js → agents-BTXL6R5I.js} +17 -7
  4. package/dist/{agents-ENAQHQRZ.js → agents-WMN7C322.js} +16 -6
  5. package/dist/{chunk-PO4M4JAJ.js → chunk-2P4XKWV2.js} +1 -1
  6. package/dist/{chunk-FA4CPYCY.js → chunk-2UBVFL2X.js} +81 -41
  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-SZJZEFTY.js → chunk-DD67JWTN.js} +1 -1
  11. package/dist/{chunk-LLMG6OVS.js → chunk-LEYY54BN.js} +19 -19
  12. package/dist/{chunk-6L25K7BE.js → chunk-NOIWXANG.js} +224 -73
  13. package/dist/{chunk-HVUVQXZ2.js → chunk-QVN2WOKJ.js} +18 -5
  14. package/dist/{chunk-7BZ7DSBN.js → chunk-RKKTCKVX.js} +17 -17
  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-TQBUXKIB.js → chunk-WPD7BR6C.js} +135 -11
  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 +519 -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 +447 -302
  31. package/dist/mcp/run-stdio.js +7 -7
  32. package/dist/{orchestrator-RJX4OKYC.js → orchestrator-7ZEGFPK4.js} +7 -7
  33. package/dist/{orchestrator-FTHJKPIX.js → orchestrator-R2WCTNJI.js} +8 -8
  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,124 @@ 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
+ function exportTarget(value) {
13975
+ if (typeof value === "string") return value;
13976
+ if (value && typeof value === "object") {
13977
+ const v = value;
13978
+ return exportTarget(v.import) ?? exportTarget(v.default);
13979
+ }
13980
+ return null;
13981
+ }
13982
+ function cursorSdkEsmEntry(root) {
13983
+ try {
13984
+ const pkg = JSON.parse((0, import_node_fs36.readFileSync)((0, import_node_path38.join)(root, "package.json"), "utf8"));
13985
+ const exp = pkg.exports;
13986
+ const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
13987
+ const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
13988
+ if (!rel) return null;
13989
+ const entry = (0, import_node_path38.join)(root, rel);
13990
+ return (0, import_node_fs36.existsSync)(entry) ? entry : null;
13991
+ } catch {
13992
+ return null;
13993
+ }
13994
+ }
13995
+ function unwrapCursorSdkModule(mod) {
13996
+ const m = mod;
13997
+ if (m && !m.Agent && m.default?.Agent) return m.default;
13998
+ return m;
13999
+ }
14000
+ async function importCursorSdk(opts) {
14001
+ const root = resolveCursorSdkRoot(opts);
14002
+ if (!root) return null;
14003
+ try {
14004
+ let entry = cursorSdkEsmEntry(root);
14005
+ if (!entry) {
14006
+ const req = (0, import_node_module2.createRequire)((0, import_node_path38.join)(root, "package.json"));
14007
+ entry = req.resolve("@cursor/sdk");
14008
+ }
14009
+ return unwrapCursorSdkModule(await import((0, import_node_url2.pathToFileURL)(entry).href));
14010
+ } catch {
14011
+ return null;
14012
+ }
14013
+ }
14014
+ function cursorSdkPlatformRipgrepPackage() {
14015
+ return `@cursor/sdk-${process.platform}-${process.arch}`;
14016
+ }
14017
+ function nodeModulesDirForPackageRoot(packageRoot) {
14018
+ const parent = (0, import_node_path38.dirname)(packageRoot);
14019
+ return (0, import_node_path38.basename)(parent).startsWith("@") ? (0, import_node_path38.dirname)(parent) : parent;
14020
+ }
14021
+ function cursorSdkRipgrepCandidate(opts) {
14022
+ const root = resolveCursorSdkRoot(opts);
14023
+ if (!root) return null;
14024
+ const nm = nodeModulesDirForPackageRoot(root);
14025
+ const pkg = cursorSdkPlatformRipgrepPackage();
14026
+ const bin = process.platform === "win32" ? "rg.exe" : "rg";
14027
+ const sibling = (0, import_node_path38.join)(nm, pkg, "bin", bin);
14028
+ if ((0, import_node_fs36.existsSync)(sibling)) return sibling;
14029
+ const nested = (0, import_node_path38.join)(root, "node_modules", pkg, "bin", bin);
14030
+ return (0, import_node_fs36.existsSync)(nested) ? nested : null;
14031
+ }
14032
+ var import_node_fs36, import_node_module2, import_node_path38, import_node_url2, import_meta2, CURSOR_SDK_INSTALL_HINT;
14033
+ var init_cursor_sdk_resolve = __esm({
14034
+ "src/agents/cursor-sdk-resolve.ts"() {
14035
+ "use strict";
14036
+ import_node_fs36 = require("fs");
14037
+ import_node_module2 = require("module");
14038
+ import_node_path38 = require("path");
14039
+ import_node_url2 = require("url");
14040
+ init_path();
14041
+ import_meta2 = {};
14042
+ 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.";
14043
+ }
14044
+ });
14045
+
13917
14046
  // src/agents/cursor-events.ts
13918
14047
  function usageFromCursor(usage) {
13919
14048
  if (!usage) return null;
@@ -14140,21 +14269,21 @@ function platformRipgrepPackage() {
14140
14269
  }
14141
14270
  function usableRipgrepPath(candidate) {
14142
14271
  const raw = candidate?.trim();
14143
- if (!raw || !(0, import_node_path38.isAbsolute)(raw)) return null;
14272
+ if (!raw || !(0, import_node_path39.isAbsolute)(raw)) return null;
14144
14273
  const readable = nodeReadableScriptPath(raw);
14145
- if (!(0, import_node_fs36.existsSync)(readable) || isAsarPath(readable)) return null;
14274
+ if (!(0, import_node_fs37.existsSync)(readable) || isAsarPath(readable)) return null;
14146
14275
  return readable;
14147
14276
  }
14148
14277
  function walkForBundledRipgrep(startFile) {
14149
14278
  if (!startFile) return null;
14150
14279
  const pkg = platformRipgrepPackage();
14151
14280
  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;
14281
+ let dir = (0, import_node_path39.dirname)((0, import_node_path39.resolve)(startFile));
14282
+ const root = (0, import_node_path39.parse)(dir).root;
14154
14283
  while (dir !== root) {
14155
- const hit = usableRipgrepPath((0, import_node_path38.join)(dir, "node_modules", pkg, "bin", name));
14284
+ const hit = usableRipgrepPath((0, import_node_path39.join)(dir, "node_modules", pkg, "bin", name));
14156
14285
  if (hit) return hit;
14157
- const next = (0, import_node_path38.dirname)(dir);
14286
+ const next = (0, import_node_path39.dirname)(dir);
14158
14287
  if (next === dir) break;
14159
14288
  dir = next;
14160
14289
  }
@@ -14162,9 +14291,9 @@ function walkForBundledRipgrep(startFile) {
14162
14291
  }
14163
14292
  function requireResolveBundledRipgrep(fromFile) {
14164
14293
  try {
14165
- const req = (0, import_node_module2.createRequire)(fromFile);
14294
+ const req = (0, import_node_module3.createRequire)(fromFile);
14166
14295
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
14167
- return usableRipgrepPath((0, import_node_path38.join)((0, import_node_path38.dirname)(pkgJson), "bin", rgBinaryName()));
14296
+ return usableRipgrepPath((0, import_node_path39.join)((0, import_node_path39.dirname)(pkgJson), "bin", rgBinaryName()));
14168
14297
  } catch {
14169
14298
  return null;
14170
14299
  }
@@ -14180,19 +14309,20 @@ function resolveCursorRipgrepPath(opts) {
14180
14309
  const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
14181
14310
  // eslint-disable-next-line camelcase
14182
14311
  (typeof __filename !== "undefined" ? __filename : "");
14183
- return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
14312
+ return walkForBundledRipgrep(start) ?? usableRipgrepPath(cursorSdkRipgrepCandidate({ env })) ?? requireResolveBundledRipgrep(start);
14184
14313
  }
14185
14314
  function cursorRipgrepEnv(opts) {
14186
14315
  const path2 = resolveCursorRipgrepPath(opts);
14187
14316
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
14188
14317
  }
14189
- var import_node_fs36, import_node_module2, import_node_path38, RIPGREP_ENV;
14318
+ var import_node_fs37, import_node_module3, import_node_path39, RIPGREP_ENV;
14190
14319
  var init_cursor_ripgrep = __esm({
14191
14320
  "src/agents/cursor-ripgrep.ts"() {
14192
14321
  "use strict";
14193
- import_node_fs36 = require("fs");
14194
- import_node_module2 = require("module");
14195
- import_node_path38 = require("path");
14322
+ import_node_fs37 = require("fs");
14323
+ import_node_module3 = require("module");
14324
+ import_node_path39 = require("path");
14325
+ init_cursor_sdk_resolve();
14196
14326
  init_node_launch();
14197
14327
  init_packaged_runtime();
14198
14328
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -14223,8 +14353,10 @@ async function listCursorModels() {
14223
14353
  }
14224
14354
  const apiKey = resolveCursorApiKey();
14225
14355
  if (!apiKey) return FALLBACK_CURSOR_MODELS;
14356
+ const sdk = await importCursorSdk();
14357
+ if (!sdk) return FALLBACK_CURSOR_MODELS;
14226
14358
  try {
14227
- const listed = await import_sdk.Cursor.models.list({ apiKey });
14359
+ const listed = await sdk.Cursor.models.list({ apiKey });
14228
14360
  const models = listed.map((m) => ({
14229
14361
  id: m.id,
14230
14362
  displayName: m.displayName || m.id,
@@ -14241,11 +14373,11 @@ function entryDir() {
14241
14373
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
14242
14374
  if (cjsDir) return cjsDir;
14243
14375
  try {
14244
- return (0, import_node_path39.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
14376
+ return (0, import_node_path40.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
14245
14377
  } catch {
14246
14378
  try {
14247
- const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
14248
- return (0, import_node_path39.dirname)(req.resolve("@sideboard-ai/core"));
14379
+ const req = (0, import_node_module4.createRequire)(process.cwd() + "/");
14380
+ return (0, import_node_path40.dirname)(req.resolve("@sideboard-ai/core"));
14249
14381
  } catch {
14250
14382
  return process.cwd();
14251
14383
  }
@@ -14256,32 +14388,32 @@ function cursorRunnerPath() {
14256
14388
  if (packaged) return packaged;
14257
14389
  const root = entryDir();
14258
14390
  const candidates = [
14259
- (0, import_node_path39.join)(root, "agents", "cursor-runner.js"),
14260
- (0, import_node_path39.join)(root, "agents", "cursor-runner.cjs"),
14391
+ (0, import_node_path40.join)(root, "agents", "cursor-runner.js"),
14392
+ (0, import_node_path40.join)(root, "agents", "cursor-runner.cjs"),
14261
14393
  // 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"),
14394
+ (0, import_node_path40.join)(root, "dist", "agents", "cursor-runner.js"),
14395
+ (0, import_node_path40.join)(root, "dist", "agents", "cursor-runner.cjs"),
14264
14396
  // 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")
14397
+ (0, import_node_path40.join)(root, "cursor-runner.ts"),
14398
+ (0, import_node_path40.join)(root, "src", "agents", "cursor-runner.ts")
14267
14399
  ];
14268
14400
  for (const candidate of candidates) {
14269
- if ((0, import_node_fs37.existsSync)(candidate)) return candidate;
14401
+ if ((0, import_node_fs38.existsSync)(candidate)) return candidate;
14270
14402
  }
14271
14403
  return candidates[0];
14272
14404
  }
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;
14405
+ var import_node_fs38, import_node_module4, import_node_path40, import_node_url3, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
14274
14406
  var init_cursor = __esm({
14275
14407
  "src/agents/cursor.ts"() {
14276
14408
  "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");
14409
+ import_node_fs38 = require("fs");
14410
+ import_node_module4 = require("module");
14411
+ import_node_path40 = require("path");
14412
+ import_node_url3 = require("url");
14282
14413
  init_run();
14283
14414
  init_app_settings();
14284
14415
  init_global_workspace();
14416
+ init_cursor_sdk_resolve();
14285
14417
  init_cursor_events();
14286
14418
  init_injected_mcp();
14287
14419
  init_cursor_ripgrep();
@@ -14289,7 +14421,7 @@ var init_cursor = __esm({
14289
14421
  init_packaged_runtime();
14290
14422
  init_turn_input();
14291
14423
  init_cursor_events();
14292
- import_meta2 = {};
14424
+ import_meta3 = {};
14293
14425
  FALLBACK_CURSOR_MODELS = [
14294
14426
  { id: "default", displayName: "Auto" },
14295
14427
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -14300,6 +14432,16 @@ var init_cursor = __esm({
14300
14432
  cursorAdapter = {
14301
14433
  kind: "cursor",
14302
14434
  async detect() {
14435
+ if (!isCursorSdkInstalled()) {
14436
+ return {
14437
+ agent: "cursor",
14438
+ installed: false,
14439
+ authenticated: false,
14440
+ linearMcp: false,
14441
+ warnings: [],
14442
+ reason: CURSOR_SDK_INSTALL_HINT
14443
+ };
14444
+ }
14303
14445
  const apiKey = resolveCursorApiKey();
14304
14446
  if (!apiKey) {
14305
14447
  return {
@@ -14428,7 +14570,7 @@ async function listOpencodeModels() {
14428
14570
  if (opencode === "opencode") {
14429
14571
  const which = await run("which", ["opencode"], { reject: false });
14430
14572
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
14431
- } else if (!(0, import_node_fs38.existsSync)(opencode)) {
14573
+ } else if (!(0, import_node_fs39.existsSync)(opencode)) {
14432
14574
  return FALLBACK_OPENCODE_MODELS;
14433
14575
  }
14434
14576
  const listed = await run(opencode, ["models"], { reject: false });
@@ -14458,11 +14600,11 @@ function usageFromOpencode(tokens) {
14458
14600
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
14459
14601
  };
14460
14602
  }
14461
- var import_node_fs38, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14603
+ var import_node_fs39, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14462
14604
  var init_opencode = __esm({
14463
14605
  "src/agents/opencode.ts"() {
14464
14606
  "use strict";
14465
- import_node_fs38 = require("fs");
14607
+ import_node_fs39 = require("fs");
14466
14608
  init_run();
14467
14609
  init_app_settings();
14468
14610
  init_global_workspace();
@@ -14490,7 +14632,7 @@ var init_opencode = __esm({
14490
14632
  async detect() {
14491
14633
  const opencode = resolveAgentExecutable("opencode");
14492
14634
  if (opencode !== "opencode") {
14493
- if (!(0, import_node_fs38.existsSync)(opencode)) {
14635
+ if (!(0, import_node_fs39.existsSync)(opencode)) {
14494
14636
  return {
14495
14637
  agent: "opencode",
14496
14638
  installed: false,
@@ -15209,14 +15351,14 @@ function accessTokenFromCredentialsJson(raw) {
15209
15351
  }
15210
15352
  }
15211
15353
  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");
15354
+ const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path41.join)((0, import_node_os13.homedir)(), ".claude");
15355
+ return (0, import_node_path41.join)(root, ".credentials.json");
15214
15356
  }
15215
15357
  async function readFileAccessToken() {
15216
15358
  const path2 = claudeCredentialsPath();
15217
- if (!(0, import_node_fs39.existsSync)(path2)) return null;
15359
+ if (!(0, import_node_fs40.existsSync)(path2)) return null;
15218
15360
  try {
15219
- return accessTokenFromCredentialsJson((0, import_node_fs39.readFileSync)(path2, "utf8"));
15361
+ return accessTokenFromCredentialsJson((0, import_node_fs40.readFileSync)(path2, "utf8"));
15220
15362
  } catch {
15221
15363
  return null;
15222
15364
  }
@@ -15320,13 +15462,13 @@ async function getClaudePlanUsage(opts = {}) {
15320
15462
  })();
15321
15463
  return inflight;
15322
15464
  }
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;
15465
+ var import_node_fs40, import_node_os13, import_node_path41, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
15324
15466
  var init_claude_usage_client = __esm({
15325
15467
  "src/agents/claude-usage-client.ts"() {
15326
15468
  "use strict";
15327
- import_node_fs39 = require("fs");
15469
+ import_node_fs40 = require("fs");
15328
15470
  import_node_os13 = require("os");
15329
- import_node_path40 = require("path");
15471
+ import_node_path41 = require("path");
15330
15472
  init_run();
15331
15473
  init_fetch();
15332
15474
  init_app_settings();
@@ -15422,16 +15564,6 @@ async function whichOnPath(bin) {
15422
15564
  }
15423
15565
  async function installNpmGlobalPackage(opts) {
15424
15566
  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
15567
  const result = await run("npm", ["install", "-g", opts.npmPackage], { reject: false });
15436
15568
  const ok = result.exitCode === 0;
15437
15569
  if (!ok) {
@@ -15468,6 +15600,33 @@ async function installNpmGlobalPackage(opts) {
15468
15600
  message: binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
15469
15601
  };
15470
15602
  }
15603
+ async function resolveExistingCli(agent) {
15604
+ if (agent === "cursor") return null;
15605
+ const exe = resolveAgentExecutable(agent);
15606
+ if ((exe.includes("/") || exe.includes("\\")) && (0, import_node_fs41.existsSync)(exe)) return exe;
15607
+ enrichPathWithNpmGlobalBin();
15608
+ return whichOnPath(CLI_BIN[agent]);
15609
+ }
15610
+ async function runVendorUpdate(existing, updateArgs) {
15611
+ const result = await run(existing, updateArgs, {
15612
+ reject: false,
15613
+ timeoutMs: 12e4
15614
+ });
15615
+ const command = `${existing} ${updateArgs.join(" ")}`;
15616
+ const ok = result.exitCode === 0;
15617
+ const detail = result.stdout.trim() || result.stderr.trim() || `exit ${result.exitCode}`;
15618
+ return {
15619
+ ok,
15620
+ command,
15621
+ exitCode: result.exitCode,
15622
+ stdout: result.stdout,
15623
+ stderr: result.stderr,
15624
+ message: ok ? isConductorBundledCli(existing) ? `Updated Conductor\u2019s CLI at ${existing}. ${detail}` : `Updated ${command}. ${detail}` : `Update failed (${command}): ${detail}`
15625
+ };
15626
+ }
15627
+ function isCurlInstaller(command) {
15628
+ return /curl\s| \|\s*bash/.test(command);
15629
+ }
15471
15630
  async function installAgent(agent) {
15472
15631
  const info = getAgentSetupInfo(agent);
15473
15632
  if (info.kind === "bundled-sdk" || info.kind === "api-key") {
@@ -15479,21 +15638,25 @@ async function installAgent(agent) {
15479
15638
  if (!info.installCommand) {
15480
15639
  return { ok: false, message: `No install command for ${agent}` };
15481
15640
  }
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
- };
15641
+ const existing = await resolveExistingCli(agent);
15642
+ if (existing && info.updateArgs?.length) {
15643
+ return runVendorUpdate(existing, info.updateArgs);
15490
15644
  }
15491
- const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
15492
- return installNpmGlobalPackage({
15493
- npmPackage: info.npmPackage,
15494
- installCommand: info.installCommand,
15495
- cliBin
15496
- });
15645
+ if (info.npmPackage && !isCurlInstaller(info.installCommand)) {
15646
+ const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
15647
+ return installNpmGlobalPackage({
15648
+ npmPackage: info.npmPackage,
15649
+ installCommand: info.installCommand,
15650
+ cliBin
15651
+ });
15652
+ }
15653
+ await openInSystemTerminal(info.installCommand);
15654
+ return {
15655
+ ok: true,
15656
+ openedTerminal: true,
15657
+ command: info.installCommand,
15658
+ message: `Opened Terminal to run: ${info.installCommand}`
15659
+ };
15497
15660
  }
15498
15661
  async function loginAgent(agent) {
15499
15662
  const info = getAgentSetupInfo(agent);
@@ -15513,10 +15676,11 @@ async function loginAgent(agent) {
15513
15676
  message: `Opened Terminal to run: ${prepared}`
15514
15677
  };
15515
15678
  }
15516
- var SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
15679
+ var import_node_fs41, SETUP, CLI_BIN, CLI_LOGIN_AGENTS;
15517
15680
  var init_install = __esm({
15518
15681
  "src/agents/install.ts"() {
15519
15682
  "use strict";
15683
+ import_node_fs41 = require("fs");
15520
15684
  init_run();
15521
15685
  init_app_settings();
15522
15686
  init_path();
@@ -15528,7 +15692,8 @@ var init_install = __esm({
15528
15692
  docsUrl: "https://code.claude.com/docs/en/install",
15529
15693
  installCommand: "npm install -g @anthropic-ai/claude-code",
15530
15694
  loginCommand: "claude auth login",
15531
- npmPackage: "@anthropic-ai/claude-code"
15695
+ npmPackage: "@anthropic-ai/claude-code",
15696
+ updateArgs: ["update"]
15532
15697
  },
15533
15698
  codex: {
15534
15699
  agent: "codex",
@@ -15537,7 +15702,8 @@ var init_install = __esm({
15537
15702
  docsUrl: "https://github.com/openai/codex",
15538
15703
  installCommand: "npm install -g @openai/codex",
15539
15704
  loginCommand: "codex login",
15540
- npmPackage: "@openai/codex"
15705
+ npmPackage: "@openai/codex",
15706
+ updateArgs: ["update"]
15541
15707
  },
15542
15708
  opencode: {
15543
15709
  agent: "opencode",
@@ -15547,20 +15713,22 @@ var init_install = __esm({
15547
15713
  // Prefer the official installer; npm package name is opencode-ai.
15548
15714
  installCommand: "curl -fsSL https://opencode.ai/install | bash",
15549
15715
  loginCommand: "opencode auth login",
15550
- npmPackage: "opencode-ai@latest"
15716
+ npmPackage: "opencode-ai@latest",
15717
+ updateArgs: ["upgrade"]
15551
15718
  },
15552
15719
  cursor: {
15553
15720
  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
15721
+ kind: "cli",
15722
+ summary: "Install (or update) @cursor/sdk with npm \u2014 Sideboard does not pin it in the app. Then add a CURSOR_API_KEY.",
15723
+ docsUrl: "https://www.npmjs.com/package/@cursor/sdk",
15724
+ installCommand: "npm install -g @cursor/sdk",
15725
+ loginCommand: null,
15726
+ npmPackage: "@cursor/sdk"
15559
15727
  },
15560
15728
  brightsy: {
15561
15729
  agent: "brightsy",
15562
15730
  kind: "cli",
15563
- summary: "Install the Brightsy CLI, then run `brightsy login`.",
15731
+ summary: "Install (or update) the Brightsy CLI with npm, then run `brightsy login`.",
15564
15732
  docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
15565
15733
  installCommand: "npm install -g @brightsy/cli",
15566
15734
  loginCommand: "brightsy login",
@@ -15586,6 +15754,7 @@ var init_install = __esm({
15586
15754
  var agents_exports = {};
15587
15755
  __export(agents_exports, {
15588
15756
  CLAUDE_MODEL_CATALOG: () => CLAUDE_MODEL_CATALOG,
15757
+ CURSOR_SDK_INSTALL_HINT: () => CURSOR_SDK_INSTALL_HINT,
15589
15758
  ORCHESTRATOR_AGENT_KINDS: () => ORCHESTRATOR_AGENT_KINDS,
15590
15759
  PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
15591
15760
  allAdapters: () => allAdapters,
@@ -15619,6 +15788,7 @@ __export(agents_exports, {
15619
15788
  isConductorBundledCli: () => isConductorBundledCli,
15620
15789
  isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
15621
15790
  isCursorAutoModel: () => isCursorAutoModel,
15791
+ isCursorSdkInstalled: () => isCursorSdkInstalled,
15622
15792
  isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
15623
15793
  isSessionQuotaLimit: () => isSessionQuotaLimit,
15624
15794
  listAgentSetupInfo: () => listAgentSetupInfo,
@@ -15629,6 +15799,8 @@ __export(agents_exports, {
15629
15799
  listOpencodeModels: () => listOpencodeModels,
15630
15800
  loginAgent: () => loginAgent,
15631
15801
  mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
15802
+ npmGlobalNodeModules: () => npmGlobalNodeModules,
15803
+ npmGlobalPrefix: () => npmGlobalPrefix,
15632
15804
  openInSystemTerminal: () => openInSystemTerminal,
15633
15805
  opencodeAdapter: () => opencodeAdapter,
15634
15806
  parseClaudeUsagePayload: () => parseClaudeUsagePayload,
@@ -15640,6 +15812,7 @@ __export(agents_exports, {
15640
15812
  prepareTerminalCommand: () => prepareTerminalCommand,
15641
15813
  resolveCommandBinarySync: () => resolveCommandBinarySync,
15642
15814
  resolveCursorModelId: () => resolveCursorModelId,
15815
+ resolveCursorSdkRoot: () => resolveCursorSdkRoot,
15643
15816
  resolveLoginCommand: () => resolveLoginCommand,
15644
15817
  resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
15645
15818
  turnCostUsdFromCursorUsage: () => turnCostUsdFromCursorUsage,
@@ -15676,6 +15849,7 @@ var init_agents = __esm({
15676
15849
  init_claude_usage_client();
15677
15850
  init_orchestrator_capable();
15678
15851
  init_path();
15852
+ init_cursor_sdk_resolve();
15679
15853
  init_install();
15680
15854
  adapters = {
15681
15855
  claude: claudeAdapter,
@@ -15694,7 +15868,7 @@ function isAgentHostEnvKey(key) {
15694
15868
  }
15695
15869
  function stripHostToolingPath(pathValue) {
15696
15870
  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);
15871
+ return pathValue.split(import_node_path42.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path42.delimiter);
15698
15872
  }
15699
15873
  function sanitizeAgentHostEnv(env, cwd) {
15700
15874
  for (const key of Object.keys(env)) {
@@ -15708,11 +15882,11 @@ function sanitizeAgentHostEnv(env, cwd) {
15708
15882
  }
15709
15883
  return env;
15710
15884
  }
15711
- var import_node_path41, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15885
+ var import_node_path42, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15712
15886
  var init_agent_host_env = __esm({
15713
15887
  "src/hook/agent-host-env.ts"() {
15714
15888
  "use strict";
15715
- import_node_path41 = require("path");
15889
+ import_node_path42 = require("path");
15716
15890
  DROP_EXACT = /* @__PURE__ */ new Set([
15717
15891
  "NODE_PATH",
15718
15892
  "NODE_ENV_ELECTRON_VITE",
@@ -15751,15 +15925,15 @@ var init_agent_host_env = __esm({
15751
15925
 
15752
15926
  // src/hook/worktree-pkg-cache.ts
15753
15927
  function worktreePkgCacheRoot(worktreePath) {
15754
- return (0, import_node_path42.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15928
+ return (0, import_node_path43.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15755
15929
  }
15756
15930
  function worktreePkgCacheEnv(worktreePath) {
15757
15931
  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");
15932
+ const store = (0, import_node_path43.join)(root, "pnpm-store");
15933
+ const pnpmCache = (0, import_node_path43.join)(root, "pnpm");
15934
+ const npmCache = (0, import_node_path43.join)(root, "npm");
15935
+ const nodeGyp = (0, import_node_path43.join)(root, "node-gyp");
15936
+ const electron = (0, import_node_path43.join)(root, "electron");
15763
15937
  return {
15764
15938
  npm_config_store_dir: store,
15765
15939
  PNPM_STORE_DIR: store,
@@ -15781,8 +15955,8 @@ function fillGroup(env, keys, values) {
15781
15955
  }
15782
15956
  }
15783
15957
  function ensureWorktreePkgCacheDirs(worktreePath) {
15784
- if (!(0, import_node_fs40.existsSync)(worktreePath)) return;
15785
- (0, import_node_fs40.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15958
+ if (!(0, import_node_fs42.existsSync)(worktreePath)) return;
15959
+ (0, import_node_fs42.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15786
15960
  }
15787
15961
  function applyWorktreePkgCacheEnv(env, worktreePath) {
15788
15962
  const cwd = worktreePath.trim();
@@ -15795,12 +15969,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15795
15969
  fillGroup(env, ["electron_config_cache"], next);
15796
15970
  ensureWorktreePkgCacheDirs(cwd);
15797
15971
  }
15798
- var import_node_fs40, import_node_path42, WORKTREE_PKG_CACHE_REL;
15972
+ var import_node_fs42, import_node_path43, WORKTREE_PKG_CACHE_REL;
15799
15973
  var init_worktree_pkg_cache = __esm({
15800
15974
  "src/hook/worktree-pkg-cache.ts"() {
15801
15975
  "use strict";
15802
- import_node_fs40 = require("fs");
15803
- import_node_path42 = require("path");
15976
+ import_node_fs42 = require("fs");
15977
+ import_node_path43 = require("path");
15804
15978
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15805
15979
  }
15806
15980
  });
@@ -17041,21 +17215,21 @@ function shouldRefreshReviewRequestTemplate(content) {
17041
17215
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
17042
17216
  }
17043
17217
  function readTextIfPresent(abs) {
17044
- if (!(0, import_node_fs41.existsSync)(abs)) return null;
17218
+ if (!(0, import_node_fs43.existsSync)(abs)) return null;
17045
17219
  try {
17046
- const content = (0, import_node_fs41.readFileSync)(abs, "utf8");
17220
+ const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
17047
17221
  return content.trim() ? content : null;
17048
17222
  } catch {
17049
17223
  return null;
17050
17224
  }
17051
17225
  }
17052
17226
  function readLocalGuidelines(worktreePath) {
17053
- const localAbs = (0, import_node_path43.join)(worktreePath, REVIEW_REQUEST_PATH);
17227
+ const localAbs = (0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH);
17054
17228
  const localContent = readTextIfPresent(localAbs);
17055
17229
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
17056
17230
  return { path: REVIEW_REQUEST_PATH, content: localContent };
17057
17231
  }
17058
- const legacyAbs = (0, import_node_path43.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17232
+ const legacyAbs = (0, import_node_path44.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
17059
17233
  const legacyContent = readTextIfPresent(legacyAbs);
17060
17234
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
17061
17235
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -17079,27 +17253,27 @@ function contextGuidelines(content, source) {
17079
17253
  };
17080
17254
  }
17081
17255
  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 });
17256
+ const abs = (0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH);
17257
+ (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
17084
17258
  const body = content.endsWith("\n") ? content : `${content}
17085
17259
  `;
17086
- (0, import_node_fs41.writeFileSync)(abs, body, "utf8");
17260
+ (0, import_node_fs43.writeFileSync)(abs, body, "utf8");
17087
17261
  return body;
17088
17262
  }
17089
17263
  function readSideboardReview(worktreePath, repoPath) {
17090
- const fromWorktree = readTextIfPresent((0, import_node_path43.join)(worktreePath, REPO_REVIEW_PATH));
17264
+ const fromWorktree = readTextIfPresent((0, import_node_path44.join)(worktreePath, REPO_REVIEW_PATH));
17091
17265
  if (fromWorktree) return fromWorktree;
17092
17266
  const repo = repoPath?.replace(/\/+$/, "");
17093
17267
  const wt = worktreePath.replace(/\/+$/, "");
17094
17268
  if (!repo || repo === wt) return null;
17095
- return readTextIfPresent((0, import_node_path43.join)(repo, REPO_REVIEW_PATH));
17269
+ return readTextIfPresent((0, import_node_path44.join)(repo, REPO_REVIEW_PATH));
17096
17270
  }
17097
17271
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
17098
- const skillContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_SKILL_PATH));
17272
+ const skillContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_SKILL_PATH));
17099
17273
  if (skillContent) {
17100
17274
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
17101
17275
  }
17102
- const contextContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH));
17276
+ const contextContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH));
17103
17277
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
17104
17278
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
17105
17279
  }
@@ -17137,7 +17311,7 @@ function buildReviewRequestAttachment(content, opts) {
17137
17311
  };
17138
17312
  }
17139
17313
  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));
17314
+ 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
17315
  }
17142
17316
  async function requestReview(threadRef, send2) {
17143
17317
  const from = findThreadByRef(threadRef);
@@ -17164,13 +17338,13 @@ async function requestReview(threadRef, send2) {
17164
17338
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
17165
17339
  return { tab: started, from };
17166
17340
  }
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;
17341
+ 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
17342
  var init_request_review = __esm({
17169
17343
  "src/review/request-review.ts"() {
17170
17344
  "use strict";
17171
17345
  import_node_crypto9 = require("crypto");
17172
- import_node_fs41 = require("fs");
17173
- import_node_path43 = require("path");
17346
+ import_node_fs43 = require("fs");
17347
+ import_node_path44 = require("path");
17174
17348
  init_global_workspace();
17175
17349
  init_chat_tabs();
17176
17350
  init_thread_store();
@@ -17196,9 +17370,9 @@ function matchSimpleGlob(pattern, name) {
17196
17370
  return new RegExp(`^${escaped}$`).test(name);
17197
17371
  }
17198
17372
  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("#"));
17373
+ const path2 = (0, import_node_path45.join)(repoPath, ".worktreeinclude");
17374
+ if (!(0, import_node_fs44.existsSync)(path2)) return [];
17375
+ return (0, import_node_fs44.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17202
17376
  }
17203
17377
  function resolveFilesToCopy(repoPath) {
17204
17378
  const fromInclude = readWorktreeInclude(repoPath);
@@ -17208,10 +17382,10 @@ function resolveFilesToCopy(repoPath) {
17208
17382
  if (settings?.fileIncludeGlobs?.length) {
17209
17383
  const matched = [];
17210
17384
  try {
17211
- for (const entry of (0, import_node_fs42.readdirSync)(repoPath, { withFileTypes: true })) {
17385
+ for (const entry of (0, import_node_fs44.readdirSync)(repoPath, { withFileTypes: true })) {
17212
17386
  if (!entry.isFile()) continue;
17213
17387
  for (const glob of settings.fileIncludeGlobs) {
17214
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path44.basename)(glob), entry.name)) {
17388
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path45.basename)(glob), entry.name)) {
17215
17389
  matched.push(entry.name);
17216
17390
  break;
17217
17391
  }
@@ -17223,7 +17397,7 @@ function resolveFilesToCopy(repoPath) {
17223
17397
  }
17224
17398
  const defaults = [];
17225
17399
  try {
17226
- for (const entry of (0, import_node_fs42.readdirSync)(repoPath, { withFileTypes: true })) {
17400
+ for (const entry of (0, import_node_fs44.readdirSync)(repoPath, { withFileTypes: true })) {
17227
17401
  if (entry.isFile() && entry.name.startsWith(".env")) {
17228
17402
  defaults.push(entry.name);
17229
17403
  }
@@ -17237,11 +17411,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
17237
17411
  const patterns = resolveFilesToCopy(repoPath);
17238
17412
  const copied = [];
17239
17413
  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);
17414
+ const src = (0, import_node_path45.join)(repoPath, rel);
17415
+ if (!(0, import_node_fs44.existsSync)(src)) continue;
17416
+ const dest = (0, import_node_path45.join)(worktreePath, rel);
17417
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
17418
+ (0, import_node_fs44.copyFileSync)(src, dest);
17245
17419
  copied.push(rel);
17246
17420
  }
17247
17421
  return copied;
@@ -17276,7 +17450,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
17276
17450
  const env = stripNestedElectronEnv({
17277
17451
  ...baseEnv ?? process.env
17278
17452
  });
17279
- const name = opts.workspaceName ?? (0, import_node_path44.basename)(opts.worktreePath);
17453
+ const name = opts.workspaceName ?? (0, import_node_path45.basename)(opts.worktreePath);
17280
17454
  const ports = opts.ports ?? [];
17281
17455
  const primary = ports[0];
17282
17456
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -17611,14 +17785,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
17611
17785
  throw err;
17612
17786
  }
17613
17787
  }
17614
- var import_node_fs42, import_node_child_process5, import_node_net, import_node_path44, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17788
+ var import_node_fs44, import_node_child_process5, import_node_net, import_node_path45, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17615
17789
  var init_conductor = __esm({
17616
17790
  "src/hook/conductor.ts"() {
17617
17791
  "use strict";
17618
- import_node_fs42 = require("fs");
17792
+ import_node_fs44 = require("fs");
17619
17793
  import_node_child_process5 = require("child_process");
17620
17794
  import_node_net = require("net");
17621
- import_node_path44 = require("path");
17795
+ import_node_path45 = require("path");
17622
17796
  import_execa4 = require("execa");
17623
17797
  import_node_readline3 = require("readline");
17624
17798
  init_settings();
@@ -17646,9 +17820,9 @@ async function findOrphanWorktrees(repoPaths) {
17646
17820
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17647
17821
  );
17648
17822
  const homeRoot = sideboardWorkspacesDir();
17649
- if ((0, import_node_fs43.existsSync)(homeRoot)) {
17823
+ if ((0, import_node_fs45.existsSync)(homeRoot)) {
17650
17824
  try {
17651
- for (const entry of (0, import_node_fs43.readdirSync)(homeRoot, { withFileTypes: true })) {
17825
+ for (const entry of (0, import_node_fs45.readdirSync)(homeRoot, { withFileTypes: true })) {
17652
17826
  if (!entry.isDirectory()) continue;
17653
17827
  void entry;
17654
17828
  }
@@ -17658,7 +17832,7 @@ async function findOrphanWorktrees(repoPaths) {
17658
17832
  const orphans = [];
17659
17833
  const seen = /* @__PURE__ */ new Set();
17660
17834
  for (const repoPath of repos) {
17661
- if (!repoPath || !(0, import_node_fs43.existsSync)(repoPath)) continue;
17835
+ if (!repoPath || !(0, import_node_fs45.existsSync)(repoPath)) continue;
17662
17836
  try {
17663
17837
  const wts = await listWorktrees(repoPath);
17664
17838
  for (const wt of wts) {
@@ -17669,7 +17843,7 @@ async function findOrphanWorktrees(repoPaths) {
17669
17843
  seen.add(path2);
17670
17844
  let mtimeMs = 0;
17671
17845
  try {
17672
- mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17846
+ mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
17673
17847
  } catch {
17674
17848
  mtimeMs = 0;
17675
17849
  }
@@ -17679,16 +17853,16 @@ async function findOrphanWorktrees(repoPaths) {
17679
17853
  }
17680
17854
  try {
17681
17855
  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 })) {
17856
+ if ((0, import_node_fs45.existsSync)(root)) {
17857
+ for (const entry of (0, import_node_fs45.readdirSync)(root, { withFileTypes: true })) {
17684
17858
  if (!entry.isDirectory()) continue;
17685
- const path2 = (0, import_node_path45.join)(root, entry.name).replace(/\/$/, "");
17859
+ const path2 = (0, import_node_path46.join)(root, entry.name).replace(/\/$/, "");
17686
17860
  if (known.has(path2) || seen.has(path2)) continue;
17687
- if (!(0, import_node_fs43.existsSync)((0, import_node_path45.join)(path2, ".git"))) continue;
17861
+ if (!(0, import_node_fs45.existsSync)((0, import_node_path46.join)(path2, ".git"))) continue;
17688
17862
  seen.add(path2);
17689
17863
  let mtimeMs = 0;
17690
17864
  try {
17691
- mtimeMs = (0, import_node_fs43.statSync)(path2).mtimeMs;
17865
+ mtimeMs = (0, import_node_fs45.statSync)(path2).mtimeMs;
17692
17866
  } catch {
17693
17867
  mtimeMs = Date.now();
17694
17868
  }
@@ -17749,12 +17923,12 @@ function worktreeCleanupSettings() {
17749
17923
  autoCleanupOrphans: a.autoCleanupOrphans
17750
17924
  };
17751
17925
  }
17752
- var import_node_fs43, import_node_path45;
17926
+ var import_node_fs45, import_node_path46;
17753
17927
  var init_orphan_cleanup = __esm({
17754
17928
  "src/git/orphan-cleanup.ts"() {
17755
17929
  "use strict";
17756
- import_node_fs43 = require("fs");
17757
- import_node_path45 = require("path");
17930
+ import_node_fs45 = require("fs");
17931
+ import_node_path46 = require("path");
17758
17932
  init_worktree();
17759
17933
  init_thread_store();
17760
17934
  init_paths();
@@ -17929,12 +18103,12 @@ async function cloneRepoIntoSideboard(opts) {
17929
18103
  if (!url) throw new Error("Clone URL is required");
17930
18104
  let name = opts.name?.trim();
17931
18105
  if (!name) {
17932
- const leaf = (0, import_node_path46.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18106
+ const leaf = (0, import_node_path47.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17933
18107
  name = leaf || "repo";
17934
18108
  }
17935
18109
  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)) {
18110
+ const dest = (0, import_node_path47.join)(sideboardReposDir(), name);
18111
+ if ((0, import_node_fs46.existsSync)(dest)) {
17938
18112
  const repoPath2 = await resolveRepoRoot(dest);
17939
18113
  const workspace2 = await ensureWorkspace(repoPath2);
17940
18114
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -17949,12 +18123,12 @@ async function cloneRepoIntoSideboard(opts) {
17949
18123
  const workspace = await ensureWorkspace(repoPath);
17950
18124
  return { repoPath, workspace };
17951
18125
  }
17952
- var import_node_fs44, import_node_path46, import_execa6;
18126
+ var import_node_fs46, import_node_path47, import_execa6;
17953
18127
  var init_clone_repo = __esm({
17954
18128
  "src/git/clone-repo.ts"() {
17955
18129
  "use strict";
17956
- import_node_fs44 = require("fs");
17957
- import_node_path46 = require("path");
18130
+ import_node_fs46 = require("fs");
18131
+ import_node_path47 = require("path");
17958
18132
  import_execa6 = require("execa");
17959
18133
  init_paths();
17960
18134
  init_workspaces();
@@ -18075,24 +18249,24 @@ function jobTreeAlive(pid) {
18075
18249
  return jobAlive(pid) || processGroupAlive(pid);
18076
18250
  }
18077
18251
  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);
18252
+ if (!(0, import_node_fs47.existsSync)(file)) return null;
18253
+ const n = Number.parseInt((0, import_node_fs47.readFileSync)(file, "utf8").trim(), 10);
18080
18254
  return Number.isInteger(n) ? n : null;
18081
18255
  }
18082
18256
  function jobDir(root, id, legacy = false) {
18083
- return (0, import_node_path47.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18257
+ return (0, import_node_path48.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
18084
18258
  }
18085
18259
  function resolveJobDir(root, id) {
18086
18260
  const modern = jobDir(root, id, false);
18087
- if ((0, import_node_fs45.existsSync)(modern)) return modern;
18261
+ if ((0, import_node_fs47.existsSync)(modern)) return modern;
18088
18262
  const legacy = jobDir(root, id, true);
18089
- if ((0, import_node_fs45.existsSync)(legacy)) return legacy;
18263
+ if ((0, import_node_fs47.existsSync)(legacy)) return legacy;
18090
18264
  return modern;
18091
18265
  }
18092
18266
  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);
18267
+ const dir = (0, import_node_path48.join)(root, rel);
18268
+ if (!(0, import_node_fs47.existsSync)(dir)) return [];
18269
+ return (0, import_node_fs47.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
18096
18270
  }
18097
18271
  function listRunningDetachedJobs(worktreePath) {
18098
18272
  const root = worktreePath.trim();
@@ -18104,7 +18278,7 @@ function listRunningDetachedJobs(worktreePath) {
18104
18278
  const running = [];
18105
18279
  for (const id of ids) {
18106
18280
  const dir = resolveJobDir(root, id);
18107
- const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18281
+ const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18108
18282
  if (jobTreeAlive(pid)) running.push(id);
18109
18283
  }
18110
18284
  return running.sort();
@@ -18187,8 +18361,8 @@ function planJobContinue(opts) {
18187
18361
  return { action: "none" };
18188
18362
  }
18189
18363
  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");
18364
+ if (!(0, import_node_fs47.existsSync)(logFile)) return "(no log yet)";
18365
+ const lines = (0, import_node_fs47.readFileSync)(logFile, "utf8").split("\n");
18192
18366
  return lines.slice(-maxLines).join("\n");
18193
18367
  }
18194
18368
  function lastProgressLine(progress) {
@@ -18196,8 +18370,8 @@ function lastProgressLine(progress) {
18196
18370
  return last ? last.slice(0, 72) : void 0;
18197
18371
  }
18198
18372
  function readLogLines(file) {
18199
- if (!(0, import_node_fs45.existsSync)(file)) return [];
18200
- const lines = (0, import_node_fs45.readFileSync)(file, "utf8").split("\n");
18373
+ if (!(0, import_node_fs47.existsSync)(file)) return [];
18374
+ const lines = (0, import_node_fs47.readFileSync)(file, "utf8").split("\n");
18201
18375
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
18202
18376
  return lines;
18203
18377
  }
@@ -18208,15 +18382,15 @@ function takeDelta(logFile, cursorFile) {
18208
18382
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
18209
18383
  }
18210
18384
  function snapshotJob(dir) {
18211
- const pid = readIntFile((0, import_node_path47.join)(dir, "pid"));
18385
+ const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
18212
18386
  const running = jobTreeAlive(pid);
18213
18387
  return {
18214
18388
  pid,
18215
18389
  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"))
18390
+ exitCode: readIntFile((0, import_node_path48.join)(dir, "exit")),
18391
+ log: (0, import_node_path48.join)(dir, "log"),
18392
+ cursor: (0, import_node_path48.join)(dir, "present.cursor"),
18393
+ progress: tailProgress((0, import_node_path48.join)(dir, "log"))
18220
18394
  };
18221
18395
  }
18222
18396
  function toResult(id, snap, extra) {
@@ -18225,8 +18399,8 @@ function toResult(id, snap, extra) {
18225
18399
  const stillRunning = snap.running && !ok;
18226
18400
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
18227
18401
  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}
18402
+ (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(snap.cursor), { recursive: true });
18403
+ (0, import_node_fs47.writeFileSync)(snap.cursor, `${nextCursor}
18230
18404
  `);
18231
18405
  } catch {
18232
18406
  }
@@ -18255,7 +18429,7 @@ async function waitForDetachedJob(cwd, id, opts) {
18255
18429
  const dir = resolveJobDir(root, jobId);
18256
18430
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
18257
18431
  const sleep2 = opts?.sleep ?? sleepMs;
18258
- if (!(0, import_node_fs45.existsSync)(dir)) {
18432
+ if (!(0, import_node_fs47.existsSync)(dir)) {
18259
18433
  return {
18260
18434
  stillRunning: false,
18261
18435
  ok: false,
@@ -18301,10 +18475,10 @@ function killProcessTree(pid, signal) {
18301
18475
  }
18302
18476
  function appendJobLog(logFile, line) {
18303
18477
  try {
18304
- (0, import_node_fs45.mkdirSync)((0, import_node_path47.dirname)(logFile), { recursive: true });
18478
+ (0, import_node_fs47.mkdirSync)((0, import_node_path48.dirname)(logFile), { recursive: true });
18305
18479
  const body = line.endsWith("\n") ? line : `${line}
18306
18480
  `;
18307
- (0, import_node_fs45.appendFileSync)(logFile, body);
18481
+ (0, import_node_fs47.appendFileSync)(logFile, body);
18308
18482
  } catch {
18309
18483
  }
18310
18484
  }
@@ -18314,7 +18488,7 @@ async function stopDetachedJob(cwd, id, opts) {
18314
18488
  const dir = resolveJobDir(root, jobId);
18315
18489
  const sleep2 = opts?.sleep ?? sleepMs;
18316
18490
  const why = opts?.reason?.trim() ?? "";
18317
- if (!(0, import_node_fs45.existsSync)(dir)) {
18491
+ if (!(0, import_node_fs47.existsSync)(dir)) {
18318
18492
  return {
18319
18493
  stillRunning: false,
18320
18494
  ok: false,
@@ -18350,10 +18524,10 @@ async function stopDetachedJob(cwd, id, opts) {
18350
18524
  killProcessTree(targetPid, "SIGKILL");
18351
18525
  await sleep2(100);
18352
18526
  }
18353
- const exitFile = (0, import_node_path47.join)(dir, "exit");
18354
- if (!(0, import_node_fs45.existsSync)(exitFile)) {
18527
+ const exitFile = (0, import_node_path48.join)(dir, "exit");
18528
+ if (!(0, import_node_fs47.existsSync)(exitFile)) {
18355
18529
  try {
18356
- (0, import_node_fs45.writeFileSync)(exitFile, "1\n");
18530
+ (0, import_node_fs47.writeFileSync)(exitFile, "1\n");
18357
18531
  } catch {
18358
18532
  }
18359
18533
  }
@@ -18373,12 +18547,12 @@ async function stopDetachedJob(cwd, id, opts) {
18373
18547
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
18374
18548
  };
18375
18549
  }
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;
18550
+ 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
18551
  var init_wait_for_job = __esm({
18378
18552
  "src/mcp/wait-for-job.ts"() {
18379
18553
  "use strict";
18380
- import_node_fs45 = require("fs");
18381
- import_node_path47 = require("path");
18554
+ import_node_fs47 = require("fs");
18555
+ import_node_path48 = require("path");
18382
18556
  init_workspace_scratch();
18383
18557
  init_wait_for_turn();
18384
18558
  MAX_JOB_CONTINUES = 8;
@@ -19923,7 +20097,7 @@ function reuseLiveThread(input, repoPath, match) {
19923
20097
  }
19924
20098
  async function createThread(input, _onSetupLine) {
19925
20099
  const repoPath = await resolveRepoRoot(input.repoPath);
19926
- if (!(0, import_node_fs46.existsSync)(repoPath)) {
20100
+ if (!(0, import_node_fs48.existsSync)(repoPath)) {
19927
20101
  throw new Error(`Repo not found: ${repoPath}`);
19928
20102
  }
19929
20103
  const reused = reuseLiveThread(input, repoPath, {
@@ -20108,11 +20282,11 @@ async function listLinearIssues(agent, repoPath) {
20108
20282
  }
20109
20283
  return adapter.listLinearIssues(repoPath);
20110
20284
  }
20111
- var import_node_fs46;
20285
+ var import_node_fs48;
20112
20286
  var init_create = __esm({
20113
20287
  "src/threads/create.ts"() {
20114
20288
  "use strict";
20115
- import_node_fs46 = require("fs");
20289
+ import_node_fs48 = require("fs");
20116
20290
  init_detect();
20117
20291
  init_worktree();
20118
20292
  init_home_board();
@@ -20264,20 +20438,20 @@ function writeTurnLive(threadId, progress) {
20264
20438
  const path2 = threadLivePath(threadId);
20265
20439
  const tmp = `${path2}.${process.pid}.tmp`;
20266
20440
  try {
20267
- (0, import_node_fs47.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20268
- (0, import_node_fs47.renameSync)(tmp, path2);
20441
+ (0, import_node_fs49.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
20442
+ (0, import_node_fs49.renameSync)(tmp, path2);
20269
20443
  } catch {
20270
20444
  try {
20271
- (0, import_node_fs47.unlinkSync)(tmp);
20445
+ (0, import_node_fs49.unlinkSync)(tmp);
20272
20446
  } catch {
20273
20447
  }
20274
20448
  }
20275
20449
  }
20276
20450
  function readTurnLive(threadId) {
20277
20451
  const path2 = threadLivePath(threadId);
20278
- if (!(0, import_node_fs47.existsSync)(path2)) return null;
20452
+ if (!(0, import_node_fs49.existsSync)(path2)) return null;
20279
20453
  try {
20280
- const raw = JSON.parse((0, import_node_fs47.readFileSync)(path2, "utf8"));
20454
+ const raw = JSON.parse((0, import_node_fs49.readFileSync)(path2, "utf8"));
20281
20455
  if (!raw || typeof raw.summary !== "string") return null;
20282
20456
  return raw;
20283
20457
  } catch {
@@ -20289,17 +20463,17 @@ function clearTurnLive(threadId) {
20289
20463
  if (buf?.timer) clearTimeout(buf.timer);
20290
20464
  buffers.delete(threadId);
20291
20465
  const path2 = threadLivePath(threadId);
20292
- if (!(0, import_node_fs47.existsSync)(path2)) return;
20466
+ if (!(0, import_node_fs49.existsSync)(path2)) return;
20293
20467
  try {
20294
- (0, import_node_fs47.unlinkSync)(path2);
20468
+ (0, import_node_fs49.unlinkSync)(path2);
20295
20469
  } catch {
20296
20470
  }
20297
20471
  }
20298
- var import_node_fs47, buffers, FLUSH_MS, MAX_PARTS;
20472
+ var import_node_fs49, buffers, FLUSH_MS, MAX_PARTS;
20299
20473
  var init_turn_live = __esm({
20300
20474
  "src/store/turn-live.ts"() {
20301
20475
  "use strict";
20302
- import_node_fs47 = require("fs");
20476
+ import_node_fs49 = require("fs");
20303
20477
  init_message_parts();
20304
20478
  init_paths();
20305
20479
  buffers = /* @__PURE__ */ new Map();
@@ -20541,12 +20715,12 @@ var init_quota_failover = __esm({
20541
20715
  });
20542
20716
 
20543
20717
  // src/threads/adopt.ts
20544
- function thisModuleFile() {
20718
+ function thisModuleFile2() {
20545
20719
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
20546
- return cjsFile || process.argv[1] || (0, import_node_path48.join)(process.cwd(), "package.json");
20720
+ return cjsFile || process.argv[1] || (0, import_node_path49.join)(process.cwd(), "package.json");
20547
20721
  }
20548
20722
  function openReadonlySqlite(file) {
20549
- const req = (0, import_node_module4.createRequire)(thisModuleFile());
20723
+ const req = (0, import_node_module5.createRequire)(thisModuleFile2());
20550
20724
  const Database = req("better-sqlite3");
20551
20725
  return new Database(file, { readonly: true, fileMustExist: true });
20552
20726
  }
@@ -20561,21 +20735,21 @@ function mapAgentType(raw) {
20561
20735
  return null;
20562
20736
  }
20563
20737
  function resolveConductorCursorAgentId(workspacePath) {
20564
- if (!workspacePath || !(0, import_node_fs48.existsSync)(CURSOR_SDK_STORE)) return null;
20738
+ if (!workspacePath || !(0, import_node_fs50.existsSync)(CURSOR_SDK_STORE)) return null;
20565
20739
  const normalized = workspacePath.replace(/\/$/, "");
20566
20740
  let best = null;
20567
20741
  let hashes;
20568
20742
  try {
20569
- hashes = (0, import_node_fs48.readdirSync)(CURSOR_SDK_STORE);
20743
+ hashes = (0, import_node_fs50.readdirSync)(CURSOR_SDK_STORE);
20570
20744
  } catch {
20571
20745
  return null;
20572
20746
  }
20573
20747
  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;
20748
+ const agentsFile = (0, import_node_path49.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20749
+ if (!(0, import_node_fs50.existsSync)(agentsFile)) continue;
20576
20750
  let text7;
20577
20751
  try {
20578
- text7 = (0, import_node_fs48.readFileSync)(agentsFile, "utf8");
20752
+ text7 = (0, import_node_fs50.readFileSync)(agentsFile, "utf8");
20579
20753
  } catch {
20580
20754
  continue;
20581
20755
  }
@@ -20599,7 +20773,7 @@ function resolveConductorCursorAgentId(workspacePath) {
20599
20773
  return best?.agentId ?? null;
20600
20774
  }
20601
20775
  async function adoptThread(input) {
20602
- if (!(0, import_node_fs48.existsSync)(input.worktreePath)) {
20776
+ if (!(0, import_node_fs50.existsSync)(input.worktreePath)) {
20603
20777
  throw new Error(`Worktree not found: ${input.worktreePath}`);
20604
20778
  }
20605
20779
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -20628,18 +20802,18 @@ function conductorDbPath() {
20628
20802
  return CONDUCTOR_DB;
20629
20803
  }
20630
20804
  function listConductorWorkspaces() {
20631
- if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20805
+ if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
20632
20806
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20633
20807
  }
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");
20808
+ const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20809
+ const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
20636
20810
  try {
20637
- (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20811
+ (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
20638
20812
  for (const suffix of ["-wal", "-shm"]) {
20639
20813
  const src = `${CONDUCTOR_DB}${suffix}`;
20640
- if ((0, import_node_fs48.existsSync)(src)) {
20814
+ if ((0, import_node_fs50.existsSync)(src)) {
20641
20815
  try {
20642
- (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20816
+ (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
20643
20817
  } catch {
20644
20818
  }
20645
20819
  }
@@ -20715,22 +20889,22 @@ function listConductorWorkspaces() {
20715
20889
  db.close();
20716
20890
  }
20717
20891
  } finally {
20718
- (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20892
+ (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
20719
20893
  }
20720
20894
  }
20721
20895
  function importConductorWorkspace(workspaceId) {
20722
- if (!(0, import_node_fs48.existsSync)(CONDUCTOR_DB)) {
20896
+ if (!(0, import_node_fs50.existsSync)(CONDUCTOR_DB)) {
20723
20897
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
20724
20898
  }
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");
20899
+ const tmp = (0, import_node_fs50.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20900
+ const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
20727
20901
  try {
20728
- (0, import_node_fs48.copyFileSync)(CONDUCTOR_DB, snapshot);
20902
+ (0, import_node_fs50.copyFileSync)(CONDUCTOR_DB, snapshot);
20729
20903
  for (const suffix of ["-wal", "-shm"]) {
20730
20904
  const src = `${CONDUCTOR_DB}${suffix}`;
20731
- if ((0, import_node_fs48.existsSync)(src)) {
20905
+ if ((0, import_node_fs50.existsSync)(src)) {
20732
20906
  try {
20733
- (0, import_node_fs48.copyFileSync)(src, `${snapshot}${suffix}`);
20907
+ (0, import_node_fs50.copyFileSync)(src, `${snapshot}${suffix}`);
20734
20908
  } catch {
20735
20909
  }
20736
20910
  }
@@ -20748,7 +20922,7 @@ function importConductorWorkspace(workspaceId) {
20748
20922
  ).get(workspaceId);
20749
20923
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
20750
20924
  const worktreePath = String(row.workspacePath);
20751
- if (!(0, import_node_fs48.existsSync)(worktreePath)) {
20925
+ if (!(0, import_node_fs50.existsSync)(worktreePath)) {
20752
20926
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
20753
20927
  }
20754
20928
  let sessionId = null;
@@ -20811,31 +20985,31 @@ function importConductorWorkspace(workspaceId) {
20811
20985
  db.close();
20812
20986
  }
20813
20987
  } finally {
20814
- (0, import_node_fs48.rmSync)(tmp, { recursive: true, force: true });
20988
+ (0, import_node_fs50.rmSync)(tmp, { recursive: true, force: true });
20815
20989
  }
20816
20990
  }
20817
20991
  async function importConductorWorkspaceAsync(workspaceId) {
20818
20992
  return importConductorWorkspace(workspaceId);
20819
20993
  }
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;
20994
+ 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
20995
  var init_adopt = __esm({
20822
20996
  "src/threads/adopt.ts"() {
20823
20997
  "use strict";
20824
20998
  import_node_child_process6 = require("child_process");
20825
- import_node_fs48 = require("fs");
20999
+ import_node_fs50 = require("fs");
20826
21000
  import_node_os14 = require("os");
20827
- import_node_path48 = require("path");
20828
- import_node_module4 = require("module");
21001
+ import_node_path49 = require("path");
21002
+ import_node_module5 = require("module");
20829
21003
  init_worktree();
20830
21004
  init_thread_store();
20831
- CONDUCTOR_APP_SUPPORT = (0, import_node_path48.join)(
21005
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path49.join)(
20832
21006
  process.env.HOME ?? "",
20833
21007
  "Library",
20834
21008
  "Application Support",
20835
21009
  "com.conductor.app"
20836
21010
  );
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");
21011
+ CONDUCTOR_DB = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
21012
+ CURSOR_SDK_STORE = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20839
21013
  }
20840
21014
  });
20841
21015
 
@@ -20902,7 +21076,7 @@ async function openStackLayer(input, _onSetupLine) {
20902
21076
  let createdWorktree = false;
20903
21077
  const trees = await listWorktrees(repoPath);
20904
21078
  const checkedOut = trees.find((w) => w.branch === branchName);
20905
- if (checkedOut?.path && (0, import_node_fs49.existsSync)(checkedOut.path)) {
21079
+ if (checkedOut?.path && (0, import_node_fs51.existsSync)(checkedOut.path)) {
20906
21080
  if (input.reuseExistingWorktree !== false) {
20907
21081
  worktreePath = checkedOut.path;
20908
21082
  } else {
@@ -21044,7 +21218,7 @@ async function initStackFromThread(input, onSetupLine) {
21044
21218
  async function createPrStack(input, onSetupLine) {
21045
21219
  await requireAgent(input.agent);
21046
21220
  const repoPath = await resolveRepoRoot(input.repoPath);
21047
- if (!(0, import_node_fs49.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21221
+ if (!(0, import_node_fs51.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
21048
21222
  if (!input.branches.length) throw new Error("At least one branch name required");
21049
21223
  const status = await detectGhStack(repoPath);
21050
21224
  if (!status.available) throw new Error(status.reason);
@@ -21111,7 +21285,7 @@ async function createPrStack(input, onSetupLine) {
21111
21285
  }
21112
21286
  }
21113
21287
  const claimed = new Set(threads.map((t) => t.worktreePath));
21114
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs49.existsSync)(bootstrap.worktreePath)) {
21288
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs51.existsSync)(bootstrap.worktreePath)) {
21115
21289
  try {
21116
21290
  await removeWorktree(repoPath, bootstrap.worktreePath, {
21117
21291
  deleteBranch: bootstrap.branchName
@@ -21131,11 +21305,11 @@ function stackAgentDefaultsFrom(input) {
21131
21305
  planMode: input.planMode
21132
21306
  };
21133
21307
  }
21134
- var import_node_fs49;
21308
+ var import_node_fs51;
21135
21309
  var init_stack_layers = __esm({
21136
21310
  "src/threads/stack-layers.ts"() {
21137
21311
  "use strict";
21138
- import_node_fs49 = require("fs");
21312
+ import_node_fs51 = require("fs");
21139
21313
  init_detect();
21140
21314
  init_run();
21141
21315
  init_stack();
@@ -21148,7 +21322,7 @@ var init_stack_layers = __esm({
21148
21322
 
21149
21323
  // src/diff/diff.ts
21150
21324
  async function inspectGitWorktree(worktreePath) {
21151
- if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) return "missing_worktree";
21325
+ if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) return "missing_worktree";
21152
21326
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
21153
21327
  reject: false
21154
21328
  });
@@ -21156,7 +21330,7 @@ async function inspectGitWorktree(worktreePath) {
21156
21330
  return "ok";
21157
21331
  }
21158
21332
  async function initializeGitRepository(worktreePath) {
21159
- if (!worktreePath || !(0, import_node_fs50.existsSync)(worktreePath)) {
21333
+ if (!worktreePath || !(0, import_node_fs52.existsSync)(worktreePath)) {
21160
21334
  throw new Error("Worktree not found");
21161
21335
  }
21162
21336
  const status = await inspectGitWorktree(worktreePath);
@@ -21290,11 +21464,11 @@ new file mode 100644
21290
21464
  };
21291
21465
  }
21292
21466
  async function untrackedPatch(worktreePath, path2, maxHunk) {
21293
- const abs = (0, import_node_path49.join)(worktreePath, path2);
21467
+ const abs = (0, import_node_path50.join)(worktreePath, path2);
21294
21468
  try {
21295
- const st = (0, import_node_fs50.statSync)(abs);
21469
+ const st = (0, import_node_fs52.statSync)(abs);
21296
21470
  if (st.isFile() && st.size > maxHunk) {
21297
- const buf = (0, import_node_fs50.readFileSync)(abs).subarray(0, maxHunk);
21471
+ const buf = (0, import_node_fs52.readFileSync)(abs).subarray(0, maxHunk);
21298
21472
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
21299
21473
  }
21300
21474
  } catch {
@@ -21761,9 +21935,9 @@ async function getDiff(worktreePath, repoPath, opts) {
21761
21935
  }
21762
21936
  function statWorktreePath(worktreePath, relativePath) {
21763
21937
  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);
21938
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21939
+ if (!(0, import_node_fs52.existsSync)(abs)) return "missing";
21940
+ const st = (0, import_node_fs52.statSync)(abs);
21767
21941
  if (st.isDirectory()) return "dir";
21768
21942
  if (st.isFile()) return "file";
21769
21943
  return "missing";
@@ -21792,8 +21966,8 @@ function isImageRelativePath(relativePath) {
21792
21966
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21793
21967
  assertSafeRelativePath(relativePath);
21794
21968
  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);
21969
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21970
+ const st = (0, import_node_fs52.statSync)(abs);
21797
21971
  if (!st.isFile()) {
21798
21972
  throw new Error(`Not a file: ${relativePath}`);
21799
21973
  }
@@ -21802,7 +21976,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21802
21976
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
21803
21977
  );
21804
21978
  }
21805
- const buf = (0, import_node_fs50.readFileSync)(abs);
21979
+ const buf = (0, import_node_fs52.readFileSync)(abs);
21806
21980
  return {
21807
21981
  path: relativePath,
21808
21982
  contentBase64: buf.toString("base64"),
@@ -21812,12 +21986,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
21812
21986
  function readWorktreeFile(worktreePath, relativePath, opts) {
21813
21987
  assertSafeRelativePath(relativePath);
21814
21988
  const maxBytes = opts?.maxBytes ?? 2e5;
21815
- const abs = (0, import_node_path49.join)(worktreePath, relativePath);
21816
- const st = (0, import_node_fs50.statSync)(abs);
21989
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
21990
+ const st = (0, import_node_fs52.statSync)(abs);
21817
21991
  if (!st.isFile()) {
21818
21992
  throw new Error(`Not a file: ${relativePath}`);
21819
21993
  }
21820
- const buf = (0, import_node_fs50.readFileSync)(abs);
21994
+ const buf = (0, import_node_fs52.readFileSync)(abs);
21821
21995
  if (isImageRelativePath(relativePath)) {
21822
21996
  const maxImageBytes = Math.max(maxBytes, 15e6);
21823
21997
  const truncated2 = buf.length > maxImageBytes;
@@ -21860,9 +22034,9 @@ function assertSafeRelativePath(relativePath) {
21860
22034
  }
21861
22035
  function writeWorktreeFile(worktreePath, relativePath, content) {
21862
22036
  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");
22037
+ const abs = (0, import_node_path50.join)(worktreePath, relativePath);
22038
+ (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
22039
+ (0, import_node_fs52.writeFileSync)(abs, content, "utf8");
21866
22040
  return { path: relativePath };
21867
22041
  }
21868
22042
  async function getWorktreeDirtyStat(worktreePath) {
@@ -21902,12 +22076,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
21902
22076
  truncated: full.files.length > maxFiles
21903
22077
  };
21904
22078
  }
21905
- var import_node_fs50, import_node_path49, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
22079
+ var import_node_fs52, import_node_path50, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21906
22080
  var init_diff = __esm({
21907
22081
  "src/diff/diff.ts"() {
21908
22082
  "use strict";
21909
- import_node_fs50 = require("fs");
21910
- import_node_path49 = require("path");
22083
+ import_node_fs52 = require("fs");
22084
+ import_node_path50 = require("path");
21911
22085
  init_run();
21912
22086
  init_worktree();
21913
22087
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -22264,7 +22438,7 @@ function parseFrontmatter(content) {
22264
22438
  }
22265
22439
  function readSkill(skillMd, source) {
22266
22440
  try {
22267
- const content = (0, import_node_fs51.readFileSync)(skillMd, "utf8");
22441
+ const content = (0, import_node_fs53.readFileSync)(skillMd, "utf8");
22268
22442
  const { name: fmName, description } = parseFrontmatter(content);
22269
22443
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
22270
22444
  const name = fmName || dirName;
@@ -22283,19 +22457,19 @@ function readSkill(skillMd, source) {
22283
22457
  }
22284
22458
  }
22285
22459
  function scanSkillsDir(dir, source, out) {
22286
- if (!(0, import_node_fs51.existsSync)(dir)) return;
22460
+ if (!(0, import_node_fs53.existsSync)(dir)) return;
22287
22461
  let entries;
22288
22462
  try {
22289
- entries = (0, import_node_fs51.readdirSync)(dir);
22463
+ entries = (0, import_node_fs53.readdirSync)(dir);
22290
22464
  } catch {
22291
22465
  return;
22292
22466
  }
22293
22467
  for (const entry of entries) {
22294
22468
  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;
22469
+ const skillMd = (0, import_node_path51.join)(dir, entry, "SKILL.md");
22470
+ if (!(0, import_node_fs53.existsSync)(skillMd)) continue;
22297
22471
  try {
22298
- if (!(0, import_node_fs51.statSync)(skillMd).isFile()) continue;
22472
+ if (!(0, import_node_fs53.statSync)(skillMd).isFile()) continue;
22299
22473
  } catch {
22300
22474
  continue;
22301
22475
  }
@@ -22304,24 +22478,24 @@ function scanSkillsDir(dir, source, out) {
22304
22478
  }
22305
22479
  }
22306
22480
  function scanClaudePluginSkills(pluginsRoot, out) {
22307
- if (!(0, import_node_fs51.existsSync)(pluginsRoot)) return;
22481
+ if (!(0, import_node_fs53.existsSync)(pluginsRoot)) return;
22308
22482
  const walk = (dir, depth, lookingForSkillsDir) => {
22309
22483
  if (depth > 7) return;
22310
22484
  let entries;
22311
22485
  try {
22312
- entries = (0, import_node_fs51.readdirSync)(dir);
22486
+ entries = (0, import_node_fs53.readdirSync)(dir);
22313
22487
  } catch {
22314
22488
  return;
22315
22489
  }
22316
22490
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
22317
- const skill = readSkill((0, import_node_path50.join)(dir, "SKILL.md"), "cli");
22491
+ const skill = readSkill((0, import_node_path51.join)(dir, "SKILL.md"), "cli");
22318
22492
  if (skill) out.push(skill);
22319
22493
  }
22320
22494
  for (const entry of entries) {
22321
22495
  if (entry === "node_modules" || entry === ".git") continue;
22322
- const full = (0, import_node_path50.join)(dir, entry);
22496
+ const full = (0, import_node_path51.join)(dir, entry);
22323
22497
  try {
22324
- if (!(0, import_node_fs51.statSync)(full).isDirectory()) continue;
22498
+ if (!(0, import_node_fs53.statSync)(full).isDirectory()) continue;
22325
22499
  } catch {
22326
22500
  continue;
22327
22501
  }
@@ -22339,17 +22513,17 @@ function discoverSkills(worktreePath) {
22339
22513
  const home = (0, import_node_os15.homedir)();
22340
22514
  const collected = [];
22341
22515
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
22342
- scanSkillsDir((0, import_node_path50.join)(worktreePath, rel), "workspace", collected);
22516
+ scanSkillsDir((0, import_node_path51.join)(worktreePath, rel), "workspace", collected);
22343
22517
  }
22344
22518
  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")
22519
+ (0, import_node_path51.join)(home, ".claude/skills"),
22520
+ (0, import_node_path51.join)(home, ".cursor/skills"),
22521
+ (0, import_node_path51.join)(home, ".sideboard/skills"),
22522
+ (0, import_node_path51.join)(home, ".brightsy/skills")
22349
22523
  ]) {
22350
22524
  scanSkillsDir(abs, "user", collected);
22351
22525
  }
22352
- scanClaudePluginSkills((0, import_node_path50.join)(home, ".claude/plugins"), collected);
22526
+ scanClaudePluginSkills((0, import_node_path51.join)(home, ".claude/plugins"), collected);
22353
22527
  collected.push(...bundledSkills());
22354
22528
  const rank = {
22355
22529
  workspace: 0,
@@ -22375,7 +22549,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22375
22549
  \u2026(truncated)` : body;
22376
22550
  }
22377
22551
  }
22378
- const raw = (0, import_node_fs51.readFileSync)(skillPath, "utf8");
22552
+ const raw = (0, import_node_fs53.readFileSync)(skillPath, "utf8");
22379
22553
  if (raw.startsWith("---")) {
22380
22554
  const end = raw.indexOf("\n---", 3);
22381
22555
  if (end >= 0) {
@@ -22389,13 +22563,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
22389
22563
 
22390
22564
  \u2026(truncated)` : raw;
22391
22565
  }
22392
- var import_node_fs51, import_node_os15, import_node_path50, BUNDLED_SKILL_PREFIX;
22566
+ var import_node_fs53, import_node_os15, import_node_path51, BUNDLED_SKILL_PREFIX;
22393
22567
  var init_discover = __esm({
22394
22568
  "src/skills/discover.ts"() {
22395
22569
  "use strict";
22396
- import_node_fs51 = require("fs");
22570
+ import_node_fs53 = require("fs");
22397
22571
  import_node_os15 = require("os");
22398
- import_node_path50 = require("path");
22572
+ import_node_path51 = require("path");
22399
22573
  init_long_running();
22400
22574
  BUNDLED_SKILL_PREFIX = "bundled:";
22401
22575
  }
@@ -22548,9 +22722,9 @@ function compiledModuleDir() {
22548
22722
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
22549
22723
  if (cjsDir) return cjsDir;
22550
22724
  try {
22551
- const url = import_meta3.url;
22725
+ const url = import_meta4.url;
22552
22726
  if (typeof url === "string" && url.length > 0) {
22553
- return (0, import_node_path51.dirname)((0, import_node_url3.fileURLToPath)(url));
22727
+ return (0, import_node_path52.dirname)((0, import_node_url4.fileURLToPath)(url));
22554
22728
  }
22555
22729
  } catch {
22556
22730
  }
@@ -22558,8 +22732,8 @@ function compiledModuleDir() {
22558
22732
  }
22559
22733
  function detachedJobScriptIn(dir) {
22560
22734
  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;
22735
+ const script = (0, import_node_path52.join)(dir, "scripts", name);
22736
+ if ((0, import_node_fs54.existsSync)(script)) return script;
22563
22737
  }
22564
22738
  return null;
22565
22739
  }
@@ -22576,7 +22750,7 @@ function resolveDetachedJobScript() {
22576
22750
  for (let i = 0; i < 8; i++) {
22577
22751
  const candidate = detachedJobScriptIn(dir);
22578
22752
  if (candidate) return candidate;
22579
- const parent = (0, import_node_path51.dirname)(dir);
22753
+ const parent = (0, import_node_path52.dirname)(dir);
22580
22754
  if (parent === dir) break;
22581
22755
  dir = parent;
22582
22756
  }
@@ -22587,15 +22761,15 @@ function formatDetachedJobInvoke(scriptPath) {
22587
22761
  if (resolved) return `node ${JSON.stringify(resolved)}`;
22588
22762
  return "node scripts/detached-job.cjs";
22589
22763
  }
22590
- var import_node_fs52, import_node_path51, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
22764
+ var import_node_fs54, import_node_path52, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
22591
22765
  var init_detached_job_path = __esm({
22592
22766
  "src/skills/detached-job-path.ts"() {
22593
22767
  "use strict";
22594
- import_node_fs52 = require("fs");
22595
- import_node_path51 = require("path");
22596
- import_node_url3 = require("url");
22768
+ import_node_fs54 = require("fs");
22769
+ import_node_path52 = require("path");
22770
+ import_node_url4 = require("url");
22597
22771
  init_packaged_runtime();
22598
- import_meta3 = {};
22772
+ import_meta4 = {};
22599
22773
  DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
22600
22774
  }
22601
22775
  });
@@ -22774,9 +22948,9 @@ function formatPrGateDirective() {
22774
22948
  }
22775
22949
  function formatProcessGuideDirective(opts) {
22776
22950
  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"));
22951
+ const hasGraphSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22952
+ const hasReviewSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/review/SKILL.md"));
22953
+ const hasInstallSkill = !!worktree && (0, import_node_fs55.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22780
22954
  return [
22781
22955
  "Process guides (recurring work only):",
22782
22956
  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 +22989,12 @@ function formatArtifactDirective() {
22815
22989
  function formatUiReminder() {
22816
22990
  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
22991
  }
22818
- var import_node_fs53, import_node_path52, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22992
+ var import_node_fs55, import_node_path53, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22819
22993
  var init_instructions = __esm({
22820
22994
  "src/agents/instructions.ts"() {
22821
22995
  "use strict";
22822
- import_node_fs53 = require("fs");
22823
- import_node_path52 = require("path");
22996
+ import_node_fs55 = require("fs");
22997
+ import_node_path53 = require("path");
22824
22998
  init_git_auth_mode();
22825
22999
  init_branch_prefix();
22826
23000
  init_worktree_labels();
@@ -23206,40 +23380,40 @@ __export(plan_file_exports, {
23206
23380
  writePlanFile: () => writePlanFile
23207
23381
  });
23208
23382
  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");
23383
+ const gitignoreAbs = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
23384
+ if ((0, import_node_fs56.existsSync)(gitignoreAbs)) return;
23385
+ (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(gitignoreAbs), { recursive: true });
23386
+ (0, import_node_fs56.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
23213
23387
  }
23214
23388
  function planFileAbs(worktreePath) {
23215
- return (0, import_node_path53.join)(worktreePath, PLAN_FILE_REL);
23389
+ return (0, import_node_path54.join)(worktreePath, PLAN_FILE_REL);
23216
23390
  }
23217
23391
  function readTextIfPresent2(abs) {
23218
- if (!(0, import_node_fs54.existsSync)(abs)) return null;
23392
+ if (!(0, import_node_fs56.existsSync)(abs)) return null;
23219
23393
  try {
23220
- const content = (0, import_node_fs54.readFileSync)(abs, "utf8");
23394
+ const content = (0, import_node_fs56.readFileSync)(abs, "utf8");
23221
23395
  return content.trim() ? content : null;
23222
23396
  } catch {
23223
23397
  return null;
23224
23398
  }
23225
23399
  }
23226
23400
  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));
23401
+ 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
23402
  }
23229
23403
  function writePlanFile(worktreePath, content) {
23230
23404
  ensureAttachmentsGitignore(worktreePath);
23231
23405
  const abs = planFileAbs(worktreePath);
23232
- (0, import_node_fs54.mkdirSync)((0, import_node_path53.dirname)(abs), { recursive: true });
23406
+ (0, import_node_fs56.mkdirSync)((0, import_node_path54.dirname)(abs), { recursive: true });
23233
23407
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
23234
- (0, import_node_fs54.writeFileSync)(abs, body, "utf8");
23408
+ (0, import_node_fs56.writeFileSync)(abs, body, "utf8");
23235
23409
  return PLAN_FILE_REL;
23236
23410
  }
23237
- var import_node_fs54, import_node_path53;
23411
+ var import_node_fs56, import_node_path54;
23238
23412
  var init_plan_file = __esm({
23239
23413
  "src/plan/plan-file.ts"() {
23240
23414
  "use strict";
23241
- import_node_fs54 = require("fs");
23242
- import_node_path53 = require("path");
23415
+ import_node_fs56 = require("fs");
23416
+ import_node_path54 = require("path");
23243
23417
  init_workspace_scratch();
23244
23418
  init_plan_present();
23245
23419
  init_plan_present();
@@ -23301,9 +23475,9 @@ function recoverFinishedCursorRun(opts) {
23301
23475
  return best;
23302
23476
  }
23303
23477
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23304
- if (!(0, import_node_fs55.existsSync)(runsPath)) return null;
23478
+ if (!(0, import_node_fs57.existsSync)(runsPath)) return null;
23305
23479
  try {
23306
- const lines = (0, import_node_fs55.readFileSync)(runsPath, "utf8").split("\n");
23480
+ const lines = (0, import_node_fs57.readFileSync)(runsPath, "utf8").split("\n");
23307
23481
  let best = null;
23308
23482
  for (const line of lines) {
23309
23483
  const trimmed = line.trim();
@@ -23329,11 +23503,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
23329
23503
  return null;
23330
23504
  }
23331
23505
  }
23332
- var import_node_fs55;
23506
+ var import_node_fs57;
23333
23507
  var init_cursor_recover = __esm({
23334
23508
  "src/agents/cursor-recover.ts"() {
23335
23509
  "use strict";
23336
- import_node_fs55 = require("fs");
23510
+ import_node_fs57 = require("fs");
23337
23511
  init_cursor_store();
23338
23512
  }
23339
23513
  });
@@ -23487,14 +23661,14 @@ async function startOrchestration(opts) {
23487
23661
  }
23488
23662
  return updated;
23489
23663
  }
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;
23664
+ 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
23665
  var init_orchestrator = __esm({
23492
23666
  "src/orchestrator/orchestrator.ts"() {
23493
23667
  "use strict";
23494
23668
  import_node_events = require("events");
23495
23669
  init_outbound_watch();
23496
23670
  import_node_crypto12 = require("crypto");
23497
- import_node_fs56 = require("fs");
23671
+ import_node_fs58 = require("fs");
23498
23672
  init_error_detail();
23499
23673
  init_run();
23500
23674
  init_stale_lock();
@@ -23671,7 +23845,7 @@ var init_orchestrator = __esm({
23671
23845
  this.lightReconcileAt.set(repoPath, Date.now());
23672
23846
  for (const thread of listThreads()) {
23673
23847
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
23674
- if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23848
+ if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
23675
23849
  setStatus(thread.id, "broken", "Worktree missing on disk");
23676
23850
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23677
23851
  }
@@ -23700,7 +23874,7 @@ var init_orchestrator = __esm({
23700
23874
  }
23701
23875
  continue;
23702
23876
  }
23703
- if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
23877
+ if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
23704
23878
  setStatus(thread.id, "broken", "Worktree missing on disk");
23705
23879
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
23706
23880
  continue;
@@ -25991,7 +26165,7 @@ var init_orchestrator = __esm({
25991
26165
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
25992
26166
  return restored2;
25993
26167
  }
25994
- if (!(0, import_node_fs56.existsSync)(thread.worktreePath)) {
26168
+ if (!(0, import_node_fs58.existsSync)(thread.worktreePath)) {
25995
26169
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
25996
26170
  throw new Error(
25997
26171
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -26236,6 +26410,7 @@ __export(index_exports, {
26236
26410
  CONTEXT_REVIEW_PATH: () => CONTEXT_REVIEW_PATH,
26237
26411
  CONVENTION_SETUP_RELPATHS: () => CONVENTION_SETUP_RELPATHS,
26238
26412
  COORDINATOR_TOOL_PLAYBOOK: () => COORDINATOR_TOOL_PLAYBOOK,
26413
+ CURSOR_SDK_INSTALL_HINT: () => CURSOR_SDK_INSTALL_HINT,
26239
26414
  DEFAULT_ABLETIME_HOST: () => DEFAULT_ABLETIME_HOST,
26240
26415
  DEFAULT_WORKTREE_SORT: () => DEFAULT_WORKTREE_SORT,
26241
26416
  DETACHED_JOBS_DIR: () => DETACHED_JOBS_DIR,
@@ -26677,6 +26852,7 @@ __export(index_exports, {
26677
26852
  isCowboyThread: () => isCowboyThread,
26678
26853
  isCursorApiKeyConfigured: () => isCursorApiKeyConfigured,
26679
26854
  isCursorAutoModel: () => isCursorAutoModel,
26855
+ isCursorSdkInstalled: () => isCursorSdkInstalled,
26680
26856
  isDefaultishSourceRef: () => isDefaultishSourceRef,
26681
26857
  isDesktopHostAlive: () => isDesktopHostAlive,
26682
26858
  isDirty: () => isDirty,
@@ -26816,6 +26992,8 @@ __export(index_exports, {
26816
26992
  normalizeThread: () => normalizeThread,
26817
26993
  normalizeTurnInput: () => normalizeTurnInput,
26818
26994
  normalizeWorktreePath: () => normalizeWorktreePath,
26995
+ npmGlobalNodeModules: () => npmGlobalNodeModules,
26996
+ npmGlobalPrefix: () => npmGlobalPrefix,
26819
26997
  openInSystemTerminal: () => openInSystemTerminal,
26820
26998
  openPrStackLayers: () => openPrStackLayers,
26821
26999
  openStackLayer: () => openStackLayer,
@@ -26904,6 +27082,7 @@ __export(index_exports, {
26904
27082
  resolveConductorCursorAgentId: () => resolveConductorCursorAgentId,
26905
27083
  resolveCreateFirstPrompt: () => resolveCreateFirstPrompt,
26906
27084
  resolveCursorModelId: () => resolveCursorModelId,
27085
+ resolveCursorSdkRoot: () => resolveCursorSdkRoot,
26907
27086
  resolveDefaultBranch: () => resolveDefaultBranch,
26908
27087
  resolveDetachedJobScript: () => resolveDetachedJobScript,
26909
27088
  resolveDiffBaseRef: () => resolveDiffBaseRef,
@@ -29243,6 +29422,15 @@ async function installOptionalServiceCli(id) {
29243
29422
  message: `${spec.label} has no CLI to install. Use the HTTP API with the stored token.`
29244
29423
  };
29245
29424
  }
29425
+ enrichPathWithNpmGlobalBin();
29426
+ const existing = await whichOnPath(spec.cli);
29427
+ if (existing) {
29428
+ return {
29429
+ ok: true,
29430
+ command: existing,
29431
+ message: `Already on PATH: ${existing}`
29432
+ };
29433
+ }
29246
29434
  return installNpmGlobalPackage({
29247
29435
  npmPackage: spec.npmPackage,
29248
29436
  installCommand: `npm install -g ${spec.npmPackage}`,
@@ -29601,7 +29789,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
29601
29789
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
29602
29790
  var import_zod9 = require("zod");
29603
29791
  var import_node_crypto16 = require("crypto");
29604
- var import_node_path56 = require("path");
29792
+ var import_node_path57 = require("path");
29605
29793
  init_orchestrator();
29606
29794
  init_worktree();
29607
29795
  init_global_workspace();
@@ -31338,27 +31526,27 @@ init_gh_errors();
31338
31526
  init_git_auth_mode();
31339
31527
 
31340
31528
  // src/board/load-home-board.ts
31341
- var import_node_fs58 = require("fs");
31342
- var import_node_path55 = require("path");
31529
+ var import_node_fs60 = require("fs");
31530
+ var import_node_path56 = require("path");
31343
31531
  init_worktree();
31344
31532
  init_paths();
31345
31533
 
31346
31534
  // src/board/board-pins.ts
31347
31535
  var import_node_crypto15 = require("crypto");
31348
- var import_node_fs57 = require("fs");
31349
- var import_node_path54 = require("path");
31536
+ var import_node_fs59 = require("fs");
31537
+ var import_node_path55 = require("path");
31350
31538
  init_paths();
31351
31539
  init_home_board();
31352
31540
  var FILE = "home-board-pins.json";
31353
31541
  var VERSION = 1;
31354
31542
  function pinsFile() {
31355
- return (0, import_node_path54.join)(appDataDir(), FILE);
31543
+ return (0, import_node_path55.join)(appDataDir(), FILE);
31356
31544
  }
31357
31545
  function readDisk() {
31358
31546
  const path2 = pinsFile();
31359
- if (!(0, import_node_fs57.existsSync)(path2)) return [];
31547
+ if (!(0, import_node_fs59.existsSync)(path2)) return [];
31360
31548
  try {
31361
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
31549
+ const raw = JSON.parse((0, import_node_fs59.readFileSync)(path2, "utf8"));
31362
31550
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
31363
31551
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
31364
31552
  } catch {
@@ -31366,8 +31554,8 @@ function readDisk() {
31366
31554
  }
31367
31555
  }
31368
31556
  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");
31557
+ (0, import_node_fs59.mkdirSync)(appDataDir(), { recursive: true });
31558
+ (0, import_node_fs59.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
31371
31559
  }
31372
31560
  function listBoardPins() {
31373
31561
  return readDisk();
@@ -31419,7 +31607,7 @@ function replaceBoardPins(items) {
31419
31607
  }
31420
31608
  function clearBoardPins() {
31421
31609
  try {
31422
- (0, import_node_fs57.unlinkSync)(pinsFile());
31610
+ (0, import_node_fs59.unlinkSync)(pinsFile());
31423
31611
  } catch {
31424
31612
  }
31425
31613
  }
@@ -31436,7 +31624,7 @@ function homeBoardWorkspaceKey(workspaces) {
31436
31624
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
31437
31625
  }
31438
31626
  function cacheFile() {
31439
- return (0, import_node_path55.join)(appDataDir(), "home-board-cache.json");
31627
+ return (0, import_node_path56.join)(appDataDir(), "home-board-cache.json");
31440
31628
  }
31441
31629
  function emptyInputs() {
31442
31630
  return {
@@ -31462,9 +31650,9 @@ function shouldCacheHomeBoardInputs(inputs) {
31462
31650
  }
31463
31651
  function readDiskCache() {
31464
31652
  const path2 = cacheFile();
31465
- if (!(0, import_node_fs58.existsSync)(path2)) return null;
31653
+ if (!(0, import_node_fs60.existsSync)(path2)) return null;
31466
31654
  try {
31467
- const raw = JSON.parse((0, import_node_fs58.readFileSync)(path2, "utf8"));
31655
+ const raw = JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
31468
31656
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
31469
31657
  return null;
31470
31658
  }
@@ -31478,14 +31666,14 @@ function readDiskCache() {
31478
31666
  }
31479
31667
  function writeDiskCache(entry) {
31480
31668
  try {
31481
- (0, import_node_fs58.mkdirSync)(appDataDir(), { recursive: true });
31482
- (0, import_node_fs58.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31669
+ (0, import_node_fs60.mkdirSync)(appDataDir(), { recursive: true });
31670
+ (0, import_node_fs60.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
31483
31671
  } catch {
31484
31672
  }
31485
31673
  }
31486
31674
  function deleteDiskCache() {
31487
31675
  try {
31488
- (0, import_node_fs58.unlinkSync)(cacheFile());
31676
+ (0, import_node_fs60.unlinkSync)(cacheFile());
31489
31677
  } catch {
31490
31678
  }
31491
31679
  }
@@ -31835,7 +32023,7 @@ async function startMcpServer() {
31835
32023
  async () => {
31836
32024
  const threads = orch.getThreads(true);
31837
32025
  const lines = threads.map((t) => {
31838
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path56.basename)(t.repoPath) || t.repoPath;
32026
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path57.basename)(t.repoPath) || t.repoPath;
31839
32027
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
31840
32028
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
31841
32029
  const preview = lastMessagePreview(t.messages, 80);
@@ -34836,9 +35024,9 @@ var import_node_http4 = require("http");
34836
35024
  var import_ws3 = require("ws");
34837
35025
 
34838
35026
  // src/slack/relay-static.ts
34839
- var import_node_fs59 = require("fs");
35027
+ var import_node_fs61 = require("fs");
34840
35028
  var import_promises = require("fs/promises");
34841
- var import_node_path57 = __toESM(require("path"), 1);
35029
+ var import_node_path58 = __toESM(require("path"), 1);
34842
35030
  var TYPES = {
34843
35031
  ".css": "text/css; charset=utf-8",
34844
35032
  ".html": "text/html; charset=utf-8",
@@ -34869,9 +35057,9 @@ function resolveStaticPath(root, requestUrl) {
34869
35057
  return null;
34870
35058
  }
34871
35059
  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)) {
35060
+ const rootResolved = import_node_path58.default.resolve(root);
35061
+ const candidate = import_node_path58.default.resolve(rootResolved, `.${pathname}`);
35062
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path58.default.sep)) {
34875
35063
  return null;
34876
35064
  }
34877
35065
  return candidate;
@@ -34885,7 +35073,7 @@ async function fileSize(file) {
34885
35073
  }
34886
35074
  }
34887
35075
  function sendFile(req, res, file, size) {
34888
- const ext = import_node_path57.default.extname(file).toLowerCase();
35076
+ const ext = import_node_path58.default.extname(file).toLowerCase();
34889
35077
  res.writeHead(200, {
34890
35078
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
34891
35079
  "Content-Length": size,
@@ -34895,7 +35083,7 @@ function sendFile(req, res, file, size) {
34895
35083
  res.end();
34896
35084
  return true;
34897
35085
  }
34898
- (0, import_node_fs59.createReadStream)(file).pipe(res);
35086
+ (0, import_node_fs61.createReadStream)(file).pipe(res);
34899
35087
  return true;
34900
35088
  }
34901
35089
  async function tryServeStatic(req, res, root) {
@@ -34904,7 +35092,7 @@ async function tryServeStatic(req, res, root) {
34904
35092
  if (!candidate) return false;
34905
35093
  const direct = await fileSize(candidate);
34906
35094
  if (direct != null) return sendFile(req, res, candidate, direct);
34907
- const asIndex = import_node_path57.default.join(candidate, "index.html");
35095
+ const asIndex = import_node_path58.default.join(candidate, "index.html");
34908
35096
  const indexSize = await fileSize(asIndex);
34909
35097
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
34910
35098
  return false;
@@ -35192,6 +35380,7 @@ init_outbound_watch();
35192
35380
  CONTEXT_REVIEW_PATH,
35193
35381
  CONVENTION_SETUP_RELPATHS,
35194
35382
  COORDINATOR_TOOL_PLAYBOOK,
35383
+ CURSOR_SDK_INSTALL_HINT,
35195
35384
  DEFAULT_ABLETIME_HOST,
35196
35385
  DEFAULT_WORKTREE_SORT,
35197
35386
  DETACHED_JOBS_DIR,
@@ -35633,6 +35822,7 @@ init_outbound_watch();
35633
35822
  isCowboyThread,
35634
35823
  isCursorApiKeyConfigured,
35635
35824
  isCursorAutoModel,
35825
+ isCursorSdkInstalled,
35636
35826
  isDefaultishSourceRef,
35637
35827
  isDesktopHostAlive,
35638
35828
  isDirty,
@@ -35772,6 +35962,8 @@ init_outbound_watch();
35772
35962
  normalizeThread,
35773
35963
  normalizeTurnInput,
35774
35964
  normalizeWorktreePath,
35965
+ npmGlobalNodeModules,
35966
+ npmGlobalPrefix,
35775
35967
  openInSystemTerminal,
35776
35968
  openPrStackLayers,
35777
35969
  openStackLayer,
@@ -35860,6 +36052,7 @@ init_outbound_watch();
35860
36052
  resolveConductorCursorAgentId,
35861
36053
  resolveCreateFirstPrompt,
35862
36054
  resolveCursorModelId,
36055
+ resolveCursorSdkRoot,
35863
36056
  resolveDefaultBranch,
35864
36057
  resolveDetachedJobScript,
35865
36058
  resolveDiffBaseRef,