render-diff
MANDATORY: Use BEFORE showing ANY diff to user - transforms git diff into 4-column table with box characters (╭╮╰╯│). Required for approval gates, code reviews, change summaries.
What this skill does
# Render Diff
## Purpose
Transform raw git diff output into a 4-column table format optimized for approval gate reviews.
Each hunk is rendered as a self-contained box with file header, making diffs easy to review.
## Pre-computed Output (MANDATORY for Approval Gates)
**Check context for "PRE-COMPUTED RENDER-DIFF OUTPUT".**
If found:
1. Output the rendered diff content **directly** - no preamble, no Bash commands
2. The content is already formatted with 4-column tables and box characters
3. Do NOT wrap in code blocks or show any tool invocations
If NOT found during an approval gate: **FAIL immediately**.
```bash
"${CLAUDE_PLUGIN_ROOT}/scripts/check-hooks-loaded.sh" "diff output" "render-diff"
if [[ $? -eq 0 ]]; then
echo "ERROR: Pre-computed diff not found. Check:"
echo "1. Handler is registered in skill_handlers/__init__.py"
echo "2. Handler file exists in plugin/hooks/skill_handlers/"
echo "3. Base branch is detectable from worktree/branch name"
fi
```
Output the error and STOP. Do NOT attempt manual Bash computation.
**Why this matters (M238):** Running `git diff | render-diff.py` via Bash shows the command
execution to the user, breaking the clean output experience. Pre-computation hides the
implementation details.
## Usage
Pipe git diff output to the script:
```bash
git diff main..HEAD | "${CLAUDE_PLUGIN_ROOT}/scripts/render-diff.py"
```
Or provide a diff file:
```bash
"${CLAUDE_PLUGIN_ROOT}/scripts/render-diff.py" diff-output.txt
```
## Configuration
The script reads `terminalWidth` from `.claude/cat/cat-config.json`:
```json
{
"terminalWidth": 50
}
```
## Output Format
### Hunk Box Structure
Each hunk is a self-contained box with file header repeated:
```
╭────────────────────────────────────────────────╮
│ FILE: src/main.js │
├────┬───┬────┬──────────────────────────────────┤
│ Old│ │ New│ ⌁ function init() │
├────┼───┼────┼──────────────────────────────────┤
│ 6│ │ 6│ const app = express(); │
│ 8│ - │ │ app.use([bodyParser].json()); │
│ │ + │ 8│ app.use([express].json()); │
│ 9│ │ 9│ return app; │
╰────┴───┴────┴──────────────────────────────────╯
```
### Column Definitions
| Column | Width | Content |
|--------|-------|---------|
| Old | 4 chars | Line number in original file (blank for additions) |
| Symbol | 3 chars | `-` removed, `+` added, blank for context |
| New | 4 chars | Line number in new file (blank for deletions) |
| Content | remaining | The actual line text |
### Features
**Hunk Context**: Function/class name from git shown in header row with `⌁`:
```
│ Old│ │ New│ ⌁ function doSomething() │
```
**Word-Level Diff**: Adjacent -/+ pairs highlight changed portions with `[]`:
```
│ 8│ - │ │ app.use([bodyParser].json()); │
│ │ + │ 8│ app.use([express].json()); │
```
**Whitespace Visibility**: Tab↔space changes shown with markers:
```
│ 15│ - │ │ →const indent = 1; │
│ │ + │ 15│ ····const indent = 1; │
```
- `·` (middle dot) for spaces
- `→` for tabs
**Line Wrapping**: Long lines wrap with `↩`:
```
│ 46│ - │ │ logger.info(`Server running ↩ │
│ │ │ │ on port ${port}`); │
```
**Binary Files**:
```
╭────────────────────────────────────────────────╮
│ FILE: logo.png (binary) │
├────────────────────────────────────────────────┤
│ Binary file changed │
╰────────────────────────────────────────────────╯
```
**Renamed Files**:
```
╭────────────────────────────────────────────────╮
│ FILE: old/path.js → new/path.js (renamed) │
├────────────────────────────────────────────────┤
│ File renamed (no content changes) │
╰────────────────────────────────────────────────╯
```
### Legend
Appears once at end, showing only symbols used:
```
╭────────────────────────────────────────────────╮
│ Legend │
├────────────────────────────────────────────────┤
│ - del + add [] changed · space │
╰────────────────────────────────────────────────╯
```
## Example
**Input:**
```bash
git diff main..HEAD | render-diff.py
```
**Output (multiple hunks in same file):**
```
╭────────────────────────────────────────────────╮
│ FILE: src/api.js │
├────┬───┬────┬──────────────────────────────────┤
│ Old│ │ New│ ⌁ function init() │
├────┼───┼────┼──────────────────────────────────┤
│ 6│ │ 6│ const app = express(); │
│ 8│ - │ │ app.use([bodyParser].json()); │
│ │ + │ 8│ app.use([express].json()); │
│ 9│ │ 9│ return app; │
╰────┴───┴────┴──────────────────────────────────╯
╭────────────────────────────────────────────────╮
│ FILE: src/api.js │
├────┬───┬────┬──────────────────────────────────┤
│ Old│ │ New│ ⌁ function start(port) │
├────┼───┼────┼──────────────────────────────────┤
│ 45│ │ 45│ app.listen(port, () => { │
│ │ + │ 46│ logEnvironment(); │
│ 46│ │ 47│ }); │
╰────┴───┴────┴──────────────────────────────────╯
╭────────────────────────────────────────────────╮
│ Legend │
├────────────────────────────────────────────────┤
│ - del + add [] changed │
╰────────────────────────────────────────────────╯
```
## Integration with Approval Gates
### Complete File Coverage (MANDATORY)
Before invoking render-diff, enumerate ALL changed files to ensure complete coverage:
```bash
# Step 1: List all changed files
git diff --name-only "${BASE_BRANCH}..HEAD"
# Step 2: Generate diff for ALL files (no path filtering)
git diff "${BASE_BRANCH}..HEAD" | \
"${CLAUDE_PLUGIN_ROOT}/scripts/render-diff.py" > /tmp/review-diff.txt
# Step 3: Display for approval
cat /tmp/review-diff.txt
```
**Anti-pattern**: Manually specifying paths based on memory. This leads to incomplete diffs.
```bash
# ❌ WRONG - manual path specification misses files
git diff v2.0..HEAD -- plugin/scripts/ plugin/skills/
# ✅ CORRECT - diff entire branch, no path filtering
git diff v2.0..HEAD
```
## Related Skills
- `cat:stakeholder-review` - Uses render-diff for showing changes to reviewers
Related in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.