## Summary Restores green **Full Suite (non-blocking)** runs on `main`. Recent main merges left i18n key parity, schema baseline bookkeeping (0011→0012), heartbeat tool inventory (FN-8058 `fn_task_logs_read`), and merger whitespace-classification mocks (execFile `git diff -p -w :2: :3:`) out of date, so all four test shards failed. ## Root causes observed on main - **Shard 4 / `@fusion/i18n`**: missing `skipConfirmationDialogs*` + `reviewBudgetExhausted` in non-en locales; orphan `awaitingApprovalPlanReviewReplanCap` - **Shard 3 / `@fusion/core`**: `SCHEMA_BASELINE_VERSION` advanced to `0012` while tests still equated it with `OWNER_PROJECT_ID_SPLIT_VERSION` (`0011`) and omitted `0012` from applied-migration lists - **Shards 1–2 / `@fusion/engine`**: tool count/snapshot drift for `fn_task_logs_read`; merger tests still mocked `git diff-tree` for trivial classification after the execFile `:2:`/`:3:` cutover; mock provider `updateTask` arity drift ## Changes - Locale catalogs: add missing keys, drop orphan key - Schema applier tests: immutable 0011 identity + baseline 0012 lists - Heartbeat + gating snapshots: include `fn_task_logs_read` - Merger unit mocks: recognize `git diff -p -w :2:path :3:path` - Mock provider: accept optional third `updateTask` arg ## Test plan - [x] `pnpm --filter @fusion/i18n exec vitest run` — 23/23 - [x] `pnpm --filter @fusion/core exec vitest run src/__tests__/postgres/schema-applier.test.ts` (immutable + automation upgrade) — pass - [x] `pnpm --filter @fusion/core exec vitest run` project-identity + satellite-fusiondir — pass - [x] Engine suites from failed CI shards (file-scoped, hermes/openclaw/paperclip/grok, reliability post-finalize/mission, heartbeat, gating, merger recovery/prompt, mock-provider, etc.) — pass - [ ] Full Suite workflow green on merge to main <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved project data isolation across backend operations. - Added safer optional toast handling when UI components render outside the full application shell. - Added support for reading task logs during agent heartbeat sessions. - **Bug Fixes** - Prevented runtime probes from hanging and avoided scanning large binary files. - Improved path handling for workspaces with missing descendants. - Corrected task retry state resets and GitHub import/issue-close behavior. - **Style** - Improved chat, terminal, and settings spacing. - Added clearer accessibility labeling for the auto-merge control. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
66 lines
2.6 KiB
TypeScript
66 lines
2.6 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 { useOptionalToast } 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) {
|
|
/*
|
|
FNXC:ToastProvider 2026-07-14-19:25:
|
|
Prefer optional toast so board card unit/harness mounts without ToastProvider still render the badge (and do not throw through ErrorBoundary blanking the board).
|
|
|
|
FNXC:RuntimeFallbackUI 2026-07-16-12:20:
|
|
Depend on the stable addToast function identity, not the whole toast context object.
|
|
useOptionalToast() returns a new object reference when the provider re-renders; putting
|
|
that object in the effect deps re-fired toasts in a loop and hung RuntimeFallbackBadge tests.
|
|
*/
|
|
const addToast = useOptionalToast()?.addToast;
|
|
const status = useRuntimeFallbackStatus(taskId, isInViewport, projectId);
|
|
|
|
useEffect(() => {
|
|
if (status.shouldToastNow && status.message) {
|
|
addToast?.(status.message, "warning");
|
|
}
|
|
}, [status.shouldToastNow, status.message, addToast]);
|
|
|
|
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";
|