Pierre Guard
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 injec...
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.
Install
Quick install
npx skills add https://github.com/pierrecomputer/pierrenpx skills add pierrecomputer/pierre --agent claude-codenpx skills add pierrecomputer/pierre --agent cursornpx skills add pierrecomputer/pierre --agent codexnpx skills add pierrecomputer/pierre --agent opencodenpx skills add pierrecomputer/pierre --agent github-copilotnpx skills add pierrecomputer/pierre --agent windsurfMore install options
Shorthand — useful for multi-skill repos:
npx skills add pierrecomputer/pierreManual — clone the repo and drop the folder into your agent's skills directory:
git clone https://github.com/pierrecomputer/pierre.gitcp -r pierre ~/.claude/skills/Pierre Guard
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.
---
name: pierre-guard
description: 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.
---
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
---
Source: https://github.com/pierrecomputer/pierre
Author: backnotprop
Discovered via: skillsdirectory.com
Genre: development
SKILL.md source
---
name: Pierre Guard
description: 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 injec...
---
# Pierre Guard
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.
---
name: pierre-guard
description: 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.
---
# 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.ts` files)
- **Integration point**: `packages/review-editor/components/DiffViewer.tsx`
- **Current version**: check `packages/review-editor/package.json` for 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
```typescript
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.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:
```bash
# 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
---
**Source**: https://github.com/pierrecomputer/pierre
**Author**: backnotprop
**Discovered via**: skillsdirectory.com
**Genre**: development
Related skills 6
caveman
Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.
secure-linux-web-hosting
Use when setting up, hardening, or reviewing a cloud server for self-hosting, including DNS, SSH, firewalls, Nginx, static-site hosting, reverse-proxying an app, HTTPS with Let's Encrypt or ACME clients, safe HTTP-to-HTTPS redirects, or optional post-launch network tuning such as BBR.
readme-i18n
Use when the user wants to translate a repository README, make a repo multilingual, localize docs, add a language switcher, internationalize the README, or update localized README variants in a GitHub-style repository.
lark-shared
Use when first setting up lark-cli, running auth login, switching user/bot identity (--as), handling permission denied or scope errors, needing to update lark-cli, or seeing _notice in JSON output.
improve-codebase-architecture
Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable.
paper-context-resolver
Optional RigorPilot helper for README-first deep learning repo reproduction. Use only when the README and repository files leave a narrow reproduction-critical gap and the task is to resolve a specific paper detail such as dataset split, preprocessing, evaluation protocol, checkpoint mapping, or runtime assumption from primary paper sources while recording conflicts. Do not use for general paper summary, repo scanning, environment setup, command execution, title-only paper lookup, or replacin...