-
Notifications
You must be signed in to change notification settings - Fork 9.9k
chore(deps): remediate Mend scan findings on release-1.11.4 (backport of #14555) #14562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c6ba06d
7ae3e8e
85dce91
775fbe1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,14 @@ import type { FlowEvent, FlowEventsResponse } from "@/types/flow-events"; | |
| const IDLE_INTERVAL = 5000; | ||
| const ACTIVE_INTERVAL = 1000; | ||
| const MIN_BANNER_DISPLAY_MS = 2000; | ||
| // Seeding the cursor with "now" drops every event posted between the route | ||
| // committing and this hook mounting with the new flow id -- the API only returns | ||
| // events strictly newer than `since`, so a dropped event never comes back. Start | ||
| // the cursor in the past instead and let the server's `settled` flag decide | ||
| // whether what we catch up on is still worth showing. | ||
| const INITIAL_LOOKBACK_SECONDS = 10; | ||
|
|
||
| const startingCursor = () => Date.now() / 1000 - INITIAL_LOOKBACK_SECONDS; | ||
|
|
||
| type UseFlowEventsReturn = { | ||
| isAgentWorking: boolean; | ||
|
|
@@ -19,9 +27,10 @@ export function useFlowEvents(flowId: string | undefined): UseFlowEventsReturn { | |
| const [events, setEvents] = useState<FlowEvent[]>([]); | ||
| const [lastSettledAt, setLastSettledAt] = useState<number | null>(null); | ||
|
|
||
| const cursorRef = useRef<number>(Date.now() / 1000); | ||
| const cursorRef = useRef<number>(startingCursor()); | ||
| const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null); | ||
| const isActiveRef = useRef(false); | ||
| const isCatchUpPollRef = useRef(true); | ||
| const isPollingRef = useRef(false); | ||
| const mountedRef = useRef(true); | ||
| const activeSinceRef = useRef<number>(0); | ||
|
|
@@ -57,6 +66,9 @@ export function useFlowEvents(flowId: string | undefined): UseFlowEventsReturn { | |
| const poll = useCallback(async () => { | ||
| if (!flowId || isPollingRef.current) return; | ||
|
|
||
| const isCatchUpPoll = isCatchUpPollRef.current; | ||
| isCatchUpPollRef.current = false; | ||
|
Comment on lines
+69
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Keep the catch-up marker after a failed request. Line 70 clears Clear the marker only after a successful response for the current flow. Add a test that rejects the initial request and then returns settled historical events. 🤖 Prompt for AI Agents |
||
|
|
||
| isPollingRef.current = true; | ||
| try { | ||
| const response = await api.get<FlowEventsResponse>( | ||
|
|
@@ -72,16 +84,24 @@ export function useFlowEvents(flowId: string | undefined): UseFlowEventsReturn { | |
| const maxTs = Math.max(...newEvents.map((e) => e.timestamp)); | ||
| cursorRef.current = maxTs; | ||
|
|
||
| setEvents((prev) => [...prev, ...newEvents]); | ||
|
|
||
| if (!isActiveRef.current) { | ||
| isActiveRef.current = true; | ||
| activeSinceRef.current = Date.now(); | ||
| setIsAgentWorking(true); | ||
| clearInterval_(); | ||
| intervalRef.current = setInterval(() => { | ||
| pollRef.current?.(); | ||
| }, ACTIVE_INTERVAL); | ||
| // The catch-up poll reaches back before mount, so it can surface work | ||
| // that is already over. Advance the cursor past it but stay quiet -- | ||
| // flashing a banner (and re-fetching the flow on the settle that | ||
| // follows) for finished work is worse than showing nothing. | ||
| const isFinishedWork = isCatchUpPoll && settled && !isActiveRef.current; | ||
|
|
||
| if (!isFinishedWork) { | ||
| setEvents((prev) => [...prev, ...newEvents]); | ||
|
|
||
| if (!isActiveRef.current) { | ||
| isActiveRef.current = true; | ||
| activeSinceRef.current = Date.now(); | ||
| setIsAgentWorking(true); | ||
| clearInterval_(); | ||
| intervalRef.current = setInterval(() => { | ||
| pollRef.current?.(); | ||
| }, ACTIVE_INTERVAL); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -129,11 +149,12 @@ export function useFlowEvents(flowId: string | undefined): UseFlowEventsReturn { | |
| if (!flowId) return; | ||
|
|
||
| mountedRef.current = true; | ||
| cursorRef.current = Date.now() / 1000; | ||
| cursorRef.current = startingCursor(); | ||
| setEvents([]); | ||
| setIsAgentWorking(false); | ||
| setLastSettledAt(null); | ||
| isActiveRef.current = false; | ||
| isCatchUpPollRef.current = true; | ||
| isPollingRef.current = false; | ||
|
Comment on lines
151
to
158
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift Reject responses from the previous flow. A request for the old Make each poll flow-scoped. Cancel the old request or use a request generation token. Apply response and 🤖 Prompt for AI Agents |
||
| activeSinceRef.current = 0; | ||
|
|
||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Make the mocks enforce the request contract.
Line 210 proves only that
sinceis in the past. The mocks return events without checkingconfig.params.since, so a cursor with a much shorter lookback still passes. The flow-change test also does not assert a request toflow-2, so it can pass when no catch-up request occurs.Use fixed time, make the mock return an event only when its timestamp is newer than
since, and assert the exact lookback window and the second request URL. As per coding guidelines, “Frontend tests should verify meaningful behavior for new functionality rather than only smoke-testing it.”🤖 Prompt for AI Agents
Source: Coding guidelines