@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.
package/dist/index.cjs CHANGED
@@ -13672,6 +13672,62 @@ var init_agents = __esm({
13672
13672
  }
13673
13673
  });
13674
13674
 
13675
+ // src/hook/worktree-pkg-cache.ts
13676
+ function worktreePkgCacheRoot(worktreePath) {
13677
+ return (0, import_node_path36.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
13678
+ }
13679
+ function worktreePkgCacheEnv(worktreePath) {
13680
+ const root = worktreePkgCacheRoot(worktreePath);
13681
+ const store = (0, import_node_path36.join)(root, "pnpm-store");
13682
+ const pnpmCache = (0, import_node_path36.join)(root, "pnpm");
13683
+ const npmCache = (0, import_node_path36.join)(root, "npm");
13684
+ const nodeGyp = (0, import_node_path36.join)(root, "node-gyp");
13685
+ const electron = (0, import_node_path36.join)(root, "electron");
13686
+ return {
13687
+ npm_config_store_dir: store,
13688
+ PNPM_STORE_DIR: store,
13689
+ npm_config_cache_dir: pnpmCache,
13690
+ npm_config_cache: npmCache,
13691
+ npm_config_devdir: nodeGyp,
13692
+ // @electron/get — do not set ELECTRON_CACHE (stripNestedElectronEnv).
13693
+ electron_config_cache: electron
13694
+ };
13695
+ }
13696
+ function isSet(value) {
13697
+ return value != null && value.trim() !== "";
13698
+ }
13699
+ function fillGroup(env, keys, values) {
13700
+ if (keys.some((key) => isSet(env[key]))) return;
13701
+ for (const key of keys) {
13702
+ const value = values[key];
13703
+ if (value) env[key] = value;
13704
+ }
13705
+ }
13706
+ function ensureWorktreePkgCacheDirs(worktreePath) {
13707
+ if (!(0, import_node_fs36.existsSync)(worktreePath)) return;
13708
+ (0, import_node_fs36.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
13709
+ }
13710
+ function applyWorktreePkgCacheEnv(env, worktreePath) {
13711
+ const cwd = worktreePath.trim();
13712
+ if (!cwd) return;
13713
+ const next = worktreePkgCacheEnv(cwd);
13714
+ fillGroup(env, ["npm_config_store_dir", "PNPM_STORE_DIR"], next);
13715
+ fillGroup(env, ["npm_config_cache_dir"], next);
13716
+ fillGroup(env, ["npm_config_cache"], next);
13717
+ fillGroup(env, ["npm_config_devdir"], next);
13718
+ fillGroup(env, ["electron_config_cache"], next);
13719
+ ensureWorktreePkgCacheDirs(cwd);
13720
+ }
13721
+ var import_node_fs36, import_node_path36, WORKTREE_PKG_CACHE_REL;
13722
+ var init_worktree_pkg_cache = __esm({
13723
+ "src/hook/worktree-pkg-cache.ts"() {
13724
+ "use strict";
13725
+ import_node_fs36 = require("fs");
13726
+ import_node_path36 = require("path");
13727
+ WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
13728
+ }
13729
+ });
13730
+
13675
13731
  // src/agents/cursor-stream-coalesce.ts
13676
13732
  function isTextEvent(event) {
13677
13733
  return event.type === "stdout" || event.type === "thinking";
@@ -13774,6 +13830,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
13774
13830
  const env = childEnvWithAppSettings(cmd.env);
13775
13831
  applyPromptCacheTtlEnv(thread.agent, env);
13776
13832
  applyAgentRunnerHeapEnv(env);
13833
+ if (!isOrchestratorThread(thread)) {
13834
+ applyWorktreePkgCacheEnv(env, thread.worktreePath);
13835
+ }
13777
13836
  try {
13778
13837
  if (isOrchestratorThread(thread)) {
13779
13838
  mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
@@ -13881,6 +13940,7 @@ var init_spawn = __esm({
13881
13940
  init_agents();
13882
13941
  init_orchestrator_capable();
13883
13942
  init_message_parts();
13943
+ init_worktree_pkg_cache();
13884
13944
  init_node_launch();
13885
13945
  init_path();
13886
13946
  init_usage();
@@ -14811,21 +14871,21 @@ function shouldRefreshReviewRequestTemplate(content) {
14811
14871
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
14812
14872
  }
14813
14873
  function readTextIfPresent(abs) {
14814
- if (!(0, import_node_fs36.existsSync)(abs)) return null;
14874
+ if (!(0, import_node_fs37.existsSync)(abs)) return null;
14815
14875
  try {
14816
- const content = (0, import_node_fs36.readFileSync)(abs, "utf8");
14876
+ const content = (0, import_node_fs37.readFileSync)(abs, "utf8");
14817
14877
  return content.trim() ? content : null;
14818
14878
  } catch {
14819
14879
  return null;
14820
14880
  }
14821
14881
  }
14822
14882
  function readLocalGuidelines(worktreePath) {
14823
- const localAbs = (0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH);
14883
+ const localAbs = (0, import_node_path37.join)(worktreePath, REVIEW_REQUEST_PATH);
14824
14884
  const localContent = readTextIfPresent(localAbs);
14825
14885
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
14826
14886
  return { path: REVIEW_REQUEST_PATH, content: localContent };
14827
14887
  }
14828
- const legacyAbs = (0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14888
+ const legacyAbs = (0, import_node_path37.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
14829
14889
  const legacyContent = readTextIfPresent(legacyAbs);
14830
14890
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
14831
14891
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -14849,27 +14909,27 @@ function contextGuidelines(content, source) {
14849
14909
  };
14850
14910
  }
14851
14911
  function writeContextGuidelines(worktreePath, content) {
14852
- const abs = (0, import_node_path36.join)(worktreePath, CONTEXT_REVIEW_PATH);
14853
- (0, import_node_fs36.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
14912
+ const abs = (0, import_node_path37.join)(worktreePath, CONTEXT_REVIEW_PATH);
14913
+ (0, import_node_fs37.mkdirSync)((0, import_node_path37.dirname)(abs), { recursive: true });
14854
14914
  const body = content.endsWith("\n") ? content : `${content}
14855
14915
  `;
14856
- (0, import_node_fs36.writeFileSync)(abs, body, "utf8");
14916
+ (0, import_node_fs37.writeFileSync)(abs, body, "utf8");
14857
14917
  return body;
14858
14918
  }
14859
14919
  function readSideboardReview(worktreePath, repoPath) {
14860
- const fromWorktree = readTextIfPresent((0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH));
14920
+ const fromWorktree = readTextIfPresent((0, import_node_path37.join)(worktreePath, REPO_REVIEW_PATH));
14861
14921
  if (fromWorktree) return fromWorktree;
14862
14922
  const repo = repoPath?.replace(/\/+$/, "");
14863
14923
  const wt = worktreePath.replace(/\/+$/, "");
14864
14924
  if (!repo || repo === wt) return null;
14865
- return readTextIfPresent((0, import_node_path36.join)(repo, REPO_REVIEW_PATH));
14925
+ return readTextIfPresent((0, import_node_path37.join)(repo, REPO_REVIEW_PATH));
14866
14926
  }
14867
14927
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
14868
- const skillContent = readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_SKILL_PATH));
14928
+ const skillContent = readTextIfPresent((0, import_node_path37.join)(worktreePath, REVIEW_SKILL_PATH));
14869
14929
  if (skillContent) {
14870
14930
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
14871
14931
  }
14872
- const contextContent = readTextIfPresent((0, import_node_path36.join)(worktreePath, CONTEXT_REVIEW_PATH));
14932
+ const contextContent = readTextIfPresent((0, import_node_path37.join)(worktreePath, CONTEXT_REVIEW_PATH));
14873
14933
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
14874
14934
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
14875
14935
  }
@@ -14907,7 +14967,7 @@ function buildReviewRequestAttachment(content, opts) {
14907
14967
  };
14908
14968
  }
14909
14969
  function readExistingReviewRequestFile(worktreePath) {
14910
- return readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path36.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14970
+ return readTextIfPresent((0, import_node_path37.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path37.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
14911
14971
  }
14912
14972
  async function requestReview(threadRef, send2) {
14913
14973
  const from = findThreadByRef(threadRef);
@@ -14934,13 +14994,13 @@ async function requestReview(threadRef, send2) {
14934
14994
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
14935
14995
  return { tab: started, from };
14936
14996
  }
14937
- var import_node_crypto8, import_node_fs36, import_node_path36, 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;
14997
+ var import_node_crypto8, import_node_fs37, import_node_path37, 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;
14938
14998
  var init_request_review = __esm({
14939
14999
  "src/review/request-review.ts"() {
14940
15000
  "use strict";
14941
15001
  import_node_crypto8 = require("crypto");
14942
- import_node_fs36 = require("fs");
14943
- import_node_path36 = require("path");
15002
+ import_node_fs37 = require("fs");
15003
+ import_node_path37 = require("path");
14944
15004
  init_global_workspace();
14945
15005
  init_chat_tabs();
14946
15006
  init_thread_store();
@@ -14966,9 +15026,9 @@ function matchSimpleGlob(pattern, name) {
14966
15026
  return new RegExp(`^${escaped}$`).test(name);
14967
15027
  }
14968
15028
  function readWorktreeInclude(repoPath) {
14969
- const path2 = (0, import_node_path37.join)(repoPath, ".worktreeinclude");
14970
- if (!(0, import_node_fs37.existsSync)(path2)) return [];
14971
- return (0, import_node_fs37.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
15029
+ const path2 = (0, import_node_path38.join)(repoPath, ".worktreeinclude");
15030
+ if (!(0, import_node_fs38.existsSync)(path2)) return [];
15031
+ return (0, import_node_fs38.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
14972
15032
  }
14973
15033
  function resolveFilesToCopy(repoPath) {
14974
15034
  const fromInclude = readWorktreeInclude(repoPath);
@@ -14978,10 +15038,10 @@ function resolveFilesToCopy(repoPath) {
14978
15038
  if (settings?.fileIncludeGlobs?.length) {
14979
15039
  const matched = [];
14980
15040
  try {
14981
- for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
15041
+ for (const entry of (0, import_node_fs38.readdirSync)(repoPath, { withFileTypes: true })) {
14982
15042
  if (!entry.isFile()) continue;
14983
15043
  for (const glob of settings.fileIncludeGlobs) {
14984
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path37.basename)(glob), entry.name)) {
15044
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path38.basename)(glob), entry.name)) {
14985
15045
  matched.push(entry.name);
14986
15046
  break;
14987
15047
  }
@@ -14993,7 +15053,7 @@ function resolveFilesToCopy(repoPath) {
14993
15053
  }
14994
15054
  const defaults = [];
14995
15055
  try {
14996
- for (const entry of (0, import_node_fs37.readdirSync)(repoPath, { withFileTypes: true })) {
15056
+ for (const entry of (0, import_node_fs38.readdirSync)(repoPath, { withFileTypes: true })) {
14997
15057
  if (entry.isFile() && entry.name.startsWith(".env")) {
14998
15058
  defaults.push(entry.name);
14999
15059
  }
@@ -15007,11 +15067,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
15007
15067
  const patterns = resolveFilesToCopy(repoPath);
15008
15068
  const copied = [];
15009
15069
  for (const rel of patterns) {
15010
- const src = (0, import_node_path37.join)(repoPath, rel);
15011
- if (!(0, import_node_fs37.existsSync)(src)) continue;
15012
- const dest = (0, import_node_path37.join)(worktreePath, rel);
15013
- (0, import_node_fs37.mkdirSync)((0, import_node_path37.dirname)(dest), { recursive: true });
15014
- (0, import_node_fs37.copyFileSync)(src, dest);
15070
+ const src = (0, import_node_path38.join)(repoPath, rel);
15071
+ if (!(0, import_node_fs38.existsSync)(src)) continue;
15072
+ const dest = (0, import_node_path38.join)(worktreePath, rel);
15073
+ (0, import_node_fs38.mkdirSync)((0, import_node_path38.dirname)(dest), { recursive: true });
15074
+ (0, import_node_fs38.copyFileSync)(src, dest);
15015
15075
  copied.push(rel);
15016
15076
  }
15017
15077
  return copied;
@@ -15046,7 +15106,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
15046
15106
  const env = stripNestedElectronEnv({
15047
15107
  ...baseEnv ?? process.env
15048
15108
  });
15049
- const name = opts.workspaceName ?? (0, import_node_path37.basename)(opts.worktreePath);
15109
+ const name = opts.workspaceName ?? (0, import_node_path38.basename)(opts.worktreePath);
15050
15110
  const ports = opts.ports ?? [];
15051
15111
  const primary = ports[0];
15052
15112
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -15069,6 +15129,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
15069
15129
  env[`CONDUCTOR_PORT_${i}`] = String(p);
15070
15130
  }
15071
15131
  }
15132
+ applyWorktreePkgCacheEnv(env, opts.worktreePath);
15072
15133
  return env;
15073
15134
  }
15074
15135
  function pipeLines(stream, onLine) {
@@ -15308,17 +15369,18 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
15308
15369
  done: handle.done
15309
15370
  };
15310
15371
  }
15311
- var import_node_fs37, import_node_net, import_node_path37, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
15372
+ var import_node_fs38, import_node_net, import_node_path38, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
15312
15373
  var init_conductor = __esm({
15313
15374
  "src/hook/conductor.ts"() {
15314
15375
  "use strict";
15315
- import_node_fs37 = require("fs");
15376
+ import_node_fs38 = require("fs");
15316
15377
  import_node_net = require("net");
15317
- import_node_path37 = require("path");
15378
+ import_node_path38 = require("path");
15318
15379
  import_execa4 = require("execa");
15319
15380
  import_node_readline3 = require("readline");
15320
15381
  init_settings();
15321
15382
  init_nested_electron_env();
15383
+ init_worktree_pkg_cache();
15322
15384
  init_convention_setup();
15323
15385
  init_cursor_worktrees();
15324
15386
  init_git_auth_mode();
@@ -15341,9 +15403,9 @@ async function findOrphanWorktrees(repoPaths) {
15341
15403
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
15342
15404
  );
15343
15405
  const homeRoot = sideboardWorkspacesDir();
15344
- if ((0, import_node_fs38.existsSync)(homeRoot)) {
15406
+ if ((0, import_node_fs39.existsSync)(homeRoot)) {
15345
15407
  try {
15346
- for (const entry of (0, import_node_fs38.readdirSync)(homeRoot, { withFileTypes: true })) {
15408
+ for (const entry of (0, import_node_fs39.readdirSync)(homeRoot, { withFileTypes: true })) {
15347
15409
  if (!entry.isDirectory()) continue;
15348
15410
  void entry;
15349
15411
  }
@@ -15353,7 +15415,7 @@ async function findOrphanWorktrees(repoPaths) {
15353
15415
  const orphans = [];
15354
15416
  const seen = /* @__PURE__ */ new Set();
15355
15417
  for (const repoPath of repos) {
15356
- if (!repoPath || !(0, import_node_fs38.existsSync)(repoPath)) continue;
15418
+ if (!repoPath || !(0, import_node_fs39.existsSync)(repoPath)) continue;
15357
15419
  try {
15358
15420
  const wts = await listWorktrees(repoPath);
15359
15421
  for (const wt of wts) {
@@ -15364,7 +15426,7 @@ async function findOrphanWorktrees(repoPaths) {
15364
15426
  seen.add(path2);
15365
15427
  let mtimeMs = 0;
15366
15428
  try {
15367
- mtimeMs = (0, import_node_fs38.statSync)(path2).mtimeMs;
15429
+ mtimeMs = (0, import_node_fs39.statSync)(path2).mtimeMs;
15368
15430
  } catch {
15369
15431
  mtimeMs = 0;
15370
15432
  }
@@ -15374,16 +15436,16 @@ async function findOrphanWorktrees(repoPaths) {
15374
15436
  }
15375
15437
  try {
15376
15438
  const root = worktreesRoot(repoPath);
15377
- if ((0, import_node_fs38.existsSync)(root)) {
15378
- for (const entry of (0, import_node_fs38.readdirSync)(root, { withFileTypes: true })) {
15439
+ if ((0, import_node_fs39.existsSync)(root)) {
15440
+ for (const entry of (0, import_node_fs39.readdirSync)(root, { withFileTypes: true })) {
15379
15441
  if (!entry.isDirectory()) continue;
15380
- const path2 = (0, import_node_path38.join)(root, entry.name).replace(/\/$/, "");
15442
+ const path2 = (0, import_node_path39.join)(root, entry.name).replace(/\/$/, "");
15381
15443
  if (known.has(path2) || seen.has(path2)) continue;
15382
- if (!(0, import_node_fs38.existsSync)((0, import_node_path38.join)(path2, ".git"))) continue;
15444
+ if (!(0, import_node_fs39.existsSync)((0, import_node_path39.join)(path2, ".git"))) continue;
15383
15445
  seen.add(path2);
15384
15446
  let mtimeMs = 0;
15385
15447
  try {
15386
- mtimeMs = (0, import_node_fs38.statSync)(path2).mtimeMs;
15448
+ mtimeMs = (0, import_node_fs39.statSync)(path2).mtimeMs;
15387
15449
  } catch {
15388
15450
  mtimeMs = Date.now();
15389
15451
  }
@@ -15444,12 +15506,12 @@ function worktreeCleanupSettings() {
15444
15506
  autoCleanupOrphans: a.autoCleanupOrphans
15445
15507
  };
15446
15508
  }
15447
- var import_node_fs38, import_node_path38;
15509
+ var import_node_fs39, import_node_path39;
15448
15510
  var init_orphan_cleanup = __esm({
15449
15511
  "src/git/orphan-cleanup.ts"() {
15450
15512
  "use strict";
15451
- import_node_fs38 = require("fs");
15452
- import_node_path38 = require("path");
15513
+ import_node_fs39 = require("fs");
15514
+ import_node_path39 = require("path");
15453
15515
  init_worktree();
15454
15516
  init_thread_store();
15455
15517
  init_paths();
@@ -15552,12 +15614,12 @@ async function cloneRepoIntoSideboard(opts) {
15552
15614
  if (!url) throw new Error("Clone URL is required");
15553
15615
  let name = opts.name?.trim();
15554
15616
  if (!name) {
15555
- const leaf = (0, import_node_path39.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15617
+ const leaf = (0, import_node_path40.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
15556
15618
  name = leaf || "repo";
15557
15619
  }
15558
15620
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
15559
- const dest = (0, import_node_path39.join)(sideboardReposDir(), name);
15560
- if ((0, import_node_fs39.existsSync)(dest)) {
15621
+ const dest = (0, import_node_path40.join)(sideboardReposDir(), name);
15622
+ if ((0, import_node_fs40.existsSync)(dest)) {
15561
15623
  const repoPath2 = await resolveRepoRoot(dest);
15562
15624
  const workspace2 = await ensureWorkspace(repoPath2);
15563
15625
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -15572,12 +15634,12 @@ async function cloneRepoIntoSideboard(opts) {
15572
15634
  const workspace = await ensureWorkspace(repoPath);
15573
15635
  return { repoPath, workspace };
15574
15636
  }
15575
- var import_node_fs39, import_node_path39, import_execa6;
15637
+ var import_node_fs40, import_node_path40, import_execa6;
15576
15638
  var init_clone_repo = __esm({
15577
15639
  "src/git/clone-repo.ts"() {
15578
15640
  "use strict";
15579
- import_node_fs39 = require("fs");
15580
- import_node_path39 = require("path");
15641
+ import_node_fs40 = require("fs");
15642
+ import_node_path40 = require("path");
15581
15643
  import_execa6 = require("execa");
15582
15644
  init_paths();
15583
15645
  init_workspaces();
@@ -15695,24 +15757,24 @@ function jobTreeAlive(pid) {
15695
15757
  return jobAlive(pid) || processGroupAlive(pid);
15696
15758
  }
15697
15759
  function readIntFile(file) {
15698
- if (!(0, import_node_fs40.existsSync)(file)) return null;
15699
- const n = Number.parseInt((0, import_node_fs40.readFileSync)(file, "utf8").trim(), 10);
15760
+ if (!(0, import_node_fs41.existsSync)(file)) return null;
15761
+ const n = Number.parseInt((0, import_node_fs41.readFileSync)(file, "utf8").trim(), 10);
15700
15762
  return Number.isInteger(n) ? n : null;
15701
15763
  }
15702
15764
  function jobDir(root, id, legacy = false) {
15703
- return (0, import_node_path40.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15765
+ return (0, import_node_path41.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
15704
15766
  }
15705
15767
  function resolveJobDir(root, id) {
15706
15768
  const modern = jobDir(root, id, false);
15707
- if ((0, import_node_fs40.existsSync)(modern)) return modern;
15769
+ if ((0, import_node_fs41.existsSync)(modern)) return modern;
15708
15770
  const legacy = jobDir(root, id, true);
15709
- if ((0, import_node_fs40.existsSync)(legacy)) return legacy;
15771
+ if ((0, import_node_fs41.existsSync)(legacy)) return legacy;
15710
15772
  return modern;
15711
15773
  }
15712
15774
  function listJobIdsIn(root, rel) {
15713
- const dir = (0, import_node_path40.join)(root, rel);
15714
- if (!(0, import_node_fs40.existsSync)(dir)) return [];
15715
- return (0, import_node_fs40.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15775
+ const dir = (0, import_node_path41.join)(root, rel);
15776
+ if (!(0, import_node_fs41.existsSync)(dir)) return [];
15777
+ return (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
15716
15778
  }
15717
15779
  function listRunningDetachedJobs(worktreePath) {
15718
15780
  const root = worktreePath.trim();
@@ -15724,7 +15786,7 @@ function listRunningDetachedJobs(worktreePath) {
15724
15786
  const running = [];
15725
15787
  for (const id of ids) {
15726
15788
  const dir = resolveJobDir(root, id);
15727
- const pid = readIntFile((0, import_node_path40.join)(dir, "pid"));
15789
+ const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
15728
15790
  if (pid != null && jobAlive(pid)) running.push(id);
15729
15791
  }
15730
15792
  return running.sort();
@@ -15777,13 +15839,13 @@ function planJobContinue(opts) {
15777
15839
  return { action: "none" };
15778
15840
  }
15779
15841
  function tailProgress(logFile, maxLines = 12) {
15780
- if (!(0, import_node_fs40.existsSync)(logFile)) return "(no log yet)";
15781
- const lines = (0, import_node_fs40.readFileSync)(logFile, "utf8").split("\n");
15842
+ if (!(0, import_node_fs41.existsSync)(logFile)) return "(no log yet)";
15843
+ const lines = (0, import_node_fs41.readFileSync)(logFile, "utf8").split("\n");
15782
15844
  return lines.slice(-maxLines).join("\n");
15783
15845
  }
15784
15846
  function readLogLines(file) {
15785
- if (!(0, import_node_fs40.existsSync)(file)) return [];
15786
- const lines = (0, import_node_fs40.readFileSync)(file, "utf8").split("\n");
15847
+ if (!(0, import_node_fs41.existsSync)(file)) return [];
15848
+ const lines = (0, import_node_fs41.readFileSync)(file, "utf8").split("\n");
15787
15849
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
15788
15850
  return lines;
15789
15851
  }
@@ -15794,15 +15856,15 @@ function takeDelta(logFile, cursorFile) {
15794
15856
  return { delta: lines.slice(start).join("\n"), nextCursor: lines.length };
15795
15857
  }
15796
15858
  function snapshotJob(dir) {
15797
- const pid = readIntFile((0, import_node_path40.join)(dir, "pid"));
15859
+ const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
15798
15860
  const running = jobTreeAlive(pid);
15799
15861
  return {
15800
15862
  pid,
15801
15863
  running,
15802
- exitCode: readIntFile((0, import_node_path40.join)(dir, "exit")),
15803
- log: (0, import_node_path40.join)(dir, "log"),
15804
- cursor: (0, import_node_path40.join)(dir, "present.cursor"),
15805
- progress: tailProgress((0, import_node_path40.join)(dir, "log"))
15864
+ exitCode: readIntFile((0, import_node_path41.join)(dir, "exit")),
15865
+ log: (0, import_node_path41.join)(dir, "log"),
15866
+ cursor: (0, import_node_path41.join)(dir, "present.cursor"),
15867
+ progress: tailProgress((0, import_node_path41.join)(dir, "log"))
15806
15868
  };
15807
15869
  }
15808
15870
  function toResult(id, snap, extra) {
@@ -15811,8 +15873,8 @@ function toResult(id, snap, extra) {
15811
15873
  const stillRunning = snap.running && !ok;
15812
15874
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
15813
15875
  try {
15814
- (0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(snap.cursor), { recursive: true });
15815
- (0, import_node_fs40.writeFileSync)(snap.cursor, `${nextCursor}
15876
+ (0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(snap.cursor), { recursive: true });
15877
+ (0, import_node_fs41.writeFileSync)(snap.cursor, `${nextCursor}
15816
15878
  `);
15817
15879
  } catch {
15818
15880
  }
@@ -15839,7 +15901,7 @@ async function waitForDetachedJob(cwd, id, opts) {
15839
15901
  const dir = resolveJobDir(root, jobId);
15840
15902
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
15841
15903
  const sleep2 = opts?.sleep ?? sleepMs;
15842
- if (!(0, import_node_fs40.existsSync)(dir)) {
15904
+ if (!(0, import_node_fs41.existsSync)(dir)) {
15843
15905
  return {
15844
15906
  stillRunning: false,
15845
15907
  ok: false,
@@ -15885,10 +15947,10 @@ function killProcessTree(pid, signal) {
15885
15947
  }
15886
15948
  function appendJobLog(logFile, line) {
15887
15949
  try {
15888
- (0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(logFile), { recursive: true });
15950
+ (0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(logFile), { recursive: true });
15889
15951
  const body = line.endsWith("\n") ? line : `${line}
15890
15952
  `;
15891
- (0, import_node_fs40.appendFileSync)(logFile, body);
15953
+ (0, import_node_fs41.appendFileSync)(logFile, body);
15892
15954
  } catch {
15893
15955
  }
15894
15956
  }
@@ -15898,7 +15960,7 @@ async function stopDetachedJob(cwd, id, opts) {
15898
15960
  const dir = resolveJobDir(root, jobId);
15899
15961
  const sleep2 = opts?.sleep ?? sleepMs;
15900
15962
  const why = opts?.reason?.trim() ?? "";
15901
- if (!(0, import_node_fs40.existsSync)(dir)) {
15963
+ if (!(0, import_node_fs41.existsSync)(dir)) {
15902
15964
  return {
15903
15965
  stillRunning: false,
15904
15966
  ok: false,
@@ -15934,10 +15996,10 @@ async function stopDetachedJob(cwd, id, opts) {
15934
15996
  killProcessTree(targetPid, "SIGKILL");
15935
15997
  await sleep2(100);
15936
15998
  }
15937
- const exitFile = (0, import_node_path40.join)(dir, "exit");
15938
- if (!(0, import_node_fs40.existsSync)(exitFile)) {
15999
+ const exitFile = (0, import_node_path41.join)(dir, "exit");
16000
+ if (!(0, import_node_fs41.existsSync)(exitFile)) {
15939
16001
  try {
15940
- (0, import_node_fs40.writeFileSync)(exitFile, "1\n");
16002
+ (0, import_node_fs41.writeFileSync)(exitFile, "1\n");
15941
16003
  } catch {
15942
16004
  }
15943
16005
  }
@@ -15957,12 +16019,12 @@ async function stopDetachedJob(cwd, id, opts) {
15957
16019
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
15958
16020
  };
15959
16021
  }
15960
- var import_node_fs40, import_node_path40, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
16022
+ var import_node_fs41, import_node_path41, MAX_JOB_CONTINUES, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
15961
16023
  var init_wait_for_job = __esm({
15962
16024
  "src/mcp/wait-for-job.ts"() {
15963
16025
  "use strict";
15964
- import_node_fs40 = require("fs");
15965
- import_node_path40 = require("path");
16026
+ import_node_fs41 = require("fs");
16027
+ import_node_path41 = require("path");
15966
16028
  init_workspace_scratch();
15967
16029
  init_wait_for_turn();
15968
16030
  MAX_JOB_CONTINUES = 8;
@@ -17099,7 +17161,7 @@ function reuseLiveThread(input, repoPath, match) {
17099
17161
  }
17100
17162
  async function createThread(input, _onSetupLine) {
17101
17163
  const repoPath = await resolveRepoRoot(input.repoPath);
17102
- if (!(0, import_node_fs41.existsSync)(repoPath)) {
17164
+ if (!(0, import_node_fs42.existsSync)(repoPath)) {
17103
17165
  throw new Error(`Repo not found: ${repoPath}`);
17104
17166
  }
17105
17167
  const reused = reuseLiveThread(input, repoPath, {
@@ -17280,11 +17342,11 @@ async function listLinearIssues(agent, repoPath) {
17280
17342
  }
17281
17343
  return adapter.listLinearIssues(repoPath);
17282
17344
  }
17283
- var import_node_fs41;
17345
+ var import_node_fs42;
17284
17346
  var init_create = __esm({
17285
17347
  "src/threads/create.ts"() {
17286
17348
  "use strict";
17287
- import_node_fs41 = require("fs");
17349
+ import_node_fs42 = require("fs");
17288
17350
  init_detect();
17289
17351
  init_worktree();
17290
17352
  init_home_board();
@@ -17404,20 +17466,20 @@ function writeTurnLive(threadId, progress) {
17404
17466
  const path2 = threadLivePath(threadId);
17405
17467
  const tmp = `${path2}.${process.pid}.tmp`;
17406
17468
  try {
17407
- (0, import_node_fs42.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
17408
- (0, import_node_fs42.renameSync)(tmp, path2);
17469
+ (0, import_node_fs43.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
17470
+ (0, import_node_fs43.renameSync)(tmp, path2);
17409
17471
  } catch {
17410
17472
  try {
17411
- (0, import_node_fs42.unlinkSync)(tmp);
17473
+ (0, import_node_fs43.unlinkSync)(tmp);
17412
17474
  } catch {
17413
17475
  }
17414
17476
  }
17415
17477
  }
17416
17478
  function readTurnLive(threadId) {
17417
17479
  const path2 = threadLivePath(threadId);
17418
- if (!(0, import_node_fs42.existsSync)(path2)) return null;
17480
+ if (!(0, import_node_fs43.existsSync)(path2)) return null;
17419
17481
  try {
17420
- const raw = JSON.parse((0, import_node_fs42.readFileSync)(path2, "utf8"));
17482
+ const raw = JSON.parse((0, import_node_fs43.readFileSync)(path2, "utf8"));
17421
17483
  if (!raw || typeof raw.summary !== "string") return null;
17422
17484
  return raw;
17423
17485
  } catch {
@@ -17429,17 +17491,17 @@ function clearTurnLive(threadId) {
17429
17491
  if (buf?.timer) clearTimeout(buf.timer);
17430
17492
  buffers.delete(threadId);
17431
17493
  const path2 = threadLivePath(threadId);
17432
- if (!(0, import_node_fs42.existsSync)(path2)) return;
17494
+ if (!(0, import_node_fs43.existsSync)(path2)) return;
17433
17495
  try {
17434
- (0, import_node_fs42.unlinkSync)(path2);
17496
+ (0, import_node_fs43.unlinkSync)(path2);
17435
17497
  } catch {
17436
17498
  }
17437
17499
  }
17438
- var import_node_fs42, buffers, FLUSH_MS, MAX_PARTS;
17500
+ var import_node_fs43, buffers, FLUSH_MS, MAX_PARTS;
17439
17501
  var init_turn_live = __esm({
17440
17502
  "src/store/turn-live.ts"() {
17441
17503
  "use strict";
17442
- import_node_fs42 = require("fs");
17504
+ import_node_fs43 = require("fs");
17443
17505
  init_message_parts();
17444
17506
  init_paths();
17445
17507
  buffers = /* @__PURE__ */ new Map();
@@ -17659,7 +17721,7 @@ var init_quota_failover = __esm({
17659
17721
  // src/threads/adopt.ts
17660
17722
  function thisModuleFile() {
17661
17723
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
17662
- return cjsFile || process.argv[1] || (0, import_node_path41.join)(process.cwd(), "package.json");
17724
+ return cjsFile || process.argv[1] || (0, import_node_path42.join)(process.cwd(), "package.json");
17663
17725
  }
17664
17726
  function openReadonlySqlite(file) {
17665
17727
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -17677,21 +17739,21 @@ function mapAgentType(raw) {
17677
17739
  return null;
17678
17740
  }
17679
17741
  function resolveConductorCursorAgentId(workspacePath) {
17680
- if (!workspacePath || !(0, import_node_fs43.existsSync)(CURSOR_SDK_STORE)) return null;
17742
+ if (!workspacePath || !(0, import_node_fs44.existsSync)(CURSOR_SDK_STORE)) return null;
17681
17743
  const normalized = workspacePath.replace(/\/$/, "");
17682
17744
  let best = null;
17683
17745
  let hashes;
17684
17746
  try {
17685
- hashes = (0, import_node_fs43.readdirSync)(CURSOR_SDK_STORE);
17747
+ hashes = (0, import_node_fs44.readdirSync)(CURSOR_SDK_STORE);
17686
17748
  } catch {
17687
17749
  return null;
17688
17750
  }
17689
17751
  for (const hash of hashes) {
17690
- const agentsFile = (0, import_node_path41.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
17691
- if (!(0, import_node_fs43.existsSync)(agentsFile)) continue;
17752
+ const agentsFile = (0, import_node_path42.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
17753
+ if (!(0, import_node_fs44.existsSync)(agentsFile)) continue;
17692
17754
  let text7;
17693
17755
  try {
17694
- text7 = (0, import_node_fs43.readFileSync)(agentsFile, "utf8");
17756
+ text7 = (0, import_node_fs44.readFileSync)(agentsFile, "utf8");
17695
17757
  } catch {
17696
17758
  continue;
17697
17759
  }
@@ -17715,7 +17777,7 @@ function resolveConductorCursorAgentId(workspacePath) {
17715
17777
  return best?.agentId ?? null;
17716
17778
  }
17717
17779
  async function adoptThread(input) {
17718
- if (!(0, import_node_fs43.existsSync)(input.worktreePath)) {
17780
+ if (!(0, import_node_fs44.existsSync)(input.worktreePath)) {
17719
17781
  throw new Error(`Worktree not found: ${input.worktreePath}`);
17720
17782
  }
17721
17783
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -17744,18 +17806,18 @@ function conductorDbPath() {
17744
17806
  return CONDUCTOR_DB;
17745
17807
  }
17746
17808
  function listConductorWorkspaces() {
17747
- if (!(0, import_node_fs43.existsSync)(CONDUCTOR_DB)) {
17809
+ if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
17748
17810
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
17749
17811
  }
17750
- const tmp = (0, import_node_fs43.mkdtempSync)((0, import_node_path41.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17751
- const snapshot = (0, import_node_path41.join)(tmp, "conductor.db");
17812
+ const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17813
+ const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
17752
17814
  try {
17753
- (0, import_node_fs43.copyFileSync)(CONDUCTOR_DB, snapshot);
17815
+ (0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
17754
17816
  for (const suffix of ["-wal", "-shm"]) {
17755
17817
  const src = `${CONDUCTOR_DB}${suffix}`;
17756
- if ((0, import_node_fs43.existsSync)(src)) {
17818
+ if ((0, import_node_fs44.existsSync)(src)) {
17757
17819
  try {
17758
- (0, import_node_fs43.copyFileSync)(src, `${snapshot}${suffix}`);
17820
+ (0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
17759
17821
  } catch {
17760
17822
  }
17761
17823
  }
@@ -17831,22 +17893,22 @@ function listConductorWorkspaces() {
17831
17893
  db.close();
17832
17894
  }
17833
17895
  } finally {
17834
- (0, import_node_fs43.rmSync)(tmp, { recursive: true, force: true });
17896
+ (0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
17835
17897
  }
17836
17898
  }
17837
17899
  function importConductorWorkspace(workspaceId) {
17838
- if (!(0, import_node_fs43.existsSync)(CONDUCTOR_DB)) {
17900
+ if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
17839
17901
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
17840
17902
  }
17841
- const tmp = (0, import_node_fs43.mkdtempSync)((0, import_node_path41.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17842
- const snapshot = (0, import_node_path41.join)(tmp, "conductor.db");
17903
+ const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
17904
+ const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
17843
17905
  try {
17844
- (0, import_node_fs43.copyFileSync)(CONDUCTOR_DB, snapshot);
17906
+ (0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
17845
17907
  for (const suffix of ["-wal", "-shm"]) {
17846
17908
  const src = `${CONDUCTOR_DB}${suffix}`;
17847
- if ((0, import_node_fs43.existsSync)(src)) {
17909
+ if ((0, import_node_fs44.existsSync)(src)) {
17848
17910
  try {
17849
- (0, import_node_fs43.copyFileSync)(src, `${snapshot}${suffix}`);
17911
+ (0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
17850
17912
  } catch {
17851
17913
  }
17852
17914
  }
@@ -17864,7 +17926,7 @@ function importConductorWorkspace(workspaceId) {
17864
17926
  ).get(workspaceId);
17865
17927
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
17866
17928
  const worktreePath = String(row.workspacePath);
17867
- if (!(0, import_node_fs43.existsSync)(worktreePath)) {
17929
+ if (!(0, import_node_fs44.existsSync)(worktreePath)) {
17868
17930
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
17869
17931
  }
17870
17932
  let sessionId = null;
@@ -17927,31 +17989,31 @@ function importConductorWorkspace(workspaceId) {
17927
17989
  db.close();
17928
17990
  }
17929
17991
  } finally {
17930
- (0, import_node_fs43.rmSync)(tmp, { recursive: true, force: true });
17992
+ (0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
17931
17993
  }
17932
17994
  }
17933
17995
  async function importConductorWorkspaceAsync(workspaceId) {
17934
17996
  return importConductorWorkspace(workspaceId);
17935
17997
  }
17936
- var import_node_child_process4, import_node_fs43, import_node_os13, import_node_path41, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
17998
+ var import_node_child_process4, import_node_fs44, import_node_os13, import_node_path42, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
17937
17999
  var init_adopt = __esm({
17938
18000
  "src/threads/adopt.ts"() {
17939
18001
  "use strict";
17940
18002
  import_node_child_process4 = require("child_process");
17941
- import_node_fs43 = require("fs");
18003
+ import_node_fs44 = require("fs");
17942
18004
  import_node_os13 = require("os");
17943
- import_node_path41 = require("path");
18005
+ import_node_path42 = require("path");
17944
18006
  import_node_module4 = require("module");
17945
18007
  init_worktree();
17946
18008
  init_thread_store();
17947
- CONDUCTOR_APP_SUPPORT = (0, import_node_path41.join)(
18009
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path42.join)(
17948
18010
  process.env.HOME ?? "",
17949
18011
  "Library",
17950
18012
  "Application Support",
17951
18013
  "com.conductor.app"
17952
18014
  );
17953
- CONDUCTOR_DB = (0, import_node_path41.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
17954
- CURSOR_SDK_STORE = (0, import_node_path41.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
18015
+ CONDUCTOR_DB = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
18016
+ CURSOR_SDK_STORE = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
17955
18017
  }
17956
18018
  });
17957
18019
 
@@ -18018,7 +18080,7 @@ async function openStackLayer(input, _onSetupLine) {
18018
18080
  let createdWorktree = false;
18019
18081
  const trees = await listWorktrees(repoPath);
18020
18082
  const checkedOut = trees.find((w) => w.branch === branchName);
18021
- if (checkedOut?.path && (0, import_node_fs44.existsSync)(checkedOut.path)) {
18083
+ if (checkedOut?.path && (0, import_node_fs45.existsSync)(checkedOut.path)) {
18022
18084
  if (input.reuseExistingWorktree !== false) {
18023
18085
  worktreePath = checkedOut.path;
18024
18086
  } else {
@@ -18160,7 +18222,7 @@ async function initStackFromThread(input, onSetupLine) {
18160
18222
  async function createPrStack(input, onSetupLine) {
18161
18223
  await requireAgent(input.agent);
18162
18224
  const repoPath = await resolveRepoRoot(input.repoPath);
18163
- if (!(0, import_node_fs44.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
18225
+ if (!(0, import_node_fs45.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
18164
18226
  if (!input.branches.length) throw new Error("At least one branch name required");
18165
18227
  const status = await detectGhStack(repoPath);
18166
18228
  if (!status.available) throw new Error(status.reason);
@@ -18227,7 +18289,7 @@ async function createPrStack(input, onSetupLine) {
18227
18289
  }
18228
18290
  }
18229
18291
  const claimed = new Set(threads.map((t) => t.worktreePath));
18230
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs44.existsSync)(bootstrap.worktreePath)) {
18292
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs45.existsSync)(bootstrap.worktreePath)) {
18231
18293
  try {
18232
18294
  await removeWorktree(repoPath, bootstrap.worktreePath, {
18233
18295
  deleteBranch: bootstrap.branchName
@@ -18247,11 +18309,11 @@ function stackAgentDefaultsFrom(input) {
18247
18309
  planMode: input.planMode
18248
18310
  };
18249
18311
  }
18250
- var import_node_fs44;
18312
+ var import_node_fs45;
18251
18313
  var init_stack_layers = __esm({
18252
18314
  "src/threads/stack-layers.ts"() {
18253
18315
  "use strict";
18254
- import_node_fs44 = require("fs");
18316
+ import_node_fs45 = require("fs");
18255
18317
  init_detect();
18256
18318
  init_run();
18257
18319
  init_stack();
@@ -18264,7 +18326,7 @@ var init_stack_layers = __esm({
18264
18326
 
18265
18327
  // src/diff/diff.ts
18266
18328
  async function inspectGitWorktree(worktreePath) {
18267
- if (!worktreePath || !(0, import_node_fs45.existsSync)(worktreePath)) return "missing_worktree";
18329
+ if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) return "missing_worktree";
18268
18330
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
18269
18331
  reject: false
18270
18332
  });
@@ -18272,7 +18334,7 @@ async function inspectGitWorktree(worktreePath) {
18272
18334
  return "ok";
18273
18335
  }
18274
18336
  async function initializeGitRepository(worktreePath) {
18275
- if (!worktreePath || !(0, import_node_fs45.existsSync)(worktreePath)) {
18337
+ if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) {
18276
18338
  throw new Error("Worktree not found");
18277
18339
  }
18278
18340
  const status = await inspectGitWorktree(worktreePath);
@@ -18406,11 +18468,11 @@ new file mode 100644
18406
18468
  };
18407
18469
  }
18408
18470
  async function untrackedPatch(worktreePath, path2, maxHunk) {
18409
- const abs = (0, import_node_path42.join)(worktreePath, path2);
18471
+ const abs = (0, import_node_path43.join)(worktreePath, path2);
18410
18472
  try {
18411
- const st = (0, import_node_fs45.statSync)(abs);
18473
+ const st = (0, import_node_fs46.statSync)(abs);
18412
18474
  if (st.isFile() && st.size > maxHunk) {
18413
- const buf = (0, import_node_fs45.readFileSync)(abs).subarray(0, maxHunk);
18475
+ const buf = (0, import_node_fs46.readFileSync)(abs).subarray(0, maxHunk);
18414
18476
  return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
18415
18477
  }
18416
18478
  } catch {
@@ -18899,8 +18961,8 @@ function isImageRelativePath(relativePath) {
18899
18961
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
18900
18962
  assertSafeRelativePath(relativePath);
18901
18963
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
18902
- const abs = (0, import_node_path42.join)(worktreePath, relativePath);
18903
- const st = (0, import_node_fs45.statSync)(abs);
18964
+ const abs = (0, import_node_path43.join)(worktreePath, relativePath);
18965
+ const st = (0, import_node_fs46.statSync)(abs);
18904
18966
  if (!st.isFile()) {
18905
18967
  throw new Error(`Not a file: ${relativePath}`);
18906
18968
  }
@@ -18909,7 +18971,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
18909
18971
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
18910
18972
  );
18911
18973
  }
18912
- const buf = (0, import_node_fs45.readFileSync)(abs);
18974
+ const buf = (0, import_node_fs46.readFileSync)(abs);
18913
18975
  return {
18914
18976
  path: relativePath,
18915
18977
  contentBase64: buf.toString("base64"),
@@ -18919,12 +18981,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
18919
18981
  function readWorktreeFile(worktreePath, relativePath, opts) {
18920
18982
  assertSafeRelativePath(relativePath);
18921
18983
  const maxBytes = opts?.maxBytes ?? 2e5;
18922
- const abs = (0, import_node_path42.join)(worktreePath, relativePath);
18923
- const st = (0, import_node_fs45.statSync)(abs);
18984
+ const abs = (0, import_node_path43.join)(worktreePath, relativePath);
18985
+ const st = (0, import_node_fs46.statSync)(abs);
18924
18986
  if (!st.isFile()) {
18925
18987
  throw new Error(`Not a file: ${relativePath}`);
18926
18988
  }
18927
- const buf = (0, import_node_fs45.readFileSync)(abs);
18989
+ const buf = (0, import_node_fs46.readFileSync)(abs);
18928
18990
  if (isImageRelativePath(relativePath)) {
18929
18991
  const maxImageBytes = Math.max(maxBytes, 15e6);
18930
18992
  const truncated2 = buf.length > maxImageBytes;
@@ -18967,9 +19029,9 @@ function assertSafeRelativePath(relativePath) {
18967
19029
  }
18968
19030
  function writeWorktreeFile(worktreePath, relativePath, content) {
18969
19031
  assertSafeRelativePath(relativePath);
18970
- const abs = (0, import_node_path42.join)(worktreePath, relativePath);
18971
- (0, import_node_fs45.mkdirSync)((0, import_node_path42.dirname)(abs), { recursive: true });
18972
- (0, import_node_fs45.writeFileSync)(abs, content, "utf8");
19032
+ const abs = (0, import_node_path43.join)(worktreePath, relativePath);
19033
+ (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
19034
+ (0, import_node_fs46.writeFileSync)(abs, content, "utf8");
18973
19035
  return { path: relativePath };
18974
19036
  }
18975
19037
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -18986,12 +19048,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
18986
19048
  truncated: full.files.length > maxFiles
18987
19049
  };
18988
19050
  }
18989
- var import_node_fs45, import_node_path42, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
19051
+ var import_node_fs46, import_node_path43, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
18990
19052
  var init_diff = __esm({
18991
19053
  "src/diff/diff.ts"() {
18992
19054
  "use strict";
18993
- import_node_fs45 = require("fs");
18994
- import_node_path42 = require("path");
19055
+ import_node_fs46 = require("fs");
19056
+ import_node_path43 = require("path");
18995
19057
  init_run();
18996
19058
  init_worktree();
18997
19059
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -19267,7 +19329,7 @@ function parseFrontmatter(content) {
19267
19329
  }
19268
19330
  function readSkill(skillMd, source) {
19269
19331
  try {
19270
- const content = (0, import_node_fs46.readFileSync)(skillMd, "utf8");
19332
+ const content = (0, import_node_fs47.readFileSync)(skillMd, "utf8");
19271
19333
  const { name: fmName, description } = parseFrontmatter(content);
19272
19334
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
19273
19335
  const name = fmName || dirName;
@@ -19286,19 +19348,19 @@ function readSkill(skillMd, source) {
19286
19348
  }
19287
19349
  }
19288
19350
  function scanSkillsDir(dir, source, out) {
19289
- if (!(0, import_node_fs46.existsSync)(dir)) return;
19351
+ if (!(0, import_node_fs47.existsSync)(dir)) return;
19290
19352
  let entries;
19291
19353
  try {
19292
- entries = (0, import_node_fs46.readdirSync)(dir);
19354
+ entries = (0, import_node_fs47.readdirSync)(dir);
19293
19355
  } catch {
19294
19356
  return;
19295
19357
  }
19296
19358
  for (const entry of entries) {
19297
19359
  if (entry.startsWith(".")) continue;
19298
- const skillMd = (0, import_node_path43.join)(dir, entry, "SKILL.md");
19299
- if (!(0, import_node_fs46.existsSync)(skillMd)) continue;
19360
+ const skillMd = (0, import_node_path44.join)(dir, entry, "SKILL.md");
19361
+ if (!(0, import_node_fs47.existsSync)(skillMd)) continue;
19300
19362
  try {
19301
- if (!(0, import_node_fs46.statSync)(skillMd).isFile()) continue;
19363
+ if (!(0, import_node_fs47.statSync)(skillMd).isFile()) continue;
19302
19364
  } catch {
19303
19365
  continue;
19304
19366
  }
@@ -19307,24 +19369,24 @@ function scanSkillsDir(dir, source, out) {
19307
19369
  }
19308
19370
  }
19309
19371
  function scanClaudePluginSkills(pluginsRoot, out) {
19310
- if (!(0, import_node_fs46.existsSync)(pluginsRoot)) return;
19372
+ if (!(0, import_node_fs47.existsSync)(pluginsRoot)) return;
19311
19373
  const walk = (dir, depth, lookingForSkillsDir) => {
19312
19374
  if (depth > 7) return;
19313
19375
  let entries;
19314
19376
  try {
19315
- entries = (0, import_node_fs46.readdirSync)(dir);
19377
+ entries = (0, import_node_fs47.readdirSync)(dir);
19316
19378
  } catch {
19317
19379
  return;
19318
19380
  }
19319
19381
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
19320
- const skill = readSkill((0, import_node_path43.join)(dir, "SKILL.md"), "cli");
19382
+ const skill = readSkill((0, import_node_path44.join)(dir, "SKILL.md"), "cli");
19321
19383
  if (skill) out.push(skill);
19322
19384
  }
19323
19385
  for (const entry of entries) {
19324
19386
  if (entry === "node_modules" || entry === ".git") continue;
19325
- const full = (0, import_node_path43.join)(dir, entry);
19387
+ const full = (0, import_node_path44.join)(dir, entry);
19326
19388
  try {
19327
- if (!(0, import_node_fs46.statSync)(full).isDirectory()) continue;
19389
+ if (!(0, import_node_fs47.statSync)(full).isDirectory()) continue;
19328
19390
  } catch {
19329
19391
  continue;
19330
19392
  }
@@ -19342,17 +19404,17 @@ function discoverSkills(worktreePath) {
19342
19404
  const home = (0, import_node_os14.homedir)();
19343
19405
  const collected = [];
19344
19406
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
19345
- scanSkillsDir((0, import_node_path43.join)(worktreePath, rel), "workspace", collected);
19407
+ scanSkillsDir((0, import_node_path44.join)(worktreePath, rel), "workspace", collected);
19346
19408
  }
19347
19409
  for (const abs of [
19348
- (0, import_node_path43.join)(home, ".claude/skills"),
19349
- (0, import_node_path43.join)(home, ".cursor/skills"),
19350
- (0, import_node_path43.join)(home, ".sideboard/skills"),
19351
- (0, import_node_path43.join)(home, ".brightsy/skills")
19410
+ (0, import_node_path44.join)(home, ".claude/skills"),
19411
+ (0, import_node_path44.join)(home, ".cursor/skills"),
19412
+ (0, import_node_path44.join)(home, ".sideboard/skills"),
19413
+ (0, import_node_path44.join)(home, ".brightsy/skills")
19352
19414
  ]) {
19353
19415
  scanSkillsDir(abs, "user", collected);
19354
19416
  }
19355
- scanClaudePluginSkills((0, import_node_path43.join)(home, ".claude/plugins"), collected);
19417
+ scanClaudePluginSkills((0, import_node_path44.join)(home, ".claude/plugins"), collected);
19356
19418
  collected.push(...bundledSkills());
19357
19419
  const rank = {
19358
19420
  workspace: 0,
@@ -19378,7 +19440,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
19378
19440
  \u2026(truncated)` : body;
19379
19441
  }
19380
19442
  }
19381
- const raw = (0, import_node_fs46.readFileSync)(skillPath, "utf8");
19443
+ const raw = (0, import_node_fs47.readFileSync)(skillPath, "utf8");
19382
19444
  if (raw.startsWith("---")) {
19383
19445
  const end = raw.indexOf("\n---", 3);
19384
19446
  if (end >= 0) {
@@ -19392,13 +19454,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
19392
19454
 
19393
19455
  \u2026(truncated)` : raw;
19394
19456
  }
19395
- var import_node_fs46, import_node_os14, import_node_path43, BUNDLED_SKILL_PREFIX;
19457
+ var import_node_fs47, import_node_os14, import_node_path44, BUNDLED_SKILL_PREFIX;
19396
19458
  var init_discover = __esm({
19397
19459
  "src/skills/discover.ts"() {
19398
19460
  "use strict";
19399
- import_node_fs46 = require("fs");
19461
+ import_node_fs47 = require("fs");
19400
19462
  import_node_os14 = require("os");
19401
- import_node_path43 = require("path");
19463
+ import_node_path44 = require("path");
19402
19464
  init_long_running();
19403
19465
  BUNDLED_SKILL_PREFIX = "bundled:";
19404
19466
  }
@@ -19492,8 +19554,8 @@ var init_expand = __esm({
19492
19554
  // src/skills/detached-job-path.ts
19493
19555
  function detachedJobScriptIn(dir) {
19494
19556
  for (const name of DETACHED_JOB_FILENAMES) {
19495
- const script = (0, import_node_path44.join)(dir, "scripts", name);
19496
- if ((0, import_node_fs47.existsSync)(script)) return script;
19557
+ const script = (0, import_node_path45.join)(dir, "scripts", name);
19558
+ if ((0, import_node_fs48.existsSync)(script)) return script;
19497
19559
  }
19498
19560
  return null;
19499
19561
  }
@@ -19505,11 +19567,11 @@ function packagedDetachedJobPath() {
19505
19567
  function resolveDetachedJobScript() {
19506
19568
  const packaged = packagedDetachedJobPath();
19507
19569
  if (packaged) return packaged;
19508
- let dir = (0, import_node_path44.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
19570
+ let dir = (0, import_node_path45.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
19509
19571
  for (let i = 0; i < 8; i++) {
19510
19572
  const candidate = detachedJobScriptIn(dir);
19511
19573
  if (candidate) return candidate;
19512
- const parent = (0, import_node_path44.dirname)(dir);
19574
+ const parent = (0, import_node_path45.dirname)(dir);
19513
19575
  if (parent === dir) break;
19514
19576
  dir = parent;
19515
19577
  }
@@ -19520,12 +19582,12 @@ function formatDetachedJobInvoke(scriptPath) {
19520
19582
  if (resolved) return `node ${JSON.stringify(resolved)}`;
19521
19583
  return "node scripts/detached-job.cjs";
19522
19584
  }
19523
- var import_node_fs47, import_node_path44, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
19585
+ var import_node_fs48, import_node_path45, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
19524
19586
  var init_detached_job_path = __esm({
19525
19587
  "src/skills/detached-job-path.ts"() {
19526
19588
  "use strict";
19527
- import_node_fs47 = require("fs");
19528
- import_node_path44 = require("path");
19589
+ import_node_fs48 = require("fs");
19590
+ import_node_path45 = require("path");
19529
19591
  import_node_url3 = require("url");
19530
19592
  init_packaged_runtime();
19531
19593
  import_meta3 = {};
@@ -19705,11 +19767,13 @@ function formatPrGateDirective() {
19705
19767
  }
19706
19768
  function formatProcessGuideDirective(opts) {
19707
19769
  const worktree = opts?.worktreePath?.trim();
19708
- const hasGraphSkill = !!worktree && (0, import_node_fs48.existsSync)((0, import_node_path45.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
19709
- const hasReviewSkill = !!worktree && (0, import_node_fs48.existsSync)((0, import_node_path45.join)(worktree, ".claude/skills/review/SKILL.md"));
19770
+ const hasGraphSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
19771
+ const hasReviewSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/review/SKILL.md"));
19772
+ const hasInstallSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
19710
19773
  return [
19711
19774
  "Process guides (recurring work only):",
19712
19775
  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,
19776
+ 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,
19713
19777
  "- 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`.",
19714
19778
  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.",
19715
19779
  "- 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."
@@ -19743,12 +19807,12 @@ function formatArtifactDirective() {
19743
19807
  function formatUiReminder() {
19744
19808
  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.";
19745
19809
  }
19746
- var import_node_fs48, import_node_path45, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
19810
+ var import_node_fs49, import_node_path46, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
19747
19811
  var init_instructions = __esm({
19748
19812
  "src/agents/instructions.ts"() {
19749
19813
  "use strict";
19750
- import_node_fs48 = require("fs");
19751
- import_node_path45 = require("path");
19814
+ import_node_fs49 = require("fs");
19815
+ import_node_path46 = require("path");
19752
19816
  init_git_auth_mode();
19753
19817
  init_worktree_labels();
19754
19818
  init_detached_job_path();
@@ -20101,40 +20165,40 @@ __export(plan_file_exports, {
20101
20165
  writePlanFile: () => writePlanFile
20102
20166
  });
20103
20167
  function ensureAttachmentsGitignore(worktreePath) {
20104
- const gitignoreAbs = (0, import_node_path46.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20105
- if ((0, import_node_fs49.existsSync)(gitignoreAbs)) return;
20106
- (0, import_node_fs49.mkdirSync)((0, import_node_path46.dirname)(gitignoreAbs), { recursive: true });
20107
- (0, import_node_fs49.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20168
+ const gitignoreAbs = (0, import_node_path47.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
20169
+ if ((0, import_node_fs50.existsSync)(gitignoreAbs)) return;
20170
+ (0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(gitignoreAbs), { recursive: true });
20171
+ (0, import_node_fs50.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
20108
20172
  }
20109
20173
  function planFileAbs(worktreePath) {
20110
- return (0, import_node_path46.join)(worktreePath, PLAN_FILE_REL);
20174
+ return (0, import_node_path47.join)(worktreePath, PLAN_FILE_REL);
20111
20175
  }
20112
20176
  function readTextIfPresent2(abs) {
20113
- if (!(0, import_node_fs49.existsSync)(abs)) return null;
20177
+ if (!(0, import_node_fs50.existsSync)(abs)) return null;
20114
20178
  try {
20115
- const content = (0, import_node_fs49.readFileSync)(abs, "utf8");
20179
+ const content = (0, import_node_fs50.readFileSync)(abs, "utf8");
20116
20180
  return content.trim() ? content : null;
20117
20181
  } catch {
20118
20182
  return null;
20119
20183
  }
20120
20184
  }
20121
20185
  function readPlanFile(worktreePath) {
20122
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path46.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path46.join)(worktreePath, LEGACY_PLAN_FILE_REL));
20186
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path47.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path47.join)(worktreePath, LEGACY_PLAN_FILE_REL));
20123
20187
  }
20124
20188
  function writePlanFile(worktreePath, content) {
20125
20189
  ensureAttachmentsGitignore(worktreePath);
20126
20190
  const abs = planFileAbs(worktreePath);
20127
- (0, import_node_fs49.mkdirSync)((0, import_node_path46.dirname)(abs), { recursive: true });
20191
+ (0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(abs), { recursive: true });
20128
20192
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
20129
- (0, import_node_fs49.writeFileSync)(abs, body, "utf8");
20193
+ (0, import_node_fs50.writeFileSync)(abs, body, "utf8");
20130
20194
  return PLAN_FILE_REL;
20131
20195
  }
20132
- var import_node_fs49, import_node_path46;
20196
+ var import_node_fs50, import_node_path47;
20133
20197
  var init_plan_file = __esm({
20134
20198
  "src/plan/plan-file.ts"() {
20135
20199
  "use strict";
20136
- import_node_fs49 = require("fs");
20137
- import_node_path46 = require("path");
20200
+ import_node_fs50 = require("fs");
20201
+ import_node_path47 = require("path");
20138
20202
  init_workspace_scratch();
20139
20203
  init_plan_present();
20140
20204
  init_plan_present();
@@ -20182,13 +20246,13 @@ var init_sync_branch = __esm({
20182
20246
 
20183
20247
  // src/agents/cursor-store.ts
20184
20248
  function cursorSdkStoreDir(threadId) {
20185
- const root = (0, import_node_path47.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
20249
+ const root = (0, import_node_path48.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
20186
20250
  const id = sanitizeCursorStoreSegment(threadId);
20187
20251
  if (!id) return root;
20188
- return (0, import_node_path47.join)(root, "threads", id);
20252
+ return (0, import_node_path48.join)(root, "threads", id);
20189
20253
  }
20190
20254
  function cursorSdkRunsNdjsonPath(threadId) {
20191
- return (0, import_node_path47.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
20255
+ return (0, import_node_path48.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
20192
20256
  }
20193
20257
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
20194
20258
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -20201,11 +20265,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
20201
20265
  function sanitizeCursorStoreSegment(threadId) {
20202
20266
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
20203
20267
  }
20204
- var import_node_path47, CURSOR_SDK_STORE_DIR;
20268
+ var import_node_path48, CURSOR_SDK_STORE_DIR;
20205
20269
  var init_cursor_store = __esm({
20206
20270
  "src/agents/cursor-store.ts"() {
20207
20271
  "use strict";
20208
- import_node_path47 = require("path");
20272
+ import_node_path48 = require("path");
20209
20273
  init_paths();
20210
20274
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
20211
20275
  }
@@ -20227,9 +20291,9 @@ function recoverFinishedCursorRun(opts) {
20227
20291
  return best;
20228
20292
  }
20229
20293
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
20230
- if (!(0, import_node_fs50.existsSync)(runsPath)) return null;
20294
+ if (!(0, import_node_fs51.existsSync)(runsPath)) return null;
20231
20295
  try {
20232
- const lines = (0, import_node_fs50.readFileSync)(runsPath, "utf8").split("\n");
20296
+ const lines = (0, import_node_fs51.readFileSync)(runsPath, "utf8").split("\n");
20233
20297
  let best = null;
20234
20298
  for (const line of lines) {
20235
20299
  const trimmed = line.trim();
@@ -20255,11 +20319,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
20255
20319
  return null;
20256
20320
  }
20257
20321
  }
20258
- var import_node_fs50;
20322
+ var import_node_fs51;
20259
20323
  var init_cursor_recover = __esm({
20260
20324
  "src/agents/cursor-recover.ts"() {
20261
20325
  "use strict";
20262
- import_node_fs50 = require("fs");
20326
+ import_node_fs51 = require("fs");
20263
20327
  init_cursor_store();
20264
20328
  }
20265
20329
  });
@@ -20391,13 +20455,13 @@ async function startOrchestration(opts) {
20391
20455
  }
20392
20456
  return updated;
20393
20457
  }
20394
- var import_node_events, import_node_fs51, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
20458
+ var import_node_events, import_node_fs52, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
20395
20459
  var init_orchestrator = __esm({
20396
20460
  "src/orchestrator/orchestrator.ts"() {
20397
20461
  "use strict";
20398
20462
  import_node_events = require("events");
20399
20463
  init_outbound_watch();
20400
- import_node_fs51 = require("fs");
20464
+ import_node_fs52 = require("fs");
20401
20465
  init_error_detail();
20402
20466
  init_run();
20403
20467
  init_stale_lock();
@@ -20570,7 +20634,7 @@ var init_orchestrator = __esm({
20570
20634
  }
20571
20635
  continue;
20572
20636
  }
20573
- if (!(0, import_node_fs51.existsSync)(thread.worktreePath)) {
20637
+ if (!(0, import_node_fs52.existsSync)(thread.worktreePath)) {
20574
20638
  setStatus(thread.id, "broken", "Worktree missing on disk");
20575
20639
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
20576
20640
  continue;
@@ -22460,7 +22524,7 @@ var init_orchestrator = __esm({
22460
22524
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
22461
22525
  return restored2;
22462
22526
  }
22463
- if (!(0, import_node_fs51.existsSync)(thread.worktreePath)) {
22527
+ if (!(0, import_node_fs52.existsSync)(thread.worktreePath)) {
22464
22528
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
22465
22529
  throw new Error(
22466
22530
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -25090,7 +25154,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
25090
25154
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
25091
25155
  var import_zod8 = require("zod");
25092
25156
  var import_node_crypto13 = require("crypto");
25093
- var import_node_path50 = require("path");
25157
+ var import_node_path51 = require("path");
25094
25158
  init_orchestrator();
25095
25159
  init_worktree();
25096
25160
  init_global_workspace();
@@ -26674,27 +26738,27 @@ init_gh_errors();
26674
26738
  init_git_auth_mode();
26675
26739
 
26676
26740
  // src/board/load-home-board.ts
26677
- var import_node_fs53 = require("fs");
26678
- var import_node_path49 = require("path");
26741
+ var import_node_fs54 = require("fs");
26742
+ var import_node_path50 = require("path");
26679
26743
  init_worktree();
26680
26744
  init_paths();
26681
26745
 
26682
26746
  // src/board/board-pins.ts
26683
26747
  var import_node_crypto12 = require("crypto");
26684
- var import_node_fs52 = require("fs");
26685
- var import_node_path48 = require("path");
26748
+ var import_node_fs53 = require("fs");
26749
+ var import_node_path49 = require("path");
26686
26750
  init_paths();
26687
26751
  init_home_board();
26688
26752
  var FILE = "home-board-pins.json";
26689
26753
  var VERSION = 1;
26690
26754
  function pinsFile() {
26691
- return (0, import_node_path48.join)(appDataDir(), FILE);
26755
+ return (0, import_node_path49.join)(appDataDir(), FILE);
26692
26756
  }
26693
26757
  function readDisk() {
26694
26758
  const path2 = pinsFile();
26695
- if (!(0, import_node_fs52.existsSync)(path2)) return [];
26759
+ if (!(0, import_node_fs53.existsSync)(path2)) return [];
26696
26760
  try {
26697
- const raw = JSON.parse((0, import_node_fs52.readFileSync)(path2, "utf8"));
26761
+ const raw = JSON.parse((0, import_node_fs53.readFileSync)(path2, "utf8"));
26698
26762
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
26699
26763
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
26700
26764
  } catch {
@@ -26702,8 +26766,8 @@ function readDisk() {
26702
26766
  }
26703
26767
  }
26704
26768
  function writeDisk(items) {
26705
- (0, import_node_fs52.mkdirSync)(appDataDir(), { recursive: true });
26706
- (0, import_node_fs52.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
26769
+ (0, import_node_fs53.mkdirSync)(appDataDir(), { recursive: true });
26770
+ (0, import_node_fs53.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
26707
26771
  }
26708
26772
  function listBoardPins() {
26709
26773
  return readDisk();
@@ -26755,7 +26819,7 @@ function replaceBoardPins(items) {
26755
26819
  }
26756
26820
  function clearBoardPins() {
26757
26821
  try {
26758
- (0, import_node_fs52.unlinkSync)(pinsFile());
26822
+ (0, import_node_fs53.unlinkSync)(pinsFile());
26759
26823
  } catch {
26760
26824
  }
26761
26825
  }
@@ -26772,7 +26836,7 @@ function homeBoardWorkspaceKey(workspaces) {
26772
26836
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
26773
26837
  }
26774
26838
  function cacheFile() {
26775
- return (0, import_node_path49.join)(appDataDir(), "home-board-cache.json");
26839
+ return (0, import_node_path50.join)(appDataDir(), "home-board-cache.json");
26776
26840
  }
26777
26841
  function emptyInputs() {
26778
26842
  return {
@@ -26798,9 +26862,9 @@ function shouldCacheHomeBoardInputs(inputs) {
26798
26862
  }
26799
26863
  function readDiskCache() {
26800
26864
  const path2 = cacheFile();
26801
- if (!(0, import_node_fs53.existsSync)(path2)) return null;
26865
+ if (!(0, import_node_fs54.existsSync)(path2)) return null;
26802
26866
  try {
26803
- const raw = JSON.parse((0, import_node_fs53.readFileSync)(path2, "utf8"));
26867
+ const raw = JSON.parse((0, import_node_fs54.readFileSync)(path2, "utf8"));
26804
26868
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
26805
26869
  return null;
26806
26870
  }
@@ -26814,14 +26878,14 @@ function readDiskCache() {
26814
26878
  }
26815
26879
  function writeDiskCache(entry) {
26816
26880
  try {
26817
- (0, import_node_fs53.mkdirSync)(appDataDir(), { recursive: true });
26818
- (0, import_node_fs53.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
26881
+ (0, import_node_fs54.mkdirSync)(appDataDir(), { recursive: true });
26882
+ (0, import_node_fs54.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
26819
26883
  } catch {
26820
26884
  }
26821
26885
  }
26822
26886
  function deleteDiskCache() {
26823
26887
  try {
26824
- (0, import_node_fs53.unlinkSync)(cacheFile());
26888
+ (0, import_node_fs54.unlinkSync)(cacheFile());
26825
26889
  } catch {
26826
26890
  }
26827
26891
  }
@@ -27129,7 +27193,7 @@ async function startMcpServer() {
27129
27193
  async () => {
27130
27194
  const threads = orch.getThreads(true);
27131
27195
  const lines = threads.map((t) => {
27132
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path50.basename)(t.repoPath) || t.repoPath;
27196
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path51.basename)(t.repoPath) || t.repoPath;
27133
27197
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
27134
27198
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
27135
27199
  const preview = lastMessagePreview(t.messages, 80);
@@ -30089,9 +30153,9 @@ var import_node_http3 = require("http");
30089
30153
  var import_ws3 = require("ws");
30090
30154
 
30091
30155
  // src/slack/relay-static.ts
30092
- var import_node_fs54 = require("fs");
30156
+ var import_node_fs55 = require("fs");
30093
30157
  var import_promises = require("fs/promises");
30094
- var import_node_path51 = __toESM(require("path"), 1);
30158
+ var import_node_path52 = __toESM(require("path"), 1);
30095
30159
  var TYPES = {
30096
30160
  ".css": "text/css; charset=utf-8",
30097
30161
  ".html": "text/html; charset=utf-8",
@@ -30122,9 +30186,9 @@ function resolveStaticPath(root, requestUrl) {
30122
30186
  return null;
30123
30187
  }
30124
30188
  if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
30125
- const rootResolved = import_node_path51.default.resolve(root);
30126
- const candidate = import_node_path51.default.resolve(rootResolved, `.${pathname}`);
30127
- if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path51.default.sep)) {
30189
+ const rootResolved = import_node_path52.default.resolve(root);
30190
+ const candidate = import_node_path52.default.resolve(rootResolved, `.${pathname}`);
30191
+ if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path52.default.sep)) {
30128
30192
  return null;
30129
30193
  }
30130
30194
  return candidate;
@@ -30138,7 +30202,7 @@ async function fileSize(file) {
30138
30202
  }
30139
30203
  }
30140
30204
  function sendFile(req, res, file, size) {
30141
- const ext = import_node_path51.default.extname(file).toLowerCase();
30205
+ const ext = import_node_path52.default.extname(file).toLowerCase();
30142
30206
  res.writeHead(200, {
30143
30207
  "Content-Type": TYPES[ext] ?? "application/octet-stream",
30144
30208
  "Content-Length": size,
@@ -30148,7 +30212,7 @@ function sendFile(req, res, file, size) {
30148
30212
  res.end();
30149
30213
  return true;
30150
30214
  }
30151
- (0, import_node_fs54.createReadStream)(file).pipe(res);
30215
+ (0, import_node_fs55.createReadStream)(file).pipe(res);
30152
30216
  return true;
30153
30217
  }
30154
30218
  async function tryServeStatic(req, res, root) {
@@ -30157,7 +30221,7 @@ async function tryServeStatic(req, res, root) {
30157
30221
  if (!candidate) return false;
30158
30222
  const direct = await fileSize(candidate);
30159
30223
  if (direct != null) return sendFile(req, res, candidate, direct);
30160
- const asIndex = import_node_path51.default.join(candidate, "index.html");
30224
+ const asIndex = import_node_path52.default.join(candidate, "index.html");
30161
30225
  const indexSize = await fileSize(asIndex);
30162
30226
  if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
30163
30227
  return false;