@sideboard-ai/core 0.1.208 → 0.1.210

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 (51) hide show
  1. package/dist/{abletime-I4IYZBKU.js → abletime-GDZLZRMY.js} +4 -4
  2. package/dist/{abletime-UWSSLXH3.js → abletime-QGGYL2G4.js} +4 -4
  3. package/dist/{abletime-oauth-C3BQXKW3.js → abletime-oauth-3X3BAPTF.js} +3 -3
  4. package/dist/{abletime-oauth-UZHPB3W2.js → abletime-oauth-F335TWKY.js} +3 -3
  5. package/dist/{abletime-rest-HYNYDYK3.js → abletime-rest-LAGTPAJL.js} +3 -3
  6. package/dist/{abletime-rest-5YPPEOKK.js → abletime-rest-PLJVY3H3.js} +3 -3
  7. package/dist/agents/cursor-runner.js +3 -3
  8. package/dist/{agents-QHQXR55O.js → agents-G3TFVFBQ.js} +6 -5
  9. package/dist/{agents-CCS5IEBV.js → agents-IQZUN47D.js} +6 -5
  10. package/dist/{app-settings-GJ6KDYEF.js → app-settings-2TN3WLZV.js} +7 -1
  11. package/dist/{app-settings-R2KNCT37.js → app-settings-XCRNCEEE.js} +7 -1
  12. package/dist/{chunk-F4LZUEIO.js → chunk-2M5B7YNY.js} +2 -2
  13. package/dist/{chunk-C6ZNQV5W.js → chunk-2R6BZRRB.js} +117 -25
  14. package/dist/{chunk-HA4EZKFY.js → chunk-3S2LDD2F.js} +3 -3
  15. package/dist/{chunk-6YZLSZLK.js → chunk-42IULNIY.js} +3 -3
  16. package/dist/{chunk-C5MNMITQ.js → chunk-AOQZZA3M.js} +119 -25
  17. package/dist/{chunk-4EGK47WV.js → chunk-BTC2D6LS.js} +217 -0
  18. package/dist/{chunk-7DKX5JLT.js → chunk-FGTPRMPS.js} +18 -3
  19. package/dist/{chunk-X45BV4VX.js → chunk-G4TANQC3.js} +5 -5
  20. package/dist/{chunk-Y4CF7LHH.js → chunk-L5CIEBLR.js} +232 -0
  21. package/dist/{chunk-WXWJ5MJ4.js → chunk-LS6TSOCE.js} +5 -5
  22. package/dist/{chunk-6J4OQ6TF.js → chunk-MN6YUD4O.js} +3 -3
  23. package/dist/{chunk-7PEIIN7P.js → chunk-NDE5RKZP.js} +24 -87
  24. package/dist/{chunk-W6X4GZJG.js → chunk-REZRGCKV.js} +3 -3
  25. package/dist/{chunk-NJ2CCLV6.js → chunk-WX4S775K.js} +2 -2
  26. package/dist/chunk-X5B3OS5I.js +34 -0
  27. package/dist/{chunk-ZHCB4CKR.js → chunk-X5PUFYDJ.js} +18 -3
  28. package/dist/{chunk-TEDEVD4O.js → chunk-YVE4PXCJ.js} +2 -2
  29. package/dist/{chunk-A6SOSLUV.js → chunk-YYELAUKP.js} +24 -94
  30. package/dist/{chunk-DNTPX6HV.js → chunk-ZC664YBJ.js} +3 -3
  31. package/dist/{chunk-OP6CFVTB.js → chunk-ZZNZX2QW.js} +2 -2
  32. package/dist/{coordinator-prompt-WOTJQMD5.js → coordinator-prompt-GCITY3Q5.js} +5 -4
  33. package/dist/{coordinator-prompt-TUHB6ZFA.js → coordinator-prompt-PONGPWIP.js} +5 -4
  34. package/dist/{cursor-recover-TXVTLAMA.js → cursor-recover-4PQAADAU.js} +3 -28
  35. package/dist/{global-workspace-V6G2KH2V.js → global-workspace-LIZHU4GM.js} +5 -4
  36. package/dist/{global-workspace-5UUUNA4A.js → global-workspace-LQZLTGFL.js} +5 -4
  37. package/dist/index.cjs +681 -385
  38. package/dist/index.d.cts +96 -5
  39. package/dist/index.d.ts +96 -5
  40. package/dist/index.js +52 -19
  41. package/dist/mcp/run-stdio.cjs +647 -385
  42. package/dist/mcp/run-stdio.js +12 -11
  43. package/dist/{orchestrator-4IGHVRAF.js → orchestrator-G5HELCVT.js} +7 -6
  44. package/dist/{orchestrator-D4AQNF25.js → orchestrator-ZBUXJCII.js} +7 -6
  45. package/dist/{thread-store-FMWDFAO5.js → thread-store-FCWU7Y3X.js} +2 -1
  46. package/dist/{thread-store-ESZYZSVC.js → thread-store-KMZRQEPY.js} +2 -1
  47. package/dist/{workspaces-PZ36M7EQ.js → workspaces-2XW2DMRG.js} +5 -4
  48. package/dist/{workspaces-CLNANACI.js → workspaces-T6PMQZYQ.js} +5 -4
  49. package/dist/{worktree-JKTM47K5.js → worktree-2OEMMFRT.js} +4 -3
  50. package/dist/{worktree-NC4XQNQI.js → worktree-5ZGWKKZ6.js} +4 -3
  51. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -991,6 +991,182 @@ var init_branch_prefix = __esm({
991
991
  }
992
992
  });
993
993
 
994
+ // src/agents/usage.ts
995
+ function sumOptional(a, b) {
996
+ if (a == null && b == null) return void 0;
997
+ return (a ?? 0) + (b ?? 0);
998
+ }
999
+ function fromInclusiveInputUsage(opts) {
1000
+ const totalInput = Number(opts.inputTokens) || 0;
1001
+ const outputTokens = Number(opts.outputTokens) || 0;
1002
+ const cached = Number(opts.cachedInputTokens) || 0;
1003
+ if (!totalInput && !outputTokens) return null;
1004
+ const cacheReadTokens = cached > 0 ? Math.min(cached, totalInput) : 0;
1005
+ return {
1006
+ inputTokens: Math.max(0, totalInput - cacheReadTokens),
1007
+ outputTokens,
1008
+ cacheReadTokens: cacheReadTokens || void 0
1009
+ };
1010
+ }
1011
+ function requestOccupancy(u) {
1012
+ return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
1013
+ }
1014
+ function mergeUsage(a, b) {
1015
+ return {
1016
+ inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
1017
+ outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
1018
+ cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
1019
+ cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
1020
+ costUsd: sumOptional(a?.costUsd, b.costUsd),
1021
+ lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
1022
+ };
1023
+ }
1024
+ function sumUsageList(list) {
1025
+ let acc = null;
1026
+ for (const u of list) {
1027
+ if (!u) continue;
1028
+ acc = mergeUsage(acc, {
1029
+ inputTokens: u.inputTokens,
1030
+ outputTokens: u.outputTokens,
1031
+ cacheReadTokens: u.cacheReadTokens,
1032
+ cacheWriteTokens: u.cacheWriteTokens,
1033
+ costUsd: u.costUsd
1034
+ });
1035
+ }
1036
+ if (!acc) return null;
1037
+ return {
1038
+ inputTokens: acc.inputTokens,
1039
+ outputTokens: acc.outputTokens,
1040
+ ...acc.cacheReadTokens != null ? { cacheReadTokens: acc.cacheReadTokens } : {},
1041
+ ...acc.cacheWriteTokens != null ? { cacheWriteTokens: acc.cacheWriteTokens } : {},
1042
+ ...acc.costUsd != null ? { costUsd: acc.costUsd } : {}
1043
+ };
1044
+ }
1045
+ function hasBilledTokens(u) {
1046
+ return Boolean(
1047
+ u.inputTokens || u.outputTokens || u.cacheReadTokens || u.cacheWriteTokens
1048
+ );
1049
+ }
1050
+ function applyTurnUsage(current, incoming, scope = "request") {
1051
+ if (scope === "turn") {
1052
+ if (!hasBilledTokens(incoming) && current && incoming.costUsd != null) {
1053
+ return { ...current, costUsd: incoming.costUsd };
1054
+ }
1055
+ return {
1056
+ ...incoming,
1057
+ costUsd: incoming.costUsd ?? current?.costUsd,
1058
+ lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
1059
+ };
1060
+ }
1061
+ const merged = mergeUsage(current, incoming);
1062
+ const occ = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : requestOccupancy(incoming);
1063
+ return {
1064
+ ...merged,
1065
+ lastRequestTokens: occ > 0 ? occ : current?.lastRequestTokens ?? occ
1066
+ };
1067
+ }
1068
+ function totalTokens(u) {
1069
+ return u.inputTokens + u.outputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
1070
+ }
1071
+ function contextTokens(u) {
1072
+ if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
1073
+ return requestOccupancy(u);
1074
+ }
1075
+ var init_usage = __esm({
1076
+ "src/agents/usage.ts"() {
1077
+ "use strict";
1078
+ }
1079
+ });
1080
+
1081
+ // src/store/history-retention.ts
1082
+ function clampHistoryMaxCount(value) {
1083
+ return Math.max(HISTORY_MAX_COUNT_MIN, Math.min(HISTORY_MAX_COUNT_MAX, Math.floor(value)));
1084
+ }
1085
+ function clampHistoryMaxDays(value) {
1086
+ if (!Number.isFinite(value) || value <= 0) return 0;
1087
+ return Math.min(HISTORY_MAX_DAYS_MAX, Math.floor(value));
1088
+ }
1089
+ function archivedUpdatedMs(thread) {
1090
+ const stamped = thread.archivedAt ? Date.parse(thread.archivedAt) : NaN;
1091
+ if (Number.isFinite(stamped)) return stamped;
1092
+ const updated = Date.parse(thread.updatedAt);
1093
+ if (Number.isFinite(updated)) return updated;
1094
+ const created = Date.parse(thread.createdAt);
1095
+ return Number.isFinite(created) ? created : 0;
1096
+ }
1097
+ function isHistoryRetentionStub(thread) {
1098
+ if ((thread.attachments?.length ?? 0) > 0) return false;
1099
+ const messages = thread.messages ?? [];
1100
+ if (messages.length === 0) return true;
1101
+ if (messages.length > 1) return false;
1102
+ const only = messages[0];
1103
+ if (only.parts?.length) return false;
1104
+ if ((only.attachments?.length ?? 0) > 0) return false;
1105
+ const text7 = (only.text ?? "").trim();
1106
+ return text7 === "" || text7 === HISTORY_DISCARDED_TEXT;
1107
+ }
1108
+ function historyRetentionStubMessage(thread) {
1109
+ const usage = sumUsageList((thread.messages ?? []).map((m) => m.usage));
1110
+ return {
1111
+ role: "summary",
1112
+ text: HISTORY_DISCARDED_TEXT,
1113
+ ts: thread.updatedAt,
1114
+ ...usage ? { usage } : {}
1115
+ };
1116
+ }
1117
+ function sortArchivedOldestFirst(threads) {
1118
+ return [...threads].sort((a, b) => archivedUpdatedMs(a) - archivedUpdatedMs(b));
1119
+ }
1120
+ function planHistoryRetention(archived, thresholds = {}) {
1121
+ const maxCount = clampHistoryMaxCount(thresholds.maxCount ?? HISTORY_MAX_COUNT_DEFAULT);
1122
+ const maxDays = clampHistoryMaxDays(thresholds.maxDays ?? HISTORY_MAX_DAYS_DEFAULT);
1123
+ const nowMs = thresholds.nowMs ?? Date.now();
1124
+ const oldestFirst = sortArchivedOldestFirst(archived);
1125
+ const expiredIds = /* @__PURE__ */ new Set();
1126
+ if (maxDays > 0) {
1127
+ const cutoff = nowMs - maxDays * 864e5;
1128
+ for (const thread of oldestFirst) {
1129
+ if (archivedUpdatedMs(thread) < cutoff) expiredIds.add(thread.id);
1130
+ }
1131
+ }
1132
+ const remaining = oldestFirst.filter((t) => !expiredIds.has(t.id));
1133
+ const overflow = remaining.length > maxCount ? remaining.slice(0, remaining.length - maxCount) : [];
1134
+ const stripIds = [];
1135
+ const purgeIds = [...expiredIds];
1136
+ const seenPurge = new Set(purgeIds);
1137
+ for (const thread of overflow) {
1138
+ if (isHistoryRetentionStub(thread)) {
1139
+ if (!seenPurge.has(thread.id)) {
1140
+ seenPurge.add(thread.id);
1141
+ purgeIds.push(thread.id);
1142
+ }
1143
+ } else {
1144
+ stripIds.push(thread.id);
1145
+ }
1146
+ }
1147
+ return { stripIds, purgeIds };
1148
+ }
1149
+ function planHistoryAgePurge(archived, olderThanDays, nowMs = Date.now()) {
1150
+ const days = clampHistoryMaxDays(olderThanDays);
1151
+ if (days <= 0) return [];
1152
+ const cutoff = nowMs - days * 864e5;
1153
+ return sortArchivedOldestFirst(archived).filter((t) => archivedUpdatedMs(t) < cutoff).map((t) => t.id);
1154
+ }
1155
+ var HISTORY_MAX_COUNT_DEFAULT, HISTORY_MAX_COUNT_MIN, HISTORY_MAX_COUNT_MAX, HISTORY_MAX_DAYS_DEFAULT, HISTORY_MAX_DAYS_MAX, HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT, HISTORY_DISCARDED_TEXT;
1156
+ var init_history_retention = __esm({
1157
+ "src/store/history-retention.ts"() {
1158
+ "use strict";
1159
+ init_usage();
1160
+ HISTORY_MAX_COUNT_DEFAULT = 200;
1161
+ HISTORY_MAX_COUNT_MIN = 1;
1162
+ HISTORY_MAX_COUNT_MAX = 2e3;
1163
+ HISTORY_MAX_DAYS_DEFAULT = 0;
1164
+ HISTORY_MAX_DAYS_MAX = 3650;
1165
+ HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT = 6;
1166
+ HISTORY_DISCARDED_TEXT = "Transcript discarded by History retention.";
1167
+ }
1168
+ });
1169
+
994
1170
  // src/store/usage-on-limit.ts
995
1171
  function isUsageOnLimit(value) {
996
1172
  return value === "keep_going" || value === "confirm" || value === "switch_agent" || value === "wait_reset";
@@ -1047,6 +1223,7 @@ __export(app_settings_exports, {
1047
1223
  appSettingsPath: () => appSettingsPath,
1048
1224
  applyAppEnvironment: () => applyAppEnvironment,
1049
1225
  autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
1226
+ autoCleanupHistoryEnabled: () => autoCleanupHistoryEnabled,
1050
1227
  autoCleanupOrphansEnabled: () => autoCleanupOrphansEnabled,
1051
1228
  autoRenameBranchEnabled: () => autoRenameBranchEnabled,
1052
1229
  autoRunAfterSetupEnabled: () => autoRunAfterSetupEnabled,
@@ -1087,6 +1264,8 @@ __export(app_settings_exports, {
1087
1264
  getLinearApiKey: () => getLinearApiKey,
1088
1265
  gitBranchPrefixSetting: () => gitBranchPrefixSetting,
1089
1266
  harnessEnvKey: () => harnessEnvKey,
1267
+ historyMaxCount: () => historyMaxCount,
1268
+ historyMaxDays: () => historyMaxDays,
1090
1269
  isAbleTimeConnected: () => isAbleTimeConnected,
1091
1270
  isIssueSourceConnected: () => isIssueSourceConnected,
1092
1271
  isLinearConnected: () => isLinearConnected,
@@ -1532,6 +1711,24 @@ function normalizeAdvanced(raw) {
1532
1711
  if (typeof source.autoCleanupOrphans === "boolean") {
1533
1712
  out.autoCleanupOrphans = source.autoCleanupOrphans;
1534
1713
  }
1714
+ if (typeof source.autoCleanupHistory === "boolean") {
1715
+ out.autoCleanupHistory = source.autoCleanupHistory;
1716
+ }
1717
+ if (typeof source.historyMaxCount === "number" && Number.isFinite(source.historyMaxCount)) {
1718
+ out.historyMaxCount = clampHistoryMaxCount(source.historyMaxCount);
1719
+ }
1720
+ if (typeof source.historyMaxDays === "number" && Number.isFinite(source.historyMaxDays)) {
1721
+ out.historyMaxDays = clampHistoryMaxDays(source.historyMaxDays);
1722
+ }
1723
+ if (typeof source.historyCleanupIntervalHours === "number" && Number.isFinite(source.historyCleanupIntervalHours)) {
1724
+ out.historyCleanupIntervalHours = Math.max(
1725
+ 1,
1726
+ Math.min(168, Math.floor(source.historyCleanupIntervalHours))
1727
+ );
1728
+ }
1729
+ if (typeof source.historyLastCleanupAt === "string" && source.historyLastCleanupAt.trim()) {
1730
+ out.historyLastCleanupAt = source.historyLastCleanupAt.trim();
1731
+ }
1535
1732
  if (source.orchestrationQuotaOnLimit === "switch_agent" || source.orchestrationQuotaOnLimit === "wait_reset") {
1536
1733
  out.orchestrationQuotaOnLimit = source.orchestrationQuotaOnLimit;
1537
1734
  }
@@ -2424,6 +2621,24 @@ function updateAdvancedSettings(patch) {
2424
2621
  if (typeof patch.autoCleanupOrphans === "boolean") {
2425
2622
  advanced.autoCleanupOrphans = patch.autoCleanupOrphans;
2426
2623
  }
2624
+ if (typeof patch.autoCleanupHistory === "boolean") {
2625
+ advanced.autoCleanupHistory = patch.autoCleanupHistory;
2626
+ }
2627
+ if (typeof patch.historyMaxCount === "number" && Number.isFinite(patch.historyMaxCount)) {
2628
+ advanced.historyMaxCount = clampHistoryMaxCount(patch.historyMaxCount);
2629
+ }
2630
+ if (typeof patch.historyMaxDays === "number" && Number.isFinite(patch.historyMaxDays)) {
2631
+ advanced.historyMaxDays = clampHistoryMaxDays(patch.historyMaxDays);
2632
+ }
2633
+ if (typeof patch.historyCleanupIntervalHours === "number" && Number.isFinite(patch.historyCleanupIntervalHours)) {
2634
+ advanced.historyCleanupIntervalHours = Math.max(
2635
+ 1,
2636
+ Math.min(168, Math.floor(patch.historyCleanupIntervalHours))
2637
+ );
2638
+ }
2639
+ if (typeof patch.historyLastCleanupAt === "string") {
2640
+ advanced.historyLastCleanupAt = patch.historyLastCleanupAt;
2641
+ }
2427
2642
  if (patch.orchestrationQuotaOnLimit === "switch_agent" || patch.orchestrationQuotaOnLimit === "wait_reset") {
2428
2643
  advanced.orchestrationQuotaOnLimit = patch.orchestrationQuotaOnLimit;
2429
2644
  }
@@ -2474,6 +2689,15 @@ function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
2474
2689
  function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
2475
2690
  return Boolean(settings.advanced.autoCleanupOrphans);
2476
2691
  }
2692
+ function autoCleanupHistoryEnabled(settings = loadAppSettings()) {
2693
+ return settings.advanced.autoCleanupHistory !== false;
2694
+ }
2695
+ function historyMaxCount(settings = loadAppSettings()) {
2696
+ return clampHistoryMaxCount(settings.advanced.historyMaxCount ?? HISTORY_MAX_COUNT_DEFAULT);
2697
+ }
2698
+ function historyMaxDays(settings = loadAppSettings()) {
2699
+ return clampHistoryMaxDays(settings.advanced.historyMaxDays ?? HISTORY_MAX_DAYS_DEFAULT);
2700
+ }
2477
2701
  function usageOnLimit(settings = loadAppSettings()) {
2478
2702
  return resolveUsageOnLimit(settings.advanced);
2479
2703
  }
@@ -2594,6 +2818,7 @@ var init_app_settings = __esm({
2594
2818
  init_private_file();
2595
2819
  init_secret_vault();
2596
2820
  init_branch_prefix();
2821
+ init_history_retention();
2597
2822
  init_usage_on_limit();
2598
2823
  init_usage_on_limit();
2599
2824
  init_issue_source_labels();
@@ -2814,6 +3039,37 @@ var init_caffeinate_hold = __esm({
2814
3039
  }
2815
3040
  });
2816
3041
 
3042
+ // src/agents/cursor-store.ts
3043
+ function cursorSdkStoreDir(threadId) {
3044
+ const root = (0, import_node_path10.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
3045
+ const id = sanitizeCursorStoreSegment(threadId);
3046
+ if (!id) return root;
3047
+ return (0, import_node_path10.join)(root, "threads", id);
3048
+ }
3049
+ function cursorSdkRunsNdjsonPath(threadId) {
3050
+ return (0, import_node_path10.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
3051
+ }
3052
+ function cursorSdkRunsNdjsonSearchPaths(threadId) {
3053
+ const scoped = cursorSdkRunsNdjsonPath(threadId);
3054
+ const shared = cursorSdkRunsNdjsonPath(null);
3055
+ if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
3056
+ return [shared];
3057
+ }
3058
+ return [scoped, shared];
3059
+ }
3060
+ function sanitizeCursorStoreSegment(threadId) {
3061
+ return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
3062
+ }
3063
+ var import_node_path10, CURSOR_SDK_STORE_DIR;
3064
+ var init_cursor_store = __esm({
3065
+ "src/agents/cursor-store.ts"() {
3066
+ "use strict";
3067
+ import_node_path10 = require("path");
3068
+ init_paths();
3069
+ CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
3070
+ }
3071
+ });
3072
+
2817
3073
  // src/store/thread-store.ts
2818
3074
  var thread_store_exports = {};
2819
3075
  __export(thread_store_exports, {
@@ -2865,7 +3121,8 @@ function normalizeThread(raw) {
2865
3121
  userSetTitle: Boolean(raw.userSetTitle),
2866
3122
  activeRuns: Array.isArray(raw.activeRuns) ? raw.activeRuns : [],
2867
3123
  quotaResumeAt: raw.quotaResumeAt ?? null,
2868
- quotaContinuedFromId: raw.quotaContinuedFromId ?? null
3124
+ quotaContinuedFromId: raw.quotaContinuedFromId ?? null,
3125
+ archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0
2869
3126
  };
2870
3127
  }
2871
3128
  function createEmptyThread(partial) {
@@ -2900,6 +3157,7 @@ function createEmptyThread(partial) {
2900
3157
  pendingTurnAttachments: partial.pendingTurnAttachments ?? [],
2901
3158
  createdAt: ts,
2902
3159
  updatedAt: ts,
3160
+ archivedAt: typeof partial.archivedAt === "string" && partial.archivedAt.trim() ? partial.archivedAt.trim() : void 0,
2903
3161
  title: partial.title,
2904
3162
  sourceType: partial.sourceType,
2905
3163
  sourceRef: partial.sourceRef,
@@ -2971,10 +3229,10 @@ function readThread(id) {
2971
3229
  rememberThread(thread, mtimeMs);
2972
3230
  return thread;
2973
3231
  }
2974
- function writeThread(thread) {
3232
+ function writeThread(thread, opts) {
2975
3233
  const path2 = threadFilePath(idPath(thread.id));
2976
3234
  const tmp = `${path2}.${process.pid}.tmp`;
2977
- const next = { ...thread, updatedAt: nowIso() };
3235
+ const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
2978
3236
  (0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
2979
3237
  (0, import_node_fs9.renameSync)(tmp, path2);
2980
3238
  rememberThread(next, fileMtimeMs(path2) ?? Date.now());
@@ -2983,7 +3241,7 @@ function idPath(id) {
2983
3241
  return id;
2984
3242
  }
2985
3243
  function isThreadRecordFile(nameOrPath) {
2986
- const name = (0, import_node_path10.basename)(nameOrPath);
3244
+ const name = (0, import_node_path11.basename)(nameOrPath);
2987
3245
  return name.endsWith(".json") && !name.endsWith(".live.json");
2988
3246
  }
2989
3247
  function listThreads(opts) {
@@ -3019,11 +3277,20 @@ function deleteThreadRecord(id) {
3019
3277
  } catch {
3020
3278
  }
3021
3279
  }
3280
+ try {
3281
+ (0, import_node_fs9.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
3282
+ } catch {
3283
+ }
3022
3284
  }
3023
3285
  function updateThread(id, patch) {
3024
3286
  const current = readThread(id);
3025
3287
  if (!current) throw new Error(`Thread not found: ${id}`);
3026
3288
  const next = { ...current, ...patch, id: current.id, updatedAt: nowIso() };
3289
+ if (next.status === "archived") {
3290
+ next.archivedAt = typeof next.archivedAt === "string" && next.archivedAt.trim() || current.archivedAt || nowIso();
3291
+ } else {
3292
+ delete next.archivedAt;
3293
+ }
3027
3294
  writeThread(next);
3028
3295
  return next;
3029
3296
  }
@@ -3041,15 +3308,16 @@ function findThreadByRef(ref) {
3041
3308
  (t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
3042
3309
  ) ?? null;
3043
3310
  }
3044
- var import_node_crypto3, import_node_fs9, import_node_path10, import_proper_lockfile, listCache;
3311
+ var import_node_crypto3, import_node_fs9, import_node_path11, import_proper_lockfile, listCache;
3045
3312
  var init_thread_store = __esm({
3046
3313
  "src/store/thread-store.ts"() {
3047
3314
  "use strict";
3048
3315
  import_node_crypto3 = require("crypto");
3049
3316
  import_node_fs9 = require("fs");
3050
- import_node_path10 = require("path");
3317
+ import_node_path11 = require("path");
3051
3318
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
3052
3319
  init_thinking_effort();
3320
+ init_cursor_store();
3053
3321
  init_paths();
3054
3322
  listCache = null;
3055
3323
  }
@@ -4048,93 +4316,6 @@ var init_message_parts = __esm({
4048
4316
  }
4049
4317
  });
4050
4318
 
4051
- // src/agents/usage.ts
4052
- function sumOptional(a, b) {
4053
- if (a == null && b == null) return void 0;
4054
- return (a ?? 0) + (b ?? 0);
4055
- }
4056
- function fromInclusiveInputUsage(opts) {
4057
- const totalInput = Number(opts.inputTokens) || 0;
4058
- const outputTokens = Number(opts.outputTokens) || 0;
4059
- const cached = Number(opts.cachedInputTokens) || 0;
4060
- if (!totalInput && !outputTokens) return null;
4061
- const cacheReadTokens = cached > 0 ? Math.min(cached, totalInput) : 0;
4062
- return {
4063
- inputTokens: Math.max(0, totalInput - cacheReadTokens),
4064
- outputTokens,
4065
- cacheReadTokens: cacheReadTokens || void 0
4066
- };
4067
- }
4068
- function requestOccupancy(u) {
4069
- return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
4070
- }
4071
- function mergeUsage(a, b) {
4072
- return {
4073
- inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
4074
- outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
4075
- cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
4076
- cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
4077
- costUsd: sumOptional(a?.costUsd, b.costUsd),
4078
- lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
4079
- };
4080
- }
4081
- function sumUsageList(list) {
4082
- let acc = null;
4083
- for (const u of list) {
4084
- if (!u) continue;
4085
- acc = mergeUsage(acc, {
4086
- inputTokens: u.inputTokens,
4087
- outputTokens: u.outputTokens,
4088
- cacheReadTokens: u.cacheReadTokens,
4089
- cacheWriteTokens: u.cacheWriteTokens,
4090
- costUsd: u.costUsd
4091
- });
4092
- }
4093
- if (!acc) return null;
4094
- return {
4095
- inputTokens: acc.inputTokens,
4096
- outputTokens: acc.outputTokens,
4097
- ...acc.cacheReadTokens != null ? { cacheReadTokens: acc.cacheReadTokens } : {},
4098
- ...acc.cacheWriteTokens != null ? { cacheWriteTokens: acc.cacheWriteTokens } : {},
4099
- ...acc.costUsd != null ? { costUsd: acc.costUsd } : {}
4100
- };
4101
- }
4102
- function hasBilledTokens(u) {
4103
- return Boolean(
4104
- u.inputTokens || u.outputTokens || u.cacheReadTokens || u.cacheWriteTokens
4105
- );
4106
- }
4107
- function applyTurnUsage(current, incoming, scope = "request") {
4108
- if (scope === "turn") {
4109
- if (!hasBilledTokens(incoming) && current && incoming.costUsd != null) {
4110
- return { ...current, costUsd: incoming.costUsd };
4111
- }
4112
- return {
4113
- ...incoming,
4114
- costUsd: incoming.costUsd ?? current?.costUsd,
4115
- lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
4116
- };
4117
- }
4118
- const merged = mergeUsage(current, incoming);
4119
- const occ = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : requestOccupancy(incoming);
4120
- return {
4121
- ...merged,
4122
- lastRequestTokens: occ > 0 ? occ : current?.lastRequestTokens ?? occ
4123
- };
4124
- }
4125
- function totalTokens(u) {
4126
- return u.inputTokens + u.outputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
4127
- }
4128
- function contextTokens(u) {
4129
- if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
4130
- return requestOccupancy(u);
4131
- }
4132
- var init_usage = __esm({
4133
- "src/agents/usage.ts"() {
4134
- "use strict";
4135
- }
4136
- });
4137
-
4138
4319
  // src/git/team-meta.ts
4139
4320
  var SOCCER_TEAM_META;
4140
4321
  var init_team_meta = __esm({
@@ -5574,7 +5755,7 @@ ${line}` : line;
5574
5755
  return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
5575
5756
  }
5576
5757
  function setupLogPath(threadId) {
5577
- return (0, import_node_path11.join)(threadsDir(), `${threadId}.setup.log.json`);
5758
+ return (0, import_node_path12.join)(threadsDir(), `${threadId}.setup.log.json`);
5578
5759
  }
5579
5760
  function setupLogKeyForWorktree(worktreePath) {
5580
5761
  const norm = normalizeWorktreePath(worktreePath);
@@ -5677,13 +5858,13 @@ function finishSetupLog(threadId, exitCode, source) {
5677
5858
  persistNow(threadId);
5678
5859
  return clone(snap);
5679
5860
  }
5680
- var import_node_crypto4, import_node_fs10, import_node_path11, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
5861
+ var import_node_crypto4, import_node_fs10, import_node_path12, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
5681
5862
  var init_setup_log = __esm({
5682
5863
  "src/store/setup-log.ts"() {
5683
5864
  "use strict";
5684
5865
  import_node_crypto4 = require("crypto");
5685
5866
  import_node_fs10 = require("fs");
5686
- import_node_path11 = require("path");
5867
+ import_node_path12 = require("path");
5687
5868
  init_worktree_labels();
5688
5869
  init_paths();
5689
5870
  EMPTY = {
@@ -5700,7 +5881,7 @@ var init_setup_log = __esm({
5700
5881
 
5701
5882
  // src/store/schedules.ts
5702
5883
  function schedulesPath() {
5703
- return (0, import_node_path12.join)(appDataDir(), "schedules.json");
5884
+ return (0, import_node_path13.join)(appDataDir(), "schedules.json");
5704
5885
  }
5705
5886
  function parseDurationMs(every) {
5706
5887
  const m = every.trim().match(DURATION_RE);
@@ -5923,13 +6104,13 @@ function recordScheduleRun(id, result) {
5923
6104
  writeAll(rows);
5924
6105
  return next;
5925
6106
  }
5926
- var import_node_crypto5, import_node_fs11, import_node_path12, import_croner, DURATION_RE, UNIT_MS;
6107
+ var import_node_crypto5, import_node_fs11, import_node_path13, import_croner, DURATION_RE, UNIT_MS;
5927
6108
  var init_schedules = __esm({
5928
6109
  "src/store/schedules.ts"() {
5929
6110
  "use strict";
5930
6111
  import_node_crypto5 = require("crypto");
5931
6112
  import_node_fs11 = require("fs");
5932
- import_node_path12 = require("path");
6113
+ import_node_path13 = require("path");
5933
6114
  import_croner = require("croner");
5934
6115
  init_orchestrator_capable();
5935
6116
  init_paths();
@@ -5946,7 +6127,7 @@ var init_schedules = __esm({
5946
6127
 
5947
6128
  // src/store/desktop-host.ts
5948
6129
  function desktopHostPidPath() {
5949
- return (0, import_node_path13.join)(appDataDir(), "desktop-host.pid");
6130
+ return (0, import_node_path14.join)(appDataDir(), "desktop-host.pid");
5950
6131
  }
5951
6132
  function claimDesktopHost(pid = process.pid) {
5952
6133
  (0, import_node_fs12.writeFileSync)(desktopHostPidPath(), `${pid}
@@ -5987,12 +6168,12 @@ function thisProcessShouldDrainAgentQueues() {
5987
6168
  if (isThisProcessDesktopHost()) return true;
5988
6169
  return !isDesktopHostAlive();
5989
6170
  }
5990
- var import_node_fs12, import_node_path13;
6171
+ var import_node_fs12, import_node_path14;
5991
6172
  var init_desktop_host = __esm({
5992
6173
  "src/store/desktop-host.ts"() {
5993
6174
  "use strict";
5994
6175
  import_node_fs12 = require("fs");
5995
- import_node_path13 = require("path");
6176
+ import_node_path14 = require("path");
5996
6177
  init_paths();
5997
6178
  }
5998
6179
  });
@@ -6059,7 +6240,7 @@ var init_workspace_scratch = __esm({
6059
6240
 
6060
6241
  // src/composer/stage-files.ts
6061
6242
  function fileExtension(filePath) {
6062
- const base = (0, import_node_path14.basename)(filePath).toLowerCase();
6243
+ const base = (0, import_node_path15.basename)(filePath).toLowerCase();
6063
6244
  return base.includes(".") ? base.split(".").pop() || "" : "";
6064
6245
  }
6065
6246
  function isImageFilePath(filePath) {
@@ -6069,9 +6250,9 @@ function imageMimeType(filePath) {
6069
6250
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
6070
6251
  }
6071
6252
  function ensureAttachmentsDir(worktreePath) {
6072
- const dir = (0, import_node_path14.join)(worktreePath, ATTACHMENTS_DIR);
6253
+ const dir = (0, import_node_path15.join)(worktreePath, ATTACHMENTS_DIR);
6073
6254
  (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
6074
- const gi = (0, import_node_path14.join)(dir, ".gitignore");
6255
+ const gi = (0, import_node_path15.join)(dir, ".gitignore");
6075
6256
  if (!(0, import_node_fs13.existsSync)(gi)) {
6076
6257
  (0, import_node_fs13.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
6077
6258
  }
@@ -6079,12 +6260,12 @@ function ensureAttachmentsDir(worktreePath) {
6079
6260
  }
6080
6261
  function uniqueAttachmentName(dir, originalName) {
6081
6262
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
6082
- if (!(0, import_node_fs13.existsSync)((0, import_node_path14.join)(dir, safe))) return safe;
6083
- const ext = (0, import_node_path14.extname)(safe);
6263
+ if (!(0, import_node_fs13.existsSync)((0, import_node_path15.join)(dir, safe))) return safe;
6264
+ const ext = (0, import_node_path15.extname)(safe);
6084
6265
  const stem = ext ? safe.slice(0, -ext.length) : safe;
6085
6266
  for (let i = 1; i < 1e4; i++) {
6086
6267
  const candidate = `${stem}-${i}${ext}`;
6087
- if (!(0, import_node_fs13.existsSync)((0, import_node_path14.join)(dir, candidate))) return candidate;
6268
+ if (!(0, import_node_fs13.existsSync)((0, import_node_path15.join)(dir, candidate))) return candidate;
6088
6269
  }
6089
6270
  return `${stem}-${(0, import_node_crypto6.randomUUID)()}${ext}`;
6090
6271
  }
@@ -6136,7 +6317,7 @@ function attachmentFromBuffer(name, buf, opts) {
6136
6317
  };
6137
6318
  }
6138
6319
  function attachmentFromAbsolutePath(absolutePath) {
6139
- const name = (0, import_node_path14.basename)(absolutePath);
6320
+ const name = (0, import_node_path15.basename)(absolutePath);
6140
6321
  try {
6141
6322
  const st = (0, import_node_fs13.statSync)(absolutePath);
6142
6323
  if (!st.isFile()) {
@@ -6163,12 +6344,12 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
6163
6344
  const dir = ensureAttachmentsDir(worktreePath);
6164
6345
  const out = [];
6165
6346
  for (const abs of absolutePaths) {
6166
- const originalName = (0, import_node_path14.basename)(abs);
6347
+ const originalName = (0, import_node_path15.basename)(abs);
6167
6348
  try {
6168
6349
  const st = (0, import_node_fs13.statSync)(abs);
6169
6350
  if (!st.isFile()) continue;
6170
6351
  const name = uniqueAttachmentName(dir, originalName);
6171
- const destAbs = (0, import_node_path14.join)(dir, name);
6352
+ const destAbs = (0, import_node_path15.join)(dir, name);
6172
6353
  (0, import_node_fs13.copyFileSync)(abs, destAbs);
6173
6354
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6174
6355
  const buf = (0, import_node_fs13.readFileSync)(destAbs);
@@ -6193,7 +6374,7 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
6193
6374
  try {
6194
6375
  const buf = Buffer.from(item.dataBase64, "base64");
6195
6376
  const name = uniqueAttachmentName(dir, originalName);
6196
- const destAbs = (0, import_node_path14.join)(dir, name);
6377
+ const destAbs = (0, import_node_path15.join)(dir, name);
6197
6378
  (0, import_node_fs13.writeFileSync)(destAbs, buf);
6198
6379
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6199
6380
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
@@ -6271,15 +6452,15 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6271
6452
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
6272
6453
  out.push({
6273
6454
  id: (0, import_node_crypto6.randomUUID)(),
6274
- name: (0, import_node_path14.basename)(rel) || "file",
6455
+ name: (0, import_node_path15.basename)(rel) || "file",
6275
6456
  kind: "file",
6276
6457
  content: `(invalid path: ${rel})`
6277
6458
  });
6278
6459
  continue;
6279
6460
  }
6280
- const name = (0, import_node_path14.basename)(rel);
6461
+ const name = (0, import_node_path15.basename)(rel);
6281
6462
  try {
6282
- const abs = (0, import_node_path14.join)(worktreePath, rel);
6463
+ const abs = (0, import_node_path15.join)(worktreePath, rel);
6283
6464
  const st = (0, import_node_fs13.statSync)(abs);
6284
6465
  if (!st.isFile()) continue;
6285
6466
  const buf = (0, import_node_fs13.readFileSync)(abs);
@@ -6295,12 +6476,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6295
6476
  }
6296
6477
  return out;
6297
6478
  }
6298
- var import_node_fs13, import_node_path14, import_node_crypto6, IMAGE_EXTENSIONS, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES, IMAGE_HINT_RE, PLACEHOLDER_CONTENT_RE;
6479
+ var import_node_fs13, import_node_path15, import_node_crypto6, IMAGE_EXTENSIONS, IMAGE_MIME_BY_EXT, MAX_INLINE_BYTES, MAX_PREVIEW_BYTES, IMAGE_HINT_RE, PLACEHOLDER_CONTENT_RE;
6299
6480
  var init_stage_files = __esm({
6300
6481
  "src/composer/stage-files.ts"() {
6301
6482
  "use strict";
6302
6483
  import_node_fs13 = require("fs");
6303
- import_node_path14 = require("path");
6484
+ import_node_path15 = require("path");
6304
6485
  import_node_crypto6 = require("crypto");
6305
6486
  init_workspace_scratch();
6306
6487
  IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -6444,15 +6625,15 @@ var init_gh_errors = __esm({
6444
6625
  function prependPathDir(env, dir) {
6445
6626
  if (!dir || !(0, import_node_fs14.existsSync)(dir)) return;
6446
6627
  const current = env.PATH ?? "";
6447
- const parts = current.split(import_node_path15.delimiter).filter(Boolean);
6628
+ const parts = current.split(import_node_path16.delimiter).filter(Boolean);
6448
6629
  if (parts.includes(dir)) {
6449
6630
  env.PATH = current;
6450
6631
  return;
6451
6632
  }
6452
- env.PATH = [dir, ...parts].join(import_node_path15.delimiter);
6633
+ env.PATH = [dir, ...parts].join(import_node_path16.delimiter);
6453
6634
  }
6454
6635
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
6455
- return (0, import_node_path15.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6636
+ return (0, import_node_path16.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6456
6637
  }
6457
6638
  function isConductorBundledCli(filePath) {
6458
6639
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -6461,10 +6642,10 @@ function isConductorBundledCli(filePath) {
6461
6642
  function ensureAgentPath(env = process.env) {
6462
6643
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
6463
6644
  const current = env.PATH ?? "";
6464
- const parts = current.split(import_node_path15.delimiter).filter(Boolean);
6645
+ const parts = current.split(import_node_path16.delimiter).filter(Boolean);
6465
6646
  const seen = new Set(parts);
6466
6647
  const extras = [
6467
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path15.join)(home, rel)),
6648
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path16.join)(home, rel)),
6468
6649
  "/opt/homebrew/bin",
6469
6650
  "/usr/local/bin",
6470
6651
  // Keep after Homebrew/npm so a user-installed CLI still wins.
@@ -6475,7 +6656,7 @@ function ensureAgentPath(env = process.env) {
6475
6656
  parts.unshift(dir);
6476
6657
  seen.add(dir);
6477
6658
  }
6478
- const next = parts.join(import_node_path15.delimiter);
6659
+ const next = parts.join(import_node_path16.delimiter);
6479
6660
  env.PATH = next;
6480
6661
  return next;
6481
6662
  }
@@ -6489,7 +6670,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
6489
6670
  stdio: ["ignore", "pipe", "ignore"]
6490
6671
  }).trim().split(/\r?\n/).find(Boolean);
6491
6672
  if (prefix) {
6492
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path15.join)(prefix, "bin");
6673
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path16.join)(prefix, "bin");
6493
6674
  prependPathDir(env, binDir);
6494
6675
  }
6495
6676
  } catch {
@@ -6517,14 +6698,14 @@ function withExportedPath(command, pathValue) {
6517
6698
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
6518
6699
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
6519
6700
  }
6520
- var import_node_fs14, import_node_child_process3, import_node_os4, import_node_path15, EXTRA_BIN_DIRS;
6701
+ var import_node_fs14, import_node_child_process3, import_node_os4, import_node_path16, EXTRA_BIN_DIRS;
6521
6702
  var init_path = __esm({
6522
6703
  "src/agents/path.ts"() {
6523
6704
  "use strict";
6524
6705
  import_node_fs14 = require("fs");
6525
6706
  import_node_child_process3 = require("child_process");
6526
6707
  import_node_os4 = require("os");
6527
- import_node_path15 = require("path");
6708
+ import_node_path16 = require("path");
6528
6709
  EXTRA_BIN_DIRS = [
6529
6710
  ".local/bin",
6530
6711
  ".cargo/bin",
@@ -6545,18 +6726,18 @@ var init_path = __esm({
6545
6726
  function githubAgentAuthDir() {
6546
6727
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
6547
6728
  if (override) return override;
6548
- return (0, import_node_path16.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6729
+ return (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6549
6730
  }
6550
6731
  function githubCredentialStorePath() {
6551
- return (0, import_node_path16.join)(githubAgentAuthDir(), "git-credentials");
6732
+ return (0, import_node_path17.join)(githubAgentAuthDir(), "git-credentials");
6552
6733
  }
6553
6734
  function githubGhConfigDir() {
6554
- return (0, import_node_path16.join)(githubAgentAuthDir(), "gh");
6735
+ return (0, import_node_path17.join)(githubAgentAuthDir(), "gh");
6555
6736
  }
6556
6737
  function writePrivateFile2(file, body) {
6557
- (0, import_node_fs15.mkdirSync)((0, import_node_path16.dirname)(file), { recursive: true, mode: 448 });
6738
+ (0, import_node_fs15.mkdirSync)((0, import_node_path17.dirname)(file), { recursive: true, mode: 448 });
6558
6739
  try {
6559
- (0, import_node_fs15.chmodSync)((0, import_node_path16.dirname)(file), 448);
6740
+ (0, import_node_fs15.chmodSync)((0, import_node_path17.dirname)(file), 448);
6560
6741
  } catch {
6561
6742
  }
6562
6743
  (0, import_node_fs15.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
@@ -6594,11 +6775,11 @@ function materializeGithubAgentAuth(token, user) {
6594
6775
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
6595
6776
  const ghDir = githubGhConfigDir();
6596
6777
  (0, import_node_fs15.mkdirSync)(ghDir, { recursive: true, mode: 448 });
6597
- writePrivateFile2((0, import_node_path16.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6598
- writePrivateFile2((0, import_node_path16.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6778
+ writePrivateFile2((0, import_node_path17.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6779
+ writePrivateFile2((0, import_node_path17.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6599
6780
  }
6600
6781
  function githubAgentAuthReady() {
6601
- return (0, import_node_fs15.existsSync)(githubCredentialStorePath()) && (0, import_node_fs15.existsSync)((0, import_node_path16.join)(githubGhConfigDir(), "hosts.yml"));
6782
+ return (0, import_node_fs15.existsSync)(githubCredentialStorePath()) && (0, import_node_fs15.existsSync)((0, import_node_path17.join)(githubGhConfigDir(), "hosts.yml"));
6602
6783
  }
6603
6784
  function githubCredentialHelperGitConfig() {
6604
6785
  const file = githubCredentialStorePath();
@@ -6613,13 +6794,13 @@ function githubGhConfigEnv() {
6613
6794
  GH_PROMPT_DISABLED: "1"
6614
6795
  };
6615
6796
  }
6616
- var import_node_fs15, import_node_os5, import_node_path16;
6797
+ var import_node_fs15, import_node_os5, import_node_path17;
6617
6798
  var init_github_agent_auth = __esm({
6618
6799
  "src/git/github-agent-auth.ts"() {
6619
6800
  "use strict";
6620
6801
  import_node_fs15 = require("fs");
6621
6802
  import_node_os5 = require("os");
6622
- import_node_path16 = require("path");
6803
+ import_node_path17 = require("path");
6623
6804
  }
6624
6805
  });
6625
6806
 
@@ -6628,7 +6809,7 @@ function isIndexLockError(text7) {
6628
6809
  return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text7);
6629
6810
  }
6630
6811
  function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
6631
- const lockPath = (0, import_node_path17.join)(gitDir, "index.lock");
6812
+ const lockPath = (0, import_node_path18.join)(gitDir, "index.lock");
6632
6813
  try {
6633
6814
  if (!(0, import_node_fs16.existsSync)(lockPath)) return null;
6634
6815
  if (now - (0, import_node_fs16.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
@@ -6647,12 +6828,12 @@ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
6647
6828
  }
6648
6829
  return removed;
6649
6830
  }
6650
- var import_node_fs16, import_node_path17, STALE_INDEX_LOCK_MS;
6831
+ var import_node_fs16, import_node_path18, STALE_INDEX_LOCK_MS;
6651
6832
  var init_stale_lock = __esm({
6652
6833
  "src/git/stale-lock.ts"() {
6653
6834
  "use strict";
6654
6835
  import_node_fs16 = require("fs");
6655
- import_node_path17 = require("path");
6836
+ import_node_path18 = require("path");
6656
6837
  STALE_INDEX_LOCK_MS = 2e4;
6657
6838
  }
6658
6839
  });
@@ -6792,8 +6973,8 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
6792
6973
  if (gitDir.exitCode !== 0) return;
6793
6974
  const dir = gitDir.stdout.trim();
6794
6975
  if (!dir) return;
6795
- const excludePath = (0, import_node_path18.join)(dir, "info", "exclude");
6796
- (0, import_node_fs17.mkdirSync)((0, import_node_path18.dirname)(excludePath), { recursive: true });
6976
+ const excludePath = (0, import_node_path19.join)(dir, "info", "exclude");
6977
+ (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(excludePath), { recursive: true });
6797
6978
  let body = "";
6798
6979
  try {
6799
6980
  body = (0, import_node_fs17.readFileSync)(excludePath, "utf8");
@@ -6827,12 +7008,12 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
6827
7008
  timeoutMs: 8e3
6828
7009
  });
6829
7010
  }
6830
- var import_node_fs17, import_node_path18, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
7011
+ var import_node_fs17, import_node_path19, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
6831
7012
  var init_worktree_exclude = __esm({
6832
7013
  "src/git/worktree-exclude.ts"() {
6833
7014
  "use strict";
6834
7015
  import_node_fs17 = require("fs");
6835
- import_node_path18 = require("path");
7016
+ import_node_path19 = require("path");
6836
7017
  init_run();
6837
7018
  WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
6838
7019
  WORKTREE_CONTEXT_EXCLUDE = ".context/";
@@ -6953,7 +7134,7 @@ async function warmGithubAgentAuth(opts) {
6953
7134
  }
6954
7135
  function normalizeWritableRoot(raw) {
6955
7136
  const trimmed = raw.trim().replace(/\/+$/, "");
6956
- return trimmed && (0, import_node_path19.isAbsolute)(trimmed) ? trimmed : null;
7137
+ return trimmed && (0, import_node_path20.isAbsolute)(trimmed) ? trimmed : null;
6957
7138
  }
6958
7139
  async function resolveCodexGitWritableRoots(cwd) {
6959
7140
  const roots = /* @__PURE__ */ new Set();
@@ -7031,11 +7212,11 @@ function formatGitAuthModeDirective(mode) {
7031
7212
  ].join("\n");
7032
7213
  }
7033
7214
  }
7034
- var import_node_path19, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7215
+ var import_node_path20, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7035
7216
  var init_git_auth_mode = __esm({
7036
7217
  "src/git/git-auth-mode.ts"() {
7037
7218
  "use strict";
7038
- import_node_path19 = require("path");
7219
+ import_node_path20 = require("path");
7039
7220
  init_app_settings();
7040
7221
  init_github_agent_auth();
7041
7222
  init_run();
@@ -8724,7 +8905,7 @@ async function refreshOriginAndMaybeFastForwardMain(repoPath, sourceRef) {
8724
8905
  }
8725
8906
  async function createThreadWorktree(opts) {
8726
8907
  let branchName = `thread/${opts.slug}`;
8727
- const worktreePath = (0, import_node_path20.join)(worktreesRoot(opts.repoPath), opts.slug);
8908
+ const worktreePath = (0, import_node_path21.join)(worktreesRoot(opts.repoPath), opts.slug);
8728
8909
  if ((0, import_node_fs18.existsSync)(worktreePath)) {
8729
8910
  throw new Error(`Worktree already exists at ${worktreePath}`);
8730
8911
  }
@@ -8766,7 +8947,7 @@ ${add.stdout}`;
8766
8947
  async function createExistingBranchWorktree(opts) {
8767
8948
  const branchName = opts.branchName.trim();
8768
8949
  if (!branchName) throw new Error("branch name required");
8769
- const worktreePath = (0, import_node_path20.join)(worktreesRoot(opts.repoPath), opts.slug);
8950
+ const worktreePath = (0, import_node_path21.join)(worktreesRoot(opts.repoPath), opts.slug);
8770
8951
  if ((0, import_node_fs18.existsSync)(worktreePath)) {
8771
8952
  throw new Error(`Worktree already exists at ${worktreePath}`);
8772
8953
  }
@@ -9048,7 +9229,7 @@ async function createOrUpdatePr(worktreePath, opts) {
9048
9229
  const headRef = ghHeadRef(slug, opts.head);
9049
9230
  const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
9050
9231
  const bodyText = clampGithubPrBody(opts.body ?? opts.title);
9051
- const bodyFile = (0, import_node_path20.join)(
9232
+ const bodyFile = (0, import_node_path21.join)(
9052
9233
  (0, import_node_os6.tmpdir)(),
9053
9234
  `sideboard-pr-body-${process.pid}-${(0, import_node_crypto7.randomBytes)(6).toString("hex")}.md`
9054
9235
  );
@@ -9148,7 +9329,7 @@ function sameRepoPath2(a, b) {
9148
9329
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
9149
9330
  }
9150
9331
  function listLocalThreadBranchSlugs(repoPath) {
9151
- const refsDir = (0, import_node_path20.join)(repoPath, ".git", "refs", "heads", "thread");
9332
+ const refsDir = (0, import_node_path21.join)(repoPath, ".git", "refs", "heads", "thread");
9152
9333
  if (!(0, import_node_fs18.existsSync)(refsDir)) return [];
9153
9334
  try {
9154
9335
  return (0, import_node_fs18.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
@@ -9185,20 +9366,20 @@ function allocateTeamSlug(repoPath) {
9185
9366
  const taken = collectTakenTeamSlugs(repoPath);
9186
9367
  for (let attempt = 0; attempt < 32; attempt++) {
9187
9368
  const team = allocateTeamName(taken);
9188
- const path2 = (0, import_node_path20.join)(worktreesRoot(repoPath), team.slug);
9369
+ const path2 = (0, import_node_path21.join)(worktreesRoot(repoPath), team.slug);
9189
9370
  if (!(0, import_node_fs18.existsSync)(path2)) return team;
9190
9371
  taken.add(team.slug);
9191
9372
  }
9192
9373
  throw new Error("No available soccer team worktree directories left");
9193
9374
  }
9194
- var import_node_crypto7, import_node_fs18, import_node_os6, import_node_path20, PR_DETAILS_JSON_FIELDS;
9375
+ var import_node_crypto7, import_node_fs18, import_node_os6, import_node_path21, PR_DETAILS_JSON_FIELDS;
9195
9376
  var init_worktree = __esm({
9196
9377
  "src/git/worktree.ts"() {
9197
9378
  "use strict";
9198
9379
  import_node_crypto7 = require("crypto");
9199
9380
  import_node_fs18 = require("fs");
9200
9381
  import_node_os6 = require("os");
9201
- import_node_path20 = require("path");
9382
+ import_node_path21 = require("path");
9202
9383
  init_paths();
9203
9384
  init_thread_store();
9204
9385
  init_teams();
@@ -9250,10 +9431,10 @@ __export(workspaces_exports, {
9250
9431
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
9251
9432
  });
9252
9433
  function workspacesFile() {
9253
- return (0, import_node_path21.join)(appDataDir(), "workspaces.json");
9434
+ return (0, import_node_path22.join)(appDataDir(), "workspaces.json");
9254
9435
  }
9255
9436
  function removedWorkspacesFile() {
9256
- return (0, import_node_path21.join)(appDataDir(), "removed-workspaces.json");
9437
+ return (0, import_node_path22.join)(appDataDir(), "removed-workspaces.json");
9257
9438
  }
9258
9439
  function readAll2() {
9259
9440
  const path2 = workspacesFile();
@@ -9312,7 +9493,7 @@ async function addWorkspace(repoPath) {
9312
9493
  if (existing) return existing;
9313
9494
  const next = {
9314
9495
  path: root,
9315
- name: (0, import_node_path21.basename)(root),
9496
+ name: (0, import_node_path22.basename)(root),
9316
9497
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9317
9498
  };
9318
9499
  writeAll2([...current, next]);
@@ -9337,7 +9518,7 @@ function syncWorkspacesFromThreads(repoPaths) {
9337
9518
  if (!(0, import_node_fs19.existsSync)(path2)) continue;
9338
9519
  const ws = {
9339
9520
  path: path2,
9340
- name: (0, import_node_path21.basename)(path2),
9521
+ name: (0, import_node_path22.basename)(path2),
9341
9522
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9342
9523
  };
9343
9524
  byPath.set(path2, ws);
@@ -9347,12 +9528,12 @@ function syncWorkspacesFromThreads(repoPaths) {
9347
9528
  if (dirty) writeAll2(next);
9348
9529
  return next.sort((a, b) => a.name.localeCompare(b.name));
9349
9530
  }
9350
- var import_node_fs19, import_node_path21;
9531
+ var import_node_fs19, import_node_path22;
9351
9532
  var init_workspaces = __esm({
9352
9533
  "src/store/workspaces.ts"() {
9353
9534
  "use strict";
9354
9535
  import_node_fs19 = require("fs");
9355
- import_node_path21 = require("path");
9536
+ import_node_path22 = require("path");
9356
9537
  init_paths();
9357
9538
  init_global_workspace();
9358
9539
  init_worktree();
@@ -9471,7 +9652,7 @@ function ensureGlobalCoordinatorCwd(opts) {
9471
9652
  let orchId = opts?.orchestratorThreadId?.trim() || "";
9472
9653
  if (!orchId) {
9473
9654
  try {
9474
- const existing = (0, import_node_fs20.readFileSync)((0, import_node_path22.join)(dir, "AGENTS.md"), "utf8");
9655
+ const existing = (0, import_node_fs20.readFileSync)((0, import_node_path23.join)(dir, "AGENTS.md"), "utf8");
9475
9656
  const m = existing.match(
9476
9657
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
9477
9658
  );
@@ -9516,9 +9697,9 @@ function ensureGlobalCoordinatorCwd(opts) {
9516
9697
  "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). If the user gave a goal (Greptile 5/5, CI green), pass that goal through so they watch-fix-push until it lands \u2014 do not start that loop on a plain push, and do not tell the human to poll. Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
9517
9698
  ].join("\n");
9518
9699
  try {
9519
- (0, import_node_fs20.writeFileSync)((0, import_node_path22.join)(dir, "CLAUDE.md"), `${body}
9700
+ (0, import_node_fs20.writeFileSync)((0, import_node_path23.join)(dir, "CLAUDE.md"), `${body}
9520
9701
  `, "utf8");
9521
- (0, import_node_fs20.writeFileSync)((0, import_node_path22.join)(dir, "AGENTS.md"), `${body}
9702
+ (0, import_node_fs20.writeFileSync)((0, import_node_path23.join)(dir, "AGENTS.md"), `${body}
9522
9703
  `, "utf8");
9523
9704
  } catch {
9524
9705
  }
@@ -9550,12 +9731,12 @@ function coordinatorSystemPrompt(opts) {
9550
9731
  formatWorkspaceInventory(opts.workspaces)
9551
9732
  ].join("\n");
9552
9733
  }
9553
- var import_node_fs20, import_node_path22, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9734
+ var import_node_fs20, import_node_path23, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9554
9735
  var init_coordinator_prompt = __esm({
9555
9736
  "src/orchestrator/coordinator-prompt.ts"() {
9556
9737
  "use strict";
9557
9738
  import_node_fs20 = require("fs");
9558
- import_node_path22 = require("path");
9739
+ import_node_path23 = require("path");
9559
9740
  init_worktree();
9560
9741
  init_app_settings();
9561
9742
  init_paths();
@@ -9914,7 +10095,7 @@ var init_api = __esm({
9914
10095
 
9915
10096
  // src/slack/reply-target.ts
9916
10097
  function storePath() {
9917
- return (0, import_node_path23.join)(appDataDir(), "slack-reply-to.json");
10098
+ return (0, import_node_path24.join)(appDataDir(), "slack-reply-to.json");
9918
10099
  }
9919
10100
  function readStore() {
9920
10101
  const path2 = storePath();
@@ -9935,12 +10116,12 @@ function setSlackReplyTarget(target) {
9935
10116
  function getSlackReplyTarget(threadId) {
9936
10117
  return readStore()[threadId] ?? null;
9937
10118
  }
9938
- var import_node_fs21, import_node_path23;
10119
+ var import_node_fs21, import_node_path24;
9939
10120
  var init_reply_target = __esm({
9940
10121
  "src/slack/reply-target.ts"() {
9941
10122
  "use strict";
9942
10123
  import_node_fs21 = require("fs");
9943
- import_node_path23 = require("path");
10124
+ import_node_path24 = require("path");
9944
10125
  init_paths();
9945
10126
  init_private_file();
9946
10127
  init_secure_file();
@@ -9949,7 +10130,7 @@ var init_reply_target = __esm({
9949
10130
 
9950
10131
  // src/slack/workspaces.ts
9951
10132
  function storePath2() {
9952
- return (0, import_node_path24.join)(appDataDir(), "slack-workspaces.json");
10133
+ return (0, import_node_path25.join)(appDataDir(), "slack-workspaces.json");
9953
10134
  }
9954
10135
  function readStore2() {
9955
10136
  try {
@@ -10056,11 +10237,11 @@ function requireSlackWorkspace(teamId) {
10056
10237
  }
10057
10238
  return ws;
10058
10239
  }
10059
- var import_node_path24;
10240
+ var import_node_path25;
10060
10241
  var init_workspaces2 = __esm({
10061
10242
  "src/slack/workspaces.ts"() {
10062
10243
  "use strict";
10063
- import_node_path24 = require("path");
10244
+ import_node_path25 = require("path");
10064
10245
  init_paths();
10065
10246
  init_secure_file();
10066
10247
  init_api();
@@ -10069,7 +10250,7 @@ var init_workspaces2 = __esm({
10069
10250
 
10070
10251
  // src/slack/outbound-watch.ts
10071
10252
  function storePath3() {
10072
- return (0, import_node_path25.join)(appDataDir(), "slack-outbound-watch.json");
10253
+ return (0, import_node_path26.join)(appDataDir(), "slack-outbound-watch.json");
10073
10254
  }
10074
10255
  function watchId(teamId, channelId, ts) {
10075
10256
  return `${teamId}:${channelId}:${ts}`;
@@ -10406,12 +10587,12 @@ async function pollSlackOutboundWatches(opts) {
10406
10587
  }
10407
10588
  if (changed) writeStore2(watches);
10408
10589
  }
10409
- var import_node_fs22, import_node_path25, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10590
+ var import_node_fs22, import_node_path26, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10410
10591
  var init_outbound_watch = __esm({
10411
10592
  "src/slack/outbound-watch.ts"() {
10412
10593
  "use strict";
10413
10594
  import_node_fs22 = require("fs");
10414
- import_node_path25 = require("path");
10595
+ import_node_path26 = require("path");
10415
10596
  init_paths();
10416
10597
  init_private_file();
10417
10598
  init_secure_file();
@@ -10432,7 +10613,7 @@ var init_outbound_watch = __esm({
10432
10613
  function brightsyConfigPath() {
10433
10614
  const override = process.env.BRIGHTSY_CONFIG?.trim();
10434
10615
  if (override) return override;
10435
- return (0, import_node_path26.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10616
+ return (0, import_node_path27.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10436
10617
  }
10437
10618
  function loadBrightsyConfig() {
10438
10619
  const path2 = brightsyConfigPath();
@@ -10451,13 +10632,13 @@ function saveBrightsyConfig(cfg) {
10451
10632
  mode: 384
10452
10633
  });
10453
10634
  }
10454
- var import_node_fs23, import_node_os7, import_node_path26;
10635
+ var import_node_fs23, import_node_os7, import_node_path27;
10455
10636
  var init_config = __esm({
10456
10637
  "src/brightsy/config.ts"() {
10457
10638
  "use strict";
10458
10639
  import_node_fs23 = require("fs");
10459
10640
  import_node_os7 = require("os");
10460
- import_node_path26 = require("path");
10641
+ import_node_path27 = require("path");
10461
10642
  }
10462
10643
  });
10463
10644
 
@@ -10684,7 +10865,7 @@ __export(connected_teams_exports, {
10684
10865
  listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
10685
10866
  });
10686
10867
  function storePath4() {
10687
- return (0, import_node_path27.join)(appDataDir(), "brightsy-teams.json");
10868
+ return (0, import_node_path28.join)(appDataDir(), "brightsy-teams.json");
10688
10869
  }
10689
10870
  function readStore4() {
10690
10871
  const path2 = storePath4();
@@ -10855,12 +11036,12 @@ function brightsyMcpServerName(slug) {
10855
11036
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
10856
11037
  return `brightsy_${cleaned || "team"}`;
10857
11038
  }
10858
- var import_node_fs24, import_node_path27;
11039
+ var import_node_fs24, import_node_path28;
10859
11040
  var init_connected_teams = __esm({
10860
11041
  "src/brightsy/connected-teams.ts"() {
10861
11042
  "use strict";
10862
11043
  import_node_fs24 = require("fs");
10863
- import_node_path27 = require("path");
11044
+ import_node_path28 = require("path");
10864
11045
  init_paths();
10865
11046
  init_accounts();
10866
11047
  init_config();
@@ -11452,7 +11633,7 @@ function collectSystemCaPem(io = {}) {
11452
11633
  return "";
11453
11634
  }
11454
11635
  function systemCaBundlePath(io = {}) {
11455
- return (0, import_node_path28.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11636
+ return (0, import_node_path29.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11456
11637
  }
11457
11638
  function bundleIsFresh(path2, now) {
11458
11639
  try {
@@ -11482,7 +11663,7 @@ function materializeSystemCaBundle(io = {}) {
11482
11663
  return (0, import_node_fs26.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
11483
11664
  }
11484
11665
  try {
11485
- (0, import_node_fs26.mkdirSync)((0, import_node_path28.dirname)(dest), { recursive: true });
11666
+ (0, import_node_fs26.mkdirSync)((0, import_node_path29.dirname)(dest), { recursive: true });
11486
11667
  (0, import_node_fs26.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
11487
11668
  `, { mode: 384 });
11488
11669
  return dest;
@@ -11523,13 +11704,13 @@ function trustSystemCertificates(io = {}) {
11523
11704
  return false;
11524
11705
  }
11525
11706
  }
11526
- var import_node_child_process4, import_node_fs26, import_node_path28, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
11707
+ var import_node_child_process4, import_node_fs26, import_node_path29, import_node_tls, NODE_USE_SYSTEM_CA, NODE_EXTRA_CA_CERTS, BUNDLE_NAME, BUNDLE_MAX_AGE_MS, LINUX_CA_FILES, PEM_CERT_RE;
11527
11708
  var init_system_ca = __esm({
11528
11709
  "src/http/system-ca.ts"() {
11529
11710
  "use strict";
11530
11711
  import_node_child_process4 = require("child_process");
11531
11712
  import_node_fs26 = require("fs");
11532
- import_node_path28 = require("path");
11713
+ import_node_path29 = require("path");
11533
11714
  import_node_tls = __toESM(require("tls"), 1);
11534
11715
  init_paths();
11535
11716
  NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
@@ -11555,43 +11736,43 @@ function electronResourcesPath() {
11555
11736
  function packagedCursorRuntimeDir() {
11556
11737
  const resources = electronResourcesPath();
11557
11738
  if (!resources) return null;
11558
- const dir = (0, import_node_path29.join)(resources, "cursor-runtime");
11559
- if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11739
+ const dir = (0, import_node_path30.join)(resources, "cursor-runtime");
11740
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path30.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11560
11741
  return dir;
11561
11742
  }
11562
11743
  function packagedCursorRunnerPath() {
11563
11744
  const dir = packagedCursorRuntimeDir();
11564
- return dir ? (0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11745
+ return dir ? (0, import_node_path30.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11565
11746
  }
11566
11747
  function packagedMcpDir() {
11567
11748
  const resources = electronResourcesPath();
11568
11749
  if (!resources) return null;
11569
- const dir = (0, import_node_path29.join)(resources, "sideboard-mcp");
11570
- if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
11750
+ const dir = (0, import_node_path30.join)(resources, "sideboard-mcp");
11751
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path30.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
11571
11752
  return dir;
11572
11753
  }
11573
11754
  function packagedMcpStdioPath() {
11574
11755
  const dir = packagedMcpDir();
11575
- return dir ? (0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
11756
+ return dir ? (0, import_node_path30.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
11576
11757
  }
11577
11758
  function packagedBundledNodePath() {
11578
11759
  const resources = electronResourcesPath();
11579
11760
  if (!resources) return null;
11580
- const bin = (0, import_node_path29.join)(resources, "node", "bin", "node");
11761
+ const bin = (0, import_node_path30.join)(resources, "node", "bin", "node");
11581
11762
  if (!(0, import_node_fs27.existsSync)(bin)) return null;
11582
11763
  return bin;
11583
11764
  }
11584
11765
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
11585
11766
  const dir = packagedCursorRuntimeDir();
11586
11767
  if (!dir) return null;
11587
- return (0, import_node_path29.join)(dir, "node_modules", platformPkg, "bin", binName);
11768
+ return (0, import_node_path30.join)(dir, "node_modules", platformPkg, "bin", binName);
11588
11769
  }
11589
- var import_node_fs27, import_node_path29;
11770
+ var import_node_fs27, import_node_path30;
11590
11771
  var init_packaged_runtime = __esm({
11591
11772
  "src/agents/packaged-runtime.ts"() {
11592
11773
  "use strict";
11593
11774
  import_node_fs27 = require("fs");
11594
- import_node_path29 = require("path");
11775
+ import_node_path30 = require("path");
11595
11776
  }
11596
11777
  });
11597
11778
 
@@ -11675,28 +11856,28 @@ function versionDirNodeBins(root, toBin) {
11675
11856
  }
11676
11857
  function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
11677
11858
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
11678
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path30.join)(prefix, "opt", `node@${major}`, "bin", "node"))
11859
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path31.join)(prefix, "opt", `node@${major}`, "bin", "node"))
11679
11860
  );
11680
11861
  return [
11681
11862
  ...kegs,
11682
11863
  "/opt/homebrew/bin/node",
11683
11864
  "/usr/local/bin/node",
11684
- (0, import_node_path30.join)(home, ".local/share/fnm/aliases/default/bin/node"),
11685
- (0, import_node_path30.join)(home, ".nvm/current/bin/node"),
11686
- (0, import_node_path30.join)(home, ".volta/bin/node"),
11687
- (0, import_node_path30.join)(home, ".asdf/shims/node"),
11688
- (0, import_node_path30.join)(home, ".local/share/mise/shims/node"),
11865
+ (0, import_node_path31.join)(home, ".local/share/fnm/aliases/default/bin/node"),
11866
+ (0, import_node_path31.join)(home, ".nvm/current/bin/node"),
11867
+ (0, import_node_path31.join)(home, ".volta/bin/node"),
11868
+ (0, import_node_path31.join)(home, ".asdf/shims/node"),
11869
+ (0, import_node_path31.join)(home, ".local/share/mise/shims/node"),
11689
11870
  ...versionDirNodeBins(
11690
- (0, import_node_path30.join)(home, ".nvm", "versions", "node"),
11691
- (name) => (0, import_node_path30.join)(home, ".nvm", "versions", "node", name, "bin", "node")
11871
+ (0, import_node_path31.join)(home, ".nvm", "versions", "node"),
11872
+ (name) => (0, import_node_path31.join)(home, ".nvm", "versions", "node", name, "bin", "node")
11692
11873
  ),
11693
11874
  ...versionDirNodeBins(
11694
- (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions"),
11695
- (name) => (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
11875
+ (0, import_node_path31.join)(home, ".local/share/fnm", "node-versions"),
11876
+ (name) => (0, import_node_path31.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
11696
11877
  ),
11697
11878
  ...versionDirNodeBins(
11698
- (0, import_node_path30.join)(home, ".volta", "tools", "image", "node"),
11699
- (name) => (0, import_node_path30.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
11879
+ (0, import_node_path31.join)(home, ".volta", "tools", "image", "node"),
11880
+ (name) => (0, import_node_path31.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
11700
11881
  )
11701
11882
  ];
11702
11883
  }
@@ -11788,13 +11969,13 @@ async function resolveNodeLaunch(scriptPath) {
11788
11969
  env: { ELECTRON_RUN_AS_NODE: "1" }
11789
11970
  };
11790
11971
  }
11791
- var import_node_fs28, import_node_os8, import_node_path30, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
11972
+ var import_node_fs28, import_node_os8, import_node_path31, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
11792
11973
  var init_node_launch = __esm({
11793
11974
  "src/agents/node-launch.ts"() {
11794
11975
  "use strict";
11795
11976
  import_node_fs28 = require("fs");
11796
11977
  import_node_os8 = require("os");
11797
- import_node_path30 = require("path");
11978
+ import_node_path31 = require("path");
11798
11979
  init_nested_electron_env();
11799
11980
  init_system_ca();
11800
11981
  init_run();
@@ -11896,13 +12077,13 @@ function corePackageDir() {
11896
12077
  try {
11897
12078
  const url = import_meta.url;
11898
12079
  if (typeof url === "string" && url.length > 0) {
11899
- return (0, import_node_path31.dirname)((0, import_node_url.fileURLToPath)(url));
12080
+ return (0, import_node_path32.dirname)((0, import_node_url.fileURLToPath)(url));
11900
12081
  }
11901
12082
  } catch {
11902
12083
  }
11903
12084
  try {
11904
- const req = (0, import_node_module.createRequire)((0, import_node_path31.join)(process.cwd(), "package.json"));
11905
- return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
12085
+ const req = (0, import_node_module.createRequire)((0, import_node_path32.join)(process.cwd(), "package.json"));
12086
+ return (0, import_node_path32.dirname)(req.resolve("@sideboard-ai/core"));
11906
12087
  } catch {
11907
12088
  return process.cwd();
11908
12089
  }
@@ -11915,18 +12096,18 @@ function findSideboardMcpJsEntry() {
11915
12096
  let dir = corePackageDir();
11916
12097
  for (let i = 0; i < 10; i++) {
11917
12098
  const candidates = [
11918
- (0, import_node_path31.join)(dir, "mcp/run-stdio.js"),
11919
- (0, import_node_path31.join)(dir, "mcp/run-stdio.cjs"),
11920
- (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.js"),
11921
- (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.cjs"),
11922
- (0, import_node_path31.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
11923
- (0, import_node_path31.join)(dir, "packages/cli/dist/index.js"),
11924
- (0, import_node_path31.join)(dir, "cli/dist/index.js")
12099
+ (0, import_node_path32.join)(dir, "mcp/run-stdio.js"),
12100
+ (0, import_node_path32.join)(dir, "mcp/run-stdio.cjs"),
12101
+ (0, import_node_path32.join)(dir, "dist/mcp/run-stdio.js"),
12102
+ (0, import_node_path32.join)(dir, "dist/mcp/run-stdio.cjs"),
12103
+ (0, import_node_path32.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
12104
+ (0, import_node_path32.join)(dir, "packages/cli/dist/index.js"),
12105
+ (0, import_node_path32.join)(dir, "cli/dist/index.js")
11925
12106
  ];
11926
12107
  for (const p of candidates) {
11927
12108
  if ((0, import_node_fs29.existsSync)(p) && !isAsarPath(p)) return p;
11928
12109
  }
11929
- const parent = (0, import_node_path31.dirname)(dir);
12110
+ const parent = (0, import_node_path32.dirname)(dir);
11930
12111
  if (parent === dir) break;
11931
12112
  dir = parent;
11932
12113
  }
@@ -12073,22 +12254,22 @@ function writeMcpServersConfig(servers) {
12073
12254
  ...env ? { env } : {}
12074
12255
  };
12075
12256
  }
12076
- const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path31.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12077
- const cfgPath = (0, import_node_path31.join)(dir, "mcp.json");
12257
+ const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path32.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12258
+ const cfgPath = (0, import_node_path32.join)(dir, "mcp.json");
12078
12259
  (0, import_node_fs29.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12079
12260
  return cfgPath;
12080
12261
  }
12081
12262
  async function writeInjectedMcpConfig(opts) {
12082
12263
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
12083
12264
  }
12084
- var import_node_fs29, import_node_module, import_node_os9, import_node_path31, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
12265
+ var import_node_fs29, import_node_module, import_node_os9, import_node_path32, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, BRIGHTSY_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
12085
12266
  var init_injected_mcp = __esm({
12086
12267
  "src/agents/injected-mcp.ts"() {
12087
12268
  "use strict";
12088
12269
  import_node_fs29 = require("fs");
12089
12270
  import_node_module = require("module");
12090
12271
  import_node_os9 = require("os");
12091
- import_node_path31 = require("path");
12272
+ import_node_path32 = require("path");
12092
12273
  import_node_url = require("url");
12093
12274
  init_run();
12094
12275
  init_config();
@@ -12329,13 +12510,31 @@ function mcpStatusThinkingFromClaudeInit(obj) {
12329
12510
  }
12330
12511
  }
12331
12512
  }
12332
- const notable = servers.filter((s) => !isCleanMcpConnect(s.status));
12513
+ const notable = servers.filter(isNotableMcpInitStatus);
12333
12514
  if (notable.length === 0) return null;
12334
12515
  return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
12335
12516
  }
12336
12517
  function isCleanMcpConnect(status) {
12337
12518
  return /^(connected|ok|ready|success)$/i.test(status.trim());
12338
12519
  }
12520
+ function isMcpAuthStatus(status) {
12521
+ return /needs[_-]?auth|needs authentication|unauthorized|not authenticated|authrequired/i.test(
12522
+ status
12523
+ );
12524
+ }
12525
+ function isSideboardMcpName(name) {
12526
+ return /^sideboard$/i.test(name.trim()) || /^mcp__sideboard$/i.test(name.trim());
12527
+ }
12528
+ function isVendorClaudeAiMcpName(name) {
12529
+ return /^claude\.ai\b/i.test(name.trim()) || /^mcp__claude_ai_/i.test(name.trim());
12530
+ }
12531
+ function isNotableMcpInitStatus(server) {
12532
+ if (isCleanMcpConnect(server.status)) return false;
12533
+ if (isSideboardMcpName(server.name)) return true;
12534
+ if (isVendorClaudeAiMcpName(server.name)) return false;
12535
+ if (isMcpAuthStatus(server.status)) return false;
12536
+ return true;
12537
+ }
12339
12538
  function eventsFromClaudeSystem(obj) {
12340
12539
  const subtype = claudeString(obj, "subtype") ?? "";
12341
12540
  const parentId = claudeParentToolUseId(obj);
@@ -12779,10 +12978,10 @@ var init_claude = __esm({
12779
12978
 
12780
12979
  // src/agents/user-mcp-config.ts
12781
12980
  function userCursorMcpConfigPath() {
12782
- return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12981
+ return (0, import_node_path33.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12783
12982
  }
12784
12983
  function userClaudeMcpConfigPath() {
12785
- return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".claude.json");
12984
+ return (0, import_node_path33.join)((0, import_node_os10.homedir)(), ".claude.json");
12786
12985
  }
12787
12986
  function asObject(value) {
12788
12987
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -12817,7 +13016,7 @@ function writeMergedMcpServersJson(configPath, sideboard) {
12817
13016
  }
12818
13017
  }
12819
13018
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
12820
- (0, import_node_fs31.mkdirSync)((0, import_node_path32.dirname)(configPath), { recursive: true });
13019
+ (0, import_node_fs31.mkdirSync)((0, import_node_path33.dirname)(configPath), { recursive: true });
12821
13020
  (0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
12822
13021
  `);
12823
13022
  }
@@ -12842,13 +13041,13 @@ async function registerPackagedUserMcpClients() {
12842
13041
  }
12843
13042
  return { cursor };
12844
13043
  }
12845
- var import_node_fs31, import_node_os10, import_node_path32;
13044
+ var import_node_fs31, import_node_os10, import_node_path33;
12846
13045
  var init_user_mcp_config = __esm({
12847
13046
  "src/agents/user-mcp-config.ts"() {
12848
13047
  "use strict";
12849
13048
  import_node_fs31 = require("fs");
12850
13049
  import_node_os10 = require("os");
12851
- import_node_path32 = require("path");
13050
+ import_node_path33 = require("path");
12852
13051
  init_paths();
12853
13052
  init_injected_mcp();
12854
13053
  }
@@ -12889,12 +13088,12 @@ function readText(path2) {
12889
13088
  }
12890
13089
  }
12891
13090
  function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
12892
- return [(0, import_node_path33.join)(home, ".codex", "config.toml"), (0, import_node_path33.join)(home, ".config", "codex", "config.toml")];
13091
+ return [(0, import_node_path34.join)(home, ".codex", "config.toml"), (0, import_node_path34.join)(home, ".config", "codex", "config.toml")];
12893
13092
  }
12894
13093
  function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
12895
13094
  return [
12896
- (0, import_node_path33.join)(home, ".config", "opencode", "opencode.json"),
12897
- (0, import_node_path33.join)(home, ".config", "opencode", "opencode.jsonc")
13095
+ (0, import_node_path34.join)(home, ".config", "opencode", "opencode.json"),
13096
+ (0, import_node_path34.join)(home, ".config", "opencode", "opencode.jsonc")
12898
13097
  ];
12899
13098
  }
12900
13099
  function userMcpNamesToDisable(opts) {
@@ -12949,13 +13148,13 @@ function toCodexUnattendedAppsArgs() {
12949
13148
  "features.plugins=false"
12950
13149
  ];
12951
13150
  }
12952
- var import_node_fs32, import_node_os11, import_node_path33, import_smol_toml2;
13151
+ var import_node_fs32, import_node_os11, import_node_path34, import_smol_toml2;
12953
13152
  var init_orch_mcp_isolation = __esm({
12954
13153
  "src/agents/orch-mcp-isolation.ts"() {
12955
13154
  "use strict";
12956
13155
  import_node_fs32 = require("fs");
12957
13156
  import_node_os11 = require("os");
12958
- import_node_path33 = require("path");
13157
+ import_node_path34 = require("path");
12959
13158
  import_smol_toml2 = require("smol-toml");
12960
13159
  init_user_mcp_config();
12961
13160
  }
@@ -13006,8 +13205,8 @@ function usageFromCodex(usage) {
13006
13205
  }
13007
13206
  function codexConfigHasNetworkAccess() {
13008
13207
  const candidates = [
13009
- (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13010
- (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13208
+ (0, import_node_path35.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13209
+ (0, import_node_path35.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13011
13210
  ];
13012
13211
  for (const path2 of candidates) {
13013
13212
  if (!(0, import_node_fs33.existsSync)(path2)) continue;
@@ -13043,7 +13242,7 @@ function asRecord2(value) {
13043
13242
  return void 0;
13044
13243
  }
13045
13244
  function codexLooksAuthenticated() {
13046
- const authPath = (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13245
+ const authPath = (0, import_node_path35.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13047
13246
  if (!(0, import_node_fs33.existsSync)(authPath)) return false;
13048
13247
  try {
13049
13248
  return (0, import_node_fs33.statSync)(authPath).size > 2;
@@ -13051,13 +13250,13 @@ function codexLooksAuthenticated() {
13051
13250
  return false;
13052
13251
  }
13053
13252
  }
13054
- var import_node_fs33, import_node_os12, import_node_path34, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13253
+ var import_node_fs33, import_node_os12, import_node_path35, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13055
13254
  var init_codex = __esm({
13056
13255
  "src/agents/codex.ts"() {
13057
13256
  "use strict";
13058
13257
  import_node_fs33 = require("fs");
13059
13258
  import_node_os12 = require("os");
13060
- import_node_path34 = require("path");
13259
+ import_node_path35 = require("path");
13061
13260
  init_run();
13062
13261
  init_app_settings();
13063
13262
  init_global_workspace();
@@ -13583,7 +13782,7 @@ function platformRipgrepPackage() {
13583
13782
  }
13584
13783
  function usableRipgrepPath(candidate) {
13585
13784
  const raw = candidate?.trim();
13586
- if (!raw || !(0, import_node_path35.isAbsolute)(raw)) return null;
13785
+ if (!raw || !(0, import_node_path36.isAbsolute)(raw)) return null;
13587
13786
  const readable = nodeReadableScriptPath(raw);
13588
13787
  if (!(0, import_node_fs34.existsSync)(readable) || isAsarPath(readable)) return null;
13589
13788
  return readable;
@@ -13592,12 +13791,12 @@ function walkForBundledRipgrep(startFile) {
13592
13791
  if (!startFile) return null;
13593
13792
  const pkg = platformRipgrepPackage();
13594
13793
  const name = rgBinaryName();
13595
- let dir = (0, import_node_path35.dirname)((0, import_node_path35.resolve)(startFile));
13596
- const root = (0, import_node_path35.parse)(dir).root;
13794
+ let dir = (0, import_node_path36.dirname)((0, import_node_path36.resolve)(startFile));
13795
+ const root = (0, import_node_path36.parse)(dir).root;
13597
13796
  while (dir !== root) {
13598
- const hit = usableRipgrepPath((0, import_node_path35.join)(dir, "node_modules", pkg, "bin", name));
13797
+ const hit = usableRipgrepPath((0, import_node_path36.join)(dir, "node_modules", pkg, "bin", name));
13599
13798
  if (hit) return hit;
13600
- const next = (0, import_node_path35.dirname)(dir);
13799
+ const next = (0, import_node_path36.dirname)(dir);
13601
13800
  if (next === dir) break;
13602
13801
  dir = next;
13603
13802
  }
@@ -13607,7 +13806,7 @@ function requireResolveBundledRipgrep(fromFile) {
13607
13806
  try {
13608
13807
  const req = (0, import_node_module2.createRequire)(fromFile);
13609
13808
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
13610
- return usableRipgrepPath((0, import_node_path35.join)((0, import_node_path35.dirname)(pkgJson), "bin", rgBinaryName()));
13809
+ return usableRipgrepPath((0, import_node_path36.join)((0, import_node_path36.dirname)(pkgJson), "bin", rgBinaryName()));
13611
13810
  } catch {
13612
13811
  return null;
13613
13812
  }
@@ -13629,13 +13828,13 @@ function cursorRipgrepEnv(opts) {
13629
13828
  const path2 = resolveCursorRipgrepPath(opts);
13630
13829
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
13631
13830
  }
13632
- var import_node_fs34, import_node_module2, import_node_path35, RIPGREP_ENV;
13831
+ var import_node_fs34, import_node_module2, import_node_path36, RIPGREP_ENV;
13633
13832
  var init_cursor_ripgrep = __esm({
13634
13833
  "src/agents/cursor-ripgrep.ts"() {
13635
13834
  "use strict";
13636
13835
  import_node_fs34 = require("fs");
13637
13836
  import_node_module2 = require("module");
13638
- import_node_path35 = require("path");
13837
+ import_node_path36 = require("path");
13639
13838
  init_node_launch();
13640
13839
  init_packaged_runtime();
13641
13840
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -13684,11 +13883,11 @@ function entryDir() {
13684
13883
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
13685
13884
  if (cjsDir) return cjsDir;
13686
13885
  try {
13687
- return (0, import_node_path36.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
13886
+ return (0, import_node_path37.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
13688
13887
  } catch {
13689
13888
  try {
13690
13889
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
13691
- return (0, import_node_path36.dirname)(req.resolve("@sideboard-ai/core"));
13890
+ return (0, import_node_path37.dirname)(req.resolve("@sideboard-ai/core"));
13692
13891
  } catch {
13693
13892
  return process.cwd();
13694
13893
  }
@@ -13699,27 +13898,27 @@ function cursorRunnerPath() {
13699
13898
  if (packaged) return packaged;
13700
13899
  const root = entryDir();
13701
13900
  const candidates = [
13702
- (0, import_node_path36.join)(root, "agents", "cursor-runner.js"),
13703
- (0, import_node_path36.join)(root, "agents", "cursor-runner.cjs"),
13901
+ (0, import_node_path37.join)(root, "agents", "cursor-runner.js"),
13902
+ (0, import_node_path37.join)(root, "agents", "cursor-runner.cjs"),
13704
13903
  // If somehow resolved from package root instead of dist/
13705
- (0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.js"),
13706
- (0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.cjs"),
13904
+ (0, import_node_path37.join)(root, "dist", "agents", "cursor-runner.js"),
13905
+ (0, import_node_path37.join)(root, "dist", "agents", "cursor-runner.cjs"),
13707
13906
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
13708
- (0, import_node_path36.join)(root, "cursor-runner.ts"),
13709
- (0, import_node_path36.join)(root, "src", "agents", "cursor-runner.ts")
13907
+ (0, import_node_path37.join)(root, "cursor-runner.ts"),
13908
+ (0, import_node_path37.join)(root, "src", "agents", "cursor-runner.ts")
13710
13909
  ];
13711
13910
  for (const candidate of candidates) {
13712
13911
  if ((0, import_node_fs35.existsSync)(candidate)) return candidate;
13713
13912
  }
13714
13913
  return candidates[0];
13715
13914
  }
13716
- var import_node_fs35, import_node_module3, import_node_path36, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
13915
+ var import_node_fs35, import_node_module3, import_node_path37, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
13717
13916
  var init_cursor = __esm({
13718
13917
  "src/agents/cursor.ts"() {
13719
13918
  "use strict";
13720
13919
  import_node_fs35 = require("fs");
13721
13920
  import_node_module3 = require("module");
13722
- import_node_path36 = require("path");
13921
+ import_node_path37 = require("path");
13723
13922
  import_node_url2 = require("url");
13724
13923
  import_sdk = require("@cursor/sdk");
13725
13924
  init_run();
@@ -14652,8 +14851,8 @@ function accessTokenFromCredentialsJson(raw) {
14652
14851
  }
14653
14852
  }
14654
14853
  function claudeCredentialsPath() {
14655
- const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path37.join)((0, import_node_os13.homedir)(), ".claude");
14656
- return (0, import_node_path37.join)(root, ".credentials.json");
14854
+ const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path38.join)((0, import_node_os13.homedir)(), ".claude");
14855
+ return (0, import_node_path38.join)(root, ".credentials.json");
14657
14856
  }
14658
14857
  async function readFileAccessToken() {
14659
14858
  const path2 = claudeCredentialsPath();
@@ -14763,13 +14962,13 @@ async function getClaudePlanUsage(opts = {}) {
14763
14962
  })();
14764
14963
  return inflight;
14765
14964
  }
14766
- var import_node_fs37, import_node_os13, import_node_path37, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
14965
+ var import_node_fs37, import_node_os13, import_node_path38, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
14767
14966
  var init_claude_usage_client = __esm({
14768
14967
  "src/agents/claude-usage-client.ts"() {
14769
14968
  "use strict";
14770
14969
  import_node_fs37 = require("fs");
14771
14970
  import_node_os13 = require("os");
14772
- import_node_path37 = require("path");
14971
+ import_node_path38 = require("path");
14773
14972
  init_run();
14774
14973
  init_fetch();
14775
14974
  init_app_settings();
@@ -15132,15 +15331,15 @@ var init_agents = __esm({
15132
15331
 
15133
15332
  // src/hook/worktree-pkg-cache.ts
15134
15333
  function worktreePkgCacheRoot(worktreePath) {
15135
- return (0, import_node_path38.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15334
+ return (0, import_node_path39.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15136
15335
  }
15137
15336
  function worktreePkgCacheEnv(worktreePath) {
15138
15337
  const root = worktreePkgCacheRoot(worktreePath);
15139
- const store = (0, import_node_path38.join)(root, "pnpm-store");
15140
- const pnpmCache = (0, import_node_path38.join)(root, "pnpm");
15141
- const npmCache = (0, import_node_path38.join)(root, "npm");
15142
- const nodeGyp = (0, import_node_path38.join)(root, "node-gyp");
15143
- const electron = (0, import_node_path38.join)(root, "electron");
15338
+ const store = (0, import_node_path39.join)(root, "pnpm-store");
15339
+ const pnpmCache = (0, import_node_path39.join)(root, "pnpm");
15340
+ const npmCache = (0, import_node_path39.join)(root, "npm");
15341
+ const nodeGyp = (0, import_node_path39.join)(root, "node-gyp");
15342
+ const electron = (0, import_node_path39.join)(root, "electron");
15144
15343
  return {
15145
15344
  npm_config_store_dir: store,
15146
15345
  PNPM_STORE_DIR: store,
@@ -15176,12 +15375,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15176
15375
  fillGroup(env, ["electron_config_cache"], next);
15177
15376
  ensureWorktreePkgCacheDirs(cwd);
15178
15377
  }
15179
- var import_node_fs38, import_node_path38, WORKTREE_PKG_CACHE_REL;
15378
+ var import_node_fs38, import_node_path39, WORKTREE_PKG_CACHE_REL;
15180
15379
  var init_worktree_pkg_cache = __esm({
15181
15380
  "src/hook/worktree-pkg-cache.ts"() {
15182
15381
  "use strict";
15183
15382
  import_node_fs38 = require("fs");
15184
- import_node_path38 = require("path");
15383
+ import_node_path39 = require("path");
15185
15384
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15186
15385
  }
15187
15386
  });
@@ -16394,12 +16593,12 @@ function readTextIfPresent(abs) {
16394
16593
  }
16395
16594
  }
16396
16595
  function readLocalGuidelines(worktreePath) {
16397
- const localAbs = (0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH);
16596
+ const localAbs = (0, import_node_path40.join)(worktreePath, REVIEW_REQUEST_PATH);
16398
16597
  const localContent = readTextIfPresent(localAbs);
16399
16598
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
16400
16599
  return { path: REVIEW_REQUEST_PATH, content: localContent };
16401
16600
  }
16402
- const legacyAbs = (0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16601
+ const legacyAbs = (0, import_node_path40.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16403
16602
  const legacyContent = readTextIfPresent(legacyAbs);
16404
16603
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
16405
16604
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -16423,27 +16622,27 @@ function contextGuidelines(content, source) {
16423
16622
  };
16424
16623
  }
16425
16624
  function writeContextGuidelines(worktreePath, content) {
16426
- const abs = (0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH);
16427
- (0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
16625
+ const abs = (0, import_node_path40.join)(worktreePath, CONTEXT_REVIEW_PATH);
16626
+ (0, import_node_fs39.mkdirSync)((0, import_node_path40.dirname)(abs), { recursive: true });
16428
16627
  const body = content.endsWith("\n") ? content : `${content}
16429
16628
  `;
16430
16629
  (0, import_node_fs39.writeFileSync)(abs, body, "utf8");
16431
16630
  return body;
16432
16631
  }
16433
16632
  function readSideboardReview(worktreePath, repoPath) {
16434
- const fromWorktree = readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH));
16633
+ const fromWorktree = readTextIfPresent((0, import_node_path40.join)(worktreePath, REPO_REVIEW_PATH));
16435
16634
  if (fromWorktree) return fromWorktree;
16436
16635
  const repo = repoPath?.replace(/\/+$/, "");
16437
16636
  const wt = worktreePath.replace(/\/+$/, "");
16438
16637
  if (!repo || repo === wt) return null;
16439
- return readTextIfPresent((0, import_node_path39.join)(repo, REPO_REVIEW_PATH));
16638
+ return readTextIfPresent((0, import_node_path40.join)(repo, REPO_REVIEW_PATH));
16440
16639
  }
16441
16640
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
16442
- const skillContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH));
16641
+ const skillContent = readTextIfPresent((0, import_node_path40.join)(worktreePath, REVIEW_SKILL_PATH));
16443
16642
  if (skillContent) {
16444
16643
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
16445
16644
  }
16446
- const contextContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH));
16645
+ const contextContent = readTextIfPresent((0, import_node_path40.join)(worktreePath, CONTEXT_REVIEW_PATH));
16447
16646
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
16448
16647
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
16449
16648
  }
@@ -16481,7 +16680,7 @@ function buildReviewRequestAttachment(content, opts) {
16481
16680
  };
16482
16681
  }
16483
16682
  function readExistingReviewRequestFile(worktreePath) {
16484
- return readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
16683
+ return readTextIfPresent((0, import_node_path40.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path40.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path40.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path40.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path40.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
16485
16684
  }
16486
16685
  async function requestReview(threadRef, send2) {
16487
16686
  const from = findThreadByRef(threadRef);
@@ -16508,13 +16707,13 @@ async function requestReview(threadRef, send2) {
16508
16707
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
16509
16708
  return { tab: started, from };
16510
16709
  }
16511
- var import_node_crypto9, import_node_fs39, import_node_path39, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
16710
+ var import_node_crypto9, import_node_fs39, import_node_path40, 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;
16512
16711
  var init_request_review = __esm({
16513
16712
  "src/review/request-review.ts"() {
16514
16713
  "use strict";
16515
16714
  import_node_crypto9 = require("crypto");
16516
16715
  import_node_fs39 = require("fs");
16517
- import_node_path39 = require("path");
16716
+ import_node_path40 = require("path");
16518
16717
  init_global_workspace();
16519
16718
  init_chat_tabs();
16520
16719
  init_thread_store();
@@ -16540,7 +16739,7 @@ function matchSimpleGlob(pattern, name) {
16540
16739
  return new RegExp(`^${escaped}$`).test(name);
16541
16740
  }
16542
16741
  function readWorktreeInclude(repoPath) {
16543
- const path2 = (0, import_node_path40.join)(repoPath, ".worktreeinclude");
16742
+ const path2 = (0, import_node_path41.join)(repoPath, ".worktreeinclude");
16544
16743
  if (!(0, import_node_fs40.existsSync)(path2)) return [];
16545
16744
  return (0, import_node_fs40.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
16546
16745
  }
@@ -16555,7 +16754,7 @@ function resolveFilesToCopy(repoPath) {
16555
16754
  for (const entry of (0, import_node_fs40.readdirSync)(repoPath, { withFileTypes: true })) {
16556
16755
  if (!entry.isFile()) continue;
16557
16756
  for (const glob of settings.fileIncludeGlobs) {
16558
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path40.basename)(glob), entry.name)) {
16757
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path41.basename)(glob), entry.name)) {
16559
16758
  matched.push(entry.name);
16560
16759
  break;
16561
16760
  }
@@ -16581,10 +16780,10 @@ function copyConfiguredFiles(repoPath, worktreePath) {
16581
16780
  const patterns = resolveFilesToCopy(repoPath);
16582
16781
  const copied = [];
16583
16782
  for (const rel of patterns) {
16584
- const src = (0, import_node_path40.join)(repoPath, rel);
16783
+ const src = (0, import_node_path41.join)(repoPath, rel);
16585
16784
  if (!(0, import_node_fs40.existsSync)(src)) continue;
16586
- const dest = (0, import_node_path40.join)(worktreePath, rel);
16587
- (0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(dest), { recursive: true });
16785
+ const dest = (0, import_node_path41.join)(worktreePath, rel);
16786
+ (0, import_node_fs40.mkdirSync)((0, import_node_path41.dirname)(dest), { recursive: true });
16588
16787
  (0, import_node_fs40.copyFileSync)(src, dest);
16589
16788
  copied.push(rel);
16590
16789
  }
@@ -16620,7 +16819,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
16620
16819
  const env = stripNestedElectronEnv({
16621
16820
  ...baseEnv ?? process.env
16622
16821
  });
16623
- const name = opts.workspaceName ?? (0, import_node_path40.basename)(opts.worktreePath);
16822
+ const name = opts.workspaceName ?? (0, import_node_path41.basename)(opts.worktreePath);
16624
16823
  const ports = opts.ports ?? [];
16625
16824
  const primary = ports[0];
16626
16825
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -16883,13 +17082,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
16883
17082
  done: handle.done
16884
17083
  };
16885
17084
  }
16886
- var import_node_fs40, import_node_net, import_node_path40, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17085
+ var import_node_fs40, import_node_net, import_node_path41, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
16887
17086
  var init_conductor = __esm({
16888
17087
  "src/hook/conductor.ts"() {
16889
17088
  "use strict";
16890
17089
  import_node_fs40 = require("fs");
16891
17090
  import_node_net = require("net");
16892
- import_node_path40 = require("path");
17091
+ import_node_path41 = require("path");
16893
17092
  import_execa4 = require("execa");
16894
17093
  import_node_readline3 = require("readline");
16895
17094
  init_settings();
@@ -16953,9 +17152,9 @@ async function findOrphanWorktrees(repoPaths) {
16953
17152
  if ((0, import_node_fs41.existsSync)(root)) {
16954
17153
  for (const entry of (0, import_node_fs41.readdirSync)(root, { withFileTypes: true })) {
16955
17154
  if (!entry.isDirectory()) continue;
16956
- const path2 = (0, import_node_path41.join)(root, entry.name).replace(/\/$/, "");
17155
+ const path2 = (0, import_node_path42.join)(root, entry.name).replace(/\/$/, "");
16957
17156
  if (known.has(path2) || seen.has(path2)) continue;
16958
- if (!(0, import_node_fs41.existsSync)((0, import_node_path41.join)(path2, ".git"))) continue;
17157
+ if (!(0, import_node_fs41.existsSync)((0, import_node_path42.join)(path2, ".git"))) continue;
16959
17158
  seen.add(path2);
16960
17159
  let mtimeMs = 0;
16961
17160
  try {
@@ -17020,12 +17219,12 @@ function worktreeCleanupSettings() {
17020
17219
  autoCleanupOrphans: a.autoCleanupOrphans
17021
17220
  };
17022
17221
  }
17023
- var import_node_fs41, import_node_path41;
17222
+ var import_node_fs41, import_node_path42;
17024
17223
  var init_orphan_cleanup = __esm({
17025
17224
  "src/git/orphan-cleanup.ts"() {
17026
17225
  "use strict";
17027
17226
  import_node_fs41 = require("fs");
17028
- import_node_path41 = require("path");
17227
+ import_node_path42 = require("path");
17029
17228
  init_worktree();
17030
17229
  init_thread_store();
17031
17230
  init_paths();
@@ -17033,6 +17232,77 @@ var init_orphan_cleanup = __esm({
17033
17232
  }
17034
17233
  });
17035
17234
 
17235
+ // src/store/history-cleanup.ts
17236
+ function stripArchivedTranscript(thread) {
17237
+ writeThread(
17238
+ {
17239
+ ...thread,
17240
+ attachments: [],
17241
+ pendingTurnAttachments: [],
17242
+ messages: [historyRetentionStubMessage(thread)]
17243
+ },
17244
+ { touch: false }
17245
+ );
17246
+ }
17247
+ function cleanupArchivedHistory(opts = {}) {
17248
+ const settings = loadAppSettings();
17249
+ if (!opts.force && opts.purgeOlderThanDays == null && !autoCleanupHistoryEnabled(settings)) {
17250
+ return { stripped: [], purged: [] };
17251
+ }
17252
+ const archived = listThreads({ includeArchived: true }).filter((t) => t.status === "archived");
17253
+ const nowMs = opts.nowMs ?? Date.now();
17254
+ const plan = opts.purgeOlderThanDays != null ? { stripIds: [], purgeIds: planHistoryAgePurge(archived, opts.purgeOlderThanDays, nowMs) } : planHistoryRetention(archived, {
17255
+ maxCount: opts.maxCount ?? historyMaxCount(settings),
17256
+ maxDays: opts.maxDays ?? historyMaxDays(settings),
17257
+ nowMs
17258
+ });
17259
+ const stripped = [];
17260
+ const purged = [];
17261
+ if (opts.dryRun) {
17262
+ return { stripped: plan.stripIds, purged: plan.purgeIds };
17263
+ }
17264
+ for (const id of plan.stripIds) {
17265
+ const thread = readThread(id);
17266
+ if (!thread || thread.status !== "archived") continue;
17267
+ try {
17268
+ stripArchivedTranscript(thread);
17269
+ stripped.push(id);
17270
+ } catch {
17271
+ }
17272
+ }
17273
+ for (const id of plan.purgeIds) {
17274
+ const thread = readThread(id);
17275
+ if (!thread || thread.status !== "archived") continue;
17276
+ try {
17277
+ deleteThreadRecord(id);
17278
+ purged.push(id);
17279
+ } catch {
17280
+ }
17281
+ }
17282
+ if (stripped.length > 0 || purged.length > 0) {
17283
+ updateAdvancedSettings({
17284
+ historyLastCleanupAt: new Date(nowMs).toISOString()
17285
+ });
17286
+ }
17287
+ return { stripped, purged };
17288
+ }
17289
+ function shouldRunHistoryCleanup(settings = loadAppSettings()) {
17290
+ if (!autoCleanupHistoryEnabled(settings)) return false;
17291
+ const intervalHours = settings.advanced.historyCleanupIntervalHours ?? HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT;
17292
+ const last = settings.advanced.historyLastCleanupAt;
17293
+ if (!last) return true;
17294
+ const elapsed = Date.now() - Date.parse(last);
17295
+ return Number.isFinite(elapsed) && elapsed >= intervalHours * 36e5;
17296
+ }
17297
+ var init_history_cleanup = __esm({
17298
+ "src/store/history-cleanup.ts"() {
17299
+ "use strict";
17300
+ init_app_settings();
17301
+ init_history_retention();
17302
+ init_thread_store();
17303
+ }
17304
+ });
17305
+
17036
17306
  // src/git/apply-into-main.ts
17037
17307
  async function applyThreadIntoMain(thread, opts) {
17038
17308
  const method = opts?.method ?? "merge";
@@ -17128,11 +17398,11 @@ async function cloneRepoIntoSideboard(opts) {
17128
17398
  if (!url) throw new Error("Clone URL is required");
17129
17399
  let name = opts.name?.trim();
17130
17400
  if (!name) {
17131
- const leaf = (0, import_node_path42.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17401
+ const leaf = (0, import_node_path43.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17132
17402
  name = leaf || "repo";
17133
17403
  }
17134
17404
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
17135
- const dest = (0, import_node_path42.join)(sideboardReposDir(), name);
17405
+ const dest = (0, import_node_path43.join)(sideboardReposDir(), name);
17136
17406
  if ((0, import_node_fs42.existsSync)(dest)) {
17137
17407
  const repoPath2 = await resolveRepoRoot(dest);
17138
17408
  const workspace2 = await ensureWorkspace(repoPath2);
@@ -17148,12 +17418,12 @@ async function cloneRepoIntoSideboard(opts) {
17148
17418
  const workspace = await ensureWorkspace(repoPath);
17149
17419
  return { repoPath, workspace };
17150
17420
  }
17151
- var import_node_fs42, import_node_path42, import_execa6;
17421
+ var import_node_fs42, import_node_path43, import_execa6;
17152
17422
  var init_clone_repo = __esm({
17153
17423
  "src/git/clone-repo.ts"() {
17154
17424
  "use strict";
17155
17425
  import_node_fs42 = require("fs");
17156
- import_node_path42 = require("path");
17426
+ import_node_path43 = require("path");
17157
17427
  import_execa6 = require("execa");
17158
17428
  init_paths();
17159
17429
  init_workspaces();
@@ -17279,7 +17549,7 @@ function readIntFile(file) {
17279
17549
  return Number.isInteger(n) ? n : null;
17280
17550
  }
17281
17551
  function jobDir(root, id, legacy = false) {
17282
- return (0, import_node_path43.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
17552
+ return (0, import_node_path44.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
17283
17553
  }
17284
17554
  function resolveJobDir(root, id) {
17285
17555
  const modern = jobDir(root, id, false);
@@ -17289,7 +17559,7 @@ function resolveJobDir(root, id) {
17289
17559
  return modern;
17290
17560
  }
17291
17561
  function listJobIdsIn(root, rel) {
17292
- const dir = (0, import_node_path43.join)(root, rel);
17562
+ const dir = (0, import_node_path44.join)(root, rel);
17293
17563
  if (!(0, import_node_fs43.existsSync)(dir)) return [];
17294
17564
  return (0, import_node_fs43.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
17295
17565
  }
@@ -17303,7 +17573,7 @@ function listRunningDetachedJobs(worktreePath) {
17303
17573
  const running = [];
17304
17574
  for (const id of ids) {
17305
17575
  const dir = resolveJobDir(root, id);
17306
- const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
17576
+ const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
17307
17577
  if (jobTreeAlive(pid)) running.push(id);
17308
17578
  }
17309
17579
  return running.sort();
@@ -17406,15 +17676,15 @@ function takeDelta(logFile, cursorFile) {
17406
17676
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
17407
17677
  }
17408
17678
  function snapshotJob(dir) {
17409
- const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
17679
+ const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
17410
17680
  const running = jobTreeAlive(pid);
17411
17681
  return {
17412
17682
  pid,
17413
17683
  running,
17414
- exitCode: readIntFile((0, import_node_path43.join)(dir, "exit")),
17415
- log: (0, import_node_path43.join)(dir, "log"),
17416
- cursor: (0, import_node_path43.join)(dir, "present.cursor"),
17417
- progress: tailProgress((0, import_node_path43.join)(dir, "log"))
17684
+ exitCode: readIntFile((0, import_node_path44.join)(dir, "exit")),
17685
+ log: (0, import_node_path44.join)(dir, "log"),
17686
+ cursor: (0, import_node_path44.join)(dir, "present.cursor"),
17687
+ progress: tailProgress((0, import_node_path44.join)(dir, "log"))
17418
17688
  };
17419
17689
  }
17420
17690
  function toResult(id, snap, extra) {
@@ -17423,7 +17693,7 @@ function toResult(id, snap, extra) {
17423
17693
  const stillRunning = snap.running && !ok;
17424
17694
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
17425
17695
  try {
17426
- (0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(snap.cursor), { recursive: true });
17696
+ (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(snap.cursor), { recursive: true });
17427
17697
  (0, import_node_fs43.writeFileSync)(snap.cursor, `${nextCursor}
17428
17698
  `);
17429
17699
  } catch {
@@ -17499,7 +17769,7 @@ function killProcessTree(pid, signal) {
17499
17769
  }
17500
17770
  function appendJobLog(logFile, line) {
17501
17771
  try {
17502
- (0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(logFile), { recursive: true });
17772
+ (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(logFile), { recursive: true });
17503
17773
  const body = line.endsWith("\n") ? line : `${line}
17504
17774
  `;
17505
17775
  (0, import_node_fs43.appendFileSync)(logFile, body);
@@ -17548,7 +17818,7 @@ async function stopDetachedJob(cwd, id, opts) {
17548
17818
  killProcessTree(targetPid, "SIGKILL");
17549
17819
  await sleep2(100);
17550
17820
  }
17551
- const exitFile = (0, import_node_path43.join)(dir, "exit");
17821
+ const exitFile = (0, import_node_path44.join)(dir, "exit");
17552
17822
  if (!(0, import_node_fs43.existsSync)(exitFile)) {
17553
17823
  try {
17554
17824
  (0, import_node_fs43.writeFileSync)(exitFile, "1\n");
@@ -17571,12 +17841,12 @@ async function stopDetachedJob(cwd, id, opts) {
17571
17841
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
17572
17842
  };
17573
17843
  }
17574
- var import_node_fs43, import_node_path43, 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;
17844
+ var import_node_fs43, import_node_path44, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
17575
17845
  var init_wait_for_job = __esm({
17576
17846
  "src/mcp/wait-for-job.ts"() {
17577
17847
  "use strict";
17578
17848
  import_node_fs43 = require("fs");
17579
- import_node_path43 = require("path");
17849
+ import_node_path44 = require("path");
17580
17850
  init_workspace_scratch();
17581
17851
  init_wait_for_turn();
17582
17852
  MAX_JOB_CONTINUES = 8;
@@ -19709,7 +19979,7 @@ var init_quota_failover = __esm({
19709
19979
  // src/threads/adopt.ts
19710
19980
  function thisModuleFile() {
19711
19981
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
19712
- return cjsFile || process.argv[1] || (0, import_node_path44.join)(process.cwd(), "package.json");
19982
+ return cjsFile || process.argv[1] || (0, import_node_path45.join)(process.cwd(), "package.json");
19713
19983
  }
19714
19984
  function openReadonlySqlite(file) {
19715
19985
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -19737,7 +20007,7 @@ function resolveConductorCursorAgentId(workspacePath) {
19737
20007
  return null;
19738
20008
  }
19739
20009
  for (const hash of hashes) {
19740
- const agentsFile = (0, import_node_path44.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20010
+ const agentsFile = (0, import_node_path45.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
19741
20011
  if (!(0, import_node_fs46.existsSync)(agentsFile)) continue;
19742
20012
  let text7;
19743
20013
  try {
@@ -19797,8 +20067,8 @@ function listConductorWorkspaces() {
19797
20067
  if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
19798
20068
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
19799
20069
  }
19800
- const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
19801
- const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
20070
+ const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20071
+ const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
19802
20072
  try {
19803
20073
  (0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
19804
20074
  for (const suffix of ["-wal", "-shm"]) {
@@ -19888,8 +20158,8 @@ function importConductorWorkspace(workspaceId) {
19888
20158
  if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
19889
20159
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
19890
20160
  }
19891
- const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
19892
- const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
20161
+ const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20162
+ const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
19893
20163
  try {
19894
20164
  (0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
19895
20165
  for (const suffix of ["-wal", "-shm"]) {
@@ -19983,25 +20253,25 @@ function importConductorWorkspace(workspaceId) {
19983
20253
  async function importConductorWorkspaceAsync(workspaceId) {
19984
20254
  return importConductorWorkspace(workspaceId);
19985
20255
  }
19986
- var import_node_child_process5, import_node_fs46, import_node_os14, import_node_path44, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
20256
+ var import_node_child_process5, import_node_fs46, import_node_os14, import_node_path45, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
19987
20257
  var init_adopt = __esm({
19988
20258
  "src/threads/adopt.ts"() {
19989
20259
  "use strict";
19990
20260
  import_node_child_process5 = require("child_process");
19991
20261
  import_node_fs46 = require("fs");
19992
20262
  import_node_os14 = require("os");
19993
- import_node_path44 = require("path");
20263
+ import_node_path45 = require("path");
19994
20264
  import_node_module4 = require("module");
19995
20265
  init_worktree();
19996
20266
  init_thread_store();
19997
- CONDUCTOR_APP_SUPPORT = (0, import_node_path44.join)(
20267
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path45.join)(
19998
20268
  process.env.HOME ?? "",
19999
20269
  "Library",
20000
20270
  "Application Support",
20001
20271
  "com.conductor.app"
20002
20272
  );
20003
- CONDUCTOR_DB = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20004
- CURSOR_SDK_STORE = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20273
+ CONDUCTOR_DB = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20274
+ CURSOR_SDK_STORE = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20005
20275
  }
20006
20276
  });
20007
20277
 
@@ -20456,7 +20726,7 @@ new file mode 100644
20456
20726
  };
20457
20727
  }
20458
20728
  async function untrackedPatch(worktreePath, path2, maxHunk) {
20459
- const abs = (0, import_node_path45.join)(worktreePath, path2);
20729
+ const abs = (0, import_node_path46.join)(worktreePath, path2);
20460
20730
  try {
20461
20731
  const st = (0, import_node_fs48.statSync)(abs);
20462
20732
  if (st.isFile() && st.size > maxHunk) {
@@ -20949,7 +21219,7 @@ function isImageRelativePath(relativePath) {
20949
21219
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
20950
21220
  assertSafeRelativePath(relativePath);
20951
21221
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
20952
- const abs = (0, import_node_path45.join)(worktreePath, relativePath);
21222
+ const abs = (0, import_node_path46.join)(worktreePath, relativePath);
20953
21223
  const st = (0, import_node_fs48.statSync)(abs);
20954
21224
  if (!st.isFile()) {
20955
21225
  throw new Error(`Not a file: ${relativePath}`);
@@ -20969,7 +21239,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
20969
21239
  function readWorktreeFile(worktreePath, relativePath, opts) {
20970
21240
  assertSafeRelativePath(relativePath);
20971
21241
  const maxBytes = opts?.maxBytes ?? 2e5;
20972
- const abs = (0, import_node_path45.join)(worktreePath, relativePath);
21242
+ const abs = (0, import_node_path46.join)(worktreePath, relativePath);
20973
21243
  const st = (0, import_node_fs48.statSync)(abs);
20974
21244
  if (!st.isFile()) {
20975
21245
  throw new Error(`Not a file: ${relativePath}`);
@@ -21017,8 +21287,8 @@ function assertSafeRelativePath(relativePath) {
21017
21287
  }
21018
21288
  function writeWorktreeFile(worktreePath, relativePath, content) {
21019
21289
  assertSafeRelativePath(relativePath);
21020
- const abs = (0, import_node_path45.join)(worktreePath, relativePath);
21021
- (0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
21290
+ const abs = (0, import_node_path46.join)(worktreePath, relativePath);
21291
+ (0, import_node_fs48.mkdirSync)((0, import_node_path46.dirname)(abs), { recursive: true });
21022
21292
  (0, import_node_fs48.writeFileSync)(abs, content, "utf8");
21023
21293
  return { path: relativePath };
21024
21294
  }
@@ -21036,12 +21306,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
21036
21306
  truncated: full.files.length > maxFiles
21037
21307
  };
21038
21308
  }
21039
- var import_node_fs48, import_node_path45, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21309
+ var import_node_fs48, import_node_path46, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21040
21310
  var init_diff = __esm({
21041
21311
  "src/diff/diff.ts"() {
21042
21312
  "use strict";
21043
21313
  import_node_fs48 = require("fs");
21044
- import_node_path45 = require("path");
21314
+ import_node_path46 = require("path");
21045
21315
  init_run();
21046
21316
  init_worktree();
21047
21317
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -21426,7 +21696,7 @@ function scanSkillsDir(dir, source, out) {
21426
21696
  }
21427
21697
  for (const entry of entries) {
21428
21698
  if (entry.startsWith(".")) continue;
21429
- const skillMd = (0, import_node_path46.join)(dir, entry, "SKILL.md");
21699
+ const skillMd = (0, import_node_path47.join)(dir, entry, "SKILL.md");
21430
21700
  if (!(0, import_node_fs49.existsSync)(skillMd)) continue;
21431
21701
  try {
21432
21702
  if (!(0, import_node_fs49.statSync)(skillMd).isFile()) continue;
@@ -21448,12 +21718,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
21448
21718
  return;
21449
21719
  }
21450
21720
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
21451
- const skill = readSkill((0, import_node_path46.join)(dir, "SKILL.md"), "cli");
21721
+ const skill = readSkill((0, import_node_path47.join)(dir, "SKILL.md"), "cli");
21452
21722
  if (skill) out.push(skill);
21453
21723
  }
21454
21724
  for (const entry of entries) {
21455
21725
  if (entry === "node_modules" || entry === ".git") continue;
21456
- const full = (0, import_node_path46.join)(dir, entry);
21726
+ const full = (0, import_node_path47.join)(dir, entry);
21457
21727
  try {
21458
21728
  if (!(0, import_node_fs49.statSync)(full).isDirectory()) continue;
21459
21729
  } catch {
@@ -21473,17 +21743,17 @@ function discoverSkills(worktreePath) {
21473
21743
  const home = (0, import_node_os15.homedir)();
21474
21744
  const collected = [];
21475
21745
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
21476
- scanSkillsDir((0, import_node_path46.join)(worktreePath, rel), "workspace", collected);
21746
+ scanSkillsDir((0, import_node_path47.join)(worktreePath, rel), "workspace", collected);
21477
21747
  }
21478
21748
  for (const abs of [
21479
- (0, import_node_path46.join)(home, ".claude/skills"),
21480
- (0, import_node_path46.join)(home, ".cursor/skills"),
21481
- (0, import_node_path46.join)(home, ".sideboard/skills"),
21482
- (0, import_node_path46.join)(home, ".brightsy/skills")
21749
+ (0, import_node_path47.join)(home, ".claude/skills"),
21750
+ (0, import_node_path47.join)(home, ".cursor/skills"),
21751
+ (0, import_node_path47.join)(home, ".sideboard/skills"),
21752
+ (0, import_node_path47.join)(home, ".brightsy/skills")
21483
21753
  ]) {
21484
21754
  scanSkillsDir(abs, "user", collected);
21485
21755
  }
21486
- scanClaudePluginSkills((0, import_node_path46.join)(home, ".claude/plugins"), collected);
21756
+ scanClaudePluginSkills((0, import_node_path47.join)(home, ".claude/plugins"), collected);
21487
21757
  collected.push(...bundledSkills());
21488
21758
  const rank = {
21489
21759
  workspace: 0,
@@ -21523,13 +21793,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
21523
21793
 
21524
21794
  \u2026(truncated)` : raw;
21525
21795
  }
21526
- var import_node_fs49, import_node_os15, import_node_path46, BUNDLED_SKILL_PREFIX;
21796
+ var import_node_fs49, import_node_os15, import_node_path47, BUNDLED_SKILL_PREFIX;
21527
21797
  var init_discover = __esm({
21528
21798
  "src/skills/discover.ts"() {
21529
21799
  "use strict";
21530
21800
  import_node_fs49 = require("fs");
21531
21801
  import_node_os15 = require("os");
21532
- import_node_path46 = require("path");
21802
+ import_node_path47 = require("path");
21533
21803
  init_long_running();
21534
21804
  BUNDLED_SKILL_PREFIX = "bundled:";
21535
21805
  }
@@ -21650,7 +21920,7 @@ var init_consume_attachments = __esm({
21650
21920
  // src/skills/detached-job-path.ts
21651
21921
  function detachedJobScriptIn(dir) {
21652
21922
  for (const name of DETACHED_JOB_FILENAMES) {
21653
- const script = (0, import_node_path47.join)(dir, "scripts", name);
21923
+ const script = (0, import_node_path48.join)(dir, "scripts", name);
21654
21924
  if ((0, import_node_fs50.existsSync)(script)) return script;
21655
21925
  }
21656
21926
  return null;
@@ -21663,11 +21933,11 @@ function packagedDetachedJobPath() {
21663
21933
  function resolveDetachedJobScript() {
21664
21934
  const packaged = packagedDetachedJobPath();
21665
21935
  if (packaged) return packaged;
21666
- let dir = (0, import_node_path47.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
21936
+ let dir = (0, import_node_path48.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
21667
21937
  for (let i = 0; i < 8; i++) {
21668
21938
  const candidate = detachedJobScriptIn(dir);
21669
21939
  if (candidate) return candidate;
21670
- const parent = (0, import_node_path47.dirname)(dir);
21940
+ const parent = (0, import_node_path48.dirname)(dir);
21671
21941
  if (parent === dir) break;
21672
21942
  dir = parent;
21673
21943
  }
@@ -21678,12 +21948,12 @@ function formatDetachedJobInvoke(scriptPath) {
21678
21948
  if (resolved) return `node ${JSON.stringify(resolved)}`;
21679
21949
  return "node scripts/detached-job.cjs";
21680
21950
  }
21681
- var import_node_fs50, import_node_path47, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
21951
+ var import_node_fs50, import_node_path48, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
21682
21952
  var init_detached_job_path = __esm({
21683
21953
  "src/skills/detached-job-path.ts"() {
21684
21954
  "use strict";
21685
21955
  import_node_fs50 = require("fs");
21686
- import_node_path47 = require("path");
21956
+ import_node_path48 = require("path");
21687
21957
  import_node_url3 = require("url");
21688
21958
  init_packaged_runtime();
21689
21959
  import_meta3 = {};
@@ -21865,9 +22135,9 @@ function formatPrGateDirective() {
21865
22135
  }
21866
22136
  function formatProcessGuideDirective(opts) {
21867
22137
  const worktree = opts?.worktreePath?.trim();
21868
- const hasGraphSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
21869
- const hasReviewSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/review/SKILL.md"));
21870
- const hasInstallSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22138
+ const hasGraphSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22139
+ const hasReviewSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/review/SKILL.md"));
22140
+ const hasInstallSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
21871
22141
  return [
21872
22142
  "Process guides (recurring work only):",
21873
22143
  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,
@@ -21905,12 +22175,12 @@ function formatArtifactDirective() {
21905
22175
  function formatUiReminder() {
21906
22176
  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.";
21907
22177
  }
21908
- var import_node_fs51, import_node_path48, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22178
+ var import_node_fs51, import_node_path49, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
21909
22179
  var init_instructions = __esm({
21910
22180
  "src/agents/instructions.ts"() {
21911
22181
  "use strict";
21912
22182
  import_node_fs51 = require("fs");
21913
- import_node_path48 = require("path");
22183
+ import_node_path49 = require("path");
21914
22184
  init_git_auth_mode();
21915
22185
  init_branch_prefix();
21916
22186
  init_worktree_labels();
@@ -22296,13 +22566,13 @@ __export(plan_file_exports, {
22296
22566
  writePlanFile: () => writePlanFile
22297
22567
  });
22298
22568
  function ensureAttachmentsGitignore(worktreePath) {
22299
- const gitignoreAbs = (0, import_node_path49.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
22569
+ const gitignoreAbs = (0, import_node_path50.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
22300
22570
  if ((0, import_node_fs52.existsSync)(gitignoreAbs)) return;
22301
- (0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(gitignoreAbs), { recursive: true });
22571
+ (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(gitignoreAbs), { recursive: true });
22302
22572
  (0, import_node_fs52.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
22303
22573
  }
22304
22574
  function planFileAbs(worktreePath) {
22305
- return (0, import_node_path49.join)(worktreePath, PLAN_FILE_REL);
22575
+ return (0, import_node_path50.join)(worktreePath, PLAN_FILE_REL);
22306
22576
  }
22307
22577
  function readTextIfPresent2(abs) {
22308
22578
  if (!(0, import_node_fs52.existsSync)(abs)) return null;
@@ -22314,22 +22584,22 @@ function readTextIfPresent2(abs) {
22314
22584
  }
22315
22585
  }
22316
22586
  function readPlanFile(worktreePath) {
22317
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path49.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path49.join)(worktreePath, LEGACY_PLAN_FILE_REL));
22587
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path50.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path50.join)(worktreePath, LEGACY_PLAN_FILE_REL));
22318
22588
  }
22319
22589
  function writePlanFile(worktreePath, content) {
22320
22590
  ensureAttachmentsGitignore(worktreePath);
22321
22591
  const abs = planFileAbs(worktreePath);
22322
- (0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(abs), { recursive: true });
22592
+ (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
22323
22593
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
22324
22594
  (0, import_node_fs52.writeFileSync)(abs, body, "utf8");
22325
22595
  return PLAN_FILE_REL;
22326
22596
  }
22327
- var import_node_fs52, import_node_path49;
22597
+ var import_node_fs52, import_node_path50;
22328
22598
  var init_plan_file = __esm({
22329
22599
  "src/plan/plan-file.ts"() {
22330
22600
  "use strict";
22331
22601
  import_node_fs52 = require("fs");
22332
- import_node_path49 = require("path");
22602
+ import_node_path50 = require("path");
22333
22603
  init_workspace_scratch();
22334
22604
  init_plan_present();
22335
22605
  init_plan_present();
@@ -22375,37 +22645,6 @@ var init_sync_branch = __esm({
22375
22645
  }
22376
22646
  });
22377
22647
 
22378
- // src/agents/cursor-store.ts
22379
- function cursorSdkStoreDir(threadId) {
22380
- const root = (0, import_node_path50.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
22381
- const id = sanitizeCursorStoreSegment(threadId);
22382
- if (!id) return root;
22383
- return (0, import_node_path50.join)(root, "threads", id);
22384
- }
22385
- function cursorSdkRunsNdjsonPath(threadId) {
22386
- return (0, import_node_path50.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
22387
- }
22388
- function cursorSdkRunsNdjsonSearchPaths(threadId) {
22389
- const scoped = cursorSdkRunsNdjsonPath(threadId);
22390
- const shared = cursorSdkRunsNdjsonPath(null);
22391
- if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
22392
- return [shared];
22393
- }
22394
- return [scoped, shared];
22395
- }
22396
- function sanitizeCursorStoreSegment(threadId) {
22397
- return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
22398
- }
22399
- var import_node_path50, CURSOR_SDK_STORE_DIR;
22400
- var init_cursor_store = __esm({
22401
- "src/agents/cursor-store.ts"() {
22402
- "use strict";
22403
- import_node_path50 = require("path");
22404
- init_paths();
22405
- CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
22406
- }
22407
- });
22408
-
22409
22648
  // src/agents/cursor-recover.ts
22410
22649
  var cursor_recover_exports = {};
22411
22650
  __export(cursor_recover_exports, {
@@ -22615,6 +22854,7 @@ var init_orchestrator = __esm({
22615
22854
  init_conductor();
22616
22855
  init_setup_log();
22617
22856
  init_orphan_cleanup();
22857
+ init_history_cleanup();
22618
22858
  init_apply_into_main();
22619
22859
  init_clone_repo();
22620
22860
  init_message_parts();
@@ -22802,6 +23042,12 @@ var init_orchestrator = __esm({
22802
23042
  }
22803
23043
  } catch {
22804
23044
  }
23045
+ try {
23046
+ if (shouldRunHistoryCleanup()) {
23047
+ cleanupArchivedHistory();
23048
+ }
23049
+ } catch {
23050
+ }
22805
23051
  if (drainQueues) {
22806
23052
  this.adoptPersistedQueues();
22807
23053
  }
@@ -24130,6 +24376,20 @@ var init_orchestrator = __esm({
24130
24376
  repoPaths
24131
24377
  });
24132
24378
  }
24379
+ /** Bound Settings → History. After archive always; reconcile is interval-gated. */
24380
+ enforceHistoryRetention() {
24381
+ try {
24382
+ cleanupArchivedHistory();
24383
+ } catch {
24384
+ }
24385
+ }
24386
+ cleanupHistory(opts) {
24387
+ return cleanupArchivedHistory({
24388
+ dryRun: opts?.dryRun,
24389
+ purgeOlderThanDays: opts?.purgeOlderThanDays,
24390
+ force: opts?.force
24391
+ });
24392
+ }
24133
24393
  /**
24134
24394
  * Best-of-n / fanout: create N threads (one per agent) with the same prompt.
24135
24395
  */
@@ -24690,6 +24950,7 @@ var init_orchestrator = __esm({
24690
24950
  if (isGlobalThread(thread)) {
24691
24951
  const archived2 = setStatus(thread.id, "archived");
24692
24952
  this.emit({ type: "status_changed", threadId: archived2.id, status: "archived" });
24953
+ this.enforceHistoryRetention();
24693
24954
  return archived2;
24694
24955
  }
24695
24956
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
@@ -24711,6 +24972,7 @@ var init_orchestrator = __esm({
24711
24972
  }
24712
24973
  const archived = setStatus(thread.id, "archived");
24713
24974
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
24975
+ this.enforceHistoryRetention();
24714
24976
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
24715
24977
  try {
24716
24978
  const { ensureWorkspace: ensureWorkspace2 } = await Promise.resolve().then(() => (init_workspaces(), workspaces_exports));
@@ -25011,6 +25273,12 @@ __export(index_exports, {
25011
25273
  GITHUB_PR_BODY_SAFE_CHARS: () => GITHUB_PR_BODY_SAFE_CHARS,
25012
25274
  GLOBAL_WORKSPACE_ID: () => GLOBAL_WORKSPACE_ID2,
25013
25275
  HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
25276
+ HISTORY_DISCARDED_TEXT: () => HISTORY_DISCARDED_TEXT,
25277
+ HISTORY_MAX_COUNT_DEFAULT: () => HISTORY_MAX_COUNT_DEFAULT,
25278
+ HISTORY_MAX_COUNT_MAX: () => HISTORY_MAX_COUNT_MAX,
25279
+ HISTORY_MAX_COUNT_MIN: () => HISTORY_MAX_COUNT_MIN,
25280
+ HISTORY_MAX_DAYS_DEFAULT: () => HISTORY_MAX_DAYS_DEFAULT,
25281
+ HISTORY_MAX_DAYS_MAX: () => HISTORY_MAX_DAYS_MAX,
25014
25282
  HOME_BOARD_CACHE_TTL_MS: () => HOME_BOARD_CACHE_TTL_MS,
25015
25283
  IMPLIED_TICKET_RESOLVE_PROMPT: () => IMPLIED_TICKET_RESOLVE_PROMPT,
25016
25284
  ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
@@ -25118,6 +25386,7 @@ __export(index_exports, {
25118
25386
  attachmentsFromWorktreePaths: () => attachmentsFromWorktreePaths,
25119
25387
  attachmentsGitignoreBody: () => attachmentsGitignoreBody,
25120
25388
  autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
25389
+ autoCleanupHistoryEnabled: () => autoCleanupHistoryEnabled,
25121
25390
  autoCleanupOrphansEnabled: () => autoCleanupOrphansEnabled,
25122
25391
  autoRenameBranchEnabled: () => autoRenameBranchEnabled,
25123
25392
  autoRunAfterSetupEnabled: () => autoRunAfterSetupEnabled,
@@ -25155,11 +25424,14 @@ __export(index_exports, {
25155
25424
  childEnvWithAppSettings: () => childEnvWithAppSettings,
25156
25425
  claimDesktopHost: () => claimDesktopHost,
25157
25426
  clampGithubPrBody: () => clampGithubPrBody,
25427
+ clampHistoryMaxCount: () => clampHistoryMaxCount,
25428
+ clampHistoryMaxDays: () => clampHistoryMaxDays,
25158
25429
  classifyWorktreeColumn: () => classifyWorktreeColumn,
25159
25430
  claudeAdapter: () => claudeAdapter,
25160
25431
  claudeChromeEnabled: () => claudeChromeEnabled,
25161
25432
  claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
25162
25433
  claudeUserSettingsPath: () => claudeUserSettingsPath,
25434
+ cleanupArchivedHistory: () => cleanupArchivedHistory,
25163
25435
  cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
25164
25436
  clearBoardPins: () => clearBoardPins,
25165
25437
  clearHomeBoardCache: () => clearHomeBoardCache,
@@ -25391,6 +25663,8 @@ __export(index_exports, {
25391
25663
  hasRepoHook: () => hasRepoHook,
25392
25664
  hasWorkspaceHook: () => hasWorkspaceHook,
25393
25665
  healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
25666
+ historyMaxCount: () => historyMaxCount,
25667
+ historyMaxDays: () => historyMaxDays,
25394
25668
  hottestClaudeWindow: () => hottestClaudeWindow,
25395
25669
  httpFetch: () => httpFetch,
25396
25670
  importConductorWorkspace: () => importConductorWorkspace,
@@ -25423,6 +25697,7 @@ __export(index_exports, {
25423
25697
  isGhRateLimitError: () => isGhRateLimitError,
25424
25698
  isGlobalRepoPath: () => isGlobalRepoPath,
25425
25699
  isGlobalThread: () => isGlobalThread,
25700
+ isHistoryRetentionStub: () => isHistoryRetentionStub,
25426
25701
  isHomeBoardThread: () => isHomeBoardThread,
25427
25702
  isImageFilePath: () => isImageFilePath,
25428
25703
  isInPrStack: () => isInPrStack,
@@ -25581,6 +25856,8 @@ __export(index_exports, {
25581
25856
  persistPendingFileAttachments: () => persistPendingFileAttachments,
25582
25857
  persistVaultKeyInKeychain: () => persistVaultKeyInKeychain,
25583
25858
  planFileAbs: () => planFileAbs,
25859
+ planHistoryAgePurge: () => planHistoryAgePurge,
25860
+ planHistoryRetention: () => planHistoryRetention,
25584
25861
  planQuestionsSignature: () => planQuestionsSignature,
25585
25862
  pollSlackOutboundWatches: () => pollSlackOutboundWatches,
25586
25863
  posixShellSingleQuote: () => posixShellSingleQuote,
@@ -25696,6 +25973,7 @@ __export(index_exports, {
25696
25973
  shouldRefreshReviewRequestTemplate: () => shouldRefreshReviewRequestTemplate,
25697
25974
  shouldRemoveWorktreeOnTeardown: () => shouldRemoveWorktreeOnTeardown,
25698
25975
  shouldResetSessionForOccupancy: () => shouldResetSessionForOccupancy,
25976
+ shouldRunHistoryCleanup: () => shouldRunHistoryCleanup,
25699
25977
  shouldRunWorktreeCleanup: () => shouldRunWorktreeCleanup,
25700
25978
  shouldStampSetupLastError: () => shouldStampSetupLastError,
25701
25979
  showCostEnabled: () => showCostEnabled,
@@ -28221,6 +28499,8 @@ init_coordinator_prompt();
28221
28499
  init_apply_into_main();
28222
28500
  init_clone_repo();
28223
28501
  init_orphan_cleanup();
28502
+ init_history_retention();
28503
+ init_history_cleanup();
28224
28504
 
28225
28505
  // src/mcp/server.ts
28226
28506
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
@@ -33772,6 +34052,12 @@ init_outbound_watch();
33772
34052
  GITHUB_PR_BODY_SAFE_CHARS,
33773
34053
  GLOBAL_WORKSPACE_ID,
33774
34054
  HARNESS_ENV_KEYS,
34055
+ HISTORY_DISCARDED_TEXT,
34056
+ HISTORY_MAX_COUNT_DEFAULT,
34057
+ HISTORY_MAX_COUNT_MAX,
34058
+ HISTORY_MAX_COUNT_MIN,
34059
+ HISTORY_MAX_DAYS_DEFAULT,
34060
+ HISTORY_MAX_DAYS_MAX,
33775
34061
  HOME_BOARD_CACHE_TTL_MS,
33776
34062
  IMPLIED_TICKET_RESOLVE_PROMPT,
33777
34063
  ISSUE_SOURCE_LABELS,
@@ -33879,6 +34165,7 @@ init_outbound_watch();
33879
34165
  attachmentsFromWorktreePaths,
33880
34166
  attachmentsGitignoreBody,
33881
34167
  autoArchiveOnMergeEnabled,
34168
+ autoCleanupHistoryEnabled,
33882
34169
  autoCleanupOrphansEnabled,
33883
34170
  autoRenameBranchEnabled,
33884
34171
  autoRunAfterSetupEnabled,
@@ -33916,11 +34203,14 @@ init_outbound_watch();
33916
34203
  childEnvWithAppSettings,
33917
34204
  claimDesktopHost,
33918
34205
  clampGithubPrBody,
34206
+ clampHistoryMaxCount,
34207
+ clampHistoryMaxDays,
33919
34208
  classifyWorktreeColumn,
33920
34209
  claudeAdapter,
33921
34210
  claudeChromeEnabled,
33922
34211
  claudeUsageOverLimitWindows,
33923
34212
  claudeUserSettingsPath,
34213
+ cleanupArchivedHistory,
33924
34214
  cleanupOrphanWorktrees,
33925
34215
  clearBoardPins,
33926
34216
  clearHomeBoardCache,
@@ -34152,6 +34442,8 @@ init_outbound_watch();
34152
34442
  hasRepoHook,
34153
34443
  hasWorkspaceHook,
34154
34444
  healOrchestrationSoccerTitles,
34445
+ historyMaxCount,
34446
+ historyMaxDays,
34155
34447
  hottestClaudeWindow,
34156
34448
  httpFetch,
34157
34449
  importConductorWorkspace,
@@ -34184,6 +34476,7 @@ init_outbound_watch();
34184
34476
  isGhRateLimitError,
34185
34477
  isGlobalRepoPath,
34186
34478
  isGlobalThread,
34479
+ isHistoryRetentionStub,
34187
34480
  isHomeBoardThread,
34188
34481
  isImageFilePath,
34189
34482
  isInPrStack,
@@ -34342,6 +34635,8 @@ init_outbound_watch();
34342
34635
  persistPendingFileAttachments,
34343
34636
  persistVaultKeyInKeychain,
34344
34637
  planFileAbs,
34638
+ planHistoryAgePurge,
34639
+ planHistoryRetention,
34345
34640
  planQuestionsSignature,
34346
34641
  pollSlackOutboundWatches,
34347
34642
  posixShellSingleQuote,
@@ -34457,6 +34752,7 @@ init_outbound_watch();
34457
34752
  shouldRefreshReviewRequestTemplate,
34458
34753
  shouldRemoveWorktreeOnTeardown,
34459
34754
  shouldResetSessionForOccupancy,
34755
+ shouldRunHistoryCleanup,
34460
34756
  shouldRunWorktreeCleanup,
34461
34757
  shouldStampSetupLastError,
34462
34758
  showCostEnabled,