pierre-guard
关于
This skill protects the integration between Plannotator's code review UI and the `@pierre/diffs` package, which uses Shadow DOM. Use it when modifying the DiffViewer component, updating the package, or changing CSS/selectors that cross the shadow boundary. It helps verify changes don't break the fragile contract with the diff renderer's undocumented internals.
快速安装
Claude Code
推荐npx skills add backnotprop/plannotator -a claude-code/plugin add https://github.com/backnotprop/plannotatorgit clone https://github.com/backnotprop/plannotator.git ~/.claude/skills/pierre-guard在 Claude Code 中复制并粘贴此命令以安装该技能
技能文档
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
GitHub 仓库
相关推荐技能
content-collections
元Content Collections 是一个 TypeScript 优先的构建工具,可将本地 Markdown/MDX 文件转换为类型安全的数据集合。它专为构建博客、文档站和内容密集型 Vite+React 应用而设计,提供基于 Zod 的自动模式验证。该工具涵盖从 Vite 插件配置、MDX 编译到生产环境部署的完整工作流。
polymarket
元这个Claude Skill为开发者提供完整的Polymarket预测市场开发支持,涵盖API调用、交易执行和市场数据分析。关键特性包括实时WebSocket数据流,可监控实时交易、订单和市场动态。开发者可用它构建预测市场应用、实施交易策略并集成实时市场预测功能。
creating-opencode-plugins
元该Skill帮助开发者创建OpenCode插件,用于接入命令、文件、LSP等25+种事件。它提供了插件结构、事件API规范和JavaScript/TypeScript实现模式,适合需要拦截操作、扩展功能或自定义事件处理的场景。开发者可通过它快速构建响应式模块来增强OpenCode AI助手的能力。
sglang
元SGLang是一个专为LLM设计的高性能推理框架,特别适用于需要结构化输出的场景。它通过RadixAttention前缀缓存技术,在处理JSON、正则表达式、工具调用等具有重复前缀的复杂工作流时,能实现极速生成。如果你正在构建智能体或多轮对话系统,并追求远超vLLM的推理性能,SGLang是理想选择。
