Xzero UI
Pro library

Agent cursorPro

A live document where Claude edits like a collaborator. Its labeled cursor comes out of its avatar, selects a paragraph and streams in a rewrite, adds a heading and fixes a typo, while a teammate's cursor reads along. Changes stay tinted until someone accepts or undoes them from a floating review bar.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/agent-cursor
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/agent-cursor

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { AgentCursor, type AgentEdit, type DocBlock } from "@/components/xzero/agent-cursor/agent-cursor";

const [doc, setDoc] = useState<DocBlock[]>(initialDoc);

<AgentCursor
  blocks={doc}
  run={async signal => {
    const res = await fetch("/api/agent/edits", { method: "POST", body: JSON.stringify(doc), signal });
    return (await res.json()) as AgentEdit[];
  }}
  collaborator={{ name: "Emma Collins", avatar: "/media/people/emma-collins.jpg" }}
  onAccept={setDoc}
/>

API reference

AgentCursor

A document card where an AI agent edits live with a labeled cursor beside a human collaborator, then hands the changes over for review. With no props it plays a simulated run on a sample launch brief.

PropTypeDefaultDescription
blocksDocBlock[]sample launch briefThe document as title, heading and paragraph blocks with stable ids. Compared by content, so an inline array is fine.
metastring–A muted line under the title, such as the owner and a target date.
editsAgentEdit[]sample editsEdits to play in order: rewrite (select a block and stream new text), insert (add a block after another) and fix (replace a word, flagged with a wavy underline first). Ignored when run is set.
run(signal: AbortSignal) => Promise<AgentEdit[]>–Fetches edits from your agent. The signal aborts when someone presses Stop. A rejected promise shows the error with a Retry button.
agent{ name: string; mark?: ReactNode; color?: string }Claude, #D97757The agent's name, 24 × 24 currentColor mark, and the color used for its cursor, selection and change tint.
collaborator{ name: string; avatar?: string; color?: string } | nullEmma CollinsA human in the doc, drawn as a second cursor with their portrait and first name. Null hides it.
autoPlaybooleantrueStarts a run as soon as the card is on screen. Off, the header shows an Ask button instead.
loopbooleantrue for the sampleReplays the run: the collaborator accepts after a short pause (never while you hover or focus the card), then the doc resets.
speednumber1Playback speed multiplier for cursor travel, streaming and pauses.
onAccept(blocks: DocBlock[]) => void–Called with the edited document when someone accepts. Store it and pass it back as blocks.
onUndo(blocks: DocBlock[]) => void–Called with the restored document when someone undoes the edits.
onPhaseChange(phase: AgentCursorPhase) => void–Fires on idle, thinking, editing, review, accepted, reverted, stopped, empty and error.
simulatedbooleantrue for the sampleAdds "Simulated, nothing was saved" to the screen reader status.
classNamestring–Extra class on the card.

Keyboard interactions

KeysAction
TabMoves between Stop or Run again in the header, then Undo and Accept changes in the review bar.
Enter / SpaceActivates the focused button.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Agent cursor: A live document where Claude edits like a collaborator. Its labeled cursor comes out of its avatar, selects a paragraph and streams in a rewrite, adds a heading and fixes a typo, while a teammate's cursor reads along. Changes stay tinted until someone accepts or undoes them from a floating review bar. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components