@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
@@ -13,9 +13,8 @@ import {
13
13
  adjustBrightsyTurnExit,
14
14
  applyAgentEvent,
15
15
  applyAgentRunnerHeapEnv,
16
- applyTurnUsage,
16
+ clipAgentEventForPaint,
17
17
  clipToolResultForStore,
18
- contextTokens,
19
18
  fallbackTurnFailDetail,
20
19
  finalizeParts,
21
20
  formatAgentErrorContinuePrompt,
@@ -40,11 +39,10 @@ import {
40
39
  shouldRetryCodexPluginIsolate,
41
40
  shouldRetryFailedAgentTurn,
42
41
  stripBrightsyNdjsonNoise,
43
- sumUsageList,
44
42
  summarizeTurnStderr,
45
43
  toolDescription,
46
44
  turnFailChatText
47
- } from "./chunk-ZU7R35NY.js";
45
+ } from "./chunk-MS2P5GXL.js";
48
46
  import {
49
47
  SLACK_REPLY_FORMATTING,
50
48
  addWorkspace,
@@ -67,7 +65,7 @@ import {
67
65
  stageAbsolutePathsAsAttachments,
68
66
  stageBuffersAsAttachments,
69
67
  syncWorkspacesFromThreads
70
- } from "./chunk-QOJB5PC7.js";
68
+ } from "./chunk-PTOIWKDU.js";
71
69
  import {
72
70
  addPrStackLayer,
73
71
  allocateTeamName,
@@ -117,7 +115,7 @@ import {
117
115
  worktreeDisplayLabelForGroup,
118
116
  worktreeNameFromPath,
119
117
  worktreeSlugForTicket
120
- } from "./chunk-N4A4NWFO.js";
118
+ } from "./chunk-42VGWRSE.js";
121
119
  import {
122
120
  ATTACHMENTS_DIR,
123
121
  DETACHED_JOBS_DIR,
@@ -135,7 +133,7 @@ import {
135
133
  updateThread,
136
134
  withThreadLock,
137
135
  writeThread
138
- } from "./chunk-DWGEBZ3C.js";
136
+ } from "./chunk-RPZFNKND.js";
139
137
  import {
140
138
  ensureWorktreeSideboardIgnored
141
139
  } from "./chunk-SYFVUF2C.js";
@@ -148,19 +146,28 @@ import {
148
146
  run
149
147
  } from "./chunk-FNQNJOHY.js";
150
148
  import {
149
+ HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
150
+ applyTurnUsage,
151
151
  assertOrchestratorCapableAgent,
152
+ autoCleanupHistoryEnabled,
152
153
  childEnvWithAppSettings,
153
154
  coerceOrchestratorAgent,
155
+ contextTokens,
154
156
  followUpBehavior,
155
157
  formatViewerContextDirective,
156
158
  formatViewerContextReminder,
157
159
  getIssueSource,
160
+ historyMaxCount,
161
+ historyMaxDays,
162
+ historyRetentionStubMessage,
158
163
  isAbleTimeConnected,
159
164
  isLinearConnected,
160
165
  isOrchestratorCapableAgent,
161
166
  isSecureFileEncrypted,
162
167
  loadAppSettings,
163
168
  orchestrationQuotaFallbackAgent,
169
+ planHistoryAgePurge,
170
+ planHistoryRetention,
164
171
  readSecureJson,
165
172
  resolveEffectiveIssueSource,
166
173
  resolveNewThreadOptions,
@@ -168,10 +175,11 @@ import {
168
175
  resolveVaultKey,
169
176
  resolveViewerProfileForRepo,
170
177
  stripNestedElectronEnv,
178
+ sumUsageList,
171
179
  updateAdvancedSettings,
172
180
  usageOnLimit,
173
181
  writeSecureJson
174
- } from "./chunk-4EGK47WV.js";
182
+ } from "./chunk-FUC3XFE2.js";
175
183
  import {
176
184
  writePrivateFile
177
185
  } from "./chunk-NSTQ6QKD.js";
@@ -409,7 +417,7 @@ async function continueSourceThread(threadId, prompt) {
409
417
  await continueOnReply(threadId, prompt);
410
418
  return;
411
419
  }
412
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-7WF32ZXJ.js");
420
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-RUQXDYM7.js");
413
421
  await getOrchestrator2().send(threadId, prompt);
414
422
  } catch {
415
423
  }
@@ -802,9 +810,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
802
810
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
803
811
  );
804
812
  }
805
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-I2X6UQMX.js");
813
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-H2ANUSGR.js");
806
814
  if (isGlobalThread2(thread)) {
807
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-6NV2IHEX.js");
815
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-2YCOE5R4.js");
808
816
  ensureGlobalCoordinatorCwd2(
809
817
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
810
818
  );
@@ -2514,6 +2522,69 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
2514
2522
  return elapsed >= intervalHours * 36e5;
2515
2523
  }
2516
2524
 
2525
+ // src/store/history-cleanup.ts
2526
+ function stripArchivedTranscript(thread) {
2527
+ writeThread(
2528
+ {
2529
+ ...thread,
2530
+ attachments: [],
2531
+ pendingTurnAttachments: [],
2532
+ messages: [historyRetentionStubMessage(thread)]
2533
+ },
2534
+ { touch: false }
2535
+ );
2536
+ }
2537
+ function cleanupArchivedHistory(opts = {}) {
2538
+ const settings = loadAppSettings();
2539
+ if (!opts.force && opts.purgeOlderThanDays == null && !autoCleanupHistoryEnabled(settings)) {
2540
+ return { stripped: [], purged: [] };
2541
+ }
2542
+ const archived = listThreads({ includeArchived: true }).filter((t) => t.status === "archived");
2543
+ const nowMs = opts.nowMs ?? Date.now();
2544
+ const plan = opts.purgeOlderThanDays != null ? { stripIds: [], purgeIds: planHistoryAgePurge(archived, opts.purgeOlderThanDays, nowMs) } : planHistoryRetention(archived, {
2545
+ maxCount: opts.maxCount ?? historyMaxCount(settings),
2546
+ maxDays: opts.maxDays ?? historyMaxDays(settings),
2547
+ nowMs
2548
+ });
2549
+ const stripped = [];
2550
+ const purged = [];
2551
+ if (opts.dryRun) {
2552
+ return { stripped: plan.stripIds, purged: plan.purgeIds };
2553
+ }
2554
+ for (const id of plan.stripIds) {
2555
+ const thread = readThread(id);
2556
+ if (!thread || thread.status !== "archived") continue;
2557
+ try {
2558
+ stripArchivedTranscript(thread);
2559
+ stripped.push(id);
2560
+ } catch {
2561
+ }
2562
+ }
2563
+ for (const id of plan.purgeIds) {
2564
+ const thread = readThread(id);
2565
+ if (!thread || thread.status !== "archived") continue;
2566
+ try {
2567
+ deleteThreadRecord(id);
2568
+ purged.push(id);
2569
+ } catch {
2570
+ }
2571
+ }
2572
+ if (stripped.length > 0 || purged.length > 0) {
2573
+ updateAdvancedSettings({
2574
+ historyLastCleanupAt: new Date(nowMs).toISOString()
2575
+ });
2576
+ }
2577
+ return { stripped, purged };
2578
+ }
2579
+ function shouldRunHistoryCleanup(settings = loadAppSettings()) {
2580
+ if (!autoCleanupHistoryEnabled(settings)) return false;
2581
+ const intervalHours = settings.advanced.historyCleanupIntervalHours ?? HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT;
2582
+ const last = settings.advanced.historyLastCleanupAt;
2583
+ if (!last) return true;
2584
+ const elapsed = Date.now() - Date.parse(last);
2585
+ return Number.isFinite(elapsed) && elapsed >= intervalHours * 36e5;
2586
+ }
2587
+
2517
2588
  // src/git/apply-into-main.ts
2518
2589
  import { execa as execa3 } from "execa";
2519
2590
  async function applyThreadIntoMain(thread, opts) {
@@ -3648,7 +3719,7 @@ async function createThread(input, _onSetupLine) {
3648
3719
  });
3649
3720
  await requireAgent(resolved.agent);
3650
3721
  if (input.cowboy) {
3651
- const { cowboyModeEnabled } = await import("./app-settings-R2KNCT37.js");
3722
+ const { cowboyModeEnabled } = await import("./app-settings-6SZLZNA7.js");
3652
3723
  if (!cowboyModeEnabled()) {
3653
3724
  throw new Error(
3654
3725
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3706,7 +3777,7 @@ async function createThread(input, _onSetupLine) {
3706
3777
  let sourceIsFork = false;
3707
3778
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3708
3779
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3709
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-UWSSLXH3.js");
3780
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-SQREWITG.js");
3710
3781
  const task = await ensureAbleTimeTask({
3711
3782
  title: title?.trim() || "Untitled work",
3712
3783
  description: input.prompt?.trim() || void 0
@@ -4242,7 +4313,7 @@ async function adoptThread(input) {
4242
4313
  messages: input.messages ?? []
4243
4314
  });
4244
4315
  writeThread(thread);
4245
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-CEU25ANO.js");
4316
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-2YNYLSPV.js");
4246
4317
  await ensureWorkspace2(repoPath);
4247
4318
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
4248
4319
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -5987,6 +6058,28 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
5987
6058
  };
5988
6059
  }
5989
6060
 
6061
+ // src/composer/consume-attachments.ts
6062
+ function consumeComposerAttachments(thread) {
6063
+ if (thread.attachments.length === 0) {
6064
+ return {
6065
+ attachments: [],
6066
+ pendingTurnAttachments: thread.pendingTurnAttachments ?? []
6067
+ };
6068
+ }
6069
+ return {
6070
+ attachments: [],
6071
+ pendingTurnAttachments: [
6072
+ ...thread.pendingTurnAttachments ?? [],
6073
+ ...thread.attachments
6074
+ ]
6075
+ };
6076
+ }
6077
+ function takePendingTurnAttachments(thread) {
6078
+ const pending = thread.pendingTurnAttachments ?? [];
6079
+ if (pending.length === 0 && thread.attachments.length === 0) return [];
6080
+ return [...pending, ...thread.attachments];
6081
+ }
6082
+
5990
6083
  // src/agents/instructions.ts
5991
6084
  import { existsSync as existsSync17 } from "fs";
5992
6085
  import { join as join16 } from "path";
@@ -6620,7 +6713,7 @@ function formatScheduledPrompt(name, prompt) {
6620
6713
  ${prompt}`;
6621
6714
  }
6622
6715
  async function defaultDeps() {
6623
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-7WF32ZXJ.js");
6716
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-RUQXDYM7.js");
6624
6717
  const orch = getOrchestrator2();
6625
6718
  return {
6626
6719
  findThread: (id) => findThreadByRef(id),
@@ -6890,12 +6983,18 @@ var Orchestrator = class {
6890
6983
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
6891
6984
  });
6892
6985
  }
6893
- const { autoCleanupOrphansEnabled } = await import("./app-settings-R2KNCT37.js");
6986
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-6SZLZNA7.js");
6894
6987
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
6895
6988
  await cleanupOrphanWorktrees({ repoPaths });
6896
6989
  }
6897
6990
  } catch {
6898
6991
  }
6992
+ try {
6993
+ if (shouldRunHistoryCleanup()) {
6994
+ cleanupArchivedHistory();
6995
+ }
6996
+ } catch {
6997
+ }
6899
6998
  if (drainQueues) {
6900
6999
  this.adoptPersistedQueues();
6901
7000
  }
@@ -7182,7 +7281,7 @@ var Orchestrator = class {
7182
7281
  }
7183
7282
  await setup;
7184
7283
  if (skipSetup) return;
7185
- const { autoRunAfterSetupEnabled } = await import("./app-settings-R2KNCT37.js");
7284
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-6SZLZNA7.js");
7186
7285
  if (autoRunAfterSetupEnabled()) {
7187
7286
  try {
7188
7287
  await this.startDev(threadId);
@@ -7243,6 +7342,11 @@ var Orchestrator = class {
7243
7342
  const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id) || current.status === "running";
7244
7343
  shouldSteer = followUp === "steer" && (inFlight || current.queue.length > 0);
7245
7344
  const patch = { queue };
7345
+ if (current.attachments.length > 0) {
7346
+ const consumed = consumeComposerAttachments(current);
7347
+ patch.attachments = consumed.attachments;
7348
+ patch.pendingTurnAttachments = consumed.pendingTurnAttachments;
7349
+ }
7246
7350
  if (!inFlight) patch.status = "queued";
7247
7351
  const pid = current.agentPid;
7248
7352
  if (typeof pid === "number" && pid > 0 && !isPidAlive(pid)) {
@@ -7423,7 +7527,8 @@ var Orchestrator = class {
7423
7527
  thread = this.requireThread(threadId);
7424
7528
  }
7425
7529
  const autoContinue = isJobContinuePrompt(prompt) || prompt.trim().startsWith("The previous agent process ended before it finished.");
7426
- const sentAttachments = !autoContinue && thread.attachments.length > 0 ? [...thread.attachments] : void 0;
7530
+ const parked = takePendingTurnAttachments(thread);
7531
+ const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
7427
7532
  appendMessage(threadId, {
7428
7533
  role: "user",
7429
7534
  text: prompt,
@@ -7490,8 +7595,8 @@ var Orchestrator = class {
7490
7595
  slackReplyContext,
7491
7596
  expandedPrompt
7492
7597
  ].filter(Boolean).join("\n\n");
7493
- if (!autoContinue && thread.attachments.length > 0) {
7494
- updateThread(threadId, { attachments: [] });
7598
+ if (!autoContinue && sentAttachments) {
7599
+ updateThread(threadId, { attachments: [], pendingTurnAttachments: [] });
7495
7600
  }
7496
7601
  const adapter = getAdapter(thread.agent);
7497
7602
  const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
@@ -7506,7 +7611,7 @@ var Orchestrator = class {
7506
7611
  }
7507
7612
  const isBrightsy = fresh.agent === "brightsy";
7508
7613
  const isOrchestration = isOrchestratorThread(fresh);
7509
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-R2KNCT37.js");
7614
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-6SZLZNA7.js");
7510
7615
  const gitAuthMode = getGithubGitAuthMode();
7511
7616
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7512
7617
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -7597,8 +7702,9 @@ var Orchestrator = class {
7597
7702
  isolateCodexPlugins: fresh.isolateCodexPlugins === true
7598
7703
  },
7599
7704
  (event) => {
7600
- this.emit({ type: "turn_output", threadId, event });
7601
- noteTurnLiveEvent(threadId, event);
7705
+ const paint = clipAgentEventForPaint(event);
7706
+ this.emit({ type: "turn_output", threadId, event: paint });
7707
+ noteTurnLiveEvent(threadId, paint);
7602
7708
  if (event.type === "session_id") {
7603
7709
  updateThread(threadId, { sessionId: event.data });
7604
7710
  }
@@ -7651,7 +7757,7 @@ var Orchestrator = class {
7651
7757
  if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
7652
7758
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
7653
7759
  if (sessionId) {
7654
- const { recoverFinishedCursorRun } = await import("./cursor-recover-TXVTLAMA.js");
7760
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-4PQAADAU.js");
7655
7761
  for (let i = 0; i < 8; i++) {
7656
7762
  const recovered = recoverFinishedCursorRun({
7657
7763
  agentId: sessionId,
@@ -7723,7 +7829,8 @@ var Orchestrator = class {
7723
7829
  isolateCodexPlugins: isolateCodexPluginRetry || retryThread.isolateCodexPlugins === true
7724
7830
  },
7725
7831
  (event) => {
7726
- this.emit({ type: "turn_output", threadId, event });
7832
+ const paint = clipAgentEventForPaint(event);
7833
+ this.emit({ type: "turn_output", threadId, event: paint });
7727
7834
  if (event.type === "session_id") {
7728
7835
  updateThread(threadId, { sessionId: event.data });
7729
7836
  }
@@ -8216,6 +8323,20 @@ var Orchestrator = class {
8216
8323
  repoPaths
8217
8324
  });
8218
8325
  }
8326
+ /** Bound Settings → History. After archive always; reconcile is interval-gated. */
8327
+ enforceHistoryRetention() {
8328
+ try {
8329
+ cleanupArchivedHistory();
8330
+ } catch {
8331
+ }
8332
+ }
8333
+ cleanupHistory(opts) {
8334
+ return cleanupArchivedHistory({
8335
+ dryRun: opts?.dryRun,
8336
+ purgeOlderThanDays: opts?.purgeOlderThanDays,
8337
+ force: opts?.force
8338
+ });
8339
+ }
8219
8340
  /**
8220
8341
  * Best-of-n / fanout: create N threads (one per agent) with the same prompt.
8221
8342
  */
@@ -8522,7 +8643,7 @@ var Orchestrator = class {
8522
8643
  if (!titled.userSetTitle && meta.title && titled.title !== meta.title) {
8523
8644
  updateThread(thread.id, { title: meta.title });
8524
8645
  }
8525
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-R2KNCT37.js");
8646
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-6SZLZNA7.js");
8526
8647
  const latest = this.requireThread(thread.id);
8527
8648
  if (!shouldAutoArchiveOnPrMerge({
8528
8649
  previousPrState: prevState || null,
@@ -8776,6 +8897,7 @@ var Orchestrator = class {
8776
8897
  if (isGlobalThread(thread)) {
8777
8898
  const archived2 = setStatus(thread.id, "archived");
8778
8899
  this.emit({ type: "status_changed", threadId: archived2.id, status: "archived" });
8900
+ this.enforceHistoryRetention();
8779
8901
  return archived2;
8780
8902
  }
8781
8903
  const siblings = threadsSharingWorktree(thread.worktreePath).filter((t) => t.id !== thread.id);
@@ -8797,9 +8919,10 @@ var Orchestrator = class {
8797
8919
  }
8798
8920
  const archived = setStatus(thread.id, "archived");
8799
8921
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8922
+ this.enforceHistoryRetention();
8800
8923
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8801
8924
  try {
8802
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-CEU25ANO.js");
8925
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-2YNYLSPV.js");
8803
8926
  await ensureWorkspace2(thread.repoPath);
8804
8927
  } catch {
8805
8928
  }
@@ -8826,7 +8949,7 @@ var Orchestrator = class {
8826
8949
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8827
8950
  } catch {
8828
8951
  }
8829
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-R2KNCT37.js");
8952
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-6SZLZNA7.js");
8830
8953
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8831
8954
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8832
8955
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8853,7 +8976,7 @@ var Orchestrator = class {
8853
8976
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8854
8977
  );
8855
8978
  }
8856
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-YD7Y6NRY.js");
8979
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-5CPGB4D2.js");
8857
8980
  const slug = thread.worktreePath.split("/").pop();
8858
8981
  const dest = thread.worktreePath;
8859
8982
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8963,7 +9086,7 @@ async function startOrchestration(opts) {
8963
9086
  sourceRef: "default",
8964
9087
  ...createOpts
8965
9088
  }).catch(async () => {
8966
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-YD7Y6NRY.js");
9089
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-5CPGB4D2.js");
8967
9090
  const repo = await resolveRepoRoot2(repoPath);
8968
9091
  const def = await resolveDefaultBranch2(repo);
8969
9092
  return orch.createThread({
@@ -8973,7 +9096,7 @@ async function startOrchestration(opts) {
8973
9096
  repoPath: repo
8974
9097
  });
8975
9098
  });
8976
- const { updateThread: upd } = await import("./thread-store-LS2T6RVH.js");
9099
+ const { updateThread: upd } = await import("./thread-store-CMZWM5NY.js");
8977
9100
  const updated = upd(thread.id, {
8978
9101
  sourceType: "orchestration",
8979
9102
  sourceRef: goal
@@ -6,14 +6,14 @@ import {
6
6
  normalizeAbleTimeCredential,
7
7
  normalizeAbleTimeHost,
8
8
  rewriteAbleTimeError
9
- } from "./chunk-WXWJ5MJ4.js";
9
+ } from "./chunk-XRIF6M5H.js";
10
10
  import {
11
11
  httpFetch
12
12
  } from "./chunk-VKQGAWHY.js";
13
13
  import {
14
14
  getAbleTimeAccessToken,
15
15
  getAbleTimeHost
16
- } from "./chunk-4EGK47WV.js";
16
+ } from "./chunk-FUC3XFE2.js";
17
17
 
18
18
  // src/integrations/abletime-rest.ts
19
19
  var ABLETIME_REST_PREFIX = "/api/public/v2";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_ABLETIME_HOST,
3
3
  normalizeAbleTimeHost
4
- } from "./chunk-X45BV4VX.js";
4
+ } from "./chunk-5LFD3KCJ.js";
5
5
  import {
6
6
  httpFetch
7
7
  } from "./chunk-N7WZ6NIN.js";
@@ -10,7 +10,7 @@ import {
10
10
  getAbleTimeHost,
11
11
  loadAppSettings,
12
12
  saveAbleTimeConnection
13
- } from "./chunk-Y4CF7LHH.js";
13
+ } from "./chunk-VJQDUD24.js";
14
14
 
15
15
  // src/integrations/abletime-oauth.ts
16
16
  import { createHash, randomBytes } from "crypto";
@@ -280,7 +280,7 @@ async function startAbleTimeOAuth(opts) {
280
280
  persistAbleTimeTokens(data, { host });
281
281
  const token = data.access_token.trim();
282
282
  try {
283
- const { getAbleTimeOrientation } = await import("./abletime-I4IYZBKU.js");
283
+ const { getAbleTimeOrientation } = await import("./abletime-G3MWSZVM.js");
284
284
  const orientation = await getAbleTimeOrientation({ token, host });
285
285
  return saveAbleTimeConnection({
286
286
  accessToken: token,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-PAQPT3JO.js";
3
+ } from "./chunk-TZCWNRMC.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
7
7
  resolveAgentGitAuthEnv,
8
8
  resolveCodexGitWritableRoots
9
- } from "./chunk-6KH4OBEW.js";
9
+ } from "./chunk-22A45QOI.js";
10
10
  import {
11
11
  applyConnectedTeamToCli,
12
12
  brightsyMcpServerName,
@@ -36,12 +36,13 @@ import {
36
36
  } from "./chunk-JZHRZ3DR.js";
37
37
  import {
38
38
  claudeChromeEnabled,
39
+ fromInclusiveInputUsage,
39
40
  isAbleTimeConnected,
40
41
  isLinearConnected,
41
42
  loadAppSettings,
42
43
  resolveAgentExecutable,
43
44
  resolveClaudeExecutable
44
- } from "./chunk-Y4CF7LHH.js";
45
+ } from "./chunk-VJQDUD24.js";
45
46
  import {
46
47
  isElectronLikeCommand,
47
48
  unwrapStrippedElectronLaunch
@@ -60,88 +61,6 @@ import {
60
61
  // src/agents/brightsy.ts
61
62
  import { existsSync } from "fs";
62
63
 
63
- // src/agents/usage.ts
64
- function sumOptional(a, b) {
65
- if (a == null && b == null) return void 0;
66
- return (a ?? 0) + (b ?? 0);
67
- }
68
- function fromInclusiveInputUsage(opts) {
69
- const totalInput = Number(opts.inputTokens) || 0;
70
- const outputTokens = Number(opts.outputTokens) || 0;
71
- const cached = Number(opts.cachedInputTokens) || 0;
72
- if (!totalInput && !outputTokens) return null;
73
- const cacheReadTokens = cached > 0 ? Math.min(cached, totalInput) : 0;
74
- return {
75
- inputTokens: Math.max(0, totalInput - cacheReadTokens),
76
- outputTokens,
77
- cacheReadTokens: cacheReadTokens || void 0
78
- };
79
- }
80
- function requestOccupancy(u) {
81
- return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
82
- }
83
- function mergeUsage(a, b) {
84
- return {
85
- inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
86
- outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
87
- cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
88
- cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
89
- costUsd: sumOptional(a?.costUsd, b.costUsd),
90
- lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
91
- };
92
- }
93
- function sumUsageList(list) {
94
- let acc = null;
95
- for (const u of list) {
96
- if (!u) continue;
97
- acc = mergeUsage(acc, {
98
- inputTokens: u.inputTokens,
99
- outputTokens: u.outputTokens,
100
- cacheReadTokens: u.cacheReadTokens,
101
- cacheWriteTokens: u.cacheWriteTokens,
102
- costUsd: u.costUsd
103
- });
104
- }
105
- if (!acc) return null;
106
- return {
107
- inputTokens: acc.inputTokens,
108
- outputTokens: acc.outputTokens,
109
- ...acc.cacheReadTokens != null ? { cacheReadTokens: acc.cacheReadTokens } : {},
110
- ...acc.cacheWriteTokens != null ? { cacheWriteTokens: acc.cacheWriteTokens } : {},
111
- ...acc.costUsd != null ? { costUsd: acc.costUsd } : {}
112
- };
113
- }
114
- function hasBilledTokens(u) {
115
- return Boolean(
116
- u.inputTokens || u.outputTokens || u.cacheReadTokens || u.cacheWriteTokens
117
- );
118
- }
119
- function applyTurnUsage(current, incoming, scope = "request") {
120
- if (scope === "turn") {
121
- if (!hasBilledTokens(incoming) && current && incoming.costUsd != null) {
122
- return { ...current, costUsd: incoming.costUsd };
123
- }
124
- return {
125
- ...incoming,
126
- costUsd: incoming.costUsd ?? current?.costUsd,
127
- lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
128
- };
129
- }
130
- const merged = mergeUsage(current, incoming);
131
- const occ = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : requestOccupancy(incoming);
132
- return {
133
- ...merged,
134
- lastRequestTokens: occ > 0 ? occ : current?.lastRequestTokens ?? occ
135
- };
136
- }
137
- function totalTokens(u) {
138
- return u.inputTokens + u.outputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
139
- }
140
- function contextTokens(u) {
141
- if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
142
- return requestOccupancy(u);
143
- }
144
-
145
64
  // src/agents/brightsy-targets.ts
146
65
  function encodeBrightsyTarget(type, id, accountId) {
147
66
  if (accountId) return `team:${accountId}:${type}:${id}`;
@@ -968,6 +887,30 @@ function clipThinkingForStore(text, max = THINKING_PART_MAX_CHARS) {
968
887
  const marker = "\u2026(earlier thinking trimmed)\n";
969
888
  return marker + text.slice(text.length - Math.max(1, max - marker.length));
970
889
  }
890
+ var STDOUT_EVENT_MAX_CHARS = 16e3;
891
+ var STDERR_EVENT_MAX_CHARS = 4e3;
892
+ function clipEventTail(text, max) {
893
+ if (text.length <= max) return text;
894
+ const marker = "\u2026(truncated)\n";
895
+ return marker + text.slice(text.length - Math.max(1, max - marker.length));
896
+ }
897
+ function clipAgentEventForPaint(event) {
898
+ if (event.type === "tool_result" && event.content) {
899
+ const content = clipToolResultForStore(event.content);
900
+ if (content === event.content) return event;
901
+ return { ...event, content };
902
+ }
903
+ if (event.type === "thinking" && event.data.length > THINKING_PART_MAX_CHARS) {
904
+ return { ...event, data: clipThinkingForStore(event.data) };
905
+ }
906
+ if (event.type === "stdout" && event.data.length > STDOUT_EVENT_MAX_CHARS) {
907
+ return { ...event, data: clipEventTail(event.data, STDOUT_EVENT_MAX_CHARS) };
908
+ }
909
+ if (event.type === "stderr" && event.data.length > STDERR_EVENT_MAX_CHARS) {
910
+ return { ...event, data: clipEventTail(event.data, STDERR_EVENT_MAX_CHARS) };
911
+ }
912
+ return event;
913
+ }
971
914
  function withPartTimes(next, prev) {
972
915
  const now = Date.now();
973
916
  const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
@@ -1767,13 +1710,31 @@ function mcpStatusThinkingFromClaudeInit(obj) {
1767
1710
  }
1768
1711
  }
1769
1712
  }
1770
- const notable = servers.filter((s) => !isCleanMcpConnect(s.status));
1713
+ const notable = servers.filter(isNotableMcpInitStatus);
1771
1714
  if (notable.length === 0) return null;
1772
1715
  return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
1773
1716
  }
1774
1717
  function isCleanMcpConnect(status) {
1775
1718
  return /^(connected|ok|ready|success)$/i.test(status.trim());
1776
1719
  }
1720
+ function isMcpAuthStatus(status) {
1721
+ return /needs[_-]?auth|needs authentication|unauthorized|not authenticated|authrequired/i.test(
1722
+ status
1723
+ );
1724
+ }
1725
+ function isSideboardMcpName(name) {
1726
+ return /^sideboard$/i.test(name.trim()) || /^mcp__sideboard$/i.test(name.trim());
1727
+ }
1728
+ function isVendorClaudeAiMcpName(name) {
1729
+ return /^claude\.ai\b/i.test(name.trim()) || /^mcp__claude_ai_/i.test(name.trim());
1730
+ }
1731
+ function isNotableMcpInitStatus(server) {
1732
+ if (isCleanMcpConnect(server.status)) return false;
1733
+ if (isSideboardMcpName(server.name)) return true;
1734
+ if (isVendorClaudeAiMcpName(server.name)) return false;
1735
+ if (isMcpAuthStatus(server.status)) return false;
1736
+ return true;
1737
+ }
1777
1738
  function eventsFromClaudeSystem(obj) {
1778
1739
  const subtype = claudeString(obj, "subtype") ?? "";
1779
1740
  const parentId = claudeParentToolUseId(obj);
@@ -1942,7 +1903,7 @@ var claudeAdapter = {
1942
1903
  );
1943
1904
  }
1944
1905
  const mode = permissionMode(thread);
1945
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-VS6HZF2I.js");
1906
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-JEKMVE42.js");
1946
1907
  const isOrchestrator = isOrchestratorThread2(thread);
1947
1908
  const injectedServers = await buildInjectedMcpServers({
1948
1909
  includeSideboard: true,
@@ -4067,6 +4028,9 @@ export {
4067
4028
  toolFilePath,
4068
4029
  THINKING_PART_MAX_CHARS,
4069
4030
  clipThinkingForStore,
4031
+ STDOUT_EVENT_MAX_CHARS,
4032
+ STDERR_EVENT_MAX_CHARS,
4033
+ clipAgentEventForPaint,
4070
4034
  applyAgentEvent,
4071
4035
  partsToAssistantText,
4072
4036
  lastAssistantMessageText,
@@ -4074,13 +4038,6 @@ export {
4074
4038
  isBrightsyNdjsonLine,
4075
4039
  finalizeParts,
4076
4040
  normalizeParseResult,
4077
- fromInclusiveInputUsage,
4078
- requestOccupancy,
4079
- mergeUsage,
4080
- sumUsageList,
4081
- applyTurnUsage,
4082
- totalTokens,
4083
- contextTokens,
4084
4041
  encodeBrightsyTarget,
4085
4042
  decodeBrightsyTarget,
4086
4043
  normalizeTurnInput,