diff --git a/.oxlintrc.json b/.oxlintrc.json index 5d7fbddbe63..7d863dcbe73 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -70,6 +70,19 @@ "react/require-render-return": "error", "react/style-prop-object": "error", "react/void-dom-elements-no-children": "error", + "react/error-boundaries": "off", + "react/globals": "off", + "react/immutability": "off", + "react/incompatible-library": "off", + "react/preserve-manual-memoization": "off", + "react/purity": "off", + "react/refs": "off", + "react/set-state-in-effect": "off", + "react/set-state-in-render": "off", + "react/static-components": "off", + "react/unsupported-syntax": "off", + "react/use-memo": "off", + "react/void-use-memo": "off", "react/checked-requires-onchange-or-readonly": "error", "react/forward-ref-uses-ref": "error", "react/iframe-missing-sandbox": "error", @@ -124,7 +137,22 @@ "react/button-has-type": "error", "react/jsx-no-useless-fragment": "error", "react/no-unstable-nested-components": "error", - "react/react-compiler": "error", + "react/error-boundaries": "error", + "react/globals": "error", + "react/hooks": "error", + "react/immutability": "error", + "react/incompatible-library": "error", + "react/memo-dependencies": "error", + "react/no-deriving-state-in-effects": "error", + "react/preserve-manual-memoization": "error", + "react/purity": "error", + "react/refs": "error", + "react/set-state-in-effect": "error", + "react/set-state-in-render": "error", + "react/static-components": "error", + "react/unsupported-syntax": "error", + "react/use-memo": "error", + "react/void-use-memo": "error", "react/rules-of-hooks": "error", "trigger-runops/no-control-plane-run-graph-access": "error", "trigger-runops/no-control-plane-in-runops-slot": "error" @@ -136,6 +164,12 @@ "react/rules-of-hooks": "error" } }, + { + "files": ["**/*.ts", "**/*.tsx"], + "rules": { + "no-redeclare": "off" + } + }, { "files": ["apps/webapp/app/**/*.test.ts", "apps/webapp/app/**/*.test.tsx"], "rules": { diff --git a/apps/webapp/app/components/AskAI.tsx b/apps/webapp/app/components/AskAI.tsx index 2f31a970426..1bbfab0f0df 100644 --- a/apps/webapp/app/components/AskAI.tsx +++ b/apps/webapp/app/components/AskAI.tsx @@ -273,7 +273,7 @@ function ChatMessages({ // Reset feedback state when conversation is reset useEffect(() => { if (conversation.length === 0) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setFeedbackGivenForQAs(new Set()); } }, [conversation.length]); diff --git a/apps/webapp/app/components/DevPresence.tsx b/apps/webapp/app/components/DevPresence.tsx index cd9b79cf1f3..29a753c129b 100644 --- a/apps/webapp/app/components/DevPresence.tsx +++ b/apps/webapp/app/components/DevPresence.tsx @@ -55,7 +55,7 @@ export function DevPresenceProvider({ children, enabled = true }: DevPresencePro useEffect(() => { // If disabled or no events if (!enabled || streamedEvents === null) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsConnected(undefined); return; } @@ -114,7 +114,7 @@ export function useCrossEngineIsConnected({ useEffect(() => { if (project.engine === "V2") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setCrossEngineIsConnected(isConnected); return; } diff --git a/apps/webapp/app/components/Feedback.tsx b/apps/webapp/app/components/Feedback.tsx index 52d7bb95005..2b1b0b152f9 100644 --- a/apps/webapp/app/components/Feedback.tsx +++ b/apps/webapp/app/components/Feedback.tsx @@ -76,7 +76,7 @@ export function Feedback({ useEffect(() => { const open = searchParams.get("feedbackPanel"); if (open) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setType(open as FeedbackType); setOpen(true); // Clone instead of mutating in place diff --git a/apps/webapp/app/components/LoginPageLayout.tsx b/apps/webapp/app/components/LoginPageLayout.tsx index a0c2cbf5237..a4f2d197517 100644 --- a/apps/webapp/app/components/LoginPageLayout.tsx +++ b/apps/webapp/app/components/LoginPageLayout.tsx @@ -47,7 +47,7 @@ export function LoginPageLayout({ const [randomQuote, setRandomQuote] = useState(null); useEffect(() => { const randomIndex = Math.floor(Math.random() * quotes.length); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setRandomQuote(quotes[randomIndex]); }, []); diff --git a/apps/webapp/app/components/TriggerRotatingLogo.tsx b/apps/webapp/app/components/TriggerRotatingLogo.tsx index 055fd7703a3..e82389f49ba 100644 --- a/apps/webapp/app/components/TriggerRotatingLogo.tsx +++ b/apps/webapp/app/components/TriggerRotatingLogo.tsx @@ -25,7 +25,7 @@ export function TriggerRotatingLogo() { useEffect(() => { // Already registered from a previous render if (customElements.get("spline-viewer")) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsSplineReady(true); return; } diff --git a/apps/webapp/app/components/admin/FeatureFlagsDialog.tsx b/apps/webapp/app/components/admin/FeatureFlagsDialog.tsx index 58b2b7722f1..25d030f6c48 100644 --- a/apps/webapp/app/components/admin/FeatureFlagsDialog.tsx +++ b/apps/webapp/app/components/admin/FeatureFlagsDialog.tsx @@ -56,7 +56,7 @@ export function FeatureFlagsDialog({ const saveFetcher = useFetcher(); const loadFeatureFlags = loadFetcher.load; const onOpenChangeRef = useRef(onOpenChange); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. onOpenChangeRef.current = onOpenChange; const [overrides, setOverrides] = useState>({}); @@ -68,7 +68,7 @@ export function FeatureFlagsDialog({ useEffect(() => { if (open && orgId) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setSaveError(null); setOverrides({}); setInitialOverrides({}); @@ -79,7 +79,7 @@ export function FeatureFlagsDialog({ useEffect(() => { if (loadFetcher.data) { const loaded = loadFetcher.data.orgFlags ?? {}; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setOverrides({ ...loaded }); setInitialOverrides({ ...loaded }); } @@ -89,7 +89,7 @@ export function FeatureFlagsDialog({ if (saveFetcher.data?.success) { onOpenChangeRef.current(false); } else if (saveFetcher.data?.error) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setSaveError(saveFetcher.data.error); } }, [saveFetcher.data]); diff --git a/apps/webapp/app/components/admin/backOffice/MaxProjectsSection.tsx b/apps/webapp/app/components/admin/backOffice/MaxProjectsSection.tsx index 7375cdb6caf..f1fb574baa2 100644 --- a/apps/webapp/app/components/admin/backOffice/MaxProjectsSection.tsx +++ b/apps/webapp/app/components/admin/backOffice/MaxProjectsSection.tsx @@ -34,12 +34,12 @@ export function MaxProjectsSection({ const [value, setValue] = useState(String(maximumProjectCount)); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. if (hasFieldErrors) setIsEditing(true); }, [hasFieldErrors]); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. if (savedJustNow && !hasFieldErrors) setIsEditing(false); }, [savedJustNow, hasFieldErrors]); diff --git a/apps/webapp/app/components/admin/backOffice/RateLimitSection.tsx b/apps/webapp/app/components/admin/backOffice/RateLimitSection.tsx index b9f2c5bff41..9e84e40c110 100644 --- a/apps/webapp/app/components/admin/backOffice/RateLimitSection.tsx +++ b/apps/webapp/app/components/admin/backOffice/RateLimitSection.tsx @@ -65,12 +65,12 @@ export function RateLimitSection({ const [maxTokens, setMaxTokens] = useState(current ? String(current.maxTokens) : ""); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. if (hasFieldErrors) setIsEditing(true); }, [hasFieldErrors]); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. if (savedJustNow && !hasFieldErrors) setIsEditing(false); }, [savedJustNow, hasFieldErrors]); diff --git a/apps/webapp/app/components/billing/BillingAlertsSection.tsx b/apps/webapp/app/components/billing/BillingAlertsSection.tsx index b3afe574f7d..47930cb54f2 100644 --- a/apps/webapp/app/components/billing/BillingAlertsSection.tsx +++ b/apps/webapp/app/components/billing/BillingAlertsSection.tsx @@ -119,7 +119,7 @@ export function BillingAlertsSection({ return; } - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setShowResetBanner(true); if (searchParams.get("alertsReset") !== "1") { @@ -141,12 +141,12 @@ export function BillingAlertsSection({ ); const maxAlerts = isPercentageMode ? MAX_PERCENTAGE_ALERTS : MAX_ABSOLUTE_ALERTS; - /* oxlint-disable react/react-compiler -- Stable derived thresholds prevent the synchronization effect from resetting local edits. */ + /* oxlint-disable react/preserve-manual-memoization -- Stable derived thresholds prevent the synchronization effect from resetting local edits. */ const savedThresholds = useMemo( () => storedAlertsToThresholds(alerts, billingLimitMode, effectiveLimitCents, planLimitCents), [alerts, billingLimitMode, effectiveLimitCents, planLimitCents] ); - /* oxlint-enable react/react-compiler */ + /* oxlint-enable react/preserve-manual-memoization */ const savedEmails = useMemo(() => alerts.emails, [alerts.emails]); const hasLegacySpikes = hasLegacySpikeAlertLevels( alerts, @@ -190,7 +190,7 @@ export function BillingAlertsSection({ useEffect(() => { nextThresholdIdRef.current = savedThresholds.length; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setThresholdRows(toThresholdRows(savedThresholds)); setEmailValues(savedEmails.length > 0 ? [...savedEmails, ""] : [""]); }, [savedThresholds, savedEmails]); diff --git a/apps/webapp/app/components/billing/BillingLimitConfigSection.tsx b/apps/webapp/app/components/billing/BillingLimitConfigSection.tsx index d031bb6c674..02c77d65a73 100644 --- a/apps/webapp/app/components/billing/BillingLimitConfigSection.tsx +++ b/apps/webapp/app/components/billing/BillingLimitConfigSection.tsx @@ -126,7 +126,7 @@ export function BillingLimitConfigSection({ const formRef = useRef(null); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setMode(resetMode); setCustomAmount(savedCustomAmount); setCancelInProgressRuns(savedCancelInProgressRuns); diff --git a/apps/webapp/app/components/billing/BillingLimitRecoveryPanel.tsx b/apps/webapp/app/components/billing/BillingLimitRecoveryPanel.tsx index f5a83ba7a77..2ed56fd26e4 100644 --- a/apps/webapp/app/components/billing/BillingLimitRecoveryPanel.tsx +++ b/apps/webapp/app/components/billing/BillingLimitRecoveryPanel.tsx @@ -63,7 +63,7 @@ export function BillingLimitRecoveryPanel({ const formRef = useRef(null); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- A refreshed server recommendation intentionally resets this editable amount draft. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- A refreshed server recommendation intentionally resets this editable amount draft. setNewAmount(String(suggestedNewLimitDollars)); }, [suggestedNewLimitDollars]); diff --git a/apps/webapp/app/components/code/AIQueryInput.tsx b/apps/webapp/app/components/code/AIQueryInput.tsx index 9ac49fba72e..0670dc7c8a2 100644 --- a/apps/webapp/app/components/code/AIQueryInput.tsx +++ b/apps/webapp/app/components/code/AIQueryInput.tsx @@ -61,7 +61,7 @@ export function AIQueryInput({ // If mode is edit but there's no current query, switch to new useEffect(() => { if (mode === "edit" && !canEdit) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setMode("new"); } }, [mode, canEdit]); diff --git a/apps/webapp/app/components/code/JSONEditor.tsx b/apps/webapp/app/components/code/JSONEditor.tsx index 0c5153c969f..7f13c14ca4b 100644 --- a/apps/webapp/app/components/code/JSONEditor.tsx +++ b/apps/webapp/app/components/code/JSONEditor.tsx @@ -94,7 +94,7 @@ export function JSONEditor(opts: JSONEditorProps) { const editor = useRef(null); const settings: Omit = { ...opts, - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. container: editor.current, extensions, editable: !readOnly, diff --git a/apps/webapp/app/components/code/TSQLEditor.tsx b/apps/webapp/app/components/code/TSQLEditor.tsx index 2beede97cc9..03af976265d 100644 --- a/apps/webapp/app/components/code/TSQLEditor.tsx +++ b/apps/webapp/app/components/code/TSQLEditor.tsx @@ -196,7 +196,7 @@ export function TSQLEditor(opts: TSQLEditorProps) { const settings: Omit = { ...opts, - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. container: editor.current, extensions, editable: !readOnly, diff --git a/apps/webapp/app/components/code/TSQLResultsTable.tsx b/apps/webapp/app/components/code/TSQLResultsTable.tsx index e99874d8663..b5e9fc80c91 100644 --- a/apps/webapp/app/components/code/TSQLResultsTable.tsx +++ b/apps/webapp/app/components/code/TSQLResultsTable.tsx @@ -224,7 +224,7 @@ const DebouncedInput = forwardRef< const [value, setValue] = useState(initialValue); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- Programmatic filter changes intentionally reset the debounced input draft. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- Programmatic filter changes intentionally reset the debounced input draft. setValue(initialValue); }, [initialValue]); @@ -1065,7 +1065,6 @@ function ColumnResizeHandle({ header }: { header: Header }) { } /* oxlint-enable jsx-a11y/no-static-element-interactions */ -// oxlint-disable-next-line react/react-compiler -- TanStack Table is not compatible with compiler memoization. export const TSQLResultsTable = memo(function TSQLResultsTable({ rows, columns, @@ -1122,6 +1121,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({ // Column resize mode: 'onChange' for real-time feedback, 'onEnd' for performance const columnResizeMode: ColumnResizeMode = "onChange"; + // oxlint-disable-next-line react/incompatible-library -- TanStack Table is not compatible with compiler memoization. const table = useReactTable({ data: rows, columns: columnDefs, diff --git a/apps/webapp/app/components/code/TextEditor.tsx b/apps/webapp/app/components/code/TextEditor.tsx index f81cedabcad..b86d3aacedf 100644 --- a/apps/webapp/app/components/code/TextEditor.tsx +++ b/apps/webapp/app/components/code/TextEditor.tsx @@ -48,7 +48,7 @@ export function TextEditor(opts: TextEditorProps) { const editor = useRef(null); const settings: Omit = { ...opts, - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. container: editor.current, extensions, editable: !readOnly, diff --git a/apps/webapp/app/components/dashboard-agent/AgentChart.tsx b/apps/webapp/app/components/dashboard-agent/AgentChart.tsx index 70beed5a200..88becb33418 100644 --- a/apps/webapp/app/components/dashboard-agent/AgentChart.tsx +++ b/apps/webapp/app/components/dashboard-agent/AgentChart.tsx @@ -93,7 +93,7 @@ export function AgentChart({ // The block can render before `query` has streamed in; an empty query 400s. if (!block.query) return; if (!organizationId || !projectId || !environmentId) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState({ status: "error", error: "No environment context to run the query." }); return; } diff --git a/apps/webapp/app/components/dashboard-agent/DashboardAgentChat.tsx b/apps/webapp/app/components/dashboard-agent/DashboardAgentChat.tsx index 1153cd98126..c36a9692e71 100644 --- a/apps/webapp/app/components/dashboard-agent/DashboardAgentChat.tsx +++ b/apps/webapp/app/components/dashboard-agent/DashboardAgentChat.tsx @@ -123,7 +123,7 @@ export function DashboardAgentChat({ // The path this chat last rendered on. React never unmounts on a page teardown, so an // unmount whose live URL has moved is the router having navigated out from under it. const renderedPathRef = useRef(location.pathname); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + renderedPathRef.current = location.pathname; const transport = useTriggerChatTransport({ @@ -210,7 +210,7 @@ export function DashboardAgentChat({ }); const orderRef = useRef(createTranscriptOrder(initialMessages)); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + const messages = orderTranscript(rawMessages, orderRef.current); // Read here, not in the panel, so it re-reads as each turn settles. @@ -361,7 +361,7 @@ export function DashboardAgentChat({ const navigatedRef = useRef | null>(null); if (navigatedRef.current === null) { navigatedRef.current = new Set(); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + pendingNavigateIntents(initialMessages, navigatedRef.current); } useEffect(() => { @@ -377,7 +377,7 @@ export function DashboardAgentChat({ const watchProposedRef = useRef | null>(null); if (watchProposedRef.current === null) { watchProposedRef.current = new Set(); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + pendingWatchIntents(initialMessages, watchProposedRef.current); } useEffect(() => { @@ -392,7 +392,7 @@ export function DashboardAgentChat({ }, [transport, chatId, aiStop]); const teardownRef = useRef<() => void>(() => {}); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + teardownRef.current = () => { if (status !== "streaming" && status !== "submitted") return; const reason = unmountTeardown({ @@ -406,7 +406,7 @@ export function DashboardAgentChat({ // Read by the settle effect, which must not re-run when the transcript changes. const messagesRef = useRef(messages); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + messagesRef.current = messages; const prevStatus = useRef(status); diff --git a/apps/webapp/app/components/dashboard-agent/DashboardAgentMessages.tsx b/apps/webapp/app/components/dashboard-agent/DashboardAgentMessages.tsx index 819e11209fd..e28405c32c8 100644 --- a/apps/webapp/app/components/dashboard-agent/DashboardAgentMessages.tsx +++ b/apps/webapp/app/components/dashboard-agent/DashboardAgentMessages.tsx @@ -126,9 +126,9 @@ export function winningInvestigationOccurrences(messages: UIMessage[]): Map { const previous = useRef>(); const next = useMemo(() => winningInvestigationOccurrences(messages), [messages]); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. previous.current = reuseWinners(previous.current, next); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. return previous.current; } diff --git a/apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx b/apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx index c034aa0c7cc..bc74db273a1 100644 --- a/apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx +++ b/apps/webapp/app/components/dashboard-agent/DashboardAgentPanel.tsx @@ -168,13 +168,11 @@ export function DashboardAgentPanel({ // Ordering-safe: if the new chat has not reported yet, its own report re-sets the marker. useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. setThinkingChatId((previous) => markerAfterActiveChat(previous, active?.chatId)); }, [active?.chatId]); const loadHistory = useMemo( () => - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. createCoalescedReload(async () => { try { const res = await fetch(actionPath); @@ -315,7 +313,6 @@ export function DashboardAgentPanel({ void loadHistory(); const stored = readLastChat(storageKey); if (stored && stored.path === location.pathname) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. void openChat(stored.chatId); } else { setLoading(false); @@ -344,7 +341,7 @@ export function DashboardAgentPanel({ handledOpenChatSeq.current = openChatRequest.seq; // Reloading the visible transcript would drop a turn in flight. if (openChatRequest.chatId === active?.chatId) return; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + void openChat(openChatRequest.chatId); // `active` is read, not tracked: a later change must not re-run the request. // eslint-disable-next-line react-hooks/exhaustive-deps @@ -361,7 +358,7 @@ export function DashboardAgentPanel({ onChatRead?.(chatId, { leaving: false }); visibleChatId.current = nextVisibleChat(chatId, { leaving: false }); justRead.current.add(chatId); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + setChats((previous) => markChatListRead(previous, chatId)); // Read again on the way out: a wake can land while the chat is open. return () => { @@ -389,7 +386,6 @@ export function DashboardAgentPanel({ if (target === "hold") return; handledRequestSeq.current = requestedMessage.seq; if (target === "new-chat") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. void createChat(requestedMessage.text); return; } diff --git a/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx b/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx index 189f409dc7a..195f03599fb 100644 --- a/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx +++ b/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx @@ -183,7 +183,7 @@ export function VercelOnboardingModal({ hasSyncedStagingRef.current = false; hasSyncedPreviewRef.current = false; } else if (isOpen && state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState(computeInitialState()); } prevIsOpenRef.current = isOpen; @@ -263,7 +263,7 @@ export function VercelOnboardingModal({ // Strip "stg" from build settings when the staging environment mapping is cleared useEffect(() => { if (!vercelStagingEnvironment) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setPullEnvVarsBeforeBuild((prev) => prev.filter((s) => s !== "stg")); setDiscoverEnvVars((prev) => prev.filter((s) => s !== "stg")); } @@ -331,7 +331,7 @@ export function VercelOnboardingModal({ useEffect(() => { if (!isOpen) { hasTriggeredMarketplaceRedirectRef.current = false; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsRedirecting(false); } }, [isOpen]); @@ -393,7 +393,7 @@ export function VercelOnboardingModal({ state === "loading-projects" && onboardingData?.availableProjects !== undefined ) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("project-selection"); } }, [state, onboardingData?.availableProjects, onboardingData?.authInvalid]); @@ -404,7 +404,7 @@ export function VercelOnboardingModal({ state === "loading-env-vars" && onboardingData?.environmentVariables ) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("env-var-sync"); } }, [state, onboardingData?.environmentVariables, onboardingData?.authInvalid]); @@ -420,7 +420,7 @@ export function VercelOnboardingModal({ trackOnboarding("vercel onboarding project selected", { vercel_project_name: selectedVercelProject?.name, }); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("loading-env-mapping"); if (onDataReload) { onDataReload(); @@ -443,7 +443,7 @@ export function VercelOnboardingModal({ const hasCustomEnvs = (onboardingData.customEnvironments?.length ?? 0) > 0 && hasStagingEnvironment; if (hasCustomEnvs && !fromMarketplaceContext) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("env-mapping"); } else { setState("loading-env-vars"); @@ -668,7 +668,7 @@ export function VercelOnboardingModal({ } return; } - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("completed"); } }, [completeOnboardingFetcher.data, completeOnboardingFetcher.state, state]); @@ -683,7 +683,7 @@ export function VercelOnboardingModal({ return; } } - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("completed"); } }, [state, isGitHubConnectedForOnboarding, fromMarketplaceContext, nextUrl, trackOnboarding]); @@ -713,7 +713,7 @@ export function VercelOnboardingModal({ envMappingFetcher.data.success && envMappingFetcher.state === "idle" ) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setState("loading-env-vars"); } }, [envMappingFetcher.data, envMappingFetcher.state]); @@ -729,14 +729,14 @@ export function VercelOnboardingModal({ selectedEnv = stagingEnv ?? customEnvironments[0]; } - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setVercelStagingEnvironment({ environmentId: selectedEnv.id, displayName: selectedEnv.slug }); } }, [state, customEnvironments, vercelStagingEnvironment]); useEffect(() => { if (state === "project-selection" && availableProjects.length > 0 && !selectedVercelProject) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setSelectedVercelProject(availableProjects[0]); } }, [state, availableProjects, selectedVercelProject]); diff --git a/apps/webapp/app/components/logs/LogDetailView.tsx b/apps/webapp/app/components/logs/LogDetailView.tsx index adf691884f9..c0f52b76a46 100644 --- a/apps/webapp/app/components/logs/LogDetailView.tsx +++ b/apps/webapp/app/components/logs/LogDetailView.tsx @@ -68,7 +68,6 @@ export function LogDetailView({ logId, initialLog, onClose, searchTerm }: LogDet useEffect(() => { if (!logId) return; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. setError(null); fetcher.load( `/resources/orgs/${organization.slug}/projects/${project.slug}/env/${ @@ -81,7 +80,6 @@ export function LogDetailView({ logId, initialLog, onClose, searchTerm }: LogDet // Handle fetch errors useEffect(() => { if (fetcher.data && typeof fetcher.data === "object" && "error" in fetcher.data) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. setError(fetcher.data.error as string); } else if (fetcher.state === "idle" && fetcher.data === null && !initialLog) { setError("Failed to load log details"); diff --git a/apps/webapp/app/components/logs/LogsTable.tsx b/apps/webapp/app/components/logs/LogsTable.tsx index 73cefe32a0a..df9f97d09ff 100644 --- a/apps/webapp/app/components/logs/LogsTable.tsx +++ b/apps/webapp/app/components/logs/LogsTable.tsx @@ -76,7 +76,7 @@ export function LogsTable({ // Show load more spinner only after 0.2 seconds of loading time useEffect(() => { if (!isLoadingMore) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setShowLoadMoreSpinner(false); return; } diff --git a/apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx b/apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx index 90ebec0e9c7..acf8740ed2f 100644 --- a/apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx +++ b/apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx @@ -88,7 +88,7 @@ export function SaveToDashboardDialog({ useEffect(() => { if (customDashboards.length > 0 && !selectedDashboardId) { const available = customDashboards.find((d) => d.widgetCount < widgetLimit); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setSelectedDashboardId(available?.friendlyId ?? customDashboards[0].friendlyId); } }, [customDashboards, selectedDashboardId, widgetLimit]); diff --git a/apps/webapp/app/components/navigation/DashboardDialogs.tsx b/apps/webapp/app/components/navigation/DashboardDialogs.tsx index f9e4c643b5a..3668e719b4c 100644 --- a/apps/webapp/app/components/navigation/DashboardDialogs.tsx +++ b/apps/webapp/app/components/navigation/DashboardDialogs.tsx @@ -52,7 +52,7 @@ function useCreateDashboard({ useEffect(() => { if (navigation.formAction === formAction && navigation.state === "loading") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsOpen(false); } }, [navigation.formAction, navigation.state, formAction]); diff --git a/apps/webapp/app/components/navigation/EnvironmentSelector.tsx b/apps/webapp/app/components/navigation/EnvironmentSelector.tsx index 925c583d529..d07fb7899db 100644 --- a/apps/webapp/app/components/navigation/EnvironmentSelector.tsx +++ b/apps/webapp/app/components/navigation/EnvironmentSelector.tsx @@ -61,7 +61,6 @@ export function EnvironmentSelector({ const revalidator = useRevalidator(); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsMenuOpen(false); }, [navigation.location?.pathname]); @@ -250,7 +249,7 @@ function Branches({ }, []); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setMenuOpen(false); }, [navigation.location?.pathname]); diff --git a/apps/webapp/app/components/navigation/FavoritesSection.tsx b/apps/webapp/app/components/navigation/FavoritesSection.tsx index 48c6ecf1f04..1edab7ca99b 100644 --- a/apps/webapp/app/components/navigation/FavoritesSection.tsx +++ b/apps/webapp/app/components/navigation/FavoritesSection.tsx @@ -49,7 +49,7 @@ export function FavoriteMenuItem({ // Watch search too: navigating to a favorite can change only the search on the same pathname useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setMenuOpen(false); }, [navigation.location?.pathname, navigation.location?.search]); diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index 3227c021b98..e8a6a99f229 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -445,7 +445,7 @@ export function SideMenu({ const data = customizationFetcher.data; if (!data) { // Settled with no response body (e.g. a session-expiry redirect): fail rather than spin - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setCustomizeConfirmPending(false); setCustomizeError("Couldn't save your changes. Please try again."); return; @@ -532,7 +532,7 @@ export function SideMenu({ // object each render, so depending on it would fire the cleanup (flushing the debounce) every // render — and drags re-render constantly — instead of only on unmount. const flushPendingPreferencesRef = useRef<() => void>(); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. flushPendingPreferencesRef.current = () => { if (debounceTimeoutRef.current) { clearTimeout(debounceTimeoutRef.current); @@ -598,7 +598,7 @@ export function SideMenu({ }, []); // Animate width + progress over COLLAPSE_ANIM_MS (toggle button, ⌘B shortcut, release-snap). - /* oxlint-disable react/react-compiler -- The animation step is local to each callback invocation. */ + const animateTo = useCallback( (targetWidth: number, targetProgress: number) => { if (rafRef.current !== null) cancelAnimationFrame(rafRef.current); @@ -629,7 +629,6 @@ export function SideMenu({ }, [writeVisual] ); - /* oxlint-enable react/react-compiler */ // Collapse/expand to a resting state and remember it. const applyCollapsed = useCallback( @@ -648,7 +647,7 @@ export function SideMenu({ // Drag runs on window-level listeners so releasing anywhere finalizes it. (Pointer capture alone // was unreliable: if the browser drops it mid-drag, the release never fires and the menu strands.) - /* oxlint-disable react/react-compiler -- Drag handlers share invocation-local state and listeners. */ + const onHandlePointerDown = useCallback( (e: ReactPointerEvent) => { if (e.button !== 0) return; @@ -758,7 +757,6 @@ export function SideMenu({ }, [animateTo, applyCollapsed, persistSideMenuPreferences, writeVisual] ); - /* oxlint-enable react/react-compiler */ // Keep the drag handlers' collapsed mirror in sync; tear down any in-flight animation/drag on unmount. useEffect(() => { @@ -1497,7 +1495,7 @@ function SideMenuMoreItem({ // Watch search too: navigating to a favorite can change only the search on the same pathname useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setOpen(false); }, [navigation.location?.pathname, navigation.location?.search]); @@ -1711,7 +1709,7 @@ function OrgSelector({ const planTitle = currentPlan?.v3Subscription?.plan?.title; useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setOrgMenuOpen(false); }, [navigation.location?.pathname]); @@ -1990,7 +1988,7 @@ function AccountMenu({ isAdmin, isImpersonating }: { isAdmin: boolean; isImperso const navigation = useNavigation(); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsOpen(false); }, [navigation.location?.pathname]); @@ -2045,7 +2043,7 @@ function ProjectSelector({ const { urlForProject } = usePageSwitcher(); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsMenuOpen(false); }, [navigation.location?.pathname]); @@ -2167,7 +2165,7 @@ function SideMenuPopoverSubMenu({ // Close the submenu on navigation (the parent popover closes too). useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsOpen(false); }, [navigation.location?.pathname]); diff --git a/apps/webapp/app/components/navigation/SideMenuHeader.tsx b/apps/webapp/app/components/navigation/SideMenuHeader.tsx index 4bd88c2f6ca..b62d0118cf0 100644 --- a/apps/webapp/app/components/navigation/SideMenuHeader.tsx +++ b/apps/webapp/app/components/navigation/SideMenuHeader.tsx @@ -19,7 +19,7 @@ export function SideMenuHeader({ const navigation = useNavigation(); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setHeaderMenuOpen(false); }, [navigation.location?.pathname]); diff --git a/apps/webapp/app/components/navigation/useReorderableList.ts b/apps/webapp/app/components/navigation/useReorderableList.ts index 48eeb986923..5b2014a8365 100644 --- a/apps/webapp/app/components/navigation/useReorderableList.ts +++ b/apps/webapp/app/components/navigation/useReorderableList.ts @@ -34,7 +34,7 @@ export function useReorderableList({ const [order, setOrder] = useState(() => initialOrder ?? items.map(itemKey)); const resetOrderRef = useRef({ initialOrder, items, itemKey }); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. resetOrderRef.current = { initialOrder, items, itemKey }; // Only an organization switch resets user-managed order. Keep the latest inputs in a ref so diff --git a/apps/webapp/app/components/primitives/AgentDotMatrix.tsx b/apps/webapp/app/components/primitives/AgentDotMatrix.tsx index 9d1a78d8455..976d7f25d55 100644 --- a/apps/webapp/app/components/primitives/AgentDotMatrix.tsx +++ b/apps/webapp/app/components/primitives/AgentDotMatrix.tsx @@ -290,9 +290,9 @@ export function AgentDotMatrix({ const playlistKey = playlist.join(","); const paletteObjRef = useRef(paletteObj); const playlistRef = useRef(playlist); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. paletteObjRef.current = paletteObj; - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. playlistRef.current = playlist; useEffect(() => { diff --git a/apps/webapp/app/components/primitives/AnimatedCallout.tsx b/apps/webapp/app/components/primitives/AnimatedCallout.tsx index e71ba8bd7fd..bee07d580ad 100644 --- a/apps/webapp/app/components/primitives/AnimatedCallout.tsx +++ b/apps/webapp/app/components/primitives/AnimatedCallout.tsx @@ -41,14 +41,14 @@ export function AnimatedCallout({ useEffect(() => { if (!show) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setAutoDismissed(false); } }, [show]); useEffect(() => { if (shouldShow) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setRendered(true); return; } diff --git a/apps/webapp/app/components/primitives/Buttons.tsx b/apps/webapp/app/components/primitives/Buttons.tsx index c4332606013..7446eccf041 100644 --- a/apps/webapp/app/components/primitives/Buttons.tsx +++ b/apps/webapp/app/components/primitives/Buttons.tsx @@ -261,7 +261,7 @@ export function ButtonContent(props: ButtonContentPropsType) { const [showSpinner, setShowSpinner] = useState(false); useEffect(() => { if (!isLoading) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setShowSpinner(false); return; } diff --git a/apps/webapp/app/components/primitives/Checkbox.tsx b/apps/webapp/app/components/primitives/Checkbox.tsx index 6972294c48e..77419462dd6 100644 --- a/apps/webapp/app/components/primitives/Checkbox.tsx +++ b/apps/webapp/app/components/primitives/Checkbox.tsx @@ -111,7 +111,7 @@ export const CheckboxWithLabel = React.forwardRef { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsChecked(defaultChecked ?? false); }, [defaultChecked]); diff --git a/apps/webapp/app/components/primitives/ClipboardField.tsx b/apps/webapp/app/components/primitives/ClipboardField.tsx index c3498a915d9..c953add06cc 100644 --- a/apps/webapp/app/components/primitives/ClipboardField.tsx +++ b/apps/webapp/app/components/primitives/ClipboardField.tsx @@ -120,7 +120,7 @@ export function ClipboardField({ const { container, input, buttonVariant, button, size } = variants[variant]; useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsSecure(secure !== undefined && secure); }, [secure]); diff --git a/apps/webapp/app/components/primitives/DateField.tsx b/apps/webapp/app/components/primitives/DateField.tsx index 274811412f4..98addd0065a 100644 --- a/apps/webapp/app/components/primitives/DateField.tsx +++ b/apps/webapp/app/components/primitives/DateField.tsx @@ -81,7 +81,7 @@ export function DateField({ }); const stateValueRef = useRef(state.value); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. stateValueRef.current = state.value; // Sync only when the passed value or timezone mode changes. Depending on state.value directly diff --git a/apps/webapp/app/components/primitives/DateTime.tsx b/apps/webapp/app/components/primitives/DateTime.tsx index 9eb3c4af8ee..a3e75543a07 100644 --- a/apps/webapp/app/components/primitives/DateTime.tsx +++ b/apps/webapp/app/components/primitives/DateTime.tsx @@ -372,7 +372,7 @@ export const RelativeDateTime = ({ date, timeZone, capitalize = true }: Relative // On first render useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- A changed date intentionally resets the timer-backed relative text. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- A changed date intentionally resets the timer-backed relative text. setRelativeText(getRelativeText(realDate, capitalize)); }, [realDate, capitalize]); diff --git a/apps/webapp/app/components/primitives/DurationPicker.tsx b/apps/webapp/app/components/primitives/DurationPicker.tsx index 991563cec30..cc548de2349 100644 --- a/apps/webapp/app/components/primitives/DurationPicker.tsx +++ b/apps/webapp/app/components/primitives/DurationPicker.tsx @@ -48,7 +48,7 @@ export function DurationPicker({ const newMinutes = Math.floor((controlledValue % 3600) / 60); const newSeconds = controlledValue % 60; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setHours(newHours); setMinutes(newMinutes); setSeconds(newSeconds); diff --git a/apps/webapp/app/components/primitives/InputNumberStepper.tsx b/apps/webapp/app/components/primitives/InputNumberStepper.tsx index f298929c6fa..11fbb676f2b 100644 --- a/apps/webapp/app/components/primitives/InputNumberStepper.tsx +++ b/apps/webapp/app/components/primitives/InputNumberStepper.tsx @@ -10,7 +10,6 @@ type InputNumberStepperProps = Omit { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. calculateTruncation(); // Recalculate on resize (guard for jsdom/older browsers) diff --git a/apps/webapp/app/components/primitives/Resizable.tsx b/apps/webapp/app/components/primitives/Resizable.tsx index ece2dc77af0..6eb91412b11 100644 --- a/apps/webapp/app/components/primitives/Resizable.tsx +++ b/apps/webapp/app/components/primitives/Resizable.tsx @@ -100,9 +100,9 @@ function collapsibleHandleClassName(show: boolean) { function useFrozenValue(value: T | null | undefined): T | null | undefined { const ref = useRef(value); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. if (value != null) ref.current = value; - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. return ref.current; } diff --git a/apps/webapp/app/components/primitives/SearchInput.tsx b/apps/webapp/app/components/primitives/SearchInput.tsx index 2597cb9ec3b..c6693d40b85 100644 --- a/apps/webapp/app/components/primitives/SearchInput.tsx +++ b/apps/webapp/app/components/primitives/SearchInput.tsx @@ -70,7 +70,7 @@ export function SearchInput({ // Only mark synced once we actually apply it, so a URL change during focus still syncs on blur. if (!isFocused) { lastSyncedRef.current = urlSearch; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setText(urlSearch); } }, [isControlled, controlledValue, value, isFocused, paramName]); diff --git a/apps/webapp/app/components/primitives/TooltipPortal.tsx b/apps/webapp/app/components/primitives/TooltipPortal.tsx index 5f9337f8a4f..c8f1c9de8c3 100644 --- a/apps/webapp/app/components/primitives/TooltipPortal.tsx +++ b/apps/webapp/app/components/primitives/TooltipPortal.tsx @@ -39,7 +39,7 @@ export default function TooltipPortal({ active = true, children }: PopperPortalP useEffect(() => { const el = document.createElement("div"); document.body.appendChild(el); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setPortalElement(el); return () => el.remove(); }, []); diff --git a/apps/webapp/app/components/primitives/TreeView/TreeView.tsx b/apps/webapp/app/components/primitives/TreeView/TreeView.tsx index 28babf0a9c0..4e66af96fcf 100644 --- a/apps/webapp/app/components/primitives/TreeView/TreeView.tsx +++ b/apps/webapp/app/components/primitives/TreeView/TreeView.tsx @@ -193,7 +193,6 @@ export type UseTreeStateOutput = { scrollToNode: (id: string) => void; }; -// oxlint-disable-next-line react/react-compiler -- TanStack Virtual is not compatible with compiler memoization. export function useTree({ tree, selectedId, @@ -277,6 +276,7 @@ export function useTree({ dispatch({ type: "UPDATE_FILTER", payload: { filter: latestFilterRef.current } }); }, [serializedFilterValue]); + // oxlint-disable-next-line react/incompatible-library -- TanStack Virtual is not compatible with compiler memoization. const virtualizer = useVirtualizer({ count: state.visibleNodeIds.length, getItemKey: (index) => state.visibleNodeIds[index], diff --git a/apps/webapp/app/components/primitives/charts/hooks/useZoomSelection.ts b/apps/webapp/app/components/primitives/charts/hooks/useZoomSelection.ts index 4a5f2feea76..92e784bcec4 100644 --- a/apps/webapp/app/components/primitives/charts/hooks/useZoomSelection.ts +++ b/apps/webapp/app/components/primitives/charts/hooks/useZoomSelection.ts @@ -55,7 +55,7 @@ export function useZoomSelection(): UseZoomSelectionReturn { const stateRef = useRef(state); // Keep ref in sync with state - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. stateRef.current = state; const startSelection = useCallback((label: string) => { diff --git a/apps/webapp/app/components/query/QueryEditor.tsx b/apps/webapp/app/components/query/QueryEditor.tsx index 69f9e19a46c..68ba3c8ccbb 100644 --- a/apps/webapp/app/components/query/QueryEditor.tsx +++ b/apps/webapp/app/components/query/QueryEditor.tsx @@ -505,7 +505,7 @@ export function QueryEditor({ // Use a ref so the effect can read chartConfig without re-firing on every config tweak const chartConfigRef = useRef(chartConfig); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. chartConfigRef.current = chartConfig; // Reset chart config only when a column referenced by the current config is no @@ -563,7 +563,7 @@ export function QueryEditor({ }, []); // Compute current save data for the save render prop - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. const currentQuery = editorRef.current?.getQuery() ?? ""; const saveData: QueryEditorSaveData = { title: queryTitle ?? "Untitled Query", @@ -792,7 +792,7 @@ export function QueryEditor({ onRename={handleRenameTitle} /> } - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. query={editorRef.current?.getQuery() ?? defaultQuery} data={{ rows: results.rows, @@ -847,7 +847,7 @@ export function QueryEditor({ { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setRenameValue(title ?? ""); }, [title]); diff --git a/apps/webapp/app/components/queues/QueueControls.tsx b/apps/webapp/app/components/queues/QueueControls.tsx index 5cfe0c69e9c..b2499bb6d0e 100644 --- a/apps/webapp/app/components/queues/QueueControls.tsx +++ b/apps/webapp/app/components/queues/QueueControls.tsx @@ -183,7 +183,7 @@ export function QueueOverrideConcurrencyButton({ useEffect(() => { if (navigation.state === "loading" || navigation.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsOpen(false); } }, [navigation.state]); diff --git a/apps/webapp/app/components/runs/v3/AIFilterInput.tsx b/apps/webapp/app/components/runs/v3/AIFilterInput.tsx index 5faf1581496..664cffcf68c 100644 --- a/apps/webapp/app/components/runs/v3/AIFilterInput.tsx +++ b/apps/webapp/app/components/runs/v3/AIFilterInput.tsx @@ -39,7 +39,7 @@ export function AIFilterInput() { useEffect(() => { if (fetcher.data?.success && fetcher.state === "loading") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setText(""); setIsFocused(false); @@ -185,7 +185,7 @@ function ErrorPopover({ useEffect(() => { if (error) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setIsOpen(true); } if (timeout.current) { diff --git a/apps/webapp/app/components/runs/v3/RunStatusCellTooltip.tsx b/apps/webapp/app/components/runs/v3/RunStatusCellTooltip.tsx index e1a25dbbabb..73c23e035b9 100644 --- a/apps/webapp/app/components/runs/v3/RunStatusCellTooltip.tsx +++ b/apps/webapp/app/components/runs/v3/RunStatusCellTooltip.tsx @@ -100,7 +100,7 @@ function useChildRunStatusesTooltip({ key: `child-statuses-${friendlyId}`, }); const fetcherStateRef = useRef(fetcher.state); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + fetcherStateRef.current = fetcher.state; const [childStatuses, setChildStatuses] = useState(); @@ -121,7 +121,7 @@ function useChildRunStatusesTooltip({ // Keep the latest loader callback available to the polling interval // without recreating the interval on every render. const loadChildStatusesRef = useRef(loadChildStatuses); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + loadChildStatusesRef.current = loadChildStatuses; const stopPolling = useCallback(() => { @@ -146,7 +146,6 @@ function useChildRunStatusesTooltip({ const entry = fetcher.data.runs.find((run) => run.friendlyId === friendlyId); if (!entry) return; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. setChildStatuses((previous) => areChildStatusesEqual(previous, entry.statuses) ? previous : entry.statuses ); @@ -172,7 +171,7 @@ function useChildRunStatusesTooltip({ useEffect(() => { prevHasFinishedRef.current = hasFinished; stopPolling(); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + setChildStatuses(undefined); if (isOpenRef.current) { loadChildStatuses(); diff --git a/apps/webapp/app/components/runs/v3/SharedFilters.tsx b/apps/webapp/app/components/runs/v3/SharedFilters.tsx index 0588ece063f..eef5f98b185 100644 --- a/apps/webapp/app/components/runs/v3/SharedFilters.tsx +++ b/apps/webapp/app/components/runs/v3/SharedFilters.tsx @@ -519,7 +519,7 @@ function TimeDropdown({ // Sync state when props change useEffect(() => { const parsed = getInitialCustomDuration(period); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setCustomValue(parsed.value); setCustomUnit(parsed.unit); diff --git a/apps/webapp/app/components/runs/v3/agent/AgentView.tsx b/apps/webapp/app/components/runs/v3/agent/AgentView.tsx index 58797b1f75c..f2570e3b928 100644 --- a/apps/webapp/app/components/runs/v3/agent/AgentView.tsx +++ b/apps/webapp/app/components/runs/v3/agent/AgentView.tsx @@ -285,7 +285,6 @@ function useAgentSessionMessages({ // `scheduleFlush`. The Map *reference* changes on every flush so React // detects the state update and the downstream `useMemo` recomputes. const [messagesById, setMessagesById] = useState>( - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. () => new Map(pendingRef.current) ); @@ -295,7 +294,7 @@ function useAgentSessionMessages({ const lastFlushAtRef = useRef(0); const pendingTimerRef = useRef | null>(null); const scheduleFlush = useRef<() => void>(() => {}); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + scheduleFlush.current = () => { if (pendingTimerRef.current !== null) return; // already scheduled const now = Date.now(); @@ -672,7 +671,7 @@ function useAgentSessionMessages({ return useMemo(() => { const timestamps = timestampsRef.current; const arr = Array.from(messagesById.values()); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + arr.sort((a, b) => { const ta = timestamps.get(a.id) ?? 0; const tb = timestamps.get(b.id) ?? 0; diff --git a/apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx b/apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx index bdafce941e0..046ac151d4b 100644 --- a/apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx +++ b/apps/webapp/app/components/runs/v3/ai/AIChatMessages.tsx @@ -289,7 +289,7 @@ export function ToolUseRow({ tool }: { tool: ToolUse }) { // Auto-select input tab when input arrives after initial render (e.g. streaming tool calls) useEffect(() => { if (!hasSubAgent && hasInput) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setActiveTab((current) => current ?? "input"); } }, [hasInput, hasSubAgent]); diff --git a/apps/webapp/app/components/scheduled/timezones.tsx b/apps/webapp/app/components/scheduled/timezones.tsx index 7116e13cee5..023c20920b3 100644 --- a/apps/webapp/app/components/scheduled/timezones.tsx +++ b/apps/webapp/app/components/scheduled/timezones.tsx @@ -2,10 +2,10 @@ import { useVirtualizer } from "@tanstack/react-virtual"; import { useRef } from "react"; import { SelectItem } from "../primitives/Select"; -// oxlint-disable-next-line react/react-compiler -- TanStack Virtual is not compatible with compiler memoization. export function TimezoneList({ timezones }: { timezones: string[] }) { const parentRef = useRef(null); + // oxlint-disable-next-line react/incompatible-library -- TanStack Virtual is not compatible with compiler memoization. const rowVirtualizer = useVirtualizer({ count: timezones.length, getScrollElement: () => parentRef.current, diff --git a/apps/webapp/app/components/schedules/PurchaseSchedulesModal.tsx b/apps/webapp/app/components/schedules/PurchaseSchedulesModal.tsx index 497486b530b..53f561c652c 100644 --- a/apps/webapp/app/components/schedules/PurchaseSchedulesModal.tsx +++ b/apps/webapp/app/components/schedules/PurchaseSchedulesModal.tsx @@ -75,7 +75,7 @@ export function PurchaseSchedulesModal({ useEffect(() => { if (!open) return; - // oxlint-disable-next-line react/react-compiler -- Keep the open draft aligned with authoritative billing values. + // oxlint-disable-next-line react/set-state-in-effect -- Keep the open draft aligned with authoritative billing values. setBundles(Math.round(extraSchedules / stepSize)); }, [open, extraSchedules, stepSize]); @@ -88,7 +88,7 @@ export function PurchaseSchedulesModal({ "ok" in data && data.ok ) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setOpen(false); } }, [fetcher.state, fetcher.data]); diff --git a/apps/webapp/app/components/webhookConsole/SampleSourcePicker.tsx b/apps/webapp/app/components/webhookConsole/SampleSourcePicker.tsx index 7f2c2b83bb8..9392670da7b 100644 --- a/apps/webapp/app/components/webhookConsole/SampleSourcePicker.tsx +++ b/apps/webapp/app/components/webhookConsole/SampleSourcePicker.tsx @@ -46,7 +46,7 @@ export function SampleSourcePicker({ useEffect(() => { if (!providers || providers.length === 0) return; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setSelectedProvider((current) => { if (current && providers.some((p) => p.id === current)) return current; if (endpointSource && providers.some((p) => p.id === endpointSource)) return endpointSource; diff --git a/apps/webapp/app/components/webhookDeliveries/v1/useDeliveriesLiveReload.ts b/apps/webapp/app/components/webhookDeliveries/v1/useDeliveriesLiveReload.ts index 9cf28d80237..5469c68d006 100644 --- a/apps/webapp/app/components/webhookDeliveries/v1/useDeliveriesLiveReload.ts +++ b/apps/webapp/app/components/webhookDeliveries/v1/useDeliveriesLiveReload.ts @@ -124,7 +124,7 @@ export function useDeliveriesLiveReload({ const location = useLocation(); const deliveriesPollFetcher = useTypedFetcher(); const deliveriesPollFetcherStateRef = useRef(deliveriesPollFetcher.state); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. deliveriesPollFetcherStateRef.current = deliveriesPollFetcher.state; const [visibleDeliveries, setVisibleDeliveries] = useState(deliveries); @@ -141,7 +141,7 @@ export function useDeliveriesLiveReload({ } = useNewDeliveriesDetection({ deliveries, isLoading }); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setVisibleDeliveries(deliveries); resetNewDeliveriesTracking(); }, [deliveries, location.search, resetNewDeliveriesTracking]); @@ -150,7 +150,7 @@ export function useDeliveriesLiveReload({ const data = deliveriesPollFetcher.data; if (!data?.deliveries.length) return; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setVisibleDeliveries((current) => patchVisibleDeliveriesWithLiveUpdates(current, data.deliveries) ); diff --git a/apps/webapp/app/hooks/useAutoRevalidate.ts b/apps/webapp/app/hooks/useAutoRevalidate.ts index eec1f3c34fc..ff12f01c209 100644 --- a/apps/webapp/app/hooks/useAutoRevalidate.ts +++ b/apps/webapp/app/hooks/useAutoRevalidate.ts @@ -11,7 +11,7 @@ export function useAutoRevalidate(options: UseAutoRevalidateOptions = {}) { const { interval = 5000, onFocus = true, disabled = false } = options; const revalidator = useRevalidator(); const revalidatorRef = useRef(revalidator); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. revalidatorRef.current = revalidator; useEffect(() => { diff --git a/apps/webapp/app/hooks/useChanged.ts b/apps/webapp/app/hooks/useChanged.ts index f7e08dd3a48..5f05559f196 100644 --- a/apps/webapp/app/hooks/useChanged.ts +++ b/apps/webapp/app/hooks/useChanged.ts @@ -12,9 +12,9 @@ export function useChanged( const itemRef = useRef(); const itemId = item?.id; - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. actionRef.current = action; - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. itemRef.current = item; useEffect(() => { diff --git a/apps/webapp/app/hooks/useDashboardEditor.ts b/apps/webapp/app/hooks/useDashboardEditor.ts index d7fae76383b..7affadccce3 100644 --- a/apps/webapp/app/hooks/useDashboardEditor.ts +++ b/apps/webapp/app/hooks/useDashboardEditor.ts @@ -207,7 +207,7 @@ export function useDashboardEditor({ const isInitializedRef = useRef(false); const currentLayoutJsonRef = useRef(JSON.stringify(initialData.layout)); const initialDataRef = useRef(initialData); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. initialDataRef.current = initialData; // Sync queue to prevent race conditions @@ -258,7 +258,7 @@ export function useDashboardEditor({ // Sync queue processor - ensures only one sync runs at a time // ------------------------------------------------------------------------- - /* oxlint-disable react/react-compiler -- The recursive callback drains a serialized sync queue. */ + /* oxlint-disable react/preserve-manual-memoization -- The recursive callback drains a serialized sync queue. */ const processNextSync = useCallback(async () => { // If already syncing or queue is empty, do nothing if (isSyncingRef.current || syncQueueRef.current.length === 0) { @@ -311,7 +311,7 @@ export function useDashboardEditor({ processNextSync(); } }, [widgetActionUrl, layoutActionUrl, onSyncError]); - /* oxlint-enable react/react-compiler */ + /* oxlint-enable react/preserve-manual-memoization */ // ------------------------------------------------------------------------- // Queue helpers diff --git a/apps/webapp/app/hooks/useDebounce.ts b/apps/webapp/app/hooks/useDebounce.ts index b9bb51e48cc..42545216ec0 100644 --- a/apps/webapp/app/hooks/useDebounce.ts +++ b/apps/webapp/app/hooks/useDebounce.ts @@ -29,7 +29,7 @@ export function useDebounceEffect(value: T, fn: (value: T) => void, delay: nu const fnRef = useRef(fn); // Update the ref whenever the function changes - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. fnRef.current = fn; useEffect(() => { diff --git a/apps/webapp/app/hooks/useElementVisibility.ts b/apps/webapp/app/hooks/useElementVisibility.ts index 44726cece0d..be04c1f998d 100644 --- a/apps/webapp/app/hooks/useElementVisibility.ts +++ b/apps/webapp/app/hooks/useElementVisibility.ts @@ -8,7 +8,7 @@ export function useElementVisibility({ onVisibilityChange }: UseElementVisibilit const ref = useRef(null); const isVisibleRef = useRef(false); const callbackRef = useRef(onVisibilityChange); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative integration outside React state. callbackRef.current = onVisibilityChange; useEffect(() => { diff --git a/apps/webapp/app/hooks/useEventSource.tsx b/apps/webapp/app/hooks/useEventSource.tsx index 63c3b18734e..4f76db5e05a 100644 --- a/apps/webapp/app/hooks/useEventSource.tsx +++ b/apps/webapp/app/hooks/useEventSource.tsx @@ -24,7 +24,7 @@ export function useEventSource( } // reset data if dependencies change - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. setData(null); const eventSource = new EventSource(url, init); diff --git a/apps/webapp/app/hooks/useMetricResourceQuery.ts b/apps/webapp/app/hooks/useMetricResourceQuery.ts index 8fa3738376d..fe8e8f397ee 100644 --- a/apps/webapp/app/hooks/useMetricResourceQuery.ts +++ b/apps/webapp/app/hooks/useMetricResourceQuery.ts @@ -214,7 +214,7 @@ export function useMetricResourceQuery(query: string, opts: MetricResourceQueryO ]); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes local state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes local state after an external or lifecycle change. load(); return () => abortRef.current?.abort(); }, [load]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx index 744332fabad..55741c30548 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx @@ -243,7 +243,7 @@ export default function Page() { const usefulLinksPanelRef = useRef(null); const fetcher = useFetcher(); const fetcherRef = useRef(fetcher); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. fetcherRef.current = fetcher; const toggleUsefulLinks = useCallback((show: boolean) => { diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx index d726b4e0163..1717cc7681f 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx @@ -617,7 +617,7 @@ function NewApiKeyDialog({ } if (actionData?.ok && actionData.action === "create") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setCreatedApiKey(actionData.apiKey); } else if (actionData && !actionData.ok) { setShowError(true); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx index a5c986ebce9..3baba8a2ee7 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx @@ -652,7 +652,7 @@ function PurchaseBranchesModal({ const [amountValue, setAmountValue] = useState(extraBranches); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- The authoritative branch count intentionally resets this modal draft. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- The authoritative branch count intentionally resets this modal draft. setAmountValue(extraBranches); }, [extraBranches]); const isLoading = fetcher.state !== "idle"; @@ -667,7 +667,7 @@ function PurchaseBranchesModal({ "ok" in data && data.ok ) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setOpen(false); } }, [fetcher.state, fetcher.data]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx index a89bccf27f1..d6fce9f7ba0 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx @@ -648,7 +648,7 @@ function PurchaseConcurrencyModal({ const [open, setOpen] = useState(false); useEffect(() => { if (purchaseSucceeded) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setOpen(false); setSearchParams((s) => { s.delete("success"); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardKey/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardKey/route.tsx index 31f14f8b70d..0736dc690c0 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardKey/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.$dashboardKey/route.tsx @@ -444,7 +444,7 @@ function useContainerWidth(initialWidth = 1280) { useEffect(() => { measureWidth(); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setMounted(true); const element = containerRef.current; diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.custom.$dashboardId/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.custom.$dashboardId/route.tsx index 9b2664139e2..93536d89d6c 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.custom.$dashboardId/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.custom.$dashboardId/route.tsx @@ -677,14 +677,14 @@ function RenameDashboardDialog({ title }: { title: string }) { // Close dialog when navigation completes useEffect(() => { if (navigation.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsOpen(false); } }, [navigation.state]); // Sync newTitle state when title changes (after successful rename) useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- A completed rename intentionally resets this editable title draft. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- A completed rename intentionally resets this editable title draft. setNewTitle(title); }, [title]); @@ -751,7 +751,7 @@ function DeleteDashboardDialog({ title }: { title: string }) { // Close dialog when navigation completes useEffect(() => { if (navigation.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsOpen(false); } }, [navigation.state]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx index 851b0ba75ee..ee503b726d3 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx @@ -214,7 +214,7 @@ export default function Page() { const abortController = new AbortController(); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setLogs([]); setStreamError(null); setIsStreaming(true); @@ -632,7 +632,7 @@ function LogsDisplay({ const logsContainerRef = useRef(null); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- Deployment status changes intentionally reset the user-controlled collapse state. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- Deployment status changes intentionally reset the user-controlled collapse state. setCollapsed(initialCollapsed); }, [initialCollapsed]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx index 28bd697e04b..617dc577b80 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx @@ -451,7 +451,7 @@ function EnvironmentVariablesListPage({ const [isVirtualized, setIsVirtualized] = useState(false); useLayoutEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsVirtualized(shouldVirtualize); }, [shouldVirtualize]); @@ -744,7 +744,6 @@ function EnvironmentVariableTableRow({ ); } -// oxlint-disable-next-line react/react-compiler -- TanStack Virtual is not compatible with compiler memoization. function EnvironmentVariablesVirtualTableBody({ groupedEnvironmentVariables, scrollRef, @@ -758,6 +757,7 @@ function EnvironmentVariablesVirtualTableBody({ vercelIntegration: PageVercelIntegration | null; columnCount: number; }) { + // oxlint-disable-next-line react/incompatible-library -- TanStack Virtual is not compatible with compiler memoization. const rowVirtualizer = useVirtualizer({ count: groupedEnvironmentVariables.length, getScrollElement: () => scrollRef.current, @@ -816,7 +816,7 @@ function EditEnvironmentVariablePanel({ // Close dialog on successful submission useEffect(() => { if (lastSubmission?.success && fetcher.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsOpen(false); } }, [lastSubmission?.success, fetcher.state]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs/route.tsx index a1d55a90330..4639fba8459 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs/route.tsx @@ -318,7 +318,7 @@ function LogsList({ // Clear accumulated logs immediately when filters change (for instant visual feedback) useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setAccumulatedLogs([]); setNextCursor(undefined); // Preserve log selection from URL param, clear if not present @@ -328,7 +328,7 @@ function LogsList({ // Populate accumulated logs when new data arrives useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setAccumulatedLogs(list.logs); setNextCursor(list.pagination.next); }, [list.logs, list.pagination.next]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx index c13a64b0a60..1fc159fac7c 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx @@ -207,7 +207,7 @@ function PlaygroundChat() { activeConversation?.clientData ? JSON.stringify(activeConversation.clientData, null, 2) : "{}" ); const clientDataJsonRef = useRef(clientDataJson); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. clientDataJsonRef.current = clientDataJson; const [machine, setMachine] = useState(undefined); const [tags, setTags] = useState([]); @@ -268,14 +268,14 @@ function PlaygroundChat() { // silently ignored on the first send. Mirror the `clientDataJsonRef` // pattern so the transport always calls the latest `startSession`. const startSessionRef = useRef(startSession); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. startSessionRef.current = startSession; // Create TriggerChatTransport directly (not via useTriggerChatTransport hook // to avoid React version mismatch between SDK and webapp) const transportRef = useRef(null); if (transportRef.current === null) { - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. transportRef.current = new TriggerChatTransport({ task: agent.slug, // The Remix action is idempotent on `(env, externalId)` and @@ -304,7 +304,7 @@ function PlaygroundChat() { : {}), }); } - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. const transport = transportRef.current; // Keep the transport's `defaultMetadata` in sync with the JSON editor. @@ -355,7 +355,7 @@ function PlaygroundChat() { ); // useChat from AI SDK — handles message accumulation, streaming, stop - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. const { messages, sendMessage, stop, status, error } = useChat({ id: chatId, messages: initialMessages, @@ -396,10 +396,10 @@ function PlaygroundChat() { inputRef.current?.focus(); }, [isEmpty]); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. const session = transport.getSession(chatId); - /* oxlint-disable react/react-compiler -- The transport and chat ID are stable for this component's lifetime. */ + /* oxlint-disable react/memo-dependencies -- The transport and chat ID are stable for this component's lifetime. */ const handlePreload = useCallback(async () => { setPreloading(true); try { @@ -410,7 +410,7 @@ function PlaygroundChat() { setPreloading(false); } }, [transport, chatId]); - /* oxlint-enable react/react-compiler */ + /* oxlint-enable react/memo-dependencies */ const handleNewConversation = useCallback(() => { // Navigate without ?conversation= so the loader returns activeConversation=null @@ -1177,7 +1177,7 @@ function usePlaygroundPendingMessages({ [status, transport, chatId, sendMessage, metadata] ); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. const pending: PendingMessageEntry[] = pendingMsgs.map((m) => ({ id: m.id, text: m.parts[0]?.text ?? "", diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx index e5b4f900512..d8f4bec18aa 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.prompts.$promptSlug/route.tsx @@ -909,7 +909,7 @@ function OverrideDialog({ // Reset when dialog opens useEffect(() => { if (open) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setEditedContent(content); setCommitMessage(""); setModel(currentOverrideModel ?? prompt.defaultModel ?? ""); @@ -1333,7 +1333,7 @@ function GenerationsTab({ // Append fetched rows when fetcher completes useEffect(() => { if (fetcher.data && fetcher.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setGenerations((prev) => { const existingIds = new Set(prev.map((g) => g.span_id)); const newRows = fetcher.data!.generations.filter((g) => !existingIds.has(g.span_id)); @@ -1424,7 +1424,7 @@ function GenerationsTab({ const [showSpinner, setShowSpinner] = useState(false); useEffect(() => { if (!isLoadingMore) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setShowSpinner(false); return; } diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx index 597901527a1..06fd1b22089 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx @@ -1035,7 +1035,7 @@ function EnvironmentPauseResumeButton({ useEffect(() => { if (navigation.state === "loading" || navigation.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsOpen(false); } }, [navigation.state]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues_.$queueParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues_.$queueParam/route.tsx index c0c0f5016c6..67acb397a50 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues_.$queueParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues_.$queueParam/route.tsx @@ -899,7 +899,7 @@ function useConcurrencyKeys(opts: { }, [body]); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. load(); return () => abortRef.current?.abort(); }, [load]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 9a332a08fb1..27eb4cf10d8 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -1264,7 +1264,7 @@ function TimelineView({ const [duration, setDuration] = useState(queueAdjustedNs(totalDuration, queuedDuration)); useEffect(() => { if (rootSpanStatus !== "executing" || !rootStartedAt) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setDuration(queueAdjustedNs(totalDuration, queuedDuration)); return; } diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/useRunsLiveReload.ts b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/useRunsLiveReload.ts index eb8bff60666..90088952f25 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/useRunsLiveReload.ts +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/useRunsLiveReload.ts @@ -165,7 +165,7 @@ export function useRunsLiveReload({ const location = useLocation(); const runsPollFetcher = useTypedFetcher(); const runsPollFetcherStateRef = useRef(runsPollFetcher.state); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. runsPollFetcherStateRef.current = runsPollFetcher.state; const [visibleRuns, setVisibleRuns] = useState(runs); @@ -193,7 +193,7 @@ export function useRunsLiveReload({ // Single reset path: new loader data or changed filters re-baseline both the // visible rows and new-run tracking. useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setVisibleRuns(runs); resetNewRunsTracking(); }, [runs, searchKeyWithoutPagination, resetNewRunsTracking]); @@ -204,7 +204,7 @@ export function useRunsLiveReload({ const data = runsPollFetcher.data; if (!data?.runs.length) return; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setVisibleRuns((currentRuns) => patchVisibleRunsWithLiveUpdates(currentRuns, data.runs)); }, [runsPollFetcher.data]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx index 1880c2c1112..3f8017227d1 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx @@ -261,7 +261,6 @@ const ROW_NUMBER_COL_MIN_CH = 3; const TIME_COL_WIDTH = "7rem"; const TYPE_COL_WIDTH = "5rem"; -// oxlint-disable-next-line react/react-compiler -- TanStack Virtual is not compatible with compiler memoization. function RawConversationView({ inResourcePath, outResourcePath, @@ -387,6 +386,7 @@ function RawConversationView({ return () => cancelAnimationFrame(raf); }, [merged, isAtBottom]); + // oxlint-disable-next-line react/incompatible-library -- TanStack Virtual is not compatible with compiler memoization. const rowVirtualizer = useVirtualizer({ count: merged.length, getScrollElement: () => scrollRef.current, diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.settings.integrations/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.settings.integrations/route.tsx index 9554aff131c..864cc300fa4 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.settings.integrations/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.settings.integrations/route.tsx @@ -261,7 +261,7 @@ export default function IntegrationsSettingsPage() { if (onboardingData && vercelFetcher.state === "idle") { // Data is loaded, ensure modal is open (query param takes precedence) if (!isModalOpen) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. openVercelOnboarding(); } } else if (vercelFetcher.state === "idle" && !hasVercelFetcherData) { @@ -290,7 +290,7 @@ export default function IntegrationsSettingsPage() { if (hasQueryParam && !isModalOpen) { // Query param is present but modal is closed, open it // This ensures the modal stays open during the onboarding flow - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. openVercelOnboarding(); } }, [hasQueryParam, isModalOpen, openVercelOnboarding]); @@ -300,7 +300,7 @@ export default function IntegrationsSettingsPage() { if (hasQueryParam && onboardingData && vercelFetcher.state === "idle") { // Data loaded and query param is present, ensure modal is open if (!isModalOpen) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. openVercelOnboarding(); } } @@ -445,7 +445,7 @@ function BuildSettingsForm({ buildSettings }: { buildSettings: BuildSettings }) buildSettingsValues.installCommand !== (buildSettings?.installCommand || "") || buildSettingsValues.triggerConfigFilePath !== (buildSettings?.triggerConfigFilePath || "") || buildSettingsValues.useNativeBuildServer !== nativeBuildServerEnabled; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setHasBuildSettingsChanges(hasChanges); }, [buildSettingsValues, buildSettings, nativeBuildServerEnabled]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx index 590556e087b..1ec27ba6a4c 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx @@ -651,7 +651,7 @@ function ScheduleSheet({ // Always reopen in inspect mode. useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setMode("inspect"); }, [openScheduleId]); @@ -694,7 +694,7 @@ function ScheduleSheet({ handledUpdateRef.current = data; if (data.ok) { toast.success(data.message ?? "Schedule updated"); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setMode("inspect"); if (detailPath) loadScheduleDetail(detailPath); revalidator.revalidate(); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx index c3ba7694ba3..887dc384c02 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx @@ -1585,7 +1585,7 @@ function RunTemplatesPopover({ useEffect(() => { if (lastSubmission && "success" in lastSubmission && lastSubmission.success === true) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsDeleteDialogOpen(false); } }, [lastSubmission]); @@ -1773,7 +1773,7 @@ function CreateTemplateModal({ useEffect(() => { if (lastSubmission && "success" in lastSubmission && lastSubmission.success === true) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsModalOpen(false); setShowCreatedSuccessMessage(true); clearTimeout(successMessageTimeoutRef.current); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.webhooks.endpoints.$endpointParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.webhooks.endpoints.$endpointParam/route.tsx index f7fba86c64e..4fce66597e5 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.webhooks.endpoints.$endpointParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.webhooks.endpoints.$endpointParam/route.tsx @@ -614,7 +614,7 @@ function SetSecretDialog({ // Close on a successful save; the loader revalidates and the state flips to "Set". useEffect(() => { if (fetcher.state === "idle" && fetcher.data?.success) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setOpen(false); } }, [fetcher.state, fetcher.data]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso/route.tsx index 019798b2daf..e3500d5398e 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso/route.tsx @@ -375,7 +375,7 @@ function useOverrideDraft(serverValue: T): { const [override, setOverride] = useState<{ value: T } | null>(null); useEffect(() => { // Server matches the pending edit → clear the override. - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setOverride((current) => (current && Object.is(current.value, serverValue) ? null : current)); }, [serverValue]); const value = override ? override.value : serverValue; @@ -420,7 +420,7 @@ export default function Page() { useEffect(() => { if (portalFetcher.data?.ok && portalFetcher.data.url) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setPortalUrl(portalFetcher.data.url); } }, [portalFetcher.data]); @@ -919,7 +919,7 @@ function DirectorySyncSection({ // server value so polled-in groups appear and matched overrides drop. const [draftGroupRoles, setDraftGroupRoles] = useState>({}); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setDraftGroupRoles((current) => { const next: Record = {}; for (const g of directorySync.groups) { diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx index 80ba22056d1..b4b7eb4971f 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx @@ -970,7 +970,7 @@ export function PurchaseSeatsModal({ const [amountValue, setAmountValue] = useState(extraSeats); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- The authoritative seat count intentionally resets this modal draft. + // oxlint-disable-next-line react/set-state-in-effect, react/no-deriving-state-in-effects -- The authoritative seat count intentionally resets this modal draft. setAmountValue(extraSeats); }, [extraSeats]); const isLoading = fetcher.state !== "idle"; @@ -985,7 +985,7 @@ export function PurchaseSeatsModal({ "ok" in data && data.ok ) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setOpen(false); } }, [fetcher.state, fetcher.data]); diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug_.projects.new/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug_.projects.new/route.tsx index ce82f4caa8a..a268bd26ff9 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug_.projects.new/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug_.projects.new/route.tsx @@ -360,7 +360,7 @@ export default function Page() { useEffect(() => { const nonOther = workingOnOptions.filter((o) => o !== WORKING_ON_OTHER); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setShuffledWorkingOn([...shuffleArray(nonOther), WORKING_ON_OTHER]); const nonOtherGoals = goalOptions.filter((o) => o !== GOALS_OTHER); diff --git a/apps/webapp/app/routes/account._index/route.tsx b/apps/webapp/app/routes/account._index/route.tsx index 246904d0b24..9d78165835d 100644 --- a/apps/webapp/app/routes/account._index/route.tsx +++ b/apps/webapp/app/routes/account._index/route.tsx @@ -221,7 +221,7 @@ export default function Page() { const [contrastPreview, setContrastPreview] = useState(contrast); useEffect(() => { if (contrastFetcher.state === "idle") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setContrastPreview(contrast); document.documentElement.style.setProperty("--theme-contrast", String(contrast / 100)); } diff --git a/apps/webapp/app/routes/admin.feature-flags.tsx b/apps/webapp/app/routes/admin.feature-flags.tsx index 22799689117..be0f6174622 100644 --- a/apps/webapp/app/routes/admin.feature-flags.tsx +++ b/apps/webapp/app/routes/admin.feature-flags.tsx @@ -182,14 +182,14 @@ export default function AdminFeatureFlagsRoute() { editable[key] = value; } } - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setValues({ ...editable }); setInitialValues({ ...editable }); }, [globalFlags, unlocked]); useEffect(() => { if (saveFetcher.data?.success) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setSaveError(null); setConfirmOpen(false); } else if (saveFetcher.data?.error) { diff --git a/apps/webapp/app/routes/admin.queue-metrics.tsx b/apps/webapp/app/routes/admin.queue-metrics.tsx index 1701c609c7c..5b44404576c 100644 --- a/apps/webapp/app/routes/admin.queue-metrics.tsx +++ b/apps/webapp/app/routes/admin.queue-metrics.tsx @@ -65,7 +65,7 @@ export default function AdminQueueMetricsRoute() { const handledSaveDataRef = useRef(saveFetcher.data); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setEnabled(controls.enabled); setSampleRate(String(controls.sampleRate)); }, [controls.enabled, controls.sampleRate]); @@ -77,7 +77,7 @@ export default function AdminQueueMetricsRoute() { handledSaveDataRef.current = saveFetcher.data; if (saveFetcher.data.success) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setError(null); revalidate(); } else if (saveFetcher.data.error) { diff --git a/apps/webapp/app/routes/confirm-basic-details.tsx b/apps/webapp/app/routes/confirm-basic-details.tsx index 8e189817f6a..8258e79b606 100644 --- a/apps/webapp/app/routes/confirm-basic-details.tsx +++ b/apps/webapp/app/routes/confirm-basic-details.tsx @@ -228,7 +228,7 @@ export default function Page() { useEffect(() => { const nonOtherReferral = referralSourceOptions.filter((r) => r !== "Other"); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setShuffledReferralSources([...shuffleArray(nonOtherReferral), "Other"]); const nonOtherRoles = roleOptions.filter((r) => r !== "Other"); diff --git a/apps/webapp/app/routes/login.mfa/route.tsx b/apps/webapp/app/routes/login.mfa/route.tsx index 16dfb81c208..238880af800 100644 --- a/apps/webapp/app/routes/login.mfa/route.tsx +++ b/apps/webapp/app/routes/login.mfa/route.tsx @@ -197,7 +197,7 @@ export default function LoginMfaPage() { // Reset hideError when a new error appears React.useEffect(() => { if (rawMfaError) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setHideError(false); } }, [rawMfaError]); diff --git a/apps/webapp/app/routes/resources.account.mfa.setup/useMfaSetup.ts b/apps/webapp/app/routes/resources.account.mfa.setup/useMfaSetup.ts index 1c7d7b028ba..a5efd18935c 100644 --- a/apps/webapp/app/routes/resources.account.mfa.setup/useMfaSetup.ts +++ b/apps/webapp/app/routes/resources.account.mfa.setup/useMfaSetup.ts @@ -178,10 +178,12 @@ export function useMfaSetup(initialIsEnabled: boolean) { disableMethod: "totp", }); + const fetcherData = fetcher.data; + // Handle fetcher responses useEffect(() => { - if (fetcher.data) { - const { data } = fetcher; + if (fetcherData) { + const data = fetcherData; switch (data.action) { case "enable-mfa": @@ -222,7 +224,7 @@ export function useMfaSetup(initialIsEnabled: boolean) { break; } } - }, [fetcher.data]); + }, [fetcherData]); // Handle submitting state useEffect(() => { diff --git a/apps/webapp/app/routes/resources.branches.create.tsx b/apps/webapp/app/routes/resources.branches.create.tsx index ed033b31d08..d1e0aaec65b 100644 --- a/apps/webapp/app/routes/resources.branches.create.tsx +++ b/apps/webapp/app/routes/resources.branches.create.tsx @@ -99,7 +99,7 @@ export function NewBranchPanel({ s.delete("dialogClosed"); return s; }); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsOpen(false); } }, [searchParams, setSearchParams]); diff --git a/apps/webapp/app/routes/resources.metric.tsx b/apps/webapp/app/routes/resources.metric.tsx index 93a2a759512..efb01aa83db 100644 --- a/apps/webapp/app/routes/resources.metric.tsx +++ b/apps/webapp/app/routes/resources.metric.tsx @@ -207,7 +207,7 @@ export function MetricWidget({ // Track the latest props so the submit callback always uses fresh values // without needing to be recreated (which would cause useInterval to re-register listeners). const propsRef = useRef(props); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. propsRef.current = props; // Track visibility so we only fetch for on-screen widgets. @@ -220,7 +220,7 @@ export function MetricWidget({ }, }); - /* oxlint-disable react/react-compiler -- These ref objects are stable callback inputs. */ + /* oxlint-disable react/memo-dependencies -- These ref objects are stable callback inputs. */ const submit = useCallback(() => { if (!isVisibleRef.current) { isDirtyRef.current = true; @@ -265,8 +265,8 @@ export function MetricWidget({ } }); }, [isVisibleRef]); - /* oxlint-enable react/react-compiler */ - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + /* oxlint-enable react/memo-dependencies */ + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. submitRef.current = submit; // Clean up on unmount diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx index 77770e5f3fa..4421b76daf1 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github.tsx @@ -442,7 +442,7 @@ export function ConnectGitHubRepoModal({ const params = new URLSearchParams(searchParams); if (params.get("openGithubRepoModal") === "1") { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsModalOpen(true); params.delete("openGithubRepoModal"); setSearchParams(params); @@ -451,7 +451,7 @@ export function ConnectGitHubRepoModal({ useEffect(() => { if (lastSubmission && "success" in lastSubmission && lastSubmission.success === true) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsModalOpen(false); } }, [lastSubmission]); @@ -812,7 +812,7 @@ export function ConnectedGitHubRepoForm({ gitSettingsValues.stagingBranch !== (connectedGitHubRepo.branchTracking?.staging?.branch || "") || gitSettingsValues.previewDeploymentsEnabled !== connectedGitHubRepo.previewDeploymentsEnabled; - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setHasGitSettingsChanges(hasChanges); }, [gitSettingsValues, connectedGitHubRepo]); diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.streams.$streamKey/route.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.streams.$streamKey/route.tsx index 98fa3ca06f2..e62d703ee58 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.streams.$streamKey/route.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.streams.$streamKey/route.tsx @@ -105,7 +105,6 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { ); }; -// oxlint-disable-next-line react/react-compiler -- TanStack Virtual is not compatible with compiler memoization. export function RealtimeStreamViewer({ runId, streamKey, @@ -254,6 +253,7 @@ export function RealtimeStreamViewer({ .length; // Virtual rendering for list view + // oxlint-disable-next-line react/incompatible-library -- TanStack Virtual is not compatible with compiler memoization. const rowVirtualizer = useVirtualizer({ count: chunks.length, getScrollElement: () => scrollRef.current, @@ -540,7 +540,7 @@ export function useRealtimeStream(resourcePath: string, startIndex?: number) { const [isConnected, setIsConnected] = useState(false); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setChunks([]); setError(null); diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx index c63f874b635..c5107482490 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel.tsx @@ -1118,7 +1118,7 @@ function VercelSettingsPanel({ useEffect(() => { if (!data?.authInvalid && !hasError && !data && !hasFetched) { load(vercelResourcePath(organizationSlug, projectSlug, environmentSlug)); - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setHasFetched(true); } }, [ diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx index 8cf1b653b8e..5d81b26cd7b 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx @@ -249,7 +249,7 @@ function CompleteDateTimeWaitpointForm({ const project = useProject(); const environment = useEnvironment(); - // oxlint-disable-next-line react/react-compiler -- This form intentionally snapshots wall-clock time for its deadline UI. + // oxlint-disable-next-line react/purity -- This form intentionally snapshots wall-clock time for its deadline UI. const now = Date.now(); const timeToComplete = waitpoint.completedAfter.getTime() - now; if (timeToComplete < 0) { @@ -368,7 +368,7 @@ function CompleteManualWaitpointForm({ waitpoint }: { waitpoint: { id: string }
(); const [text, setText] = useState(""); const onSuccessRef = useRef(onSuccess); - // oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state. + // oxlint-disable-next-line react/refs -- This ref intentionally coordinates an imperative route integration outside React state. onSuccessRef.current = onSuccess; const organization = useOrganization(); const project = useProject(); diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx index 88faa7096bf..0640c2d1354 100644 --- a/apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.select-plan.tsx @@ -327,7 +327,7 @@ export function TierFree({ const [isLackingFeaturesChecked, setIsLackingFeaturesChecked] = useState(false); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsDialogOpen(false); }, [subscription]); @@ -494,7 +494,7 @@ export function TierHobby({ const [isDialogOpen, setIsDialogOpen] = useState(false); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsDialogOpen(false); }, [subscription]); @@ -637,7 +637,7 @@ export function TierPro({ const [isDialogOpen, setIsDialogOpen] = useState(false); useEffect(() => { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsDialogOpen(false); }, [subscription]); diff --git a/apps/webapp/app/routes/vercel.onboarding.tsx b/apps/webapp/app/routes/vercel.onboarding.tsx index 80f27ff4a8d..67f28c8da75 100644 --- a/apps/webapp/app/routes/vercel.onboarding.tsx +++ b/apps/webapp/app/routes/vercel.onboarding.tsx @@ -328,7 +328,7 @@ export default function VercelOnboardingPage() { // Reset isInstalling when navigation returns to idle (e.g. on error) useEffect(() => { if (navigation.state === "idle" && isInstalling) { - // oxlint-disable-next-line react/react-compiler -- This effect intentionally synchronizes route state after an external or lifecycle change. + // oxlint-disable-next-line react/set-state-in-effect -- This effect intentionally synchronizes route state after an external or lifecycle change. setIsInstalling(false); } }, [navigation.state, isInstalling]); diff --git a/internal-packages/observability-map/src/suppression.ts b/internal-packages/observability-map/src/suppression.ts index b944061a3a3..8d36d672623 100644 --- a/internal-packages/observability-map/src/suppression.ts +++ b/internal-packages/observability-map/src/suppression.ts @@ -80,8 +80,8 @@ function commentRanges(source: string, sf: ts.SourceFile): ts.CommentRange[] { return ranges; } -/** One physical line of comment content per range, the `//`, `/*`, `*​/` and a jsdoc `*` prefix - * stripped, so a multi-line block comment still matches the directive one line at a time. */ +/** One physical line of comment content per range, with comment delimiters and a jsdoc `*` + * prefix stripped, so a multi-line block comment still matches the directive one line at a time. */ function commentLines(source: string, sf: ts.SourceFile): string[] { const lines: string[] = []; for (const range of commentRanges(source, sf)) { diff --git a/package.json b/package.json index c4ac2507624..51bf1c68511 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "knip": "6.25.0", "lefthook": "^2.1.10", "oxfmt": "^0.54.0", - "oxlint": "^1.69.0", + "oxlint": "^1.79.0", "pkg-pr-new": "0.0.75", "pkg-types": "1.1.3", "tsx": "^3.7.1", diff --git a/packages/cli-v3/e2e/e2e.test.ts b/packages/cli-v3/e2e/e2e.test.ts index 300e794242e..1629fcbdec2 100644 --- a/packages/cli-v3/e2e/e2e.test.ts +++ b/packages/cli-v3/e2e/e2e.test.ts @@ -233,7 +233,7 @@ describe("buildWorker", async () => { const rewrittenManifest = rewriteBuildManifestPaths(buildManifest!, destination.path); - if (resolvedConfig!.instrumentedPackageNames?.length ?? 0 > 0) { + if ((resolvedConfig!.instrumentedPackageNames?.length ?? 0) > 0) { expect(rewrittenManifest.loaderEntryPoint).toBe("/app/src/entryPoints/loader.mjs"); } else { expect(rewrittenManifest.loaderEntryPoint).toBeUndefined(); diff --git a/packages/core/src/v3/utils/globals.ts b/packages/core/src/v3/utils/globals.ts index bbc64f42895..89ab86d8092 100644 --- a/packages/core/src/v3/utils/globals.ts +++ b/packages/core/src/v3/utils/globals.ts @@ -27,7 +27,11 @@ export function registerGlobal( instance: TriggerDotDevGlobalAPI[Type], allowOverride = false ): boolean { - const api = (_global[GLOBAL_TRIGGER_DOT_DEV_KEY] = _global[GLOBAL_TRIGGER_DOT_DEV_KEY] ?? {}); + let api = _global[GLOBAL_TRIGGER_DOT_DEV_KEY]; + if (!api) { + api = {}; + _global[GLOBAL_TRIGGER_DOT_DEV_KEY] = api; + } if (!allowOverride && api[type]) { // already registered an API of this type diff --git a/packages/trigger-sdk/src/v3/envvars.ts b/packages/trigger-sdk/src/v3/envvars.ts index 153be22a3d3..8ff68ab8907 100644 --- a/packages/trigger-sdk/src/v3/envvars.ts +++ b/packages/trigger-sdk/src/v3/envvars.ts @@ -200,8 +200,8 @@ export function retrieve( name?: string, requestOptions?: ApiRequestOptions ): ApiPromise { - let $projectRef: string; - let $slug: string; + let $projectRef: string | undefined; + let $slug: string | undefined; let $name: string; const $requestOptions = overloadRequestOptions("retrieve", slugOrRequestOptions, requestOptions); @@ -210,11 +210,11 @@ export function retrieve( $slug = typeof slugOrRequestOptions === "string" ? slugOrRequestOptions - : taskContext.ctx?.environment.slug!; + : taskContext.ctx?.environment.slug; $name = name; } else { - $projectRef = taskContext.ctx?.project.ref!; - $slug = taskContext.ctx?.environment.slug!; + $projectRef = taskContext.ctx?.project.ref; + $slug = taskContext.ctx?.environment.slug; $name = projectRefOrName; } @@ -247,8 +247,8 @@ export function del( name?: string, requestOptions?: ApiRequestOptions ): ApiPromise { - let $projectRef: string; - let $slug: string; + let $projectRef: string | undefined; + let $slug: string | undefined; let $name: string; const $requestOptions = overloadRequestOptions("del", slugOrRequestOptions, requestOptions); @@ -257,11 +257,11 @@ export function del( $slug = typeof slugOrRequestOptions === "string" ? slugOrRequestOptions - : taskContext.ctx?.environment.slug!; + : taskContext.ctx?.environment.slug; $name = name; } else { - $projectRef = taskContext.ctx?.project.ref!; - $slug = taskContext.ctx?.environment.slug!; + $projectRef = taskContext.ctx?.project.ref; + $slug = taskContext.ctx?.environment.slug; $name = projectRefOrName; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19f0c5e18dc..7d74cbbe905 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -135,8 +135,8 @@ importers: specifier: ^0.54.0 version: 0.54.0 oxlint: - specifier: ^1.69.0 - version: 1.70.0 + specifier: ^1.79.0 + version: 1.79.0 pkg-pr-new: specifier: 0.0.75 version: 0.0.75 @@ -5350,124 +5350,124 @@ packages: cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.70.0': - resolution: {integrity: sha512-zFh0P4cswmRvw6nkyb89dr18rRanuaCPAsEXsFDoQY8WdaquI8Pt4NWFjaMJg6L23cy5NeN8J9cBnREbWzZhaw==} + '@oxlint/binding-android-arm-eabi@1.79.0': + resolution: {integrity: sha512-TebFaaMklO/RXzTv7PucaCq9l3X6D1gA+C8H6K4njtjFOV+zWE9MKLpulcJZN9bzytbUbQIY0mZuz12nQ5Kv4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.70.0': - resolution: {integrity: sha512-qI8o4HZjeGiBrWv+pJv4lH0Yi2Gl/JSp/EumBUApezJprIKa5PS4nU0lQsQngtky8k+SplQIOjv6hwu0SSxeyg==} + '@oxlint/binding-android-arm64@1.79.0': + resolution: {integrity: sha512-KqqnOtAVgNsPPF0YSodkFZA1O80jcKoCZCTu3bgsszxA+MrMP9TLzfXitKjEj1FmrPprKDMdRDMmY3weESO9sg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.70.0': - resolution: {integrity: sha512-8KjgVVHI5F9nVwHCRwwA78Ty7zNKP4Wd9OeN5PSv3iu/F/u1RVXoOCgLhWqust6HmwQG6xc8c+RCyaWENy24+w==} + '@oxlint/binding-darwin-arm64@1.79.0': + resolution: {integrity: sha512-BVC2nsMzqQzRDPc5RhixkZ+m1p7iH4bxRRvqkbwDXX0PlQKm1BPy8J8cRjnAFafOq2QzI+BfO3vE8w2GZ3CBag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.70.0': - resolution: {integrity: sha512-WVydssv5PSUBXFJTdNBWlmGkbNmvPGaFt/2SUT/EZRB6bq6bEOHmMlbnupZD5jmlEvi9+mZJHi8TCw15lyfSfQ==} + '@oxlint/binding-darwin-x64@1.79.0': + resolution: {integrity: sha512-p6Lm+snmhGuLKL1+CpCV8L6ijkE/qJzK2H2jG9+eKJT0n31RbY4FLsdhexekgP3bLpw4Kgde+9DZuDZQ4yIInA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.70.0': - resolution: {integrity: sha512-hJucmUf8OlinHNb1R7fI4Fw6WsAstOz7i8nmkWQfiHoZXtbufNm+MxiDTIMk1ggh2Ro4vLzgQ+bKvRY54MZoRA==} + '@oxlint/binding-freebsd-x64@1.79.0': + resolution: {integrity: sha512-qDMm0dXZnoHyRqSL4N4xUq82T4sqK5cbKSjvd/dF/YbMUXc2R1wEPf+vmA5S0qUmi0nwXfNbjXBtZaIqzQLIMg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.70.0': - resolution: {integrity: sha512-1BnS7wbCYDSXwWzJJ+mc3NURoha6m6m6RT5c6vgAY3oz7C3OVXP+S0awo2mRq97arrJkVvO3qRQfyAHL+76xtQ==} + '@oxlint/binding-linux-arm-gnueabihf@1.79.0': + resolution: {integrity: sha512-2od7s0nuKPzqyUZAWk9KkCyGg7eI9dwFPZg+20lB15fKFkVZ0c9ZFxqPfiBAyDTlTkh9stPI0t+JlPCqMbItVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.70.0': - resolution: {integrity: sha512-yKy/UdbR55+M2yEcuiV5DCNC/gdQAjr/GioUy50QwBzSrKm8ueWADqyRLS9Xk+qjNeCYGg6A8FvUBds56ttfqg==} + '@oxlint/binding-linux-arm-musleabihf@1.79.0': + resolution: {integrity: sha512-ZOQUjkzDnvlhSE3+tWC3YXx94MMl+sYMlwH+u1+YGApGHOJP/YAc8ZBRFOXZ6eOBmxtXAWuS/fBcdZr8qqNO1A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.70.0': - resolution: {integrity: sha512-0A5XJ4alvmqFUFP/4oYSyaO+qLto/HrKEWTSaegiVl+HOufFngK2BjYw9x4RbwBt/du5QG6l5q1zeWiJYYG5yg==} + '@oxlint/binding-linux-arm64-gnu@1.79.0': + resolution: {integrity: sha512-lu158FR4nGqGeRS3BQvtG85wRgU/Fy4MD5Cxp1hzJXizGiLo6u2742wJSCDKh8cFcZntvX7fcxlq4mMmfryH1g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-musl@1.70.0': - resolution: {integrity: sha512-JiylyurlB0CLSedNtx1gzv3FvfWPF1h/2Y3BJszPLNt5XQFlBsH5ke0Jle3iJb3uqu5m2e7A/DwzpuCAHdiU+A==} + '@oxlint/binding-linux-arm64-musl@1.79.0': + resolution: {integrity: sha512-mbpKQeE2aflTjddaHK7MP8KP/OFbUM++lt5M635ENM8IyIdK0jm2t9pb+2v9mVVIvhF6TqA4l7F79Pll1mi+uw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/binding-linux-ppc64-gnu@1.70.0': - resolution: {integrity: sha512-J8VPG7I3/HmgaU4u8pNU2kFx2+0U+vPLS1dXFxXOaR/2TQ0f8AC7DRz0SRGRI1bfphnX2hVYTTtLuhL4nYKL+Q==} + '@oxlint/binding-linux-ppc64-gnu@1.79.0': + resolution: {integrity: sha512-WpGNua7gaxaHnpSDeog2ji8IDHn/QLPl9LPzwkR/FvVv58vT5BcXjRXnU+wbu3N75cpeha8CdC7ho/U2OIsB4g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.70.0': - resolution: {integrity: sha512-N2+4lV2KLN+oXTIIIwmWDhwkrnvqf5oX7Hw0zPjk+RuIVgiBQSOlJWF7uQoFx2siEYX0ZQ5cfSbEAHm+J3t7Wg==} + '@oxlint/binding-linux-riscv64-gnu@1.79.0': + resolution: {integrity: sha512-tK1E93A5LVzISg4ngpKJnfTs7EqtIUceGI7MQ4GyDjJiLi8wPCkEyKlj2xkyKWZ1yzkDJyLHTBJ5/iFWRdnJvg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-musl@1.70.0': - resolution: {integrity: sha512-1e2L7cFCvx9QDzq6NPP+0tABKb5z6nWHyddWTNKprEsjO9xNrAtPowuCGpjNXxkTdsMiZ4jc8YQ5SstZd4XK6g==} + '@oxlint/binding-linux-riscv64-musl@1.79.0': + resolution: {integrity: sha512-qhQvUIrngXivA2A9pQ+xPCychztn/5qUv7yS3gDwXv3w7Rag+eTeeXWmRyx+t7XsW5x6LuY/8AsTq36UgFIblg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxlint/binding-linux-s390x-gnu@1.70.0': - resolution: {integrity: sha512-Kwu/l/8GcYibCWA9m9N5pRXMIKVSsL/YbgpLzYkqDhWTiqdRfnNJ/+nqIKRKQiFbHWsdlHEhzMwruJK+qcEruA==} + '@oxlint/binding-linux-s390x-gnu@1.79.0': + resolution: {integrity: sha512-sv6AaVgU/eE6u+6WFiQVDcPPwTxP6IJMSB9k701W2r/r6Tx465e8vPvVyRxquNH4Vy6KwRNu90mVbxXJN8+5gg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.70.0': - resolution: {integrity: sha512-tap04CsHYOl0nSAQJfPNIuBxqEPB2HnhQqwaOXLg1jnp2XfRo8Fa814dA4QC4zpvTWXCjAAaCY1W5LOORkEQuQ==} + '@oxlint/binding-linux-x64-gnu@1.79.0': + resolution: {integrity: sha512-iFZL02deziHslb3jEX9KdqlAkYoo4fGyotchKDzdfK1f5mxlIBeiQeHhvK3iFpuEJSB4ma/qeFn9oxPiwnhUPQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.70.0': - resolution: {integrity: sha512-hzJa/WgvtJpbBD9rgfy0qe+MjbxOXNUT0bfR1S6EQQzfTtBFA9xg5q8KSwRrQ2QfSS+TaP4j+4mVPQrfNc6UNg==} + '@oxlint/binding-linux-x64-musl@1.79.0': + resolution: {integrity: sha512-3DtZR2raqObnh7wXZoFYFd0Fw7skBvcb3f7A+/lkEiDuh8hrE6vv9b/62Qxao1a9/OeHLw/FcXlXzgsW9wTRFg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxlint/binding-openharmony-arm64@1.70.0': - resolution: {integrity: sha512-xbsaNSNzVSnaJACCUYr1HQMyY/Q/Q1LkePmHG3UvZPvGCYGNxrsZp9OmtA6ick8xH47ltRRbRrPCM1YXYcyC+A==} + '@oxlint/binding-openharmony-arm64@1.79.0': + resolution: {integrity: sha512-Oatt4GuA1WJkqzk2ozx4HrWROOi7opV3AKDw/U8qDIqeTqzsjn5K2x3REJMNjU3/KU/Bkq96Zi3CknaiDTaC/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.70.0': - resolution: {integrity: sha512-icAEsUI7JbW1TMRdEXV83mVAInhRVQYuuAlPpxdGwJ95chNdnCzjloRW8GglT0WvzOEZSio6fnYSk2DJ2Hv7LQ==} + '@oxlint/binding-win32-arm64-msvc@1.79.0': + resolution: {integrity: sha512-NAgZr9Qp8nIA9rpo0JEvwiabTF/2UVqBNnupBG9X4kxXcQoScJUTi+qHhvabb9s/thgj5wQ4XcIaJvb+ZMgoKw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.70.0': - resolution: {integrity: sha512-FHMSWbVsPVs/f+Jcl04ws4JJ2wUnauyTzlpxWRG/lSO/8GpX08Fo2gQZqdA6CrRFI+zvkxl+N/KwJGWfUwYVZA==} + '@oxlint/binding-win32-ia32-msvc@1.79.0': + resolution: {integrity: sha512-+KyXjIvcpaXmWW/j9NNY5yWjrIVxaX18VyIheQy3jwc2GSYgpCr7MGI/HxIGQ/shAL5IWEKbhsqoMpAO5Stiog==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.70.0': - resolution: {integrity: sha512-ptOlKwCz7n4AKs5VweMqG6DAg677FmKOK+vBkkL9DMNgFATIQ+upqUYBTOEwRQyRAx1ncGlPlXleV2hIcm3z4g==} + '@oxlint/binding-win32-x64-msvc@1.79.0': + resolution: {integrity: sha512-mEelcCMMBS57sIXh2veGMNy+pQwuGtcMxHxGIZWQ5Ba9pJ5jCCUFOZB9E2JhBaxGsURe+WGe0zJp4RVre52gpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -12361,12 +12361,12 @@ packages: vite-plus: optional: true - oxlint@1.70.0: - resolution: {integrity: sha512-D6JgHtzkhRwvEC+A0Nw5AEc5bk8x5i1pHzvZIEf/a0C4hOzmAACNGtkDGPyFaxxX3ZVGxCPeig3P3rMM8XU3/g==} + oxlint@1.79.0: + resolution: {integrity: sha512-hVJ9hq9m2unPS+Of4eJJgCPdIeCC+3DHEUX3tkmrPJr3OK2hz7PhXwgC+ZP71ZcYu8cCDEtQrqLxWNvxBppBVg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.22.1' + oxlint-tsgolint: '>=7.0.2001' vite-plus: '*' peerDependenciesMeta: oxlint-tsgolint: @@ -19214,61 +19214,61 @@ snapshots: '@oxfmt/binding-win32-x64-msvc@0.54.0': optional: true - '@oxlint/binding-android-arm-eabi@1.70.0': + '@oxlint/binding-android-arm-eabi@1.79.0': optional: true - '@oxlint/binding-android-arm64@1.70.0': + '@oxlint/binding-android-arm64@1.79.0': optional: true - '@oxlint/binding-darwin-arm64@1.70.0': + '@oxlint/binding-darwin-arm64@1.79.0': optional: true - '@oxlint/binding-darwin-x64@1.70.0': + '@oxlint/binding-darwin-x64@1.79.0': optional: true - '@oxlint/binding-freebsd-x64@1.70.0': + '@oxlint/binding-freebsd-x64@1.79.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.70.0': + '@oxlint/binding-linux-arm-gnueabihf@1.79.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.70.0': + '@oxlint/binding-linux-arm-musleabihf@1.79.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.70.0': + '@oxlint/binding-linux-arm64-gnu@1.79.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.70.0': + '@oxlint/binding-linux-arm64-musl@1.79.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.70.0': + '@oxlint/binding-linux-ppc64-gnu@1.79.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.70.0': + '@oxlint/binding-linux-riscv64-gnu@1.79.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.70.0': + '@oxlint/binding-linux-riscv64-musl@1.79.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.70.0': + '@oxlint/binding-linux-s390x-gnu@1.79.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.70.0': + '@oxlint/binding-linux-x64-gnu@1.79.0': optional: true - '@oxlint/binding-linux-x64-musl@1.70.0': + '@oxlint/binding-linux-x64-musl@1.79.0': optional: true - '@oxlint/binding-openharmony-arm64@1.70.0': + '@oxlint/binding-openharmony-arm64@1.79.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.70.0': + '@oxlint/binding-win32-arm64-msvc@1.79.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.70.0': + '@oxlint/binding-win32-ia32-msvc@1.79.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.70.0': + '@oxlint/binding-win32-x64-msvc@1.79.0': optional: true '@pinojs/redact@0.4.0': {} @@ -27372,27 +27372,27 @@ snapshots: '@oxfmt/binding-win32-ia32-msvc': 0.54.0 '@oxfmt/binding-win32-x64-msvc': 0.54.0 - oxlint@1.70.0: + oxlint@1.79.0: optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.70.0 - '@oxlint/binding-android-arm64': 1.70.0 - '@oxlint/binding-darwin-arm64': 1.70.0 - '@oxlint/binding-darwin-x64': 1.70.0 - '@oxlint/binding-freebsd-x64': 1.70.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.70.0 - '@oxlint/binding-linux-arm-musleabihf': 1.70.0 - '@oxlint/binding-linux-arm64-gnu': 1.70.0 - '@oxlint/binding-linux-arm64-musl': 1.70.0 - '@oxlint/binding-linux-ppc64-gnu': 1.70.0 - '@oxlint/binding-linux-riscv64-gnu': 1.70.0 - '@oxlint/binding-linux-riscv64-musl': 1.70.0 - '@oxlint/binding-linux-s390x-gnu': 1.70.0 - '@oxlint/binding-linux-x64-gnu': 1.70.0 - '@oxlint/binding-linux-x64-musl': 1.70.0 - '@oxlint/binding-openharmony-arm64': 1.70.0 - '@oxlint/binding-win32-arm64-msvc': 1.70.0 - '@oxlint/binding-win32-ia32-msvc': 1.70.0 - '@oxlint/binding-win32-x64-msvc': 1.70.0 + '@oxlint/binding-android-arm-eabi': 1.79.0 + '@oxlint/binding-android-arm64': 1.79.0 + '@oxlint/binding-darwin-arm64': 1.79.0 + '@oxlint/binding-darwin-x64': 1.79.0 + '@oxlint/binding-freebsd-x64': 1.79.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.79.0 + '@oxlint/binding-linux-arm-musleabihf': 1.79.0 + '@oxlint/binding-linux-arm64-gnu': 1.79.0 + '@oxlint/binding-linux-arm64-musl': 1.79.0 + '@oxlint/binding-linux-ppc64-gnu': 1.79.0 + '@oxlint/binding-linux-riscv64-gnu': 1.79.0 + '@oxlint/binding-linux-riscv64-musl': 1.79.0 + '@oxlint/binding-linux-s390x-gnu': 1.79.0 + '@oxlint/binding-linux-x64-gnu': 1.79.0 + '@oxlint/binding-linux-x64-musl': 1.79.0 + '@oxlint/binding-openharmony-arm64': 1.79.0 + '@oxlint/binding-win32-arm64-msvc': 1.79.0 + '@oxlint/binding-win32-ia32-msvc': 1.79.0 + '@oxlint/binding-win32-x64-msvc': 1.79.0 p-filter@2.1.0: dependencies: