Skip to content

Instantly share code, notes, and snippets.

@ryanlewis
Last active June 10, 2026 11:22
Show Gist options
  • Select an option

  • Save ryanlewis/ae6a1570fab365f29392bb7db6e09bca to your computer and use it in GitHub Desktop.

Select an option

Save ryanlewis/ae6a1570fab365f29392bb7db6e09bca to your computer and use it in GitHub Desktop.
preview-markdown — Claude Code skill: present markdown docs in a separate terminal pane (herdr, cmux, Ghostty 1.3+, iTerm2)
name preview-markdown
description Present a markdown file to the user in a separate terminal pane with rich rendering, instead of pasting its content into the conversation. Use when writing a tmp markdown doc for a long explanation, plan, report, or complex point, or when the user says "preview this", "show me the doc", "open it in a pane", or asks to view a markdown file alongside the terminal. Works in herdr, cmux, Ghostty (≥1.3), and iTerm2; falls back gracefully elsewhere.

Previewing markdown files in a separate pane

When presenting a markdown doc to the user — a long explanation, plan, report, or anything written to a tmp file — open it in a split pane rather than pasting the content into the conversation.

1. Detect the terminal and viewer

One command discovers the terminal and whether glow is installed:

echo HERDR_ENV=$HERDR_ENV CMUX_WORKSPACE_ID=$CMUX_WORKSPACE_ID TERM_PROGRAM=$TERM_PROGRAM TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION GLOW=$(command -v glow || echo missing)

Check in priority order — multiplexers run inside a terminal, so they must win over TERM_PROGRAM:

  1. HERDR_ENV set → herdr
  2. CMUX_WORKSPACE_ID set → cmux
  3. TERM_PROGRAM=ghostty and version ≥ 1.3.0 → Ghostty (AppleScript)
  4. TERM_PROGRAM=iTerm.app → iTerm2 (AppleScript)
  5. None of the above → no pane support; give the file path and summarise inline instead

Viewer (matters for every branch except cmux, which renders markdown itself):

  • GLOW is a path → viewer is glow -t (interactive TUI, live-reloads on file changes)
  • missing → viewer is less (plain text, no live-reload — tell the user to press R in the pane after edits). Also advise the user that installing glow gives rendered, live-reloading previews, showing the command: brew install glow. Do not install it (or offer to) unless they explicitly ask you to

2. Open the preview

cmux

One command — opens the doc in a read-only markdown panel split to the right of the focused surface:

cmux markdown open <path>

Then:

  • The output is OK surface=surface:N pane=pane:N path=... — capture the surface id for cleanup
  • The panel live-reloads when the file changes on disk (no viewer needed — cmux renders markdown itself)
  • For routing options (--workspace, --surface, --window) or troubleshooting, load the cmux-markdown skill

Ghostty (≥ 1.3.0)

Split right of the focused terminal with the viewer as the new surface's command — returns the new terminal's id (a UUID):

osascript <<EOF
tell application "Ghostty"
    set cfg to new surface configuration
    set command of cfg to "<viewer> '$DOC_PATH'"
    set newTerm to split (focused terminal of selected tab of front window) direction right with configuration cfg
    return id of newTerm
end tell
EOF
  • First use triggers a macOS Automation (TCC) prompt — if it fails with a permissions error, tell the user to approve it (or it's disabled via macos-applescript = false in their Ghostty config)
  • The AppleScript API is a preview feature in 1.3 — expect breaking changes in 1.4
  • There's no way to read the pane back to verify; trust a clean exit

iTerm2

Split side-by-side ("vertically" = vertical divider) with the viewer as the session command — returns the new session's id:

osascript <<EOF
tell application "iTerm2"
    tell current session of current tab of current window
        return id of (split vertically with default profile command "<viewer> '$DOC_PATH'")
    end tell
end tell
EOF
  • Same one-time TCC prompt as Ghostty
  • The pane may auto-close when the viewer exits (profile-dependent "close on exit")

In every branch, substitute <viewer> with the one detected in step 1 (glow -t or less), and report the captured pane/surface/terminal/session id so it can be closed later. With glow -t, file edits live-reload in the pane automatically — never re-open the pane after editing the doc.

herdr

Split a new pane to the right of the focused pane, capture its id, then run the viewer in it:

DOC_PATH=<path>
PANE_ID=$(herdr pane split "$(herdr pane list | jq -r '.result.panes[] | select(.focused) | .pane_id')" --direction right --no-focus | jq -r '.result.pane.pane_id')
herdr pane run "$PANE_ID" "<viewer> '$DOC_PATH'" && echo "$PANE_ID"
  • Run all three lines in one shell call (variables don't survive across calls)
  • Capture the id from the split response as above — do not infer it from herdr pane list; its ordering doesn't reflect creation order
  • Verify it rendered: herdr pane read $PANE_ID | head

3. Clean up

When the user is finished with the preview, close the pane (the tmp file can stay unless asked):

# herdr
herdr pane close <pane_id>

# cmux — use the surface id captured from `cmux markdown open`
cmux close-surface --surface <surface_id>

# Ghostty — use the terminal id (UUID) returned by the split; quotes required
osascript -e 'tell application "Ghostty" to close (first terminal whose id is "<terminal_id>")'

# iTerm2 — use the session id returned by the split
osascript -e 'tell application "iTerm2" to close (first session of current tab of current window whose id is "<session_id>")'

Install the preview-markdown skill

The preview-markdown skill teaches Claude Code to present markdown documents — plans, reports, long explanations — in a separate terminal pane with rich rendering, instead of dumping them into the conversation. It detects the terminal it's running in (herdr, cmux, Ghostty ≥ 1.3, or iTerm2), opens the doc in a split pane to the right (live-reloading as the file is edited, where supported), and closes the pane on request when you're done. In unsupported terminals it falls back to summarising inline.

Copy everything below the line into Claude Code to install it.


Install the preview-markdown Claude Code skill by following these steps exactly:

  1. Download the skill file into my personal skills directory:

    mkdir -p ~/.claude/skills/preview-markdown
    curl -fsSL https://gist.githubusercontent.com/ryanlewis/ae6a1570fab365f29392bb7db6e09bca/raw/preview-markdown.md -o ~/.claude/skills/preview-markdown/SKILL.md
  2. Verify the download: the file must start with YAML frontmatter declaring name: preview-markdown. If it doesn't, stop, show me the first few lines, and don't continue.

  3. Add the following section to ~/.claude/CLAUDE.md so the skill gets used proactively. Create the file if it doesn't exist. If it already contains an equivalent instruction, leave it as is and tell me:

    ## Long explanations or complex points
    For anything needing a long explanation or a complex point, write a tmp markdown file
    and present it in a separate pane using the `preview-markdown` skill.
  4. Report what you did. Mention that:

    • the skill is picked up in new Claude Code sessions
    • rendered, live-reloading previews need glow (brew install glow); without it the skill falls back to less — but do not install glow or offer to install it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment