affectUI › Components › Agents
Conflict Radar
Agents working on their own branches at once, and where they get in each other's way – a row per file and a column per agent, a line between the agents that changed the same lines, each agent's way in one sentence to pick from, and Merge once all are settled.
Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/conflict-radar.json · Import from @/components/ui/conflict-radar
When to use
- Several coding agents work on their own branches of the same repo at once, and people need to see where they overlap before anything is merged
- Agents came up with different ways to solve the same thing and someone has to pick one
When not to use
- When the agents try the same task and the best one simply wins – use Parallel Attempts
- When the timeline matters – use Agent Lanes
- For a single agent's changes – use Agent Ledger
Usage
import { ConflictRadar, type RadarAgent, type RadarFile } from "@/components/ui/conflict-radar";
export function Branches({ agents, files }: { agents: RadarAgent[]; files: RadarFile[] }) {
const [resolved, setResolved] = useState<Record<string, string>>({});
return (
<ConflictRadar
agents={agents} // { id, name, model?, avatar?, status?: "running" | "done" }
files={files} // { path, edits: [{ agentId, lines: [from, to], summary?, active? }] }
resolved={resolved}
onResolve={(path, agentId) => setResolved((r) => ({ ...r, [path]: agentId }))}
onMerge={() => mergeBranches(resolved)}
/>
);
}Props
| Name | Type | Default | Description |
|---|---|---|---|
agents | RadarAgent[] | One column each: name, model or branch, a mark, and whether it's still working | |
files | RadarFile[] | One row each, with every agent's edit – the lines it changes, whether it's still writing, and for conflicts its way in one sentence | |
title | string | "Parallel work" | Heading in the bar |
resolved | Record<string, string> | The agent picked per conflicting file – leave it out and the component keeps the picks itself | |
onResolve | (path: string, agentId: string) => void | A way was picked for a conflict | |
onMerge | () => void | Merge was clicked – it's only enabled once every conflict is settled and every agent is done | |
className | string | Extra class on the root |
Keyboard
- Tab: Moves through Merge, the conflicting files and the ways to settle the one in focus
- Enter / Space: On a conflicting file: shows its ways below; on a way: keeps it
Accessibility
- The grid is a table with the agents as column headers; every cell says who changed the file and whether it was kept
- Conflicts and settled files are named in text, not only by color
- The ways to settle a conflict are a radio group
- The comparison is a polite live region, so the next conflict is announced when it comes into focus
Responsive
- Below 440px agent names and folders drop, the columns get smaller and a way's sentence moves under its name
- Dark mode built in; colors are CSS variables on .ui-cr
Requirements
- React 19
Related
- Parallel Attempts – An agent tries the same task several ways at once and the best one wins – every attempt races as a row with its model, approach and live bar, then gets a score; the best is marked and picked, and you can switch to another
- Agent Lanes – Where every agent is right now – a live timeline with a lane per agent, tasks growing into “now”, hand-offs drawn between agents and approvals right on the block
- Agent Ledger – Everything an agent changed in your systems, each change with an undo – before and after per row, and pointing at Undo shows what builds on it: what would be undone too, and what can't be taken back