@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
@@ -2034,6 +2034,14 @@ function ensureAgentPath(env = process.env) {
2034
2034
  }
2035
2035
  function enrichPathWithNpmGlobalBin(env = process.env) {
2036
2036
  ensureAgentPath(env);
2037
+ const prefix = npmGlobalPrefix(env);
2038
+ if (prefix) {
2039
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
2040
+ prependPathDir(env, binDir);
2041
+ }
2042
+ return env.PATH ?? "";
2043
+ }
2044
+ function npmGlobalPrefix(env = process.env) {
2037
2045
  try {
2038
2046
  const prefix = (0, import_node_child_process3.execFileSync)("npm", ["prefix", "-g"], {
2039
2047
  encoding: "utf8",
@@ -2041,13 +2049,16 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
2041
2049
  timeout: 8e3,
2042
2050
  stdio: ["ignore", "pipe", "ignore"]
2043
2051
  }).trim().split(/\r?\n/).find(Boolean);
2044
- if (prefix) {
2045
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path13.join)(prefix, "bin");
2046
- prependPathDir(env, binDir);
2047
- }
2052
+ return prefix || null;
2048
2053
  } catch {
2054
+ return null;
2049
2055
  }
2050
- return env.PATH ?? "";
2056
+ }
2057
+ function npmGlobalNodeModules(env = process.env) {
2058
+ const prefix = npmGlobalPrefix(env);
2059
+ if (!prefix) return null;
2060
+ const dir = process.platform === "win32" ? (0, import_node_path13.join)(prefix, "node_modules") : (0, import_node_path13.join)(prefix, "lib", "node_modules");
2061
+ return (0, import_node_fs11.existsSync)(dir) ? dir : null;
2051
2062
  }
2052
2063
  var import_node_fs11, import_node_child_process3, import_node_os3, import_node_path13, EXTRA_BIN_DIRS;
2053
2064
  var init_path = __esm({
@@ -12005,6 +12016,124 @@ var init_codex = __esm({
12005
12016
  }
12006
12017
  });
12007
12018
 
12019
+ // src/agents/cursor-sdk-resolve.ts
12020
+ function thisModuleFile() {
12021
+ const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12022
+ if (cjsDir) return (0, import_node_path33.join)(cjsDir, "cursor-sdk-resolve.js");
12023
+ try {
12024
+ return (0, import_node_url2.fileURLToPath)(import_meta2.url);
12025
+ } catch {
12026
+ return (0, import_node_path33.join)(process.cwd(), "package.json");
12027
+ }
12028
+ }
12029
+ function packageRootLooksLikeSdk(dir) {
12030
+ try {
12031
+ const raw = (0, import_node_fs31.readFileSync)((0, import_node_path33.join)(dir, "package.json"), "utf8");
12032
+ const pkg = JSON.parse(raw);
12033
+ return pkg.name === "@cursor/sdk" && (0, import_node_fs31.existsSync)(dir);
12034
+ } catch {
12035
+ return false;
12036
+ }
12037
+ }
12038
+ function resolvedPackageRoot(fromFile) {
12039
+ try {
12040
+ const req = (0, import_node_module2.createRequire)(fromFile);
12041
+ const pkgJson = req.resolve("@cursor/sdk/package.json");
12042
+ const root = (0, import_node_path33.dirname)(pkgJson);
12043
+ return packageRootLooksLikeSdk(root) ? root : null;
12044
+ } catch {
12045
+ return null;
12046
+ }
12047
+ }
12048
+ function resolveCursorSdkRoot(opts) {
12049
+ const env = opts?.env ?? process.env;
12050
+ const override = env.SIDEBOARD_CURSOR_SDK?.trim();
12051
+ if (override) {
12052
+ return packageRootLooksLikeSdk(override) ? override : null;
12053
+ }
12054
+ const globalNm = npmGlobalNodeModules(env);
12055
+ if (globalNm) {
12056
+ const globalRoot = (0, import_node_path33.join)(globalNm, "@cursor/sdk");
12057
+ if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
12058
+ }
12059
+ const cwdPkg = (0, import_node_path33.join)(process.cwd(), "package.json");
12060
+ return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
12061
+ }
12062
+ function isCursorSdkInstalled(opts) {
12063
+ return Boolean(resolveCursorSdkRoot(opts));
12064
+ }
12065
+ function exportTarget(value) {
12066
+ if (typeof value === "string") return value;
12067
+ if (value && typeof value === "object") {
12068
+ const v = value;
12069
+ return exportTarget(v.import) ?? exportTarget(v.default);
12070
+ }
12071
+ return null;
12072
+ }
12073
+ function cursorSdkEsmEntry(root) {
12074
+ try {
12075
+ const pkg = JSON.parse((0, import_node_fs31.readFileSync)((0, import_node_path33.join)(root, "package.json"), "utf8"));
12076
+ const exp = pkg.exports;
12077
+ const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
12078
+ const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
12079
+ if (!rel) return null;
12080
+ const entry = (0, import_node_path33.join)(root, rel);
12081
+ return (0, import_node_fs31.existsSync)(entry) ? entry : null;
12082
+ } catch {
12083
+ return null;
12084
+ }
12085
+ }
12086
+ function unwrapCursorSdkModule(mod) {
12087
+ const m = mod;
12088
+ if (m && !m.Agent && m.default?.Agent) return m.default;
12089
+ return m;
12090
+ }
12091
+ async function importCursorSdk(opts) {
12092
+ const root = resolveCursorSdkRoot(opts);
12093
+ if (!root) return null;
12094
+ try {
12095
+ let entry = cursorSdkEsmEntry(root);
12096
+ if (!entry) {
12097
+ const req = (0, import_node_module2.createRequire)((0, import_node_path33.join)(root, "package.json"));
12098
+ entry = req.resolve("@cursor/sdk");
12099
+ }
12100
+ return unwrapCursorSdkModule(await import((0, import_node_url2.pathToFileURL)(entry).href));
12101
+ } catch {
12102
+ return null;
12103
+ }
12104
+ }
12105
+ function cursorSdkPlatformRipgrepPackage() {
12106
+ return `@cursor/sdk-${process.platform}-${process.arch}`;
12107
+ }
12108
+ function nodeModulesDirForPackageRoot(packageRoot) {
12109
+ const parent = (0, import_node_path33.dirname)(packageRoot);
12110
+ return (0, import_node_path33.basename)(parent).startsWith("@") ? (0, import_node_path33.dirname)(parent) : parent;
12111
+ }
12112
+ function cursorSdkRipgrepCandidate(opts) {
12113
+ const root = resolveCursorSdkRoot(opts);
12114
+ if (!root) return null;
12115
+ const nm = nodeModulesDirForPackageRoot(root);
12116
+ const pkg = cursorSdkPlatformRipgrepPackage();
12117
+ const bin = process.platform === "win32" ? "rg.exe" : "rg";
12118
+ const sibling = (0, import_node_path33.join)(nm, pkg, "bin", bin);
12119
+ if ((0, import_node_fs31.existsSync)(sibling)) return sibling;
12120
+ const nested = (0, import_node_path33.join)(root, "node_modules", pkg, "bin", bin);
12121
+ return (0, import_node_fs31.existsSync)(nested) ? nested : null;
12122
+ }
12123
+ var import_node_fs31, import_node_module2, import_node_path33, import_node_url2, import_meta2, CURSOR_SDK_INSTALL_HINT;
12124
+ var init_cursor_sdk_resolve = __esm({
12125
+ "src/agents/cursor-sdk-resolve.ts"() {
12126
+ "use strict";
12127
+ import_node_fs31 = require("fs");
12128
+ import_node_module2 = require("module");
12129
+ import_node_path33 = require("path");
12130
+ import_node_url2 = require("url");
12131
+ init_path();
12132
+ import_meta2 = {};
12133
+ 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.";
12134
+ }
12135
+ });
12136
+
12008
12137
  // src/agents/cursor-events.ts
12009
12138
  function parseCursorRunnerLine(line) {
12010
12139
  const trimmed = line.trim();
@@ -12039,21 +12168,21 @@ function platformRipgrepPackage() {
12039
12168
  }
12040
12169
  function usableRipgrepPath(candidate) {
12041
12170
  const raw = candidate?.trim();
12042
- if (!raw || !(0, import_node_path33.isAbsolute)(raw)) return null;
12171
+ if (!raw || !(0, import_node_path34.isAbsolute)(raw)) return null;
12043
12172
  const readable = nodeReadableScriptPath(raw);
12044
- if (!(0, import_node_fs31.existsSync)(readable) || isAsarPath(readable)) return null;
12173
+ if (!(0, import_node_fs32.existsSync)(readable) || isAsarPath(readable)) return null;
12045
12174
  return readable;
12046
12175
  }
12047
12176
  function walkForBundledRipgrep(startFile) {
12048
12177
  if (!startFile) return null;
12049
12178
  const pkg = platformRipgrepPackage();
12050
12179
  const name = rgBinaryName();
12051
- let dir = (0, import_node_path33.dirname)((0, import_node_path33.resolve)(startFile));
12052
- const root = (0, import_node_path33.parse)(dir).root;
12180
+ let dir = (0, import_node_path34.dirname)((0, import_node_path34.resolve)(startFile));
12181
+ const root = (0, import_node_path34.parse)(dir).root;
12053
12182
  while (dir !== root) {
12054
- const hit = usableRipgrepPath((0, import_node_path33.join)(dir, "node_modules", pkg, "bin", name));
12183
+ const hit = usableRipgrepPath((0, import_node_path34.join)(dir, "node_modules", pkg, "bin", name));
12055
12184
  if (hit) return hit;
12056
- const next = (0, import_node_path33.dirname)(dir);
12185
+ const next = (0, import_node_path34.dirname)(dir);
12057
12186
  if (next === dir) break;
12058
12187
  dir = next;
12059
12188
  }
@@ -12061,9 +12190,9 @@ function walkForBundledRipgrep(startFile) {
12061
12190
  }
12062
12191
  function requireResolveBundledRipgrep(fromFile) {
12063
12192
  try {
12064
- const req = (0, import_node_module2.createRequire)(fromFile);
12193
+ const req = (0, import_node_module3.createRequire)(fromFile);
12065
12194
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
12066
- return usableRipgrepPath((0, import_node_path33.join)((0, import_node_path33.dirname)(pkgJson), "bin", rgBinaryName()));
12195
+ return usableRipgrepPath((0, import_node_path34.join)((0, import_node_path34.dirname)(pkgJson), "bin", rgBinaryName()));
12067
12196
  } catch {
12068
12197
  return null;
12069
12198
  }
@@ -12079,19 +12208,20 @@ function resolveCursorRipgrepPath(opts) {
12079
12208
  const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
12080
12209
  // eslint-disable-next-line camelcase
12081
12210
  (typeof __filename !== "undefined" ? __filename : "");
12082
- return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
12211
+ return walkForBundledRipgrep(start) ?? usableRipgrepPath(cursorSdkRipgrepCandidate({ env })) ?? requireResolveBundledRipgrep(start);
12083
12212
  }
12084
12213
  function cursorRipgrepEnv(opts) {
12085
12214
  const path = resolveCursorRipgrepPath(opts);
12086
12215
  return path ? { [RIPGREP_ENV]: path } : {};
12087
12216
  }
12088
- var import_node_fs31, import_node_module2, import_node_path33, RIPGREP_ENV;
12217
+ var import_node_fs32, import_node_module3, import_node_path34, RIPGREP_ENV;
12089
12218
  var init_cursor_ripgrep = __esm({
12090
12219
  "src/agents/cursor-ripgrep.ts"() {
12091
12220
  "use strict";
12092
- import_node_fs31 = require("fs");
12093
- import_node_module2 = require("module");
12094
- import_node_path33 = require("path");
12221
+ import_node_fs32 = require("fs");
12222
+ import_node_module3 = require("module");
12223
+ import_node_path34 = require("path");
12224
+ init_cursor_sdk_resolve();
12095
12225
  init_node_launch();
12096
12226
  init_packaged_runtime();
12097
12227
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -12114,8 +12244,10 @@ async function listCursorModels() {
12114
12244
  }
12115
12245
  const apiKey = resolveCursorApiKey();
12116
12246
  if (!apiKey) return FALLBACK_CURSOR_MODELS;
12247
+ const sdk = await importCursorSdk();
12248
+ if (!sdk) return FALLBACK_CURSOR_MODELS;
12117
12249
  try {
12118
- const listed = await import_sdk.Cursor.models.list({ apiKey });
12250
+ const listed = await sdk.Cursor.models.list({ apiKey });
12119
12251
  const models = listed.map((m) => ({
12120
12252
  id: m.id,
12121
12253
  displayName: m.displayName || m.id,
@@ -12132,11 +12264,11 @@ function entryDir() {
12132
12264
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12133
12265
  if (cjsDir) return cjsDir;
12134
12266
  try {
12135
- return (0, import_node_path34.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12267
+ return (0, import_node_path35.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
12136
12268
  } catch {
12137
12269
  try {
12138
- const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
12139
- return (0, import_node_path34.dirname)(req.resolve("@sideboard-ai/core"));
12270
+ const req = (0, import_node_module4.createRequire)(process.cwd() + "/");
12271
+ return (0, import_node_path35.dirname)(req.resolve("@sideboard-ai/core"));
12140
12272
  } catch {
12141
12273
  return process.cwd();
12142
12274
  }
@@ -12147,32 +12279,32 @@ function cursorRunnerPath() {
12147
12279
  if (packaged) return packaged;
12148
12280
  const root = entryDir();
12149
12281
  const candidates = [
12150
- (0, import_node_path34.join)(root, "agents", "cursor-runner.js"),
12151
- (0, import_node_path34.join)(root, "agents", "cursor-runner.cjs"),
12282
+ (0, import_node_path35.join)(root, "agents", "cursor-runner.js"),
12283
+ (0, import_node_path35.join)(root, "agents", "cursor-runner.cjs"),
12152
12284
  // If somehow resolved from package root instead of dist/
12153
- (0, import_node_path34.join)(root, "dist", "agents", "cursor-runner.js"),
12154
- (0, import_node_path34.join)(root, "dist", "agents", "cursor-runner.cjs"),
12285
+ (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.js"),
12286
+ (0, import_node_path35.join)(root, "dist", "agents", "cursor-runner.cjs"),
12155
12287
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
12156
- (0, import_node_path34.join)(root, "cursor-runner.ts"),
12157
- (0, import_node_path34.join)(root, "src", "agents", "cursor-runner.ts")
12288
+ (0, import_node_path35.join)(root, "cursor-runner.ts"),
12289
+ (0, import_node_path35.join)(root, "src", "agents", "cursor-runner.ts")
12158
12290
  ];
12159
12291
  for (const candidate of candidates) {
12160
- if ((0, import_node_fs32.existsSync)(candidate)) return candidate;
12292
+ if ((0, import_node_fs33.existsSync)(candidate)) return candidate;
12161
12293
  }
12162
12294
  return candidates[0];
12163
12295
  }
12164
- var import_node_fs32, import_node_module3, import_node_path34, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12296
+ var import_node_fs33, import_node_module4, import_node_path35, import_node_url3, import_meta3, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
12165
12297
  var init_cursor = __esm({
12166
12298
  "src/agents/cursor.ts"() {
12167
12299
  "use strict";
12168
- import_node_fs32 = require("fs");
12169
- import_node_module3 = require("module");
12170
- import_node_path34 = require("path");
12171
- import_node_url2 = require("url");
12172
- import_sdk = require("@cursor/sdk");
12300
+ import_node_fs33 = require("fs");
12301
+ import_node_module4 = require("module");
12302
+ import_node_path35 = require("path");
12303
+ import_node_url3 = require("url");
12173
12304
  init_run();
12174
12305
  init_app_settings();
12175
12306
  init_global_workspace();
12307
+ init_cursor_sdk_resolve();
12176
12308
  init_cursor_events();
12177
12309
  init_injected_mcp();
12178
12310
  init_cursor_ripgrep();
@@ -12180,7 +12312,7 @@ var init_cursor = __esm({
12180
12312
  init_packaged_runtime();
12181
12313
  init_turn_input();
12182
12314
  init_cursor_events();
12183
- import_meta2 = {};
12315
+ import_meta3 = {};
12184
12316
  FALLBACK_CURSOR_MODELS = [
12185
12317
  { id: "default", displayName: "Auto" },
12186
12318
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -12191,6 +12323,16 @@ var init_cursor = __esm({
12191
12323
  cursorAdapter = {
12192
12324
  kind: "cursor",
12193
12325
  async detect() {
12326
+ if (!isCursorSdkInstalled()) {
12327
+ return {
12328
+ agent: "cursor",
12329
+ installed: false,
12330
+ authenticated: false,
12331
+ linearMcp: false,
12332
+ warnings: [],
12333
+ reason: CURSOR_SDK_INSTALL_HINT
12334
+ };
12335
+ }
12194
12336
  const apiKey = resolveCursorApiKey();
12195
12337
  if (!apiKey) {
12196
12338
  return {
@@ -12319,7 +12461,7 @@ async function listOpencodeModels() {
12319
12461
  if (opencode === "opencode") {
12320
12462
  const which = await run("which", ["opencode"], { reject: false });
12321
12463
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
12322
- } else if (!(0, import_node_fs33.existsSync)(opencode)) {
12464
+ } else if (!(0, import_node_fs34.existsSync)(opencode)) {
12323
12465
  return FALLBACK_OPENCODE_MODELS;
12324
12466
  }
12325
12467
  const listed = await run(opencode, ["models"], { reject: false });
@@ -12349,11 +12491,11 @@ function usageFromOpencode(tokens) {
12349
12491
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
12350
12492
  };
12351
12493
  }
12352
- var import_node_fs33, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12494
+ var import_node_fs34, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
12353
12495
  var init_opencode = __esm({
12354
12496
  "src/agents/opencode.ts"() {
12355
12497
  "use strict";
12356
- import_node_fs33 = require("fs");
12498
+ import_node_fs34 = require("fs");
12357
12499
  init_run();
12358
12500
  init_app_settings();
12359
12501
  init_global_workspace();
@@ -12381,7 +12523,7 @@ var init_opencode = __esm({
12381
12523
  async detect() {
12382
12524
  const opencode = resolveAgentExecutable("opencode");
12383
12525
  if (opencode !== "opencode") {
12384
- if (!(0, import_node_fs33.existsSync)(opencode)) {
12526
+ if (!(0, import_node_fs34.existsSync)(opencode)) {
12385
12527
  return {
12386
12528
  agent: "opencode",
12387
12529
  installed: false,
@@ -12868,13 +13010,13 @@ var init_claude_usage = __esm({
12868
13010
  });
12869
13011
 
12870
13012
  // src/agents/claude-usage-client.ts
12871
- var import_node_fs34, import_node_os13, import_node_path35, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
13013
+ var import_node_fs35, import_node_os13, import_node_path36, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
12872
13014
  var init_claude_usage_client = __esm({
12873
13015
  "src/agents/claude-usage-client.ts"() {
12874
13016
  "use strict";
12875
- import_node_fs34 = require("fs");
13017
+ import_node_fs35 = require("fs");
12876
13018
  import_node_os13 = require("os");
12877
- import_node_path35 = require("path");
13019
+ import_node_path36 = require("path");
12878
13020
  init_run();
12879
13021
  init_fetch();
12880
13022
  init_app_settings();
@@ -12885,9 +13027,11 @@ var init_claude_usage_client = __esm({
12885
13027
  });
12886
13028
 
12887
13029
  // src/agents/install.ts
13030
+ var import_node_fs36;
12888
13031
  var init_install = __esm({
12889
13032
  "src/agents/install.ts"() {
12890
13033
  "use strict";
13034
+ import_node_fs36 = require("fs");
12891
13035
  init_run();
12892
13036
  init_app_settings();
12893
13037
  init_path();
@@ -12922,6 +13066,7 @@ var init_agents = __esm({
12922
13066
  init_claude_usage_client();
12923
13067
  init_orchestrator_capable();
12924
13068
  init_path();
13069
+ init_cursor_sdk_resolve();
12925
13070
  init_install();
12926
13071
  adapters = {
12927
13072
  claude: claudeAdapter,
@@ -12940,7 +13085,7 @@ function isAgentHostEnvKey(key) {
12940
13085
  }
12941
13086
  function stripHostToolingPath(pathValue) {
12942
13087
  if (!pathValue?.trim()) return "";
12943
- return pathValue.split(import_node_path36.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path36.delimiter);
13088
+ return pathValue.split(import_node_path37.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path37.delimiter);
12944
13089
  }
12945
13090
  function sanitizeAgentHostEnv(env, cwd) {
12946
13091
  for (const key of Object.keys(env)) {
@@ -12954,11 +13099,11 @@ function sanitizeAgentHostEnv(env, cwd) {
12954
13099
  }
12955
13100
  return env;
12956
13101
  }
12957
- var import_node_path36, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
13102
+ var import_node_path37, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
12958
13103
  var init_agent_host_env = __esm({
12959
13104
  "src/hook/agent-host-env.ts"() {
12960
13105
  "use strict";
12961
- import_node_path36 = require("path");
13106
+ import_node_path37 = require("path");
12962
13107
  DROP_EXACT = /* @__PURE__ */ new Set([
12963
13108
  "NODE_PATH",
12964
13109
  "NODE_ENV_ELECTRON_VITE",
@@ -12997,15 +13142,15 @@ var init_agent_host_env = __esm({
12997
13142
 
12998
13143
  // src/hook/worktree-pkg-cache.ts
12999
13144
  function worktreePkgCacheRoot(worktreePath) {
13000
- return (0, import_node_path37.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13145
+ return (0, import_node_path38.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13001
13146
  }
13002
13147
  function worktreePkgCacheEnv(worktreePath) {
13003
13148
  const root = worktreePkgCacheRoot(worktreePath);
13004
- const store = (0, import_node_path37.join)(root, "pnpm-store");
13005
- const pnpmCache = (0, import_node_path37.join)(root, "pnpm");
13006
- const npmCache = (0, import_node_path37.join)(root, "npm");
13007
- const nodeGyp = (0, import_node_path37.join)(root, "node-gyp");
13008
- const electron = (0, import_node_path37.join)(root, "electron");
13149
+ const store = (0, import_node_path38.join)(root, "pnpm-store");
13150
+ const pnpmCache = (0, import_node_path38.join)(root, "pnpm");
13151
+ const npmCache = (0, import_node_path38.join)(root, "npm");
13152
+ const nodeGyp = (0, import_node_path38.join)(root, "node-gyp");
13153
+ const electron = (0, import_node_path38.join)(root, "electron");
13009
13154
  return {
13010
13155
  npm_config_store_dir: store,
13011
13156
  PNPM_STORE_DIR: store,
@@ -13027,8 +13172,8 @@ function fillGroup(env, keys, values) {
13027
13172
  }
13028
13173
  }
13029
13174
  function ensureWorktreePkgCacheDirs(worktreePath) {
13030
- if (!(0, import_node_fs35.existsSync)(worktreePath)) return;
13031
- (0, import_node_fs35.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13175
+ if (!(0, import_node_fs37.existsSync)(worktreePath)) return;
13176
+ (0, import_node_fs37.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13032
13177
  }
13033
13178
  function applyWorktreePkgCacheEnv(env, worktreePath) {
13034
13179
  const cwd = worktreePath.trim();
@@ -13041,12 +13186,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
13041
13186
  fillGroup(env, ["electron_config_cache"], next);
13042
13187
  ensureWorktreePkgCacheDirs(cwd);
13043
13188
  }
13044
- var import_node_fs35, import_node_path37, WORKTREE_PKG_CACHE_REL;
13189
+ var import_node_fs37, import_node_path38, WORKTREE_PKG_CACHE_REL;
13045
13190
  var init_worktree_pkg_cache = __esm({
13046
13191
  "src/hook/worktree-pkg-cache.ts"() {
13047
13192
  "use strict";
13048
- import_node_fs35 = require("fs");
13049
- import_node_path37 = require("path");
13193
+ import_node_fs37 = require("fs");
13194
+ import_node_path38 = require("path");
13050
13195
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
13051
13196
  }
13052
13197
  });
@@ -14244,21 +14389,21 @@ function shouldRefreshReviewRequestTemplate(content) {
14244
14389
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
14245
14390
  }
14246
14391
  function readTextIfPresent(abs) {
14247
- if (!(0, import_node_fs36.existsSync)(abs)) return null;
14392
+ if (!(0, import_node_fs38.existsSync)(abs)) return null;
14248
14393
  try {
14249
- const content = (0, import_node_fs36.readFileSync)(abs, "utf8");
14394
+ const content = (0, import_node_fs38.readFileSync)(abs, "utf8");
14250
14395
  return content.trim() ? content : null;
14251
14396
  } catch {
14252
14397
  return null;
14253
14398
  }
14254
14399
  }
14255
14400
  function readLocalGuidelines(worktreePath) {
14256
- const localAbs = (0, import_node_path38.join)(worktreePath, REVIEW_REQUEST_PATH);
14401
+ const localAbs = (0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH);
14257
14402
  const localContent = readTextIfPresent(localAbs);
14258
14403
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14259
14404
  return { path: REVIEW_REQUEST_PATH, content: localContent };
14260
14405
  }
14261
- const legacyAbs = (0, import_node_path38.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14406
+ const legacyAbs = (0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14262
14407
  const legacyContent = readTextIfPresent(legacyAbs);
14263
14408
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
14264
14409
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -14282,27 +14427,27 @@ function contextGuidelines(content, source) {
14282
14427
  };
14283
14428
  }
14284
14429
  function writeContextGuidelines(worktreePath, content) {
14285
- const abs = (0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH);
14286
- (0, import_node_fs36.mkdirSync)((0, import_node_path38.dirname)(abs), { recursive: true });
14430
+ const abs = (0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH);
14431
+ (0, import_node_fs38.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
14287
14432
  const body = content.endsWith("\n") ? content : `${content}
14288
14433
  `;
14289
- (0, import_node_fs36.writeFileSync)(abs, body, "utf8");
14434
+ (0, import_node_fs38.writeFileSync)(abs, body, "utf8");
14290
14435
  return body;
14291
14436
  }
14292
14437
  function readSideboardReview(worktreePath, repoPath) {
14293
- const fromWorktree = readTextIfPresent((0, import_node_path38.join)(worktreePath, REPO_REVIEW_PATH));
14438
+ const fromWorktree = readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH));
14294
14439
  if (fromWorktree) return fromWorktree;
14295
14440
  const repo = repoPath?.replace(/\/+$/, "");
14296
14441
  const wt = worktreePath.replace(/\/+$/, "");
14297
14442
  if (!repo || repo === wt) return null;
14298
- return readTextIfPresent((0, import_node_path38.join)(repo, REPO_REVIEW_PATH));
14443
+ return readTextIfPresent((0, import_node_path39.join)(repo, REPO_REVIEW_PATH));
14299
14444
  }
14300
14445
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
14301
- const skillContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, REVIEW_SKILL_PATH));
14446
+ const skillContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH));
14302
14447
  if (skillContent) {
14303
14448
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
14304
14449
  }
14305
- const contextContent = readTextIfPresent((0, import_node_path38.join)(worktreePath, CONTEXT_REVIEW_PATH));
14450
+ const contextContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH));
14306
14451
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
14307
14452
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
14308
14453
  }
@@ -14357,13 +14502,13 @@ async function requestReview(threadRef, send) {
14357
14502
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
14358
14503
  return { tab: started, from };
14359
14504
  }
14360
- var import_node_crypto7, import_node_fs36, import_node_path38, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
14505
+ var import_node_crypto7, import_node_fs38, import_node_path39, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
14361
14506
  var init_request_review = __esm({
14362
14507
  "src/review/request-review.ts"() {
14363
14508
  "use strict";
14364
14509
  import_node_crypto7 = require("crypto");
14365
- import_node_fs36 = require("fs");
14366
- import_node_path38 = require("path");
14510
+ import_node_fs38 = require("fs");
14511
+ import_node_path39 = require("path");
14367
14512
  init_global_workspace();
14368
14513
  init_chat_tabs();
14369
14514
  init_thread_store();
@@ -14389,9 +14534,9 @@ function matchSimpleGlob(pattern, name) {
14389
14534
  return new RegExp(`^${escaped}$`).test(name);
14390
14535
  }
14391
14536
  function readWorktreeInclude(repoPath) {
14392
- const path = (0, import_node_path39.join)(repoPath, ".worktreeinclude");
14393
- if (!(0, import_node_fs37.existsSync)(path)) return [];
14394
- return (0, import_node_fs37.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14537
+ const path = (0, import_node_path40.join)(repoPath, ".worktreeinclude");
14538
+ if (!(0, import_node_fs39.existsSync)(path)) return [];
14539
+ return (0, import_node_fs39.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14395
14540
  }
14396
14541
  function resolveFilesToCopy(repoPath) {
14397
14542
  const fromInclude = readWorktreeInclude(repoPath);
@@ -14401,10 +14546,10 @@ function resolveFilesToCopy(repoPath) {
14401
14546
  if (settings?.fileIncludeGlobs?.length) {
14402
14547
  const matched = [];
14403
14548
  try {
14404
- for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
14549
+ for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
14405
14550
  if (!entry.isFile()) continue;
14406
14551
  for (const glob of settings.fileIncludeGlobs) {
14407
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path39.basename)(glob), entry.name)) {
14552
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path40.basename)(glob), entry.name)) {
14408
14553
  matched.push(entry.name);
14409
14554
  break;
14410
14555
  }
@@ -14416,7 +14561,7 @@ function resolveFilesToCopy(repoPath) {
14416
14561
  }
14417
14562
  const defaults = [];
14418
14563
  try {
14419
- for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
14564
+ for (const entry of (0, import_node_fs39.readdirSync)(repoPath, { withFileTypes: true })) {
14420
14565
  if (entry.isFile() && entry.name.startsWith(".env")) {
14421
14566
  defaults.push(entry.name);
14422
14567
  }
@@ -14430,11 +14575,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
14430
14575
  const patterns = resolveFilesToCopy(repoPath);
14431
14576
  const copied = [];
14432
14577
  for (const rel of patterns) {
14433
- const src = (0, import_node_path39.join)(repoPath, rel);
14434
- if (!(0, import_node_fs37.existsSync)(src)) continue;
14435
- const dest = (0, import_node_path39.join)(worktreePath, rel);
14436
- (0, import_node_fs37.mkdirSync)((0, import_node_path39.dirname)(dest), { recursive: true });
14437
- (0, import_node_fs37.copyFileSync)(src, dest);
14578
+ const src = (0, import_node_path40.join)(repoPath, rel);
14579
+ if (!(0, import_node_fs39.existsSync)(src)) continue;
14580
+ const dest = (0, import_node_path40.join)(worktreePath, rel);
14581
+ (0, import_node_fs39.mkdirSync)((0, import_node_path40.dirname)(dest), { recursive: true });
14582
+ (0, import_node_fs39.copyFileSync)(src, dest);
14438
14583
  copied.push(rel);
14439
14584
  }
14440
14585
  return copied;
@@ -14469,7 +14614,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
14469
14614
  const env = stripNestedElectronEnv({
14470
14615
  ...baseEnv ?? process.env
14471
14616
  });
14472
- const name = opts.workspaceName ?? (0, import_node_path39.basename)(opts.worktreePath);
14617
+ const name = opts.workspaceName ?? (0, import_node_path40.basename)(opts.worktreePath);
14473
14618
  const ports = opts.ports ?? [];
14474
14619
  const primary = ports[0];
14475
14620
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -14793,14 +14938,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
14793
14938
  throw err;
14794
14939
  }
14795
14940
  }
14796
- var import_node_fs37, import_node_child_process4, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
14941
+ var import_node_fs39, import_node_child_process4, import_node_net, import_node_path40, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
14797
14942
  var init_conductor = __esm({
14798
14943
  "src/hook/conductor.ts"() {
14799
14944
  "use strict";
14800
- import_node_fs37 = require("fs");
14945
+ import_node_fs39 = require("fs");
14801
14946
  import_node_child_process4 = require("child_process");
14802
14947
  import_node_net = require("net");
14803
- import_node_path39 = require("path");
14948
+ import_node_path40 = require("path");
14804
14949
  import_execa4 = require("execa");
14805
14950
  import_node_readline3 = require("readline");
14806
14951
  init_settings();
@@ -14850,7 +14995,7 @@ function materialize(mem) {
14850
14995
  };
14851
14996
  }
14852
14997
  function setupLogPath(threadId) {
14853
- return (0, import_node_path40.join)(threadsDir(), `${threadId}.setup.log.json`);
14998
+ return (0, import_node_path41.join)(threadsDir(), `${threadId}.setup.log.json`);
14854
14999
  }
14855
15000
  function setupLogKeyForWorktree(worktreePath) {
14856
15001
  const norm = normalizeWorktreePath(worktreePath);
@@ -14868,7 +15013,7 @@ function persistNow(threadId) {
14868
15013
  const mem = memory.get(threadId);
14869
15014
  if (!mem) return;
14870
15015
  try {
14871
- (0, import_node_fs38.writeFileSync)(
15016
+ (0, import_node_fs40.writeFileSync)(
14872
15017
  setupLogPath(threadId),
14873
15018
  `${JSON.stringify(materialize(mem))}
14874
15019
  `,
@@ -14889,9 +15034,9 @@ function schedulePersist(threadId) {
14889
15034
  }
14890
15035
  function loadFromDisk(threadId) {
14891
15036
  const path = setupLogPath(threadId);
14892
- if (!(0, import_node_fs38.existsSync)(path)) return null;
15037
+ if (!(0, import_node_fs40.existsSync)(path)) return null;
14893
15038
  try {
14894
- const raw = JSON.parse((0, import_node_fs38.readFileSync)(path, "utf8"));
15039
+ const raw = JSON.parse((0, import_node_fs40.readFileSync)(path, "utf8"));
14895
15040
  return {
14896
15041
  output: typeof raw.output === "string" ? raw.output : "",
14897
15042
  running: Boolean(raw.running),
@@ -14947,13 +15092,13 @@ function finishSetupLog(threadId, exitCode, source) {
14947
15092
  persistNow(threadId);
14948
15093
  return materialize(mem);
14949
15094
  }
14950
- var import_node_crypto8, import_node_fs38, import_node_path40, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
15095
+ var import_node_crypto8, import_node_fs40, import_node_path41, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
14951
15096
  var init_setup_log = __esm({
14952
15097
  "src/store/setup-log.ts"() {
14953
15098
  "use strict";
14954
15099
  import_node_crypto8 = require("crypto");
14955
- import_node_fs38 = require("fs");
14956
- import_node_path40 = require("path");
15100
+ import_node_fs40 = require("fs");
15101
+ import_node_path41 = require("path");
14957
15102
  init_worktree_labels();
14958
15103
  init_paths();
14959
15104
  EMPTY = {
@@ -14980,9 +15125,9 @@ async function findOrphanWorktrees(repoPaths) {
14980
15125
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
14981
15126
  );
14982
15127
  const homeRoot = sideboardWorkspacesDir();
14983
- if ((0, import_node_fs39.existsSync)(homeRoot)) {
15128
+ if ((0, import_node_fs41.existsSync)(homeRoot)) {
14984
15129
  try {
14985
- for (const entry of (0, import_node_fs39.readdirSync)(homeRoot, { withFileTypes: true })) {
15130
+ for (const entry of (0, import_node_fs41.readdirSync)(homeRoot, { withFileTypes: true })) {
14986
15131
  if (!entry.isDirectory()) continue;
14987
15132
  void entry;
14988
15133
  }
@@ -14992,7 +15137,7 @@ async function findOrphanWorktrees(repoPaths) {
14992
15137
  const orphans = [];
14993
15138
  const seen = /* @__PURE__ */ new Set();
14994
15139
  for (const repoPath of repos) {
14995
- if (!repoPath || !(0, import_node_fs39.existsSync)(repoPath)) continue;
15140
+ if (!repoPath || !(0, import_node_fs41.existsSync)(repoPath)) continue;
14996
15141
  try {
14997
15142
  const wts = await listWorktrees(repoPath);
14998
15143
  for (const wt of wts) {
@@ -15003,7 +15148,7 @@ async function findOrphanWorktrees(repoPaths) {
15003
15148
  seen.add(path);
15004
15149
  let mtimeMs = 0;
15005
15150
  try {
15006
- mtimeMs = (0, import_node_fs39.statSync)(path).mtimeMs;
15151
+ mtimeMs = (0, import_node_fs41.statSync)(path).mtimeMs;
15007
15152
  } catch {
15008
15153
  mtimeMs = 0;
15009
15154
  }
@@ -15013,16 +15158,16 @@ async function findOrphanWorktrees(repoPaths) {
15013
15158
  }
15014
15159
  try {
15015
15160
  const root = worktreesRoot(repoPath);
15016
- if ((0, import_node_fs39.existsSync)(root)) {
15017
- for (const entry of (0, import_node_fs39.readdirSync)(root, { withFileTypes: true })) {
15161
+ if ((0, import_node_fs41.existsSync)(root)) {
15162
+ for (const entry of (0, import_node_fs41.readdirSync)(root, { withFileTypes: true })) {
15018
15163
  if (!entry.isDirectory()) continue;
15019
- const path = (0, import_node_path41.join)(root, entry.name).replace(/\/$/, "");
15164
+ const path = (0, import_node_path42.join)(root, entry.name).replace(/\/$/, "");
15020
15165
  if (known.has(path) || seen.has(path)) continue;
15021
- if (!(0, import_node_fs39.existsSync)((0, import_node_path41.join)(path, ".git"))) continue;
15166
+ if (!(0, import_node_fs41.existsSync)((0, import_node_path42.join)(path, ".git"))) continue;
15022
15167
  seen.add(path);
15023
15168
  let mtimeMs = 0;
15024
15169
  try {
15025
- mtimeMs = (0, import_node_fs39.statSync)(path).mtimeMs;
15170
+ mtimeMs = (0, import_node_fs41.statSync)(path).mtimeMs;
15026
15171
  } catch {
15027
15172
  mtimeMs = Date.now();
15028
15173
  }
@@ -15074,12 +15219,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
15074
15219
  const elapsed = Date.now() - Date.parse(last);
15075
15220
  return elapsed >= intervalHours * 36e5;
15076
15221
  }
15077
- var import_node_fs39, import_node_path41;
15222
+ var import_node_fs41, import_node_path42;
15078
15223
  var init_orphan_cleanup = __esm({
15079
15224
  "src/git/orphan-cleanup.ts"() {
15080
15225
  "use strict";
15081
- import_node_fs39 = require("fs");
15082
- import_node_path41 = require("path");
15226
+ import_node_fs41 = require("fs");
15227
+ import_node_path42 = require("path");
15083
15228
  init_worktree();
15084
15229
  init_thread_store();
15085
15230
  init_paths();
@@ -15254,12 +15399,12 @@ async function cloneRepoIntoSideboard(opts) {
15254
15399
  if (!url) throw new Error("Clone URL is required");
15255
15400
  let name = opts.name?.trim();
15256
15401
  if (!name) {
15257
- const leaf = (0, import_node_path42.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15402
+ const leaf = (0, import_node_path43.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15258
15403
  name = leaf || "repo";
15259
15404
  }
15260
15405
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
15261
- const dest = (0, import_node_path42.join)(sideboardReposDir(), name);
15262
- if ((0, import_node_fs40.existsSync)(dest)) {
15406
+ const dest = (0, import_node_path43.join)(sideboardReposDir(), name);
15407
+ if ((0, import_node_fs42.existsSync)(dest)) {
15263
15408
  const repoPath2 = await resolveRepoRoot(dest);
15264
15409
  const workspace2 = await ensureWorkspace(repoPath2);
15265
15410
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -15274,12 +15419,12 @@ async function cloneRepoIntoSideboard(opts) {
15274
15419
  const workspace = await ensureWorkspace(repoPath);
15275
15420
  return { repoPath, workspace };
15276
15421
  }
15277
- var import_node_fs40, import_node_path42, import_execa6;
15422
+ var import_node_fs42, import_node_path43, import_execa6;
15278
15423
  var init_clone_repo = __esm({
15279
15424
  "src/git/clone-repo.ts"() {
15280
15425
  "use strict";
15281
- import_node_fs40 = require("fs");
15282
- import_node_path42 = require("path");
15426
+ import_node_fs42 = require("fs");
15427
+ import_node_path43 = require("path");
15283
15428
  import_execa6 = require("execa");
15284
15429
  init_paths();
15285
15430
  init_workspaces2();
@@ -15299,11 +15444,11 @@ var init_thread = __esm({
15299
15444
 
15300
15445
  // src/store/desktop-host.ts
15301
15446
  function desktopHostPidPath() {
15302
- return (0, import_node_path43.join)(appDataDir(), "desktop-host.pid");
15447
+ return (0, import_node_path44.join)(appDataDir(), "desktop-host.pid");
15303
15448
  }
15304
15449
  function readDesktopHostPid() {
15305
15450
  try {
15306
- const pid = Number.parseInt((0, import_node_fs41.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
15451
+ const pid = Number.parseInt((0, import_node_fs43.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
15307
15452
  if (!Number.isFinite(pid) || pid <= 0) return null;
15308
15453
  return pid;
15309
15454
  } catch {
@@ -15329,12 +15474,12 @@ function thisProcessShouldDrainAgentQueues() {
15329
15474
  if (isThisProcessDesktopHost()) return true;
15330
15475
  return !isDesktopHostAlive();
15331
15476
  }
15332
- var import_node_fs41, import_node_path43;
15477
+ var import_node_fs43, import_node_path44;
15333
15478
  var init_desktop_host = __esm({
15334
15479
  "src/store/desktop-host.ts"() {
15335
15480
  "use strict";
15336
- import_node_fs41 = require("fs");
15337
- import_node_path43 = require("path");
15481
+ import_node_fs43 = require("fs");
15482
+ import_node_path44 = require("path");
15338
15483
  init_paths();
15339
15484
  }
15340
15485
  });
@@ -15452,24 +15597,24 @@ function jobTreeAlive(pid) {
15452
15597
  return jobAlive(pid) || processGroupAlive(pid);
15453
15598
  }
15454
15599
  function readIntFile(file) {
15455
- if (!(0, import_node_fs42.existsSync)(file)) return null;
15456
- const n = Number.parseInt((0, import_node_fs42.readFileSync)(file, "utf8").trim(), 10);
15600
+ if (!(0, import_node_fs44.existsSync)(file)) return null;
15601
+ const n = Number.parseInt((0, import_node_fs44.readFileSync)(file, "utf8").trim(), 10);
15457
15602
  return Number.isInteger(n) ? n : null;
15458
15603
  }
15459
15604
  function jobDir(root, id, legacy = false) {
15460
- return (0, import_node_path44.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15605
+ return (0, import_node_path45.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15461
15606
  }
15462
15607
  function resolveJobDir(root, id) {
15463
15608
  const modern = jobDir(root, id, false);
15464
- if ((0, import_node_fs42.existsSync)(modern)) return modern;
15609
+ if ((0, import_node_fs44.existsSync)(modern)) return modern;
15465
15610
  const legacy = jobDir(root, id, true);
15466
- if ((0, import_node_fs42.existsSync)(legacy)) return legacy;
15611
+ if ((0, import_node_fs44.existsSync)(legacy)) return legacy;
15467
15612
  return modern;
15468
15613
  }
15469
15614
  function listJobIdsIn(root, rel) {
15470
- const dir = (0, import_node_path44.join)(root, rel);
15471
- if (!(0, import_node_fs42.existsSync)(dir)) return [];
15472
- return (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15615
+ const dir = (0, import_node_path45.join)(root, rel);
15616
+ if (!(0, import_node_fs44.existsSync)(dir)) return [];
15617
+ return (0, import_node_fs44.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15473
15618
  }
15474
15619
  function listRunningDetachedJobs(worktreePath) {
15475
15620
  const root = worktreePath.trim();
@@ -15481,7 +15626,7 @@ function listRunningDetachedJobs(worktreePath) {
15481
15626
  const running = [];
15482
15627
  for (const id of ids) {
15483
15628
  const dir = resolveJobDir(root, id);
15484
- const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
15629
+ const pid = readIntFile((0, import_node_path45.join)(dir, "pid"));
15485
15630
  if (jobTreeAlive(pid)) running.push(id);
15486
15631
  }
15487
15632
  return running.sort();
@@ -15564,8 +15709,8 @@ function planJobContinue(opts) {
15564
15709
  return { action: "none" };
15565
15710
  }
15566
15711
  function tailProgress(logFile, maxLines = 12) {
15567
- if (!(0, import_node_fs42.existsSync)(logFile)) return "(no log yet)";
15568
- const lines = (0, import_node_fs42.readFileSync)(logFile, "utf8").split("\n");
15712
+ if (!(0, import_node_fs44.existsSync)(logFile)) return "(no log yet)";
15713
+ const lines = (0, import_node_fs44.readFileSync)(logFile, "utf8").split("\n");
15569
15714
  return lines.slice(-maxLines).join("\n");
15570
15715
  }
15571
15716
  function lastProgressLine(progress) {
@@ -15573,8 +15718,8 @@ function lastProgressLine(progress) {
15573
15718
  return last ? last.slice(0, 72) : void 0;
15574
15719
  }
15575
15720
  function readLogLines(file) {
15576
- if (!(0, import_node_fs42.existsSync)(file)) return [];
15577
- const lines = (0, import_node_fs42.readFileSync)(file, "utf8").split("\n");
15721
+ if (!(0, import_node_fs44.existsSync)(file)) return [];
15722
+ const lines = (0, import_node_fs44.readFileSync)(file, "utf8").split("\n");
15578
15723
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
15579
15724
  return lines;
15580
15725
  }
@@ -15585,15 +15730,15 @@ function takeDelta(logFile, cursorFile) {
15585
15730
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
15586
15731
  }
15587
15732
  function snapshotJob(dir) {
15588
- const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
15733
+ const pid = readIntFile((0, import_node_path45.join)(dir, "pid"));
15589
15734
  const running = jobTreeAlive(pid);
15590
15735
  return {
15591
15736
  pid,
15592
15737
  running,
15593
- exitCode: readIntFile((0, import_node_path44.join)(dir, "exit")),
15594
- log: (0, import_node_path44.join)(dir, "log"),
15595
- cursor: (0, import_node_path44.join)(dir, "present.cursor"),
15596
- progress: tailProgress((0, import_node_path44.join)(dir, "log"))
15738
+ exitCode: readIntFile((0, import_node_path45.join)(dir, "exit")),
15739
+ log: (0, import_node_path45.join)(dir, "log"),
15740
+ cursor: (0, import_node_path45.join)(dir, "present.cursor"),
15741
+ progress: tailProgress((0, import_node_path45.join)(dir, "log"))
15597
15742
  };
15598
15743
  }
15599
15744
  function toResult(id, snap, extra) {
@@ -15602,8 +15747,8 @@ function toResult(id, snap, extra) {
15602
15747
  const stillRunning = snap.running && !ok;
15603
15748
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
15604
15749
  try {
15605
- (0, import_node_fs42.mkdirSync)((0, import_node_path44.dirname)(snap.cursor), { recursive: true });
15606
- (0, import_node_fs42.writeFileSync)(snap.cursor, `${nextCursor}
15750
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(snap.cursor), { recursive: true });
15751
+ (0, import_node_fs44.writeFileSync)(snap.cursor, `${nextCursor}
15607
15752
  `);
15608
15753
  } catch {
15609
15754
  }
@@ -15632,7 +15777,7 @@ async function waitForDetachedJob(cwd, id, opts) {
15632
15777
  const dir = resolveJobDir(root, jobId);
15633
15778
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
15634
15779
  const sleep = opts?.sleep ?? sleepMs;
15635
- if (!(0, import_node_fs42.existsSync)(dir)) {
15780
+ if (!(0, import_node_fs44.existsSync)(dir)) {
15636
15781
  return {
15637
15782
  stillRunning: false,
15638
15783
  ok: false,
@@ -15678,10 +15823,10 @@ function killProcessTree(pid, signal) {
15678
15823
  }
15679
15824
  function appendJobLog(logFile, line) {
15680
15825
  try {
15681
- (0, import_node_fs42.mkdirSync)((0, import_node_path44.dirname)(logFile), { recursive: true });
15826
+ (0, import_node_fs44.mkdirSync)((0, import_node_path45.dirname)(logFile), { recursive: true });
15682
15827
  const body = line.endsWith("\n") ? line : `${line}
15683
15828
  `;
15684
- (0, import_node_fs42.appendFileSync)(logFile, body);
15829
+ (0, import_node_fs44.appendFileSync)(logFile, body);
15685
15830
  } catch {
15686
15831
  }
15687
15832
  }
@@ -15691,7 +15836,7 @@ async function stopDetachedJob(cwd, id, opts) {
15691
15836
  const dir = resolveJobDir(root, jobId);
15692
15837
  const sleep = opts?.sleep ?? sleepMs;
15693
15838
  const why = opts?.reason?.trim() ?? "";
15694
- if (!(0, import_node_fs42.existsSync)(dir)) {
15839
+ if (!(0, import_node_fs44.existsSync)(dir)) {
15695
15840
  return {
15696
15841
  stillRunning: false,
15697
15842
  ok: false,
@@ -15727,10 +15872,10 @@ async function stopDetachedJob(cwd, id, opts) {
15727
15872
  killProcessTree(targetPid, "SIGKILL");
15728
15873
  await sleep(100);
15729
15874
  }
15730
- const exitFile = (0, import_node_path44.join)(dir, "exit");
15731
- if (!(0, import_node_fs42.existsSync)(exitFile)) {
15875
+ const exitFile = (0, import_node_path45.join)(dir, "exit");
15876
+ if (!(0, import_node_fs44.existsSync)(exitFile)) {
15732
15877
  try {
15733
- (0, import_node_fs42.writeFileSync)(exitFile, "1\n");
15878
+ (0, import_node_fs44.writeFileSync)(exitFile, "1\n");
15734
15879
  } catch {
15735
15880
  }
15736
15881
  }
@@ -15750,12 +15895,12 @@ async function stopDetachedJob(cwd, id, opts) {
15750
15895
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
15751
15896
  };
15752
15897
  }
15753
- var import_node_fs42, import_node_path44, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
15898
+ var import_node_fs44, import_node_path45, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
15754
15899
  var init_wait_for_job = __esm({
15755
15900
  "src/mcp/wait-for-job.ts"() {
15756
15901
  "use strict";
15757
- import_node_fs42 = require("fs");
15758
- import_node_path44 = require("path");
15902
+ import_node_fs44 = require("fs");
15903
+ import_node_path45 = require("path");
15759
15904
  init_workspace_scratch();
15760
15905
  init_wait_for_turn();
15761
15906
  MAX_JOB_CONTINUES = 8;
@@ -17790,7 +17935,7 @@ function reuseLiveThread(input, repoPath, match) {
17790
17935
  }
17791
17936
  async function createThread(input, _onSetupLine) {
17792
17937
  const repoPath = await resolveRepoRoot(input.repoPath);
17793
- if (!(0, import_node_fs43.existsSync)(repoPath)) {
17938
+ if (!(0, import_node_fs45.existsSync)(repoPath)) {
17794
17939
  throw new Error(`Repo not found: ${repoPath}`);
17795
17940
  }
17796
17941
  const reused = reuseLiveThread(input, repoPath, {
@@ -17966,11 +18111,11 @@ async function createThread(input, _onSetupLine) {
17966
18111
  await ensureWorkspace(repoPath);
17967
18112
  return readThread(thread.id) ?? thread;
17968
18113
  }
17969
- var import_node_fs43;
18114
+ var import_node_fs45;
17970
18115
  var init_create = __esm({
17971
18116
  "src/threads/create.ts"() {
17972
18117
  "use strict";
17973
- import_node_fs43 = require("fs");
18118
+ import_node_fs45 = require("fs");
17974
18119
  init_detect();
17975
18120
  init_worktree();
17976
18121
  init_home_board();
@@ -18122,20 +18267,20 @@ function writeTurnLive(threadId, progress) {
18122
18267
  const path = threadLivePath(threadId);
18123
18268
  const tmp = `${path}.${process.pid}.tmp`;
18124
18269
  try {
18125
- (0, import_node_fs44.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
18126
- (0, import_node_fs44.renameSync)(tmp, path);
18270
+ (0, import_node_fs46.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
18271
+ (0, import_node_fs46.renameSync)(tmp, path);
18127
18272
  } catch {
18128
18273
  try {
18129
- (0, import_node_fs44.unlinkSync)(tmp);
18274
+ (0, import_node_fs46.unlinkSync)(tmp);
18130
18275
  } catch {
18131
18276
  }
18132
18277
  }
18133
18278
  }
18134
18279
  function readTurnLive(threadId) {
18135
18280
  const path = threadLivePath(threadId);
18136
- if (!(0, import_node_fs44.existsSync)(path)) return null;
18281
+ if (!(0, import_node_fs46.existsSync)(path)) return null;
18137
18282
  try {
18138
- const raw = JSON.parse((0, import_node_fs44.readFileSync)(path, "utf8"));
18283
+ const raw = JSON.parse((0, import_node_fs46.readFileSync)(path, "utf8"));
18139
18284
  if (!raw || typeof raw.summary !== "string") return null;
18140
18285
  return raw;
18141
18286
  } catch {
@@ -18147,17 +18292,17 @@ function clearTurnLive(threadId) {
18147
18292
  if (buf?.timer) clearTimeout(buf.timer);
18148
18293
  buffers.delete(threadId);
18149
18294
  const path = threadLivePath(threadId);
18150
- if (!(0, import_node_fs44.existsSync)(path)) return;
18295
+ if (!(0, import_node_fs46.existsSync)(path)) return;
18151
18296
  try {
18152
- (0, import_node_fs44.unlinkSync)(path);
18297
+ (0, import_node_fs46.unlinkSync)(path);
18153
18298
  } catch {
18154
18299
  }
18155
18300
  }
18156
- var import_node_fs44, buffers, FLUSH_MS, MAX_PARTS;
18301
+ var import_node_fs46, buffers, FLUSH_MS, MAX_PARTS;
18157
18302
  var init_turn_live = __esm({
18158
18303
  "src/store/turn-live.ts"() {
18159
18304
  "use strict";
18160
- import_node_fs44 = require("fs");
18305
+ import_node_fs46 = require("fs");
18161
18306
  init_message_parts();
18162
18307
  init_paths();
18163
18308
  buffers = /* @__PURE__ */ new Map();
@@ -18396,12 +18541,12 @@ var init_quota_failover = __esm({
18396
18541
  });
18397
18542
 
18398
18543
  // src/threads/adopt.ts
18399
- function thisModuleFile() {
18544
+ function thisModuleFile2() {
18400
18545
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
18401
- return cjsFile || process.argv[1] || (0, import_node_path45.join)(process.cwd(), "package.json");
18546
+ return cjsFile || process.argv[1] || (0, import_node_path46.join)(process.cwd(), "package.json");
18402
18547
  }
18403
18548
  function openReadonlySqlite(file) {
18404
- const req = (0, import_node_module4.createRequire)(thisModuleFile());
18549
+ const req = (0, import_node_module5.createRequire)(thisModuleFile2());
18405
18550
  const Database = req("better-sqlite3");
18406
18551
  return new Database(file, { readonly: true, fileMustExist: true });
18407
18552
  }
@@ -18416,21 +18561,21 @@ function mapAgentType(raw) {
18416
18561
  return null;
18417
18562
  }
18418
18563
  function resolveConductorCursorAgentId(workspacePath) {
18419
- if (!workspacePath || !(0, import_node_fs45.existsSync)(CURSOR_SDK_STORE)) return null;
18564
+ if (!workspacePath || !(0, import_node_fs47.existsSync)(CURSOR_SDK_STORE)) return null;
18420
18565
  const normalized = workspacePath.replace(/\/$/, "");
18421
18566
  let best = null;
18422
18567
  let hashes;
18423
18568
  try {
18424
- hashes = (0, import_node_fs45.readdirSync)(CURSOR_SDK_STORE);
18569
+ hashes = (0, import_node_fs47.readdirSync)(CURSOR_SDK_STORE);
18425
18570
  } catch {
18426
18571
  return null;
18427
18572
  }
18428
18573
  for (const hash of hashes) {
18429
- const agentsFile = (0, import_node_path45.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
18430
- if (!(0, import_node_fs45.existsSync)(agentsFile)) continue;
18574
+ const agentsFile = (0, import_node_path46.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
18575
+ if (!(0, import_node_fs47.existsSync)(agentsFile)) continue;
18431
18576
  let text7;
18432
18577
  try {
18433
- text7 = (0, import_node_fs45.readFileSync)(agentsFile, "utf8");
18578
+ text7 = (0, import_node_fs47.readFileSync)(agentsFile, "utf8");
18434
18579
  } catch {
18435
18580
  continue;
18436
18581
  }
@@ -18454,7 +18599,7 @@ function resolveConductorCursorAgentId(workspacePath) {
18454
18599
  return best?.agentId ?? null;
18455
18600
  }
18456
18601
  async function adoptThread(input) {
18457
- if (!(0, import_node_fs45.existsSync)(input.worktreePath)) {
18602
+ if (!(0, import_node_fs47.existsSync)(input.worktreePath)) {
18458
18603
  throw new Error(`Worktree not found: ${input.worktreePath}`);
18459
18604
  }
18460
18605
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -18480,18 +18625,18 @@ async function adoptThread(input) {
18480
18625
  return thread;
18481
18626
  }
18482
18627
  function listConductorWorkspaces() {
18483
- if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
18628
+ if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
18484
18629
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
18485
18630
  }
18486
- const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18487
- const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
18631
+ const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path46.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18632
+ const snapshot = (0, import_node_path46.join)(tmp, "conductor.db");
18488
18633
  try {
18489
- (0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
18634
+ (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
18490
18635
  for (const suffix of ["-wal", "-shm"]) {
18491
18636
  const src = `${CONDUCTOR_DB}${suffix}`;
18492
- if ((0, import_node_fs45.existsSync)(src)) {
18637
+ if ((0, import_node_fs47.existsSync)(src)) {
18493
18638
  try {
18494
- (0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
18639
+ (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
18495
18640
  } catch {
18496
18641
  }
18497
18642
  }
@@ -18567,22 +18712,22 @@ function listConductorWorkspaces() {
18567
18712
  db.close();
18568
18713
  }
18569
18714
  } finally {
18570
- (0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
18715
+ (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
18571
18716
  }
18572
18717
  }
18573
18718
  function importConductorWorkspace(workspaceId) {
18574
- if (!(0, import_node_fs45.existsSync)(CONDUCTOR_DB)) {
18719
+ if (!(0, import_node_fs47.existsSync)(CONDUCTOR_DB)) {
18575
18720
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
18576
18721
  }
18577
- const tmp = (0, import_node_fs45.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18578
- const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
18722
+ const tmp = (0, import_node_fs47.mkdtempSync)((0, import_node_path46.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
18723
+ const snapshot = (0, import_node_path46.join)(tmp, "conductor.db");
18579
18724
  try {
18580
- (0, import_node_fs45.copyFileSync)(CONDUCTOR_DB, snapshot);
18725
+ (0, import_node_fs47.copyFileSync)(CONDUCTOR_DB, snapshot);
18581
18726
  for (const suffix of ["-wal", "-shm"]) {
18582
18727
  const src = `${CONDUCTOR_DB}${suffix}`;
18583
- if ((0, import_node_fs45.existsSync)(src)) {
18728
+ if ((0, import_node_fs47.existsSync)(src)) {
18584
18729
  try {
18585
- (0, import_node_fs45.copyFileSync)(src, `${snapshot}${suffix}`);
18730
+ (0, import_node_fs47.copyFileSync)(src, `${snapshot}${suffix}`);
18586
18731
  } catch {
18587
18732
  }
18588
18733
  }
@@ -18600,7 +18745,7 @@ function importConductorWorkspace(workspaceId) {
18600
18745
  ).get(workspaceId);
18601
18746
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
18602
18747
  const worktreePath = String(row.workspacePath);
18603
- if (!(0, import_node_fs45.existsSync)(worktreePath)) {
18748
+ if (!(0, import_node_fs47.existsSync)(worktreePath)) {
18604
18749
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
18605
18750
  }
18606
18751
  let sessionId = null;
@@ -18663,31 +18808,31 @@ function importConductorWorkspace(workspaceId) {
18663
18808
  db.close();
18664
18809
  }
18665
18810
  } finally {
18666
- (0, import_node_fs45.rmSync)(tmp, { recursive: true, force: true });
18811
+ (0, import_node_fs47.rmSync)(tmp, { recursive: true, force: true });
18667
18812
  }
18668
18813
  }
18669
18814
  async function importConductorWorkspaceAsync(workspaceId) {
18670
18815
  return importConductorWorkspace(workspaceId);
18671
18816
  }
18672
- var import_node_child_process5, import_node_fs45, import_node_os14, import_node_path45, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
18817
+ var import_node_child_process5, import_node_fs47, import_node_os14, import_node_path46, import_node_module5, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
18673
18818
  var init_adopt = __esm({
18674
18819
  "src/threads/adopt.ts"() {
18675
18820
  "use strict";
18676
18821
  import_node_child_process5 = require("child_process");
18677
- import_node_fs45 = require("fs");
18822
+ import_node_fs47 = require("fs");
18678
18823
  import_node_os14 = require("os");
18679
- import_node_path45 = require("path");
18680
- import_node_module4 = require("module");
18824
+ import_node_path46 = require("path");
18825
+ import_node_module5 = require("module");
18681
18826
  init_worktree();
18682
18827
  init_thread_store();
18683
- CONDUCTOR_APP_SUPPORT = (0, import_node_path45.join)(
18828
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path46.join)(
18684
18829
  process.env.HOME ?? "",
18685
18830
  "Library",
18686
18831
  "Application Support",
18687
18832
  "com.conductor.app"
18688
18833
  );
18689
- CONDUCTOR_DB = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18690
- CURSOR_SDK_STORE = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18834
+ CONDUCTOR_DB = (0, import_node_path46.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18835
+ CURSOR_SDK_STORE = (0, import_node_path46.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18691
18836
  }
18692
18837
  });
18693
18838
 
@@ -18754,7 +18899,7 @@ async function openStackLayer(input, _onSetupLine) {
18754
18899
  let createdWorktree = false;
18755
18900
  const trees = await listWorktrees(repoPath);
18756
18901
  const checkedOut = trees.find((w) => w.branch === branchName);
18757
- if (checkedOut?.path && (0, import_node_fs46.existsSync)(checkedOut.path)) {
18902
+ if (checkedOut?.path && (0, import_node_fs48.existsSync)(checkedOut.path)) {
18758
18903
  if (input.reuseExistingWorktree !== false) {
18759
18904
  worktreePath = checkedOut.path;
18760
18905
  } else {
@@ -18896,7 +19041,7 @@ async function initStackFromThread(input, onSetupLine) {
18896
19041
  async function createPrStack(input, onSetupLine) {
18897
19042
  await requireAgent(input.agent);
18898
19043
  const repoPath = await resolveRepoRoot(input.repoPath);
18899
- if (!(0, import_node_fs46.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
19044
+ if (!(0, import_node_fs48.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
18900
19045
  if (!input.branches.length) throw new Error("At least one branch name required");
18901
19046
  const status = await detectGhStack(repoPath);
18902
19047
  if (!status.available) throw new Error(status.reason);
@@ -18963,7 +19108,7 @@ async function createPrStack(input, onSetupLine) {
18963
19108
  }
18964
19109
  }
18965
19110
  const claimed = new Set(threads.map((t) => t.worktreePath));
18966
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs46.existsSync)(bootstrap.worktreePath)) {
19111
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs48.existsSync)(bootstrap.worktreePath)) {
18967
19112
  try {
18968
19113
  await removeWorktree(repoPath, bootstrap.worktreePath, {
18969
19114
  deleteBranch: bootstrap.branchName
@@ -18973,11 +19118,11 @@ async function createPrStack(input, onSetupLine) {
18973
19118
  }
18974
19119
  return { stack, threads, createdThreadIds };
18975
19120
  }
18976
- var import_node_fs46;
19121
+ var import_node_fs48;
18977
19122
  var init_stack_layers = __esm({
18978
19123
  "src/threads/stack-layers.ts"() {
18979
19124
  "use strict";
18980
- import_node_fs46 = require("fs");
19125
+ import_node_fs48 = require("fs");
18981
19126
  init_detect();
18982
19127
  init_run();
18983
19128
  init_stack();
@@ -18990,7 +19135,7 @@ var init_stack_layers = __esm({
18990
19135
 
18991
19136
  // src/diff/diff.ts
18992
19137
  async function inspectGitWorktree(worktreePath) {
18993
- if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) return "missing_worktree";
19138
+ if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) return "missing_worktree";
18994
19139
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
18995
19140
  reject: false
18996
19141
  });
@@ -18998,7 +19143,7 @@ async function inspectGitWorktree(worktreePath) {
18998
19143
  return "ok";
18999
19144
  }
19000
19145
  async function initializeGitRepository(worktreePath) {
19001
- if (!worktreePath || !(0, import_node_fs47.existsSync)(worktreePath)) {
19146
+ if (!worktreePath || !(0, import_node_fs49.existsSync)(worktreePath)) {
19002
19147
  throw new Error("Worktree not found");
19003
19148
  }
19004
19149
  const status = await inspectGitWorktree(worktreePath);
@@ -19132,11 +19277,11 @@ new file mode 100644
19132
19277
  };
19133
19278
  }
19134
19279
  async function untrackedPatch(worktreePath, path, maxHunk) {
19135
- const abs = (0, import_node_path46.join)(worktreePath, path);
19280
+ const abs = (0, import_node_path47.join)(worktreePath, path);
19136
19281
  try {
19137
- const st = (0, import_node_fs47.statSync)(abs);
19282
+ const st = (0, import_node_fs49.statSync)(abs);
19138
19283
  if (st.isFile() && st.size > maxHunk) {
19139
- const buf = (0, import_node_fs47.readFileSync)(abs).subarray(0, maxHunk);
19284
+ const buf = (0, import_node_fs49.readFileSync)(abs).subarray(0, maxHunk);
19140
19285
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
19141
19286
  }
19142
19287
  } catch {
@@ -19603,9 +19748,9 @@ async function getDiff(worktreePath, repoPath, opts) {
19603
19748
  }
19604
19749
  function statWorktreePath(worktreePath, relativePath) {
19605
19750
  assertSafeRelativePath(relativePath);
19606
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19607
- if (!(0, import_node_fs47.existsSync)(abs)) return "missing";
19608
- const st = (0, import_node_fs47.statSync)(abs);
19751
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19752
+ if (!(0, import_node_fs49.existsSync)(abs)) return "missing";
19753
+ const st = (0, import_node_fs49.statSync)(abs);
19609
19754
  if (st.isDirectory()) return "dir";
19610
19755
  if (st.isFile()) return "file";
19611
19756
  return "missing";
@@ -19634,8 +19779,8 @@ function isImageRelativePath(relativePath) {
19634
19779
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19635
19780
  assertSafeRelativePath(relativePath);
19636
19781
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
19637
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19638
- const st = (0, import_node_fs47.statSync)(abs);
19782
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19783
+ const st = (0, import_node_fs49.statSync)(abs);
19639
19784
  if (!st.isFile()) {
19640
19785
  throw new Error(`Not a file: ${relativePath}`);
19641
19786
  }
@@ -19644,7 +19789,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19644
19789
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
19645
19790
  );
19646
19791
  }
19647
- const buf = (0, import_node_fs47.readFileSync)(abs);
19792
+ const buf = (0, import_node_fs49.readFileSync)(abs);
19648
19793
  return {
19649
19794
  path: relativePath,
19650
19795
  contentBase64: buf.toString("base64"),
@@ -19654,12 +19799,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
19654
19799
  function readWorktreeFile(worktreePath, relativePath, opts) {
19655
19800
  assertSafeRelativePath(relativePath);
19656
19801
  const maxBytes = opts?.maxBytes ?? 2e5;
19657
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19658
- const st = (0, import_node_fs47.statSync)(abs);
19802
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19803
+ const st = (0, import_node_fs49.statSync)(abs);
19659
19804
  if (!st.isFile()) {
19660
19805
  throw new Error(`Not a file: ${relativePath}`);
19661
19806
  }
19662
- const buf = (0, import_node_fs47.readFileSync)(abs);
19807
+ const buf = (0, import_node_fs49.readFileSync)(abs);
19663
19808
  if (isImageRelativePath(relativePath)) {
19664
19809
  const maxImageBytes = Math.max(maxBytes, 15e6);
19665
19810
  const truncated2 = buf.length > maxImageBytes;
@@ -19702,9 +19847,9 @@ function assertSafeRelativePath(relativePath) {
19702
19847
  }
19703
19848
  function writeWorktreeFile(worktreePath, relativePath, content) {
19704
19849
  assertSafeRelativePath(relativePath);
19705
- const abs = (0, import_node_path46.join)(worktreePath, relativePath);
19706
- (0, import_node_fs47.mkdirSync)((0, import_node_path46.dirname)(abs), { recursive: true });
19707
- (0, import_node_fs47.writeFileSync)(abs, content, "utf8");
19850
+ const abs = (0, import_node_path47.join)(worktreePath, relativePath);
19851
+ (0, import_node_fs49.mkdirSync)((0, import_node_path47.dirname)(abs), { recursive: true });
19852
+ (0, import_node_fs49.writeFileSync)(abs, content, "utf8");
19708
19853
  return { path: relativePath };
19709
19854
  }
19710
19855
  async function getWorktreeDirtyStat(worktreePath) {
@@ -19744,12 +19889,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
19744
19889
  truncated: full.files.length > maxFiles
19745
19890
  };
19746
19891
  }
19747
- var import_node_fs47, import_node_path46, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19892
+ var import_node_fs49, import_node_path47, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19748
19893
  var init_diff = __esm({
19749
19894
  "src/diff/diff.ts"() {
19750
19895
  "use strict";
19751
- import_node_fs47 = require("fs");
19752
- import_node_path46 = require("path");
19896
+ import_node_fs49 = require("fs");
19897
+ import_node_path47 = require("path");
19753
19898
  init_run();
19754
19899
  init_worktree();
19755
19900
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -20106,7 +20251,7 @@ function parseFrontmatter(content) {
20106
20251
  }
20107
20252
  function readSkill(skillMd, source) {
20108
20253
  try {
20109
- const content = (0, import_node_fs48.readFileSync)(skillMd, "utf8");
20254
+ const content = (0, import_node_fs50.readFileSync)(skillMd, "utf8");
20110
20255
  const { name: fmName, description } = parseFrontmatter(content);
20111
20256
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
20112
20257
  const name = fmName || dirName;
@@ -20125,19 +20270,19 @@ function readSkill(skillMd, source) {
20125
20270
  }
20126
20271
  }
20127
20272
  function scanSkillsDir(dir, source, out) {
20128
- if (!(0, import_node_fs48.existsSync)(dir)) return;
20273
+ if (!(0, import_node_fs50.existsSync)(dir)) return;
20129
20274
  let entries;
20130
20275
  try {
20131
- entries = (0, import_node_fs48.readdirSync)(dir);
20276
+ entries = (0, import_node_fs50.readdirSync)(dir);
20132
20277
  } catch {
20133
20278
  return;
20134
20279
  }
20135
20280
  for (const entry of entries) {
20136
20281
  if (entry.startsWith(".")) continue;
20137
- const skillMd = (0, import_node_path47.join)(dir, entry, "SKILL.md");
20138
- if (!(0, import_node_fs48.existsSync)(skillMd)) continue;
20282
+ const skillMd = (0, import_node_path48.join)(dir, entry, "SKILL.md");
20283
+ if (!(0, import_node_fs50.existsSync)(skillMd)) continue;
20139
20284
  try {
20140
- if (!(0, import_node_fs48.statSync)(skillMd).isFile()) continue;
20285
+ if (!(0, import_node_fs50.statSync)(skillMd).isFile()) continue;
20141
20286
  } catch {
20142
20287
  continue;
20143
20288
  }
@@ -20146,24 +20291,24 @@ function scanSkillsDir(dir, source, out) {
20146
20291
  }
20147
20292
  }
20148
20293
  function scanClaudePluginSkills(pluginsRoot, out) {
20149
- if (!(0, import_node_fs48.existsSync)(pluginsRoot)) return;
20294
+ if (!(0, import_node_fs50.existsSync)(pluginsRoot)) return;
20150
20295
  const walk = (dir, depth, lookingForSkillsDir) => {
20151
20296
  if (depth > 7) return;
20152
20297
  let entries;
20153
20298
  try {
20154
- entries = (0, import_node_fs48.readdirSync)(dir);
20299
+ entries = (0, import_node_fs50.readdirSync)(dir);
20155
20300
  } catch {
20156
20301
  return;
20157
20302
  }
20158
20303
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
20159
- const skill = readSkill((0, import_node_path47.join)(dir, "SKILL.md"), "cli");
20304
+ const skill = readSkill((0, import_node_path48.join)(dir, "SKILL.md"), "cli");
20160
20305
  if (skill) out.push(skill);
20161
20306
  }
20162
20307
  for (const entry of entries) {
20163
20308
  if (entry === "node_modules" || entry === ".git") continue;
20164
- const full = (0, import_node_path47.join)(dir, entry);
20309
+ const full = (0, import_node_path48.join)(dir, entry);
20165
20310
  try {
20166
- if (!(0, import_node_fs48.statSync)(full).isDirectory()) continue;
20311
+ if (!(0, import_node_fs50.statSync)(full).isDirectory()) continue;
20167
20312
  } catch {
20168
20313
  continue;
20169
20314
  }
@@ -20181,17 +20326,17 @@ function discoverSkills(worktreePath) {
20181
20326
  const home = (0, import_node_os15.homedir)();
20182
20327
  const collected = [];
20183
20328
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
20184
- scanSkillsDir((0, import_node_path47.join)(worktreePath, rel), "workspace", collected);
20329
+ scanSkillsDir((0, import_node_path48.join)(worktreePath, rel), "workspace", collected);
20185
20330
  }
20186
20331
  for (const abs of [
20187
- (0, import_node_path47.join)(home, ".claude/skills"),
20188
- (0, import_node_path47.join)(home, ".cursor/skills"),
20189
- (0, import_node_path47.join)(home, ".sideboard/skills"),
20190
- (0, import_node_path47.join)(home, ".brightsy/skills")
20332
+ (0, import_node_path48.join)(home, ".claude/skills"),
20333
+ (0, import_node_path48.join)(home, ".cursor/skills"),
20334
+ (0, import_node_path48.join)(home, ".sideboard/skills"),
20335
+ (0, import_node_path48.join)(home, ".brightsy/skills")
20191
20336
  ]) {
20192
20337
  scanSkillsDir(abs, "user", collected);
20193
20338
  }
20194
- scanClaudePluginSkills((0, import_node_path47.join)(home, ".claude/plugins"), collected);
20339
+ scanClaudePluginSkills((0, import_node_path48.join)(home, ".claude/plugins"), collected);
20195
20340
  collected.push(...bundledSkills());
20196
20341
  const rank = {
20197
20342
  workspace: 0,
@@ -20217,7 +20362,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
20217
20362
  \u2026(truncated)` : body;
20218
20363
  }
20219
20364
  }
20220
- const raw = (0, import_node_fs48.readFileSync)(skillPath, "utf8");
20365
+ const raw = (0, import_node_fs50.readFileSync)(skillPath, "utf8");
20221
20366
  if (raw.startsWith("---")) {
20222
20367
  const end = raw.indexOf("\n---", 3);
20223
20368
  if (end >= 0) {
@@ -20231,13 +20376,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
20231
20376
 
20232
20377
  \u2026(truncated)` : raw;
20233
20378
  }
20234
- var import_node_fs48, import_node_os15, import_node_path47, BUNDLED_SKILL_PREFIX;
20379
+ var import_node_fs50, import_node_os15, import_node_path48, BUNDLED_SKILL_PREFIX;
20235
20380
  var init_discover = __esm({
20236
20381
  "src/skills/discover.ts"() {
20237
20382
  "use strict";
20238
- import_node_fs48 = require("fs");
20383
+ import_node_fs50 = require("fs");
20239
20384
  import_node_os15 = require("os");
20240
- import_node_path47 = require("path");
20385
+ import_node_path48 = require("path");
20241
20386
  init_long_running();
20242
20387
  BUNDLED_SKILL_PREFIX = "bundled:";
20243
20388
  }
@@ -20390,9 +20535,9 @@ function compiledModuleDir() {
20390
20535
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
20391
20536
  if (cjsDir) return cjsDir;
20392
20537
  try {
20393
- const url = import_meta3.url;
20538
+ const url = import_meta4.url;
20394
20539
  if (typeof url === "string" && url.length > 0) {
20395
- return (0, import_node_path48.dirname)((0, import_node_url3.fileURLToPath)(url));
20540
+ return (0, import_node_path49.dirname)((0, import_node_url4.fileURLToPath)(url));
20396
20541
  }
20397
20542
  } catch {
20398
20543
  }
@@ -20400,8 +20545,8 @@ function compiledModuleDir() {
20400
20545
  }
20401
20546
  function detachedJobScriptIn(dir) {
20402
20547
  for (const name of DETACHED_JOB_FILENAMES) {
20403
- const script = (0, import_node_path48.join)(dir, "scripts", name);
20404
- if ((0, import_node_fs49.existsSync)(script)) return script;
20548
+ const script = (0, import_node_path49.join)(dir, "scripts", name);
20549
+ if ((0, import_node_fs51.existsSync)(script)) return script;
20405
20550
  }
20406
20551
  return null;
20407
20552
  }
@@ -20418,7 +20563,7 @@ function resolveDetachedJobScript() {
20418
20563
  for (let i = 0; i < 8; i++) {
20419
20564
  const candidate = detachedJobScriptIn(dir);
20420
20565
  if (candidate) return candidate;
20421
- const parent = (0, import_node_path48.dirname)(dir);
20566
+ const parent = (0, import_node_path49.dirname)(dir);
20422
20567
  if (parent === dir) break;
20423
20568
  dir = parent;
20424
20569
  }
@@ -20429,15 +20574,15 @@ function formatDetachedJobInvoke(scriptPath) {
20429
20574
  if (resolved) return `node ${JSON.stringify(resolved)}`;
20430
20575
  return "node scripts/detached-job.cjs";
20431
20576
  }
20432
- var import_node_fs49, import_node_path48, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
20577
+ var import_node_fs51, import_node_path49, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
20433
20578
  var init_detached_job_path = __esm({
20434
20579
  "src/skills/detached-job-path.ts"() {
20435
20580
  "use strict";
20436
- import_node_fs49 = require("fs");
20437
- import_node_path48 = require("path");
20438
- import_node_url3 = require("url");
20581
+ import_node_fs51 = require("fs");
20582
+ import_node_path49 = require("path");
20583
+ import_node_url4 = require("url");
20439
20584
  init_packaged_runtime();
20440
- import_meta3 = {};
20585
+ import_meta4 = {};
20441
20586
  DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
20442
20587
  }
20443
20588
  });
@@ -20594,9 +20739,9 @@ function formatPrGateDirective() {
20594
20739
  }
20595
20740
  function formatProcessGuideDirective(opts) {
20596
20741
  const worktree = opts?.worktreePath?.trim();
20597
- const hasGraphSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
20598
- const hasReviewSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/review/SKILL.md"));
20599
- const hasInstallSkill = !!worktree && (0, import_node_fs50.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
20742
+ const hasGraphSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path50.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
20743
+ const hasReviewSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path50.join)(worktree, ".claude/skills/review/SKILL.md"));
20744
+ const hasInstallSkill = !!worktree && (0, import_node_fs52.existsSync)((0, import_node_path50.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
20600
20745
  return [
20601
20746
  "Process guides (recurring work only):",
20602
20747
  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,
@@ -20635,12 +20780,12 @@ function formatArtifactDirective() {
20635
20780
  function formatUiReminder() {
20636
20781
  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.";
20637
20782
  }
20638
- var import_node_fs50, import_node_path49, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
20783
+ var import_node_fs52, import_node_path50, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
20639
20784
  var init_instructions = __esm({
20640
20785
  "src/agents/instructions.ts"() {
20641
20786
  "use strict";
20642
- import_node_fs50 = require("fs");
20643
- import_node_path49 = require("path");
20787
+ import_node_fs52 = require("fs");
20788
+ import_node_path50 = require("path");
20644
20789
  init_git_auth_mode();
20645
20790
  init_branch_prefix();
20646
20791
  init_worktree_labels();
@@ -20864,40 +21009,40 @@ __export(plan_file_exports, {
20864
21009
  writePlanFile: () => writePlanFile
20865
21010
  });
20866
21011
  function ensureAttachmentsGitignore(worktreePath) {
20867
- const gitignoreAbs = (0, import_node_path50.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20868
- if ((0, import_node_fs51.existsSync)(gitignoreAbs)) return;
20869
- (0, import_node_fs51.mkdirSync)((0, import_node_path50.dirname)(gitignoreAbs), { recursive: true });
20870
- (0, import_node_fs51.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
21012
+ const gitignoreAbs = (0, import_node_path51.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
21013
+ if ((0, import_node_fs53.existsSync)(gitignoreAbs)) return;
21014
+ (0, import_node_fs53.mkdirSync)((0, import_node_path51.dirname)(gitignoreAbs), { recursive: true });
21015
+ (0, import_node_fs53.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20871
21016
  }
20872
21017
  function planFileAbs(worktreePath) {
20873
- return (0, import_node_path50.join)(worktreePath, PLAN_FILE_REL);
21018
+ return (0, import_node_path51.join)(worktreePath, PLAN_FILE_REL);
20874
21019
  }
20875
21020
  function readTextIfPresent2(abs) {
20876
- if (!(0, import_node_fs51.existsSync)(abs)) return null;
21021
+ if (!(0, import_node_fs53.existsSync)(abs)) return null;
20877
21022
  try {
20878
- const content = (0, import_node_fs51.readFileSync)(abs, "utf8");
21023
+ const content = (0, import_node_fs53.readFileSync)(abs, "utf8");
20879
21024
  return content.trim() ? content : null;
20880
21025
  } catch {
20881
21026
  return null;
20882
21027
  }
20883
21028
  }
20884
21029
  function readPlanFile(worktreePath) {
20885
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path50.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path50.join)(worktreePath, LEGACY_PLAN_FILE_REL));
21030
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path51.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path51.join)(worktreePath, LEGACY_PLAN_FILE_REL));
20886
21031
  }
20887
21032
  function writePlanFile(worktreePath, content) {
20888
21033
  ensureAttachmentsGitignore(worktreePath);
20889
21034
  const abs = planFileAbs(worktreePath);
20890
- (0, import_node_fs51.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
21035
+ (0, import_node_fs53.mkdirSync)((0, import_node_path51.dirname)(abs), { recursive: true });
20891
21036
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
20892
- (0, import_node_fs51.writeFileSync)(abs, body, "utf8");
21037
+ (0, import_node_fs53.writeFileSync)(abs, body, "utf8");
20893
21038
  return PLAN_FILE_REL;
20894
21039
  }
20895
- var import_node_fs51, import_node_path50;
21040
+ var import_node_fs53, import_node_path51;
20896
21041
  var init_plan_file = __esm({
20897
21042
  "src/plan/plan-file.ts"() {
20898
21043
  "use strict";
20899
- import_node_fs51 = require("fs");
20900
- import_node_path50 = require("path");
21044
+ import_node_fs53 = require("fs");
21045
+ import_node_path51 = require("path");
20901
21046
  init_workspace_scratch();
20902
21047
  init_plan_present();
20903
21048
  init_plan_present();
@@ -20957,7 +21102,7 @@ function setCaffeinateHoldHooks(next) {
20957
21102
  hooks = next;
20958
21103
  }
20959
21104
  function caffeinateHoldPath() {
20960
- return (0, import_node_path51.join)(appDataDir(), "caffeinate-hold.json");
21105
+ return (0, import_node_path52.join)(appDataDir(), "caffeinate-hold.json");
20961
21106
  }
20962
21107
  function processAlive(pid) {
20963
21108
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -20991,9 +21136,9 @@ function uniqueIds(ids) {
20991
21136
  }
20992
21137
  function readHold() {
20993
21138
  const path = caffeinateHoldPath();
20994
- if (!(0, import_node_fs52.existsSync)(path)) return null;
21139
+ if (!(0, import_node_fs54.existsSync)(path)) return null;
20995
21140
  try {
20996
- const parsed = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
21141
+ const parsed = JSON.parse((0, import_node_fs54.readFileSync)(path, "utf8"));
20997
21142
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
20998
21143
  return {
20999
21144
  pid: parsed.pid,
@@ -21015,7 +21160,7 @@ function writeHold(pid, threadIds) {
21015
21160
  }
21016
21161
  function clearHold() {
21017
21162
  try {
21018
- (0, import_node_fs52.unlinkSync)(caffeinateHoldPath());
21163
+ (0, import_node_fs54.unlinkSync)(caffeinateHoldPath());
21019
21164
  } catch {
21020
21165
  }
21021
21166
  }
@@ -21100,13 +21245,13 @@ function releaseCaffeinateHoldForThread(threadId) {
21100
21245
  }
21101
21246
  return setCaffeinateHold(false, { threadId: id });
21102
21247
  }
21103
- var import_node_child_process6, import_node_fs52, import_node_path51, hooks;
21248
+ var import_node_child_process6, import_node_fs54, import_node_path52, hooks;
21104
21249
  var init_caffeinate_hold = __esm({
21105
21250
  "src/store/caffeinate-hold.ts"() {
21106
21251
  "use strict";
21107
21252
  import_node_child_process6 = require("child_process");
21108
- import_node_fs52 = require("fs");
21109
- import_node_path51 = require("path");
21253
+ import_node_fs54 = require("fs");
21254
+ import_node_path52 = require("path");
21110
21255
  init_paths();
21111
21256
  init_private_file();
21112
21257
  hooks = {};
@@ -21115,7 +21260,7 @@ var init_caffeinate_hold = __esm({
21115
21260
 
21116
21261
  // src/store/schedules.ts
21117
21262
  function schedulesPath() {
21118
- return (0, import_node_path52.join)(appDataDir(), "schedules.json");
21263
+ return (0, import_node_path53.join)(appDataDir(), "schedules.json");
21119
21264
  }
21120
21265
  function parseDurationMs(every) {
21121
21266
  const m = every.trim().match(DURATION_RE);
@@ -21215,9 +21360,9 @@ function normalizeTask(raw) {
21215
21360
  }
21216
21361
  function readAll2() {
21217
21362
  const path = schedulesPath();
21218
- if (!(0, import_node_fs53.existsSync)(path)) return [];
21363
+ if (!(0, import_node_fs55.existsSync)(path)) return [];
21219
21364
  try {
21220
- const parsed = JSON.parse((0, import_node_fs53.readFileSync)(path, "utf8"));
21365
+ const parsed = JSON.parse((0, import_node_fs55.readFileSync)(path, "utf8"));
21221
21366
  if (!Array.isArray(parsed)) return [];
21222
21367
  return parsed.map((row) => {
21223
21368
  try {
@@ -21329,13 +21474,13 @@ function recordScheduleRun(id, result) {
21329
21474
  writeAll2(rows);
21330
21475
  return next;
21331
21476
  }
21332
- var import_node_crypto11, import_node_fs53, import_node_path52, import_croner, DURATION_RE, UNIT_MS;
21477
+ var import_node_crypto11, import_node_fs55, import_node_path53, import_croner, DURATION_RE, UNIT_MS;
21333
21478
  var init_schedules = __esm({
21334
21479
  "src/store/schedules.ts"() {
21335
21480
  "use strict";
21336
21481
  import_node_crypto11 = require("crypto");
21337
- import_node_fs53 = require("fs");
21338
- import_node_path52 = require("path");
21482
+ import_node_fs55 = require("fs");
21483
+ import_node_path53 = require("path");
21339
21484
  import_croner = require("croner");
21340
21485
  init_orchestrator_capable();
21341
21486
  init_paths();
@@ -21491,9 +21636,9 @@ function recoverFinishedCursorRun(opts) {
21491
21636
  return best;
21492
21637
  }
21493
21638
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
21494
- if (!(0, import_node_fs54.existsSync)(runsPath)) return null;
21639
+ if (!(0, import_node_fs56.existsSync)(runsPath)) return null;
21495
21640
  try {
21496
- const lines = (0, import_node_fs54.readFileSync)(runsPath, "utf8").split("\n");
21641
+ const lines = (0, import_node_fs56.readFileSync)(runsPath, "utf8").split("\n");
21497
21642
  let best = null;
21498
21643
  for (const line of lines) {
21499
21644
  const trimmed = line.trim();
@@ -21519,11 +21664,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
21519
21664
  return null;
21520
21665
  }
21521
21666
  }
21522
- var import_node_fs54;
21667
+ var import_node_fs56;
21523
21668
  var init_cursor_recover = __esm({
21524
21669
  "src/agents/cursor-recover.ts"() {
21525
21670
  "use strict";
21526
- import_node_fs54 = require("fs");
21671
+ import_node_fs56 = require("fs");
21527
21672
  init_cursor_store();
21528
21673
  }
21529
21674
  });
@@ -21677,14 +21822,14 @@ async function startOrchestration(opts) {
21677
21822
  }
21678
21823
  return updated;
21679
21824
  }
21680
- var import_node_events, import_node_crypto12, import_node_fs55, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
21825
+ var import_node_events, import_node_crypto12, import_node_fs57, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
21681
21826
  var init_orchestrator = __esm({
21682
21827
  "src/orchestrator/orchestrator.ts"() {
21683
21828
  "use strict";
21684
21829
  import_node_events = require("events");
21685
21830
  init_outbound_watch();
21686
21831
  import_node_crypto12 = require("crypto");
21687
- import_node_fs55 = require("fs");
21832
+ import_node_fs57 = require("fs");
21688
21833
  init_error_detail();
21689
21834
  init_run();
21690
21835
  init_stale_lock();
@@ -21861,7 +22006,7 @@ var init_orchestrator = __esm({
21861
22006
  this.lightReconcileAt.set(repoPath, Date.now());
21862
22007
  for (const thread of listThreads()) {
21863
22008
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
21864
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
22009
+ if (!(0, import_node_fs57.existsSync)(thread.worktreePath)) {
21865
22010
  setStatus(thread.id, "broken", "Worktree missing on disk");
21866
22011
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
21867
22012
  }
@@ -21890,7 +22035,7 @@ var init_orchestrator = __esm({
21890
22035
  }
21891
22036
  continue;
21892
22037
  }
21893
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
22038
+ if (!(0, import_node_fs57.existsSync)(thread.worktreePath)) {
21894
22039
  setStatus(thread.id, "broken", "Worktree missing on disk");
21895
22040
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
21896
22041
  continue;
@@ -24181,7 +24326,7 @@ var init_orchestrator = __esm({
24181
24326
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
24182
24327
  return restored2;
24183
24328
  }
24184
- if (!(0, import_node_fs55.existsSync)(thread.worktreePath)) {
24329
+ if (!(0, import_node_fs57.existsSync)(thread.worktreePath)) {
24185
24330
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
24186
24331
  throw new Error(
24187
24332
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -24265,7 +24410,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
24265
24410
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
24266
24411
  var import_zod9 = require("zod");
24267
24412
  var import_node_crypto15 = require("crypto");
24268
- var import_node_path55 = require("path");
24413
+ var import_node_path56 = require("path");
24269
24414
  init_orchestrator();
24270
24415
  init_worktree();
24271
24416
 
@@ -27685,27 +27830,27 @@ init_gh_errors();
27685
27830
  init_git_auth_mode();
27686
27831
 
27687
27832
  // src/board/load-home-board.ts
27688
- var import_node_fs57 = require("fs");
27689
- var import_node_path54 = require("path");
27833
+ var import_node_fs59 = require("fs");
27834
+ var import_node_path55 = require("path");
27690
27835
  init_worktree();
27691
27836
  init_paths();
27692
27837
 
27693
27838
  // src/board/board-pins.ts
27694
27839
  var import_node_crypto14 = require("crypto");
27695
- var import_node_fs56 = require("fs");
27696
- var import_node_path53 = require("path");
27840
+ var import_node_fs58 = require("fs");
27841
+ var import_node_path54 = require("path");
27697
27842
  init_paths();
27698
27843
  init_home_board();
27699
27844
  var FILE = "home-board-pins.json";
27700
27845
  var VERSION = 1;
27701
27846
  function pinsFile() {
27702
- return (0, import_node_path53.join)(appDataDir(), FILE);
27847
+ return (0, import_node_path54.join)(appDataDir(), FILE);
27703
27848
  }
27704
27849
  function readDisk() {
27705
27850
  const path = pinsFile();
27706
- if (!(0, import_node_fs56.existsSync)(path)) return [];
27851
+ if (!(0, import_node_fs58.existsSync)(path)) return [];
27707
27852
  try {
27708
- const raw = JSON.parse((0, import_node_fs56.readFileSync)(path, "utf8"));
27853
+ const raw = JSON.parse((0, import_node_fs58.readFileSync)(path, "utf8"));
27709
27854
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
27710
27855
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
27711
27856
  } catch {
@@ -27713,8 +27858,8 @@ function readDisk() {
27713
27858
  }
27714
27859
  }
27715
27860
  function writeDisk(items) {
27716
- (0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
27717
- (0, import_node_fs56.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
27861
+ (0, import_node_fs58.mkdirSync)(appDataDir(), { recursive: true });
27862
+ (0, import_node_fs58.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
27718
27863
  }
27719
27864
  function listBoardPins() {
27720
27865
  return readDisk();
@@ -27735,7 +27880,7 @@ function homeBoardWorkspaceKey(workspaces) {
27735
27880
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
27736
27881
  }
27737
27882
  function cacheFile() {
27738
- return (0, import_node_path54.join)(appDataDir(), "home-board-cache.json");
27883
+ return (0, import_node_path55.join)(appDataDir(), "home-board-cache.json");
27739
27884
  }
27740
27885
  function emptyInputs() {
27741
27886
  return {
@@ -27761,9 +27906,9 @@ function shouldCacheHomeBoardInputs(inputs) {
27761
27906
  }
27762
27907
  function readDiskCache() {
27763
27908
  const path = cacheFile();
27764
- if (!(0, import_node_fs57.existsSync)(path)) return null;
27909
+ if (!(0, import_node_fs59.existsSync)(path)) return null;
27765
27910
  try {
27766
- const raw = JSON.parse((0, import_node_fs57.readFileSync)(path, "utf8"));
27911
+ const raw = JSON.parse((0, import_node_fs59.readFileSync)(path, "utf8"));
27767
27912
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
27768
27913
  return null;
27769
27914
  }
@@ -27777,8 +27922,8 @@ function readDiskCache() {
27777
27922
  }
27778
27923
  function writeDiskCache(entry) {
27779
27924
  try {
27780
- (0, import_node_fs57.mkdirSync)(appDataDir(), { recursive: true });
27781
- (0, import_node_fs57.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
27925
+ (0, import_node_fs59.mkdirSync)(appDataDir(), { recursive: true });
27926
+ (0, import_node_fs59.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
27782
27927
  } catch {
27783
27928
  }
27784
27929
  }
@@ -28165,7 +28310,7 @@ async function startMcpServer() {
28165
28310
  async () => {
28166
28311
  const threads = orch.getThreads(true);
28167
28312
  const lines = threads.map((t) => {
28168
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path55.basename)(t.repoPath) || t.repoPath;
28313
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path56.basename)(t.repoPath) || t.repoPath;
28169
28314
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
28170
28315
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
28171
28316
  const preview = lastMessagePreview(t.messages, 80);