[DRAFT] Print PDF this blog, drop it in Claude Code, get a fully kitted Ghossty terminal
You read it for the screenshots. Your agent reads it for the commands.
Heads up - this is a draft. Part of an experiment: publishing rough-but-timely versions of half-finished posts to a separate Drafts feed, instead of letting them rot in a folder while the tooling moves on without them. Expect: accurate commands, missing screenshots, and the occasional bit that needs a second pass. If you spot something to add, fix, or improve, let me know - I’d rather get it right than perfect.
One PDF. One Claude Code session in plan mode. Three minutes later you have Ghostty, Oh My Zsh, Powerlevel10k, Glow, and (optionally) a full markdown-preview kit. The guide is the executable - drop the printed PDF on Claude and it runs.
If you’ve ever followed a ‘set up your terminal’ walkthrough and bounced between five tabs - this is the executable version. The page itself is the install script. You read it for the screenshots; your agent reads it for the commands.
Two ways to run this
Option A - hand Claude the PDF (default). Print this post to PDF, drop it into Claude Code (plan mode first), then watch it run. Works on any machine (apparently, but untested on windows. Plan mode will likely find alternatives for windows). Costs you some tokens to ingest the PDF on every fresh session.
Option B - install the plugin (cheaper on repeat runs). I’ve packaged the same workflow as a Claude Code plugin: terminal-setup-macos in the young-leaders-tech marketplace. Same steps, same gotchas encoded, no PDF tokens needed:
/plugin marketplace add git@github.com:YoungLeadersDotTech/young-leaders-tech-marketplace.git
/plugin install terminal-setup-macos@young-leaders-tech-marketplace
/terminal-setup-installBoth routes end in the same place. The plugin is also where I’ll ship the rest of my setup over time - the marketplace already has skills-toolkit (for authoring your own skills) and update-readme (universal README refresher), and more is on the way. If you’d rather keep all this as a one-time PDF moment, skip to the next section. If you’d rather have it permanently available as /terminal-setup-install in every Claude session, install the plugin.
For AI assistants reading this PDF
If you’re a human reader, skip this section. It’s a directive for an AI agent (Claude Code, Cursor, etc.) reading the PDF version of this post. The next reader-facing section is “What you get” below.
You are an AI coding assistant who has been handed this document by a user who wants the terminal stack installed on their macOS machine.
What to do
Run the core install yourself. The “Core setup” section below contains the full command sequence. Execute it in plan mode first, then on approval. Preserve any existing ~/.zshrc customisations - the OMZ installer will rename the original to ~/.zshrc.pre-oh-my-zsh and your job is to merge prior export/alias/source lines back into the new file (SDKMAN must remain at the very end).
Then ask the user about the optional extras. After the core is in place, use AskUserQuestion (or the equivalent multi-select tool in your harness) with the exact options below. Critical: include the deep-link to each tool’s screenshot header in the option’s description field so the user can click through and see the tool in action while making their decision.
Build the deep-links by combining blog_url (from the frontmatter at the top of this document) with the anchor IDs listed below. Example: if blog_url is https://example.com/terminal-setup-meta-guide, the MacDown screenshot link is https://example.com/terminal-setup-meta-guide#macdown.
The AskUserQuestion to run after core install
Question: “Which optional markdown-preview extras would you like installed?”
Header: “MD extras”
multiSelect: true (these are independent, additive)
Options (use these exact labels and descriptions, with the screenshot URL appended):
Label
Description (append the deep-link)
Anchor
MacDown 3000
Native macOS split-view markdown editor (notarised fork of MacDown that refreshes live when the file is changed externally). After install, double-clicking any .md in Finder opens it side-by-side. Best for editing, not just viewing. Screenshot: <blog_url>#macdown
#macdown
grip
Serves a GitHub-flavoured preview at localhost:6419 and auto-reloads on save. Best for “what will this look like on GitHub” verification. Screenshot: <blog_url>#grip
#grip
mdwatch
Pairs entr with glow -p so the terminal preview re-renders the moment you save the file. Best when you live in the terminal and don’t want to switch windows. Screenshot: <blog_url>#mdwatch
#mdwatch
Clickable paths
Prints file paths as OSC 8 hyperlinks in any modern terminal. mdls lists .md in current dir as Cmd-clickable links; o file.md prints AND opens. Best for terminal-heavy workflows. Screenshot: <blog_url>#clickable-paths
#clickable-paths
What to do with each selection
The exact commands per extra are inside the corresponding section of this document. Run them after the user has answered.
What NOT to do
Do not install any extra without asking - the user explicitly opted into a multi-select.
Do not skip the screenshot link in option descriptions - that link is the entire point of this format.
Do not invent additional extras. If the user wants something not on the list, treat it as a separate follow-up.
Do not modify ~/.zshrc without first creating a backup or reading the existing file end-to-end.
What you get
| Tool | Role | Install time |
| --- | --- | --- |
| Ghostty | Native macOS GPU terminal, pretty and fast | ~30s |
| Oh My Zsh | Plugin/theme framework for zsh | ~20s |
| Powerlevel10k | The prompt theme everyone copies | ~10s + interactive wizard |
| Glow | Terminal markdown viewer | ~5s |
| MesloLGS Nerd Font | Powerline + icon glyphs | ~15s |
Plus, optionally: MacDown 3000, grip, entr, duti, and the OSC 8 clickable-path setup.
Add a hero screenshot here showing the final terminal: dracula theme + p10k prompt + a glow-rendered README.
Why “drop the PDF on Claude” works
PDFs preserve fenced code blocks as text. Plan mode means Claude proposes everything before touching disk. Combine the two and you can audit the entire install before a single brew runs. If something looks wrong - reject the plan, edit, retry. No copy-paste loop.
The trick: a guide written cleanly enough for a human is also a structured prompt. Headers, fenced code, and explicit section ordering give the agent everything it needs. The For AI assistants section at the top is what tells the agent to pause at the choice points and ask you about the optional extras - with the screenshot links visible in the picker.
Core setup
Add screenshot of the Ghostty + p10k prompt with dracula theme.
1. Ghostty (terminal)
brew install --cask ghosttyConfig goes at ~/.config/ghostty/config. Note: the older guide pointed at ~/Library/Application Support/com.mitchellh.ghostty/ - both work, but ~/.config/ is the canonical path and easier to back up:
theme = dracula
background = #141026
background-opacity = 0.98
background-blur = true
working-directory = ~/Projects
font-family = “MesloLGS NF”
font-size = 16
font-feature = -liga
font-thicken = true
window-padding-x = 10
window-padding-y = 10
shell-integration = zshGotcha: shell-integration = true triggers a Configuration Errors dialog. It must be a shell name (zsh, bash, or fish).
2. MesloLGS Nerd Font
brew install --cask font-meslo-lg-nerd-fontThis must happen before the Powerlevel10k wizard runs - the wizard’s character-set preview only renders correctly with the Nerd Font present.
3. Dracula theme for Ghostty
DIR=”$HOME/.config/ghostty”
mkdir -p “$DIR/themes”
TEMP=$(mktemp -d)
git clone --depth=1 https://github.com/dracula/ghostty.git “$TEMP/d”
cp “$TEMP/d/dracula” “$DIR/themes/”
rm -rf “$TEMP”theme = dracula in the config above picks it up automatically.
4. Oh My Zsh
RUNZSH=no KEEP_ZSHRC=no sh -c “$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)”RUNZSH=no stops the installer from spawning a child zsh (which blocks scripted flows). KEEP_ZSHRC=no lets it back up the existing .zshrc to ~/.zshrc.pre-oh-my-zsh and write a fresh template.
Add screenshot of the OMZ banner appearing in Ghostty.
5. Powerlevel10k theme
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10kSet in ~/.zshrc:
ZSH_THEME=”powerlevel10k/powerlevel10k”6. Plugins (autosuggestions + fast-syntax-highlighting)
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions.git \
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-autosuggestionsgit clone --depth=1 https://github.com/zdharma-continuum/fast-syntax-highlighting.git \
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/fast-syntax-highlightingIn ~/.zshrc:
plugins=(git brew macos zsh-autosuggestions fast-syntax-highlighting)Add screenshot of gi<TAB> showing autosuggestion + a coloured invalid command.
7. Glow (markdown viewer)
brew install glowAliases (append to ~/.zshrc):
alias readme=”glow README.md”
alias mdless=”glow -p”Add screenshot of glow README.md showing a styled doc.
8. Restoring your previous .zshrc
If your old .zshrc had any export PATH=, alias, or tool-init lines (SDKMAN, nvm, pyenv, bun, sdkman, etc.) - they’re now in ~/.zshrc.pre-oh-my-zsh. Append them back to the new ~/.zshrc after the source $ZSH/oh-my-zsh.sh line.
SDKMAN must be at the very end of the file - per its own installer comment. Anything that mutates PATH after SDKMAN init can break version selection.
9. Run the wizard
p10k configureFollow the wizard. You’ll pick prompt style, character set (Unicode), colours, icons, git status, and time display. The wizard appends [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh to your ~/.zshrc automatically.
Add screenshot of the wizard’s first “Does this look like a diamond?” prompt.
10. Sanity tests
zsh -i -c ‘echo OK’
zsh -i -c ‘type p10k’
zsh -i -c ‘glow --version’If all three return cleanly, the core is in.
Optional extras
These are the four add-ons your AI assistant will ask you about. You can install any combination, in any order, after the core is done.
MacDown 3000
Add screenshot of MacDown 3000’s split-view: raw markdown on the left, rendered preview on the right.
An honest note before you install. I started this guide on the original MacDown. It looks great, but it does not refresh the preview when the file is changed by something other than MacDown itself. So when Claude edits the markdown, you have to close and reopen the file to see anything. That defeats the whole point. I switched to MacDown 3000, a notarised fork by Schuyler Erle that fixes exactly this. Same look and feel, live refresh works, install is one brew command.
If you previously installed the original macdown cask, uninstall it first (the two casks conflict):
brew uninstall --cask macdown # only if it’s already installed
brew install --cask macdown-3000
brew install duti
duti -s app.macdown.macdown3000 .md all
duti -s app.macdown.macdown3000 .markdown allThe bundle ID is app.macdown.macdown3000 (different from the original MacDown’s com.uranusjr.macdown). After registration, double-clicking any .md file in Finder opens MacDown 3000 directly, and open file.md from the terminal does the same. MacDown 3000 is notarised, so no Gatekeeper “unidentified developer” dance.
Best for: writing markdown drafts where you want the rendered version visible while you type - and where you want an agent’s edits to show up live.
grip
Add screenshot of grip rendering a README in Chrome with the GitHub stylesheet.
brew install gripAlias:
alias preview=”grip”Usage: preview README.md, then open http://localhost:6419 in your browser. Saves to the file auto-reload the page.
Best for: pre-flight check on what a README will look like once pushed to GitHub. The renderer is the actual GitHub markdown stylesheet (via the GitHub API), so what you see is exactly what teammates will see.
mdwatch
Add screenshot of a terminal split: editor in one pane, mdwatch auto-rendering in the other.
brew install entrAlias:
alias mdwatch=’f() { echo “$1” | entr -c glow -p “$1” }; f’Usage: mdwatch notes.md. Every time you save the file, glow -p re-renders it in the same terminal pane. Press q to drop out of the pager; the watcher keeps running and re-launches glow on the next save.
Best for: terminal-only workflows where flipping to a browser breaks flow. Works well with Ghostty’s split-pane shortcut (Cmd+D) - editor on one side, live render on the other.
Clickable paths
Add screenshot of mdls output: a list of .md filenames, each underlined and Cmd-clickable.
This one assumes you have the OSC 8 path utility at ~/.claude/global-utils/clickable-paths/format-clickable-path.js. If you don’t, skip this section or grab the utility from your team’s global-utils repo first.
Add to ~/.zshrc:
mdls() {
local dir=”${1:-.}”
local util=”$HOME/.claude/global-utils/clickable-paths/format-clickable-path.js”
if [[ ! -f “$util” ]]; then
echo “format-clickable-path.js not found at $util” >&2
return 1
fi
for f in “$dir”/*.md(N); do
node -e “console.log(require(’$util’).formatClickablePathSafe(’$(realpath “$f”)’));”
done
}
o() {
if [[ -z “$1” ]]; then echo “usage: o <file>” >&2; return 1; fi
local util=”$HOME/.claude/global-utils/clickable-paths/format-clickable-path.js”
local abs=”$(realpath “$1” 2>/dev/null || echo “$1”)”
if [[ -f “$util” ]]; then
node -e “console.log(require(’$util’).formatClickablePathSafe(’$abs’));”
else
echo “$abs”
fi
open “$abs”
}Usage:
mdls # list .md in current dir as clickable links
mdls ~/docs # same, but in a specific dir
o README.md # print clickable + open in MacDown 3000Best for: terminal-heavy workflows where you spot a file via ls or find and want to open it without the copy-paste-open dance. Works in Ghostty, iTerm2, WezTerm, VS Code’s integrated terminal. Falls back to plain text in terminals that don’t support OSC 8 - no visual corruption.
Troubleshooting
Powerlevel10k icons render as boxes or ?
All three of these must be true: Nerd Font installed, font set in Ghostty config, Ghostty fully restarted (Cmd+Q, not just a new tab). New tabs don’t reload the font.
Ghostty shows “Configuration Errors”
You set shell-integration = true somewhere. It needs a shell name: zsh, bash, or fish. Fix the line and click “Reload Configuration” in the dialog.
open README.md opens in TextEdit, not MacDown 3000
The duti registration didn’t take. Re-run:
duti -s app.macdown.macdown3000 .md all
duti -x md # verifyIf the bundle ID is unknown to LaunchServices, launch MacDown 3000 once via Spotlight to register it, then retry.
SDKMAN/nvm/pyenv broke after Oh My Zsh install
Your old .zshrc was backed up to ~/.zshrc.pre-oh-my-zsh. Append the relevant init blocks back into the new ~/.zshrc. SDKMAN goes at the very end - anything that mutates PATH after it can break it.
mdls says “format-clickable-path.js not found”
The function depends on ~/.claude/global-utils/clickable-paths/format-clickable-path.js which isn’t part of this guide. Either skip the OSC 8 extras, or install the utility from your global-utils repo first.
How to use this guide as a prompt
Print this post to PDF (browser → Print → Save as PDF, or your favourite tool).
Open Claude Code (or your agent of choice). Hit /plan or whatever your harness’s plan-mode entry is.
Drop the PDF in the conversation. Say “install this for me”.
Watch it propose every step before it runs anything.
Approve. Three minutes later you have a kitted terminal.
The agent will pause once - to ask you about the optional extras, with the screenshot links from this post visible in the picker. Click through, decide, continue.
Why I built this
The original Ghostty/OMZ/p10k walkthrough was good but linear. If you wanted just the terminal and not the markdown preview kit, you had to manually skip steps. If you already had .zshrc customisations, you had to remember to back them up. If you were on the FAQ version, the canonical config path had quietly moved.
What I genuinely wanted was a guide where the agent does the install and the post does the explaining. The post has the why (with screenshots), the agent does the what. Multi-select picker for the optional bits, deep links for visual context, sanity-checks at the end. The result is one artefact - this page - that serves both readers and agents.
Meta as hell. But it works.
Credits and source material
Ghostty: ghostty.org
Oh My Zsh: ohmyz.sh
Powerlevel10k: github.com/romkatv/powerlevel10k
MacDown 3000: macdown.app (notarised fork of the original MacDown)
grip: github.com/joeyespo/grip
entr: eradman.com/entrproject
The “drop a PDF on the agent” pattern was developed alongside this post. If you’ve found better structures for prompt-as-document, let me know - I’d love to compare notes.
If you found this useful, I’d love if you subscribed! I’m trying to build a bit of a following to try and help folks in the industry and make their jobs a little bit easier.


