mcpField
P
pierre-guard

pierre-guard

github.com/backnotpropTesting & quality9.7k246 installsUpdated today
Repository

About pierre-guard

pierre-guard is a skill for checking Plannotator’s integration with @pierre/diffs, aimed at developers maintaining its diff review UI. It focuses on compatibility with Shadow DOM selectors, CSS variables, and grid layout assumptions.

Key features

  1. 01Check component props and types
  2. 02Inspect Shadow DOM selectors
  3. 03Verify CSS variables and theming
  4. 04Check split-grid layout assumptions
  5. 05Test builds and runtime using a checklist

Use cases

  1. 01Check API changes before upgrading @pierre/diffs
  2. 02Review changes to the diff viewer
  3. 03Verify split and unified views
  4. 04Investigate styling or layout compatibility

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/backnotprop/plannotator --skill pierre-guard

After installing, type/pierre-guardin Claude Code to confirm it loaded.

Details

From the project README

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

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:

PropTypeNotes
fileDiffFileDiffMetadataFrom getSingularPatch() or processFile()
optionsFileDiffOptions<T>See options table below
lineAnnotationsDiffLineAnnotation<T>[]{ side, lineNumber, metadata }
selectedLinesSelectedLineRange | null{ start, end, side }
renderAnnotation(ann) => ReactNodeCustom inline annotation renderer
renderHoverUtility(getHoveredLine) => ReactNodeThe + button on hover (deprecated upstream — watch for removal)
2. Options Object
OptionValue We PassRisk
themeType'dark' | 'light'Low — standard enum
unsafeCSSCSS stringHigh — targets internal selectors
diffStyle'split' | 'unified'Low — standard enum
diffIndicators'bars'Low
hunkSeparators'line-info'Low
enableLineSelectiontrueLow
enableHoverUtilitytrueMedium — deprecated prop
onLineSelectionEndcallbackMedium — 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.ts files to confirm prop names and types haven't changed
  • Check if renderHoverUtility is still supported (it's deprecated — may be removed)
  • Verify DiffLineAnnotation still uses side: 'deletions' | 'additions' (not 'old' | 'new')
  • Confirm SelectedLineRange shape: { start, end, side? }
Shadow DOM Selectors
  • Grep the upstream source for each data-* attribute we target in unsafeCSS
  • If upgrading the package version, diff the old and new CSS/HTML output for renamed attributes
  • Test both split and unified views — 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 !important is still needed (Pierre may change specificity)
Theme Compliance
  • New UI elements must use theme tokens (bg-border, bg-primary, etc.), not hardcoded colors like bg-blue-500
  • The existing ResizeHandle component in packages/ui/components/ResizeHandle.tsx sets the visual convention — match it
Build & Runtime
  • Run bun run dev:review and 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

  1. Check the upstream changelog / commit history at https://github.com/pierrecomputer/pierre
  2. Diff the .d.ts files 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
    
  3. Search for renamed/removed data attributes in the new version
  4. Run through the full verification checklist above
  5. Test the resizable split pane — it depends on grid layout internals

Comments

Markdown supported