Review an agent's file edits: a card per file with +/- counts, line numbers, and Accept or Reject on each hunk.
Set your access key from API keys as NEXTUI_TOKEN in .env.local and add the @nextui namespace below to components.json once. Then every item installs by name. Each install counts as a copy on a free account.
$pnpm dlx shadcn@latest add @nextui/diff-viewer
1{2"registries": {3"@nextui": {4"url": "https://nextui.dev/r/{name}.json",5"headers": { "Authorization": "Bearer ${NEXTUI_TOKEN}" }6}7}8}
1"use client";23import { useState } from "react";4import { DiffViewer, parseUnifiedDiff, type DiffDecision } from "@/components/nextui/diff-viewer";56export function ReviewEdits({ patch }: { patch: string }) {7// patch is the agent's proposed change as unified diff, e.g. from a tool result8const files = parseUnifiedDiff(patch);9const [decisions, setDecisions] = useState<Record<string, DiffDecision>>({});1011return (12<DiffViewer13files={files}14decisions={decisions}15onDecisionsChange={(next) => {16setDecisions(next);17// apply accepted hunk ids, drop rejected ones, then tell the agent18}}19/>20);21}
| Prop | Type | Default | Description |
|---|---|---|---|
| files | { path: string; hunks: DiffHunk[] }[] | – | Changed files. Each hunk has an id, oldStart, newStart and unified lines starting with +, - or a space. parseUnifiedDiff builds this from git diff output |
| decisions | Record<string, "accepted" | "rejected"> | – | Controlled decisions, keyed by hunk id |
| defaultDecisions | Record<string, "accepted" | "rejected"> | {} | Starting decisions when uncontrolled |
| onDecisionsChange | (decisions) => void | – | Called with the full map when a hunk is accepted, rejected or undone, including Accept all and Reject all |
| autoPlay | boolean | false | Loop a scripted review for demos. Stops as soon as someone clicks |
| className | string | – | Extra classes on the wrapper |
Sign in to see the code
Preview it freely. A free account copies code and prompts a few times a day.