Design system
Docs
Surfaces

Diff view

One diff surface for transcript receipts, the Changes panel, and stacked review

HostImplementationNote
Primitivenone
Desktopconversation/diff-view.tsxDiffView over @pierre/diffs PatchDiff
Terminaltranscript.ts + output-diff.tsDiffRenderable (later pass)

DiffView

File: packages/desktop/src/renderer/src/conversation/diff-view.tsx, memoized. From its header:

One diff surface shared by transcript receipts and the Changes workbench. Pierre renders the patch inside a shadow root; Nyte's tokens reach it as inherited custom properties on the host, so only rules that must live in the shadow tree go through unsafeCSS.

PropTypeDescription
pathstringHeader path / title.
labelstringHeader label override.
diffParsedDiff (patch, added, removed)
variant"inline" | "workbench" | "stack"inline inside a tool call; workbench adds header and stats; stack wraps lines and has no scrollport.

Options are fixed in PATCH_OPTIONS: unified layout, classic +/- indicators, file header disabled, word-level diff, shiki-js highlighting, worker pool disabled. Theme follows useAppearanceSettings().theme; "Themed Diff Backgrounds" in Appearance toggles the t.diffAdded* / t.diffRemoved* line backgrounds.

Constraint kept in onPostRender:

Pierre leaves the old <pre> in a React-managed shadow root on clean-up. StrictMode detaches and re-attaches the ref on mount, so the replacement instance would find that empty <pre>, treat it as prerendered HTML, and never render.

Where it appears

PlaceVariantSource
Tool call panel (edit tools)inlineToolCallView, panel keepMounted
Changes panel, single fileworkbenchChangesPanel with useVcsDiffs / useRunChanges
Changes panel, stacked reviewstackChangesStack (workbench/changes-stack.tsx, stacked-diff.ts)

Changes panel

ChangesPanel (workbench/changes-panel.tsx): "Local working-tree and per-turn declared changes. GitHub never participates in this path."

PropType
sessionIdSessionId | undefined (undefined → uncommitted only)
scope"uncommitted" | "turn"
selectedPathstring | undefined
revealPathRevisionnumber (bump to re-scroll)
scrollTopnumber
fileTreeVisibleboolean
onScopeChange, onToggleFileTree, onSelectPath, onRevealPath, onScrollTopcallbacks

Toolbar is @nyte-ai/ui/toolbar labelled "Changes actions" with a scope Menu (MenuRadioItems with stat meta, a MenuCheckboxItem "Show all turns"), a Refresh IconButton, and a file-tree ToggleIconButton with PanelToggleIcon side="right". The file list is role="tree" labelled "Changed files"; rows are role="treeitem" with aria-expanded on directories and aria-selected on files; labels are middle-truncated by measured width (pretext.ts).