Verify it still builds clean:
The repo has 5 files. Let me fetch all the reference docs simultaneously:
Also update the preview_excalidraw reference at the bottom of the skill:
I now have everything I need. Let me create the skill directory with all the files:
Got it. Let me strip the TUI display out entirely and make it a clean export-to-PNG tool, then update the skill to always use it.
Verify the build is clean:
Now test the render script first before building the extension:
Good. Now I have everything I need. Let me build the extension:
The skill is installed. Here's a summary of what was done:
Installed: excalidraw skill at ~/.pi/agent/skills/excalidraw/
excalidraw/
├── SKILL.md # Main skill file (auto-loaded on trigger)
└── references/
├── best-practices.md # Design tips, color theory, typography
├── diagram-patterns.md # Professional patterns (flowcharts, sequence, mind maps, etc.)
├── element-reference.md # Full property reference for all element types
└── examples.md # Complete working JSON templates
What this skill enables:
.excalidraw JSON files programmatically for flowcharts, architecture diagrams, sequence diagrams, mind maps, ERDs, wireframes, and morePi will automatically activate this skill whenever you ask to create a diagram, flowchart, architecture drawing, or anything in Excalidraw format. Use /reload if you're in an active Pi session to pick it up immediately.
Now swap the TUI component to use sixel:
Good, let's debug step by step. First let's check the environment and try blasting a raw Kitty sequence straight to the terminal:
Let me investigate the environment and excalidraw-cli first.
Let me create a quick test diagram and fire the preview tool!
Do /reload and then ask me to draw something — I'll write the .excalidraw file and immediately call export_excalidraw, which saves the PNG right next to it. You can open the PNG in any image viewer (xdg-open, display, etc.).
Sixel bytes look correct (\x1bP DCS prefix). Let me update the extension to try sixel via ImageMagick, since that's what xterm understands:
It works — 7060 chars of base64 PNG. Now let me build the Pi extension:
Now let's verify the extension loads cleanly with a quick type-check:
Valid PNG, 220×120px. Now let's do the final sanity check on the full extension structure:
Everything is in place. Here's what was built:
render.ts — A standalone Bun/Playwright script that:
@excalidraw/excalidraw from jsDelivr CDN into a headless Chromium pageexportToBlob() on the diagram elementsindex.ts — The Pi extension that:
tmux set -g allow-passthrough on) automatically before renderingrender.ts as a subprocessencodeKitty from @mariozechner/pi-tui (bypassing the tmux capability detection)Manually:
/preview-diagram path/to/diagram.excalidraw
Automatically by the AI: After creating a .excalidraw file, Claude can call the preview_excalidraw tool directly to show it to you without any extra prompting.
Your outer terminal (the one running tmux) must support the Kitty graphics protocol — Kitty, Ghostty, WezTerm, or iTerm2 all work. Run /reload in Pi to pick up the extension, then try it with /preview-diagram on a diagram.
Builds clean. Let's do a quick end-to-end test of the full render → display pipeline to make sure the PNG is valid:
Now write all the reference files in parallel:
Now let me fetch the GitHub repository to see its contents:
Let me test the export command and then look at how Pi renders images:
Wait, there's a bug with the await in the IIFE. Let me fix the render script properly:
DISPLAY=:0 and ImageMagick supports sixel! Let me check if xterm has sixel enabled and test a raw sixel render:
The scripts race with the IIFE. Let me fix the render script to use addScriptTag which awaits each script's load:
Did the image pop up? You should have seen two rounded rectangles connected by an arrow — "Hello from Pi!" → "It works! 🎉".
If nothing appeared, the most likely culprit is the outer terminal not supporting the Kitty graphics protocol. What terminal emulator are you running tmux inside?
Good. Do /reload in Pi then run:
/preview-diagram /tmp/hello.excalidraw
The extension now tries sixel (xterm's native format) via ImageMagick before falling back to Kitty. Since tmux allow-passthrough is already on and DISPLAY=:0, the DCS sixel sequences should pass through tmux to xterm. Let me know what you see — even garbled output is useful info.
Now update the skill to always export after creating a diagram:
Let me check the Pi TUI documentation to see what's possible.
I'll start by reading the relevant skill documentation and fetching the GitHub repo simultaneously.
Not directly — but here's the full picture:
Pi has an Image TUI component (in @mariozechner/pi-tui) that renders images using terminal graphics protocols (Kitty, iTerm2, Ghostty, WezTerm). It takes base64 image data:
So the rendering capability is there — but only for image formats (PNG, etc.), not for .excalidraw JSON directly.
An .excalidraw file is JSON that needs a renderer to become a visual. To bridge that gap you'd need:
A converter — something that takes .excalidraw JSON → PNG/SVG. Options:
@excalidraw/excalidraw (needs a browser/headless Chrome)excalidraw-cli (headless Chrome wrapper)A Pi extension — calls the converter, takes the resulting PNG, and shows it via the Image component as an overlay or widget
A /preview-excalidraw <file.excalidraw> command (or auto-preview after generation) that pops up the rendered diagram in-TUI — but only in terminals that support the Kitty graphics protocol (Kitty, Ghostty, WezTerm, iTerm2). Standard terminals would see nothing or garbage.
TL;DR: No native support exists, but it's buildable as an extension. Want me to build one? I'd need to know: which terminal you use (to confirm graphics protocol support) and whether you're okay installing something like excalidraw-cli (which requires Chrome/Puppeteer).