patchrelay 0.25.1 → 0.25.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "service": "patchrelay",
3
- "version": "0.25.1",
4
- "commit": "9c049524adf1",
5
- "builtAt": "2026-03-26T17:19:19.052Z"
3
+ "version": "0.25.2",
4
+ "commit": "9b4ed34e9645",
5
+ "builtAt": "2026-03-26T19:10:03.366Z"
6
6
  }
@@ -1,4 +1,11 @@
1
1
  import { buildTimelineFromRehydration, appendFeedToTimeline, appendCodexItemToTimeline, completeCodexItemInTimeline, appendDeltaToTimelineItem, } from "./timeline-builder.js";
2
+ // ─── Array size caps (prevent OOM) ───────────────────────────────
3
+ const MAX_TIMELINE_ENTRIES = 2000;
4
+ const MAX_RAW_FEED_EVENTS = 2000;
5
+ const MAX_FEED_EVENTS = 1000;
6
+ function capArray(arr, max) {
7
+ return arr.length > max ? arr.slice(arr.length - max) : arr;
8
+ }
2
9
  const DETAIL_INITIAL = {
3
10
  detailTab: "timeline",
4
11
  timeline: [],
@@ -119,7 +126,7 @@ export function watchReducer(state, action) {
119
126
  case "feed-snapshot":
120
127
  return { ...state, feedEvents: action.events };
121
128
  case "feed-new-event":
122
- return { ...state, feedEvents: [...state.feedEvents, action.event] };
129
+ return { ...state, feedEvents: capArray([...state.feedEvents, action.event], MAX_FEED_EVENTS) };
123
130
  case "switch-detail-tab":
124
131
  return { ...state, detailTab: action.tab };
125
132
  }
@@ -157,10 +164,10 @@ function applyFeedEvent(state, event) {
157
164
  // Append to timeline and raw feed events if this event matches the active detail issue
158
165
  const isActiveDetail = state.view === "detail" && state.activeDetailKey === event.issueKey;
159
166
  const timeline = isActiveDetail
160
- ? appendFeedToTimeline(state.timeline, event)
167
+ ? capArray(appendFeedToTimeline(state.timeline, event), MAX_TIMELINE_ENTRIES)
161
168
  : state.timeline;
162
169
  const rawFeedEvents = isActiveDetail
163
- ? [...state.rawFeedEvents, event]
170
+ ? capArray([...state.rawFeedEvents, event], MAX_RAW_FEED_EVENTS)
164
171
  : state.rawFeedEvents;
165
172
  return { ...state, issues: updated, timeline, rawFeedEvents };
166
173
  }
@@ -168,7 +175,7 @@ function applyFeedEvent(state, event) {
168
175
  function applyCodexNotification(state, method, params) {
169
176
  switch (method) {
170
177
  case "item/started":
171
- return { ...state, timeline: appendCodexItemToTimeline(state.timeline, params, state.activeRunId) };
178
+ return { ...state, timeline: capArray(appendCodexItemToTimeline(state.timeline, params, state.activeRunId), MAX_TIMELINE_ENTRIES) };
172
179
  case "item/completed":
173
180
  return { ...state, timeline: completeCodexItemInTimeline(state.timeline, params) };
174
181
  case "item/agentMessage/delta":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchrelay",
3
- "version": "0.25.1",
3
+ "version": "0.25.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {