dont worry too much about the terminal support. just write it out assuming defaults
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:
try it out. the reload worked
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 templatesWhat 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.).
try it out
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.excalidrawAutomatically 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.
ok try it out. im using tmux, u can use the excalidraw-cli with bun
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:
file:///home/lakshyaag/.bun/install/global/node_modules/@mariozechner/pi-tui/dist/tui.js:854 throw new Error(errorMsg); ^
Error: Rendered line 1162 exceeds terminal width (15867 > 144).
This is likely caused by a custom TUI component not truncating its output. Use visibleWidth() to measure and truncateToWidth() to truncate lines.
Debug log written to: /home/lakshyaag/.pi/agent/pi-crash.log at TUI.doRender (file:///home/lakshyaag/.bun/install/global/node_modules/@mariozechner/pi-tui/dist/tui.js:854:23) at file:///home/lakshyaag/.bun/install/global/node_modules/@mariozechner/pi-tui/dist/tui.js:281:18 at process.processTicksAndRejections (node:internal/process/task_queues:85:11)
this is the error. i thinkw e can skip rendering the preview in the terminal, but ewnsure that the skill knows how to export an excalidraw file to png and save it in the same directory
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:
is there a way to see the diagram in the TUI?
preview_excalidraw Previewed /tmp/hello.excalidraw
Rendering /tmp/hello.excalidraw …
i saw this. didnt see the image. we can try to fix it step by step. lets try to render any image to the terminal first
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.excalidrawThe 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:
const image = new Image(base64Data, "image/png", theme, { maxWidthCells: 80, maxHeightCells: 24 });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).
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/preview-diagram path/to/diagram.excalidraw/preview-diagram /tmp/hello.excalidrawconst image = new Image(base64Data, "image/png", theme, { maxWidthCells: 80, maxHeightCells: 24 });