@sideboard-ai/core 0.1.207 → 0.1.209

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-G3MWSZVM.js} +4 -4
  2. package/dist/{abletime-UWSSLXH3.js → abletime-SQREWITG.js} +4 -4
  3. package/dist/{abletime-oauth-UZHPB3W2.js → abletime-oauth-7AOE4KJL.js} +3 -3
  4. package/dist/{abletime-oauth-C3BQXKW3.js → abletime-oauth-SQD6K47H.js} +3 -3
  5. package/dist/{abletime-rest-5YPPEOKK.js → abletime-rest-BXL7QHCX.js} +3 -3
  6. package/dist/{abletime-rest-HYNYDYK3.js → abletime-rest-QRTJH42S.js} +3 -3
  7. package/dist/agents/cursor-runner.js +3 -3
  8. package/dist/{agents-7MULGRPU.js → agents-KA6HDNNP.js} +6 -5
  9. package/dist/{agents-KCBCFMFW.js → agents-U2NVCYGC.js} +6 -5
  10. package/dist/{app-settings-R2KNCT37.js → app-settings-6SZLZNA7.js} +7 -1
  11. package/dist/{app-settings-GJ6KDYEF.js → app-settings-VBQHGX5Z.js} +7 -1
  12. package/dist/{chunk-6KH4OBEW.js → chunk-22A45QOI.js} +2 -2
  13. package/dist/{chunk-N4A4NWFO.js → chunk-42VGWRSE.js} +2 -2
  14. package/dist/{chunk-X45BV4VX.js → chunk-5LFD3KCJ.js} +5 -5
  15. package/dist/{chunk-F4LZUEIO.js → chunk-B2RPIHNJ.js} +2 -2
  16. package/dist/{chunk-6YZLSZLK.js → chunk-CQZCXRVG.js} +3 -3
  17. package/dist/{chunk-4EGK47WV.js → chunk-FUC3XFE2.js} +215 -0
  18. package/dist/{chunk-5UQTT4S7.js → chunk-HBL7ILQA.js} +154 -31
  19. package/dist/{chunk-TEDEVD4O.js → chunk-IIENQFJ6.js} +2 -2
  20. package/dist/{chunk-6J4OQ6TF.js → chunk-IOOL3T7Q.js} +3 -3
  21. package/dist/{chunk-A2BRWIEM.js → chunk-KJAHVQL6.js} +51 -94
  22. package/dist/{chunk-ZU7R35NY.js → chunk-MS2P5GXL.js} +49 -87
  23. package/dist/{chunk-2GPZ4BAU.js → chunk-MZP2C4KE.js} +158 -31
  24. package/dist/{chunk-ARR4OGLY.js → chunk-OY7THBLG.js} +12 -2
  25. package/dist/{chunk-QOJB5PC7.js → chunk-PTOIWKDU.js} +3 -3
  26. package/dist/{chunk-W6X4GZJG.js → chunk-QVVJO4GN.js} +3 -3
  27. package/dist/{chunk-DWGEBZ3C.js → chunk-RPZFNKND.js} +12 -2
  28. package/dist/{chunk-PAQPT3JO.js → chunk-TZCWNRMC.js} +3 -3
  29. package/dist/{chunk-Y4CF7LHH.js → chunk-VJQDUD24.js} +230 -0
  30. package/dist/chunk-X5B3OS5I.js +34 -0
  31. package/dist/{chunk-WXWJ5MJ4.js → chunk-XRIF6M5H.js} +5 -5
  32. package/dist/{coordinator-prompt-6NV2IHEX.js → coordinator-prompt-2YCOE5R4.js} +5 -4
  33. package/dist/{coordinator-prompt-6A3D7BV3.js → coordinator-prompt-EO2X2EYW.js} +5 -4
  34. package/dist/{cursor-recover-TXVTLAMA.js → cursor-recover-4PQAADAU.js} +3 -28
  35. package/dist/{global-workspace-I2X6UQMX.js → global-workspace-H2ANUSGR.js} +5 -4
  36. package/dist/{global-workspace-VS6HZF2I.js → global-workspace-JEKMVE42.js} +5 -4
  37. package/dist/index.cjs +752 -391
  38. package/dist/index.d.cts +127 -5
  39. package/dist/index.d.ts +127 -5
  40. package/dist/index.js +63 -19
  41. package/dist/mcp/run-stdio.cjs +706 -391
  42. package/dist/mcp/run-stdio.js +12 -11
  43. package/dist/{orchestrator-CXQY5YRG.js → orchestrator-N7LLTK5O.js} +7 -6
  44. package/dist/{orchestrator-7WF32ZXJ.js → orchestrator-RUQXDYM7.js} +7 -6
  45. package/dist/{thread-store-XGYWXR2P.js → thread-store-55X2JYDT.js} +2 -1
  46. package/dist/{thread-store-LS2T6RVH.js → thread-store-CMZWM5NY.js} +2 -1
  47. package/dist/{workspaces-CEU25ANO.js → workspaces-2YNYLSPV.js} +5 -4
  48. package/dist/{workspaces-7PM7UGLG.js → workspaces-SVDORZEI.js} +5 -4
  49. package/dist/{worktree-YD7Y6NRY.js → worktree-5CPGB4D2.js} +4 -3
  50. package/dist/{worktree-T6PCOIHZ.js → worktree-YQ6XUSR2.js} +4 -3
  51. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -991,6 +991,180 @@ 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 updated = Date.parse(thread.updatedAt);
1091
+ if (Number.isFinite(updated)) return updated;
1092
+ const created = Date.parse(thread.createdAt);
1093
+ return Number.isFinite(created) ? created : 0;
1094
+ }
1095
+ function isHistoryRetentionStub(thread) {
1096
+ if ((thread.attachments?.length ?? 0) > 0) return false;
1097
+ const messages = thread.messages ?? [];
1098
+ if (messages.length === 0) return true;
1099
+ if (messages.length > 1) return false;
1100
+ const only = messages[0];
1101
+ if (only.parts?.length) return false;
1102
+ if ((only.attachments?.length ?? 0) > 0) return false;
1103
+ const text7 = (only.text ?? "").trim();
1104
+ return text7 === "" || text7 === HISTORY_DISCARDED_TEXT;
1105
+ }
1106
+ function historyRetentionStubMessage(thread) {
1107
+ const usage = sumUsageList((thread.messages ?? []).map((m) => m.usage));
1108
+ return {
1109
+ role: "summary",
1110
+ text: HISTORY_DISCARDED_TEXT,
1111
+ ts: thread.updatedAt,
1112
+ ...usage ? { usage } : {}
1113
+ };
1114
+ }
1115
+ function sortArchivedOldestFirst(threads) {
1116
+ return [...threads].sort((a, b) => archivedUpdatedMs(a) - archivedUpdatedMs(b));
1117
+ }
1118
+ function planHistoryRetention(archived, thresholds = {}) {
1119
+ const maxCount = clampHistoryMaxCount(thresholds.maxCount ?? HISTORY_MAX_COUNT_DEFAULT);
1120
+ const maxDays = clampHistoryMaxDays(thresholds.maxDays ?? HISTORY_MAX_DAYS_DEFAULT);
1121
+ const nowMs = thresholds.nowMs ?? Date.now();
1122
+ const oldestFirst = sortArchivedOldestFirst(archived);
1123
+ const expiredIds = /* @__PURE__ */ new Set();
1124
+ if (maxDays > 0) {
1125
+ const cutoff = nowMs - maxDays * 864e5;
1126
+ for (const thread of oldestFirst) {
1127
+ if (archivedUpdatedMs(thread) < cutoff) expiredIds.add(thread.id);
1128
+ }
1129
+ }
1130
+ const remaining = oldestFirst.filter((t) => !expiredIds.has(t.id));
1131
+ const overflow = remaining.length > maxCount ? remaining.slice(0, remaining.length - maxCount) : [];
1132
+ const stripIds = [];
1133
+ const purgeIds = [...expiredIds];
1134
+ const seenPurge = new Set(purgeIds);
1135
+ for (const thread of overflow) {
1136
+ if (isHistoryRetentionStub(thread)) {
1137
+ if (!seenPurge.has(thread.id)) {
1138
+ seenPurge.add(thread.id);
1139
+ purgeIds.push(thread.id);
1140
+ }
1141
+ } else {
1142
+ stripIds.push(thread.id);
1143
+ }
1144
+ }
1145
+ return { stripIds, purgeIds };
1146
+ }
1147
+ function planHistoryAgePurge(archived, olderThanDays, nowMs = Date.now()) {
1148
+ const days = clampHistoryMaxDays(olderThanDays);
1149
+ if (days <= 0) return [];
1150
+ const cutoff = nowMs - days * 864e5;
1151
+ return sortArchivedOldestFirst(archived).filter((t) => archivedUpdatedMs(t) < cutoff).map((t) => t.id);
1152
+ }
1153
+ 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;
1154
+ var init_history_retention = __esm({
1155
+ "src/store/history-retention.ts"() {
1156
+ "use strict";
1157
+ init_usage();
1158
+ HISTORY_MAX_COUNT_DEFAULT = 200;
1159
+ HISTORY_MAX_COUNT_MIN = 1;
1160
+ HISTORY_MAX_COUNT_MAX = 2e3;
1161
+ HISTORY_MAX_DAYS_DEFAULT = 0;
1162
+ HISTORY_MAX_DAYS_MAX = 3650;
1163
+ HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT = 6;
1164
+ HISTORY_DISCARDED_TEXT = "Transcript discarded by History retention.";
1165
+ }
1166
+ });
1167
+
994
1168
  // src/store/usage-on-limit.ts
995
1169
  function isUsageOnLimit(value) {
996
1170
  return value === "keep_going" || value === "confirm" || value === "switch_agent" || value === "wait_reset";
@@ -1047,6 +1221,7 @@ __export(app_settings_exports, {
1047
1221
  appSettingsPath: () => appSettingsPath,
1048
1222
  applyAppEnvironment: () => applyAppEnvironment,
1049
1223
  autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
1224
+ autoCleanupHistoryEnabled: () => autoCleanupHistoryEnabled,
1050
1225
  autoCleanupOrphansEnabled: () => autoCleanupOrphansEnabled,
1051
1226
  autoRenameBranchEnabled: () => autoRenameBranchEnabled,
1052
1227
  autoRunAfterSetupEnabled: () => autoRunAfterSetupEnabled,
@@ -1087,6 +1262,8 @@ __export(app_settings_exports, {
1087
1262
  getLinearApiKey: () => getLinearApiKey,
1088
1263
  gitBranchPrefixSetting: () => gitBranchPrefixSetting,
1089
1264
  harnessEnvKey: () => harnessEnvKey,
1265
+ historyMaxCount: () => historyMaxCount,
1266
+ historyMaxDays: () => historyMaxDays,
1090
1267
  isAbleTimeConnected: () => isAbleTimeConnected,
1091
1268
  isIssueSourceConnected: () => isIssueSourceConnected,
1092
1269
  isLinearConnected: () => isLinearConnected,
@@ -1532,6 +1709,24 @@ function normalizeAdvanced(raw) {
1532
1709
  if (typeof source.autoCleanupOrphans === "boolean") {
1533
1710
  out.autoCleanupOrphans = source.autoCleanupOrphans;
1534
1711
  }
1712
+ if (typeof source.autoCleanupHistory === "boolean") {
1713
+ out.autoCleanupHistory = source.autoCleanupHistory;
1714
+ }
1715
+ if (typeof source.historyMaxCount === "number" && Number.isFinite(source.historyMaxCount)) {
1716
+ out.historyMaxCount = clampHistoryMaxCount(source.historyMaxCount);
1717
+ }
1718
+ if (typeof source.historyMaxDays === "number" && Number.isFinite(source.historyMaxDays)) {
1719
+ out.historyMaxDays = clampHistoryMaxDays(source.historyMaxDays);
1720
+ }
1721
+ if (typeof source.historyCleanupIntervalHours === "number" && Number.isFinite(source.historyCleanupIntervalHours)) {
1722
+ out.historyCleanupIntervalHours = Math.max(
1723
+ 1,
1724
+ Math.min(168, Math.floor(source.historyCleanupIntervalHours))
1725
+ );
1726
+ }
1727
+ if (typeof source.historyLastCleanupAt === "string" && source.historyLastCleanupAt.trim()) {
1728
+ out.historyLastCleanupAt = source.historyLastCleanupAt.trim();
1729
+ }
1535
1730
  if (source.orchestrationQuotaOnLimit === "switch_agent" || source.orchestrationQuotaOnLimit === "wait_reset") {
1536
1731
  out.orchestrationQuotaOnLimit = source.orchestrationQuotaOnLimit;
1537
1732
  }
@@ -2424,6 +2619,24 @@ function updateAdvancedSettings(patch) {
2424
2619
  if (typeof patch.autoCleanupOrphans === "boolean") {
2425
2620
  advanced.autoCleanupOrphans = patch.autoCleanupOrphans;
2426
2621
  }
2622
+ if (typeof patch.autoCleanupHistory === "boolean") {
2623
+ advanced.autoCleanupHistory = patch.autoCleanupHistory;
2624
+ }
2625
+ if (typeof patch.historyMaxCount === "number" && Number.isFinite(patch.historyMaxCount)) {
2626
+ advanced.historyMaxCount = clampHistoryMaxCount(patch.historyMaxCount);
2627
+ }
2628
+ if (typeof patch.historyMaxDays === "number" && Number.isFinite(patch.historyMaxDays)) {
2629
+ advanced.historyMaxDays = clampHistoryMaxDays(patch.historyMaxDays);
2630
+ }
2631
+ if (typeof patch.historyCleanupIntervalHours === "number" && Number.isFinite(patch.historyCleanupIntervalHours)) {
2632
+ advanced.historyCleanupIntervalHours = Math.max(
2633
+ 1,
2634
+ Math.min(168, Math.floor(patch.historyCleanupIntervalHours))
2635
+ );
2636
+ }
2637
+ if (typeof patch.historyLastCleanupAt === "string") {
2638
+ advanced.historyLastCleanupAt = patch.historyLastCleanupAt;
2639
+ }
2427
2640
  if (patch.orchestrationQuotaOnLimit === "switch_agent" || patch.orchestrationQuotaOnLimit === "wait_reset") {
2428
2641
  advanced.orchestrationQuotaOnLimit = patch.orchestrationQuotaOnLimit;
2429
2642
  }
@@ -2474,6 +2687,15 @@ function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
2474
2687
  function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
2475
2688
  return Boolean(settings.advanced.autoCleanupOrphans);
2476
2689
  }
2690
+ function autoCleanupHistoryEnabled(settings = loadAppSettings()) {
2691
+ return settings.advanced.autoCleanupHistory !== false;
2692
+ }
2693
+ function historyMaxCount(settings = loadAppSettings()) {
2694
+ return clampHistoryMaxCount(settings.advanced.historyMaxCount ?? HISTORY_MAX_COUNT_DEFAULT);
2695
+ }
2696
+ function historyMaxDays(settings = loadAppSettings()) {
2697
+ return clampHistoryMaxDays(settings.advanced.historyMaxDays ?? HISTORY_MAX_DAYS_DEFAULT);
2698
+ }
2477
2699
  function usageOnLimit(settings = loadAppSettings()) {
2478
2700
  return resolveUsageOnLimit(settings.advanced);
2479
2701
  }
@@ -2594,6 +2816,7 @@ var init_app_settings = __esm({
2594
2816
  init_private_file();
2595
2817
  init_secret_vault();
2596
2818
  init_branch_prefix();
2819
+ init_history_retention();
2597
2820
  init_usage_on_limit();
2598
2821
  init_usage_on_limit();
2599
2822
  init_issue_source_labels();
@@ -2814,6 +3037,37 @@ var init_caffeinate_hold = __esm({
2814
3037
  }
2815
3038
  });
2816
3039
 
3040
+ // src/agents/cursor-store.ts
3041
+ function cursorSdkStoreDir(threadId) {
3042
+ const root = (0, import_node_path10.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
3043
+ const id = sanitizeCursorStoreSegment(threadId);
3044
+ if (!id) return root;
3045
+ return (0, import_node_path10.join)(root, "threads", id);
3046
+ }
3047
+ function cursorSdkRunsNdjsonPath(threadId) {
3048
+ return (0, import_node_path10.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
3049
+ }
3050
+ function cursorSdkRunsNdjsonSearchPaths(threadId) {
3051
+ const scoped = cursorSdkRunsNdjsonPath(threadId);
3052
+ const shared = cursorSdkRunsNdjsonPath(null);
3053
+ if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
3054
+ return [shared];
3055
+ }
3056
+ return [scoped, shared];
3057
+ }
3058
+ function sanitizeCursorStoreSegment(threadId) {
3059
+ return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
3060
+ }
3061
+ var import_node_path10, CURSOR_SDK_STORE_DIR;
3062
+ var init_cursor_store = __esm({
3063
+ "src/agents/cursor-store.ts"() {
3064
+ "use strict";
3065
+ import_node_path10 = require("path");
3066
+ init_paths();
3067
+ CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
3068
+ }
3069
+ });
3070
+
2817
3071
  // src/store/thread-store.ts
2818
3072
  var thread_store_exports = {};
2819
3073
  __export(thread_store_exports, {
@@ -2854,6 +3108,7 @@ function normalizeThread(raw) {
2854
3108
  lastError: raw.lastError ?? null,
2855
3109
  agentPid: raw.agentPid ?? null,
2856
3110
  attachments: Array.isArray(raw.attachments) ? raw.attachments : [],
3111
+ pendingTurnAttachments: Array.isArray(raw.pendingTurnAttachments) ? raw.pendingTurnAttachments : [],
2857
3112
  prTitle: raw.prTitle ?? null,
2858
3113
  prState: raw.prState ?? null,
2859
3114
  prIsDraft: Boolean(raw.prIsDraft),
@@ -2896,6 +3151,7 @@ function createEmptyThread(partial) {
2896
3151
  userSetTitle: partial.userSetTitle ?? false,
2897
3152
  messages: partial.messages ?? [],
2898
3153
  attachments: partial.attachments ?? [],
3154
+ pendingTurnAttachments: partial.pendingTurnAttachments ?? [],
2899
3155
  createdAt: ts,
2900
3156
  updatedAt: ts,
2901
3157
  title: partial.title,
@@ -2969,10 +3225,10 @@ function readThread(id) {
2969
3225
  rememberThread(thread, mtimeMs);
2970
3226
  return thread;
2971
3227
  }
2972
- function writeThread(thread) {
3228
+ function writeThread(thread, opts) {
2973
3229
  const path2 = threadFilePath(idPath(thread.id));
2974
3230
  const tmp = `${path2}.${process.pid}.tmp`;
2975
- const next = { ...thread, updatedAt: nowIso() };
3231
+ const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
2976
3232
  (0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
2977
3233
  (0, import_node_fs9.renameSync)(tmp, path2);
2978
3234
  rememberThread(next, fileMtimeMs(path2) ?? Date.now());
@@ -2981,7 +3237,7 @@ function idPath(id) {
2981
3237
  return id;
2982
3238
  }
2983
3239
  function isThreadRecordFile(nameOrPath) {
2984
- const name = (0, import_node_path10.basename)(nameOrPath);
3240
+ const name = (0, import_node_path11.basename)(nameOrPath);
2985
3241
  return name.endsWith(".json") && !name.endsWith(".live.json");
2986
3242
  }
2987
3243
  function listThreads(opts) {
@@ -3017,6 +3273,10 @@ function deleteThreadRecord(id) {
3017
3273
  } catch {
3018
3274
  }
3019
3275
  }
3276
+ try {
3277
+ (0, import_node_fs9.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
3278
+ } catch {
3279
+ }
3020
3280
  }
3021
3281
  function updateThread(id, patch) {
3022
3282
  const current = readThread(id);
@@ -3039,15 +3299,16 @@ function findThreadByRef(ref) {
3039
3299
  (t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
3040
3300
  ) ?? null;
3041
3301
  }
3042
- var import_node_crypto3, import_node_fs9, import_node_path10, import_proper_lockfile, listCache;
3302
+ var import_node_crypto3, import_node_fs9, import_node_path11, import_proper_lockfile, listCache;
3043
3303
  var init_thread_store = __esm({
3044
3304
  "src/store/thread-store.ts"() {
3045
3305
  "use strict";
3046
3306
  import_node_crypto3 = require("crypto");
3047
3307
  import_node_fs9 = require("fs");
3048
- import_node_path10 = require("path");
3308
+ import_node_path11 = require("path");
3049
3309
  import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
3050
3310
  init_thinking_effort();
3311
+ init_cursor_store();
3051
3312
  init_paths();
3052
3313
  listCache = null;
3053
3314
  }
@@ -3785,6 +4046,28 @@ function clipThinkingForStore(text7, max = THINKING_PART_MAX_CHARS) {
3785
4046
  const marker = "\u2026(earlier thinking trimmed)\n";
3786
4047
  return marker + text7.slice(text7.length - Math.max(1, max - marker.length));
3787
4048
  }
4049
+ function clipEventTail(text7, max) {
4050
+ if (text7.length <= max) return text7;
4051
+ const marker = "\u2026(truncated)\n";
4052
+ return marker + text7.slice(text7.length - Math.max(1, max - marker.length));
4053
+ }
4054
+ function clipAgentEventForPaint(event) {
4055
+ if (event.type === "tool_result" && event.content) {
4056
+ const content = clipToolResultForStore(event.content);
4057
+ if (content === event.content) return event;
4058
+ return { ...event, content };
4059
+ }
4060
+ if (event.type === "thinking" && event.data.length > THINKING_PART_MAX_CHARS) {
4061
+ return { ...event, data: clipThinkingForStore(event.data) };
4062
+ }
4063
+ if (event.type === "stdout" && event.data.length > STDOUT_EVENT_MAX_CHARS) {
4064
+ return { ...event, data: clipEventTail(event.data, STDOUT_EVENT_MAX_CHARS) };
4065
+ }
4066
+ if (event.type === "stderr" && event.data.length > STDERR_EVENT_MAX_CHARS) {
4067
+ return { ...event, data: clipEventTail(event.data, STDERR_EVENT_MAX_CHARS) };
4068
+ }
4069
+ return event;
4070
+ }
3788
4071
  function withPartTimes(next, prev) {
3789
4072
  const now = Date.now();
3790
4073
  const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
@@ -4011,7 +4294,7 @@ function normalizeParseResult(parsed) {
4011
4294
  if (!parsed) return [];
4012
4295
  return Array.isArray(parsed) ? parsed : [parsed];
4013
4296
  }
4014
- var CHAT_DETAIL_MAX, SHELL_BIN_DIR, THINKING_PART_MAX_CHARS;
4297
+ var CHAT_DETAIL_MAX, SHELL_BIN_DIR, THINKING_PART_MAX_CHARS, STDOUT_EVENT_MAX_CHARS, STDERR_EVENT_MAX_CHARS;
4015
4298
  var init_message_parts = __esm({
4016
4299
  "src/agents/message-parts.ts"() {
4017
4300
  "use strict";
@@ -4019,93 +4302,8 @@ var init_message_parts = __esm({
4019
4302
  CHAT_DETAIL_MAX = 72;
4020
4303
  SHELL_BIN_DIR = /^(?:\/usr\/local\/bin|\/usr\/bin|\/bin|\/opt\/homebrew\/bin|\/sbin|\/usr\/sbin)\//;
4021
4304
  THINKING_PART_MAX_CHARS = 64e3;
4022
- }
4023
- });
4024
-
4025
- // src/agents/usage.ts
4026
- function sumOptional(a, b) {
4027
- if (a == null && b == null) return void 0;
4028
- return (a ?? 0) + (b ?? 0);
4029
- }
4030
- function fromInclusiveInputUsage(opts) {
4031
- const totalInput = Number(opts.inputTokens) || 0;
4032
- const outputTokens = Number(opts.outputTokens) || 0;
4033
- const cached = Number(opts.cachedInputTokens) || 0;
4034
- if (!totalInput && !outputTokens) return null;
4035
- const cacheReadTokens = cached > 0 ? Math.min(cached, totalInput) : 0;
4036
- return {
4037
- inputTokens: Math.max(0, totalInput - cacheReadTokens),
4038
- outputTokens,
4039
- cacheReadTokens: cacheReadTokens || void 0
4040
- };
4041
- }
4042
- function requestOccupancy(u) {
4043
- return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
4044
- }
4045
- function mergeUsage(a, b) {
4046
- return {
4047
- inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
4048
- outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
4049
- cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
4050
- cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
4051
- costUsd: sumOptional(a?.costUsd, b.costUsd),
4052
- lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
4053
- };
4054
- }
4055
- function sumUsageList(list) {
4056
- let acc = null;
4057
- for (const u of list) {
4058
- if (!u) continue;
4059
- acc = mergeUsage(acc, {
4060
- inputTokens: u.inputTokens,
4061
- outputTokens: u.outputTokens,
4062
- cacheReadTokens: u.cacheReadTokens,
4063
- cacheWriteTokens: u.cacheWriteTokens,
4064
- costUsd: u.costUsd
4065
- });
4066
- }
4067
- if (!acc) return null;
4068
- return {
4069
- inputTokens: acc.inputTokens,
4070
- outputTokens: acc.outputTokens,
4071
- ...acc.cacheReadTokens != null ? { cacheReadTokens: acc.cacheReadTokens } : {},
4072
- ...acc.cacheWriteTokens != null ? { cacheWriteTokens: acc.cacheWriteTokens } : {},
4073
- ...acc.costUsd != null ? { costUsd: acc.costUsd } : {}
4074
- };
4075
- }
4076
- function hasBilledTokens(u) {
4077
- return Boolean(
4078
- u.inputTokens || u.outputTokens || u.cacheReadTokens || u.cacheWriteTokens
4079
- );
4080
- }
4081
- function applyTurnUsage(current, incoming, scope = "request") {
4082
- if (scope === "turn") {
4083
- if (!hasBilledTokens(incoming) && current && incoming.costUsd != null) {
4084
- return { ...current, costUsd: incoming.costUsd };
4085
- }
4086
- return {
4087
- ...incoming,
4088
- costUsd: incoming.costUsd ?? current?.costUsd,
4089
- lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
4090
- };
4091
- }
4092
- const merged = mergeUsage(current, incoming);
4093
- const occ = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : requestOccupancy(incoming);
4094
- return {
4095
- ...merged,
4096
- lastRequestTokens: occ > 0 ? occ : current?.lastRequestTokens ?? occ
4097
- };
4098
- }
4099
- function totalTokens(u) {
4100
- return u.inputTokens + u.outputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
4101
- }
4102
- function contextTokens(u) {
4103
- if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
4104
- return requestOccupancy(u);
4105
- }
4106
- var init_usage = __esm({
4107
- "src/agents/usage.ts"() {
4108
- "use strict";
4305
+ STDOUT_EVENT_MAX_CHARS = 16e3;
4306
+ STDERR_EVENT_MAX_CHARS = 4e3;
4109
4307
  }
4110
4308
  });
4111
4309
 
@@ -5548,7 +5746,7 @@ ${line}` : line;
5548
5746
  return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
5549
5747
  }
5550
5748
  function setupLogPath(threadId) {
5551
- return (0, import_node_path11.join)(threadsDir(), `${threadId}.setup.log.json`);
5749
+ return (0, import_node_path12.join)(threadsDir(), `${threadId}.setup.log.json`);
5552
5750
  }
5553
5751
  function setupLogKeyForWorktree(worktreePath) {
5554
5752
  const norm = normalizeWorktreePath(worktreePath);
@@ -5651,13 +5849,13 @@ function finishSetupLog(threadId, exitCode, source) {
5651
5849
  persistNow(threadId);
5652
5850
  return clone(snap);
5653
5851
  }
5654
- var import_node_crypto4, import_node_fs10, import_node_path11, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
5852
+ var import_node_crypto4, import_node_fs10, import_node_path12, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
5655
5853
  var init_setup_log = __esm({
5656
5854
  "src/store/setup-log.ts"() {
5657
5855
  "use strict";
5658
5856
  import_node_crypto4 = require("crypto");
5659
5857
  import_node_fs10 = require("fs");
5660
- import_node_path11 = require("path");
5858
+ import_node_path12 = require("path");
5661
5859
  init_worktree_labels();
5662
5860
  init_paths();
5663
5861
  EMPTY = {
@@ -5674,7 +5872,7 @@ var init_setup_log = __esm({
5674
5872
 
5675
5873
  // src/store/schedules.ts
5676
5874
  function schedulesPath() {
5677
- return (0, import_node_path12.join)(appDataDir(), "schedules.json");
5875
+ return (0, import_node_path13.join)(appDataDir(), "schedules.json");
5678
5876
  }
5679
5877
  function parseDurationMs(every) {
5680
5878
  const m = every.trim().match(DURATION_RE);
@@ -5897,13 +6095,13 @@ function recordScheduleRun(id, result) {
5897
6095
  writeAll(rows);
5898
6096
  return next;
5899
6097
  }
5900
- var import_node_crypto5, import_node_fs11, import_node_path12, import_croner, DURATION_RE, UNIT_MS;
6098
+ var import_node_crypto5, import_node_fs11, import_node_path13, import_croner, DURATION_RE, UNIT_MS;
5901
6099
  var init_schedules = __esm({
5902
6100
  "src/store/schedules.ts"() {
5903
6101
  "use strict";
5904
6102
  import_node_crypto5 = require("crypto");
5905
6103
  import_node_fs11 = require("fs");
5906
- import_node_path12 = require("path");
6104
+ import_node_path13 = require("path");
5907
6105
  import_croner = require("croner");
5908
6106
  init_orchestrator_capable();
5909
6107
  init_paths();
@@ -5920,7 +6118,7 @@ var init_schedules = __esm({
5920
6118
 
5921
6119
  // src/store/desktop-host.ts
5922
6120
  function desktopHostPidPath() {
5923
- return (0, import_node_path13.join)(appDataDir(), "desktop-host.pid");
6121
+ return (0, import_node_path14.join)(appDataDir(), "desktop-host.pid");
5924
6122
  }
5925
6123
  function claimDesktopHost(pid = process.pid) {
5926
6124
  (0, import_node_fs12.writeFileSync)(desktopHostPidPath(), `${pid}
@@ -5961,12 +6159,12 @@ function thisProcessShouldDrainAgentQueues() {
5961
6159
  if (isThisProcessDesktopHost()) return true;
5962
6160
  return !isDesktopHostAlive();
5963
6161
  }
5964
- var import_node_fs12, import_node_path13;
6162
+ var import_node_fs12, import_node_path14;
5965
6163
  var init_desktop_host = __esm({
5966
6164
  "src/store/desktop-host.ts"() {
5967
6165
  "use strict";
5968
6166
  import_node_fs12 = require("fs");
5969
- import_node_path13 = require("path");
6167
+ import_node_path14 = require("path");
5970
6168
  init_paths();
5971
6169
  }
5972
6170
  });
@@ -6033,7 +6231,7 @@ var init_workspace_scratch = __esm({
6033
6231
 
6034
6232
  // src/composer/stage-files.ts
6035
6233
  function fileExtension(filePath) {
6036
- const base = (0, import_node_path14.basename)(filePath).toLowerCase();
6234
+ const base = (0, import_node_path15.basename)(filePath).toLowerCase();
6037
6235
  return base.includes(".") ? base.split(".").pop() || "" : "";
6038
6236
  }
6039
6237
  function isImageFilePath(filePath) {
@@ -6043,9 +6241,9 @@ function imageMimeType(filePath) {
6043
6241
  return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
6044
6242
  }
6045
6243
  function ensureAttachmentsDir(worktreePath) {
6046
- const dir = (0, import_node_path14.join)(worktreePath, ATTACHMENTS_DIR);
6244
+ const dir = (0, import_node_path15.join)(worktreePath, ATTACHMENTS_DIR);
6047
6245
  (0, import_node_fs13.mkdirSync)(dir, { recursive: true });
6048
- const gi = (0, import_node_path14.join)(dir, ".gitignore");
6246
+ const gi = (0, import_node_path15.join)(dir, ".gitignore");
6049
6247
  if (!(0, import_node_fs13.existsSync)(gi)) {
6050
6248
  (0, import_node_fs13.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
6051
6249
  }
@@ -6053,12 +6251,12 @@ function ensureAttachmentsDir(worktreePath) {
6053
6251
  }
6054
6252
  function uniqueAttachmentName(dir, originalName) {
6055
6253
  const safe = originalName.replace(/[/\\]/g, "_") || "file";
6056
- if (!(0, import_node_fs13.existsSync)((0, import_node_path14.join)(dir, safe))) return safe;
6057
- const ext = (0, import_node_path14.extname)(safe);
6254
+ if (!(0, import_node_fs13.existsSync)((0, import_node_path15.join)(dir, safe))) return safe;
6255
+ const ext = (0, import_node_path15.extname)(safe);
6058
6256
  const stem = ext ? safe.slice(0, -ext.length) : safe;
6059
6257
  for (let i = 1; i < 1e4; i++) {
6060
6258
  const candidate = `${stem}-${i}${ext}`;
6061
- if (!(0, import_node_fs13.existsSync)((0, import_node_path14.join)(dir, candidate))) return candidate;
6259
+ if (!(0, import_node_fs13.existsSync)((0, import_node_path15.join)(dir, candidate))) return candidate;
6062
6260
  }
6063
6261
  return `${stem}-${(0, import_node_crypto6.randomUUID)()}${ext}`;
6064
6262
  }
@@ -6110,7 +6308,7 @@ function attachmentFromBuffer(name, buf, opts) {
6110
6308
  };
6111
6309
  }
6112
6310
  function attachmentFromAbsolutePath(absolutePath) {
6113
- const name = (0, import_node_path14.basename)(absolutePath);
6311
+ const name = (0, import_node_path15.basename)(absolutePath);
6114
6312
  try {
6115
6313
  const st = (0, import_node_fs13.statSync)(absolutePath);
6116
6314
  if (!st.isFile()) {
@@ -6137,12 +6335,12 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
6137
6335
  const dir = ensureAttachmentsDir(worktreePath);
6138
6336
  const out = [];
6139
6337
  for (const abs of absolutePaths) {
6140
- const originalName = (0, import_node_path14.basename)(abs);
6338
+ const originalName = (0, import_node_path15.basename)(abs);
6141
6339
  try {
6142
6340
  const st = (0, import_node_fs13.statSync)(abs);
6143
6341
  if (!st.isFile()) continue;
6144
6342
  const name = uniqueAttachmentName(dir, originalName);
6145
- const destAbs = (0, import_node_path14.join)(dir, name);
6343
+ const destAbs = (0, import_node_path15.join)(dir, name);
6146
6344
  (0, import_node_fs13.copyFileSync)(abs, destAbs);
6147
6345
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6148
6346
  const buf = (0, import_node_fs13.readFileSync)(destAbs);
@@ -6167,7 +6365,7 @@ function stageBuffersAsAttachments(worktreePath, buffers2) {
6167
6365
  try {
6168
6366
  const buf = Buffer.from(item.dataBase64, "base64");
6169
6367
  const name = uniqueAttachmentName(dir, originalName);
6170
- const destAbs = (0, import_node_path14.join)(dir, name);
6368
+ const destAbs = (0, import_node_path15.join)(dir, name);
6171
6369
  (0, import_node_fs13.writeFileSync)(destAbs, buf);
6172
6370
  const rel = `${ATTACHMENTS_DIR}/${name}`;
6173
6371
  out.push(attachmentFromBuffer(name, buf, { path: rel }));
@@ -6245,15 +6443,15 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6245
6443
  if (!rel || rel.includes("..") || rel.startsWith("/")) {
6246
6444
  out.push({
6247
6445
  id: (0, import_node_crypto6.randomUUID)(),
6248
- name: (0, import_node_path14.basename)(rel) || "file",
6446
+ name: (0, import_node_path15.basename)(rel) || "file",
6249
6447
  kind: "file",
6250
6448
  content: `(invalid path: ${rel})`
6251
6449
  });
6252
6450
  continue;
6253
6451
  }
6254
- const name = (0, import_node_path14.basename)(rel);
6452
+ const name = (0, import_node_path15.basename)(rel);
6255
6453
  try {
6256
- const abs = (0, import_node_path14.join)(worktreePath, rel);
6454
+ const abs = (0, import_node_path15.join)(worktreePath, rel);
6257
6455
  const st = (0, import_node_fs13.statSync)(abs);
6258
6456
  if (!st.isFile()) continue;
6259
6457
  const buf = (0, import_node_fs13.readFileSync)(abs);
@@ -6269,12 +6467,12 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
6269
6467
  }
6270
6468
  return out;
6271
6469
  }
6272
- 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;
6470
+ 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;
6273
6471
  var init_stage_files = __esm({
6274
6472
  "src/composer/stage-files.ts"() {
6275
6473
  "use strict";
6276
6474
  import_node_fs13 = require("fs");
6277
- import_node_path14 = require("path");
6475
+ import_node_path15 = require("path");
6278
6476
  import_node_crypto6 = require("crypto");
6279
6477
  init_workspace_scratch();
6280
6478
  IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -6418,15 +6616,15 @@ var init_gh_errors = __esm({
6418
6616
  function prependPathDir(env, dir) {
6419
6617
  if (!dir || !(0, import_node_fs14.existsSync)(dir)) return;
6420
6618
  const current = env.PATH ?? "";
6421
- const parts = current.split(import_node_path15.delimiter).filter(Boolean);
6619
+ const parts = current.split(import_node_path16.delimiter).filter(Boolean);
6422
6620
  if (parts.includes(dir)) {
6423
6621
  env.PATH = current;
6424
6622
  return;
6425
6623
  }
6426
- env.PATH = [dir, ...parts].join(import_node_path15.delimiter);
6624
+ env.PATH = [dir, ...parts].join(import_node_path16.delimiter);
6427
6625
  }
6428
6626
  function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os4.homedir)()) {
6429
- return (0, import_node_path15.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6627
+ return (0, import_node_path16.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
6430
6628
  }
6431
6629
  function isConductorBundledCli(filePath) {
6432
6630
  const p = (filePath ?? "").replace(/\\/g, "/");
@@ -6435,10 +6633,10 @@ function isConductorBundledCli(filePath) {
6435
6633
  function ensureAgentPath(env = process.env) {
6436
6634
  const home = env.HOME || env.USERPROFILE || (0, import_node_os4.homedir)();
6437
6635
  const current = env.PATH ?? "";
6438
- const parts = current.split(import_node_path15.delimiter).filter(Boolean);
6636
+ const parts = current.split(import_node_path16.delimiter).filter(Boolean);
6439
6637
  const seen = new Set(parts);
6440
6638
  const extras = [
6441
- ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path15.join)(home, rel)),
6639
+ ...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path16.join)(home, rel)),
6442
6640
  "/opt/homebrew/bin",
6443
6641
  "/usr/local/bin",
6444
6642
  // Keep after Homebrew/npm so a user-installed CLI still wins.
@@ -6449,7 +6647,7 @@ function ensureAgentPath(env = process.env) {
6449
6647
  parts.unshift(dir);
6450
6648
  seen.add(dir);
6451
6649
  }
6452
- const next = parts.join(import_node_path15.delimiter);
6650
+ const next = parts.join(import_node_path16.delimiter);
6453
6651
  env.PATH = next;
6454
6652
  return next;
6455
6653
  }
@@ -6463,7 +6661,7 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
6463
6661
  stdio: ["ignore", "pipe", "ignore"]
6464
6662
  }).trim().split(/\r?\n/).find(Boolean);
6465
6663
  if (prefix) {
6466
- const binDir = process.platform === "win32" ? prefix : (0, import_node_path15.join)(prefix, "bin");
6664
+ const binDir = process.platform === "win32" ? prefix : (0, import_node_path16.join)(prefix, "bin");
6467
6665
  prependPathDir(env, binDir);
6468
6666
  }
6469
6667
  } catch {
@@ -6491,14 +6689,14 @@ function withExportedPath(command, pathValue) {
6491
6689
  if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
6492
6690
  return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
6493
6691
  }
6494
- var import_node_fs14, import_node_child_process3, import_node_os4, import_node_path15, EXTRA_BIN_DIRS;
6692
+ var import_node_fs14, import_node_child_process3, import_node_os4, import_node_path16, EXTRA_BIN_DIRS;
6495
6693
  var init_path = __esm({
6496
6694
  "src/agents/path.ts"() {
6497
6695
  "use strict";
6498
6696
  import_node_fs14 = require("fs");
6499
6697
  import_node_child_process3 = require("child_process");
6500
6698
  import_node_os4 = require("os");
6501
- import_node_path15 = require("path");
6699
+ import_node_path16 = require("path");
6502
6700
  EXTRA_BIN_DIRS = [
6503
6701
  ".local/bin",
6504
6702
  ".cargo/bin",
@@ -6519,18 +6717,18 @@ var init_path = __esm({
6519
6717
  function githubAgentAuthDir() {
6520
6718
  const override = process.env.SIDEBOARD_GIT_AUTH_DIR?.trim();
6521
6719
  if (override) return override;
6522
- return (0, import_node_path16.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6720
+ return (0, import_node_path17.join)((0, import_node_os5.homedir)(), ".sideboard-git-auth");
6523
6721
  }
6524
6722
  function githubCredentialStorePath() {
6525
- return (0, import_node_path16.join)(githubAgentAuthDir(), "git-credentials");
6723
+ return (0, import_node_path17.join)(githubAgentAuthDir(), "git-credentials");
6526
6724
  }
6527
6725
  function githubGhConfigDir() {
6528
- return (0, import_node_path16.join)(githubAgentAuthDir(), "gh");
6726
+ return (0, import_node_path17.join)(githubAgentAuthDir(), "gh");
6529
6727
  }
6530
6728
  function writePrivateFile2(file, body) {
6531
- (0, import_node_fs15.mkdirSync)((0, import_node_path16.dirname)(file), { recursive: true, mode: 448 });
6729
+ (0, import_node_fs15.mkdirSync)((0, import_node_path17.dirname)(file), { recursive: true, mode: 448 });
6532
6730
  try {
6533
- (0, import_node_fs15.chmodSync)((0, import_node_path16.dirname)(file), 448);
6731
+ (0, import_node_fs15.chmodSync)((0, import_node_path17.dirname)(file), 448);
6534
6732
  } catch {
6535
6733
  }
6536
6734
  (0, import_node_fs15.writeFileSync)(file, body, { encoding: "utf8", mode: 384 });
@@ -6568,11 +6766,11 @@ function materializeGithubAgentAuth(token, user) {
6568
6766
  writePrivateFile2(githubCredentialStorePath(), gitCredentialStoreContents(trimmed));
6569
6767
  const ghDir = githubGhConfigDir();
6570
6768
  (0, import_node_fs15.mkdirSync)(ghDir, { recursive: true, mode: 448 });
6571
- writePrivateFile2((0, import_node_path16.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6572
- writePrivateFile2((0, import_node_path16.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6769
+ writePrivateFile2((0, import_node_path17.join)(ghDir, "hosts.yml"), ghHostsYml(trimmed, user));
6770
+ writePrivateFile2((0, import_node_path17.join)(ghDir, "config.yml"), "git_protocol: https\nprompt: disabled\n");
6573
6771
  }
6574
6772
  function githubAgentAuthReady() {
6575
- return (0, import_node_fs15.existsSync)(githubCredentialStorePath()) && (0, import_node_fs15.existsSync)((0, import_node_path16.join)(githubGhConfigDir(), "hosts.yml"));
6773
+ return (0, import_node_fs15.existsSync)(githubCredentialStorePath()) && (0, import_node_fs15.existsSync)((0, import_node_path17.join)(githubGhConfigDir(), "hosts.yml"));
6576
6774
  }
6577
6775
  function githubCredentialHelperGitConfig() {
6578
6776
  const file = githubCredentialStorePath();
@@ -6587,13 +6785,13 @@ function githubGhConfigEnv() {
6587
6785
  GH_PROMPT_DISABLED: "1"
6588
6786
  };
6589
6787
  }
6590
- var import_node_fs15, import_node_os5, import_node_path16;
6788
+ var import_node_fs15, import_node_os5, import_node_path17;
6591
6789
  var init_github_agent_auth = __esm({
6592
6790
  "src/git/github-agent-auth.ts"() {
6593
6791
  "use strict";
6594
6792
  import_node_fs15 = require("fs");
6595
6793
  import_node_os5 = require("os");
6596
- import_node_path16 = require("path");
6794
+ import_node_path17 = require("path");
6597
6795
  }
6598
6796
  });
6599
6797
 
@@ -6602,7 +6800,7 @@ function isIndexLockError(text7) {
6602
6800
  return /Unable to create ['"][^'"]*index\.lock['"]: File exists/i.test(text7);
6603
6801
  }
6604
6802
  function clearStaleIndexLock(gitDir, maxAgeMs = STALE_INDEX_LOCK_MS, now = Date.now()) {
6605
- const lockPath = (0, import_node_path17.join)(gitDir, "index.lock");
6803
+ const lockPath = (0, import_node_path18.join)(gitDir, "index.lock");
6606
6804
  try {
6607
6805
  if (!(0, import_node_fs16.existsSync)(lockPath)) return null;
6608
6806
  if (now - (0, import_node_fs16.statSync)(lockPath).mtimeMs < maxAgeMs) return null;
@@ -6621,12 +6819,12 @@ function clearStaleIndexLocks(gitDirs, maxAgeMs = STALE_INDEX_LOCK_MS) {
6621
6819
  }
6622
6820
  return removed;
6623
6821
  }
6624
- var import_node_fs16, import_node_path17, STALE_INDEX_LOCK_MS;
6822
+ var import_node_fs16, import_node_path18, STALE_INDEX_LOCK_MS;
6625
6823
  var init_stale_lock = __esm({
6626
6824
  "src/git/stale-lock.ts"() {
6627
6825
  "use strict";
6628
6826
  import_node_fs16 = require("fs");
6629
- import_node_path17 = require("path");
6827
+ import_node_path18 = require("path");
6630
6828
  STALE_INDEX_LOCK_MS = 2e4;
6631
6829
  }
6632
6830
  });
@@ -6766,8 +6964,8 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
6766
6964
  if (gitDir.exitCode !== 0) return;
6767
6965
  const dir = gitDir.stdout.trim();
6768
6966
  if (!dir) return;
6769
- const excludePath = (0, import_node_path18.join)(dir, "info", "exclude");
6770
- (0, import_node_fs17.mkdirSync)((0, import_node_path18.dirname)(excludePath), { recursive: true });
6967
+ const excludePath = (0, import_node_path19.join)(dir, "info", "exclude");
6968
+ (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(excludePath), { recursive: true });
6771
6969
  let body = "";
6772
6970
  try {
6773
6971
  body = (0, import_node_fs17.readFileSync)(excludePath, "utf8");
@@ -6801,12 +6999,12 @@ async function ensureWorktreeSideboardIgnored(worktreePath) {
6801
6999
  timeoutMs: 8e3
6802
7000
  });
6803
7001
  }
6804
- var import_node_fs17, import_node_path18, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
7002
+ var import_node_fs17, import_node_path19, WORKTREE_SIDEBOARD_EXCLUDE, WORKTREE_CONTEXT_EXCLUDE, EXCLUDE_COMMENT;
6805
7003
  var init_worktree_exclude = __esm({
6806
7004
  "src/git/worktree-exclude.ts"() {
6807
7005
  "use strict";
6808
7006
  import_node_fs17 = require("fs");
6809
- import_node_path18 = require("path");
7007
+ import_node_path19 = require("path");
6810
7008
  init_run();
6811
7009
  WORKTREE_SIDEBOARD_EXCLUDE = ".sideboard/";
6812
7010
  WORKTREE_CONTEXT_EXCLUDE = ".context/";
@@ -6927,7 +7125,7 @@ async function warmGithubAgentAuth(opts) {
6927
7125
  }
6928
7126
  function normalizeWritableRoot(raw) {
6929
7127
  const trimmed = raw.trim().replace(/\/+$/, "");
6930
- return trimmed && (0, import_node_path19.isAbsolute)(trimmed) ? trimmed : null;
7128
+ return trimmed && (0, import_node_path20.isAbsolute)(trimmed) ? trimmed : null;
6931
7129
  }
6932
7130
  async function resolveCodexGitWritableRoots(cwd) {
6933
7131
  const roots = /* @__PURE__ */ new Set();
@@ -7005,11 +7203,11 @@ function formatGitAuthModeDirective(mode) {
7005
7203
  ].join("\n");
7006
7204
  }
7007
7205
  }
7008
- var import_node_path19, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7206
+ var import_node_path20, HTTPS_REWRITE, TOKEN_TTL_MS, tokenMemo, GITHUB_CHILD_TOKEN_KEYS;
7009
7207
  var init_git_auth_mode = __esm({
7010
7208
  "src/git/git-auth-mode.ts"() {
7011
7209
  "use strict";
7012
- import_node_path19 = require("path");
7210
+ import_node_path20 = require("path");
7013
7211
  init_app_settings();
7014
7212
  init_github_agent_auth();
7015
7213
  init_run();
@@ -8698,7 +8896,7 @@ async function refreshOriginAndMaybeFastForwardMain(repoPath, sourceRef) {
8698
8896
  }
8699
8897
  async function createThreadWorktree(opts) {
8700
8898
  let branchName = `thread/${opts.slug}`;
8701
- const worktreePath = (0, import_node_path20.join)(worktreesRoot(opts.repoPath), opts.slug);
8899
+ const worktreePath = (0, import_node_path21.join)(worktreesRoot(opts.repoPath), opts.slug);
8702
8900
  if ((0, import_node_fs18.existsSync)(worktreePath)) {
8703
8901
  throw new Error(`Worktree already exists at ${worktreePath}`);
8704
8902
  }
@@ -8740,7 +8938,7 @@ ${add.stdout}`;
8740
8938
  async function createExistingBranchWorktree(opts) {
8741
8939
  const branchName = opts.branchName.trim();
8742
8940
  if (!branchName) throw new Error("branch name required");
8743
- const worktreePath = (0, import_node_path20.join)(worktreesRoot(opts.repoPath), opts.slug);
8941
+ const worktreePath = (0, import_node_path21.join)(worktreesRoot(opts.repoPath), opts.slug);
8744
8942
  if ((0, import_node_fs18.existsSync)(worktreePath)) {
8745
8943
  throw new Error(`Worktree already exists at ${worktreePath}`);
8746
8944
  }
@@ -9022,7 +9220,7 @@ async function createOrUpdatePr(worktreePath, opts) {
9022
9220
  const headRef = ghHeadRef(slug, opts.head);
9023
9221
  const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
9024
9222
  const bodyText = clampGithubPrBody(opts.body ?? opts.title);
9025
- const bodyFile = (0, import_node_path20.join)(
9223
+ const bodyFile = (0, import_node_path21.join)(
9026
9224
  (0, import_node_os6.tmpdir)(),
9027
9225
  `sideboard-pr-body-${process.pid}-${(0, import_node_crypto7.randomBytes)(6).toString("hex")}.md`
9028
9226
  );
@@ -9122,7 +9320,7 @@ function sameRepoPath2(a, b) {
9122
9320
  return normalizeWorktreePath(a) === normalizeWorktreePath(b);
9123
9321
  }
9124
9322
  function listLocalThreadBranchSlugs(repoPath) {
9125
- const refsDir = (0, import_node_path20.join)(repoPath, ".git", "refs", "heads", "thread");
9323
+ const refsDir = (0, import_node_path21.join)(repoPath, ".git", "refs", "heads", "thread");
9126
9324
  if (!(0, import_node_fs18.existsSync)(refsDir)) return [];
9127
9325
  try {
9128
9326
  return (0, import_node_fs18.readdirSync)(refsDir).filter((name) => !name.startsWith(".")).map((name) => normalizeTakenSlug(name));
@@ -9159,20 +9357,20 @@ function allocateTeamSlug(repoPath) {
9159
9357
  const taken = collectTakenTeamSlugs(repoPath);
9160
9358
  for (let attempt = 0; attempt < 32; attempt++) {
9161
9359
  const team = allocateTeamName(taken);
9162
- const path2 = (0, import_node_path20.join)(worktreesRoot(repoPath), team.slug);
9360
+ const path2 = (0, import_node_path21.join)(worktreesRoot(repoPath), team.slug);
9163
9361
  if (!(0, import_node_fs18.existsSync)(path2)) return team;
9164
9362
  taken.add(team.slug);
9165
9363
  }
9166
9364
  throw new Error("No available soccer team worktree directories left");
9167
9365
  }
9168
- var import_node_crypto7, import_node_fs18, import_node_os6, import_node_path20, PR_DETAILS_JSON_FIELDS;
9366
+ var import_node_crypto7, import_node_fs18, import_node_os6, import_node_path21, PR_DETAILS_JSON_FIELDS;
9169
9367
  var init_worktree = __esm({
9170
9368
  "src/git/worktree.ts"() {
9171
9369
  "use strict";
9172
9370
  import_node_crypto7 = require("crypto");
9173
9371
  import_node_fs18 = require("fs");
9174
9372
  import_node_os6 = require("os");
9175
- import_node_path20 = require("path");
9373
+ import_node_path21 = require("path");
9176
9374
  init_paths();
9177
9375
  init_thread_store();
9178
9376
  init_teams();
@@ -9224,10 +9422,10 @@ __export(workspaces_exports, {
9224
9422
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads
9225
9423
  });
9226
9424
  function workspacesFile() {
9227
- return (0, import_node_path21.join)(appDataDir(), "workspaces.json");
9425
+ return (0, import_node_path22.join)(appDataDir(), "workspaces.json");
9228
9426
  }
9229
9427
  function removedWorkspacesFile() {
9230
- return (0, import_node_path21.join)(appDataDir(), "removed-workspaces.json");
9428
+ return (0, import_node_path22.join)(appDataDir(), "removed-workspaces.json");
9231
9429
  }
9232
9430
  function readAll2() {
9233
9431
  const path2 = workspacesFile();
@@ -9286,7 +9484,7 @@ async function addWorkspace(repoPath) {
9286
9484
  if (existing) return existing;
9287
9485
  const next = {
9288
9486
  path: root,
9289
- name: (0, import_node_path21.basename)(root),
9487
+ name: (0, import_node_path22.basename)(root),
9290
9488
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9291
9489
  };
9292
9490
  writeAll2([...current, next]);
@@ -9311,7 +9509,7 @@ function syncWorkspacesFromThreads(repoPaths) {
9311
9509
  if (!(0, import_node_fs19.existsSync)(path2)) continue;
9312
9510
  const ws = {
9313
9511
  path: path2,
9314
- name: (0, import_node_path21.basename)(path2),
9512
+ name: (0, import_node_path22.basename)(path2),
9315
9513
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
9316
9514
  };
9317
9515
  byPath.set(path2, ws);
@@ -9321,12 +9519,12 @@ function syncWorkspacesFromThreads(repoPaths) {
9321
9519
  if (dirty) writeAll2(next);
9322
9520
  return next.sort((a, b) => a.name.localeCompare(b.name));
9323
9521
  }
9324
- var import_node_fs19, import_node_path21;
9522
+ var import_node_fs19, import_node_path22;
9325
9523
  var init_workspaces = __esm({
9326
9524
  "src/store/workspaces.ts"() {
9327
9525
  "use strict";
9328
9526
  import_node_fs19 = require("fs");
9329
- import_node_path21 = require("path");
9527
+ import_node_path22 = require("path");
9330
9528
  init_paths();
9331
9529
  init_global_workspace();
9332
9530
  init_worktree();
@@ -9445,7 +9643,7 @@ function ensureGlobalCoordinatorCwd(opts) {
9445
9643
  let orchId = opts?.orchestratorThreadId?.trim() || "";
9446
9644
  if (!orchId) {
9447
9645
  try {
9448
- const existing = (0, import_node_fs20.readFileSync)((0, import_node_path22.join)(dir, "AGENTS.md"), "utf8");
9646
+ const existing = (0, import_node_fs20.readFileSync)((0, import_node_path23.join)(dir, "AGENTS.md"), "utf8");
9449
9647
  const m = existing.match(
9450
9648
  /YOUR orchestration thread id is `([0-9a-f-]{36})`/i
9451
9649
  );
@@ -9490,9 +9688,9 @@ function ensureGlobalCoordinatorCwd(opts) {
9490
9688
  "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."
9491
9689
  ].join("\n");
9492
9690
  try {
9493
- (0, import_node_fs20.writeFileSync)((0, import_node_path22.join)(dir, "CLAUDE.md"), `${body}
9691
+ (0, import_node_fs20.writeFileSync)((0, import_node_path23.join)(dir, "CLAUDE.md"), `${body}
9494
9692
  `, "utf8");
9495
- (0, import_node_fs20.writeFileSync)((0, import_node_path22.join)(dir, "AGENTS.md"), `${body}
9693
+ (0, import_node_fs20.writeFileSync)((0, import_node_path23.join)(dir, "AGENTS.md"), `${body}
9496
9694
  `, "utf8");
9497
9695
  } catch {
9498
9696
  }
@@ -9524,12 +9722,12 @@ function coordinatorSystemPrompt(opts) {
9524
9722
  formatWorkspaceInventory(opts.workspaces)
9525
9723
  ].join("\n");
9526
9724
  }
9527
- var import_node_fs20, import_node_path22, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9725
+ var import_node_fs20, import_node_path23, COORDINATOR_TOOL_PLAYBOOK, SLACK_REPLY_FORMATTING;
9528
9726
  var init_coordinator_prompt = __esm({
9529
9727
  "src/orchestrator/coordinator-prompt.ts"() {
9530
9728
  "use strict";
9531
9729
  import_node_fs20 = require("fs");
9532
- import_node_path22 = require("path");
9730
+ import_node_path23 = require("path");
9533
9731
  init_worktree();
9534
9732
  init_app_settings();
9535
9733
  init_paths();
@@ -9888,7 +10086,7 @@ var init_api = __esm({
9888
10086
 
9889
10087
  // src/slack/reply-target.ts
9890
10088
  function storePath() {
9891
- return (0, import_node_path23.join)(appDataDir(), "slack-reply-to.json");
10089
+ return (0, import_node_path24.join)(appDataDir(), "slack-reply-to.json");
9892
10090
  }
9893
10091
  function readStore() {
9894
10092
  const path2 = storePath();
@@ -9909,12 +10107,12 @@ function setSlackReplyTarget(target) {
9909
10107
  function getSlackReplyTarget(threadId) {
9910
10108
  return readStore()[threadId] ?? null;
9911
10109
  }
9912
- var import_node_fs21, import_node_path23;
10110
+ var import_node_fs21, import_node_path24;
9913
10111
  var init_reply_target = __esm({
9914
10112
  "src/slack/reply-target.ts"() {
9915
10113
  "use strict";
9916
10114
  import_node_fs21 = require("fs");
9917
- import_node_path23 = require("path");
10115
+ import_node_path24 = require("path");
9918
10116
  init_paths();
9919
10117
  init_private_file();
9920
10118
  init_secure_file();
@@ -9923,7 +10121,7 @@ var init_reply_target = __esm({
9923
10121
 
9924
10122
  // src/slack/workspaces.ts
9925
10123
  function storePath2() {
9926
- return (0, import_node_path24.join)(appDataDir(), "slack-workspaces.json");
10124
+ return (0, import_node_path25.join)(appDataDir(), "slack-workspaces.json");
9927
10125
  }
9928
10126
  function readStore2() {
9929
10127
  try {
@@ -10030,11 +10228,11 @@ function requireSlackWorkspace(teamId) {
10030
10228
  }
10031
10229
  return ws;
10032
10230
  }
10033
- var import_node_path24;
10231
+ var import_node_path25;
10034
10232
  var init_workspaces2 = __esm({
10035
10233
  "src/slack/workspaces.ts"() {
10036
10234
  "use strict";
10037
- import_node_path24 = require("path");
10235
+ import_node_path25 = require("path");
10038
10236
  init_paths();
10039
10237
  init_secure_file();
10040
10238
  init_api();
@@ -10043,7 +10241,7 @@ var init_workspaces2 = __esm({
10043
10241
 
10044
10242
  // src/slack/outbound-watch.ts
10045
10243
  function storePath3() {
10046
- return (0, import_node_path25.join)(appDataDir(), "slack-outbound-watch.json");
10244
+ return (0, import_node_path26.join)(appDataDir(), "slack-outbound-watch.json");
10047
10245
  }
10048
10246
  function watchId(teamId, channelId, ts) {
10049
10247
  return `${teamId}:${channelId}:${ts}`;
@@ -10380,12 +10578,12 @@ async function pollSlackOutboundWatches(opts) {
10380
10578
  }
10381
10579
  if (changed) writeStore2(watches);
10382
10580
  }
10383
- var import_node_fs22, import_node_path25, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10581
+ var import_node_fs22, import_node_path26, MAX_WATCHES, MAX_REPLIES_PER_WATCH, WATCH_TTL_MS, POLL_INTERVAL_MS, lastPollMs, nameCache, continueOnReply;
10384
10582
  var init_outbound_watch = __esm({
10385
10583
  "src/slack/outbound-watch.ts"() {
10386
10584
  "use strict";
10387
10585
  import_node_fs22 = require("fs");
10388
- import_node_path25 = require("path");
10586
+ import_node_path26 = require("path");
10389
10587
  init_paths();
10390
10588
  init_private_file();
10391
10589
  init_secure_file();
@@ -10406,7 +10604,7 @@ var init_outbound_watch = __esm({
10406
10604
  function brightsyConfigPath() {
10407
10605
  const override = process.env.BRIGHTSY_CONFIG?.trim();
10408
10606
  if (override) return override;
10409
- return (0, import_node_path26.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10607
+ return (0, import_node_path27.join)((0, import_node_os7.homedir)(), ".brightsy", "config.json");
10410
10608
  }
10411
10609
  function loadBrightsyConfig() {
10412
10610
  const path2 = brightsyConfigPath();
@@ -10425,13 +10623,13 @@ function saveBrightsyConfig(cfg) {
10425
10623
  mode: 384
10426
10624
  });
10427
10625
  }
10428
- var import_node_fs23, import_node_os7, import_node_path26;
10626
+ var import_node_fs23, import_node_os7, import_node_path27;
10429
10627
  var init_config = __esm({
10430
10628
  "src/brightsy/config.ts"() {
10431
10629
  "use strict";
10432
10630
  import_node_fs23 = require("fs");
10433
10631
  import_node_os7 = require("os");
10434
- import_node_path26 = require("path");
10632
+ import_node_path27 = require("path");
10435
10633
  }
10436
10634
  });
10437
10635
 
@@ -10658,7 +10856,7 @@ __export(connected_teams_exports, {
10658
10856
  listConnectedBrightsyTeams: () => listConnectedBrightsyTeams
10659
10857
  });
10660
10858
  function storePath4() {
10661
- return (0, import_node_path27.join)(appDataDir(), "brightsy-teams.json");
10859
+ return (0, import_node_path28.join)(appDataDir(), "brightsy-teams.json");
10662
10860
  }
10663
10861
  function readStore4() {
10664
10862
  const path2 = storePath4();
@@ -10829,12 +11027,12 @@ function brightsyMcpServerName(slug) {
10829
11027
  const cleaned = slug.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
10830
11028
  return `brightsy_${cleaned || "team"}`;
10831
11029
  }
10832
- var import_node_fs24, import_node_path27;
11030
+ var import_node_fs24, import_node_path28;
10833
11031
  var init_connected_teams = __esm({
10834
11032
  "src/brightsy/connected-teams.ts"() {
10835
11033
  "use strict";
10836
11034
  import_node_fs24 = require("fs");
10837
- import_node_path27 = require("path");
11035
+ import_node_path28 = require("path");
10838
11036
  init_paths();
10839
11037
  init_accounts();
10840
11038
  init_config();
@@ -11426,7 +11624,7 @@ function collectSystemCaPem(io = {}) {
11426
11624
  return "";
11427
11625
  }
11428
11626
  function systemCaBundlePath(io = {}) {
11429
- return (0, import_node_path28.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11627
+ return (0, import_node_path29.join)((io.appData ?? appDataDir)(), BUNDLE_NAME);
11430
11628
  }
11431
11629
  function bundleIsFresh(path2, now) {
11432
11630
  try {
@@ -11456,7 +11654,7 @@ function materializeSystemCaBundle(io = {}) {
11456
11654
  return (0, import_node_fs26.existsSync)(dest) && splitPemCertificates(readExistingFile(dest)).length > 0 ? dest : void 0;
11457
11655
  }
11458
11656
  try {
11459
- (0, import_node_fs26.mkdirSync)((0, import_node_path28.dirname)(dest), { recursive: true });
11657
+ (0, import_node_fs26.mkdirSync)((0, import_node_path29.dirname)(dest), { recursive: true });
11460
11658
  (0, import_node_fs26.writeFileSync)(dest, pem.endsWith("\n") ? pem : `${pem}
11461
11659
  `, { mode: 384 });
11462
11660
  return dest;
@@ -11497,13 +11695,13 @@ function trustSystemCertificates(io = {}) {
11497
11695
  return false;
11498
11696
  }
11499
11697
  }
11500
- 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;
11698
+ 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;
11501
11699
  var init_system_ca = __esm({
11502
11700
  "src/http/system-ca.ts"() {
11503
11701
  "use strict";
11504
11702
  import_node_child_process4 = require("child_process");
11505
11703
  import_node_fs26 = require("fs");
11506
- import_node_path28 = require("path");
11704
+ import_node_path29 = require("path");
11507
11705
  import_node_tls = __toESM(require("tls"), 1);
11508
11706
  init_paths();
11509
11707
  NODE_USE_SYSTEM_CA = "NODE_USE_SYSTEM_CA";
@@ -11529,43 +11727,43 @@ function electronResourcesPath() {
11529
11727
  function packagedCursorRuntimeDir() {
11530
11728
  const resources = electronResourcesPath();
11531
11729
  if (!resources) return null;
11532
- const dir = (0, import_node_path29.join)(resources, "cursor-runtime");
11533
- if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11730
+ const dir = (0, import_node_path30.join)(resources, "cursor-runtime");
11731
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path30.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11534
11732
  return dir;
11535
11733
  }
11536
11734
  function packagedCursorRunnerPath() {
11537
11735
  const dir = packagedCursorRuntimeDir();
11538
- return dir ? (0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11736
+ return dir ? (0, import_node_path30.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11539
11737
  }
11540
11738
  function packagedMcpDir() {
11541
11739
  const resources = electronResourcesPath();
11542
11740
  if (!resources) return null;
11543
- const dir = (0, import_node_path29.join)(resources, "sideboard-mcp");
11544
- if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
11741
+ const dir = (0, import_node_path30.join)(resources, "sideboard-mcp");
11742
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path30.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
11545
11743
  return dir;
11546
11744
  }
11547
11745
  function packagedMcpStdioPath() {
11548
11746
  const dir = packagedMcpDir();
11549
- return dir ? (0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
11747
+ return dir ? (0, import_node_path30.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
11550
11748
  }
11551
11749
  function packagedBundledNodePath() {
11552
11750
  const resources = electronResourcesPath();
11553
11751
  if (!resources) return null;
11554
- const bin = (0, import_node_path29.join)(resources, "node", "bin", "node");
11752
+ const bin = (0, import_node_path30.join)(resources, "node", "bin", "node");
11555
11753
  if (!(0, import_node_fs27.existsSync)(bin)) return null;
11556
11754
  return bin;
11557
11755
  }
11558
11756
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
11559
11757
  const dir = packagedCursorRuntimeDir();
11560
11758
  if (!dir) return null;
11561
- return (0, import_node_path29.join)(dir, "node_modules", platformPkg, "bin", binName);
11759
+ return (0, import_node_path30.join)(dir, "node_modules", platformPkg, "bin", binName);
11562
11760
  }
11563
- var import_node_fs27, import_node_path29;
11761
+ var import_node_fs27, import_node_path30;
11564
11762
  var init_packaged_runtime = __esm({
11565
11763
  "src/agents/packaged-runtime.ts"() {
11566
11764
  "use strict";
11567
11765
  import_node_fs27 = require("fs");
11568
- import_node_path29 = require("path");
11766
+ import_node_path30 = require("path");
11569
11767
  }
11570
11768
  });
11571
11769
 
@@ -11649,28 +11847,28 @@ function versionDirNodeBins(root, toBin) {
11649
11847
  }
11650
11848
  function defaultNodeBinCandidates(home = (0, import_node_os8.homedir)()) {
11651
11849
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
11652
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path30.join)(prefix, "opt", `node@${major}`, "bin", "node"))
11850
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path31.join)(prefix, "opt", `node@${major}`, "bin", "node"))
11653
11851
  );
11654
11852
  return [
11655
11853
  ...kegs,
11656
11854
  "/opt/homebrew/bin/node",
11657
11855
  "/usr/local/bin/node",
11658
- (0, import_node_path30.join)(home, ".local/share/fnm/aliases/default/bin/node"),
11659
- (0, import_node_path30.join)(home, ".nvm/current/bin/node"),
11660
- (0, import_node_path30.join)(home, ".volta/bin/node"),
11661
- (0, import_node_path30.join)(home, ".asdf/shims/node"),
11662
- (0, import_node_path30.join)(home, ".local/share/mise/shims/node"),
11856
+ (0, import_node_path31.join)(home, ".local/share/fnm/aliases/default/bin/node"),
11857
+ (0, import_node_path31.join)(home, ".nvm/current/bin/node"),
11858
+ (0, import_node_path31.join)(home, ".volta/bin/node"),
11859
+ (0, import_node_path31.join)(home, ".asdf/shims/node"),
11860
+ (0, import_node_path31.join)(home, ".local/share/mise/shims/node"),
11663
11861
  ...versionDirNodeBins(
11664
- (0, import_node_path30.join)(home, ".nvm", "versions", "node"),
11665
- (name) => (0, import_node_path30.join)(home, ".nvm", "versions", "node", name, "bin", "node")
11862
+ (0, import_node_path31.join)(home, ".nvm", "versions", "node"),
11863
+ (name) => (0, import_node_path31.join)(home, ".nvm", "versions", "node", name, "bin", "node")
11666
11864
  ),
11667
11865
  ...versionDirNodeBins(
11668
- (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions"),
11669
- (name) => (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
11866
+ (0, import_node_path31.join)(home, ".local/share/fnm", "node-versions"),
11867
+ (name) => (0, import_node_path31.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
11670
11868
  ),
11671
11869
  ...versionDirNodeBins(
11672
- (0, import_node_path30.join)(home, ".volta", "tools", "image", "node"),
11673
- (name) => (0, import_node_path30.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
11870
+ (0, import_node_path31.join)(home, ".volta", "tools", "image", "node"),
11871
+ (name) => (0, import_node_path31.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
11674
11872
  )
11675
11873
  ];
11676
11874
  }
@@ -11762,13 +11960,13 @@ async function resolveNodeLaunch(scriptPath) {
11762
11960
  env: { ELECTRON_RUN_AS_NODE: "1" }
11763
11961
  };
11764
11962
  }
11765
- var import_node_fs28, import_node_os8, import_node_path30, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
11963
+ var import_node_fs28, import_node_os8, import_node_path31, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
11766
11964
  var init_node_launch = __esm({
11767
11965
  "src/agents/node-launch.ts"() {
11768
11966
  "use strict";
11769
11967
  import_node_fs28 = require("fs");
11770
11968
  import_node_os8 = require("os");
11771
- import_node_path30 = require("path");
11969
+ import_node_path31 = require("path");
11772
11970
  init_nested_electron_env();
11773
11971
  init_system_ca();
11774
11972
  init_run();
@@ -11870,13 +12068,13 @@ function corePackageDir() {
11870
12068
  try {
11871
12069
  const url = import_meta.url;
11872
12070
  if (typeof url === "string" && url.length > 0) {
11873
- return (0, import_node_path31.dirname)((0, import_node_url.fileURLToPath)(url));
12071
+ return (0, import_node_path32.dirname)((0, import_node_url.fileURLToPath)(url));
11874
12072
  }
11875
12073
  } catch {
11876
12074
  }
11877
12075
  try {
11878
- const req = (0, import_node_module.createRequire)((0, import_node_path31.join)(process.cwd(), "package.json"));
11879
- return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
12076
+ const req = (0, import_node_module.createRequire)((0, import_node_path32.join)(process.cwd(), "package.json"));
12077
+ return (0, import_node_path32.dirname)(req.resolve("@sideboard-ai/core"));
11880
12078
  } catch {
11881
12079
  return process.cwd();
11882
12080
  }
@@ -11889,18 +12087,18 @@ function findSideboardMcpJsEntry() {
11889
12087
  let dir = corePackageDir();
11890
12088
  for (let i = 0; i < 10; i++) {
11891
12089
  const candidates = [
11892
- (0, import_node_path31.join)(dir, "mcp/run-stdio.js"),
11893
- (0, import_node_path31.join)(dir, "mcp/run-stdio.cjs"),
11894
- (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.js"),
11895
- (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.cjs"),
11896
- (0, import_node_path31.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
11897
- (0, import_node_path31.join)(dir, "packages/cli/dist/index.js"),
11898
- (0, import_node_path31.join)(dir, "cli/dist/index.js")
12090
+ (0, import_node_path32.join)(dir, "mcp/run-stdio.js"),
12091
+ (0, import_node_path32.join)(dir, "mcp/run-stdio.cjs"),
12092
+ (0, import_node_path32.join)(dir, "dist/mcp/run-stdio.js"),
12093
+ (0, import_node_path32.join)(dir, "dist/mcp/run-stdio.cjs"),
12094
+ (0, import_node_path32.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
12095
+ (0, import_node_path32.join)(dir, "packages/cli/dist/index.js"),
12096
+ (0, import_node_path32.join)(dir, "cli/dist/index.js")
11899
12097
  ];
11900
12098
  for (const p of candidates) {
11901
12099
  if ((0, import_node_fs29.existsSync)(p) && !isAsarPath(p)) return p;
11902
12100
  }
11903
- const parent = (0, import_node_path31.dirname)(dir);
12101
+ const parent = (0, import_node_path32.dirname)(dir);
11904
12102
  if (parent === dir) break;
11905
12103
  dir = parent;
11906
12104
  }
@@ -12047,22 +12245,22 @@ function writeMcpServersConfig(servers) {
12047
12245
  ...env ? { env } : {}
12048
12246
  };
12049
12247
  }
12050
- const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path31.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12051
- const cfgPath = (0, import_node_path31.join)(dir, "mcp.json");
12248
+ const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path32.join)((0, import_node_os9.tmpdir)(), "sideboard-mcp-"));
12249
+ const cfgPath = (0, import_node_path32.join)(dir, "mcp.json");
12052
12250
  (0, import_node_fs29.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12053
12251
  return cfgPath;
12054
12252
  }
12055
12253
  async function writeInjectedMcpConfig(opts) {
12056
12254
  return writeMcpServersConfig(await buildInjectedMcpServers(opts));
12057
12255
  }
12058
- 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;
12256
+ 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;
12059
12257
  var init_injected_mcp = __esm({
12060
12258
  "src/agents/injected-mcp.ts"() {
12061
12259
  "use strict";
12062
12260
  import_node_fs29 = require("fs");
12063
12261
  import_node_module = require("module");
12064
12262
  import_node_os9 = require("os");
12065
- import_node_path31 = require("path");
12263
+ import_node_path32 = require("path");
12066
12264
  import_node_url = require("url");
12067
12265
  init_run();
12068
12266
  init_config();
@@ -12303,13 +12501,31 @@ function mcpStatusThinkingFromClaudeInit(obj) {
12303
12501
  }
12304
12502
  }
12305
12503
  }
12306
- const notable = servers.filter((s) => !isCleanMcpConnect(s.status));
12504
+ const notable = servers.filter(isNotableMcpInitStatus);
12307
12505
  if (notable.length === 0) return null;
12308
12506
  return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
12309
12507
  }
12310
12508
  function isCleanMcpConnect(status) {
12311
12509
  return /^(connected|ok|ready|success)$/i.test(status.trim());
12312
12510
  }
12511
+ function isMcpAuthStatus(status) {
12512
+ return /needs[_-]?auth|needs authentication|unauthorized|not authenticated|authrequired/i.test(
12513
+ status
12514
+ );
12515
+ }
12516
+ function isSideboardMcpName(name) {
12517
+ return /^sideboard$/i.test(name.trim()) || /^mcp__sideboard$/i.test(name.trim());
12518
+ }
12519
+ function isVendorClaudeAiMcpName(name) {
12520
+ return /^claude\.ai\b/i.test(name.trim()) || /^mcp__claude_ai_/i.test(name.trim());
12521
+ }
12522
+ function isNotableMcpInitStatus(server) {
12523
+ if (isCleanMcpConnect(server.status)) return false;
12524
+ if (isSideboardMcpName(server.name)) return true;
12525
+ if (isVendorClaudeAiMcpName(server.name)) return false;
12526
+ if (isMcpAuthStatus(server.status)) return false;
12527
+ return true;
12528
+ }
12313
12529
  function eventsFromClaudeSystem(obj) {
12314
12530
  const subtype = claudeString(obj, "subtype") ?? "";
12315
12531
  const parentId = claudeParentToolUseId(obj);
@@ -12753,10 +12969,10 @@ var init_claude = __esm({
12753
12969
 
12754
12970
  // src/agents/user-mcp-config.ts
12755
12971
  function userCursorMcpConfigPath() {
12756
- return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12972
+ return (0, import_node_path33.join)((0, import_node_os10.homedir)(), ".cursor", "mcp.json");
12757
12973
  }
12758
12974
  function userClaudeMcpConfigPath() {
12759
- return (0, import_node_path32.join)((0, import_node_os10.homedir)(), ".claude.json");
12975
+ return (0, import_node_path33.join)((0, import_node_os10.homedir)(), ".claude.json");
12760
12976
  }
12761
12977
  function asObject(value) {
12762
12978
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -12791,7 +13007,7 @@ function writeMergedMcpServersJson(configPath, sideboard) {
12791
13007
  }
12792
13008
  }
12793
13009
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
12794
- (0, import_node_fs31.mkdirSync)((0, import_node_path32.dirname)(configPath), { recursive: true });
13010
+ (0, import_node_fs31.mkdirSync)((0, import_node_path33.dirname)(configPath), { recursive: true });
12795
13011
  (0, import_node_fs31.writeFileSync)(configPath, `${JSON.stringify(next, null, 2)}
12796
13012
  `);
12797
13013
  }
@@ -12816,13 +13032,13 @@ async function registerPackagedUserMcpClients() {
12816
13032
  }
12817
13033
  return { cursor };
12818
13034
  }
12819
- var import_node_fs31, import_node_os10, import_node_path32;
13035
+ var import_node_fs31, import_node_os10, import_node_path33;
12820
13036
  var init_user_mcp_config = __esm({
12821
13037
  "src/agents/user-mcp-config.ts"() {
12822
13038
  "use strict";
12823
13039
  import_node_fs31 = require("fs");
12824
13040
  import_node_os10 = require("os");
12825
- import_node_path32 = require("path");
13041
+ import_node_path33 = require("path");
12826
13042
  init_paths();
12827
13043
  init_injected_mcp();
12828
13044
  }
@@ -12863,12 +13079,12 @@ function readText(path2) {
12863
13079
  }
12864
13080
  }
12865
13081
  function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
12866
- return [(0, import_node_path33.join)(home, ".codex", "config.toml"), (0, import_node_path33.join)(home, ".config", "codex", "config.toml")];
13082
+ return [(0, import_node_path34.join)(home, ".codex", "config.toml"), (0, import_node_path34.join)(home, ".config", "codex", "config.toml")];
12867
13083
  }
12868
13084
  function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
12869
13085
  return [
12870
- (0, import_node_path33.join)(home, ".config", "opencode", "opencode.json"),
12871
- (0, import_node_path33.join)(home, ".config", "opencode", "opencode.jsonc")
13086
+ (0, import_node_path34.join)(home, ".config", "opencode", "opencode.json"),
13087
+ (0, import_node_path34.join)(home, ".config", "opencode", "opencode.jsonc")
12872
13088
  ];
12873
13089
  }
12874
13090
  function userMcpNamesToDisable(opts) {
@@ -12923,13 +13139,13 @@ function toCodexUnattendedAppsArgs() {
12923
13139
  "features.plugins=false"
12924
13140
  ];
12925
13141
  }
12926
- var import_node_fs32, import_node_os11, import_node_path33, import_smol_toml2;
13142
+ var import_node_fs32, import_node_os11, import_node_path34, import_smol_toml2;
12927
13143
  var init_orch_mcp_isolation = __esm({
12928
13144
  "src/agents/orch-mcp-isolation.ts"() {
12929
13145
  "use strict";
12930
13146
  import_node_fs32 = require("fs");
12931
13147
  import_node_os11 = require("os");
12932
- import_node_path33 = require("path");
13148
+ import_node_path34 = require("path");
12933
13149
  import_smol_toml2 = require("smol-toml");
12934
13150
  init_user_mcp_config();
12935
13151
  }
@@ -12980,8 +13196,8 @@ function usageFromCodex(usage) {
12980
13196
  }
12981
13197
  function codexConfigHasNetworkAccess() {
12982
13198
  const candidates = [
12983
- (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
12984
- (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
13199
+ (0, import_node_path35.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
13200
+ (0, import_node_path35.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
12985
13201
  ];
12986
13202
  for (const path2 of candidates) {
12987
13203
  if (!(0, import_node_fs33.existsSync)(path2)) continue;
@@ -13017,7 +13233,7 @@ function asRecord2(value) {
13017
13233
  return void 0;
13018
13234
  }
13019
13235
  function codexLooksAuthenticated() {
13020
- const authPath = (0, import_node_path34.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13236
+ const authPath = (0, import_node_path35.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
13021
13237
  if (!(0, import_node_fs33.existsSync)(authPath)) return false;
13022
13238
  try {
13023
13239
  return (0, import_node_fs33.statSync)(authPath).size > 2;
@@ -13025,13 +13241,13 @@ function codexLooksAuthenticated() {
13025
13241
  return false;
13026
13242
  }
13027
13243
  }
13028
- var import_node_fs33, import_node_os12, import_node_path34, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13244
+ var import_node_fs33, import_node_os12, import_node_path35, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13029
13245
  var init_codex = __esm({
13030
13246
  "src/agents/codex.ts"() {
13031
13247
  "use strict";
13032
13248
  import_node_fs33 = require("fs");
13033
13249
  import_node_os12 = require("os");
13034
- import_node_path34 = require("path");
13250
+ import_node_path35 = require("path");
13035
13251
  init_run();
13036
13252
  init_app_settings();
13037
13253
  init_global_workspace();
@@ -13557,7 +13773,7 @@ function platformRipgrepPackage() {
13557
13773
  }
13558
13774
  function usableRipgrepPath(candidate) {
13559
13775
  const raw = candidate?.trim();
13560
- if (!raw || !(0, import_node_path35.isAbsolute)(raw)) return null;
13776
+ if (!raw || !(0, import_node_path36.isAbsolute)(raw)) return null;
13561
13777
  const readable = nodeReadableScriptPath(raw);
13562
13778
  if (!(0, import_node_fs34.existsSync)(readable) || isAsarPath(readable)) return null;
13563
13779
  return readable;
@@ -13566,12 +13782,12 @@ function walkForBundledRipgrep(startFile) {
13566
13782
  if (!startFile) return null;
13567
13783
  const pkg = platformRipgrepPackage();
13568
13784
  const name = rgBinaryName();
13569
- let dir = (0, import_node_path35.dirname)((0, import_node_path35.resolve)(startFile));
13570
- const root = (0, import_node_path35.parse)(dir).root;
13785
+ let dir = (0, import_node_path36.dirname)((0, import_node_path36.resolve)(startFile));
13786
+ const root = (0, import_node_path36.parse)(dir).root;
13571
13787
  while (dir !== root) {
13572
- const hit = usableRipgrepPath((0, import_node_path35.join)(dir, "node_modules", pkg, "bin", name));
13788
+ const hit = usableRipgrepPath((0, import_node_path36.join)(dir, "node_modules", pkg, "bin", name));
13573
13789
  if (hit) return hit;
13574
- const next = (0, import_node_path35.dirname)(dir);
13790
+ const next = (0, import_node_path36.dirname)(dir);
13575
13791
  if (next === dir) break;
13576
13792
  dir = next;
13577
13793
  }
@@ -13581,7 +13797,7 @@ function requireResolveBundledRipgrep(fromFile) {
13581
13797
  try {
13582
13798
  const req = (0, import_node_module2.createRequire)(fromFile);
13583
13799
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
13584
- return usableRipgrepPath((0, import_node_path35.join)((0, import_node_path35.dirname)(pkgJson), "bin", rgBinaryName()));
13800
+ return usableRipgrepPath((0, import_node_path36.join)((0, import_node_path36.dirname)(pkgJson), "bin", rgBinaryName()));
13585
13801
  } catch {
13586
13802
  return null;
13587
13803
  }
@@ -13603,13 +13819,13 @@ function cursorRipgrepEnv(opts) {
13603
13819
  const path2 = resolveCursorRipgrepPath(opts);
13604
13820
  return path2 ? { [RIPGREP_ENV]: path2 } : {};
13605
13821
  }
13606
- var import_node_fs34, import_node_module2, import_node_path35, RIPGREP_ENV;
13822
+ var import_node_fs34, import_node_module2, import_node_path36, RIPGREP_ENV;
13607
13823
  var init_cursor_ripgrep = __esm({
13608
13824
  "src/agents/cursor-ripgrep.ts"() {
13609
13825
  "use strict";
13610
13826
  import_node_fs34 = require("fs");
13611
13827
  import_node_module2 = require("module");
13612
- import_node_path35 = require("path");
13828
+ import_node_path36 = require("path");
13613
13829
  init_node_launch();
13614
13830
  init_packaged_runtime();
13615
13831
  RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
@@ -13658,11 +13874,11 @@ function entryDir() {
13658
13874
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
13659
13875
  if (cjsDir) return cjsDir;
13660
13876
  try {
13661
- return (0, import_node_path36.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
13877
+ return (0, import_node_path37.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
13662
13878
  } catch {
13663
13879
  try {
13664
13880
  const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
13665
- return (0, import_node_path36.dirname)(req.resolve("@sideboard-ai/core"));
13881
+ return (0, import_node_path37.dirname)(req.resolve("@sideboard-ai/core"));
13666
13882
  } catch {
13667
13883
  return process.cwd();
13668
13884
  }
@@ -13673,27 +13889,27 @@ function cursorRunnerPath() {
13673
13889
  if (packaged) return packaged;
13674
13890
  const root = entryDir();
13675
13891
  const candidates = [
13676
- (0, import_node_path36.join)(root, "agents", "cursor-runner.js"),
13677
- (0, import_node_path36.join)(root, "agents", "cursor-runner.cjs"),
13892
+ (0, import_node_path37.join)(root, "agents", "cursor-runner.js"),
13893
+ (0, import_node_path37.join)(root, "agents", "cursor-runner.cjs"),
13678
13894
  // If somehow resolved from package root instead of dist/
13679
- (0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.js"),
13680
- (0, import_node_path36.join)(root, "dist", "agents", "cursor-runner.cjs"),
13895
+ (0, import_node_path37.join)(root, "dist", "agents", "cursor-runner.js"),
13896
+ (0, import_node_path37.join)(root, "dist", "agents", "cursor-runner.cjs"),
13681
13897
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
13682
- (0, import_node_path36.join)(root, "cursor-runner.ts"),
13683
- (0, import_node_path36.join)(root, "src", "agents", "cursor-runner.ts")
13898
+ (0, import_node_path37.join)(root, "cursor-runner.ts"),
13899
+ (0, import_node_path37.join)(root, "src", "agents", "cursor-runner.ts")
13684
13900
  ];
13685
13901
  for (const candidate of candidates) {
13686
13902
  if ((0, import_node_fs35.existsSync)(candidate)) return candidate;
13687
13903
  }
13688
13904
  return candidates[0];
13689
13905
  }
13690
- 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;
13906
+ 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;
13691
13907
  var init_cursor = __esm({
13692
13908
  "src/agents/cursor.ts"() {
13693
13909
  "use strict";
13694
13910
  import_node_fs35 = require("fs");
13695
13911
  import_node_module3 = require("module");
13696
- import_node_path36 = require("path");
13912
+ import_node_path37 = require("path");
13697
13913
  import_node_url2 = require("url");
13698
13914
  import_sdk = require("@cursor/sdk");
13699
13915
  init_run();
@@ -14626,8 +14842,8 @@ function accessTokenFromCredentialsJson(raw) {
14626
14842
  }
14627
14843
  }
14628
14844
  function claudeCredentialsPath() {
14629
- const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path37.join)((0, import_node_os13.homedir)(), ".claude");
14630
- return (0, import_node_path37.join)(root, ".credentials.json");
14845
+ const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path38.join)((0, import_node_os13.homedir)(), ".claude");
14846
+ return (0, import_node_path38.join)(root, ".credentials.json");
14631
14847
  }
14632
14848
  async function readFileAccessToken() {
14633
14849
  const path2 = claudeCredentialsPath();
@@ -14737,13 +14953,13 @@ async function getClaudePlanUsage(opts = {}) {
14737
14953
  })();
14738
14954
  return inflight;
14739
14955
  }
14740
- 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;
14956
+ 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;
14741
14957
  var init_claude_usage_client = __esm({
14742
14958
  "src/agents/claude-usage-client.ts"() {
14743
14959
  "use strict";
14744
14960
  import_node_fs37 = require("fs");
14745
14961
  import_node_os13 = require("os");
14746
- import_node_path37 = require("path");
14962
+ import_node_path38 = require("path");
14747
14963
  init_run();
14748
14964
  init_fetch();
14749
14965
  init_app_settings();
@@ -15106,15 +15322,15 @@ var init_agents = __esm({
15106
15322
 
15107
15323
  // src/hook/worktree-pkg-cache.ts
15108
15324
  function worktreePkgCacheRoot(worktreePath) {
15109
- return (0, import_node_path38.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15325
+ return (0, import_node_path39.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15110
15326
  }
15111
15327
  function worktreePkgCacheEnv(worktreePath) {
15112
15328
  const root = worktreePkgCacheRoot(worktreePath);
15113
- const store = (0, import_node_path38.join)(root, "pnpm-store");
15114
- const pnpmCache = (0, import_node_path38.join)(root, "pnpm");
15115
- const npmCache = (0, import_node_path38.join)(root, "npm");
15116
- const nodeGyp = (0, import_node_path38.join)(root, "node-gyp");
15117
- const electron = (0, import_node_path38.join)(root, "electron");
15329
+ const store = (0, import_node_path39.join)(root, "pnpm-store");
15330
+ const pnpmCache = (0, import_node_path39.join)(root, "pnpm");
15331
+ const npmCache = (0, import_node_path39.join)(root, "npm");
15332
+ const nodeGyp = (0, import_node_path39.join)(root, "node-gyp");
15333
+ const electron = (0, import_node_path39.join)(root, "electron");
15118
15334
  return {
15119
15335
  npm_config_store_dir: store,
15120
15336
  PNPM_STORE_DIR: store,
@@ -15150,12 +15366,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
15150
15366
  fillGroup(env, ["electron_config_cache"], next);
15151
15367
  ensureWorktreePkgCacheDirs(cwd);
15152
15368
  }
15153
- var import_node_fs38, import_node_path38, WORKTREE_PKG_CACHE_REL;
15369
+ var import_node_fs38, import_node_path39, WORKTREE_PKG_CACHE_REL;
15154
15370
  var init_worktree_pkg_cache = __esm({
15155
15371
  "src/hook/worktree-pkg-cache.ts"() {
15156
15372
  "use strict";
15157
15373
  import_node_fs38 = require("fs");
15158
- import_node_path38 = require("path");
15374
+ import_node_path39 = require("path");
15159
15375
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
15160
15376
  }
15161
15377
  });
@@ -16368,12 +16584,12 @@ function readTextIfPresent(abs) {
16368
16584
  }
16369
16585
  }
16370
16586
  function readLocalGuidelines(worktreePath) {
16371
- const localAbs = (0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH);
16587
+ const localAbs = (0, import_node_path40.join)(worktreePath, REVIEW_REQUEST_PATH);
16372
16588
  const localContent = readTextIfPresent(localAbs);
16373
16589
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
16374
16590
  return { path: REVIEW_REQUEST_PATH, content: localContent };
16375
16591
  }
16376
- const legacyAbs = (0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16592
+ const legacyAbs = (0, import_node_path40.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16377
16593
  const legacyContent = readTextIfPresent(legacyAbs);
16378
16594
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
16379
16595
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -16397,27 +16613,27 @@ function contextGuidelines(content, source) {
16397
16613
  };
16398
16614
  }
16399
16615
  function writeContextGuidelines(worktreePath, content) {
16400
- const abs = (0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH);
16401
- (0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
16616
+ const abs = (0, import_node_path40.join)(worktreePath, CONTEXT_REVIEW_PATH);
16617
+ (0, import_node_fs39.mkdirSync)((0, import_node_path40.dirname)(abs), { recursive: true });
16402
16618
  const body = content.endsWith("\n") ? content : `${content}
16403
16619
  `;
16404
16620
  (0, import_node_fs39.writeFileSync)(abs, body, "utf8");
16405
16621
  return body;
16406
16622
  }
16407
16623
  function readSideboardReview(worktreePath, repoPath) {
16408
- const fromWorktree = readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH));
16624
+ const fromWorktree = readTextIfPresent((0, import_node_path40.join)(worktreePath, REPO_REVIEW_PATH));
16409
16625
  if (fromWorktree) return fromWorktree;
16410
16626
  const repo = repoPath?.replace(/\/+$/, "");
16411
16627
  const wt = worktreePath.replace(/\/+$/, "");
16412
16628
  if (!repo || repo === wt) return null;
16413
- return readTextIfPresent((0, import_node_path39.join)(repo, REPO_REVIEW_PATH));
16629
+ return readTextIfPresent((0, import_node_path40.join)(repo, REPO_REVIEW_PATH));
16414
16630
  }
16415
16631
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
16416
- const skillContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH));
16632
+ const skillContent = readTextIfPresent((0, import_node_path40.join)(worktreePath, REVIEW_SKILL_PATH));
16417
16633
  if (skillContent) {
16418
16634
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
16419
16635
  }
16420
- const contextContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH));
16636
+ const contextContent = readTextIfPresent((0, import_node_path40.join)(worktreePath, CONTEXT_REVIEW_PATH));
16421
16637
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
16422
16638
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
16423
16639
  }
@@ -16455,7 +16671,7 @@ function buildReviewRequestAttachment(content, opts) {
16455
16671
  };
16456
16672
  }
16457
16673
  function readExistingReviewRequestFile(worktreePath) {
16458
- 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));
16674
+ 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));
16459
16675
  }
16460
16676
  async function requestReview(threadRef, send2) {
16461
16677
  const from = findThreadByRef(threadRef);
@@ -16482,13 +16698,13 @@ async function requestReview(threadRef, send2) {
16482
16698
  const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
16483
16699
  return { tab: started, from };
16484
16700
  }
16485
- 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;
16701
+ 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;
16486
16702
  var init_request_review = __esm({
16487
16703
  "src/review/request-review.ts"() {
16488
16704
  "use strict";
16489
16705
  import_node_crypto9 = require("crypto");
16490
16706
  import_node_fs39 = require("fs");
16491
- import_node_path39 = require("path");
16707
+ import_node_path40 = require("path");
16492
16708
  init_global_workspace();
16493
16709
  init_chat_tabs();
16494
16710
  init_thread_store();
@@ -16514,7 +16730,7 @@ function matchSimpleGlob(pattern, name) {
16514
16730
  return new RegExp(`^${escaped}$`).test(name);
16515
16731
  }
16516
16732
  function readWorktreeInclude(repoPath) {
16517
- const path2 = (0, import_node_path40.join)(repoPath, ".worktreeinclude");
16733
+ const path2 = (0, import_node_path41.join)(repoPath, ".worktreeinclude");
16518
16734
  if (!(0, import_node_fs40.existsSync)(path2)) return [];
16519
16735
  return (0, import_node_fs40.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
16520
16736
  }
@@ -16529,7 +16745,7 @@ function resolveFilesToCopy(repoPath) {
16529
16745
  for (const entry of (0, import_node_fs40.readdirSync)(repoPath, { withFileTypes: true })) {
16530
16746
  if (!entry.isFile()) continue;
16531
16747
  for (const glob of settings.fileIncludeGlobs) {
16532
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path40.basename)(glob), entry.name)) {
16748
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path41.basename)(glob), entry.name)) {
16533
16749
  matched.push(entry.name);
16534
16750
  break;
16535
16751
  }
@@ -16555,10 +16771,10 @@ function copyConfiguredFiles(repoPath, worktreePath) {
16555
16771
  const patterns = resolveFilesToCopy(repoPath);
16556
16772
  const copied = [];
16557
16773
  for (const rel of patterns) {
16558
- const src = (0, import_node_path40.join)(repoPath, rel);
16774
+ const src = (0, import_node_path41.join)(repoPath, rel);
16559
16775
  if (!(0, import_node_fs40.existsSync)(src)) continue;
16560
- const dest = (0, import_node_path40.join)(worktreePath, rel);
16561
- (0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(dest), { recursive: true });
16776
+ const dest = (0, import_node_path41.join)(worktreePath, rel);
16777
+ (0, import_node_fs40.mkdirSync)((0, import_node_path41.dirname)(dest), { recursive: true });
16562
16778
  (0, import_node_fs40.copyFileSync)(src, dest);
16563
16779
  copied.push(rel);
16564
16780
  }
@@ -16594,7 +16810,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
16594
16810
  const env = stripNestedElectronEnv({
16595
16811
  ...baseEnv ?? process.env
16596
16812
  });
16597
- const name = opts.workspaceName ?? (0, import_node_path40.basename)(opts.worktreePath);
16813
+ const name = opts.workspaceName ?? (0, import_node_path41.basename)(opts.worktreePath);
16598
16814
  const ports = opts.ports ?? [];
16599
16815
  const primary = ports[0];
16600
16816
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -16857,13 +17073,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
16857
17073
  done: handle.done
16858
17074
  };
16859
17075
  }
16860
- var import_node_fs40, import_node_net, import_node_path40, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
17076
+ var import_node_fs40, import_node_net, import_node_path41, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
16861
17077
  var init_conductor = __esm({
16862
17078
  "src/hook/conductor.ts"() {
16863
17079
  "use strict";
16864
17080
  import_node_fs40 = require("fs");
16865
17081
  import_node_net = require("net");
16866
- import_node_path40 = require("path");
17082
+ import_node_path41 = require("path");
16867
17083
  import_execa4 = require("execa");
16868
17084
  import_node_readline3 = require("readline");
16869
17085
  init_settings();
@@ -16927,9 +17143,9 @@ async function findOrphanWorktrees(repoPaths) {
16927
17143
  if ((0, import_node_fs41.existsSync)(root)) {
16928
17144
  for (const entry of (0, import_node_fs41.readdirSync)(root, { withFileTypes: true })) {
16929
17145
  if (!entry.isDirectory()) continue;
16930
- const path2 = (0, import_node_path41.join)(root, entry.name).replace(/\/$/, "");
17146
+ const path2 = (0, import_node_path42.join)(root, entry.name).replace(/\/$/, "");
16931
17147
  if (known.has(path2) || seen.has(path2)) continue;
16932
- if (!(0, import_node_fs41.existsSync)((0, import_node_path41.join)(path2, ".git"))) continue;
17148
+ if (!(0, import_node_fs41.existsSync)((0, import_node_path42.join)(path2, ".git"))) continue;
16933
17149
  seen.add(path2);
16934
17150
  let mtimeMs = 0;
16935
17151
  try {
@@ -16994,12 +17210,12 @@ function worktreeCleanupSettings() {
16994
17210
  autoCleanupOrphans: a.autoCleanupOrphans
16995
17211
  };
16996
17212
  }
16997
- var import_node_fs41, import_node_path41;
17213
+ var import_node_fs41, import_node_path42;
16998
17214
  var init_orphan_cleanup = __esm({
16999
17215
  "src/git/orphan-cleanup.ts"() {
17000
17216
  "use strict";
17001
17217
  import_node_fs41 = require("fs");
17002
- import_node_path41 = require("path");
17218
+ import_node_path42 = require("path");
17003
17219
  init_worktree();
17004
17220
  init_thread_store();
17005
17221
  init_paths();
@@ -17007,6 +17223,77 @@ var init_orphan_cleanup = __esm({
17007
17223
  }
17008
17224
  });
17009
17225
 
17226
+ // src/store/history-cleanup.ts
17227
+ function stripArchivedTranscript(thread) {
17228
+ writeThread(
17229
+ {
17230
+ ...thread,
17231
+ attachments: [],
17232
+ pendingTurnAttachments: [],
17233
+ messages: [historyRetentionStubMessage(thread)]
17234
+ },
17235
+ { touch: false }
17236
+ );
17237
+ }
17238
+ function cleanupArchivedHistory(opts = {}) {
17239
+ const settings = loadAppSettings();
17240
+ if (!opts.force && opts.purgeOlderThanDays == null && !autoCleanupHistoryEnabled(settings)) {
17241
+ return { stripped: [], purged: [] };
17242
+ }
17243
+ const archived = listThreads({ includeArchived: true }).filter((t) => t.status === "archived");
17244
+ const nowMs = opts.nowMs ?? Date.now();
17245
+ const plan = opts.purgeOlderThanDays != null ? { stripIds: [], purgeIds: planHistoryAgePurge(archived, opts.purgeOlderThanDays, nowMs) } : planHistoryRetention(archived, {
17246
+ maxCount: opts.maxCount ?? historyMaxCount(settings),
17247
+ maxDays: opts.maxDays ?? historyMaxDays(settings),
17248
+ nowMs
17249
+ });
17250
+ const stripped = [];
17251
+ const purged = [];
17252
+ if (opts.dryRun) {
17253
+ return { stripped: plan.stripIds, purged: plan.purgeIds };
17254
+ }
17255
+ for (const id of plan.stripIds) {
17256
+ const thread = readThread(id);
17257
+ if (!thread || thread.status !== "archived") continue;
17258
+ try {
17259
+ stripArchivedTranscript(thread);
17260
+ stripped.push(id);
17261
+ } catch {
17262
+ }
17263
+ }
17264
+ for (const id of plan.purgeIds) {
17265
+ const thread = readThread(id);
17266
+ if (!thread || thread.status !== "archived") continue;
17267
+ try {
17268
+ deleteThreadRecord(id);
17269
+ purged.push(id);
17270
+ } catch {
17271
+ }
17272
+ }
17273
+ if (stripped.length > 0 || purged.length > 0) {
17274
+ updateAdvancedSettings({
17275
+ historyLastCleanupAt: new Date(nowMs).toISOString()
17276
+ });
17277
+ }
17278
+ return { stripped, purged };
17279
+ }
17280
+ function shouldRunHistoryCleanup(settings = loadAppSettings()) {
17281
+ if (!autoCleanupHistoryEnabled(settings)) return false;
17282
+ const intervalHours = settings.advanced.historyCleanupIntervalHours ?? HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT;
17283
+ const last = settings.advanced.historyLastCleanupAt;
17284
+ if (!last) return true;
17285
+ const elapsed = Date.now() - Date.parse(last);
17286
+ return Number.isFinite(elapsed) && elapsed >= intervalHours * 36e5;
17287
+ }
17288
+ var init_history_cleanup = __esm({
17289
+ "src/store/history-cleanup.ts"() {
17290
+ "use strict";
17291
+ init_app_settings();
17292
+ init_history_retention();
17293
+ init_thread_store();
17294
+ }
17295
+ });
17296
+
17010
17297
  // src/git/apply-into-main.ts
17011
17298
  async function applyThreadIntoMain(thread, opts) {
17012
17299
  const method = opts?.method ?? "merge";
@@ -17102,11 +17389,11 @@ async function cloneRepoIntoSideboard(opts) {
17102
17389
  if (!url) throw new Error("Clone URL is required");
17103
17390
  let name = opts.name?.trim();
17104
17391
  if (!name) {
17105
- const leaf = (0, import_node_path42.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17392
+ const leaf = (0, import_node_path43.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
17106
17393
  name = leaf || "repo";
17107
17394
  }
17108
17395
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
17109
- const dest = (0, import_node_path42.join)(sideboardReposDir(), name);
17396
+ const dest = (0, import_node_path43.join)(sideboardReposDir(), name);
17110
17397
  if ((0, import_node_fs42.existsSync)(dest)) {
17111
17398
  const repoPath2 = await resolveRepoRoot(dest);
17112
17399
  const workspace2 = await ensureWorkspace(repoPath2);
@@ -17122,12 +17409,12 @@ async function cloneRepoIntoSideboard(opts) {
17122
17409
  const workspace = await ensureWorkspace(repoPath);
17123
17410
  return { repoPath, workspace };
17124
17411
  }
17125
- var import_node_fs42, import_node_path42, import_execa6;
17412
+ var import_node_fs42, import_node_path43, import_execa6;
17126
17413
  var init_clone_repo = __esm({
17127
17414
  "src/git/clone-repo.ts"() {
17128
17415
  "use strict";
17129
17416
  import_node_fs42 = require("fs");
17130
- import_node_path42 = require("path");
17417
+ import_node_path43 = require("path");
17131
17418
  import_execa6 = require("execa");
17132
17419
  init_paths();
17133
17420
  init_workspaces();
@@ -17253,7 +17540,7 @@ function readIntFile(file) {
17253
17540
  return Number.isInteger(n) ? n : null;
17254
17541
  }
17255
17542
  function jobDir(root, id, legacy = false) {
17256
- return (0, import_node_path43.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
17543
+ return (0, import_node_path44.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
17257
17544
  }
17258
17545
  function resolveJobDir(root, id) {
17259
17546
  const modern = jobDir(root, id, false);
@@ -17263,7 +17550,7 @@ function resolveJobDir(root, id) {
17263
17550
  return modern;
17264
17551
  }
17265
17552
  function listJobIdsIn(root, rel) {
17266
- const dir = (0, import_node_path43.join)(root, rel);
17553
+ const dir = (0, import_node_path44.join)(root, rel);
17267
17554
  if (!(0, import_node_fs43.existsSync)(dir)) return [];
17268
17555
  return (0, import_node_fs43.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
17269
17556
  }
@@ -17277,7 +17564,7 @@ function listRunningDetachedJobs(worktreePath) {
17277
17564
  const running = [];
17278
17565
  for (const id of ids) {
17279
17566
  const dir = resolveJobDir(root, id);
17280
- const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
17567
+ const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
17281
17568
  if (jobTreeAlive(pid)) running.push(id);
17282
17569
  }
17283
17570
  return running.sort();
@@ -17380,15 +17667,15 @@ function takeDelta(logFile, cursorFile) {
17380
17667
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
17381
17668
  }
17382
17669
  function snapshotJob(dir) {
17383
- const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
17670
+ const pid = readIntFile((0, import_node_path44.join)(dir, "pid"));
17384
17671
  const running = jobTreeAlive(pid);
17385
17672
  return {
17386
17673
  pid,
17387
17674
  running,
17388
- exitCode: readIntFile((0, import_node_path43.join)(dir, "exit")),
17389
- log: (0, import_node_path43.join)(dir, "log"),
17390
- cursor: (0, import_node_path43.join)(dir, "present.cursor"),
17391
- progress: tailProgress((0, import_node_path43.join)(dir, "log"))
17675
+ exitCode: readIntFile((0, import_node_path44.join)(dir, "exit")),
17676
+ log: (0, import_node_path44.join)(dir, "log"),
17677
+ cursor: (0, import_node_path44.join)(dir, "present.cursor"),
17678
+ progress: tailProgress((0, import_node_path44.join)(dir, "log"))
17392
17679
  };
17393
17680
  }
17394
17681
  function toResult(id, snap, extra) {
@@ -17397,7 +17684,7 @@ function toResult(id, snap, extra) {
17397
17684
  const stillRunning = snap.running && !ok;
17398
17685
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
17399
17686
  try {
17400
- (0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(snap.cursor), { recursive: true });
17687
+ (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(snap.cursor), { recursive: true });
17401
17688
  (0, import_node_fs43.writeFileSync)(snap.cursor, `${nextCursor}
17402
17689
  `);
17403
17690
  } catch {
@@ -17473,7 +17760,7 @@ function killProcessTree(pid, signal) {
17473
17760
  }
17474
17761
  function appendJobLog(logFile, line) {
17475
17762
  try {
17476
- (0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(logFile), { recursive: true });
17763
+ (0, import_node_fs43.mkdirSync)((0, import_node_path44.dirname)(logFile), { recursive: true });
17477
17764
  const body = line.endsWith("\n") ? line : `${line}
17478
17765
  `;
17479
17766
  (0, import_node_fs43.appendFileSync)(logFile, body);
@@ -17522,7 +17809,7 @@ async function stopDetachedJob(cwd, id, opts) {
17522
17809
  killProcessTree(targetPid, "SIGKILL");
17523
17810
  await sleep2(100);
17524
17811
  }
17525
- const exitFile = (0, import_node_path43.join)(dir, "exit");
17812
+ const exitFile = (0, import_node_path44.join)(dir, "exit");
17526
17813
  if (!(0, import_node_fs43.existsSync)(exitFile)) {
17527
17814
  try {
17528
17815
  (0, import_node_fs43.writeFileSync)(exitFile, "1\n");
@@ -17545,12 +17832,12 @@ async function stopDetachedJob(cwd, id, opts) {
17545
17832
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
17546
17833
  };
17547
17834
  }
17548
- 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;
17835
+ 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;
17549
17836
  var init_wait_for_job = __esm({
17550
17837
  "src/mcp/wait-for-job.ts"() {
17551
17838
  "use strict";
17552
17839
  import_node_fs43 = require("fs");
17553
- import_node_path43 = require("path");
17840
+ import_node_path44 = require("path");
17554
17841
  init_workspace_scratch();
17555
17842
  init_wait_for_turn();
17556
17843
  MAX_JOB_CONTINUES = 8;
@@ -19683,7 +19970,7 @@ var init_quota_failover = __esm({
19683
19970
  // src/threads/adopt.ts
19684
19971
  function thisModuleFile() {
19685
19972
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
19686
- return cjsFile || process.argv[1] || (0, import_node_path44.join)(process.cwd(), "package.json");
19973
+ return cjsFile || process.argv[1] || (0, import_node_path45.join)(process.cwd(), "package.json");
19687
19974
  }
19688
19975
  function openReadonlySqlite(file) {
19689
19976
  const req = (0, import_node_module4.createRequire)(thisModuleFile());
@@ -19711,7 +19998,7 @@ function resolveConductorCursorAgentId(workspacePath) {
19711
19998
  return null;
19712
19999
  }
19713
20000
  for (const hash of hashes) {
19714
- const agentsFile = (0, import_node_path44.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
20001
+ const agentsFile = (0, import_node_path45.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
19715
20002
  if (!(0, import_node_fs46.existsSync)(agentsFile)) continue;
19716
20003
  let text7;
19717
20004
  try {
@@ -19771,8 +20058,8 @@ function listConductorWorkspaces() {
19771
20058
  if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
19772
20059
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
19773
20060
  }
19774
- const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
19775
- const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
20061
+ const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20062
+ const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
19776
20063
  try {
19777
20064
  (0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
19778
20065
  for (const suffix of ["-wal", "-shm"]) {
@@ -19862,8 +20149,8 @@ function importConductorWorkspace(workspaceId) {
19862
20149
  if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
19863
20150
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
19864
20151
  }
19865
- const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
19866
- const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
20152
+ const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path45.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
20153
+ const snapshot = (0, import_node_path45.join)(tmp, "conductor.db");
19867
20154
  try {
19868
20155
  (0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
19869
20156
  for (const suffix of ["-wal", "-shm"]) {
@@ -19957,25 +20244,25 @@ function importConductorWorkspace(workspaceId) {
19957
20244
  async function importConductorWorkspaceAsync(workspaceId) {
19958
20245
  return importConductorWorkspace(workspaceId);
19959
20246
  }
19960
- 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;
20247
+ 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;
19961
20248
  var init_adopt = __esm({
19962
20249
  "src/threads/adopt.ts"() {
19963
20250
  "use strict";
19964
20251
  import_node_child_process5 = require("child_process");
19965
20252
  import_node_fs46 = require("fs");
19966
20253
  import_node_os14 = require("os");
19967
- import_node_path44 = require("path");
20254
+ import_node_path45 = require("path");
19968
20255
  import_node_module4 = require("module");
19969
20256
  init_worktree();
19970
20257
  init_thread_store();
19971
- CONDUCTOR_APP_SUPPORT = (0, import_node_path44.join)(
20258
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path45.join)(
19972
20259
  process.env.HOME ?? "",
19973
20260
  "Library",
19974
20261
  "Application Support",
19975
20262
  "com.conductor.app"
19976
20263
  );
19977
- CONDUCTOR_DB = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
19978
- CURSOR_SDK_STORE = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
20264
+ CONDUCTOR_DB = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
20265
+ CURSOR_SDK_STORE = (0, import_node_path45.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
19979
20266
  }
19980
20267
  });
19981
20268
 
@@ -20430,7 +20717,7 @@ new file mode 100644
20430
20717
  };
20431
20718
  }
20432
20719
  async function untrackedPatch(worktreePath, path2, maxHunk) {
20433
- const abs = (0, import_node_path45.join)(worktreePath, path2);
20720
+ const abs = (0, import_node_path46.join)(worktreePath, path2);
20434
20721
  try {
20435
20722
  const st = (0, import_node_fs48.statSync)(abs);
20436
20723
  if (st.isFile() && st.size > maxHunk) {
@@ -20923,7 +21210,7 @@ function isImageRelativePath(relativePath) {
20923
21210
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
20924
21211
  assertSafeRelativePath(relativePath);
20925
21212
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
20926
- const abs = (0, import_node_path45.join)(worktreePath, relativePath);
21213
+ const abs = (0, import_node_path46.join)(worktreePath, relativePath);
20927
21214
  const st = (0, import_node_fs48.statSync)(abs);
20928
21215
  if (!st.isFile()) {
20929
21216
  throw new Error(`Not a file: ${relativePath}`);
@@ -20943,7 +21230,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
20943
21230
  function readWorktreeFile(worktreePath, relativePath, opts) {
20944
21231
  assertSafeRelativePath(relativePath);
20945
21232
  const maxBytes = opts?.maxBytes ?? 2e5;
20946
- const abs = (0, import_node_path45.join)(worktreePath, relativePath);
21233
+ const abs = (0, import_node_path46.join)(worktreePath, relativePath);
20947
21234
  const st = (0, import_node_fs48.statSync)(abs);
20948
21235
  if (!st.isFile()) {
20949
21236
  throw new Error(`Not a file: ${relativePath}`);
@@ -20991,8 +21278,8 @@ function assertSafeRelativePath(relativePath) {
20991
21278
  }
20992
21279
  function writeWorktreeFile(worktreePath, relativePath, content) {
20993
21280
  assertSafeRelativePath(relativePath);
20994
- const abs = (0, import_node_path45.join)(worktreePath, relativePath);
20995
- (0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
21281
+ const abs = (0, import_node_path46.join)(worktreePath, relativePath);
21282
+ (0, import_node_fs48.mkdirSync)((0, import_node_path46.dirname)(abs), { recursive: true });
20996
21283
  (0, import_node_fs48.writeFileSync)(abs, content, "utf8");
20997
21284
  return { path: relativePath };
20998
21285
  }
@@ -21010,12 +21297,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
21010
21297
  truncated: full.files.length > maxFiles
21011
21298
  };
21012
21299
  }
21013
- var import_node_fs48, import_node_path45, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21300
+ var import_node_fs48, import_node_path46, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
21014
21301
  var init_diff = __esm({
21015
21302
  "src/diff/diff.ts"() {
21016
21303
  "use strict";
21017
21304
  import_node_fs48 = require("fs");
21018
- import_node_path45 = require("path");
21305
+ import_node_path46 = require("path");
21019
21306
  init_run();
21020
21307
  init_worktree();
21021
21308
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -21400,7 +21687,7 @@ function scanSkillsDir(dir, source, out) {
21400
21687
  }
21401
21688
  for (const entry of entries) {
21402
21689
  if (entry.startsWith(".")) continue;
21403
- const skillMd = (0, import_node_path46.join)(dir, entry, "SKILL.md");
21690
+ const skillMd = (0, import_node_path47.join)(dir, entry, "SKILL.md");
21404
21691
  if (!(0, import_node_fs49.existsSync)(skillMd)) continue;
21405
21692
  try {
21406
21693
  if (!(0, import_node_fs49.statSync)(skillMd).isFile()) continue;
@@ -21422,12 +21709,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
21422
21709
  return;
21423
21710
  }
21424
21711
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
21425
- const skill = readSkill((0, import_node_path46.join)(dir, "SKILL.md"), "cli");
21712
+ const skill = readSkill((0, import_node_path47.join)(dir, "SKILL.md"), "cli");
21426
21713
  if (skill) out.push(skill);
21427
21714
  }
21428
21715
  for (const entry of entries) {
21429
21716
  if (entry === "node_modules" || entry === ".git") continue;
21430
- const full = (0, import_node_path46.join)(dir, entry);
21717
+ const full = (0, import_node_path47.join)(dir, entry);
21431
21718
  try {
21432
21719
  if (!(0, import_node_fs49.statSync)(full).isDirectory()) continue;
21433
21720
  } catch {
@@ -21447,17 +21734,17 @@ function discoverSkills(worktreePath) {
21447
21734
  const home = (0, import_node_os15.homedir)();
21448
21735
  const collected = [];
21449
21736
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
21450
- scanSkillsDir((0, import_node_path46.join)(worktreePath, rel), "workspace", collected);
21737
+ scanSkillsDir((0, import_node_path47.join)(worktreePath, rel), "workspace", collected);
21451
21738
  }
21452
21739
  for (const abs of [
21453
- (0, import_node_path46.join)(home, ".claude/skills"),
21454
- (0, import_node_path46.join)(home, ".cursor/skills"),
21455
- (0, import_node_path46.join)(home, ".sideboard/skills"),
21456
- (0, import_node_path46.join)(home, ".brightsy/skills")
21740
+ (0, import_node_path47.join)(home, ".claude/skills"),
21741
+ (0, import_node_path47.join)(home, ".cursor/skills"),
21742
+ (0, import_node_path47.join)(home, ".sideboard/skills"),
21743
+ (0, import_node_path47.join)(home, ".brightsy/skills")
21457
21744
  ]) {
21458
21745
  scanSkillsDir(abs, "user", collected);
21459
21746
  }
21460
- scanClaudePluginSkills((0, import_node_path46.join)(home, ".claude/plugins"), collected);
21747
+ scanClaudePluginSkills((0, import_node_path47.join)(home, ".claude/plugins"), collected);
21461
21748
  collected.push(...bundledSkills());
21462
21749
  const rank = {
21463
21750
  workspace: 0,
@@ -21497,13 +21784,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
21497
21784
 
21498
21785
  \u2026(truncated)` : raw;
21499
21786
  }
21500
- var import_node_fs49, import_node_os15, import_node_path46, BUNDLED_SKILL_PREFIX;
21787
+ var import_node_fs49, import_node_os15, import_node_path47, BUNDLED_SKILL_PREFIX;
21501
21788
  var init_discover = __esm({
21502
21789
  "src/skills/discover.ts"() {
21503
21790
  "use strict";
21504
21791
  import_node_fs49 = require("fs");
21505
21792
  import_node_os15 = require("os");
21506
- import_node_path46 = require("path");
21793
+ import_node_path47 = require("path");
21507
21794
  init_long_running();
21508
21795
  BUNDLED_SKILL_PREFIX = "bundled:";
21509
21796
  }
@@ -21594,10 +21881,37 @@ var init_expand = __esm({
21594
21881
  }
21595
21882
  });
21596
21883
 
21884
+ // src/composer/consume-attachments.ts
21885
+ function consumeComposerAttachments(thread) {
21886
+ if (thread.attachments.length === 0) {
21887
+ return {
21888
+ attachments: [],
21889
+ pendingTurnAttachments: thread.pendingTurnAttachments ?? []
21890
+ };
21891
+ }
21892
+ return {
21893
+ attachments: [],
21894
+ pendingTurnAttachments: [
21895
+ ...thread.pendingTurnAttachments ?? [],
21896
+ ...thread.attachments
21897
+ ]
21898
+ };
21899
+ }
21900
+ function takePendingTurnAttachments(thread) {
21901
+ const pending = thread.pendingTurnAttachments ?? [];
21902
+ if (pending.length === 0 && thread.attachments.length === 0) return [];
21903
+ return [...pending, ...thread.attachments];
21904
+ }
21905
+ var init_consume_attachments = __esm({
21906
+ "src/composer/consume-attachments.ts"() {
21907
+ "use strict";
21908
+ }
21909
+ });
21910
+
21597
21911
  // src/skills/detached-job-path.ts
21598
21912
  function detachedJobScriptIn(dir) {
21599
21913
  for (const name of DETACHED_JOB_FILENAMES) {
21600
- const script = (0, import_node_path47.join)(dir, "scripts", name);
21914
+ const script = (0, import_node_path48.join)(dir, "scripts", name);
21601
21915
  if ((0, import_node_fs50.existsSync)(script)) return script;
21602
21916
  }
21603
21917
  return null;
@@ -21610,11 +21924,11 @@ function packagedDetachedJobPath() {
21610
21924
  function resolveDetachedJobScript() {
21611
21925
  const packaged = packagedDetachedJobPath();
21612
21926
  if (packaged) return packaged;
21613
- let dir = (0, import_node_path47.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
21927
+ let dir = (0, import_node_path48.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
21614
21928
  for (let i = 0; i < 8; i++) {
21615
21929
  const candidate = detachedJobScriptIn(dir);
21616
21930
  if (candidate) return candidate;
21617
- const parent = (0, import_node_path47.dirname)(dir);
21931
+ const parent = (0, import_node_path48.dirname)(dir);
21618
21932
  if (parent === dir) break;
21619
21933
  dir = parent;
21620
21934
  }
@@ -21625,12 +21939,12 @@ function formatDetachedJobInvoke(scriptPath) {
21625
21939
  if (resolved) return `node ${JSON.stringify(resolved)}`;
21626
21940
  return "node scripts/detached-job.cjs";
21627
21941
  }
21628
- var import_node_fs50, import_node_path47, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
21942
+ var import_node_fs50, import_node_path48, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
21629
21943
  var init_detached_job_path = __esm({
21630
21944
  "src/skills/detached-job-path.ts"() {
21631
21945
  "use strict";
21632
21946
  import_node_fs50 = require("fs");
21633
- import_node_path47 = require("path");
21947
+ import_node_path48 = require("path");
21634
21948
  import_node_url3 = require("url");
21635
21949
  init_packaged_runtime();
21636
21950
  import_meta3 = {};
@@ -21812,9 +22126,9 @@ function formatPrGateDirective() {
21812
22126
  }
21813
22127
  function formatProcessGuideDirective(opts) {
21814
22128
  const worktree = opts?.worktreePath?.trim();
21815
- const hasGraphSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
21816
- const hasReviewSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/review/SKILL.md"));
21817
- const hasInstallSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
22129
+ const hasGraphSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
22130
+ const hasReviewSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/review/SKILL.md"));
22131
+ const hasInstallSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path49.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
21818
22132
  return [
21819
22133
  "Process guides (recurring work only):",
21820
22134
  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,
@@ -21852,12 +22166,12 @@ function formatArtifactDirective() {
21852
22166
  function formatUiReminder() {
21853
22167
  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.";
21854
22168
  }
21855
- var import_node_fs51, import_node_path48, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
22169
+ var import_node_fs51, import_node_path49, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
21856
22170
  var init_instructions = __esm({
21857
22171
  "src/agents/instructions.ts"() {
21858
22172
  "use strict";
21859
22173
  import_node_fs51 = require("fs");
21860
- import_node_path48 = require("path");
22174
+ import_node_path49 = require("path");
21861
22175
  init_git_auth_mode();
21862
22176
  init_branch_prefix();
21863
22177
  init_worktree_labels();
@@ -22243,13 +22557,13 @@ __export(plan_file_exports, {
22243
22557
  writePlanFile: () => writePlanFile
22244
22558
  });
22245
22559
  function ensureAttachmentsGitignore(worktreePath) {
22246
- const gitignoreAbs = (0, import_node_path49.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
22560
+ const gitignoreAbs = (0, import_node_path50.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
22247
22561
  if ((0, import_node_fs52.existsSync)(gitignoreAbs)) return;
22248
- (0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(gitignoreAbs), { recursive: true });
22562
+ (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(gitignoreAbs), { recursive: true });
22249
22563
  (0, import_node_fs52.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
22250
22564
  }
22251
22565
  function planFileAbs(worktreePath) {
22252
- return (0, import_node_path49.join)(worktreePath, PLAN_FILE_REL);
22566
+ return (0, import_node_path50.join)(worktreePath, PLAN_FILE_REL);
22253
22567
  }
22254
22568
  function readTextIfPresent2(abs) {
22255
22569
  if (!(0, import_node_fs52.existsSync)(abs)) return null;
@@ -22261,22 +22575,22 @@ function readTextIfPresent2(abs) {
22261
22575
  }
22262
22576
  }
22263
22577
  function readPlanFile(worktreePath) {
22264
- 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));
22578
+ 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));
22265
22579
  }
22266
22580
  function writePlanFile(worktreePath, content) {
22267
22581
  ensureAttachmentsGitignore(worktreePath);
22268
22582
  const abs = planFileAbs(worktreePath);
22269
- (0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(abs), { recursive: true });
22583
+ (0, import_node_fs52.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
22270
22584
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
22271
22585
  (0, import_node_fs52.writeFileSync)(abs, body, "utf8");
22272
22586
  return PLAN_FILE_REL;
22273
22587
  }
22274
- var import_node_fs52, import_node_path49;
22588
+ var import_node_fs52, import_node_path50;
22275
22589
  var init_plan_file = __esm({
22276
22590
  "src/plan/plan-file.ts"() {
22277
22591
  "use strict";
22278
22592
  import_node_fs52 = require("fs");
22279
- import_node_path49 = require("path");
22593
+ import_node_path50 = require("path");
22280
22594
  init_workspace_scratch();
22281
22595
  init_plan_present();
22282
22596
  init_plan_present();
@@ -22322,37 +22636,6 @@ var init_sync_branch = __esm({
22322
22636
  }
22323
22637
  });
22324
22638
 
22325
- // src/agents/cursor-store.ts
22326
- function cursorSdkStoreDir(threadId) {
22327
- const root = (0, import_node_path50.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
22328
- const id = sanitizeCursorStoreSegment(threadId);
22329
- if (!id) return root;
22330
- return (0, import_node_path50.join)(root, "threads", id);
22331
- }
22332
- function cursorSdkRunsNdjsonPath(threadId) {
22333
- return (0, import_node_path50.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
22334
- }
22335
- function cursorSdkRunsNdjsonSearchPaths(threadId) {
22336
- const scoped = cursorSdkRunsNdjsonPath(threadId);
22337
- const shared = cursorSdkRunsNdjsonPath(null);
22338
- if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
22339
- return [shared];
22340
- }
22341
- return [scoped, shared];
22342
- }
22343
- function sanitizeCursorStoreSegment(threadId) {
22344
- return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
22345
- }
22346
- var import_node_path50, CURSOR_SDK_STORE_DIR;
22347
- var init_cursor_store = __esm({
22348
- "src/agents/cursor-store.ts"() {
22349
- "use strict";
22350
- import_node_path50 = require("path");
22351
- init_paths();
22352
- CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
22353
- }
22354
- });
22355
-
22356
22639
  // src/agents/cursor-recover.ts
22357
22640
  var cursor_recover_exports = {};
22358
22641
  __export(cursor_recover_exports, {
@@ -22562,6 +22845,7 @@ var init_orchestrator = __esm({
22562
22845
  init_conductor();
22563
22846
  init_setup_log();
22564
22847
  init_orphan_cleanup();
22848
+ init_history_cleanup();
22565
22849
  init_apply_into_main();
22566
22850
  init_clone_repo();
22567
22851
  init_message_parts();
@@ -22591,6 +22875,7 @@ var init_orchestrator = __esm({
22591
22875
  init_diff();
22592
22876
  init_discover();
22593
22877
  init_expand();
22878
+ init_consume_attachments();
22594
22879
  init_stage_files();
22595
22880
  init_context_compact();
22596
22881
  init_instructions();
@@ -22748,6 +23033,12 @@ var init_orchestrator = __esm({
22748
23033
  }
22749
23034
  } catch {
22750
23035
  }
23036
+ try {
23037
+ if (shouldRunHistoryCleanup()) {
23038
+ cleanupArchivedHistory();
23039
+ }
23040
+ } catch {
23041
+ }
22751
23042
  if (drainQueues) {
22752
23043
  this.adoptPersistedQueues();
22753
23044
  }
@@ -23095,6 +23386,11 @@ var init_orchestrator = __esm({
23095
23386
  const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id) || current.status === "running";
23096
23387
  shouldSteer = followUp === "steer" && (inFlight || current.queue.length > 0);
23097
23388
  const patch = { queue };
23389
+ if (current.attachments.length > 0) {
23390
+ const consumed = consumeComposerAttachments(current);
23391
+ patch.attachments = consumed.attachments;
23392
+ patch.pendingTurnAttachments = consumed.pendingTurnAttachments;
23393
+ }
23098
23394
  if (!inFlight) patch.status = "queued";
23099
23395
  const pid = current.agentPid;
23100
23396
  if (typeof pid === "number" && pid > 0 && !isPidAlive(pid)) {
@@ -23275,7 +23571,8 @@ var init_orchestrator = __esm({
23275
23571
  thread = this.requireThread(threadId);
23276
23572
  }
23277
23573
  const autoContinue = isJobContinuePrompt(prompt) || prompt.trim().startsWith("The previous agent process ended before it finished.");
23278
- const sentAttachments = !autoContinue && thread.attachments.length > 0 ? [...thread.attachments] : void 0;
23574
+ const parked = takePendingTurnAttachments(thread);
23575
+ const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
23279
23576
  appendMessage(threadId, {
23280
23577
  role: "user",
23281
23578
  text: prompt,
@@ -23342,8 +23639,8 @@ var init_orchestrator = __esm({
23342
23639
  slackReplyContext,
23343
23640
  expandedPrompt
23344
23641
  ].filter(Boolean).join("\n\n");
23345
- if (!autoContinue && thread.attachments.length > 0) {
23346
- updateThread(threadId, { attachments: [] });
23642
+ if (!autoContinue && sentAttachments) {
23643
+ updateThread(threadId, { attachments: [], pendingTurnAttachments: [] });
23347
23644
  }
23348
23645
  const adapter = getAdapter(thread.agent);
23349
23646
  const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
@@ -23449,8 +23746,9 @@ var init_orchestrator = __esm({
23449
23746
  isolateCodexPlugins: fresh.isolateCodexPlugins === true
23450
23747
  },
23451
23748
  (event) => {
23452
- this.emit({ type: "turn_output", threadId, event });
23453
- noteTurnLiveEvent(threadId, event);
23749
+ const paint = clipAgentEventForPaint(event);
23750
+ this.emit({ type: "turn_output", threadId, event: paint });
23751
+ noteTurnLiveEvent(threadId, paint);
23454
23752
  if (event.type === "session_id") {
23455
23753
  updateThread(threadId, { sessionId: event.data });
23456
23754
  }
@@ -23575,7 +23873,8 @@ var init_orchestrator = __esm({
23575
23873
  isolateCodexPlugins: isolateCodexPluginRetry || retryThread.isolateCodexPlugins === true
23576
23874
  },
23577
23875
  (event) => {
23578
- this.emit({ type: "turn_output", threadId, event });
23876
+ const paint = clipAgentEventForPaint(event);
23877
+ this.emit({ type: "turn_output", threadId, event: paint });
23579
23878
  if (event.type === "session_id") {
23580
23879
  updateThread(threadId, { sessionId: event.data });
23581
23880
  }
@@ -24068,6 +24367,20 @@ var init_orchestrator = __esm({
24068
24367
  repoPaths
24069
24368
  });
24070
24369
  }
24370
+ /** Bound Settings → History. After archive always; reconcile is interval-gated. */
24371
+ enforceHistoryRetention() {
24372
+ try {
24373
+ cleanupArchivedHistory();
24374
+ } catch {
24375
+ }
24376
+ }
24377
+ cleanupHistory(opts) {
24378
+ return cleanupArchivedHistory({
24379
+ dryRun: opts?.dryRun,
24380
+ purgeOlderThanDays: opts?.purgeOlderThanDays,
24381
+ force: opts?.force
24382
+ });
24383
+ }
24071
24384
  /**
24072
24385
  * Best-of-n / fanout: create N threads (one per agent) with the same prompt.
24073
24386
  */
@@ -24628,6 +24941,7 @@ var init_orchestrator = __esm({
24628
24941
  if (isGlobalThread(thread)) {
24629
24942
  const archived2 = setStatus(thread.id, "archived");
24630
24943
  this.emit({ type: "status_changed", threadId: archived2.id, status: "archived" });
24944
+ this.enforceHistoryRetention();
24631
24945
  return archived2;
24632
24946
  }
24633
24947
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
@@ -24649,6 +24963,7 @@ var init_orchestrator = __esm({
24649
24963
  }
24650
24964
  const archived = setStatus(thread.id, "archived");
24651
24965
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
24966
+ this.enforceHistoryRetention();
24652
24967
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
24653
24968
  try {
24654
24969
  const { ensureWorkspace: ensureWorkspace2 } = await Promise.resolve().then(() => (init_workspaces(), workspaces_exports));
@@ -24949,6 +25264,12 @@ __export(index_exports, {
24949
25264
  GITHUB_PR_BODY_SAFE_CHARS: () => GITHUB_PR_BODY_SAFE_CHARS,
24950
25265
  GLOBAL_WORKSPACE_ID: () => GLOBAL_WORKSPACE_ID2,
24951
25266
  HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
25267
+ HISTORY_DISCARDED_TEXT: () => HISTORY_DISCARDED_TEXT,
25268
+ HISTORY_MAX_COUNT_DEFAULT: () => HISTORY_MAX_COUNT_DEFAULT,
25269
+ HISTORY_MAX_COUNT_MAX: () => HISTORY_MAX_COUNT_MAX,
25270
+ HISTORY_MAX_COUNT_MIN: () => HISTORY_MAX_COUNT_MIN,
25271
+ HISTORY_MAX_DAYS_DEFAULT: () => HISTORY_MAX_DAYS_DEFAULT,
25272
+ HISTORY_MAX_DAYS_MAX: () => HISTORY_MAX_DAYS_MAX,
24952
25273
  HOME_BOARD_CACHE_TTL_MS: () => HOME_BOARD_CACHE_TTL_MS,
24953
25274
  IMPLIED_TICKET_RESOLVE_PROMPT: () => IMPLIED_TICKET_RESOLVE_PROMPT,
24954
25275
  ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
@@ -24998,6 +25319,8 @@ __export(index_exports, {
24998
25319
  SLACK_PROGRESS_EDIT_MS: () => SLACK_PROGRESS_EDIT_MS,
24999
25320
  SLACK_REPLY_FORMATTING: () => SLACK_REPLY_FORMATTING,
25000
25321
  SLACK_SEEN_REACTION: () => SLACK_SEEN_REACTION,
25322
+ STDERR_EVENT_MAX_CHARS: () => STDERR_EVENT_MAX_CHARS,
25323
+ STDOUT_EVENT_MAX_CHARS: () => STDOUT_EVENT_MAX_CHARS,
25001
25324
  SlackOAuthCancelledError: () => SlackOAuthCancelledError,
25002
25325
  SlackRelayHub: () => SlackRelayHub,
25003
25326
  THINKING_EFFORTS: () => THINKING_EFFORTS,
@@ -25054,6 +25377,7 @@ __export(index_exports, {
25054
25377
  attachmentsFromWorktreePaths: () => attachmentsFromWorktreePaths,
25055
25378
  attachmentsGitignoreBody: () => attachmentsGitignoreBody,
25056
25379
  autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
25380
+ autoCleanupHistoryEnabled: () => autoCleanupHistoryEnabled,
25057
25381
  autoCleanupOrphansEnabled: () => autoCleanupOrphansEnabled,
25058
25382
  autoRenameBranchEnabled: () => autoRenameBranchEnabled,
25059
25383
  autoRunAfterSetupEnabled: () => autoRunAfterSetupEnabled,
@@ -25091,14 +25415,18 @@ __export(index_exports, {
25091
25415
  childEnvWithAppSettings: () => childEnvWithAppSettings,
25092
25416
  claimDesktopHost: () => claimDesktopHost,
25093
25417
  clampGithubPrBody: () => clampGithubPrBody,
25418
+ clampHistoryMaxCount: () => clampHistoryMaxCount,
25419
+ clampHistoryMaxDays: () => clampHistoryMaxDays,
25094
25420
  classifyWorktreeColumn: () => classifyWorktreeColumn,
25095
25421
  claudeAdapter: () => claudeAdapter,
25096
25422
  claudeChromeEnabled: () => claudeChromeEnabled,
25097
25423
  claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
25098
25424
  claudeUserSettingsPath: () => claudeUserSettingsPath,
25425
+ cleanupArchivedHistory: () => cleanupArchivedHistory,
25099
25426
  cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
25100
25427
  clearBoardPins: () => clearBoardPins,
25101
25428
  clearHomeBoardCache: () => clearHomeBoardCache,
25429
+ clipAgentEventForPaint: () => clipAgentEventForPaint,
25102
25430
  clipThinkingForStore: () => clipThinkingForStore,
25103
25431
  cloneRepoIntoSideboard: () => cloneRepoIntoSideboard,
25104
25432
  codeRefRangeLabel: () => codeRefRangeLabel,
@@ -25121,6 +25449,7 @@ __export(index_exports, {
25121
25449
  connectSlackToken: () => connectSlackToken,
25122
25450
  connectedOptionalServices: () => connectedOptionalServices,
25123
25451
  connectedPrSelectors: () => connectedPrSelectors,
25452
+ consumeComposerAttachments: () => consumeComposerAttachments,
25124
25453
  contextTokens: () => contextTokens,
25125
25454
  coordinatorSystemPrompt: () => coordinatorSystemPrompt,
25126
25455
  coordinatorTurnReminder: () => coordinatorTurnReminder,
@@ -25325,6 +25654,8 @@ __export(index_exports, {
25325
25654
  hasRepoHook: () => hasRepoHook,
25326
25655
  hasWorkspaceHook: () => hasWorkspaceHook,
25327
25656
  healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
25657
+ historyMaxCount: () => historyMaxCount,
25658
+ historyMaxDays: () => historyMaxDays,
25328
25659
  hottestClaudeWindow: () => hottestClaudeWindow,
25329
25660
  httpFetch: () => httpFetch,
25330
25661
  importConductorWorkspace: () => importConductorWorkspace,
@@ -25357,6 +25688,7 @@ __export(index_exports, {
25357
25688
  isGhRateLimitError: () => isGhRateLimitError,
25358
25689
  isGlobalRepoPath: () => isGlobalRepoPath,
25359
25690
  isGlobalThread: () => isGlobalThread,
25691
+ isHistoryRetentionStub: () => isHistoryRetentionStub,
25360
25692
  isHomeBoardThread: () => isHomeBoardThread,
25361
25693
  isImageFilePath: () => isImageFilePath,
25362
25694
  isInPrStack: () => isInPrStack,
@@ -25515,6 +25847,8 @@ __export(index_exports, {
25515
25847
  persistPendingFileAttachments: () => persistPendingFileAttachments,
25516
25848
  persistVaultKeyInKeychain: () => persistVaultKeyInKeychain,
25517
25849
  planFileAbs: () => planFileAbs,
25850
+ planHistoryAgePurge: () => planHistoryAgePurge,
25851
+ planHistoryRetention: () => planHistoryRetention,
25518
25852
  planQuestionsSignature: () => planQuestionsSignature,
25519
25853
  pollSlackOutboundWatches: () => pollSlackOutboundWatches,
25520
25854
  posixShellSingleQuote: () => posixShellSingleQuote,
@@ -25630,6 +25964,7 @@ __export(index_exports, {
25630
25964
  shouldRefreshReviewRequestTemplate: () => shouldRefreshReviewRequestTemplate,
25631
25965
  shouldRemoveWorktreeOnTeardown: () => shouldRemoveWorktreeOnTeardown,
25632
25966
  shouldResetSessionForOccupancy: () => shouldResetSessionForOccupancy,
25967
+ shouldRunHistoryCleanup: () => shouldRunHistoryCleanup,
25633
25968
  shouldRunWorktreeCleanup: () => shouldRunWorktreeCleanup,
25634
25969
  shouldStampSetupLastError: () => shouldStampSetupLastError,
25635
25970
  showCostEnabled: () => showCostEnabled,
@@ -25670,6 +26005,7 @@ __export(index_exports, {
25670
26005
  summarizeConversation: () => summarizeConversation,
25671
26006
  switchBrightsyAccount: () => switchBrightsyAccount,
25672
26007
  syncWorkspacesFromThreads: () => syncWorkspacesFromThreads,
26008
+ takePendingTurnAttachments: () => takePendingTurnAttachments,
25673
26009
  takenTeamSlugsForChatTab: () => takenTeamSlugsForChatTab,
25674
26010
  takenTeamSlugsForOrchestration: () => takenTeamSlugsForOrchestration,
25675
26011
  taskMessageText: () => taskMessageText,
@@ -25760,6 +26096,7 @@ function slimThreadForUiList(thread) {
25760
26096
  return {
25761
26097
  ...thread,
25762
26098
  attachments: [],
26099
+ pendingTurnAttachments: [],
25763
26100
  messages: slimMessagesForUiList(messages, thread.updatedAt)
25764
26101
  };
25765
26102
  }
@@ -27974,6 +28311,7 @@ function buildPathRefAttachment(input) {
27974
28311
 
27975
28312
  // src/index.ts
27976
28313
  init_stage_files();
28314
+ init_consume_attachments();
27977
28315
 
27978
28316
  // src/composer/pasted-text.ts
27979
28317
  var import_node_crypto13 = require("crypto");
@@ -28152,6 +28490,8 @@ init_coordinator_prompt();
28152
28490
  init_apply_into_main();
28153
28491
  init_clone_repo();
28154
28492
  init_orphan_cleanup();
28493
+ init_history_retention();
28494
+ init_history_cleanup();
28155
28495
 
28156
28496
  // src/mcp/server.ts
28157
28497
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
@@ -33703,6 +34043,12 @@ init_outbound_watch();
33703
34043
  GITHUB_PR_BODY_SAFE_CHARS,
33704
34044
  GLOBAL_WORKSPACE_ID,
33705
34045
  HARNESS_ENV_KEYS,
34046
+ HISTORY_DISCARDED_TEXT,
34047
+ HISTORY_MAX_COUNT_DEFAULT,
34048
+ HISTORY_MAX_COUNT_MAX,
34049
+ HISTORY_MAX_COUNT_MIN,
34050
+ HISTORY_MAX_DAYS_DEFAULT,
34051
+ HISTORY_MAX_DAYS_MAX,
33706
34052
  HOME_BOARD_CACHE_TTL_MS,
33707
34053
  IMPLIED_TICKET_RESOLVE_PROMPT,
33708
34054
  ISSUE_SOURCE_LABELS,
@@ -33752,6 +34098,8 @@ init_outbound_watch();
33752
34098
  SLACK_PROGRESS_EDIT_MS,
33753
34099
  SLACK_REPLY_FORMATTING,
33754
34100
  SLACK_SEEN_REACTION,
34101
+ STDERR_EVENT_MAX_CHARS,
34102
+ STDOUT_EVENT_MAX_CHARS,
33755
34103
  SlackOAuthCancelledError,
33756
34104
  SlackRelayHub,
33757
34105
  THINKING_EFFORTS,
@@ -33808,6 +34156,7 @@ init_outbound_watch();
33808
34156
  attachmentsFromWorktreePaths,
33809
34157
  attachmentsGitignoreBody,
33810
34158
  autoArchiveOnMergeEnabled,
34159
+ autoCleanupHistoryEnabled,
33811
34160
  autoCleanupOrphansEnabled,
33812
34161
  autoRenameBranchEnabled,
33813
34162
  autoRunAfterSetupEnabled,
@@ -33845,14 +34194,18 @@ init_outbound_watch();
33845
34194
  childEnvWithAppSettings,
33846
34195
  claimDesktopHost,
33847
34196
  clampGithubPrBody,
34197
+ clampHistoryMaxCount,
34198
+ clampHistoryMaxDays,
33848
34199
  classifyWorktreeColumn,
33849
34200
  claudeAdapter,
33850
34201
  claudeChromeEnabled,
33851
34202
  claudeUsageOverLimitWindows,
33852
34203
  claudeUserSettingsPath,
34204
+ cleanupArchivedHistory,
33853
34205
  cleanupOrphanWorktrees,
33854
34206
  clearBoardPins,
33855
34207
  clearHomeBoardCache,
34208
+ clipAgentEventForPaint,
33856
34209
  clipThinkingForStore,
33857
34210
  cloneRepoIntoSideboard,
33858
34211
  codeRefRangeLabel,
@@ -33875,6 +34228,7 @@ init_outbound_watch();
33875
34228
  connectSlackToken,
33876
34229
  connectedOptionalServices,
33877
34230
  connectedPrSelectors,
34231
+ consumeComposerAttachments,
33878
34232
  contextTokens,
33879
34233
  coordinatorSystemPrompt,
33880
34234
  coordinatorTurnReminder,
@@ -34079,6 +34433,8 @@ init_outbound_watch();
34079
34433
  hasRepoHook,
34080
34434
  hasWorkspaceHook,
34081
34435
  healOrchestrationSoccerTitles,
34436
+ historyMaxCount,
34437
+ historyMaxDays,
34082
34438
  hottestClaudeWindow,
34083
34439
  httpFetch,
34084
34440
  importConductorWorkspace,
@@ -34111,6 +34467,7 @@ init_outbound_watch();
34111
34467
  isGhRateLimitError,
34112
34468
  isGlobalRepoPath,
34113
34469
  isGlobalThread,
34470
+ isHistoryRetentionStub,
34114
34471
  isHomeBoardThread,
34115
34472
  isImageFilePath,
34116
34473
  isInPrStack,
@@ -34269,6 +34626,8 @@ init_outbound_watch();
34269
34626
  persistPendingFileAttachments,
34270
34627
  persistVaultKeyInKeychain,
34271
34628
  planFileAbs,
34629
+ planHistoryAgePurge,
34630
+ planHistoryRetention,
34272
34631
  planQuestionsSignature,
34273
34632
  pollSlackOutboundWatches,
34274
34633
  posixShellSingleQuote,
@@ -34384,6 +34743,7 @@ init_outbound_watch();
34384
34743
  shouldRefreshReviewRequestTemplate,
34385
34744
  shouldRemoveWorktreeOnTeardown,
34386
34745
  shouldResetSessionForOccupancy,
34746
+ shouldRunHistoryCleanup,
34387
34747
  shouldRunWorktreeCleanup,
34388
34748
  shouldStampSetupLastError,
34389
34749
  showCostEnabled,
@@ -34424,6 +34784,7 @@ init_outbound_watch();
34424
34784
  summarizeConversation,
34425
34785
  switchBrightsyAccount,
34426
34786
  syncWorkspacesFromThreads,
34787
+ takePendingTurnAttachments,
34427
34788
  takenTeamSlugsForChatTab,
34428
34789
  takenTeamSlugsForOrchestration,
34429
34790
  taskMessageText,