Pierre Guard
Verify code changes won't break the Pierre diff viewer integration.
Installation
- Make sure Claude is on your device and in your terminal.
Skills load from
~/.claude/skills/when Claude Code starts up — so you need it on your machine first. If you don't have it yet, install it once with the command below, then runclaudein any terminal to verify.One-time setupnpm i -g @anthropic-ai/claude-codeAlready have it? Skip ahead.
- Paste into Claude Code or into your terminal.
This copies the whole skill folder into
~/.claude/skills/pierre-guard-backnotprop/— the SKILL.md plus any scripts, reference docs, or templates the skill ships with. Safe default: works for every skill.Faster alternative (instruction-only skills)
Skips the clone and grabs only the SKILL.md file. Don't use this if the skill ships Python scripts, reference markdowns, or asset templates — they won't be downloaded and the skill will fail when it tries to load them.
Quick install (SKILL.md only)Sign up to copy - Restart Claude Code.
Quit and reopen Claude Code (or any other agent that loads from
~/.claude/skills/). New skills are picked up on startup. - Just ask Claude.
Skills auto-activate when your request matches the skill's description — no slash command needed. Trigger phrases live in the skill's own frontmatter; you can read them in the “What this skill does” section above.
Prefer to read the source first? Open on GitHub.
When Claude uses it
Guard against breaking the @pierre/diffs integration in Plannotator's code review UI. Use this skill whenever modifying DiffViewer.tsx, upgrading the @pierre/diffs package, changing unsafeCSS injection, adding new props to FileDiff, or touching shadow DOM selectors or CSS variables that cross into Pierre's shadow boundary. Also trigger when someone asks "will this break the diff viewer", "is this safe to change", or when reviewing PRs that touch the review-editor package.
What this skill does
Pierre Integration Guard
Plannotator's code review UI wraps @pierre/diffs — an open-source diff renderer that uses Shadow DOM. The integration is concentrated in a single file but relies on undocumented internals (shadow DOM selectors, CSS variable names, grid layout assumptions). This skill helps verify changes don't break that contract.
Source of Truth
- Upstream repo: https://github.com/pierrecomputer/pierre/tree/main/packages/diffs
- Local types:
node_modules/@pierre/diffs/dist/(.d.tsfiles) - Integration point:
packages/review-editor/components/DiffViewer.tsx - Current version: check
packages/review-editor/package.jsonfor the pinned version
Always verify against the upstream repo or local .d.ts files — don't rely on memory of the API shape.
What We Import
import { FileDiff } from '@pierre/diffs/react';
import { getSingularPatch, processFile } from '@pierre/diffs';
These are the only three imports. DiffViewer.tsx is the only file that touches Pierre.
API Surface to Guard
1. Component Props (FileDiff)
Read the current prop types from node_modules/@pierre/diffs/dist/react/index.d.ts or the upstream source. The props we use:
| Prop | Type | Notes |
|---|---|---|
fileDiff | FileDiffMetadata | From getSingularPatch() or processFile() |
options | FileDiffOptions<T> | See options table below |
lineAnnotations | DiffLineAnnotation<T>[] | { side, lineNumber, metadata } |
selectedLines | SelectedLineRange | null | { start, end, side } |
renderAnnotation | (ann) => ReactNode | Custom inline annotation renderer |
renderHoverUtility | (getHoveredLine) => ReactNode | The + button on hover (deprecated upstream — watch for removal) |
2. Options Object
| Option | Value We Pass | Risk |
|---|---|---|
themeType | 'dark' | 'light' | Low — standard enum |
unsafeCSS | CSS string | High — targets internal selectors |
diffStyle | 'split' | 'unified' | Low — standard enum |
diffIndicators | 'bars' | Low |
hunkSeparators | 'line-info' | Low |
enableLineSelection | true | Low |
enableHoverUtility | true | Medium — deprecated prop |
onLineSelectionEnd | callback | Medium — signature could change |
3. Shadow DOM Selectors (via unsafeCSS)
These are the selectors we inject CSS rules against. They target data-* attributes inside Pierre's shadow DOM. If Pierre renames or removes any of these, our styling breaks silently.
Currently used:
:host— shadow root[data-diff]— root diff container[data-file]— file wrapper[data-diffs-header]— header bar[data-error-wrapper]— error display[data-virtualizer-buffer]— virtual scroll buffer[data-file-info]— file metadata row[data-column-number]— line number gutter[data-diffs-header] [data-title]— title (we hide it)[data-diff-type='split']— split layout mode[data-overflow='scroll']/[data-overflow='wrap']— overflow mode
4. CSS Variables We Override
We override these --diffs-* variables to theme Pierre:
--diffs-bg,--diffs-fg— base colors--diffs-dark-bg,--diffs-light-bg— theme-specific backgrounds--diffs-dark,--diffs-light— theme-specific foregrounds
5. CSS Variables We Inject (Custom)
We set these on a wrapper div outside the shadow DOM, relying on CSS custom property inheritance:
--split-left,--split-right— control the split pane grid ratio
The unsafeCSS grid override references these: grid-template-columns: var(--split-left, 1fr) var(--split-right, 1fr). The 1fr fallback ensures the layout is safe if the variables aren't set.
6. Grid Layout Assumption
Pierre's split view uses CSS Grid with grid-template-columns: 1fr 1fr. We override this for the resizable split pane. If Pierre changes its layout engine (e.g., to flexbox or a different grid structure), the override will stop working.
How to verify: In the upstream source, search for grid-template-columns in the diff component styles.
Verification Checklist
When reviewing changes that touch the Pierre integration, check:
Props & Types
- Read the current
.d.tsfiles to confirm prop names and types haven't changed - Check if
renderHoverUtilityis still supported (it's deprecated — may be removed) - Verify
DiffLineAnnotationstill usesside: 'deletions' | 'additions'(not'old' | 'new') - Confirm
SelectedLineRangeshape:{ start, end, side? }
Shadow DOM Selectors
- Grep the upstream source for each
data-*attribute we target inunsafeCSS - If upgrading the package version, diff the old and new CSS/HTML output for renamed attributes
- Test both
splitandunifiedviews — selectors are layout-dependent
CSS Variables
- Grep upstream for
--diffs-bg,--diffs-fg, and other variables we override - Verify the variable names haven't been renamed or removed
- Check that
!importantis still needed (Pierre may change specificity)
Theme Compliance
- New UI elements must use theme tokens (
bg-border,bg-primary, etc.), not hardcoded colors likebg-blue-500 - The existing
ResizeHandlecomponent inpackages/ui/components/ResizeHandle.tsxsets the visual convention — match it
Build & Runtime
- Run
bun run dev:reviewand verify the diff renders in both split and unified modes - Check the browser console for Pierre warnings (e.g.,
parseLineType: Invalid firstChar) - Test with add-only and delete-only files (Pierre doesn't render split grid for these)
- If changing UI code, remember build order:
bun run --cwd apps/review build && bun run build:hook
When Upgrading @pierre/diffs
- Check the upstream changelog / commit history at https://github.com/pierrecomputer/pierre
- Diff the
.d.tsfiles between old and new versions:# Before upgrading, snapshot current types cp -r node_modules/@pierre/diffs/dist /tmp/pierre-old # After upgrading diff -r /tmp/pierre-old node_modules/@pierre/diffs/dist - Search for renamed/removed data attributes in the new version
- Run through the full verification checklist above
- Test the resizable split pane — it depends on grid layout internals
Related skills
Generative Code Art
anthropics
Create algorithmic art with p5.js using randomness and interactive parameters.
UI/UX Pro Max
anthropics
Build production-grade web components and interfaces with distinctive, polished design.
Artifact Theme Toolkit
anthropics
Apply professional color and font themes to slides, docs, and web pages.
Multi-Component Web Artifacts
anthropics
Build complex React artifacts with Tailwind CSS and shadcn/ui components.