feat(FN-2729): merge fusion/fn-2729

- fix(FN-2729): silence ansi strip lint warning
- test(FN-2729): complete Step 10 — cover node health indicators
- feat(FN-2729): complete Step 9 — colorize CLI node status output
- feat(FN-2729): complete Step 8 — use NodeHealthDot in settings routing status
- test(FN-2729): align ListView node override option expectations
- feat(FN-2729): complete Step 7 — add bulk node status indicators
- fix(engine): prevent auto-merge cooldown loop on unresolvable conflicts
- feat(FN-2911): improve chat attachment compose and preview UX
- feat(FN-2921): merge fusion/fn-2921
- feat(FN-2909): merge fusion/fn-2909
- feat(FN-2914): merge fusion/fn-2914
- feat(FN-2902): merge fusion/fn-2902
- chore(release): v0.8.3
- Update changeset
- fix(tui): swap 3/4 panel hotkeys so they match the help text
- fix(tui): always show auth token and report accurate macOS memory usage

Fusion-Task-Id: FN-2729
This commit is contained in:
Fusion
2026-04-28 23:21:27 -07:00
committed by gsxdsm
parent 14d2bb7b8e
commit 3263babe1b
18 changed files with 253 additions and 221 deletions

View File

@@ -13,13 +13,6 @@ interface RoutingTabProps {
onTaskUpdated?: (task: Task) => void;
}
const STATUS_DOT: Record<NodeInfo["status"], string> = {
online: "🟢",
offline: "🔴",
connecting: "🟡",
error: "🔴",
};
type RoutingSettings = Settings & {
defaultNodeId?: string;
unavailableNodePolicy?: "block" | "fallback-local";
@@ -82,7 +75,7 @@ export function RoutingTab({ task, settings, addToast, onTaskUpdated }: RoutingT
const effectiveNode = effectiveNodeId ? nodesById.get(effectiveNodeId) : undefined;
const effectiveNodeName = effectiveNode
? `${STATUS_DOT[effectiveNode.status]} ${effectiveNode.name} (${effectiveNode.type})`
? `${effectiveNode.name} (${effectiveNode.type})${effectiveNode.status}`
: effectiveNodeId
? `${effectiveNodeId} (node unavailable or unknown)`
: "Local (no routing configured)";
@@ -180,8 +173,8 @@ export function RoutingTab({ task, settings, addToast, onTaskUpdated }: RoutingT
>
<option value="">Use project default</option>
{sortedNodes.map((node) => (
<option key={node.id} value={node.id}>
{STATUS_DOT[node.status]} {node.name} ({node.type})
<option key={node.id} value={node.id} title={`Status: ${node.status}`}>
{node.name} ({node.type}) {node.status}
</option>
))}
</select>