@sideboard-ai/core 0.1.198 → 0.1.200

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/{abletime-JINF5KJV.js → abletime-345SE3B4.js} +2 -2
  2. package/dist/{abletime-HR6P4GJH.js → abletime-KGPD3UUJ.js} +2 -2
  3. package/dist/{agents-5TZY6LLX.js → agents-N7WXOGN6.js} +28 -4
  4. package/dist/{agents-AQQKPD46.js → agents-ZRIFDXCB.js} +28 -4
  5. package/dist/{app-settings-5KHVKJKO.js → app-settings-AXCURTZJ.js} +11 -1
  6. package/dist/{app-settings-J775CYOO.js → app-settings-V6IHESEQ.js} +11 -1
  7. package/dist/{chunk-SYXSSU7G.js → chunk-5XSDGJMP.js} +369 -4
  8. package/dist/{chunk-DROELG52.js → chunk-62IMZIIZ.js} +58 -41
  9. package/dist/{chunk-E37JHCO3.js → chunk-7AHAABKN.js} +1 -1
  10. package/dist/{chunk-S5GLSRLP.js → chunk-CXFW5LIH.js} +48 -1
  11. package/dist/{chunk-6YTI2HBG.js → chunk-EWDE54OI.js} +2 -2
  12. package/dist/{chunk-AH6WIBLY.js → chunk-ISV5IFH3.js} +48 -1
  13. package/dist/{chunk-DP4TKAMZ.js → chunk-NXM45OS3.js} +1 -1
  14. package/dist/{chunk-6YS5IKD2.js → chunk-O2DRYD2B.js} +59 -42
  15. package/dist/{chunk-S4QCBBXS.js → chunk-OSPE25A7.js} +1 -1
  16. package/dist/{chunk-HZTHWU6A.js → chunk-PDMNYCPL.js} +2 -2
  17. package/dist/{chunk-KTHRWHA3.js → chunk-PGQGP4FD.js} +1 -1
  18. package/dist/{chunk-EA67VQM2.js → chunk-PKUPOVKP.js} +369 -4
  19. package/dist/{coordinator-prompt-IX66YUJ2.js → coordinator-prompt-2RWBH6W7.js} +3 -3
  20. package/dist/{coordinator-prompt-LYKS3YNG.js → coordinator-prompt-AL62H73U.js} +3 -3
  21. package/dist/{global-workspace-SNJ2Z6SL.js → global-workspace-VAO3BQP5.js} +3 -3
  22. package/dist/{global-workspace-4QX6UEOY.js → global-workspace-Y5KKGXN7.js} +3 -3
  23. package/dist/index.cjs +766 -280
  24. package/dist/index.d.cts +116 -11
  25. package/dist/index.d.ts +116 -11
  26. package/dist/index.js +42 -8
  27. package/dist/mcp/run-stdio.cjs +374 -276
  28. package/dist/mcp/run-stdio.js +8 -8
  29. package/dist/{orchestrator-L2H42HPW.js → orchestrator-D2EJ4Z7Z.js} +5 -5
  30. package/dist/{orchestrator-6ZNKCPNL.js → orchestrator-DPHIMK44.js} +5 -5
  31. package/dist/{workspaces-URMUVGAQ.js → workspaces-DZZQM745.js} +3 -3
  32. package/dist/{workspaces-UTOYGBYB.js → workspaces-HEKFQP4B.js} +3 -3
  33. package/dist/{worktree-R43JOR4V.js → worktree-ENRMJUI3.js} +2 -2
  34. package/dist/{worktree-RM6UWNGZ.js → worktree-IEUSQ63V.js} +2 -2
  35. package/package.json +1 -1
@@ -3478,6 +3478,30 @@ var init_branch_prefix = __esm({
3478
3478
  }
3479
3479
  });
3480
3480
 
3481
+ // src/store/usage-on-limit.ts
3482
+ function isUsageOnLimit(value) {
3483
+ return value === "keep_going" || value === "confirm" || value === "switch_agent" || value === "wait_reset";
3484
+ }
3485
+ function resolveUsageOnLimit(advanced = {}) {
3486
+ if (isUsageOnLimit(advanced.usageOnLimit)) return advanced.usageOnLimit;
3487
+ if (advanced.confirmClaudeUsageOverLimit) return "confirm";
3488
+ if (advanced.orchestrationQuotaOnLimit === "wait_reset") return "wait_reset";
3489
+ if (advanced.orchestrationQuotaOnLimit === "switch_agent") return "switch_agent";
3490
+ return "keep_going";
3491
+ }
3492
+ var USAGE_ON_LIMIT_VALUES;
3493
+ var init_usage_on_limit = __esm({
3494
+ "src/store/usage-on-limit.ts"() {
3495
+ "use strict";
3496
+ USAGE_ON_LIMIT_VALUES = [
3497
+ "keep_going",
3498
+ "confirm",
3499
+ "switch_agent",
3500
+ "wait_reset"
3501
+ ];
3502
+ }
3503
+ });
3504
+
3481
3505
  // src/store/issue-source-labels.ts
3482
3506
  function issueSourceLabel(source) {
3483
3507
  if (source && source in ISSUE_SOURCE_LABELS) {
@@ -3506,6 +3530,7 @@ __export(app_settings_exports, {
3506
3530
  HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
3507
3531
  ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
3508
3532
  PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
3533
+ USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
3509
3534
  appSettingsPath: () => appSettingsPath,
3510
3535
  applyAppEnvironment: () => applyAppEnvironment,
3511
3536
  autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
@@ -3522,6 +3547,7 @@ __export(app_settings_exports, {
3522
3547
  childEnvWithAppSettings: () => childEnvWithAppSettings,
3523
3548
  claudeChromeEnabled: () => claudeChromeEnabled,
3524
3549
  claudeUserSettingsPath: () => claudeUserSettingsPath,
3550
+ confirmClaudeUsageOverLimitEnabled: () => confirmClaudeUsageOverLimitEnabled,
3525
3551
  cowboyModeEnabled: () => cowboyModeEnabled,
3526
3552
  deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
3527
3553
  disconnectAbleTimeConnection: () => disconnectAbleTimeConnection,
@@ -3551,6 +3577,7 @@ __export(app_settings_exports, {
3551
3577
  isAbleTimeConnected: () => isAbleTimeConnected,
3552
3578
  isIssueSourceConnected: () => isIssueSourceConnected,
3553
3579
  isLinearConnected: () => isLinearConnected,
3580
+ isUsageOnLimit: () => isUsageOnLimit,
3554
3581
  issueSourceLabel: () => issueSourceLabel,
3555
3582
  loadAppSettings: () => loadAppSettings,
3556
3583
  maxConcurrentAgents: () => maxConcurrentAgents,
@@ -3566,6 +3593,7 @@ __export(app_settings_exports, {
3566
3593
  resolveNewThreadOptions: () => resolveNewThreadOptions,
3567
3594
  resolveOrchestratorDefaults: () => resolveOrchestratorDefaults,
3568
3595
  resolveThreadDefaults: () => resolveThreadDefaults,
3596
+ resolveUsageOnLimit: () => resolveUsageOnLimit,
3569
3597
  resolveViewerProfile: () => resolveViewerProfile,
3570
3598
  resolveViewerProfileForRepo: () => resolveViewerProfileForRepo,
3571
3599
  saveAbleTimeConnection: () => saveAbleTimeConnection,
@@ -3585,6 +3613,7 @@ __export(app_settings_exports, {
3585
3613
  updateIntegrationsSettings: () => updateIntegrationsSettings,
3586
3614
  updateOpencodeSettings: () => updateOpencodeSettings,
3587
3615
  updateProjectProfileSettings: () => updateProjectProfileSettings,
3616
+ usageOnLimit: () => usageOnLimit,
3588
3617
  writeViewerContext: () => writeViewerContext
3589
3618
  });
3590
3619
  function emptyPublicIntegrations() {
@@ -3949,6 +3978,12 @@ function normalizeAdvanced(raw) {
3949
3978
  if (typeof source.showCost === "boolean") {
3950
3979
  out.showCost = source.showCost;
3951
3980
  }
3981
+ if (isUsageOnLimit(source.usageOnLimit)) {
3982
+ out.usageOnLimit = source.usageOnLimit;
3983
+ }
3984
+ if (typeof source.confirmClaudeUsageOverLimit === "boolean") {
3985
+ out.confirmClaudeUsageOverLimit = source.confirmClaudeUsageOverLimit;
3986
+ }
3952
3987
  if (typeof source.autoArchiveOnMerge === "boolean") {
3953
3988
  out.autoArchiveOnMerge = source.autoArchiveOnMerge;
3954
3989
  }
@@ -4811,6 +4846,17 @@ function updateAdvancedSettings(patch) {
4811
4846
  if (typeof patch.showCost === "boolean") {
4812
4847
  advanced.showCost = patch.showCost;
4813
4848
  }
4849
+ if (isUsageOnLimit(patch.usageOnLimit)) {
4850
+ advanced.usageOnLimit = patch.usageOnLimit;
4851
+ advanced.confirmClaudeUsageOverLimit = patch.usageOnLimit === "confirm";
4852
+ if (patch.usageOnLimit === "switch_agent" || patch.usageOnLimit === "wait_reset") {
4853
+ advanced.orchestrationQuotaOnLimit = patch.usageOnLimit;
4854
+ }
4855
+ } else if (typeof patch.confirmClaudeUsageOverLimit === "boolean") {
4856
+ advanced.confirmClaudeUsageOverLimit = patch.confirmClaudeUsageOverLimit;
4857
+ if (patch.confirmClaudeUsageOverLimit) advanced.usageOnLimit = "confirm";
4858
+ else if (advanced.usageOnLimit === "confirm") advanced.usageOnLimit = "keep_going";
4859
+ }
4814
4860
  if (typeof patch.autoArchiveOnMerge === "boolean") {
4815
4861
  advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
4816
4862
  }
@@ -4873,14 +4919,21 @@ function cowboyModeEnabled(settings = loadAppSettings()) {
4873
4919
  function showCostEnabled(settings = loadAppSettings()) {
4874
4920
  return Boolean(settings.advanced.showCost);
4875
4921
  }
4922
+ function confirmClaudeUsageOverLimitEnabled(settings = loadAppSettings()) {
4923
+ return usageOnLimit(settings) === "confirm";
4924
+ }
4876
4925
  function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
4877
4926
  return Boolean(settings.advanced.autoArchiveOnMerge);
4878
4927
  }
4879
4928
  function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
4880
4929
  return Boolean(settings.advanced.autoCleanupOrphans);
4881
4930
  }
4931
+ function usageOnLimit(settings = loadAppSettings()) {
4932
+ return resolveUsageOnLimit(settings.advanced);
4933
+ }
4882
4934
  function orchestrationQuotaOnLimit(settings = loadAppSettings()) {
4883
- return settings.advanced.orchestrationQuotaOnLimit ?? "switch_agent";
4935
+ const action = usageOnLimit(settings);
4936
+ return action === "wait_reset" ? "wait_reset" : "switch_agent";
4884
4937
  }
4885
4938
  function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
4886
4939
  const preferred = settings.advanced.orchestrationQuotaFallbackAgent;
@@ -4995,6 +5048,8 @@ var init_app_settings = __esm({
4995
5048
  init_private_file();
4996
5049
  init_secret_vault();
4997
5050
  init_branch_prefix();
5051
+ init_usage_on_limit();
5052
+ init_usage_on_limit();
4998
5053
  init_issue_source_labels();
4999
5054
  init_account_profile();
5000
5055
  HARNESS_ENV_KEYS = {
@@ -12189,6 +12244,30 @@ var init_session_quota = __esm({
12189
12244
  }
12190
12245
  });
12191
12246
 
12247
+ // src/agents/claude-usage.ts
12248
+ var init_claude_usage = __esm({
12249
+ "src/agents/claude-usage.ts"() {
12250
+ "use strict";
12251
+ }
12252
+ });
12253
+
12254
+ // src/agents/claude-usage-client.ts
12255
+ var import_node_fs33, import_node_os13, import_node_path33, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
12256
+ var init_claude_usage_client = __esm({
12257
+ "src/agents/claude-usage-client.ts"() {
12258
+ "use strict";
12259
+ import_node_fs33 = require("fs");
12260
+ import_node_os13 = require("os");
12261
+ import_node_path33 = require("path");
12262
+ init_run();
12263
+ init_fetch();
12264
+ init_app_settings();
12265
+ init_claude_usage();
12266
+ CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
12267
+ CLAUDE_USAGE_STALE_OK_MS = 30 * 6e4;
12268
+ }
12269
+ });
12270
+
12192
12271
  // src/agents/install.ts
12193
12272
  var init_install = __esm({
12194
12273
  "src/agents/install.ts"() {
@@ -12223,6 +12302,8 @@ var init_agents = __esm({
12223
12302
  init_opencode();
12224
12303
  init_list_models();
12225
12304
  init_session_quota();
12305
+ init_claude_usage();
12306
+ init_claude_usage_client();
12226
12307
  init_orchestrator_capable();
12227
12308
  init_path();
12228
12309
  init_install();
@@ -12238,15 +12319,15 @@ var init_agents = __esm({
12238
12319
 
12239
12320
  // src/hook/worktree-pkg-cache.ts
12240
12321
  function worktreePkgCacheRoot(worktreePath) {
12241
- return (0, import_node_path33.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
12322
+ return (0, import_node_path34.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
12242
12323
  }
12243
12324
  function worktreePkgCacheEnv(worktreePath) {
12244
12325
  const root = worktreePkgCacheRoot(worktreePath);
12245
- const store = (0, import_node_path33.join)(root, "pnpm-store");
12246
- const pnpmCache = (0, import_node_path33.join)(root, "pnpm");
12247
- const npmCache = (0, import_node_path33.join)(root, "npm");
12248
- const nodeGyp = (0, import_node_path33.join)(root, "node-gyp");
12249
- const electron = (0, import_node_path33.join)(root, "electron");
12326
+ const store = (0, import_node_path34.join)(root, "pnpm-store");
12327
+ const pnpmCache = (0, import_node_path34.join)(root, "pnpm");
12328
+ const npmCache = (0, import_node_path34.join)(root, "npm");
12329
+ const nodeGyp = (0, import_node_path34.join)(root, "node-gyp");
12330
+ const electron = (0, import_node_path34.join)(root, "electron");
12250
12331
  return {
12251
12332
  npm_config_store_dir: store,
12252
12333
  PNPM_STORE_DIR: store,
@@ -12268,8 +12349,8 @@ function fillGroup(env, keys, values) {
12268
12349
  }
12269
12350
  }
12270
12351
  function ensureWorktreePkgCacheDirs(worktreePath) {
12271
- if (!(0, import_node_fs33.existsSync)(worktreePath)) return;
12272
- (0, import_node_fs33.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
12352
+ if (!(0, import_node_fs34.existsSync)(worktreePath)) return;
12353
+ (0, import_node_fs34.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
12273
12354
  }
12274
12355
  function applyWorktreePkgCacheEnv(env, worktreePath) {
12275
12356
  const cwd = worktreePath.trim();
@@ -12282,12 +12363,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
12282
12363
  fillGroup(env, ["electron_config_cache"], next);
12283
12364
  ensureWorktreePkgCacheDirs(cwd);
12284
12365
  }
12285
- var import_node_fs33, import_node_path33, WORKTREE_PKG_CACHE_REL;
12366
+ var import_node_fs34, import_node_path34, WORKTREE_PKG_CACHE_REL;
12286
12367
  var init_worktree_pkg_cache = __esm({
12287
12368
  "src/hook/worktree-pkg-cache.ts"() {
12288
12369
  "use strict";
12289
- import_node_fs33 = require("fs");
12290
- import_node_path33 = require("path");
12370
+ import_node_fs34 = require("fs");
12371
+ import_node_path34 = require("path");
12291
12372
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
12292
12373
  }
12293
12374
  });
@@ -13403,21 +13484,21 @@ function shouldRefreshReviewRequestTemplate(content) {
13403
13484
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
13404
13485
  }
13405
13486
  function readTextIfPresent(abs) {
13406
- if (!(0, import_node_fs34.existsSync)(abs)) return null;
13487
+ if (!(0, import_node_fs35.existsSync)(abs)) return null;
13407
13488
  try {
13408
- const content = (0, import_node_fs34.readFileSync)(abs, "utf8");
13489
+ const content = (0, import_node_fs35.readFileSync)(abs, "utf8");
13409
13490
  return content.trim() ? content : null;
13410
13491
  } catch {
13411
13492
  return null;
13412
13493
  }
13413
13494
  }
13414
13495
  function readLocalGuidelines(worktreePath) {
13415
- const localAbs = (0, import_node_path34.join)(worktreePath, REVIEW_REQUEST_PATH);
13496
+ const localAbs = (0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH);
13416
13497
  const localContent = readTextIfPresent(localAbs);
13417
13498
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
13418
13499
  return { path: REVIEW_REQUEST_PATH, content: localContent };
13419
13500
  }
13420
- const legacyAbs = (0, import_node_path34.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
13501
+ const legacyAbs = (0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
13421
13502
  const legacyContent = readTextIfPresent(legacyAbs);
13422
13503
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
13423
13504
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -13441,27 +13522,27 @@ function contextGuidelines(content, source) {
13441
13522
  };
13442
13523
  }
13443
13524
  function writeContextGuidelines(worktreePath, content) {
13444
- const abs = (0, import_node_path34.join)(worktreePath, CONTEXT_REVIEW_PATH);
13445
- (0, import_node_fs34.mkdirSync)((0, import_node_path34.dirname)(abs), { recursive: true });
13525
+ const abs = (0, import_node_path35.join)(worktreePath, CONTEXT_REVIEW_PATH);
13526
+ (0, import_node_fs35.mkdirSync)((0, import_node_path35.dirname)(abs), { recursive: true });
13446
13527
  const body = content.endsWith("\n") ? content : `${content}
13447
13528
  `;
13448
- (0, import_node_fs34.writeFileSync)(abs, body, "utf8");
13529
+ (0, import_node_fs35.writeFileSync)(abs, body, "utf8");
13449
13530
  return body;
13450
13531
  }
13451
13532
  function readSideboardReview(worktreePath, repoPath) {
13452
- const fromWorktree = readTextIfPresent((0, import_node_path34.join)(worktreePath, REPO_REVIEW_PATH));
13533
+ const fromWorktree = readTextIfPresent((0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH));
13453
13534
  if (fromWorktree) return fromWorktree;
13454
13535
  const repo = repoPath?.replace(/\/+$/, "");
13455
13536
  const wt = worktreePath.replace(/\/+$/, "");
13456
13537
  if (!repo || repo === wt) return null;
13457
- return readTextIfPresent((0, import_node_path34.join)(repo, REPO_REVIEW_PATH));
13538
+ return readTextIfPresent((0, import_node_path35.join)(repo, REPO_REVIEW_PATH));
13458
13539
  }
13459
13540
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
13460
- const skillContent = readTextIfPresent((0, import_node_path34.join)(worktreePath, REVIEW_SKILL_PATH));
13541
+ const skillContent = readTextIfPresent((0, import_node_path35.join)(worktreePath, REVIEW_SKILL_PATH));
13461
13542
  if (skillContent) {
13462
13543
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
13463
13544
  }
13464
- const contextContent = readTextIfPresent((0, import_node_path34.join)(worktreePath, CONTEXT_REVIEW_PATH));
13545
+ const contextContent = readTextIfPresent((0, import_node_path35.join)(worktreePath, CONTEXT_REVIEW_PATH));
13465
13546
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
13466
13547
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
13467
13548
  }
@@ -13516,13 +13597,13 @@ async function requestReview(threadRef, send) {
13516
13597
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
13517
13598
  return { tab: started, from };
13518
13599
  }
13519
- var import_node_crypto7, import_node_fs34, import_node_path34, 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;
13600
+ var import_node_crypto7, import_node_fs35, import_node_path35, 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;
13520
13601
  var init_request_review = __esm({
13521
13602
  "src/review/request-review.ts"() {
13522
13603
  "use strict";
13523
13604
  import_node_crypto7 = require("crypto");
13524
- import_node_fs34 = require("fs");
13525
- import_node_path34 = require("path");
13605
+ import_node_fs35 = require("fs");
13606
+ import_node_path35 = require("path");
13526
13607
  init_global_workspace();
13527
13608
  init_chat_tabs();
13528
13609
  init_thread_store();
@@ -13548,9 +13629,9 @@ function matchSimpleGlob(pattern, name) {
13548
13629
  return new RegExp(`^${escaped}$`).test(name);
13549
13630
  }
13550
13631
  function readWorktreeInclude(repoPath) {
13551
- const path = (0, import_node_path35.join)(repoPath, ".worktreeinclude");
13552
- if (!(0, import_node_fs35.existsSync)(path)) return [];
13553
- return (0, import_node_fs35.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
13632
+ const path = (0, import_node_path36.join)(repoPath, ".worktreeinclude");
13633
+ if (!(0, import_node_fs36.existsSync)(path)) return [];
13634
+ return (0, import_node_fs36.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
13554
13635
  }
13555
13636
  function resolveFilesToCopy(repoPath) {
13556
13637
  const fromInclude = readWorktreeInclude(repoPath);
@@ -13560,10 +13641,10 @@ function resolveFilesToCopy(repoPath) {
13560
13641
  if (settings?.fileIncludeGlobs?.length) {
13561
13642
  const matched = [];
13562
13643
  try {
13563
- for (const entry of (0, import_node_fs35.readdirSync)(repoPath, { withFileTypes: true })) {
13644
+ for (const entry of (0, import_node_fs36.readdirSync)(repoPath, { withFileTypes: true })) {
13564
13645
  if (!entry.isFile()) continue;
13565
13646
  for (const glob of settings.fileIncludeGlobs) {
13566
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path35.basename)(glob), entry.name)) {
13647
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path36.basename)(glob), entry.name)) {
13567
13648
  matched.push(entry.name);
13568
13649
  break;
13569
13650
  }
@@ -13575,7 +13656,7 @@ function resolveFilesToCopy(repoPath) {
13575
13656
  }
13576
13657
  const defaults = [];
13577
13658
  try {
13578
- for (const entry of (0, import_node_fs35.readdirSync)(repoPath, { withFileTypes: true })) {
13659
+ for (const entry of (0, import_node_fs36.readdirSync)(repoPath, { withFileTypes: true })) {
13579
13660
  if (entry.isFile() && entry.name.startsWith(".env")) {
13580
13661
  defaults.push(entry.name);
13581
13662
  }
@@ -13589,11 +13670,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
13589
13670
  const patterns = resolveFilesToCopy(repoPath);
13590
13671
  const copied = [];
13591
13672
  for (const rel of patterns) {
13592
- const src = (0, import_node_path35.join)(repoPath, rel);
13593
- if (!(0, import_node_fs35.existsSync)(src)) continue;
13594
- const dest = (0, import_node_path35.join)(worktreePath, rel);
13595
- (0, import_node_fs35.mkdirSync)((0, import_node_path35.dirname)(dest), { recursive: true });
13596
- (0, import_node_fs35.copyFileSync)(src, dest);
13673
+ const src = (0, import_node_path36.join)(repoPath, rel);
13674
+ if (!(0, import_node_fs36.existsSync)(src)) continue;
13675
+ const dest = (0, import_node_path36.join)(worktreePath, rel);
13676
+ (0, import_node_fs36.mkdirSync)((0, import_node_path36.dirname)(dest), { recursive: true });
13677
+ (0, import_node_fs36.copyFileSync)(src, dest);
13597
13678
  copied.push(rel);
13598
13679
  }
13599
13680
  return copied;
@@ -13628,7 +13709,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
13628
13709
  const env = stripNestedElectronEnv({
13629
13710
  ...baseEnv ?? process.env
13630
13711
  });
13631
- const name = opts.workspaceName ?? (0, import_node_path35.basename)(opts.worktreePath);
13712
+ const name = opts.workspaceName ?? (0, import_node_path36.basename)(opts.worktreePath);
13632
13713
  const ports = opts.ports ?? [];
13633
13714
  const primary = ports[0];
13634
13715
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -13891,13 +13972,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
13891
13972
  done: handle.done
13892
13973
  };
13893
13974
  }
13894
- var import_node_fs35, import_node_net, import_node_path35, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
13975
+ var import_node_fs36, import_node_net, import_node_path36, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
13895
13976
  var init_conductor = __esm({
13896
13977
  "src/hook/conductor.ts"() {
13897
13978
  "use strict";
13898
- import_node_fs35 = require("fs");
13979
+ import_node_fs36 = require("fs");
13899
13980
  import_node_net = require("net");
13900
- import_node_path35 = require("path");
13981
+ import_node_path36 = require("path");
13901
13982
  import_execa4 = require("execa");
13902
13983
  import_node_readline3 = require("readline");
13903
13984
  init_settings();
@@ -13924,7 +14005,7 @@ ${line}` : line;
13924
14005
  return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
13925
14006
  }
13926
14007
  function setupLogPath(threadId) {
13927
- return (0, import_node_path36.join)(threadsDir(), `${threadId}.setup.log.json`);
14008
+ return (0, import_node_path37.join)(threadsDir(), `${threadId}.setup.log.json`);
13928
14009
  }
13929
14010
  function setupLogKeyForWorktree(worktreePath) {
13930
14011
  const norm = normalizeWorktreePath(worktreePath);
@@ -13945,7 +14026,7 @@ function persistNow(threadId) {
13945
14026
  const snap = memory.get(threadId);
13946
14027
  if (!snap) return;
13947
14028
  try {
13948
- (0, import_node_fs36.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
14029
+ (0, import_node_fs37.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
13949
14030
  `, "utf8");
13950
14031
  } catch {
13951
14032
  }
@@ -13962,9 +14043,9 @@ function schedulePersist(threadId) {
13962
14043
  }
13963
14044
  function loadFromDisk(threadId) {
13964
14045
  const path = setupLogPath(threadId);
13965
- if (!(0, import_node_fs36.existsSync)(path)) return null;
14046
+ if (!(0, import_node_fs37.existsSync)(path)) return null;
13966
14047
  try {
13967
- const raw = JSON.parse((0, import_node_fs36.readFileSync)(path, "utf8"));
14048
+ const raw = JSON.parse((0, import_node_fs37.readFileSync)(path, "utf8"));
13968
14049
  return {
13969
14050
  output: typeof raw.output === "string" ? raw.output : "",
13970
14051
  running: Boolean(raw.running),
@@ -14019,13 +14100,13 @@ function finishSetupLog(threadId, exitCode, source) {
14019
14100
  persistNow(threadId);
14020
14101
  return clone(snap);
14021
14102
  }
14022
- var import_node_crypto8, import_node_fs36, import_node_path36, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
14103
+ var import_node_crypto8, import_node_fs37, import_node_path37, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
14023
14104
  var init_setup_log = __esm({
14024
14105
  "src/store/setup-log.ts"() {
14025
14106
  "use strict";
14026
14107
  import_node_crypto8 = require("crypto");
14027
- import_node_fs36 = require("fs");
14028
- import_node_path36 = require("path");
14108
+ import_node_fs37 = require("fs");
14109
+ import_node_path37 = require("path");
14029
14110
  init_worktree_labels();
14030
14111
  init_paths();
14031
14112
  EMPTY = {
@@ -14051,9 +14132,9 @@ async function findOrphanWorktrees(repoPaths) {
14051
14132
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
14052
14133
  );
14053
14134
  const homeRoot = sideboardWorkspacesDir();
14054
- if ((0, import_node_fs37.existsSync)(homeRoot)) {
14135
+ if ((0, import_node_fs38.existsSync)(homeRoot)) {
14055
14136
  try {
14056
- for (const entry of (0, import_node_fs37.readdirSync)(homeRoot, { withFileTypes: true })) {
14137
+ for (const entry of (0, import_node_fs38.readdirSync)(homeRoot, { withFileTypes: true })) {
14057
14138
  if (!entry.isDirectory()) continue;
14058
14139
  void entry;
14059
14140
  }
@@ -14063,7 +14144,7 @@ async function findOrphanWorktrees(repoPaths) {
14063
14144
  const orphans = [];
14064
14145
  const seen = /* @__PURE__ */ new Set();
14065
14146
  for (const repoPath of repos) {
14066
- if (!repoPath || !(0, import_node_fs37.existsSync)(repoPath)) continue;
14147
+ if (!repoPath || !(0, import_node_fs38.existsSync)(repoPath)) continue;
14067
14148
  try {
14068
14149
  const wts = await listWorktrees(repoPath);
14069
14150
  for (const wt of wts) {
@@ -14074,7 +14155,7 @@ async function findOrphanWorktrees(repoPaths) {
14074
14155
  seen.add(path);
14075
14156
  let mtimeMs = 0;
14076
14157
  try {
14077
- mtimeMs = (0, import_node_fs37.statSync)(path).mtimeMs;
14158
+ mtimeMs = (0, import_node_fs38.statSync)(path).mtimeMs;
14078
14159
  } catch {
14079
14160
  mtimeMs = 0;
14080
14161
  }
@@ -14084,16 +14165,16 @@ async function findOrphanWorktrees(repoPaths) {
14084
14165
  }
14085
14166
  try {
14086
14167
  const root = worktreesRoot(repoPath);
14087
- if ((0, import_node_fs37.existsSync)(root)) {
14088
- for (const entry of (0, import_node_fs37.readdirSync)(root, { withFileTypes: true })) {
14168
+ if ((0, import_node_fs38.existsSync)(root)) {
14169
+ for (const entry of (0, import_node_fs38.readdirSync)(root, { withFileTypes: true })) {
14089
14170
  if (!entry.isDirectory()) continue;
14090
- const path = (0, import_node_path37.join)(root, entry.name).replace(/\/$/, "");
14171
+ const path = (0, import_node_path38.join)(root, entry.name).replace(/\/$/, "");
14091
14172
  if (known.has(path) || seen.has(path)) continue;
14092
- if (!(0, import_node_fs37.existsSync)((0, import_node_path37.join)(path, ".git"))) continue;
14173
+ if (!(0, import_node_fs38.existsSync)((0, import_node_path38.join)(path, ".git"))) continue;
14093
14174
  seen.add(path);
14094
14175
  let mtimeMs = 0;
14095
14176
  try {
14096
- mtimeMs = (0, import_node_fs37.statSync)(path).mtimeMs;
14177
+ mtimeMs = (0, import_node_fs38.statSync)(path).mtimeMs;
14097
14178
  } catch {
14098
14179
  mtimeMs = Date.now();
14099
14180
  }
@@ -14145,12 +14226,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
14145
14226
  const elapsed = Date.now() - Date.parse(last);
14146
14227
  return elapsed >= intervalHours * 36e5;
14147
14228
  }
14148
- var import_node_fs37, import_node_path37;
14229
+ var import_node_fs38, import_node_path38;
14149
14230
  var init_orphan_cleanup = __esm({
14150
14231
  "src/git/orphan-cleanup.ts"() {
14151
14232
  "use strict";
14152
- import_node_fs37 = require("fs");
14153
- import_node_path37 = require("path");
14233
+ import_node_fs38 = require("fs");
14234
+ import_node_path38 = require("path");
14154
14235
  init_worktree();
14155
14236
  init_thread_store();
14156
14237
  init_paths();
@@ -14253,12 +14334,12 @@ async function cloneRepoIntoSideboard(opts) {
14253
14334
  if (!url) throw new Error("Clone URL is required");
14254
14335
  let name = opts.name?.trim();
14255
14336
  if (!name) {
14256
- const leaf = (0, import_node_path38.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
14337
+ const leaf = (0, import_node_path39.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
14257
14338
  name = leaf || "repo";
14258
14339
  }
14259
14340
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
14260
- const dest = (0, import_node_path38.join)(sideboardReposDir(), name);
14261
- if ((0, import_node_fs38.existsSync)(dest)) {
14341
+ const dest = (0, import_node_path39.join)(sideboardReposDir(), name);
14342
+ if ((0, import_node_fs39.existsSync)(dest)) {
14262
14343
  const repoPath2 = await resolveRepoRoot(dest);
14263
14344
  const workspace2 = await ensureWorkspace(repoPath2);
14264
14345
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -14273,12 +14354,12 @@ async function cloneRepoIntoSideboard(opts) {
14273
14354
  const workspace = await ensureWorkspace(repoPath);
14274
14355
  return { repoPath, workspace };
14275
14356
  }
14276
- var import_node_fs38, import_node_path38, import_execa6;
14357
+ var import_node_fs39, import_node_path39, import_execa6;
14277
14358
  var init_clone_repo = __esm({
14278
14359
  "src/git/clone-repo.ts"() {
14279
14360
  "use strict";
14280
- import_node_fs38 = require("fs");
14281
- import_node_path38 = require("path");
14361
+ import_node_fs39 = require("fs");
14362
+ import_node_path39 = require("path");
14282
14363
  import_execa6 = require("execa");
14283
14364
  init_paths();
14284
14365
  init_workspaces2();
@@ -14288,11 +14369,11 @@ var init_clone_repo = __esm({
14288
14369
 
14289
14370
  // src/store/desktop-host.ts
14290
14371
  function desktopHostPidPath() {
14291
- return (0, import_node_path39.join)(appDataDir(), "desktop-host.pid");
14372
+ return (0, import_node_path40.join)(appDataDir(), "desktop-host.pid");
14292
14373
  }
14293
14374
  function readDesktopHostPid() {
14294
14375
  try {
14295
- const pid = Number.parseInt((0, import_node_fs39.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
14376
+ const pid = Number.parseInt((0, import_node_fs40.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
14296
14377
  if (!Number.isFinite(pid) || pid <= 0) return null;
14297
14378
  return pid;
14298
14379
  } catch {
@@ -14318,12 +14399,12 @@ function thisProcessShouldDrainAgentQueues() {
14318
14399
  if (isThisProcessDesktopHost()) return true;
14319
14400
  return !isDesktopHostAlive();
14320
14401
  }
14321
- var import_node_fs39, import_node_path39;
14402
+ var import_node_fs40, import_node_path40;
14322
14403
  var init_desktop_host = __esm({
14323
14404
  "src/store/desktop-host.ts"() {
14324
14405
  "use strict";
14325
- import_node_fs39 = require("fs");
14326
- import_node_path39 = require("path");
14406
+ import_node_fs40 = require("fs");
14407
+ import_node_path40 = require("path");
14327
14408
  init_paths();
14328
14409
  }
14329
14410
  });
@@ -14438,24 +14519,24 @@ function jobTreeAlive(pid) {
14438
14519
  return jobAlive(pid) || processGroupAlive(pid);
14439
14520
  }
14440
14521
  function readIntFile(file) {
14441
- if (!(0, import_node_fs40.existsSync)(file)) return null;
14442
- const n = Number.parseInt((0, import_node_fs40.readFileSync)(file, "utf8").trim(), 10);
14522
+ if (!(0, import_node_fs41.existsSync)(file)) return null;
14523
+ const n = Number.parseInt((0, import_node_fs41.readFileSync)(file, "utf8").trim(), 10);
14443
14524
  return Number.isInteger(n) ? n : null;
14444
14525
  }
14445
14526
  function jobDir(root, id, legacy = false) {
14446
- return (0, import_node_path40.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
14527
+ return (0, import_node_path41.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
14447
14528
  }
14448
14529
  function resolveJobDir(root, id) {
14449
14530
  const modern = jobDir(root, id, false);
14450
- if ((0, import_node_fs40.existsSync)(modern)) return modern;
14531
+ if ((0, import_node_fs41.existsSync)(modern)) return modern;
14451
14532
  const legacy = jobDir(root, id, true);
14452
- if ((0, import_node_fs40.existsSync)(legacy)) return legacy;
14533
+ if ((0, import_node_fs41.existsSync)(legacy)) return legacy;
14453
14534
  return modern;
14454
14535
  }
14455
14536
  function listJobIdsIn(root, rel) {
14456
- const dir = (0, import_node_path40.join)(root, rel);
14457
- if (!(0, import_node_fs40.existsSync)(dir)) return [];
14458
- return (0, import_node_fs40.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
14537
+ const dir = (0, import_node_path41.join)(root, rel);
14538
+ if (!(0, import_node_fs41.existsSync)(dir)) return [];
14539
+ return (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
14459
14540
  }
14460
14541
  function listRunningDetachedJobs(worktreePath) {
14461
14542
  const root = worktreePath.trim();
@@ -14467,7 +14548,7 @@ function listRunningDetachedJobs(worktreePath) {
14467
14548
  const running = [];
14468
14549
  for (const id of ids) {
14469
14550
  const dir = resolveJobDir(root, id);
14470
- const pid = readIntFile((0, import_node_path40.join)(dir, "pid"));
14551
+ const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
14471
14552
  if (jobTreeAlive(pid)) running.push(id);
14472
14553
  }
14473
14554
  return running.sort();
@@ -14549,8 +14630,8 @@ function planJobContinue(opts) {
14549
14630
  return { action: "none" };
14550
14631
  }
14551
14632
  function tailProgress(logFile, maxLines = 12) {
14552
- if (!(0, import_node_fs40.existsSync)(logFile)) return "(no log yet)";
14553
- const lines = (0, import_node_fs40.readFileSync)(logFile, "utf8").split("\n");
14633
+ if (!(0, import_node_fs41.existsSync)(logFile)) return "(no log yet)";
14634
+ const lines = (0, import_node_fs41.readFileSync)(logFile, "utf8").split("\n");
14554
14635
  return lines.slice(-maxLines).join("\n");
14555
14636
  }
14556
14637
  function lastProgressLine(progress) {
@@ -14558,8 +14639,8 @@ function lastProgressLine(progress) {
14558
14639
  return last ? last.slice(0, 72) : void 0;
14559
14640
  }
14560
14641
  function readLogLines(file) {
14561
- if (!(0, import_node_fs40.existsSync)(file)) return [];
14562
- const lines = (0, import_node_fs40.readFileSync)(file, "utf8").split("\n");
14642
+ if (!(0, import_node_fs41.existsSync)(file)) return [];
14643
+ const lines = (0, import_node_fs41.readFileSync)(file, "utf8").split("\n");
14563
14644
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
14564
14645
  return lines;
14565
14646
  }
@@ -14570,15 +14651,15 @@ function takeDelta(logFile, cursorFile) {
14570
14651
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
14571
14652
  }
14572
14653
  function snapshotJob(dir) {
14573
- const pid = readIntFile((0, import_node_path40.join)(dir, "pid"));
14654
+ const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
14574
14655
  const running = jobTreeAlive(pid);
14575
14656
  return {
14576
14657
  pid,
14577
14658
  running,
14578
- exitCode: readIntFile((0, import_node_path40.join)(dir, "exit")),
14579
- log: (0, import_node_path40.join)(dir, "log"),
14580
- cursor: (0, import_node_path40.join)(dir, "present.cursor"),
14581
- progress: tailProgress((0, import_node_path40.join)(dir, "log"))
14659
+ exitCode: readIntFile((0, import_node_path41.join)(dir, "exit")),
14660
+ log: (0, import_node_path41.join)(dir, "log"),
14661
+ cursor: (0, import_node_path41.join)(dir, "present.cursor"),
14662
+ progress: tailProgress((0, import_node_path41.join)(dir, "log"))
14582
14663
  };
14583
14664
  }
14584
14665
  function toResult(id, snap, extra) {
@@ -14587,8 +14668,8 @@ function toResult(id, snap, extra) {
14587
14668
  const stillRunning = snap.running && !ok;
14588
14669
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
14589
14670
  try {
14590
- (0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(snap.cursor), { recursive: true });
14591
- (0, import_node_fs40.writeFileSync)(snap.cursor, `${nextCursor}
14671
+ (0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(snap.cursor), { recursive: true });
14672
+ (0, import_node_fs41.writeFileSync)(snap.cursor, `${nextCursor}
14592
14673
  `);
14593
14674
  } catch {
14594
14675
  }
@@ -14617,7 +14698,7 @@ async function waitForDetachedJob(cwd, id, opts) {
14617
14698
  const dir = resolveJobDir(root, jobId);
14618
14699
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
14619
14700
  const sleep = opts?.sleep ?? sleepMs;
14620
- if (!(0, import_node_fs40.existsSync)(dir)) {
14701
+ if (!(0, import_node_fs41.existsSync)(dir)) {
14621
14702
  return {
14622
14703
  stillRunning: false,
14623
14704
  ok: false,
@@ -14663,10 +14744,10 @@ function killProcessTree(pid, signal) {
14663
14744
  }
14664
14745
  function appendJobLog(logFile, line) {
14665
14746
  try {
14666
- (0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(logFile), { recursive: true });
14747
+ (0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(logFile), { recursive: true });
14667
14748
  const body = line.endsWith("\n") ? line : `${line}
14668
14749
  `;
14669
- (0, import_node_fs40.appendFileSync)(logFile, body);
14750
+ (0, import_node_fs41.appendFileSync)(logFile, body);
14670
14751
  } catch {
14671
14752
  }
14672
14753
  }
@@ -14676,7 +14757,7 @@ async function stopDetachedJob(cwd, id, opts) {
14676
14757
  const dir = resolveJobDir(root, jobId);
14677
14758
  const sleep = opts?.sleep ?? sleepMs;
14678
14759
  const why = opts?.reason?.trim() ?? "";
14679
- if (!(0, import_node_fs40.existsSync)(dir)) {
14760
+ if (!(0, import_node_fs41.existsSync)(dir)) {
14680
14761
  return {
14681
14762
  stillRunning: false,
14682
14763
  ok: false,
@@ -14712,10 +14793,10 @@ async function stopDetachedJob(cwd, id, opts) {
14712
14793
  killProcessTree(targetPid, "SIGKILL");
14713
14794
  await sleep(100);
14714
14795
  }
14715
- const exitFile = (0, import_node_path40.join)(dir, "exit");
14716
- if (!(0, import_node_fs40.existsSync)(exitFile)) {
14796
+ const exitFile = (0, import_node_path41.join)(dir, "exit");
14797
+ if (!(0, import_node_fs41.existsSync)(exitFile)) {
14717
14798
  try {
14718
- (0, import_node_fs40.writeFileSync)(exitFile, "1\n");
14799
+ (0, import_node_fs41.writeFileSync)(exitFile, "1\n");
14719
14800
  } catch {
14720
14801
  }
14721
14802
  }
@@ -14735,12 +14816,12 @@ async function stopDetachedJob(cwd, id, opts) {
14735
14816
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
14736
14817
  };
14737
14818
  }
14738
- var import_node_fs40, import_node_path40, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
14819
+ var import_node_fs41, import_node_path41, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
14739
14820
  var init_wait_for_job = __esm({
14740
14821
  "src/mcp/wait-for-job.ts"() {
14741
14822
  "use strict";
14742
- import_node_fs40 = require("fs");
14743
- import_node_path40 = require("path");
14823
+ import_node_fs41 = require("fs");
14824
+ import_node_path41 = require("path");
14744
14825
  init_workspace_scratch();
14745
14826
  init_wait_for_turn();
14746
14827
  MAX_JOB_CONTINUES = 8;
@@ -15986,7 +16067,7 @@ function reuseLiveThread(input, repoPath, match) {
15986
16067
  }
15987
16068
  async function createThread(input, _onSetupLine) {
15988
16069
  const repoPath = await resolveRepoRoot(input.repoPath);
15989
- if (!(0, import_node_fs41.existsSync)(repoPath)) {
16070
+ if (!(0, import_node_fs42.existsSync)(repoPath)) {
15990
16071
  throw new Error(`Repo not found: ${repoPath}`);
15991
16072
  }
15992
16073
  const reused = reuseLiveThread(input, repoPath, {
@@ -16162,11 +16243,11 @@ async function createThread(input, _onSetupLine) {
16162
16243
  await ensureWorkspace(repoPath);
16163
16244
  return readThread(thread.id) ?? thread;
16164
16245
  }
16165
- var import_node_fs41;
16246
+ var import_node_fs42;
16166
16247
  var init_create = __esm({
16167
16248
  "src/threads/create.ts"() {
16168
16249
  "use strict";
16169
- import_node_fs41 = require("fs");
16250
+ import_node_fs42 = require("fs");
16170
16251
  init_detect();
16171
16252
  init_worktree();
16172
16253
  init_home_board();
@@ -16286,20 +16367,20 @@ function writeTurnLive(threadId, progress) {
16286
16367
  const path = threadLivePath(threadId);
16287
16368
  const tmp = `${path}.${process.pid}.tmp`;
16288
16369
  try {
16289
- (0, import_node_fs42.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
16290
- (0, import_node_fs42.renameSync)(tmp, path);
16370
+ (0, import_node_fs43.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
16371
+ (0, import_node_fs43.renameSync)(tmp, path);
16291
16372
  } catch {
16292
16373
  try {
16293
- (0, import_node_fs42.unlinkSync)(tmp);
16374
+ (0, import_node_fs43.unlinkSync)(tmp);
16294
16375
  } catch {
16295
16376
  }
16296
16377
  }
16297
16378
  }
16298
16379
  function readTurnLive(threadId) {
16299
16380
  const path = threadLivePath(threadId);
16300
- if (!(0, import_node_fs42.existsSync)(path)) return null;
16381
+ if (!(0, import_node_fs43.existsSync)(path)) return null;
16301
16382
  try {
16302
- const raw = JSON.parse((0, import_node_fs42.readFileSync)(path, "utf8"));
16383
+ const raw = JSON.parse((0, import_node_fs43.readFileSync)(path, "utf8"));
16303
16384
  if (!raw || typeof raw.summary !== "string") return null;
16304
16385
  return raw;
16305
16386
  } catch {
@@ -16311,17 +16392,17 @@ function clearTurnLive(threadId) {
16311
16392
  if (buf?.timer) clearTimeout(buf.timer);
16312
16393
  buffers.delete(threadId);
16313
16394
  const path = threadLivePath(threadId);
16314
- if (!(0, import_node_fs42.existsSync)(path)) return;
16395
+ if (!(0, import_node_fs43.existsSync)(path)) return;
16315
16396
  try {
16316
- (0, import_node_fs42.unlinkSync)(path);
16397
+ (0, import_node_fs43.unlinkSync)(path);
16317
16398
  } catch {
16318
16399
  }
16319
16400
  }
16320
- var import_node_fs42, buffers, FLUSH_MS, MAX_PARTS;
16401
+ var import_node_fs43, buffers, FLUSH_MS, MAX_PARTS;
16321
16402
  var init_turn_live = __esm({
16322
16403
  "src/store/turn-live.ts"() {
16323
16404
  "use strict";
16324
- import_node_fs42 = require("fs");
16405
+ import_node_fs43 = require("fs");
16325
16406
  init_message_parts();
16326
16407
  init_paths();
16327
16408
  buffers = /* @__PURE__ */ new Map();
@@ -16421,12 +16502,18 @@ var init_fork_worktree = __esm({
16421
16502
 
16422
16503
  // src/orchestrator/quota-failover.ts
16423
16504
  function planOrchestrationQuotaFailover(thread, limitText, opts) {
16424
- if (!isOrchestratorThread(thread)) return null;
16425
16505
  if (!isSessionQuotaLimit(limitText)) return null;
16426
- const onLimit = opts?.onLimit ?? orchestrationQuotaOnLimit();
16506
+ const onLimit = opts?.onLimit ?? usageOnLimit();
16427
16507
  const resumeAt = parseSessionQuotaResetAt(limitText, opts?.now);
16508
+ if (onLimit === "keep_going" || onLimit === "confirm") {
16509
+ return {
16510
+ action: "none",
16511
+ reason: onLimit === "confirm" ? "Settings: confirm with user; no automatic continue." : "Settings: keep going; no automatic continue.",
16512
+ limitText
16513
+ };
16514
+ }
16428
16515
  if (thread.quotaContinuedFromId) {
16429
- if (resumeAt) {
16516
+ if (onLimit === "switch_agent" && resumeAt) {
16430
16517
  return {
16431
16518
  action: "wait_reset",
16432
16519
  reason: "Already continued once; waiting for quota reset instead.",
@@ -16436,7 +16523,7 @@ function planOrchestrationQuotaFailover(thread, limitText, opts) {
16436
16523
  }
16437
16524
  return {
16438
16525
  action: "none",
16439
- reason: "Already continued once; no parseable reset time.",
16526
+ reason: "Already continued once; no further automatic continue.",
16440
16527
  limitText
16441
16528
  };
16442
16529
  }
@@ -16473,8 +16560,19 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
16473
16560
  const text7 = m.text.trim().replace(/\s+/g, " ").slice(0, 280);
16474
16561
  return text7 ? `- ${role}: ${text7}` : null;
16475
16562
  }).filter(Boolean);
16563
+ const orch = isOrchestratorThread(from);
16564
+ const instructions = orch ? [
16565
+ "- Continue fleet orchestration from this handoff.",
16566
+ "- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.",
16567
+ "- Leave model Auto unless there is a specific reason to pin one.",
16568
+ `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
16569
+ ] : [
16570
+ "- Continue this worktree chat from the handoff.",
16571
+ "- Leave model Auto unless there is a specific reason to pin one.",
16572
+ `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
16573
+ ];
16476
16574
  const body = [
16477
- `# Orchestration handoff`,
16575
+ `# ${orch ? "Orchestration" : "Chat"} handoff`,
16478
16576
  "",
16479
16577
  `Previous chat: ${from.title} (\`${from.id}\`) on **${from.agent}** hit a session/usage limit.`,
16480
16578
  `Limit: ${limitText.trim()}`,
@@ -16490,14 +16588,11 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
16490
16588
  recent.length ? recent.join("\n") : "(none)",
16491
16589
  "",
16492
16590
  `## Instructions`,
16493
- `- Continue fleet orchestration from this handoff.`,
16494
- `- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.`,
16495
- `- Leave model Auto unless there is a specific reason to pin one.`,
16496
- `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
16591
+ ...instructions
16497
16592
  ].join("\n");
16498
16593
  return {
16499
16594
  id: (0, import_node_crypto9.randomUUID)(),
16500
- name: "Orchestration quota handoff.md",
16595
+ name: orch ? "Orchestration quota handoff.md" : "Quota handoff.md",
16501
16596
  kind: "transcript",
16502
16597
  content: body
16503
16598
  };
@@ -16510,12 +16605,15 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
16510
16605
  model: null,
16511
16606
  attachments: [handoff]
16512
16607
  });
16513
- return updateThread(tab.id, {
16514
- parentThreadId: from.id,
16608
+ const patch = {
16515
16609
  quotaContinuedFromId: from.id,
16516
- sourceRef: from.sourceRef,
16517
- sourceType: "orchestration"
16518
- });
16610
+ sourceRef: from.sourceRef
16611
+ };
16612
+ if (isOrchestratorThread(from)) {
16613
+ patch.parentThreadId = from.id;
16614
+ patch.sourceType = "orchestration";
16615
+ }
16616
+ return updateThread(tab.id, patch);
16519
16617
  }
16520
16618
  var import_node_crypto9, QUOTA_CONTINUE_PROMPT, QUOTA_RESUME_PROMPT;
16521
16619
  var init_quota_failover = __esm({
@@ -16528,17 +16626,17 @@ var init_quota_failover = __esm({
16528
16626
  init_thread_store();
16529
16627
  init_chat_tabs();
16530
16628
  QUOTA_CONTINUE_PROMPT = (fromAgent, fallback) => [
16531
- `${fromAgent} hit a session/usage limit. Continue this orchestration on ${fallback} using the attached handoff.`,
16532
- "Call list_board or list_threads for live fleet status, then proceed with the goal. Leave model Auto unless needed."
16629
+ `${fromAgent} hit a session/usage limit. Continue this chat on ${fallback} using the attached handoff.`,
16630
+ "Proceed with the goal. Leave model Auto unless needed."
16533
16631
  ].join(" ");
16534
- QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue the orchestration from where you left off. Use list_board or list_threads for fleet status.";
16632
+ QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue this chat from where you left off.";
16535
16633
  }
16536
16634
  });
16537
16635
 
16538
16636
  // src/threads/adopt.ts
16539
16637
  function thisModuleFile() {
16540
16638
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
16541
- return cjsFile || process.argv[1] || (0, import_node_path41.join)(process.cwd(), "package.json");
16639
+ return cjsFile || process.argv[1] || (0, import_node_path42.join)(process.cwd(), "package.json");
16542
16640
  }
16543
16641
  function openReadonlySqlite(file) {
16544
16642
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -16556,21 +16654,21 @@ function mapAgentType(raw) {
16556
16654
  return null;
16557
16655
  }
16558
16656
  function resolveConductorCursorAgentId(workspacePath) {
16559
- if (!workspacePath || !(0, import_node_fs43.existsSync)(CURSOR_SDK_STORE)) return null;
16657
+ if (!workspacePath || !(0, import_node_fs44.existsSync)(CURSOR_SDK_STORE)) return null;
16560
16658
  const normalized = workspacePath.replace(/\/$/, "");
16561
16659
  let best = null;
16562
16660
  let hashes;
16563
16661
  try {
16564
- hashes = (0, import_node_fs43.readdirSync)(CURSOR_SDK_STORE);
16662
+ hashes = (0, import_node_fs44.readdirSync)(CURSOR_SDK_STORE);
16565
16663
  } catch {
16566
16664
  return null;
16567
16665
  }
16568
16666
  for (const hash of hashes) {
16569
- const agentsFile = (0, import_node_path41.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
16570
- if (!(0, import_node_fs43.existsSync)(agentsFile)) continue;
16667
+ const agentsFile = (0, import_node_path42.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
16668
+ if (!(0, import_node_fs44.existsSync)(agentsFile)) continue;
16571
16669
  let text7;
16572
16670
  try {
16573
- text7 = (0, import_node_fs43.readFileSync)(agentsFile, "utf8");
16671
+ text7 = (0, import_node_fs44.readFileSync)(agentsFile, "utf8");
16574
16672
  } catch {
16575
16673
  continue;
16576
16674
  }
@@ -16594,7 +16692,7 @@ function resolveConductorCursorAgentId(workspacePath) {
16594
16692
  return best?.agentId ?? null;
16595
16693
  }
16596
16694
  async function adoptThread(input) {
16597
- if (!(0, import_node_fs43.existsSync)(input.worktreePath)) {
16695
+ if (!(0, import_node_fs44.existsSync)(input.worktreePath)) {
16598
16696
  throw new Error(`Worktree not found: ${input.worktreePath}`);
16599
16697
  }
16600
16698
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -16620,18 +16718,18 @@ async function adoptThread(input) {
16620
16718
  return thread;
16621
16719
  }
16622
16720
  function listConductorWorkspaces() {
16623
- if (!(0, import_node_fs43.existsSync)(CONDUCTOR_DB)) {
16721
+ if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
16624
16722
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
16625
16723
  }
16626
- const tmp = (0, import_node_fs43.mkdtempSync)((0, import_node_path41.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16627
- const snapshot = (0, import_node_path41.join)(tmp, "conductor.db");
16724
+ const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
16725
+ const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
16628
16726
  try {
16629
- (0, import_node_fs43.copyFileSync)(CONDUCTOR_DB, snapshot);
16727
+ (0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
16630
16728
  for (const suffix of ["-wal", "-shm"]) {
16631
16729
  const src = `${CONDUCTOR_DB}${suffix}`;
16632
- if ((0, import_node_fs43.existsSync)(src)) {
16730
+ if ((0, import_node_fs44.existsSync)(src)) {
16633
16731
  try {
16634
- (0, import_node_fs43.copyFileSync)(src, `${snapshot}${suffix}`);
16732
+ (0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
16635
16733
  } catch {
16636
16734
  }
16637
16735
  }
@@ -16707,22 +16805,22 @@ function listConductorWorkspaces() {
16707
16805
  db.close();
16708
16806
  }
16709
16807
  } finally {
16710
- (0, import_node_fs43.rmSync)(tmp, { recursive: true, force: true });
16808
+ (0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
16711
16809
  }
16712
16810
  }
16713
16811
  function importConductorWorkspace(workspaceId) {
16714
- if (!(0, import_node_fs43.existsSync)(CONDUCTOR_DB)) {
16812
+ if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
16715
16813
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
16716
16814
  }
16717
- const tmp = (0, import_node_fs43.mkdtempSync)((0, import_node_path41.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
16718
- const snapshot = (0, import_node_path41.join)(tmp, "conductor.db");
16815
+ const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
16816
+ const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
16719
16817
  try {
16720
- (0, import_node_fs43.copyFileSync)(CONDUCTOR_DB, snapshot);
16818
+ (0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
16721
16819
  for (const suffix of ["-wal", "-shm"]) {
16722
16820
  const src = `${CONDUCTOR_DB}${suffix}`;
16723
- if ((0, import_node_fs43.existsSync)(src)) {
16821
+ if ((0, import_node_fs44.existsSync)(src)) {
16724
16822
  try {
16725
- (0, import_node_fs43.copyFileSync)(src, `${snapshot}${suffix}`);
16823
+ (0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
16726
16824
  } catch {
16727
16825
  }
16728
16826
  }
@@ -16740,7 +16838,7 @@ function importConductorWorkspace(workspaceId) {
16740
16838
  ).get(workspaceId);
16741
16839
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
16742
16840
  const worktreePath = String(row.workspacePath);
16743
- if (!(0, import_node_fs43.existsSync)(worktreePath)) {
16841
+ if (!(0, import_node_fs44.existsSync)(worktreePath)) {
16744
16842
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
16745
16843
  }
16746
16844
  let sessionId = null;
@@ -16803,31 +16901,31 @@ function importConductorWorkspace(workspaceId) {
16803
16901
  db.close();
16804
16902
  }
16805
16903
  } finally {
16806
- (0, import_node_fs43.rmSync)(tmp, { recursive: true, force: true });
16904
+ (0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
16807
16905
  }
16808
16906
  }
16809
16907
  async function importConductorWorkspaceAsync(workspaceId) {
16810
16908
  return importConductorWorkspace(workspaceId);
16811
16909
  }
16812
- 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;
16910
+ var import_node_child_process4, import_node_fs44, import_node_os14, import_node_path42, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
16813
16911
  var init_adopt = __esm({
16814
16912
  "src/threads/adopt.ts"() {
16815
16913
  "use strict";
16816
16914
  import_node_child_process4 = require("child_process");
16817
- import_node_fs43 = require("fs");
16818
- import_node_os13 = require("os");
16819
- import_node_path41 = require("path");
16915
+ import_node_fs44 = require("fs");
16916
+ import_node_os14 = require("os");
16917
+ import_node_path42 = require("path");
16820
16918
  import_node_module4 = require("module");
16821
16919
  init_worktree();
16822
16920
  init_thread_store();
16823
- CONDUCTOR_APP_SUPPORT = (0, import_node_path41.join)(
16921
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path42.join)(
16824
16922
  process.env.HOME ?? "",
16825
16923
  "Library",
16826
16924
  "Application Support",
16827
16925
  "com.conductor.app"
16828
16926
  );
16829
- CONDUCTOR_DB = (0, import_node_path41.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
16830
- CURSOR_SDK_STORE = (0, import_node_path41.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
16927
+ CONDUCTOR_DB = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
16928
+ CURSOR_SDK_STORE = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
16831
16929
  }
16832
16930
  });
16833
16931
 
@@ -16894,7 +16992,7 @@ async function openStackLayer(input, _onSetupLine) {
16894
16992
  let createdWorktree = false;
16895
16993
  const trees = await listWorktrees(repoPath);
16896
16994
  const checkedOut = trees.find((w) => w.branch === branchName);
16897
- if (checkedOut?.path && (0, import_node_fs44.existsSync)(checkedOut.path)) {
16995
+ if (checkedOut?.path && (0, import_node_fs45.existsSync)(checkedOut.path)) {
16898
16996
  if (input.reuseExistingWorktree !== false) {
16899
16997
  worktreePath = checkedOut.path;
16900
16998
  } else {
@@ -17036,7 +17134,7 @@ async function initStackFromThread(input, onSetupLine) {
17036
17134
  async function createPrStack(input, onSetupLine) {
17037
17135
  await requireAgent(input.agent);
17038
17136
  const repoPath = await resolveRepoRoot(input.repoPath);
17039
- if (!(0, import_node_fs44.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
17137
+ if (!(0, import_node_fs45.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
17040
17138
  if (!input.branches.length) throw new Error("At least one branch name required");
17041
17139
  const status = await detectGhStack(repoPath);
17042
17140
  if (!status.available) throw new Error(status.reason);
@@ -17103,7 +17201,7 @@ async function createPrStack(input, onSetupLine) {
17103
17201
  }
17104
17202
  }
17105
17203
  const claimed = new Set(threads.map((t) => t.worktreePath));
17106
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs44.existsSync)(bootstrap.worktreePath)) {
17204
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs45.existsSync)(bootstrap.worktreePath)) {
17107
17205
  try {
17108
17206
  await removeWorktree(repoPath, bootstrap.worktreePath, {
17109
17207
  deleteBranch: bootstrap.branchName
@@ -17113,11 +17211,11 @@ async function createPrStack(input, onSetupLine) {
17113
17211
  }
17114
17212
  return { stack, threads, createdThreadIds };
17115
17213
  }
17116
- var import_node_fs44;
17214
+ var import_node_fs45;
17117
17215
  var init_stack_layers = __esm({
17118
17216
  "src/threads/stack-layers.ts"() {
17119
17217
  "use strict";
17120
- import_node_fs44 = require("fs");
17218
+ import_node_fs45 = require("fs");
17121
17219
  init_detect();
17122
17220
  init_run();
17123
17221
  init_stack();
@@ -17130,7 +17228,7 @@ var init_stack_layers = __esm({
17130
17228
 
17131
17229
  // src/diff/diff.ts
17132
17230
  async function inspectGitWorktree(worktreePath) {
17133
- if (!worktreePath || !(0, import_node_fs45.existsSync)(worktreePath)) return "missing_worktree";
17231
+ if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) return "missing_worktree";
17134
17232
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
17135
17233
  reject: false
17136
17234
  });
@@ -17138,7 +17236,7 @@ async function inspectGitWorktree(worktreePath) {
17138
17236
  return "ok";
17139
17237
  }
17140
17238
  async function initializeGitRepository(worktreePath) {
17141
- if (!worktreePath || !(0, import_node_fs45.existsSync)(worktreePath)) {
17239
+ if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) {
17142
17240
  throw new Error("Worktree not found");
17143
17241
  }
17144
17242
  const status = await inspectGitWorktree(worktreePath);
@@ -17272,11 +17370,11 @@ new file mode 100644
17272
17370
  };
17273
17371
  }
17274
17372
  async function untrackedPatch(worktreePath, path, maxHunk) {
17275
- const abs = (0, import_node_path42.join)(worktreePath, path);
17373
+ const abs = (0, import_node_path43.join)(worktreePath, path);
17276
17374
  try {
17277
- const st = (0, import_node_fs45.statSync)(abs);
17375
+ const st = (0, import_node_fs46.statSync)(abs);
17278
17376
  if (st.isFile() && st.size > maxHunk) {
17279
- const buf = (0, import_node_fs45.readFileSync)(abs).subarray(0, maxHunk);
17377
+ const buf = (0, import_node_fs46.readFileSync)(abs).subarray(0, maxHunk);
17280
17378
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
17281
17379
  }
17282
17380
  } catch {
@@ -17765,8 +17863,8 @@ function isImageRelativePath(relativePath) {
17765
17863
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17766
17864
  assertSafeRelativePath(relativePath);
17767
17865
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
17768
- const abs = (0, import_node_path42.join)(worktreePath, relativePath);
17769
- const st = (0, import_node_fs45.statSync)(abs);
17866
+ const abs = (0, import_node_path43.join)(worktreePath, relativePath);
17867
+ const st = (0, import_node_fs46.statSync)(abs);
17770
17868
  if (!st.isFile()) {
17771
17869
  throw new Error(`Not a file: ${relativePath}`);
17772
17870
  }
@@ -17775,7 +17873,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17775
17873
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
17776
17874
  );
17777
17875
  }
17778
- const buf = (0, import_node_fs45.readFileSync)(abs);
17876
+ const buf = (0, import_node_fs46.readFileSync)(abs);
17779
17877
  return {
17780
17878
  path: relativePath,
17781
17879
  contentBase64: buf.toString("base64"),
@@ -17785,12 +17883,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
17785
17883
  function readWorktreeFile(worktreePath, relativePath, opts) {
17786
17884
  assertSafeRelativePath(relativePath);
17787
17885
  const maxBytes = opts?.maxBytes ?? 2e5;
17788
- const abs = (0, import_node_path42.join)(worktreePath, relativePath);
17789
- const st = (0, import_node_fs45.statSync)(abs);
17886
+ const abs = (0, import_node_path43.join)(worktreePath, relativePath);
17887
+ const st = (0, import_node_fs46.statSync)(abs);
17790
17888
  if (!st.isFile()) {
17791
17889
  throw new Error(`Not a file: ${relativePath}`);
17792
17890
  }
17793
- const buf = (0, import_node_fs45.readFileSync)(abs);
17891
+ const buf = (0, import_node_fs46.readFileSync)(abs);
17794
17892
  if (isImageRelativePath(relativePath)) {
17795
17893
  const maxImageBytes = Math.max(maxBytes, 15e6);
17796
17894
  const truncated2 = buf.length > maxImageBytes;
@@ -17833,9 +17931,9 @@ function assertSafeRelativePath(relativePath) {
17833
17931
  }
17834
17932
  function writeWorktreeFile(worktreePath, relativePath, content) {
17835
17933
  assertSafeRelativePath(relativePath);
17836
- const abs = (0, import_node_path42.join)(worktreePath, relativePath);
17837
- (0, import_node_fs45.mkdirSync)((0, import_node_path42.dirname)(abs), { recursive: true });
17838
- (0, import_node_fs45.writeFileSync)(abs, content, "utf8");
17934
+ const abs = (0, import_node_path43.join)(worktreePath, relativePath);
17935
+ (0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
17936
+ (0, import_node_fs46.writeFileSync)(abs, content, "utf8");
17839
17937
  return { path: relativePath };
17840
17938
  }
17841
17939
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -17852,12 +17950,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
17852
17950
  truncated: full.files.length > maxFiles
17853
17951
  };
17854
17952
  }
17855
- var import_node_fs45, import_node_path42, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
17953
+ var import_node_fs46, import_node_path43, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
17856
17954
  var init_diff = __esm({
17857
17955
  "src/diff/diff.ts"() {
17858
17956
  "use strict";
17859
- import_node_fs45 = require("fs");
17860
- import_node_path42 = require("path");
17957
+ import_node_fs46 = require("fs");
17958
+ import_node_path43 = require("path");
17861
17959
  init_run();
17862
17960
  init_worktree();
17863
17961
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -18214,7 +18312,7 @@ function parseFrontmatter(content) {
18214
18312
  }
18215
18313
  function readSkill(skillMd, source) {
18216
18314
  try {
18217
- const content = (0, import_node_fs46.readFileSync)(skillMd, "utf8");
18315
+ const content = (0, import_node_fs47.readFileSync)(skillMd, "utf8");
18218
18316
  const { name: fmName, description } = parseFrontmatter(content);
18219
18317
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
18220
18318
  const name = fmName || dirName;
@@ -18233,19 +18331,19 @@ function readSkill(skillMd, source) {
18233
18331
  }
18234
18332
  }
18235
18333
  function scanSkillsDir(dir, source, out) {
18236
- if (!(0, import_node_fs46.existsSync)(dir)) return;
18334
+ if (!(0, import_node_fs47.existsSync)(dir)) return;
18237
18335
  let entries;
18238
18336
  try {
18239
- entries = (0, import_node_fs46.readdirSync)(dir);
18337
+ entries = (0, import_node_fs47.readdirSync)(dir);
18240
18338
  } catch {
18241
18339
  return;
18242
18340
  }
18243
18341
  for (const entry of entries) {
18244
18342
  if (entry.startsWith(".")) continue;
18245
- const skillMd = (0, import_node_path43.join)(dir, entry, "SKILL.md");
18246
- if (!(0, import_node_fs46.existsSync)(skillMd)) continue;
18343
+ const skillMd = (0, import_node_path44.join)(dir, entry, "SKILL.md");
18344
+ if (!(0, import_node_fs47.existsSync)(skillMd)) continue;
18247
18345
  try {
18248
- if (!(0, import_node_fs46.statSync)(skillMd).isFile()) continue;
18346
+ if (!(0, import_node_fs47.statSync)(skillMd).isFile()) continue;
18249
18347
  } catch {
18250
18348
  continue;
18251
18349
  }
@@ -18254,24 +18352,24 @@ function scanSkillsDir(dir, source, out) {
18254
18352
  }
18255
18353
  }
18256
18354
  function scanClaudePluginSkills(pluginsRoot, out) {
18257
- if (!(0, import_node_fs46.existsSync)(pluginsRoot)) return;
18355
+ if (!(0, import_node_fs47.existsSync)(pluginsRoot)) return;
18258
18356
  const walk = (dir, depth, lookingForSkillsDir) => {
18259
18357
  if (depth > 7) return;
18260
18358
  let entries;
18261
18359
  try {
18262
- entries = (0, import_node_fs46.readdirSync)(dir);
18360
+ entries = (0, import_node_fs47.readdirSync)(dir);
18263
18361
  } catch {
18264
18362
  return;
18265
18363
  }
18266
18364
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
18267
- const skill = readSkill((0, import_node_path43.join)(dir, "SKILL.md"), "cli");
18365
+ const skill = readSkill((0, import_node_path44.join)(dir, "SKILL.md"), "cli");
18268
18366
  if (skill) out.push(skill);
18269
18367
  }
18270
18368
  for (const entry of entries) {
18271
18369
  if (entry === "node_modules" || entry === ".git") continue;
18272
- const full = (0, import_node_path43.join)(dir, entry);
18370
+ const full = (0, import_node_path44.join)(dir, entry);
18273
18371
  try {
18274
- if (!(0, import_node_fs46.statSync)(full).isDirectory()) continue;
18372
+ if (!(0, import_node_fs47.statSync)(full).isDirectory()) continue;
18275
18373
  } catch {
18276
18374
  continue;
18277
18375
  }
@@ -18286,20 +18384,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
18286
18384
  walk(pluginsRoot, 0, false);
18287
18385
  }
18288
18386
  function discoverSkills(worktreePath) {
18289
- const home = (0, import_node_os14.homedir)();
18387
+ const home = (0, import_node_os15.homedir)();
18290
18388
  const collected = [];
18291
18389
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
18292
- scanSkillsDir((0, import_node_path43.join)(worktreePath, rel), "workspace", collected);
18390
+ scanSkillsDir((0, import_node_path44.join)(worktreePath, rel), "workspace", collected);
18293
18391
  }
18294
18392
  for (const abs of [
18295
- (0, import_node_path43.join)(home, ".claude/skills"),
18296
- (0, import_node_path43.join)(home, ".cursor/skills"),
18297
- (0, import_node_path43.join)(home, ".sideboard/skills"),
18298
- (0, import_node_path43.join)(home, ".brightsy/skills")
18393
+ (0, import_node_path44.join)(home, ".claude/skills"),
18394
+ (0, import_node_path44.join)(home, ".cursor/skills"),
18395
+ (0, import_node_path44.join)(home, ".sideboard/skills"),
18396
+ (0, import_node_path44.join)(home, ".brightsy/skills")
18299
18397
  ]) {
18300
18398
  scanSkillsDir(abs, "user", collected);
18301
18399
  }
18302
- scanClaudePluginSkills((0, import_node_path43.join)(home, ".claude/plugins"), collected);
18400
+ scanClaudePluginSkills((0, import_node_path44.join)(home, ".claude/plugins"), collected);
18303
18401
  collected.push(...bundledSkills());
18304
18402
  const rank = {
18305
18403
  workspace: 0,
@@ -18325,7 +18423,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
18325
18423
  \u2026(truncated)` : body;
18326
18424
  }
18327
18425
  }
18328
- const raw = (0, import_node_fs46.readFileSync)(skillPath, "utf8");
18426
+ const raw = (0, import_node_fs47.readFileSync)(skillPath, "utf8");
18329
18427
  if (raw.startsWith("---")) {
18330
18428
  const end = raw.indexOf("\n---", 3);
18331
18429
  if (end >= 0) {
@@ -18339,13 +18437,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
18339
18437
 
18340
18438
  \u2026(truncated)` : raw;
18341
18439
  }
18342
- var import_node_fs46, import_node_os14, import_node_path43, BUNDLED_SKILL_PREFIX;
18440
+ var import_node_fs47, import_node_os15, import_node_path44, BUNDLED_SKILL_PREFIX;
18343
18441
  var init_discover = __esm({
18344
18442
  "src/skills/discover.ts"() {
18345
18443
  "use strict";
18346
- import_node_fs46 = require("fs");
18347
- import_node_os14 = require("os");
18348
- import_node_path43 = require("path");
18444
+ import_node_fs47 = require("fs");
18445
+ import_node_os15 = require("os");
18446
+ import_node_path44 = require("path");
18349
18447
  init_long_running();
18350
18448
  BUNDLED_SKILL_PREFIX = "bundled:";
18351
18449
  }
@@ -18439,8 +18537,8 @@ var init_expand = __esm({
18439
18537
  // src/skills/detached-job-path.ts
18440
18538
  function detachedJobScriptIn(dir) {
18441
18539
  for (const name of DETACHED_JOB_FILENAMES) {
18442
- const script = (0, import_node_path44.join)(dir, "scripts", name);
18443
- if ((0, import_node_fs47.existsSync)(script)) return script;
18540
+ const script = (0, import_node_path45.join)(dir, "scripts", name);
18541
+ if ((0, import_node_fs48.existsSync)(script)) return script;
18444
18542
  }
18445
18543
  return null;
18446
18544
  }
@@ -18452,11 +18550,11 @@ function packagedDetachedJobPath() {
18452
18550
  function resolveDetachedJobScript() {
18453
18551
  const packaged = packagedDetachedJobPath();
18454
18552
  if (packaged) return packaged;
18455
- let dir = (0, import_node_path44.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
18553
+ let dir = (0, import_node_path45.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
18456
18554
  for (let i = 0; i < 8; i++) {
18457
18555
  const candidate = detachedJobScriptIn(dir);
18458
18556
  if (candidate) return candidate;
18459
- const parent = (0, import_node_path44.dirname)(dir);
18557
+ const parent = (0, import_node_path45.dirname)(dir);
18460
18558
  if (parent === dir) break;
18461
18559
  dir = parent;
18462
18560
  }
@@ -18467,12 +18565,12 @@ function formatDetachedJobInvoke(scriptPath) {
18467
18565
  if (resolved) return `node ${JSON.stringify(resolved)}`;
18468
18566
  return "node scripts/detached-job.cjs";
18469
18567
  }
18470
- var import_node_fs47, import_node_path44, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
18568
+ var import_node_fs48, import_node_path45, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
18471
18569
  var init_detached_job_path = __esm({
18472
18570
  "src/skills/detached-job-path.ts"() {
18473
18571
  "use strict";
18474
- import_node_fs47 = require("fs");
18475
- import_node_path44 = require("path");
18572
+ import_node_fs48 = require("fs");
18573
+ import_node_path45 = require("path");
18476
18574
  import_node_url3 = require("url");
18477
18575
  init_packaged_runtime();
18478
18576
  import_meta3 = {};
@@ -18632,9 +18730,9 @@ function formatPrGateDirective() {
18632
18730
  }
18633
18731
  function formatProcessGuideDirective(opts) {
18634
18732
  const worktree = opts?.worktreePath?.trim();
18635
- const hasGraphSkill = !!worktree && (0, import_node_fs48.existsSync)((0, import_node_path45.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
18636
- const hasReviewSkill = !!worktree && (0, import_node_fs48.existsSync)((0, import_node_path45.join)(worktree, ".claude/skills/review/SKILL.md"));
18637
- const hasInstallSkill = !!worktree && (0, import_node_fs48.existsSync)((0, import_node_path45.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
18733
+ const hasGraphSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
18734
+ const hasReviewSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/review/SKILL.md"));
18735
+ const hasInstallSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
18638
18736
  return [
18639
18737
  "Process guides (recurring work only):",
18640
18738
  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,
@@ -18672,12 +18770,12 @@ function formatArtifactDirective() {
18672
18770
  function formatUiReminder() {
18673
18771
  return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
18674
18772
  }
18675
- var import_node_fs48, import_node_path45, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
18773
+ var import_node_fs49, import_node_path46, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
18676
18774
  var init_instructions = __esm({
18677
18775
  "src/agents/instructions.ts"() {
18678
18776
  "use strict";
18679
- import_node_fs48 = require("fs");
18680
- import_node_path45 = require("path");
18777
+ import_node_fs49 = require("fs");
18778
+ import_node_path46 = require("path");
18681
18779
  init_git_auth_mode();
18682
18780
  init_branch_prefix();
18683
18781
  init_worktree_labels();
@@ -18901,40 +18999,40 @@ __export(plan_file_exports, {
18901
18999
  writePlanFile: () => writePlanFile
18902
19000
  });
18903
19001
  function ensureAttachmentsGitignore(worktreePath) {
18904
- const gitignoreAbs = (0, import_node_path46.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
18905
- if ((0, import_node_fs49.existsSync)(gitignoreAbs)) return;
18906
- (0, import_node_fs49.mkdirSync)((0, import_node_path46.dirname)(gitignoreAbs), { recursive: true });
18907
- (0, import_node_fs49.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
19002
+ const gitignoreAbs = (0, import_node_path47.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
19003
+ if ((0, import_node_fs50.existsSync)(gitignoreAbs)) return;
19004
+ (0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(gitignoreAbs), { recursive: true });
19005
+ (0, import_node_fs50.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
18908
19006
  }
18909
19007
  function planFileAbs(worktreePath) {
18910
- return (0, import_node_path46.join)(worktreePath, PLAN_FILE_REL);
19008
+ return (0, import_node_path47.join)(worktreePath, PLAN_FILE_REL);
18911
19009
  }
18912
19010
  function readTextIfPresent2(abs) {
18913
- if (!(0, import_node_fs49.existsSync)(abs)) return null;
19011
+ if (!(0, import_node_fs50.existsSync)(abs)) return null;
18914
19012
  try {
18915
- const content = (0, import_node_fs49.readFileSync)(abs, "utf8");
19013
+ const content = (0, import_node_fs50.readFileSync)(abs, "utf8");
18916
19014
  return content.trim() ? content : null;
18917
19015
  } catch {
18918
19016
  return null;
18919
19017
  }
18920
19018
  }
18921
19019
  function readPlanFile(worktreePath) {
18922
- 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));
19020
+ 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));
18923
19021
  }
18924
19022
  function writePlanFile(worktreePath, content) {
18925
19023
  ensureAttachmentsGitignore(worktreePath);
18926
19024
  const abs = planFileAbs(worktreePath);
18927
- (0, import_node_fs49.mkdirSync)((0, import_node_path46.dirname)(abs), { recursive: true });
19025
+ (0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(abs), { recursive: true });
18928
19026
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
18929
- (0, import_node_fs49.writeFileSync)(abs, body, "utf8");
19027
+ (0, import_node_fs50.writeFileSync)(abs, body, "utf8");
18930
19028
  return PLAN_FILE_REL;
18931
19029
  }
18932
- var import_node_fs49, import_node_path46;
19030
+ var import_node_fs50, import_node_path47;
18933
19031
  var init_plan_file = __esm({
18934
19032
  "src/plan/plan-file.ts"() {
18935
19033
  "use strict";
18936
- import_node_fs49 = require("fs");
18937
- import_node_path46 = require("path");
19034
+ import_node_fs50 = require("fs");
19035
+ import_node_path47 = require("path");
18938
19036
  init_workspace_scratch();
18939
19037
  init_plan_present();
18940
19038
  init_plan_present();
@@ -18994,7 +19092,7 @@ function setCaffeinateHoldHooks(next) {
18994
19092
  hooks = next;
18995
19093
  }
18996
19094
  function caffeinateHoldPath() {
18997
- return (0, import_node_path47.join)(appDataDir(), "caffeinate-hold.json");
19095
+ return (0, import_node_path48.join)(appDataDir(), "caffeinate-hold.json");
18998
19096
  }
18999
19097
  function processAlive(pid) {
19000
19098
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -19028,9 +19126,9 @@ function uniqueIds(ids) {
19028
19126
  }
19029
19127
  function readHold() {
19030
19128
  const path = caffeinateHoldPath();
19031
- if (!(0, import_node_fs50.existsSync)(path)) return null;
19129
+ if (!(0, import_node_fs51.existsSync)(path)) return null;
19032
19130
  try {
19033
- const parsed = JSON.parse((0, import_node_fs50.readFileSync)(path, "utf8"));
19131
+ const parsed = JSON.parse((0, import_node_fs51.readFileSync)(path, "utf8"));
19034
19132
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
19035
19133
  return {
19036
19134
  pid: parsed.pid,
@@ -19052,7 +19150,7 @@ function writeHold(pid, threadIds) {
19052
19150
  }
19053
19151
  function clearHold() {
19054
19152
  try {
19055
- (0, import_node_fs50.unlinkSync)(caffeinateHoldPath());
19153
+ (0, import_node_fs51.unlinkSync)(caffeinateHoldPath());
19056
19154
  } catch {
19057
19155
  }
19058
19156
  }
@@ -19137,13 +19235,13 @@ function releaseCaffeinateHoldForThread(threadId) {
19137
19235
  }
19138
19236
  return setCaffeinateHold(false, { threadId: id });
19139
19237
  }
19140
- var import_node_child_process5, import_node_fs50, import_node_path47, hooks;
19238
+ var import_node_child_process5, import_node_fs51, import_node_path48, hooks;
19141
19239
  var init_caffeinate_hold = __esm({
19142
19240
  "src/store/caffeinate-hold.ts"() {
19143
19241
  "use strict";
19144
19242
  import_node_child_process5 = require("child_process");
19145
- import_node_fs50 = require("fs");
19146
- import_node_path47 = require("path");
19243
+ import_node_fs51 = require("fs");
19244
+ import_node_path48 = require("path");
19147
19245
  init_paths();
19148
19246
  init_private_file();
19149
19247
  hooks = {};
@@ -19152,7 +19250,7 @@ var init_caffeinate_hold = __esm({
19152
19250
 
19153
19251
  // src/store/schedules.ts
19154
19252
  function schedulesPath() {
19155
- return (0, import_node_path48.join)(appDataDir(), "schedules.json");
19253
+ return (0, import_node_path49.join)(appDataDir(), "schedules.json");
19156
19254
  }
19157
19255
  function parseDurationMs(every) {
19158
19256
  const m = every.trim().match(DURATION_RE);
@@ -19252,9 +19350,9 @@ function normalizeTask(raw) {
19252
19350
  }
19253
19351
  function readAll2() {
19254
19352
  const path = schedulesPath();
19255
- if (!(0, import_node_fs51.existsSync)(path)) return [];
19353
+ if (!(0, import_node_fs52.existsSync)(path)) return [];
19256
19354
  try {
19257
- const parsed = JSON.parse((0, import_node_fs51.readFileSync)(path, "utf8"));
19355
+ const parsed = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
19258
19356
  if (!Array.isArray(parsed)) return [];
19259
19357
  return parsed.map((row) => {
19260
19358
  try {
@@ -19366,13 +19464,13 @@ function recordScheduleRun(id, result) {
19366
19464
  writeAll2(rows);
19367
19465
  return next;
19368
19466
  }
19369
- var import_node_crypto10, import_node_fs51, import_node_path48, import_croner, DURATION_RE, UNIT_MS;
19467
+ var import_node_crypto10, import_node_fs52, import_node_path49, import_croner, DURATION_RE, UNIT_MS;
19370
19468
  var init_schedules = __esm({
19371
19469
  "src/store/schedules.ts"() {
19372
19470
  "use strict";
19373
19471
  import_node_crypto10 = require("crypto");
19374
- import_node_fs51 = require("fs");
19375
- import_node_path48 = require("path");
19472
+ import_node_fs52 = require("fs");
19473
+ import_node_path49 = require("path");
19376
19474
  import_croner = require("croner");
19377
19475
  init_orchestrator_capable();
19378
19476
  init_paths();
@@ -19514,13 +19612,13 @@ var init_schedule_runner = __esm({
19514
19612
 
19515
19613
  // src/agents/cursor-store.ts
19516
19614
  function cursorSdkStoreDir(threadId) {
19517
- const root = (0, import_node_path49.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
19615
+ const root = (0, import_node_path50.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
19518
19616
  const id = sanitizeCursorStoreSegment(threadId);
19519
19617
  if (!id) return root;
19520
- return (0, import_node_path49.join)(root, "threads", id);
19618
+ return (0, import_node_path50.join)(root, "threads", id);
19521
19619
  }
19522
19620
  function cursorSdkRunsNdjsonPath(threadId) {
19523
- return (0, import_node_path49.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
19621
+ return (0, import_node_path50.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
19524
19622
  }
19525
19623
  function cursorSdkRunsNdjsonSearchPaths(threadId) {
19526
19624
  const scoped = cursorSdkRunsNdjsonPath(threadId);
@@ -19533,11 +19631,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
19533
19631
  function sanitizeCursorStoreSegment(threadId) {
19534
19632
  return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
19535
19633
  }
19536
- var import_node_path49, CURSOR_SDK_STORE_DIR;
19634
+ var import_node_path50, CURSOR_SDK_STORE_DIR;
19537
19635
  var init_cursor_store = __esm({
19538
19636
  "src/agents/cursor-store.ts"() {
19539
19637
  "use strict";
19540
- import_node_path49 = require("path");
19638
+ import_node_path50 = require("path");
19541
19639
  init_paths();
19542
19640
  CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
19543
19641
  }
@@ -19559,9 +19657,9 @@ function recoverFinishedCursorRun(opts) {
19559
19657
  return best;
19560
19658
  }
19561
19659
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
19562
- if (!(0, import_node_fs52.existsSync)(runsPath)) return null;
19660
+ if (!(0, import_node_fs53.existsSync)(runsPath)) return null;
19563
19661
  try {
19564
- const lines = (0, import_node_fs52.readFileSync)(runsPath, "utf8").split("\n");
19662
+ const lines = (0, import_node_fs53.readFileSync)(runsPath, "utf8").split("\n");
19565
19663
  let best = null;
19566
19664
  for (const line of lines) {
19567
19665
  const trimmed = line.trim();
@@ -19587,11 +19685,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
19587
19685
  return null;
19588
19686
  }
19589
19687
  }
19590
- var import_node_fs52;
19688
+ var import_node_fs53;
19591
19689
  var init_cursor_recover = __esm({
19592
19690
  "src/agents/cursor-recover.ts"() {
19593
19691
  "use strict";
19594
- import_node_fs52 = require("fs");
19692
+ import_node_fs53 = require("fs");
19595
19693
  init_cursor_store();
19596
19694
  }
19597
19695
  });
@@ -19738,13 +19836,13 @@ async function startOrchestration(opts) {
19738
19836
  }
19739
19837
  return updated;
19740
19838
  }
19741
- var import_node_events, import_node_fs53, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
19839
+ var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
19742
19840
  var init_orchestrator = __esm({
19743
19841
  "src/orchestrator/orchestrator.ts"() {
19744
19842
  "use strict";
19745
19843
  import_node_events = require("events");
19746
19844
  init_outbound_watch();
19747
- import_node_fs53 = require("fs");
19845
+ import_node_fs54 = require("fs");
19748
19846
  init_error_detail();
19749
19847
  init_run();
19750
19848
  init_stale_lock();
@@ -19918,7 +20016,7 @@ var init_orchestrator = __esm({
19918
20016
  }
19919
20017
  continue;
19920
20018
  }
19921
- if (!(0, import_node_fs53.existsSync)(thread.worktreePath)) {
20019
+ if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
19922
20020
  setStatus(thread.id, "broken", "Worktree missing on disk");
19923
20021
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
19924
20022
  continue;
@@ -20048,8 +20146,8 @@ var init_orchestrator = __esm({
20048
20146
  await this.send(threadId, QUOTA_RESUME_PROMPT);
20049
20147
  }
20050
20148
  /**
20051
- * Host-side continue when an orchestration chat hits a provider session/usage
20052
- * limit (not context size): switch agent (Auto) or wait until reset.
20149
+ * Host-side continue when any chat hits a provider session/usage limit
20150
+ * (not context size): switch agent (Auto) or wait until reset.
20053
20151
  */
20054
20152
  async maybeHandleOrchestrationQuotaFailover(threadId, limitText) {
20055
20153
  const thread = findThreadByRef(threadId);
@@ -20062,7 +20160,7 @@ var init_orchestrator = __esm({
20062
20160
  setStatus(threadId, "idle", null);
20063
20161
  appendMessage(threadId, {
20064
20162
  role: "agent",
20065
- text: `Sideboard will auto-retry this orchestration around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
20163
+ text: `Sideboard will auto-retry this chat around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
20066
20164
  ts: (/* @__PURE__ */ new Date()).toISOString()
20067
20165
  });
20068
20166
  this.emit({
@@ -21865,7 +21963,7 @@ var init_orchestrator = __esm({
21865
21963
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
21866
21964
  return restored2;
21867
21965
  }
21868
- if (!(0, import_node_fs53.existsSync)(thread.worktreePath)) {
21966
+ if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
21869
21967
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
21870
21968
  throw new Error(
21871
21969
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -21949,7 +22047,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
21949
22047
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
21950
22048
  var import_zod9 = require("zod");
21951
22049
  var import_node_crypto13 = require("crypto");
21952
- var import_node_path52 = require("path");
22050
+ var import_node_path53 = require("path");
21953
22051
  init_orchestrator();
21954
22052
  init_worktree();
21955
22053
 
@@ -25352,27 +25450,27 @@ init_gh_errors();
25352
25450
  init_git_auth_mode();
25353
25451
 
25354
25452
  // src/board/load-home-board.ts
25355
- var import_node_fs55 = require("fs");
25356
- var import_node_path51 = require("path");
25453
+ var import_node_fs56 = require("fs");
25454
+ var import_node_path52 = require("path");
25357
25455
  init_worktree();
25358
25456
  init_paths();
25359
25457
 
25360
25458
  // src/board/board-pins.ts
25361
25459
  var import_node_crypto12 = require("crypto");
25362
- var import_node_fs54 = require("fs");
25363
- var import_node_path50 = require("path");
25460
+ var import_node_fs55 = require("fs");
25461
+ var import_node_path51 = require("path");
25364
25462
  init_paths();
25365
25463
  init_home_board();
25366
25464
  var FILE = "home-board-pins.json";
25367
25465
  var VERSION = 1;
25368
25466
  function pinsFile() {
25369
- return (0, import_node_path50.join)(appDataDir(), FILE);
25467
+ return (0, import_node_path51.join)(appDataDir(), FILE);
25370
25468
  }
25371
25469
  function readDisk() {
25372
25470
  const path = pinsFile();
25373
- if (!(0, import_node_fs54.existsSync)(path)) return [];
25471
+ if (!(0, import_node_fs55.existsSync)(path)) return [];
25374
25472
  try {
25375
- const raw = JSON.parse((0, import_node_fs54.readFileSync)(path, "utf8"));
25473
+ const raw = JSON.parse((0, import_node_fs55.readFileSync)(path, "utf8"));
25376
25474
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
25377
25475
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
25378
25476
  } catch {
@@ -25380,8 +25478,8 @@ function readDisk() {
25380
25478
  }
25381
25479
  }
25382
25480
  function writeDisk(items) {
25383
- (0, import_node_fs54.mkdirSync)(appDataDir(), { recursive: true });
25384
- (0, import_node_fs54.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
25481
+ (0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
25482
+ (0, import_node_fs55.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
25385
25483
  }
25386
25484
  function listBoardPins() {
25387
25485
  return readDisk();
@@ -25402,7 +25500,7 @@ function homeBoardWorkspaceKey(workspaces) {
25402
25500
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
25403
25501
  }
25404
25502
  function cacheFile() {
25405
- return (0, import_node_path51.join)(appDataDir(), "home-board-cache.json");
25503
+ return (0, import_node_path52.join)(appDataDir(), "home-board-cache.json");
25406
25504
  }
25407
25505
  function emptyInputs() {
25408
25506
  return {
@@ -25428,9 +25526,9 @@ function shouldCacheHomeBoardInputs(inputs) {
25428
25526
  }
25429
25527
  function readDiskCache() {
25430
25528
  const path = cacheFile();
25431
- if (!(0, import_node_fs55.existsSync)(path)) return null;
25529
+ if (!(0, import_node_fs56.existsSync)(path)) return null;
25432
25530
  try {
25433
- const raw = JSON.parse((0, import_node_fs55.readFileSync)(path, "utf8"));
25531
+ const raw = JSON.parse((0, import_node_fs56.readFileSync)(path, "utf8"));
25434
25532
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
25435
25533
  return null;
25436
25534
  }
@@ -25444,8 +25542,8 @@ function readDiskCache() {
25444
25542
  }
25445
25543
  function writeDiskCache(entry) {
25446
25544
  try {
25447
- (0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
25448
- (0, import_node_fs55.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
25545
+ (0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
25546
+ (0, import_node_fs56.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
25449
25547
  } catch {
25450
25548
  }
25451
25549
  }
@@ -25832,7 +25930,7 @@ async function startMcpServer() {
25832
25930
  async () => {
25833
25931
  const threads = orch.getThreads(true);
25834
25932
  const lines = threads.map((t) => {
25835
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path52.basename)(t.repoPath) || t.repoPath;
25933
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path53.basename)(t.repoPath) || t.repoPath;
25836
25934
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
25837
25935
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
25838
25936
  const preview = lastMessagePreview(t.messages, 80);