@sideboard-ai/core 0.1.171 → 0.1.173

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.
@@ -11932,6 +11932,62 @@ var init_agents = __esm({
11932
11932
  }
11933
11933
  });
11934
11934
 
11935
+ // src/hook/worktree-pkg-cache.ts
11936
+ function worktreePkgCacheRoot(worktreePath) {
11937
+ return (0, import_node_path32.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
11938
+ }
11939
+ function worktreePkgCacheEnv(worktreePath) {
11940
+ const root = worktreePkgCacheRoot(worktreePath);
11941
+ const store = (0, import_node_path32.join)(root, "pnpm-store");
11942
+ const pnpmCache = (0, import_node_path32.join)(root, "pnpm");
11943
+ const npmCache = (0, import_node_path32.join)(root, "npm");
11944
+ const nodeGyp = (0, import_node_path32.join)(root, "node-gyp");
11945
+ const electron = (0, import_node_path32.join)(root, "electron");
11946
+ return {
11947
+ npm_config_store_dir: store,
11948
+ PNPM_STORE_DIR: store,
11949
+ npm_config_cache_dir: pnpmCache,
11950
+ npm_config_cache: npmCache,
11951
+ npm_config_devdir: nodeGyp,
11952
+ // @electron/get — do not set ELECTRON_CACHE (stripNestedElectronEnv).
11953
+ electron_config_cache: electron
11954
+ };
11955
+ }
11956
+ function isSet(value) {
11957
+ return value != null && value.trim() !== "";
11958
+ }
11959
+ function fillGroup(env, keys, values) {
11960
+ if (keys.some((key) => isSet(env[key]))) return;
11961
+ for (const key of keys) {
11962
+ const value = values[key];
11963
+ if (value) env[key] = value;
11964
+ }
11965
+ }
11966
+ function ensureWorktreePkgCacheDirs(worktreePath) {
11967
+ if (!(0, import_node_fs32.existsSync)(worktreePath)) return;
11968
+ (0, import_node_fs32.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
11969
+ }
11970
+ function applyWorktreePkgCacheEnv(env, worktreePath) {
11971
+ const cwd = worktreePath.trim();
11972
+ if (!cwd) return;
11973
+ const next = worktreePkgCacheEnv(cwd);
11974
+ fillGroup(env, ["npm_config_store_dir", "PNPM_STORE_DIR"], next);
11975
+ fillGroup(env, ["npm_config_cache_dir"], next);
11976
+ fillGroup(env, ["npm_config_cache"], next);
11977
+ fillGroup(env, ["npm_config_devdir"], next);
11978
+ fillGroup(env, ["electron_config_cache"], next);
11979
+ ensureWorktreePkgCacheDirs(cwd);
11980
+ }
11981
+ var import_node_fs32, import_node_path32, WORKTREE_PKG_CACHE_REL;
11982
+ var init_worktree_pkg_cache = __esm({
11983
+ "src/hook/worktree-pkg-cache.ts"() {
11984
+ "use strict";
11985
+ import_node_fs32 = require("fs");
11986
+ import_node_path32 = require("path");
11987
+ WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
11988
+ }
11989
+ });
11990
+
11935
11991
  // src/agents/cursor-stream-coalesce.ts
11936
11992
  function isTextEvent(event) {
11937
11993
  return event.type === "stdout" || event.type === "thinking";
@@ -12034,6 +12090,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
12034
12090
  const env = childEnvWithAppSettings(cmd.env);
12035
12091
  applyPromptCacheTtlEnv(thread.agent, env);
12036
12092
  applyAgentRunnerHeapEnv(env);
12093
+ if (!isOrchestratorThread(thread)) {
12094
+ applyWorktreePkgCacheEnv(env, thread.worktreePath);
12095
+ }
12037
12096
  try {
12038
12097
  if (isOrchestratorThread(thread)) {
12039
12098
  mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
@@ -12141,6 +12200,7 @@ var init_spawn = __esm({
12141
12200
  init_agents();
12142
12201
  init_orchestrator_capable();
12143
12202
  init_message_parts();
12203
+ init_worktree_pkg_cache();
12144
12204
  init_node_launch();
12145
12205
  init_path();
12146
12206
  init_usage();
@@ -13028,21 +13088,21 @@ function shouldRefreshReviewRequestTemplate(content) {
13028
13088
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
13029
13089
  }
13030
13090
  function readTextIfPresent(abs) {
13031
- if (!(0, import_node_fs32.existsSync)(abs)) return null;
13091
+ if (!(0, import_node_fs33.existsSync)(abs)) return null;
13032
13092
  try {
13033
- const content = (0, import_node_fs32.readFileSync)(abs, "utf8");
13093
+ const content = (0, import_node_fs33.readFileSync)(abs, "utf8");
13034
13094
  return content.trim() ? content : null;
13035
13095
  } catch {
13036
13096
  return null;
13037
13097
  }
13038
13098
  }
13039
13099
  function readLocalGuidelines(worktreePath) {
13040
- const localAbs = (0, import_node_path32.join)(worktreePath, REVIEW_REQUEST_PATH);
13100
+ const localAbs = (0, import_node_path33.join)(worktreePath, REVIEW_REQUEST_PATH);
13041
13101
  const localContent = readTextIfPresent(localAbs);
13042
13102
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
13043
13103
  return { path: REVIEW_REQUEST_PATH, content: localContent };
13044
13104
  }
13045
- const legacyAbs = (0, import_node_path32.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
13105
+ const legacyAbs = (0, import_node_path33.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
13046
13106
  const legacyContent = readTextIfPresent(legacyAbs);
13047
13107
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
13048
13108
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -13066,27 +13126,27 @@ function contextGuidelines(content, source) {
13066
13126
  };
13067
13127
  }
13068
13128
  function writeContextGuidelines(worktreePath, content) {
13069
- const abs = (0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH);
13070
- (0, import_node_fs32.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
13129
+ const abs = (0, import_node_path33.join)(worktreePath, CONTEXT_REVIEW_PATH);
13130
+ (0, import_node_fs33.mkdirSync)((0, import_node_path33.dirname)(abs), { recursive: true });
13071
13131
  const body = content.endsWith("\n") ? content : `${content}
13072
13132
  `;
13073
- (0, import_node_fs32.writeFileSync)(abs, body, "utf8");
13133
+ (0, import_node_fs33.writeFileSync)(abs, body, "utf8");
13074
13134
  return body;
13075
13135
  }
13076
13136
  function readSideboardReview(worktreePath, repoPath) {
13077
- const fromWorktree = readTextIfPresent((0, import_node_path32.join)(worktreePath, REPO_REVIEW_PATH));
13137
+ const fromWorktree = readTextIfPresent((0, import_node_path33.join)(worktreePath, REPO_REVIEW_PATH));
13078
13138
  if (fromWorktree) return fromWorktree;
13079
13139
  const repo = repoPath?.replace(/\/+$/, "");
13080
13140
  const wt = worktreePath.replace(/\/+$/, "");
13081
13141
  if (!repo || repo === wt) return null;
13082
- return readTextIfPresent((0, import_node_path32.join)(repo, REPO_REVIEW_PATH));
13142
+ return readTextIfPresent((0, import_node_path33.join)(repo, REPO_REVIEW_PATH));
13083
13143
  }
13084
13144
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
13085
- const skillContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_SKILL_PATH));
13145
+ const skillContent = readTextIfPresent((0, import_node_path33.join)(worktreePath, REVIEW_SKILL_PATH));
13086
13146
  if (skillContent) {
13087
13147
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
13088
13148
  }
13089
- const contextContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH));
13149
+ const contextContent = readTextIfPresent((0, import_node_path33.join)(worktreePath, CONTEXT_REVIEW_PATH));
13090
13150
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
13091
13151
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
13092
13152
  }
@@ -13141,13 +13201,13 @@ async function requestReview(threadRef, send) {
13141
13201
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
13142
13202
  return { tab: started, from };
13143
13203
  }
13144
- var import_node_crypto7, import_node_fs32, import_node_path32, 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;
13204
+ var import_node_crypto7, import_node_fs33, import_node_path33, 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;
13145
13205
  var init_request_review = __esm({
13146
13206
  "src/review/request-review.ts"() {
13147
13207
  "use strict";
13148
13208
  import_node_crypto7 = require("crypto");
13149
- import_node_fs32 = require("fs");
13150
- import_node_path32 = require("path");
13209
+ import_node_fs33 = require("fs");
13210
+ import_node_path33 = require("path");
13151
13211
  init_global_workspace();
13152
13212
  init_chat_tabs();
13153
13213
  init_thread_store();
@@ -13173,9 +13233,9 @@ function matchSimpleGlob(pattern, name) {
13173
13233
  return new RegExp(`^${escaped}$`).test(name);
13174
13234
  }
13175
13235
  function readWorktreeInclude(repoPath) {
13176
- const path = (0, import_node_path33.join)(repoPath, ".worktreeinclude");
13177
- if (!(0, import_node_fs33.existsSync)(path)) return [];
13178
- return (0, import_node_fs33.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
13236
+ const path = (0, import_node_path34.join)(repoPath, ".worktreeinclude");
13237
+ if (!(0, import_node_fs34.existsSync)(path)) return [];
13238
+ return (0, import_node_fs34.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
13179
13239
  }
13180
13240
  function resolveFilesToCopy(repoPath) {
13181
13241
  const fromInclude = readWorktreeInclude(repoPath);
@@ -13185,10 +13245,10 @@ function resolveFilesToCopy(repoPath) {
13185
13245
  if (settings?.fileIncludeGlobs?.length) {
13186
13246
  const matched = [];
13187
13247
  try {
13188
- for (const entry of (0, import_node_fs33.readdirSync)(repoPath, { withFileTypes: true })) {
13248
+ for (const entry of (0, import_node_fs34.readdirSync)(repoPath, { withFileTypes: true })) {
13189
13249
  if (!entry.isFile()) continue;
13190
13250
  for (const glob of settings.fileIncludeGlobs) {
13191
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path33.basename)(glob), entry.name)) {
13251
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path34.basename)(glob), entry.name)) {
13192
13252
  matched.push(entry.name);
13193
13253
  break;
13194
13254
  }
@@ -13200,7 +13260,7 @@ function resolveFilesToCopy(repoPath) {
13200
13260
  }
13201
13261
  const defaults = [];
13202
13262
  try {
13203
- for (const entry of (0, import_node_fs33.readdirSync)(repoPath, { withFileTypes: true })) {
13263
+ for (const entry of (0, import_node_fs34.readdirSync)(repoPath, { withFileTypes: true })) {
13204
13264
  if (entry.isFile() && entry.name.startsWith(".env")) {
13205
13265
  defaults.push(entry.name);
13206
13266
  }
@@ -13214,11 +13274,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
13214
13274
  const patterns = resolveFilesToCopy(repoPath);
13215
13275
  const copied = [];
13216
13276
  for (const rel of patterns) {
13217
- const src = (0, import_node_path33.join)(repoPath, rel);
13218
- if (!(0, import_node_fs33.existsSync)(src)) continue;
13219
- const dest = (0, import_node_path33.join)(worktreePath, rel);
13220
- (0, import_node_fs33.mkdirSync)((0, import_node_path33.dirname)(dest), { recursive: true });
13221
- (0, import_node_fs33.copyFileSync)(src, dest);
13277
+ const src = (0, import_node_path34.join)(repoPath, rel);
13278
+ if (!(0, import_node_fs34.existsSync)(src)) continue;
13279
+ const dest = (0, import_node_path34.join)(worktreePath, rel);
13280
+ (0, import_node_fs34.mkdirSync)((0, import_node_path34.dirname)(dest), { recursive: true });
13281
+ (0, import_node_fs34.copyFileSync)(src, dest);
13222
13282
  copied.push(rel);
13223
13283
  }
13224
13284
  return copied;
@@ -13253,7 +13313,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
13253
13313
  const env = stripNestedElectronEnv({
13254
13314
  ...baseEnv ?? process.env
13255
13315
  });
13256
- const name = opts.workspaceName ?? (0, import_node_path33.basename)(opts.worktreePath);
13316
+ const name = opts.workspaceName ?? (0, import_node_path34.basename)(opts.worktreePath);
13257
13317
  const ports = opts.ports ?? [];
13258
13318
  const primary = ports[0];
13259
13319
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -13276,6 +13336,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
13276
13336
  env[`CONDUCTOR_PORT_${i}`] = String(p);
13277
13337
  }
13278
13338
  }
13339
+ applyWorktreePkgCacheEnv(env, opts.worktreePath);
13279
13340
  return env;
13280
13341
  }
13281
13342
  function pipeLines(stream, onLine) {
@@ -13515,17 +13576,18 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
13515
13576
  done: handle.done
13516
13577
  };
13517
13578
  }
13518
- var import_node_fs33, import_node_net, import_node_path33, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
13579
+ var import_node_fs34, import_node_net, import_node_path34, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
13519
13580
  var init_conductor = __esm({
13520
13581
  "src/hook/conductor.ts"() {
13521
13582
  "use strict";
13522
- import_node_fs33 = require("fs");
13583
+ import_node_fs34 = require("fs");
13523
13584
  import_node_net = require("net");
13524
- import_node_path33 = require("path");
13585
+ import_node_path34 = require("path");
13525
13586
  import_execa4 = require("execa");
13526
13587
  import_node_readline3 = require("readline");
13527
13588
  init_settings();
13528
13589
  init_nested_electron_env();
13590
+ init_worktree_pkg_cache();
13529
13591
  init_convention_setup();
13530
13592
  init_cursor_worktrees();
13531
13593
  init_git_auth_mode();
@@ -13539,7 +13601,7 @@ var init_conductor = __esm({
13539
13601
 
13540
13602
  // src/store/setup-log.ts
13541
13603
  function setupLogPath(threadId) {
13542
- return (0, import_node_path34.join)(threadsDir(), `${threadId}.setup.log.json`);
13604
+ return (0, import_node_path35.join)(threadsDir(), `${threadId}.setup.log.json`);
13543
13605
  }
13544
13606
  function emptySetupLog() {
13545
13607
  return { ...EMPTY };
@@ -13556,7 +13618,7 @@ function persistNow(threadId) {
13556
13618
  const snap = memory.get(threadId);
13557
13619
  if (!snap) return;
13558
13620
  try {
13559
- (0, import_node_fs34.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
13621
+ (0, import_node_fs35.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
13560
13622
  `, "utf8");
13561
13623
  } catch {
13562
13624
  }
@@ -13573,9 +13635,9 @@ function schedulePersist(threadId) {
13573
13635
  }
13574
13636
  function loadFromDisk(threadId) {
13575
13637
  const path = setupLogPath(threadId);
13576
- if (!(0, import_node_fs34.existsSync)(path)) return null;
13638
+ if (!(0, import_node_fs35.existsSync)(path)) return null;
13577
13639
  try {
13578
- const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
13640
+ const raw = JSON.parse((0, import_node_fs35.readFileSync)(path, "utf8"));
13579
13641
  return {
13580
13642
  output: typeof raw.output === "string" ? raw.output : "",
13581
13643
  running: Boolean(raw.running),
@@ -13631,12 +13693,12 @@ function finishSetupLog(threadId, exitCode, source) {
13631
13693
  persistNow(threadId);
13632
13694
  return clone(snap);
13633
13695
  }
13634
- var import_node_fs34, import_node_path34, EMPTY, memory, persistTimers;
13696
+ var import_node_fs35, import_node_path35, EMPTY, memory, persistTimers;
13635
13697
  var init_setup_log = __esm({
13636
13698
  "src/store/setup-log.ts"() {
13637
13699
  "use strict";
13638
- import_node_fs34 = require("fs");
13639
- import_node_path34 = require("path");
13700
+ import_node_fs35 = require("fs");
13701
+ import_node_path35 = require("path");
13640
13702
  init_paths();
13641
13703
  EMPTY = {
13642
13704
  output: "",
@@ -13660,9 +13722,9 @@ async function findOrphanWorktrees(repoPaths) {
13660
13722
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
13661
13723
  );
13662
13724
  const homeRoot = sideboardWorkspacesDir();
13663
- if ((0, import_node_fs35.existsSync)(homeRoot)) {
13725
+ if ((0, import_node_fs36.existsSync)(homeRoot)) {
13664
13726
  try {
13665
- for (const entry of (0, import_node_fs35.readdirSync)(homeRoot, { withFileTypes: true })) {
13727
+ for (const entry of (0, import_node_fs36.readdirSync)(homeRoot, { withFileTypes: true })) {
13666
13728
  if (!entry.isDirectory()) continue;
13667
13729
  void entry;
13668
13730
  }
@@ -13672,7 +13734,7 @@ async function findOrphanWorktrees(repoPaths) {
13672
13734
  const orphans = [];
13673
13735
  const seen = /* @__PURE__ */ new Set();
13674
13736
  for (const repoPath of repos) {
13675
- if (!repoPath || !(0, import_node_fs35.existsSync)(repoPath)) continue;
13737
+ if (!repoPath || !(0, import_node_fs36.existsSync)(repoPath)) continue;
13676
13738
  try {
13677
13739
  const wts = await listWorktrees(repoPath);
13678
13740
  for (const wt of wts) {
@@ -13683,7 +13745,7 @@ async function findOrphanWorktrees(repoPaths) {
13683
13745
  seen.add(path);
13684
13746
  let mtimeMs = 0;
13685
13747
  try {
13686
- mtimeMs = (0, import_node_fs35.statSync)(path).mtimeMs;
13748
+ mtimeMs = (0, import_node_fs36.statSync)(path).mtimeMs;
13687
13749
  } catch {
13688
13750
  mtimeMs = 0;
13689
13751
  }
@@ -13693,16 +13755,16 @@ async function findOrphanWorktrees(repoPaths) {
13693
13755
  }
13694
13756
  try {
13695
13757
  const root = worktreesRoot(repoPath);
13696
- if ((0, import_node_fs35.existsSync)(root)) {
13697
- for (const entry of (0, import_node_fs35.readdirSync)(root, { withFileTypes: true })) {
13758
+ if ((0, import_node_fs36.existsSync)(root)) {
13759
+ for (const entry of (0, import_node_fs36.readdirSync)(root, { withFileTypes: true })) {
13698
13760
  if (!entry.isDirectory()) continue;
13699
- const path = (0, import_node_path35.join)(root, entry.name).replace(/\/$/, "");
13761
+ const path = (0, import_node_path36.join)(root, entry.name).replace(/\/$/, "");
13700
13762
  if (known.has(path) || seen.has(path)) continue;
13701
- if (!(0, import_node_fs35.existsSync)((0, import_node_path35.join)(path, ".git"))) continue;
13763
+ if (!(0, import_node_fs36.existsSync)((0, import_node_path36.join)(path, ".git"))) continue;
13702
13764
  seen.add(path);
13703
13765
  let mtimeMs = 0;
13704
13766
  try {
13705
- mtimeMs = (0, import_node_fs35.statSync)(path).mtimeMs;
13767
+ mtimeMs = (0, import_node_fs36.statSync)(path).mtimeMs;
13706
13768
  } catch {
13707
13769
  mtimeMs = Date.now();
13708
13770
  }
@@ -13754,12 +13816,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
13754
13816
  const elapsed = Date.now() - Date.parse(last);
13755
13817
  return elapsed >= intervalHours * 36e5;
13756
13818
  }
13757
- var import_node_fs35, import_node_path35;
13819
+ var import_node_fs36, import_node_path36;
13758
13820
  var init_orphan_cleanup = __esm({
13759
13821
  "src/git/orphan-cleanup.ts"() {
13760
13822
  "use strict";
13761
- import_node_fs35 = require("fs");
13762
- import_node_path35 = require("path");
13823
+ import_node_fs36 = require("fs");
13824
+ import_node_path36 = require("path");
13763
13825
  init_worktree();
13764
13826
  init_thread_store();
13765
13827
  init_paths();
@@ -13862,12 +13924,12 @@ async function cloneRepoIntoSideboard(opts) {
13862
13924
  if (!url) throw new Error("Clone URL is required");
13863
13925
  let name = opts.name?.trim();
13864
13926
  if (!name) {
13865
- const leaf = (0, import_node_path36.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
13927
+ const leaf = (0, import_node_path37.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
13866
13928
  name = leaf || "repo";
13867
13929
  }
13868
13930
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
13869
- const dest = (0, import_node_path36.join)(sideboardReposDir(), name);
13870
- if ((0, import_node_fs36.existsSync)(dest)) {
13931
+ const dest = (0, import_node_path37.join)(sideboardReposDir(), name);
13932
+ if ((0, import_node_fs37.existsSync)(dest)) {
13871
13933
  const repoPath2 = await resolveRepoRoot(dest);
13872
13934
  const workspace2 = await ensureWorkspace(repoPath2);
13873
13935
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -13882,12 +13944,12 @@ async function cloneRepoIntoSideboard(opts) {
13882
13944
  const workspace = await ensureWorkspace(repoPath);
13883
13945
  return { repoPath, workspace };
13884
13946
  }
13885
- var import_node_fs36, import_node_path36, import_execa6;
13947
+ var import_node_fs37, import_node_path37, import_execa6;
13886
13948
  var init_clone_repo = __esm({
13887
13949
  "src/git/clone-repo.ts"() {
13888
13950
  "use strict";
13889
- import_node_fs36 = require("fs");
13890
- import_node_path36 = require("path");
13951
+ import_node_fs37 = require("fs");
13952
+ import_node_path37 = require("path");
13891
13953
  import_execa6 = require("execa");
13892
13954
  init_paths();
13893
13955
  init_workspaces2();
@@ -13897,11 +13959,11 @@ var init_clone_repo = __esm({
13897
13959
 
13898
13960
  // src/store/desktop-host.ts
13899
13961
  function desktopHostPidPath() {
13900
- return (0, import_node_path37.join)(appDataDir(), "desktop-host.pid");
13962
+ return (0, import_node_path38.join)(appDataDir(), "desktop-host.pid");
13901
13963
  }
13902
13964
  function readDesktopHostPid() {
13903
13965
  try {
13904
- const pid = Number.parseInt((0, import_node_fs37.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
13966
+ const pid = Number.parseInt((0, import_node_fs38.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
13905
13967
  if (!Number.isFinite(pid) || pid <= 0) return null;
13906
13968
  return pid;
13907
13969
  } catch {
@@ -13927,12 +13989,12 @@ function thisProcessShouldDrainAgentQueues() {
13927
13989
  if (isThisProcessDesktopHost()) return true;
13928
13990
  return !isDesktopHostAlive();
13929
13991
  }
13930
- var import_node_fs37, import_node_path37;
13992
+ var import_node_fs38, import_node_path38;
13931
13993
  var init_desktop_host = __esm({
13932
13994
  "src/store/desktop-host.ts"() {
13933
13995
  "use strict";
13934
- import_node_fs37 = require("fs");
13935
- import_node_path37 = require("path");
13996
+ import_node_fs38 = require("fs");
13997
+ import_node_path38 = require("path");
13936
13998
  init_paths();
13937
13999
  }
13938
14000
  });
@@ -14047,24 +14109,24 @@ function jobTreeAlive(pid) {
14047
14109
  return jobAlive(pid) || processGroupAlive(pid);
14048
14110
  }
14049
14111
  function readIntFile(file) {
14050
- if (!(0, import_node_fs38.existsSync)(file)) return null;
14051
- const n = Number.parseInt((0, import_node_fs38.readFileSync)(file, "utf8").trim(), 10);
14112
+ if (!(0, import_node_fs39.existsSync)(file)) return null;
14113
+ const n = Number.parseInt((0, import_node_fs39.readFileSync)(file, "utf8").trim(), 10);
14052
14114
  return Number.isInteger(n) ? n : null;
14053
14115
  }
14054
14116
  function jobDir(root, id, legacy = false) {
14055
- return (0, import_node_path38.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
14117
+ return (0, import_node_path39.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
14056
14118
  }
14057
14119
  function resolveJobDir(root, id) {
14058
14120
  const modern = jobDir(root, id, false);
14059
- if ((0, import_node_fs38.existsSync)(modern)) return modern;
14121
+ if ((0, import_node_fs39.existsSync)(modern)) return modern;
14060
14122
  const legacy = jobDir(root, id, true);
14061
- if ((0, import_node_fs38.existsSync)(legacy)) return legacy;
14123
+ if ((0, import_node_fs39.existsSync)(legacy)) return legacy;
14062
14124
  return modern;
14063
14125
  }
14064
14126
  function listJobIdsIn(root, rel) {
14065
- const dir = (0, import_node_path38.join)(root, rel);
14066
- if (!(0, import_node_fs38.existsSync)(dir)) return [];
14067
- return (0, import_node_fs38.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
14127
+ const dir = (0, import_node_path39.join)(root, rel);
14128
+ if (!(0, import_node_fs39.existsSync)(dir)) return [];
14129
+ return (0, import_node_fs39.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
14068
14130
  }
14069
14131
  function listRunningDetachedJobs(worktreePath) {
14070
14132
  const root = worktreePath.trim();
@@ -14076,7 +14138,7 @@ function listRunningDetachedJobs(worktreePath) {
14076
14138
  const running = [];
14077
14139
  for (const id of ids) {
14078
14140
  const dir = resolveJobDir(root, id);
14079
- const pid = readIntFile((0, import_node_path38.join)(dir, "pid"));
14141
+ const pid = readIntFile((0, import_node_path39.join)(dir, "pid"));
14080
14142
  if (pid != null && jobAlive(pid)) running.push(id);
14081
14143
  }
14082
14144
  return running.sort();
@@ -14129,13 +14191,13 @@ function planJobContinue(opts) {
14129
14191
  return { action: "none" };
14130
14192
  }
14131
14193
  function tailProgress(logFile, maxLines = 12) {
14132
- if (!(0, import_node_fs38.existsSync)(logFile)) return "(no log yet)";
14133
- const lines = (0, import_node_fs38.readFileSync)(logFile, "utf8").split("\n");
14194
+ if (!(0, import_node_fs39.existsSync)(logFile)) return "(no log yet)";
14195
+ const lines = (0, import_node_fs39.readFileSync)(logFile, "utf8").split("\n");
14134
14196
  return lines.slice(-maxLines).join("\n");
14135
14197
  }
14136
14198
  function readLogLines(file) {
14137
- if (!(0, import_node_fs38.existsSync)(file)) return [];
14138
- const lines = (0, import_node_fs38.readFileSync)(file, "utf8").split("\n");
14199
+ if (!(0, import_node_fs39.existsSync)(file)) return [];
14200
+ const lines = (0, import_node_fs39.readFileSync)(file, "utf8").split("\n");
14139
14201
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
14140
14202
  return lines;
14141
14203
  }
@@ -14146,15 +14208,15 @@ function takeDelta(logFile, cursorFile) {
14146
14208
  return { delta: lines.slice(start).join("\n"), nextCursor: lines.length };
14147
14209
  }
14148
14210
  function snapshotJob(dir) {
14149
- const pid = readIntFile((0, import_node_path38.join)(dir, "pid"));
14211
+ const pid = readIntFile((0, import_node_path39.join)(dir, "pid"));
14150
14212
  const running = jobTreeAlive(pid);
14151
14213
  return {
14152
14214
  pid,
14153
14215
  running,
14154
- exitCode: readIntFile((0, import_node_path38.join)(dir, "exit")),
14155
- log: (0, import_node_path38.join)(dir, "log"),
14156
- cursor: (0, import_node_path38.join)(dir, "present.cursor"),
14157
- progress: tailProgress((0, import_node_path38.join)(dir, "log"))
14216
+ exitCode: readIntFile((0, import_node_path39.join)(dir, "exit")),
14217
+ log: (0, import_node_path39.join)(dir, "log"),
14218
+ cursor: (0, import_node_path39.join)(dir, "present.cursor"),
14219
+ progress: tailProgress((0, import_node_path39.join)(dir, "log"))
14158
14220
  };
14159
14221
  }
14160
14222
  function toResult(id, snap, extra) {
@@ -14163,8 +14225,8 @@ function toResult(id, snap, extra) {
14163
14225
  const stillRunning = snap.running && !ok;
14164
14226
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
14165
14227
  try {
14166
- (0, import_node_fs38.mkdirSync)((0, import_node_path38.dirname)(snap.cursor), { recursive: true });
14167
- (0, import_node_fs38.writeFileSync)(snap.cursor, `${nextCursor}
14228
+ (0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(snap.cursor), { recursive: true });
14229
+ (0, import_node_fs39.writeFileSync)(snap.cursor, `${nextCursor}
14168
14230
  `);
14169
14231
  } catch {
14170
14232
  }
@@ -14191,7 +14253,7 @@ async function waitForDetachedJob(cwd, id, opts) {
14191
14253
  const dir = resolveJobDir(root, jobId);
14192
14254
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
14193
14255
  const sleep = opts?.sleep ?? sleepMs;
14194
- if (!(0, import_node_fs38.existsSync)(dir)) {
14256
+ if (!(0, import_node_fs39.existsSync)(dir)) {
14195
14257
  return {
14196
14258
  stillRunning: false,
14197
14259
  ok: false,
@@ -14237,10 +14299,10 @@ function killProcessTree(pid, signal) {
14237
14299
  }
14238
14300
  function appendJobLog(logFile, line) {
14239
14301
  try {
14240
- (0, import_node_fs38.mkdirSync)((0, import_node_path38.dirname)(logFile), { recursive: true });
14302
+ (0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(logFile), { recursive: true });
14241
14303
  const body = line.endsWith("\n") ? line : `${line}
14242
14304
  `;
14243
- (0, import_node_fs38.appendFileSync)(logFile, body);
14305
+ (0, import_node_fs39.appendFileSync)(logFile, body);
14244
14306
  } catch {
14245
14307
  }
14246
14308
  }
@@ -14250,7 +14312,7 @@ async function stopDetachedJob(cwd, id, opts) {
14250
14312
  const dir = resolveJobDir(root, jobId);
14251
14313
  const sleep = opts?.sleep ?? sleepMs;
14252
14314
  const why = opts?.reason?.trim() ?? "";
14253
- if (!(0, import_node_fs38.existsSync)(dir)) {
14315
+ if (!(0, import_node_fs39.existsSync)(dir)) {
14254
14316
  return {
14255
14317
  stillRunning: false,
14256
14318
  ok: false,
@@ -14286,10 +14348,10 @@ async function stopDetachedJob(cwd, id, opts) {
14286
14348
  killProcessTree(targetPid, "SIGKILL");
14287
14349
  await sleep(100);
14288
14350
  }
14289
- const exitFile = (0, import_node_path38.join)(dir, "exit");
14290
- if (!(0, import_node_fs38.existsSync)(exitFile)) {
14351
+ const exitFile = (0, import_node_path39.join)(dir, "exit");
14352
+ if (!(0, import_node_fs39.existsSync)(exitFile)) {
14291
14353
  try {
14292
- (0, import_node_fs38.writeFileSync)(exitFile, "1\n");
14354
+ (0, import_node_fs39.writeFileSync)(exitFile, "1\n");
14293
14355
  } catch {
14294
14356
  }
14295
14357
  }
@@ -14309,12 +14371,12 @@ async function stopDetachedJob(cwd, id, opts) {
14309
14371
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
14310
14372
  };
14311
14373
  }
14312
- var import_node_fs38, import_node_path38, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
14374
+ var import_node_fs39, import_node_path39, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
14313
14375
  var init_wait_for_job = __esm({
14314
14376
  "src/mcp/wait-for-job.ts"() {
14315
14377
  "use strict";
14316
- import_node_fs38 = require("fs");
14317
- import_node_path38 = require("path");
14378
+ import_node_fs39 = require("fs");
14379
+ import_node_path39 = require("path");
14318
14380
  init_workspace_scratch();
14319
14381
  init_wait_for_turn();
14320
14382
  MAX_JOB_CONTINUES = 8;
@@ -15409,7 +15471,7 @@ function reuseLiveThread(input, repoPath, match) {
15409
15471
  }
15410
15472
  async function createThread(input, _onSetupLine) {
15411
15473
  const repoPath = await resolveRepoRoot(input.repoPath);
15412
- if (!(0, import_node_fs39.existsSync)(repoPath)) {
15474
+ if (!(0, import_node_fs40.existsSync)(repoPath)) {
15413
15475
  throw new Error(`Repo not found: ${repoPath}`);
15414
15476
  }
15415
15477
  const reused = reuseLiveThread(input, repoPath, {
@@ -15581,11 +15643,11 @@ async function createThread(input, _onSetupLine) {
15581
15643
  await ensureWorkspace(repoPath);
15582
15644
  return readThread(thread.id) ?? thread;
15583
15645
  }
15584
- var import_node_fs39;
15646
+ var import_node_fs40;
15585
15647
  var init_create = __esm({
15586
15648
  "src/threads/create.ts"() {
15587
15649
  "use strict";
15588
- import_node_fs39 = require("fs");
15650
+ import_node_fs40 = require("fs");
15589
15651
  init_detect();
15590
15652
  init_worktree();
15591
15653
  init_home_board();
@@ -15705,20 +15767,20 @@ function writeTurnLive(threadId, progress) {
15705
15767
  const path = threadLivePath(threadId);
15706
15768
  const tmp = `${path}.${process.pid}.tmp`;
15707
15769
  try {
15708
- (0, import_node_fs40.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
15709
- (0, import_node_fs40.renameSync)(tmp, path);
15770
+ (0, import_node_fs41.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
15771
+ (0, import_node_fs41.renameSync)(tmp, path);
15710
15772
  } catch {
15711
15773
  try {
15712
- (0, import_node_fs40.unlinkSync)(tmp);
15774
+ (0, import_node_fs41.unlinkSync)(tmp);
15713
15775
  } catch {
15714
15776
  }
15715
15777
  }
15716
15778
  }
15717
15779
  function readTurnLive(threadId) {
15718
15780
  const path = threadLivePath(threadId);
15719
- if (!(0, import_node_fs40.existsSync)(path)) return null;
15781
+ if (!(0, import_node_fs41.existsSync)(path)) return null;
15720
15782
  try {
15721
- const raw = JSON.parse((0, import_node_fs40.readFileSync)(path, "utf8"));
15783
+ const raw = JSON.parse((0, import_node_fs41.readFileSync)(path, "utf8"));
15722
15784
  if (!raw || typeof raw.summary !== "string") return null;
15723
15785
  return raw;
15724
15786
  } catch {
@@ -15730,17 +15792,17 @@ function clearTurnLive(threadId) {
15730
15792
  if (buf?.timer) clearTimeout(buf.timer);
15731
15793
  buffers.delete(threadId);
15732
15794
  const path = threadLivePath(threadId);
15733
- if (!(0, import_node_fs40.existsSync)(path)) return;
15795
+ if (!(0, import_node_fs41.existsSync)(path)) return;
15734
15796
  try {
15735
- (0, import_node_fs40.unlinkSync)(path);
15797
+ (0, import_node_fs41.unlinkSync)(path);
15736
15798
  } catch {
15737
15799
  }
15738
15800
  }
15739
- var import_node_fs40, buffers, FLUSH_MS, MAX_PARTS;
15801
+ var import_node_fs41, buffers, FLUSH_MS, MAX_PARTS;
15740
15802
  var init_turn_live = __esm({
15741
15803
  "src/store/turn-live.ts"() {
15742
15804
  "use strict";
15743
- import_node_fs40 = require("fs");
15805
+ import_node_fs41 = require("fs");
15744
15806
  init_message_parts();
15745
15807
  init_paths();
15746
15808
  buffers = /* @__PURE__ */ new Map();
@@ -15957,7 +16019,7 @@ var init_quota_failover = __esm({
15957
16019
  // src/threads/adopt.ts
15958
16020
  function thisModuleFile() {
15959
16021
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
15960
- return cjsFile || process.argv[1] || (0, import_node_path39.join)(process.cwd(), "package.json");
16022
+ return cjsFile || process.argv[1] || (0, import_node_path40.join)(process.cwd(), "package.json");
15961
16023
  }
15962
16024
  function openReadonlySqlite(file) {
15963
16025
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -15975,21 +16037,21 @@ function mapAgentType(raw) {
15975
16037
  return null;
15976
16038
  }
15977
16039
  function resolveConductorCursorAgentId(workspacePath) {
15978
- if (!workspacePath || !(0, import_node_fs41.existsSync)(CURSOR_SDK_STORE)) return null;
16040
+ if (!workspacePath || !(0, import_node_fs42.existsSync)(CURSOR_SDK_STORE)) return null;
15979
16041
  const normalized = workspacePath.replace(/\/$/, "");
15980
16042
  let best = null;
15981
16043
  let hashes;
15982
16044
  try {
15983
- hashes = (0, import_node_fs41.readdirSync)(CURSOR_SDK_STORE);
16045
+ hashes = (0, import_node_fs42.readdirSync)(CURSOR_SDK_STORE);
15984
16046
  } catch {
15985
16047
  return null;
15986
16048
  }
15987
16049
  for (const hash of hashes) {
15988
- const agentsFile = (0, import_node_path39.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
15989
- if (!(0, import_node_fs41.existsSync)(agentsFile)) continue;
16050
+ const agentsFile = (0, import_node_path40.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
16051
+ if (!(0, import_node_fs42.existsSync)(agentsFile)) continue;
15990
16052
  let text7;
15991
16053
  try {
15992
- text7 = (0, import_node_fs41.readFileSync)(agentsFile, "utf8");
16054
+ text7 = (0, import_node_fs42.readFileSync)(agentsFile, "utf8");
15993
16055
  } catch {
15994
16056
  continue;
15995
16057
  }
@@ -16013,7 +16075,7 @@ function resolveConductorCursorAgentId(workspacePath) {
16013
16075
  return best?.agentId ?? null;
16014
16076
  }
16015
16077
  async function adoptThread(input) {
16016
- if (!(0, import_node_fs41.existsSync)(input.worktreePath)) {
16078
+ if (!(0, import_node_fs42.existsSync)(input.worktreePath)) {
16017
16079
  throw new Error(`Worktree not found: ${input.worktreePath}`);
16018
16080
  }
16019
16081
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -16039,18 +16101,18 @@ async function adoptThread(input) {
16039
16101
  return thread;
16040
16102
  }
16041
16103
  function listConductorWorkspaces() {
16042
- if (!(0, import_node_fs41.existsSync)(CONDUCTOR_DB)) {
16104
+ if (!(0, import_node_fs42.existsSync)(CONDUCTOR_DB)) {
16043
16105
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
16044
16106
  }
16045
- const tmp = (0, import_node_fs41.mkdtempSync)((0, import_node_path39.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16046
- const snapshot = (0, import_node_path39.join)(tmp, "conductor.db");
16107
+ const tmp = (0, import_node_fs42.mkdtempSync)((0, import_node_path40.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16108
+ const snapshot = (0, import_node_path40.join)(tmp, "conductor.db");
16047
16109
  try {
16048
- (0, import_node_fs41.copyFileSync)(CONDUCTOR_DB, snapshot);
16110
+ (0, import_node_fs42.copyFileSync)(CONDUCTOR_DB, snapshot);
16049
16111
  for (const suffix of ["-wal", "-shm"]) {
16050
16112
  const src = `${CONDUCTOR_DB}${suffix}`;
16051
- if ((0, import_node_fs41.existsSync)(src)) {
16113
+ if ((0, import_node_fs42.existsSync)(src)) {
16052
16114
  try {
16053
- (0, import_node_fs41.copyFileSync)(src, `${snapshot}${suffix}`);
16115
+ (0, import_node_fs42.copyFileSync)(src, `${snapshot}${suffix}`);
16054
16116
  } catch {
16055
16117
  }
16056
16118
  }
@@ -16126,22 +16188,22 @@ function listConductorWorkspaces() {
16126
16188
  db.close();
16127
16189
  }
16128
16190
  } finally {
16129
- (0, import_node_fs41.rmSync)(tmp, { recursive: true, force: true });
16191
+ (0, import_node_fs42.rmSync)(tmp, { recursive: true, force: true });
16130
16192
  }
16131
16193
  }
16132
16194
  function importConductorWorkspace(workspaceId) {
16133
- if (!(0, import_node_fs41.existsSync)(CONDUCTOR_DB)) {
16195
+ if (!(0, import_node_fs42.existsSync)(CONDUCTOR_DB)) {
16134
16196
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
16135
16197
  }
16136
- const tmp = (0, import_node_fs41.mkdtempSync)((0, import_node_path39.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16137
- const snapshot = (0, import_node_path39.join)(tmp, "conductor.db");
16198
+ const tmp = (0, import_node_fs42.mkdtempSync)((0, import_node_path40.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16199
+ const snapshot = (0, import_node_path40.join)(tmp, "conductor.db");
16138
16200
  try {
16139
- (0, import_node_fs41.copyFileSync)(CONDUCTOR_DB, snapshot);
16201
+ (0, import_node_fs42.copyFileSync)(CONDUCTOR_DB, snapshot);
16140
16202
  for (const suffix of ["-wal", "-shm"]) {
16141
16203
  const src = `${CONDUCTOR_DB}${suffix}`;
16142
- if ((0, import_node_fs41.existsSync)(src)) {
16204
+ if ((0, import_node_fs42.existsSync)(src)) {
16143
16205
  try {
16144
- (0, import_node_fs41.copyFileSync)(src, `${snapshot}${suffix}`);
16206
+ (0, import_node_fs42.copyFileSync)(src, `${snapshot}${suffix}`);
16145
16207
  } catch {
16146
16208
  }
16147
16209
  }
@@ -16159,7 +16221,7 @@ function importConductorWorkspace(workspaceId) {
16159
16221
  ).get(workspaceId);
16160
16222
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
16161
16223
  const worktreePath = String(row.workspacePath);
16162
- if (!(0, import_node_fs41.existsSync)(worktreePath)) {
16224
+ if (!(0, import_node_fs42.existsSync)(worktreePath)) {
16163
16225
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
16164
16226
  }
16165
16227
  let sessionId = null;
@@ -16222,31 +16284,31 @@ function importConductorWorkspace(workspaceId) {
16222
16284
  db.close();
16223
16285
  }
16224
16286
  } finally {
16225
- (0, import_node_fs41.rmSync)(tmp, { recursive: true, force: true });
16287
+ (0, import_node_fs42.rmSync)(tmp, { recursive: true, force: true });
16226
16288
  }
16227
16289
  }
16228
16290
  async function importConductorWorkspaceAsync(workspaceId) {
16229
16291
  return importConductorWorkspace(workspaceId);
16230
16292
  }
16231
- var import_node_child_process3, import_node_fs41, import_node_os13, import_node_path39, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
16293
+ var import_node_child_process3, import_node_fs42, import_node_os13, import_node_path40, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
16232
16294
  var init_adopt = __esm({
16233
16295
  "src/threads/adopt.ts"() {
16234
16296
  "use strict";
16235
16297
  import_node_child_process3 = require("child_process");
16236
- import_node_fs41 = require("fs");
16298
+ import_node_fs42 = require("fs");
16237
16299
  import_node_os13 = require("os");
16238
- import_node_path39 = require("path");
16300
+ import_node_path40 = require("path");
16239
16301
  import_node_module4 = require("module");
16240
16302
  init_worktree();
16241
16303
  init_thread_store();
16242
- CONDUCTOR_APP_SUPPORT = (0, import_node_path39.join)(
16304
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path40.join)(
16243
16305
  process.env.HOME ?? "",
16244
16306
  "Library",
16245
16307
  "Application Support",
16246
16308
  "com.conductor.app"
16247
16309
  );
16248
- CONDUCTOR_DB = (0, import_node_path39.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
16249
- CURSOR_SDK_STORE = (0, import_node_path39.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
16310
+ CONDUCTOR_DB = (0, import_node_path40.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
16311
+ CURSOR_SDK_STORE = (0, import_node_path40.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
16250
16312
  }
16251
16313
  });
16252
16314
 
@@ -16313,7 +16375,7 @@ async function openStackLayer(input, _onSetupLine) {
16313
16375
  let createdWorktree = false;
16314
16376
  const trees = await listWorktrees(repoPath);
16315
16377
  const checkedOut = trees.find((w) => w.branch === branchName);
16316
- if (checkedOut?.path && (0, import_node_fs42.existsSync)(checkedOut.path)) {
16378
+ if (checkedOut?.path && (0, import_node_fs43.existsSync)(checkedOut.path)) {
16317
16379
  if (input.reuseExistingWorktree !== false) {
16318
16380
  worktreePath = checkedOut.path;
16319
16381
  } else {
@@ -16455,7 +16517,7 @@ async function initStackFromThread(input, onSetupLine) {
16455
16517
  async function createPrStack(input, onSetupLine) {
16456
16518
  await requireAgent(input.agent);
16457
16519
  const repoPath = await resolveRepoRoot(input.repoPath);
16458
- if (!(0, import_node_fs42.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
16520
+ if (!(0, import_node_fs43.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
16459
16521
  if (!input.branches.length) throw new Error("At least one branch name required");
16460
16522
  const status = await detectGhStack(repoPath);
16461
16523
  if (!status.available) throw new Error(status.reason);
@@ -16522,7 +16584,7 @@ async function createPrStack(input, onSetupLine) {
16522
16584
  }
16523
16585
  }
16524
16586
  const claimed = new Set(threads.map((t) => t.worktreePath));
16525
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs42.existsSync)(bootstrap.worktreePath)) {
16587
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs43.existsSync)(bootstrap.worktreePath)) {
16526
16588
  try {
16527
16589
  await removeWorktree(repoPath, bootstrap.worktreePath, {
16528
16590
  deleteBranch: bootstrap.branchName
@@ -16532,11 +16594,11 @@ async function createPrStack(input, onSetupLine) {
16532
16594
  }
16533
16595
  return { stack, threads, createdThreadIds };
16534
16596
  }
16535
- var import_node_fs42;
16597
+ var import_node_fs43;
16536
16598
  var init_stack_layers = __esm({
16537
16599
  "src/threads/stack-layers.ts"() {
16538
16600
  "use strict";
16539
- import_node_fs42 = require("fs");
16601
+ import_node_fs43 = require("fs");
16540
16602
  init_detect();
16541
16603
  init_run();
16542
16604
  init_stack();
@@ -16549,7 +16611,7 @@ var init_stack_layers = __esm({
16549
16611
 
16550
16612
  // src/diff/diff.ts
16551
16613
  async function inspectGitWorktree(worktreePath) {
16552
- if (!worktreePath || !(0, import_node_fs43.existsSync)(worktreePath)) return "missing_worktree";
16614
+ if (!worktreePath || !(0, import_node_fs44.existsSync)(worktreePath)) return "missing_worktree";
16553
16615
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
16554
16616
  reject: false
16555
16617
  });
@@ -16557,7 +16619,7 @@ async function inspectGitWorktree(worktreePath) {
16557
16619
  return "ok";
16558
16620
  }
16559
16621
  async function initializeGitRepository(worktreePath) {
16560
- if (!worktreePath || !(0, import_node_fs43.existsSync)(worktreePath)) {
16622
+ if (!worktreePath || !(0, import_node_fs44.existsSync)(worktreePath)) {
16561
16623
  throw new Error("Worktree not found");
16562
16624
  }
16563
16625
  const status = await inspectGitWorktree(worktreePath);
@@ -16691,11 +16753,11 @@ new file mode 100644
16691
16753
  };
16692
16754
  }
16693
16755
  async function untrackedPatch(worktreePath, path, maxHunk) {
16694
- const abs = (0, import_node_path40.join)(worktreePath, path);
16756
+ const abs = (0, import_node_path41.join)(worktreePath, path);
16695
16757
  try {
16696
- const st = (0, import_node_fs43.statSync)(abs);
16758
+ const st = (0, import_node_fs44.statSync)(abs);
16697
16759
  if (st.isFile() && st.size > maxHunk) {
16698
- const buf = (0, import_node_fs43.readFileSync)(abs).subarray(0, maxHunk);
16760
+ const buf = (0, import_node_fs44.readFileSync)(abs).subarray(0, maxHunk);
16699
16761
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
16700
16762
  }
16701
16763
  } catch {
@@ -17184,8 +17246,8 @@ function isImageRelativePath(relativePath) {
17184
17246
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17185
17247
  assertSafeRelativePath(relativePath);
17186
17248
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
17187
- const abs = (0, import_node_path40.join)(worktreePath, relativePath);
17188
- const st = (0, import_node_fs43.statSync)(abs);
17249
+ const abs = (0, import_node_path41.join)(worktreePath, relativePath);
17250
+ const st = (0, import_node_fs44.statSync)(abs);
17189
17251
  if (!st.isFile()) {
17190
17252
  throw new Error(`Not a file: ${relativePath}`);
17191
17253
  }
@@ -17194,7 +17256,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17194
17256
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
17195
17257
  );
17196
17258
  }
17197
- const buf = (0, import_node_fs43.readFileSync)(abs);
17259
+ const buf = (0, import_node_fs44.readFileSync)(abs);
17198
17260
  return {
17199
17261
  path: relativePath,
17200
17262
  contentBase64: buf.toString("base64"),
@@ -17204,12 +17266,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17204
17266
  function readWorktreeFile(worktreePath, relativePath, opts) {
17205
17267
  assertSafeRelativePath(relativePath);
17206
17268
  const maxBytes = opts?.maxBytes ?? 2e5;
17207
- const abs = (0, import_node_path40.join)(worktreePath, relativePath);
17208
- const st = (0, import_node_fs43.statSync)(abs);
17269
+ const abs = (0, import_node_path41.join)(worktreePath, relativePath);
17270
+ const st = (0, import_node_fs44.statSync)(abs);
17209
17271
  if (!st.isFile()) {
17210
17272
  throw new Error(`Not a file: ${relativePath}`);
17211
17273
  }
17212
- const buf = (0, import_node_fs43.readFileSync)(abs);
17274
+ const buf = (0, import_node_fs44.readFileSync)(abs);
17213
17275
  if (isImageRelativePath(relativePath)) {
17214
17276
  const maxImageBytes = Math.max(maxBytes, 15e6);
17215
17277
  const truncated2 = buf.length > maxImageBytes;
@@ -17252,9 +17314,9 @@ function assertSafeRelativePath(relativePath) {
17252
17314
  }
17253
17315
  function writeWorktreeFile(worktreePath, relativePath, content) {
17254
17316
  assertSafeRelativePath(relativePath);
17255
- const abs = (0, import_node_path40.join)(worktreePath, relativePath);
17256
- (0, import_node_fs43.mkdirSync)((0, import_node_path40.dirname)(abs), { recursive: true });
17257
- (0, import_node_fs43.writeFileSync)(abs, content, "utf8");
17317
+ const abs = (0, import_node_path41.join)(worktreePath, relativePath);
17318
+ (0, import_node_fs44.mkdirSync)((0, import_node_path41.dirname)(abs), { recursive: true });
17319
+ (0, import_node_fs44.writeFileSync)(abs, content, "utf8");
17258
17320
  return { path: relativePath };
17259
17321
  }
17260
17322
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -17271,12 +17333,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
17271
17333
  truncated: full.files.length > maxFiles
17272
17334
  };
17273
17335
  }
17274
- var import_node_fs43, import_node_path40, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
17336
+ var import_node_fs44, import_node_path41, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
17275
17337
  var init_diff = __esm({
17276
17338
  "src/diff/diff.ts"() {
17277
17339
  "use strict";
17278
- import_node_fs43 = require("fs");
17279
- import_node_path40 = require("path");
17340
+ import_node_fs44 = require("fs");
17341
+ import_node_path41 = require("path");
17280
17342
  init_run();
17281
17343
  init_worktree();
17282
17344
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -17552,7 +17614,7 @@ function parseFrontmatter(content) {
17552
17614
  }
17553
17615
  function readSkill(skillMd, source) {
17554
17616
  try {
17555
- const content = (0, import_node_fs44.readFileSync)(skillMd, "utf8");
17617
+ const content = (0, import_node_fs45.readFileSync)(skillMd, "utf8");
17556
17618
  const { name: fmName, description } = parseFrontmatter(content);
17557
17619
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
17558
17620
  const name = fmName || dirName;
@@ -17571,19 +17633,19 @@ function readSkill(skillMd, source) {
17571
17633
  }
17572
17634
  }
17573
17635
  function scanSkillsDir(dir, source, out) {
17574
- if (!(0, import_node_fs44.existsSync)(dir)) return;
17636
+ if (!(0, import_node_fs45.existsSync)(dir)) return;
17575
17637
  let entries;
17576
17638
  try {
17577
- entries = (0, import_node_fs44.readdirSync)(dir);
17639
+ entries = (0, import_node_fs45.readdirSync)(dir);
17578
17640
  } catch {
17579
17641
  return;
17580
17642
  }
17581
17643
  for (const entry of entries) {
17582
17644
  if (entry.startsWith(".")) continue;
17583
- const skillMd = (0, import_node_path41.join)(dir, entry, "SKILL.md");
17584
- if (!(0, import_node_fs44.existsSync)(skillMd)) continue;
17645
+ const skillMd = (0, import_node_path42.join)(dir, entry, "SKILL.md");
17646
+ if (!(0, import_node_fs45.existsSync)(skillMd)) continue;
17585
17647
  try {
17586
- if (!(0, import_node_fs44.statSync)(skillMd).isFile()) continue;
17648
+ if (!(0, import_node_fs45.statSync)(skillMd).isFile()) continue;
17587
17649
  } catch {
17588
17650
  continue;
17589
17651
  }
@@ -17592,24 +17654,24 @@ function scanSkillsDir(dir, source, out) {
17592
17654
  }
17593
17655
  }
17594
17656
  function scanClaudePluginSkills(pluginsRoot, out) {
17595
- if (!(0, import_node_fs44.existsSync)(pluginsRoot)) return;
17657
+ if (!(0, import_node_fs45.existsSync)(pluginsRoot)) return;
17596
17658
  const walk = (dir, depth, lookingForSkillsDir) => {
17597
17659
  if (depth > 7) return;
17598
17660
  let entries;
17599
17661
  try {
17600
- entries = (0, import_node_fs44.readdirSync)(dir);
17662
+ entries = (0, import_node_fs45.readdirSync)(dir);
17601
17663
  } catch {
17602
17664
  return;
17603
17665
  }
17604
17666
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
17605
- const skill = readSkill((0, import_node_path41.join)(dir, "SKILL.md"), "cli");
17667
+ const skill = readSkill((0, import_node_path42.join)(dir, "SKILL.md"), "cli");
17606
17668
  if (skill) out.push(skill);
17607
17669
  }
17608
17670
  for (const entry of entries) {
17609
17671
  if (entry === "node_modules" || entry === ".git") continue;
17610
- const full = (0, import_node_path41.join)(dir, entry);
17672
+ const full = (0, import_node_path42.join)(dir, entry);
17611
17673
  try {
17612
- if (!(0, import_node_fs44.statSync)(full).isDirectory()) continue;
17674
+ if (!(0, import_node_fs45.statSync)(full).isDirectory()) continue;
17613
17675
  } catch {
17614
17676
  continue;
17615
17677
  }
@@ -17627,17 +17689,17 @@ function discoverSkills(worktreePath) {
17627
17689
  const home = (0, import_node_os14.homedir)();
17628
17690
  const collected = [];
17629
17691
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
17630
- scanSkillsDir((0, import_node_path41.join)(worktreePath, rel), "workspace", collected);
17692
+ scanSkillsDir((0, import_node_path42.join)(worktreePath, rel), "workspace", collected);
17631
17693
  }
17632
17694
  for (const abs of [
17633
- (0, import_node_path41.join)(home, ".claude/skills"),
17634
- (0, import_node_path41.join)(home, ".cursor/skills"),
17635
- (0, import_node_path41.join)(home, ".sideboard/skills"),
17636
- (0, import_node_path41.join)(home, ".brightsy/skills")
17695
+ (0, import_node_path42.join)(home, ".claude/skills"),
17696
+ (0, import_node_path42.join)(home, ".cursor/skills"),
17697
+ (0, import_node_path42.join)(home, ".sideboard/skills"),
17698
+ (0, import_node_path42.join)(home, ".brightsy/skills")
17637
17699
  ]) {
17638
17700
  scanSkillsDir(abs, "user", collected);
17639
17701
  }
17640
- scanClaudePluginSkills((0, import_node_path41.join)(home, ".claude/plugins"), collected);
17702
+ scanClaudePluginSkills((0, import_node_path42.join)(home, ".claude/plugins"), collected);
17641
17703
  collected.push(...bundledSkills());
17642
17704
  const rank = {
17643
17705
  workspace: 0,
@@ -17663,7 +17725,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
17663
17725
  \u2026(truncated)` : body;
17664
17726
  }
17665
17727
  }
17666
- const raw = (0, import_node_fs44.readFileSync)(skillPath, "utf8");
17728
+ const raw = (0, import_node_fs45.readFileSync)(skillPath, "utf8");
17667
17729
  if (raw.startsWith("---")) {
17668
17730
  const end = raw.indexOf("\n---", 3);
17669
17731
  if (end >= 0) {
@@ -17677,13 +17739,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
17677
17739
 
17678
17740
  \u2026(truncated)` : raw;
17679
17741
  }
17680
- var import_node_fs44, import_node_os14, import_node_path41, BUNDLED_SKILL_PREFIX;
17742
+ var import_node_fs45, import_node_os14, import_node_path42, BUNDLED_SKILL_PREFIX;
17681
17743
  var init_discover = __esm({
17682
17744
  "src/skills/discover.ts"() {
17683
17745
  "use strict";
17684
- import_node_fs44 = require("fs");
17746
+ import_node_fs45 = require("fs");
17685
17747
  import_node_os14 = require("os");
17686
- import_node_path41 = require("path");
17748
+ import_node_path42 = require("path");
17687
17749
  init_long_running();
17688
17750
  BUNDLED_SKILL_PREFIX = "bundled:";
17689
17751
  }
@@ -17777,8 +17839,8 @@ var init_expand = __esm({
17777
17839
  // src/skills/detached-job-path.ts
17778
17840
  function detachedJobScriptIn(dir) {
17779
17841
  for (const name of DETACHED_JOB_FILENAMES) {
17780
- const script = (0, import_node_path42.join)(dir, "scripts", name);
17781
- if ((0, import_node_fs45.existsSync)(script)) return script;
17842
+ const script = (0, import_node_path43.join)(dir, "scripts", name);
17843
+ if ((0, import_node_fs46.existsSync)(script)) return script;
17782
17844
  }
17783
17845
  return null;
17784
17846
  }
@@ -17790,11 +17852,11 @@ function packagedDetachedJobPath() {
17790
17852
  function resolveDetachedJobScript() {
17791
17853
  const packaged = packagedDetachedJobPath();
17792
17854
  if (packaged) return packaged;
17793
- let dir = (0, import_node_path42.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
17855
+ let dir = (0, import_node_path43.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
17794
17856
  for (let i = 0; i < 8; i++) {
17795
17857
  const candidate = detachedJobScriptIn(dir);
17796
17858
  if (candidate) return candidate;
17797
- const parent = (0, import_node_path42.dirname)(dir);
17859
+ const parent = (0, import_node_path43.dirname)(dir);
17798
17860
  if (parent === dir) break;
17799
17861
  dir = parent;
17800
17862
  }
@@ -17805,12 +17867,12 @@ function formatDetachedJobInvoke(scriptPath) {
17805
17867
  if (resolved) return `node ${JSON.stringify(resolved)}`;
17806
17868
  return "node scripts/detached-job.cjs";
17807
17869
  }
17808
- var import_node_fs45, import_node_path42, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
17870
+ var import_node_fs46, import_node_path43, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
17809
17871
  var init_detached_job_path = __esm({
17810
17872
  "src/skills/detached-job-path.ts"() {
17811
17873
  "use strict";
17812
- import_node_fs45 = require("fs");
17813
- import_node_path42 = require("path");
17874
+ import_node_fs46 = require("fs");
17875
+ import_node_path43 = require("path");
17814
17876
  import_node_url3 = require("url");
17815
17877
  init_packaged_runtime();
17816
17878
  import_meta3 = {};
@@ -17968,11 +18030,13 @@ function formatPrGateDirective() {
17968
18030
  }
17969
18031
  function formatProcessGuideDirective(opts) {
17970
18032
  const worktree = opts?.worktreePath?.trim();
17971
- const hasGraphSkill = !!worktree && (0, import_node_fs46.existsSync)((0, import_node_path43.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
17972
- const hasReviewSkill = !!worktree && (0, import_node_fs46.existsSync)((0, import_node_path43.join)(worktree, ".claude/skills/review/SKILL.md"));
18033
+ const hasGraphSkill = !!worktree && (0, import_node_fs47.existsSync)((0, import_node_path44.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
18034
+ const hasReviewSkill = !!worktree && (0, import_node_fs47.existsSync)((0, import_node_path44.join)(worktree, ".claude/skills/review/SKILL.md"));
18035
+ const hasInstallSkill = !!worktree && (0, import_node_fs47.existsSync)((0, import_node_path44.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
17973
18036
  return [
17974
18037
  "Process guides (recurring work only):",
17975
18038
  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,
18039
+ hasInstallSkill ? "- After merge-from-main / lockfile change, or a hung `pnpm install`: follow `.claude/skills/worktree-install/SKILL.md` (`/worktree-install`). Use the worktree-local store Sideboard already set; do not share `~/.pnpm-store` across concurrent worktrees." : null,
17976
18040
  "- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill; Sideboard `/name`, Claude Code, and `attach` all load it). Not under `.sideboard/skills/`. Point Codex/OpenCode at it from `AGENTS.md`.",
17977
18041
  hasReviewSkill ? "- Merge-readiness notes go in `.claude/skills/review/SKILL.md` (edit it; do not create another review skill)." : "- Merge-readiness notes go in `.context/review.md` (copied from `.sideboard/review.md` when that file exists). Do not create a review skill.",
17978
18042
  "- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill, do not patch around it."
@@ -18006,12 +18070,12 @@ function formatArtifactDirective() {
18006
18070
  function formatUiReminder() {
18007
18071
  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 or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
18008
18072
  }
18009
- var import_node_fs46, import_node_path43, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
18073
+ var import_node_fs47, import_node_path44, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
18010
18074
  var init_instructions = __esm({
18011
18075
  "src/agents/instructions.ts"() {
18012
18076
  "use strict";
18013
- import_node_fs46 = require("fs");
18014
- import_node_path43 = require("path");
18077
+ import_node_fs47 = require("fs");
18078
+ import_node_path44 = require("path");
18015
18079
  init_git_auth_mode();
18016
18080
  init_worktree_labels();
18017
18081
  init_detached_job_path();
@@ -18202,40 +18266,40 @@ __export(plan_file_exports, {
18202
18266
  writePlanFile: () => writePlanFile
18203
18267
  });
18204
18268
  function ensureAttachmentsGitignore(worktreePath) {
18205
- const gitignoreAbs = (0, import_node_path44.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
18206
- if ((0, import_node_fs47.existsSync)(gitignoreAbs)) return;
18207
- (0, import_node_fs47.mkdirSync)((0, import_node_path44.dirname)(gitignoreAbs), { recursive: true });
18208
- (0, import_node_fs47.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
18269
+ const gitignoreAbs = (0, import_node_path45.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
18270
+ if ((0, import_node_fs48.existsSync)(gitignoreAbs)) return;
18271
+ (0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(gitignoreAbs), { recursive: true });
18272
+ (0, import_node_fs48.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
18209
18273
  }
18210
18274
  function planFileAbs(worktreePath) {
18211
- return (0, import_node_path44.join)(worktreePath, PLAN_FILE_REL);
18275
+ return (0, import_node_path45.join)(worktreePath, PLAN_FILE_REL);
18212
18276
  }
18213
18277
  function readTextIfPresent2(abs) {
18214
- if (!(0, import_node_fs47.existsSync)(abs)) return null;
18278
+ if (!(0, import_node_fs48.existsSync)(abs)) return null;
18215
18279
  try {
18216
- const content = (0, import_node_fs47.readFileSync)(abs, "utf8");
18280
+ const content = (0, import_node_fs48.readFileSync)(abs, "utf8");
18217
18281
  return content.trim() ? content : null;
18218
18282
  } catch {
18219
18283
  return null;
18220
18284
  }
18221
18285
  }
18222
18286
  function readPlanFile(worktreePath) {
18223
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path44.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path44.join)(worktreePath, LEGACY_PLAN_FILE_REL));
18287
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path45.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path45.join)(worktreePath, LEGACY_PLAN_FILE_REL));
18224
18288
  }
18225
18289
  function writePlanFile(worktreePath, content) {
18226
18290
  ensureAttachmentsGitignore(worktreePath);
18227
18291
  const abs = planFileAbs(worktreePath);
18228
- (0, import_node_fs47.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
18292
+ (0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
18229
18293
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
18230
- (0, import_node_fs47.writeFileSync)(abs, body, "utf8");
18294
+ (0, import_node_fs48.writeFileSync)(abs, body, "utf8");
18231
18295
  return PLAN_FILE_REL;
18232
18296
  }
18233
- var import_node_fs47, import_node_path44;
18297
+ var import_node_fs48, import_node_path45;
18234
18298
  var init_plan_file = __esm({
18235
18299
  "src/plan/plan-file.ts"() {
18236
18300
  "use strict";
18237
- import_node_fs47 = require("fs");
18238
- import_node_path44 = require("path");
18301
+ import_node_fs48 = require("fs");
18302
+ import_node_path45 = require("path");
18239
18303
  init_workspace_scratch();
18240
18304
  init_plan_present();
18241
18305
  init_plan_present();
@@ -18295,7 +18359,7 @@ function setCaffeinateHoldHooks(next) {
18295
18359
  hooks = next;
18296
18360
  }
18297
18361
  function caffeinateHoldPath() {
18298
- return (0, import_node_path45.join)(appDataDir(), "caffeinate-hold.json");
18362
+ return (0, import_node_path46.join)(appDataDir(), "caffeinate-hold.json");
18299
18363
  }
18300
18364
  function processAlive(pid) {
18301
18365
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -18329,9 +18393,9 @@ function uniqueIds(ids) {
18329
18393
  }
18330
18394
  function readHold() {
18331
18395
  const path = caffeinateHoldPath();
18332
- if (!(0, import_node_fs48.existsSync)(path)) return null;
18396
+ if (!(0, import_node_fs49.existsSync)(path)) return null;
18333
18397
  try {
18334
- const parsed = JSON.parse((0, import_node_fs48.readFileSync)(path, "utf8"));
18398
+ const parsed = JSON.parse((0, import_node_fs49.readFileSync)(path, "utf8"));
18335
18399
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
18336
18400
  return {
18337
18401
  pid: parsed.pid,
@@ -18353,7 +18417,7 @@ function writeHold(pid, threadIds) {
18353
18417
  }
18354
18418
  function clearHold() {
18355
18419
  try {
18356
- (0, import_node_fs48.unlinkSync)(caffeinateHoldPath());
18420
+ (0, import_node_fs49.unlinkSync)(caffeinateHoldPath());
18357
18421
  } catch {
18358
18422
  }
18359
18423
  }
@@ -18438,13 +18502,13 @@ function releaseCaffeinateHoldForThread(threadId) {
18438
18502
  }
18439
18503
  return setCaffeinateHold(false, { threadId: id });
18440
18504
  }
18441
- var import_node_child_process4, import_node_fs48, import_node_path45, hooks;
18505
+ var import_node_child_process4, import_node_fs49, import_node_path46, hooks;
18442
18506
  var init_caffeinate_hold = __esm({
18443
18507
  "src/store/caffeinate-hold.ts"() {
18444
18508
  "use strict";
18445
18509
  import_node_child_process4 = require("child_process");
18446
- import_node_fs48 = require("fs");
18447
- import_node_path45 = require("path");
18510
+ import_node_fs49 = require("fs");
18511
+ import_node_path46 = require("path");
18448
18512
  init_paths();
18449
18513
  init_private_file();
18450
18514
  hooks = {};
@@ -18453,7 +18517,7 @@ var init_caffeinate_hold = __esm({
18453
18517
 
18454
18518
  // src/store/schedules.ts
18455
18519
  function schedulesPath() {
18456
- return (0, import_node_path46.join)(appDataDir(), "schedules.json");
18520
+ return (0, import_node_path47.join)(appDataDir(), "schedules.json");
18457
18521
  }
18458
18522
  function parseDurationMs(every) {
18459
18523
  const m = every.trim().match(DURATION_RE);
@@ -18553,9 +18617,9 @@ function normalizeTask(raw) {
18553
18617
  }
18554
18618
  function readAll2() {
18555
18619
  const path = schedulesPath();
18556
- if (!(0, import_node_fs49.existsSync)(path)) return [];
18620
+ if (!(0, import_node_fs50.existsSync)(path)) return [];
18557
18621
  try {
18558
- const parsed = JSON.parse((0, import_node_fs49.readFileSync)(path, "utf8"));
18622
+ const parsed = JSON.parse((0, import_node_fs50.readFileSync)(path, "utf8"));
18559
18623
  if (!Array.isArray(parsed)) return [];
18560
18624
  return parsed.map((row) => {
18561
18625
  try {
@@ -18667,13 +18731,13 @@ function recordScheduleRun(id, result) {
18667
18731
  writeAll2(rows);
18668
18732
  return next;
18669
18733
  }
18670
- var import_node_crypto9, import_node_fs49, import_node_path46, import_croner, DURATION_RE, UNIT_MS;
18734
+ var import_node_crypto9, import_node_fs50, import_node_path47, import_croner, DURATION_RE, UNIT_MS;
18671
18735
  var init_schedules = __esm({
18672
18736
  "src/store/schedules.ts"() {
18673
18737
  "use strict";
18674
18738
  import_node_crypto9 = require("crypto");
18675
- import_node_fs49 = require("fs");
18676
- import_node_path46 = require("path");
18739
+ import_node_fs50 = require("fs");
18740
+ import_node_path47 = require("path");
18677
18741
  import_croner = require("croner");
18678
18742
  init_orchestrator_capable();
18679
18743
  init_paths();
@@ -18815,13 +18879,13 @@ var init_schedule_runner = __esm({
18815
18879
 
18816
18880
  // src/agents/cursor-store.ts
18817
18881
  function cursorSdkStoreDir(threadId) {
18818
- const root = (0, import_node_path47.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
18882
+ const root = (0, import_node_path48.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
18819
18883
  const id = sanitizeCursorStoreSegment(threadId);
18820
18884
  if (!id) return root;
18821
- return (0, import_node_path47.join)(root, "threads", id);
18885
+ return (0, import_node_path48.join)(root, "threads", id);
18822
18886
  }
18823
18887
  function cursorSdkRunsNdjsonPath(threadId) {
18824
- return (0, import_node_path47.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
18888
+ return (0, import_node_path48.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
18825
18889
  }
18826
18890
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
18827
18891
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -18834,11 +18898,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
18834
18898
  function sanitizeCursorStoreSegment(threadId) {
18835
18899
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
18836
18900
  }
18837
- var import_node_path47, CURSOR_SDK_STORE_DIR;
18901
+ var import_node_path48, CURSOR_SDK_STORE_DIR;
18838
18902
  var init_cursor_store = __esm({
18839
18903
  "src/agents/cursor-store.ts"() {
18840
18904
  "use strict";
18841
- import_node_path47 = require("path");
18905
+ import_node_path48 = require("path");
18842
18906
  init_paths();
18843
18907
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
18844
18908
  }
@@ -18860,9 +18924,9 @@ function recoverFinishedCursorRun(opts) {
18860
18924
  return best;
18861
18925
  }
18862
18926
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
18863
- if (!(0, import_node_fs50.existsSync)(runsPath)) return null;
18927
+ if (!(0, import_node_fs51.existsSync)(runsPath)) return null;
18864
18928
  try {
18865
- const lines = (0, import_node_fs50.readFileSync)(runsPath, "utf8").split("\n");
18929
+ const lines = (0, import_node_fs51.readFileSync)(runsPath, "utf8").split("\n");
18866
18930
  let best = null;
18867
18931
  for (const line of lines) {
18868
18932
  const trimmed = line.trim();
@@ -18888,11 +18952,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
18888
18952
  return null;
18889
18953
  }
18890
18954
  }
18891
- var import_node_fs50;
18955
+ var import_node_fs51;
18892
18956
  var init_cursor_recover = __esm({
18893
18957
  "src/agents/cursor-recover.ts"() {
18894
18958
  "use strict";
18895
- import_node_fs50 = require("fs");
18959
+ import_node_fs51 = require("fs");
18896
18960
  init_cursor_store();
18897
18961
  }
18898
18962
  });
@@ -19024,13 +19088,13 @@ async function startOrchestration(opts) {
19024
19088
  }
19025
19089
  return updated;
19026
19090
  }
19027
- var import_node_events, import_node_fs51, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
19091
+ var import_node_events, import_node_fs52, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
19028
19092
  var init_orchestrator = __esm({
19029
19093
  "src/orchestrator/orchestrator.ts"() {
19030
19094
  "use strict";
19031
19095
  import_node_events = require("events");
19032
19096
  init_outbound_watch();
19033
- import_node_fs51 = require("fs");
19097
+ import_node_fs52 = require("fs");
19034
19098
  init_error_detail();
19035
19099
  init_run();
19036
19100
  init_stale_lock();
@@ -19203,7 +19267,7 @@ var init_orchestrator = __esm({
19203
19267
  }
19204
19268
  continue;
19205
19269
  }
19206
- if (!(0, import_node_fs51.existsSync)(thread.worktreePath)) {
19270
+ if (!(0, import_node_fs52.existsSync)(thread.worktreePath)) {
19207
19271
  setStatus(thread.id, "broken", "Worktree missing on disk");
19208
19272
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
19209
19273
  continue;
@@ -21093,7 +21157,7 @@ var init_orchestrator = __esm({
21093
21157
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
21094
21158
  return restored2;
21095
21159
  }
21096
- if (!(0, import_node_fs51.existsSync)(thread.worktreePath)) {
21160
+ if (!(0, import_node_fs52.existsSync)(thread.worktreePath)) {
21097
21161
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
21098
21162
  throw new Error(
21099
21163
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -21176,7 +21240,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
21176
21240
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
21177
21241
  var import_zod8 = require("zod");
21178
21242
  var import_node_crypto12 = require("crypto");
21179
- var import_node_path50 = require("path");
21243
+ var import_node_path51 = require("path");
21180
21244
  init_orchestrator();
21181
21245
  init_worktree();
21182
21246
 
@@ -23768,27 +23832,27 @@ init_gh_errors();
23768
23832
  init_git_auth_mode();
23769
23833
 
23770
23834
  // src/board/load-home-board.ts
23771
- var import_node_fs53 = require("fs");
23772
- var import_node_path49 = require("path");
23835
+ var import_node_fs54 = require("fs");
23836
+ var import_node_path50 = require("path");
23773
23837
  init_worktree();
23774
23838
  init_paths();
23775
23839
 
23776
23840
  // src/board/board-pins.ts
23777
23841
  var import_node_crypto11 = require("crypto");
23778
- var import_node_fs52 = require("fs");
23779
- var import_node_path48 = require("path");
23842
+ var import_node_fs53 = require("fs");
23843
+ var import_node_path49 = require("path");
23780
23844
  init_paths();
23781
23845
  init_home_board();
23782
23846
  var FILE = "home-board-pins.json";
23783
23847
  var VERSION = 1;
23784
23848
  function pinsFile() {
23785
- return (0, import_node_path48.join)(appDataDir(), FILE);
23849
+ return (0, import_node_path49.join)(appDataDir(), FILE);
23786
23850
  }
23787
23851
  function readDisk() {
23788
23852
  const path = pinsFile();
23789
- if (!(0, import_node_fs52.existsSync)(path)) return [];
23853
+ if (!(0, import_node_fs53.existsSync)(path)) return [];
23790
23854
  try {
23791
- const raw = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
23855
+ const raw = JSON.parse((0, import_node_fs53.readFileSync)(path, "utf8"));
23792
23856
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
23793
23857
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
23794
23858
  } catch {
@@ -23796,8 +23860,8 @@ function readDisk() {
23796
23860
  }
23797
23861
  }
23798
23862
  function writeDisk(items) {
23799
- (0, import_node_fs52.mkdirSync)(appDataDir(), { recursive: true });
23800
- (0, import_node_fs52.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
23863
+ (0, import_node_fs53.mkdirSync)(appDataDir(), { recursive: true });
23864
+ (0, import_node_fs53.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
23801
23865
  }
23802
23866
  function listBoardPins() {
23803
23867
  return readDisk();
@@ -23818,7 +23882,7 @@ function homeBoardWorkspaceKey(workspaces) {
23818
23882
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
23819
23883
  }
23820
23884
  function cacheFile() {
23821
- return (0, import_node_path49.join)(appDataDir(), "home-board-cache.json");
23885
+ return (0, import_node_path50.join)(appDataDir(), "home-board-cache.json");
23822
23886
  }
23823
23887
  function emptyInputs() {
23824
23888
  return {
@@ -23844,9 +23908,9 @@ function shouldCacheHomeBoardInputs(inputs) {
23844
23908
  }
23845
23909
  function readDiskCache() {
23846
23910
  const path = cacheFile();
23847
- if (!(0, import_node_fs53.existsSync)(path)) return null;
23911
+ if (!(0, import_node_fs54.existsSync)(path)) return null;
23848
23912
  try {
23849
- const raw = JSON.parse((0, import_node_fs53.readFileSync)(path, "utf8"));
23913
+ const raw = JSON.parse((0, import_node_fs54.readFileSync)(path, "utf8"));
23850
23914
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
23851
23915
  return null;
23852
23916
  }
@@ -23860,8 +23924,8 @@ function readDiskCache() {
23860
23924
  }
23861
23925
  function writeDiskCache(entry) {
23862
23926
  try {
23863
- (0, import_node_fs53.mkdirSync)(appDataDir(), { recursive: true });
23864
- (0, import_node_fs53.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
23927
+ (0, import_node_fs54.mkdirSync)(appDataDir(), { recursive: true });
23928
+ (0, import_node_fs54.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
23865
23929
  } catch {
23866
23930
  }
23867
23931
  }
@@ -24161,7 +24225,7 @@ async function startMcpServer() {
24161
24225
  async () => {
24162
24226
  const threads = orch.getThreads(true);
24163
24227
  const lines = threads.map((t) => {
24164
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path50.basename)(t.repoPath) || t.repoPath;
24228
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path51.basename)(t.repoPath) || t.repoPath;
24165
24229
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
24166
24230
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
24167
24231
  const preview = lastMessagePreview(t.messages, 80);