Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export default function Page() {
const usefulLinksPanelRef = useRef<PanelHandle>(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.
fetcherRef.current = fetcher;

const toggleUsefulLinks = useCallback((show: boolean) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +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.
clientDataJsonRef.current = clientDataJson;
const [machine, setMachine] = useState<string | undefined>(undefined);
const [tags, setTags] = useState<string[]>([]);
Expand Down Expand Up @@ -267,12 +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.
startSessionRef.current = startSession;

// Create TriggerChatTransport directly (not via useTriggerChatTransport hook
// to avoid React version mismatch between SDK and webapp)
const transportRef = useRef<TriggerChatTransport | null>(null);
if (transportRef.current === null) {
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
transportRef.current = new TriggerChatTransport({
Comment thread
carderne marked this conversation as resolved.
task: agent.slug,
// The Remix action is idempotent on `(env, externalId)` and
Expand Down Expand Up @@ -301,6 +304,7 @@ function PlaygroundChat() {
: {}),
});
}
// oxlint-disable-next-line react/react-compiler -- 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.
Expand Down Expand Up @@ -351,6 +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.
const { messages, sendMessage, stop, status, error } = useChat({
id: chatId,
messages: initialMessages,
Expand Down Expand Up @@ -391,6 +396,7 @@ function PlaygroundChat() {
inputRef.current?.focus();
}, [isEmpty]);

// oxlint-disable-next-line react/react-compiler -- 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. */
Expand Down Expand Up @@ -1171,6 +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.
const pending: PendingMessageEntry[] = pendingMsgs.map((m) => ({
id: m.id,
text: m.parts[0]?.text ?? "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export function useRunsLiveReload({
const location = useLocation();
const runsPollFetcher = useTypedFetcher<typeof liveRunsLoader>();
const runsPollFetcherStateRef = useRef(runsPollFetcher.state);
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
runsPollFetcherStateRef.current = runsPollFetcher.state;

const [visibleRuns, setVisibleRuns] = useState(runs);
Expand Down
2 changes: 2 additions & 0 deletions apps/webapp/app/routes/resources.metric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +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.
Comment thread
carderne marked this conversation as resolved.
propsRef.current = props;

// Track visibility so we only fetch for on-screen widgets.
Expand Down Expand Up @@ -265,6 +266,7 @@ 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.
submitRef.current = submit;

// Clean up on unmount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ function CompleteManualWaitpointForm({ waitpoint }: { waitpoint: { id: string }
<div className="max-h-[70vh] min-h-40 overflow-y-auto bg-background-deep scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<JSONEditor
autoFocus
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
defaultValue={currentJson.current}
readOnly={false}
basicSetup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export function AIGeneratedCronField({ onSuccess }: AIGeneratedCronFieldProps) {
const fetcher = useFetcher<typeof action>();
const [text, setText] = useState<string>("");
const onSuccessRef = useRef(onSuccess);
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
onSuccessRef.current = onSuccess;
const organization = useOrganization();
const project = useProject();
Expand Down