Files
fusion/packages/dashboard/app/components/RuntimeFallbackBadge.tsx
gsxdsm ec2aeed2bf fix(dashboard): drop unknown-rule eslint-disable in RuntimeFallbackBadge
The repo eslint config omits react-hooks/exhaustive-deps, so a disable
directive for it is itself a lint error (rule-not-found). Replace with a
plain comment documenting the intentional dep omission.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 07:16:53 -07:00

60 lines
2.4 KiB
TypeScript

/**
* RuntimeFallbackBadge (FUX-022)
*
* Renders a visible badge on an agent/task card when the most recent
* `session:runtime-resolved` audit event for that task shows
* `wasConfigured: false` alongside a non-empty configured `runtimeHint` —
* i.e. the configured runtime (e.g. "hermes") could not be resolved and the
* session silently fell back to the default `pi` runtime. Also fires a toast
* via the shared ToastProvider the first time this fallback state is newly
* observed for a session (not re-fired on every poll/re-render).
*
* Renders null (no leftover placeholder) for every other state: no event
* yet, wasConfigured true, or wasConfigured false with a blank hint.
*/
import { memo, useEffect } from "react";
import { AlertTriangle } from "lucide-react";
import { useRuntimeFallbackStatus } from "../hooks/useRuntimeFallbackStatus";
import { useToast } from "../hooks/useToast";
interface RuntimeFallbackBadgeProps {
taskId?: string;
/** Gate polling to visible cards only (e.g. pass the card's own isInViewport state). */
isInViewport: boolean;
projectId?: string;
}
function RuntimeFallbackBadgeComponent({ taskId, isInViewport, projectId }: RuntimeFallbackBadgeProps) {
const { addToast } = useToast();
const status = useRuntimeFallbackStatus(taskId, isInViewport, projectId);
useEffect(() => {
if (status.shouldToastNow && status.message) {
addToast(status.message, "warning");
}
// FNXC:RuntimeFallbackUI 2026-07-08-00:00:
// Intentionally omit addToast from deps — its identity is stable per ToastProvider instance, so re-toasting is keyed only on status changes.
// Note: repo eslint config omits react-hooks/exhaustive-deps, so a disable directive for it is itself a lint error (rule-not-found). Do not re-add one.
}, [status.shouldToastNow, status.message]);
if (!status.showBadge || !status.message) {
return null;
}
return (
<span
className="card-status-badge card-runtime-fallback-badge"
title={status.message}
data-testid="runtime-fallback-badge"
data-runtime-hint={status.runtimeHint ?? undefined}
data-runtime-fallback-reason={status.reason ?? undefined}
>
<AlertTriangle size={10} aria-hidden="true" />
<span>{status.message}</span>
</span>
);
}
export const RuntimeFallbackBadge = memo(RuntimeFallbackBadgeComponent);
RuntimeFallbackBadge.displayName = "RuntimeFallbackBadge";