跳到主要内容
知仓学习社ZHICANG

pierre-guard

Guard against breaking the @pierre/diffs integration in Plannotator's code review UI. Use this skill whenever modifying DiffViewer.tsx, upgrading th…

不碰外部(只输出文字)无严重或高危命中backnotprop/plannotator

它会碰到什么

扫了多少1 个文本文件,7 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

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

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:
   # 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
  1. Search for renamed/removed data attributes in the new version
  2. Run through the full verification checklist above
  3. Test the resizable split pane — it depends on grid layout internals

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。