Diff Proposal
A model-proposed edit with accept and reject. The decision is reported, never applied — and once made, the actions are replaced by the outcome so a stale card cannot be clicked twice.
src/components/ui/diff-proposal.tsxAbout
From the component's own source, where it was written.
A model-proposed edit, with accept and reject.
The decision is reported, never applied here — this component has no idea what the file system or editor buffer is. It also refuses to look decided: once a choice is made the actions are replaced by a stated outcome, so a stale card in a transcript cannot be clicked a second time.
rationale sits above the diff rather than below it. The reason for a change is what you read before deciding, and putting it after a forty-line diff means nobody reads it at all.
Install
npx astralyx-ui add diff-proposal
Usage
import { DiffProposal } from '@/components/ui/diff-proposal'
<DiffProposal
file={file}
rationale="The md size hard-codes a radius the token already defines."
onDecide={(decision) => apply(decision)}
/>Composer
Change the props and the source below follows.
The md size hard-codes rounded-lg, but --radius-control-md already defines this step. Hard-coding it means the size stops following the token.
<DiffProposal
file={file}
rationale="…"
view="unified"
onDecide={apply}
/>Examples
Proposal
<DiffProposal file={file} rationale="…" onDecide={apply} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
DiffProposal
Extends Omit<ComponentProps<'div'>, 'title'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| file | DiffFile | required | Same shape DiffView takes — use parseUnifiedDiff when you only have patch text. |
| title | ReactNode | — | — |
| rationale | ReactNode | — | Rendered above the diff. The reason for a change is what you read before deciding; after forty lines of diff nobody reads it. |
| view | 'unified' | 'split' | 'unified' | Passed through to DiffView. |
| decision | ProposalDecision | — | Controlled or uncontrolled. The component never applies anything — it has no idea what your editor buffer is. |
| onDecide | (decision: ProposalDecision) => void | — | Controlled or uncontrolled. The component never applies anything — it has no idea what your editor buffer is. |
| acceptLabel | ReactNode | 'Accept' | — |
| rejectLabel | ReactNode | 'Reject' | — |
| acceptedLabel | ReactNode | 'Accepted' | Shown once the change is accepted. |
| rejectedLabel | ReactNode | 'Rejected' | — |
Types
| Type | Definition | Description |
|---|---|---|
ProposalDecision | 'accepted' | 'rejected' | A model-proposed edit, with accept and reject. |