Skip to content

Instantly share code, notes, and snippets.

@Aboudjem
Last active May 27, 2026 22:22
Show Gist options
  • Select an option

  • Save Aboudjem/da6b37f5d58a9e8b1b238e11a860d3d3 to your computer and use it in GitHub Desktop.

Select an option

Save Aboudjem/da6b37f5d58a9e8b1b238e11a860d3d3 to your computer and use it in GitHub Desktop.
Mac setup guide for Piyush — install everything step by step (Ghostty, oh-my-zsh, Node, Python, Claude Code, browsers, comms, Raycast, etc.)
# Brewfile — Piyush's clean Mac install (May 2026)
# Verified May 2026 against formulae.brew.sh
#
# Usage (Claude does this for you in Phase 4/5):
# brew bundle install --file=Brewfile
#
# What this installs:
# ~33 CLI tools + ~28 GUI apps + 1 font cask
# ~8 GB disk, ~25 min total wall-clock
# ============================================================
# ============================================================
# CLI FORMULAE
# ============================================================
# --- Shell foundation ---
brew "starship" # cross-shell prompt, 5-15ms render
# --- Modern Unix replacements ---
brew "eza" # better ls (colors, git status, icons)
brew "bat" # better cat (syntax highlighting)
brew "fd" # better find (smarter, 3x faster)
brew "ripgrep" # better grep (10x faster, respects .gitignore) — binary: rg
brew "fzf" # fuzzy finder (Ctrl+R history, Ctrl+T files)
brew "zoxide" # smart cd — `z proj` jumps to your most-used proj folder
# --- Git + dev TUI ---
brew "lazygit" # keyboard-driven git TUI
brew "gh" # GitHub CLI — create PRs, view issues from terminal
# --- Data processing ---
brew "jq" # JSON processor (essential for API work)
brew "yq" # YAML processor (Kubernetes/CI configs)
brew "tree" # print directory tree
# --- System monitoring ---
brew "htop" # process viewer
brew "btop" # pretty process viewer (colors, mouse)
brew "dust" # better du (visual disk usage tree)
brew "duf" # better df (color-coded free space)
# --- Dev utilities ---
brew "direnv" # auto-load .envrc per project folder
brew "tlrc" # tldr client (Rust port) — short "how do I X" examples
brew "gnupg" # provides gpg (signed git commits if you ever need them)
brew "mkcert" # local HTTPS certs for dev (cookies/CORS)
# --- Network / API ---
brew "mas" # Mac App Store CLI
brew "xh" # rust port of httpie — `xh GET api.example.com`
brew "doggo" # modern dig (DNS lookups)
brew "wget" # download with resume support
# --- Misc utilities ---
brew "watch" # repeat a command every N seconds
brew "imagemagick" # image processing (resize, convert)
brew "yt-dlp" # youtube/video downloader
brew "ncdu" # interactive disk usage (walk through what's eating space)
# --- Dev runtimes / managers ---
brew "mise" # polyglot version manager — node/python/rust/go in one tool
brew "uv" # python package + venv manager (Astral) — 10-100x faster than pip
brew "git" # newer than Xcode CLT git (2.54+ vs 2.39)
# --- Database / RAG dev (for Nitya AI work) ---
brew "libpq" # postgres client libs only (psql, pg_dump) — no local server
brew "pgcli" # prettier psql REPL with autocomplete
brew "redis" # local Redis (queues, cache) — optional, skip if not needed
# --- AI / Local LLMs (for Nitya RAG dev) ---
brew "ollama" # local LLM runtime, Anthropic-compatible /v1/messages endpoint
brew "ffmpeg" # audio/video converter (transitive Python AI deps need it)
# --- Cloud CLIs ---
brew "awscli" # AWS CLI v2
brew "doctl" # DigitalOcean CLI
# ============================================================
# GUI CASKS (apps in /Applications)
# ============================================================
# --- Terminal + editor ---
cask "ghostty" # GPU terminal (premium, Apple Silicon native)
cask "iterm2" # backup terminal (fallback if Ghostty breaks)
cask "cursor" # AI-native VS Code fork
# --- Browsers ---
cask "brave-browser" # primary — Chromium + native adblock + crypto wallet
cask "google-chrome" # backup — universal DevTools reference
cask "firefox" # cross-browser testing (non-Chromium engine)
# --- Window mgmt + launcher ---
cask "raycast" # launcher (replaces Spotlight + Alfred + clipboard managers)
cask "rectangle" # window snapping (Ctrl+Opt+arrows)
# --- Menubar / quality-of-life ---
cask "jordanbaird-ice" # menubar declutter (hide noisy icons)
cask "alt-tab" # Windows-style window switcher with previews
cask "stats" # menubar CPU/RAM/network monitor
# --- Notes + productivity ---
cask "obsidian" # markdown notes (local files, your second brain)
cask "notion" # team docs / Nitya workspace
cask "notion-calendar" # unified calendar (Google + iCloud + Notion events)
# --- Security ---
cask "1password" # password manager
cask "1password-cli" # `op` CLI for injecting secrets without plaintext .env
# --- Screenshots ---
cask "cleanshot" # premium screenshots + screen recording + OCR
cask "shottr" # free backup screenshot tool
# --- Media + files ---
cask "iina" # modern video player (replaces QuickTime + VLC)
cask "the-unarchiver" # opens .rar, .7z, .tar.xz (macOS native can't)
cask "appcleaner" # proper uninstaller (removes prefs + caches too)
# --- Dev GUIs ---
cask "tableplus" # database GUI (Postgres, MySQL, SQLite, Redis)
cask "orbstack" # fast Docker for Mac (10x lighter than Docker Desktop)
cask "postman" # API testing GUI (optional — xh covers most needs)
# --- Communications ---
cask "whatsapp" # WhatsApp Desktop (needs phone QR scan)
cask "telegram" # secondary messaging
cask "slack" # team chat
cask "zoom" # video meetings
cask "signal" # encrypted messaging (needs phone QR scan)
# --- Font (for Ghostty + Cursor to render correctly) ---
cask "font-jetbrains-mono-nerd-font" # JetBrainsMono with Nerd Font glyphs (icons in terminal)
#!/usr/bin/env bash
# ============================================================
# claude-skills-install.sh — Piyush's Claude Code stack
#
# When to use this: Phase 6 of the main gist usually handles this
# automatically (Claude pastes the same commands itself). Run this
# script ONLY if Phase 6 broke and you want to install manually.
#
# Usage:
# bash claude-skills-install.sh
#
# Prereqs (verify with `which`):
# - claude (Phase 0)
# - node/npm (Phase 0)
# - uv (Phase 4 — for Python-based MCPs: serena, time, fetch, git)
# - docker (Phase 5 — for postgres-mcp via Docker, optional)
# - GitHub PAT (https://github.com/settings/tokens → repo + read:org scopes)
#
# What this installs:
# - 3 plugin marketplaces (anthropics/claude-plugins-official is pre-loaded)
# - 2 first-party skills (superpowers, frontend-design)
# - 11 MCP servers (filesystem, github, context7, chrome-devtools, playwright,
# repomix, serena, firecrawl, brave-search, time, sequential-thinking)
# - Optional extras: postgres-mcp (Nitya RAG), notion, linear
# ============================================================
set -euo pipefail
C_BLUE='\033[0;34m'; C_GRAY='\033[0;90m'; C_RESET='\033[0m'
step() { echo -e "\n${C_BLUE}▶ $1${C_RESET}"; }
info() { echo -e " ${C_GRAY}· $1${C_RESET}"; }
# ============================================================
# Preflight
# ============================================================
step "Preflight — checking required tools"
command -v claude >/dev/null || { echo "❌ claude not found — install Claude Code first (Phase 0)"; exit 1; }
command -v npx >/dev/null || { echo "❌ npx not found — install node (Phase 0 or via mise)"; exit 1; }
command -v uvx >/dev/null || echo "⚠ uvx not found — Serena/time/fetch/git MCPs will skip. Run: brew install uv"
info "claude: $(claude --version 2>&1 | head -1)"
info "node: $(node --version)"
# ============================================================
# 1. Plugin marketplaces
# ============================================================
step "1. Adding plugin marketplaces"
info "anthropics/claude-plugins-official is pre-registered by Claude Code — skipping"
claude plugin marketplace add obra/superpowers-marketplace || info "already added"
claude plugin marketplace add shinpr/claude-code-workflows || info "already added"
claude plugin marketplace add Yeachan-Heo/oh-my-claudecode || info "already added"
# hesreallyhim/awesome-claude-code is a curated awesome-list, NOT a marketplace — browse on GitHub
# ============================================================
# 2. Skills / plugins
# ============================================================
step "2. Installing plugins / skills"
claude plugin install superpowers@claude-plugins-official || info "already installed"
claude plugin install frontend-design@claude-plugins-official || info "already installed"
# superpowers bundles: brainstorming, systematic-debugging, TDD, verification-before-completion
claude plugin install dev-workflows-fullstack@claude-code-workflows || info "already installed (optional)"
# ============================================================
# 3. MCP servers
# ============================================================
step "3. Installing MCP servers (essentials)"
# --- Filesystem (read/write outside Claude's default scope) ---
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem "$HOME/projects"
# --- GitHub (REMOTE — the npm one is archived) ---
# You'll be prompted for a PAT. Create one at github.com/settings/tokens (scopes: repo, read:org)
if [[ -n "${GITHUB_PAT:-}" ]]; then
claude mcp add-json github "{\"type\":\"http\",\"url\":\"https://api.githubcopilot.com/mcp\",\"headers\":{\"Authorization\":\"Bearer $GITHUB_PAT\"}}"
else
echo " ⚠ Skipping GitHub MCP — set GITHUB_PAT env var first, or add manually:"
echo " claude mcp add-json github '{\"type\":\"http\",\"url\":\"https://api.githubcopilot.com/mcp\",\"headers\":{\"Authorization\":\"Bearer YOUR_PAT\"}}'"
fi
# --- Context7 (live framework docs — kills hallucinated APIs) ---
# OAuth path is easier: run `npx ctx7 setup` interactively after this script
claude mcp add context7 -- npx -y @upstash/context7-mcp
# --- Chrome DevTools (debug RAG admin UIs, network inspection) ---
claude mcp add chrome-devtools -- npx -y chrome-devtools-mcp@latest
# --- Playwright (E2E tests, browser automation) ---
claude mcp add playwright -- npx -y @playwright/mcp@latest
# --- Repomix (pack codebase to single XML for whole-repo analysis) ---
claude mcp add repomix -- npx -y repomix --mcp
# --- Serena (semantic code search via LSP — better than grep for refactors) ---
if command -v uv >/dev/null; then
uv tool install -p 3.13 serena-agent || true
claude mcp add serena -- serena start-mcp-server
else
echo " ⚠ Skipping Serena — install uv first: brew install uv"
fi
# --- Firecrawl (web scraping for RAG ingestion) ---
if [[ -n "${FIRECRAWL_API_KEY:-}" ]]; then
FIRECRAWL_API_KEY="$FIRECRAWL_API_KEY" claude mcp add firecrawl -- npx -y firecrawl-mcp
else
echo " ⚠ Skipping Firecrawl — get key at firecrawl.dev, then re-run with FIRECRAWL_API_KEY=fc-..."
fi
# --- Brave Search (web search inside Claude) ---
if [[ -n "${BRAVE_API_KEY:-}" ]]; then
BRAVE_API_KEY="$BRAVE_API_KEY" claude mcp add brave-search -- npx -y @brave/brave-search-mcp-server --transport stdio
else
echo " ⚠ Skipping Brave Search — get key at brave.com/search/api, then re-run with BRAVE_API_KEY=..."
fi
# --- Time (timezone-correct timestamps) ---
if command -v uvx >/dev/null; then
claude mcp add time -- uvx mcp-server-time
fi
# --- Sequential thinking (structured reasoning chains) ---
claude mcp add sequential-thinking -- npx -y @modelcontextprotocol/server-sequential-thinking
# ============================================================
# 4. OPTIONAL — Nitya stack additions
# ============================================================
step "4. Optional Nitya stack add-ons"
# --- Postgres MCP (read-only SQL against Nitya's pgvector DB, via Docker) ---
# Uncomment + set DATABASE_URI to enable:
# claude mcp add postgres -e DATABASE_URI=postgresql://USER:PASS@HOST:5432/DB -- docker run -i --rm -e DATABASE_URI crystaldba/postgres-mcp --access-mode=restricted
# --- Fetch (lightweight HTTP without Firecrawl quota) ---
if command -v uvx >/dev/null; then
claude mcp add fetch -- uvx mcp-server-fetch
fi
# --- Git (local repo introspection) ---
# claude mcp add git -- uvx mcp-server-git --repository "$HOME/projects/nitya-capital"
# --- Linear (only if Nitya uses Linear) ---
# claude mcp add --transport http linear https://mcp.linear.app/mcp
# Then run: /mcp inside Claude to complete OAuth
# --- Notion (only if Nitya docs live in Notion) ---
# claude mcp add --transport http notion https://mcp.notion.com/mcp
# Then run: /mcp inside Claude to complete OAuth
# --- Supabase (only if Nitya uses Supabase) ---
# claude mcp add-json supabase '{"type":"http","url":"https://mcp.supabase.com/mcp"}'
# ============================================================
# Summary
# ============================================================
step "Done."
info "Verify with: claude mcp list"
info "If any MCP shows red, restart Claude Code: quit and re-run \`claude\`"
info "OAuth-style MCPs (linear, notion, supabase) need /mcp inside Claude to authenticate"

Piyush — Mac setup via Claude Code (May 2026)

Tip

The whole idea: install Claude Code first (~10 min, you do it). Then copy 8 prompts from this gist, one at a time, into Claude. Claude installs everything else for you. Total time: ~30 min of you doing things + ~60 min of Claude working in the background.


How this works

Old way: copy 50 commands into your terminal, one by one, hoping you don't fat-finger a rm -rf.

This way:

  1. You do Phase 0 yourself (5 commands, all explained).
  2. Then for each of Phases 1-8 you:
    • Read the "What this does" line so you know what's happening.
    • Copy the prompt block.
    • Paste it into Claude.
    • Sit back. Claude will pause if it needs you to click something or sign into something — it tells you exactly what to do.
    • When you see ✅ PHASE N DONE in Claude's output, type /clear in Claude and paste the next phase.

Files in this gist:

  • piyush-mac-setup.md — this walkthrough (the file you're reading)
  • Brewfile — list of apps + CLI tools to install (Claude downloads this in Phase 4 / 5)
  • claude-skills-install.sh — backup script for Phase 6 if Claude struggles
  • verify.sh — final health-check script

⚠️ Read this before starting

Claude will sometimes stop and ask you to do something manually. This is normal — there are things Claude can't do on a Mac:

  • Click a button in System Settings (Apple security — no AI can click those)
  • Scan a QR code with your phone (WhatsApp, Signal)
  • Enter a license key or sign into an app
  • Approve a browser OAuth flow

When Claude stops, you'll see a banner like this:

🛑 ============== ACTION REQUIRED ==============
What to do:    Open System Settings → Privacy → Accessibility
               Enable Raycast. Enter your password.
When done:     Reply "done"
============================================

Just do what it says, then type done (or skip) in Claude. Claude continues from there.

Expect ~16 of these stops across all 8 phases. Most are 10 seconds each. Total interactive time: ~30 min.


Phase 0 — Manual bootstrap (you do this, no Claude yet)

Important

What this does: Installs Apple's developer tools (git, compiler), Homebrew (the Mac package manager), Node.js, and Claude Code itself. Why manual: Claude doesn't exist on your machine yet — you have to install it first. ~15 min total.

0a. Sign into Apple ID + iCloud (2 min)

  • System Settings → Apple Account → sign in with your Apple ID
  • This is needed so the App Store works (later, Claude installs apps via mas, the Mac App Store CLI — that requires you to be signed in first).
  • Leave iCloud Drive Documents & Desktop sync OFF — syncs your entire home folder to iCloud, slows everything down.

0b. Xcode Command Line Tools (10 min, mostly waiting)

Open Terminal.app (Spotlight → "Terminal") and paste:

xcode-select --install

A popup appears. Click Install → accept the license → wait. Downloads about 2 GB. This installs git, the C compiler, and Python headers. Without it, nothing else works.

When done, verify:

git --version
# Should print something like: git version 2.39.x

0c. Homebrew (2 min)

Paste into Terminal:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

It'll ask for your Mac login password (the one you use to log into your Mac, NOT your Apple ID). Type it (you won't see the characters as you type — that's normal). Press Enter.

At the end, Homebrew prints 2 lines that look like this — copy and paste them into Terminal:

echo >> ~/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Verify:

brew --version
which brew
# MUST output: /opt/homebrew/bin/brew

Warning

If which brew shows /usr/local/bin/brew, that's wrong (the Intel Mac path). Re-run the installer.

0d. Node.js + Claude Code (2 min)

brew install node
npm install -g @anthropic-ai/claude-code

0e. First Claude run + OAuth + Keychain "Always Allow" (3 min)

claude

A browser opens. Sign into your Anthropic account (Pro or Max plan — free tier won't get you Opus model access).

When you come back to the terminal, macOS will show a Keychain dialog:

"claude wants to access key in your keychain"

Click "Always Allow" (NOT just "Allow" — Always Allow means Claude won't pester you on every command). If you click the wrong one, every Claude operation will trigger another popup.

Type /exit to quit Claude for now.

0f. Done with manual setup — switch to Claude-driven from here

Open Claude again:

claude

You're ready to paste Phase 1 below.


Phase 1 — Install a beautiful terminal (Ghostty) + premium config

Important

What this does: Installs Ghostty (a modern terminal that looks gorgeous on macOS Tahoe — frosted glass, smooth ligatures, JetBrains Mono font). Also installs notification hooks so Claude makes a sound when it needs you. ~5 min. You'll do: Open Ghostty once after install, click "Allow" if macOS asks for notification permission. Success looks like: A new terminal window with a transparent frosted-glass background, the prompt rendering with crisp ligatures (e.g. == and => look like single elegant characters).

Copy ↓, paste into Claude:

You are helping Piyush, a junior-mid Mac developer at Nitya Capital, set up his brand-new MacBook (macOS 26 Tahoe, May 2026). He just finished Phase 0 (Homebrew + Node + Claude Code installed, Apple ID signed in). Now do Phase 1: install Ghostty terminal, configure it premium-style, and wire notification sounds.

BEFORE YOU START
1. Register every step below as a todo via your task-tracking tool. Mark in_progress before each, completed after.
2. Run a preflight check — `which brew` must return `/opt/homebrew/bin/brew`. If it doesn't, STOP and tell Piyush: "Phase 0 wasn't completed correctly — re-run `eval \"$(/opt/homebrew/bin/brew shellenv)\"` and try again."

STOP RULES
- If macOS will show a sudo password prompt, GUI dialog, or browser OAuth → print a 🛑 ACTION REQUIRED banner and wait for Piyush to type "done" (or "skip").
- Banner format:
  🛑 =========== ACTION REQUIRED ===========
  What:  <one sentence>
  Where: <exact menu path or app name>
  Then:  reply "done"
  =======================================
- Do NOT try to bypass these — Piyush is sitting at the keyboard, this is fine.

STEPS

1. Install Ghostty and the JetBrains Mono Nerd Font:
   ```
   brew install --cask ghostty font-jetbrains-mono-nerd-font
   ```
   This may take 1-2 min and ask for Piyush's Mac password (Gatekeeper). Print the STOP banner if so.

2. Write the premium Ghostty config to `~/.config/ghostty/config`:
   ```bash
   mkdir -p ~/.config/ghostty && cat > ~/.config/ghostty/config <<'EOF'
   # ~/.config/ghostty/config — premium glass setup for macOS 26 Tahoe

   theme = Catppuccin Macchiato

   font-family = JetBrainsMono Nerd Font
   font-size = 14
   font-feature = +liga
   font-feature = +calt
   font-feature = +ss01
   font-feature = +ss02
   font-thicken = true

   background-opacity = 0.92
   background-blur = macos-glass-regular
   window-colorspace = display-p3

   macos-titlebar-style = transparent
   macos-titlebar-proxy-icon = visible
   macos-window-shadow = true
   macos-option-as-alt = left
   macos-icon = official

   window-padding-x = 14
   window-padding-y = 12
   window-padding-balance = true
   window-save-state = always

   cursor-style = bar
   cursor-style-blink = true

   mouse-hide-while-typing = true
   confirm-close-surface = false
   quit-after-last-window-closed = true

   copy-on-select = clipboard
   shell-integration = detect
   shell-integration-features = cursor,sudo,title
   EOF
   ```

3. Set up Claude Code notification hooks so Piyush hears a sound when a phase finishes or Claude needs his input. Write/merge into `~/.claude/settings.json`:
   ```json
   {
     "hooks": {
       "Notification": [{
         "hooks": [{
           "type": "command",
           "command": "osascript -e 'display notification \"Claude needs you\" with title \"Claude Code\" sound name \"Glass\"'"
         }]
       }],
       "Stop": [{
         "hooks": [{
           "type": "command",
           "command": "afplay /System/Library/Sounds/Hero.aiff"
         }]
       }]
     }
   }
   ```
   If `~/.claude/settings.json` already has content, MERGE (don't clobber) — read the existing JSON first, add the `hooks` key, write back.

4. STOP banner — tell Piyush:
   🛑 OPEN GHOSTTY NOW
   What:  Cmd+Space → type "Ghostty" → Enter. If macOS shows "Ghostty is from the internet" → click Open.
          If it asks about Notifications → click Allow.
   Then:  Reply "done" — I'll continue.

5. After Piyush replies "done", verify by checking:
   - `[[ -f ~/.config/ghostty/config ]]` → true
   - `[[ -f ~/.claude/settings.json ]]` → true
   - Ghostty process running: `pgrep -x Ghostty`

6. Print:
   ========================================
   ✅ PHASE 1 DONE — Ghostty + premium config + notification hooks
   Proof:
     - Ghostty installed, config at ~/.config/ghostty/config
     - JetBrains Mono Nerd Font in ~/Library/Fonts/
     - Notification hooks in ~/.claude/settings.json
   Next: type /clear in Claude, then paste Phase 2 from the gist.
        Optional: switch to Ghostty (Cmd+Tab) and run `claude` there — better experience.
   ========================================

Phase 2 — Smart shell (oh-my-zsh + Starship + plugins)

Important

What this does: Makes your terminal much smarter. Auto-suggests commands you've typed before (press → to accept). Colors valid commands green and typos red BEFORE you press Enter. Adds a beautiful prompt with your current folder, git branch, and language version. ~3 min. You'll do: Nothing — fully automatic. (You might be asked your name/email for git in Phase 3, not here.) Success looks like: Your prompt shows ~/projects ❯ with an icon, and faded ghost text appears as you type recalled commands.

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. He finished Phase 1 (Ghostty installed). Now do Phase 2: install oh-my-zsh, Starship, and zsh plugins for a smart, modern shell.

BEFORE YOU START
1. Register every step below as a todo via your task-tracking tool.
2. Preflight: `which brew` returns /opt/homebrew/bin/brew. If not, STOP and tell Piyush Phase 0 broke.

CRITICAL GOTCHA — oh-my-zsh installer
The vanilla installer:
  (a) prompts to change shell (asks for password — would hang you), AND
  (b) launches a new zsh subshell (would halt your bash session), AND
  (c) backs up any existing ~/.zshrc and writes its own.
Use these env vars to fix ALL THREE: `RUNZSH=no CHSH=no KEEP_ZSHRC=no`
- KEEP_ZSHRC=no LETS oh-my-zsh write its template ON A FRESH MAC (Piyush has no existing .zshrc). This is what we want — Phase 3 will append to OMZ's template, not the other way around.

STEPS

1. Install oh-my-zsh, NON-INTERACTIVELY (this is the only way it works in a Claude subprocess):
   ```bash
   RUNZSH=no CHSH=no sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
   ```

2. Install Starship (the prompt) via brew:
   ```bash
   brew install starship
   ```

3. Clone the two zsh plugins into oh-my-zsh's custom directory:
   ```bash
   git clone https://github.com/zsh-users/zsh-autosuggestions \
     ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
   git clone https://github.com/zsh-users/zsh-syntax-highlighting \
     ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
   ```

4. Edit `~/.zshrc` to:
   (a) enable the plugins (change the `plugins=(git)` line to `plugins=(git zsh-autosuggestions zsh-syntax-highlighting)`)
   (b) APPEND a starship init line at the end of the file
   ```
   eval "$(starship init zsh)"
   ```

5. Write a Starship config to `~/.config/starship.toml` — keep it simple and premium (NO neon, NO emoji-spam, just clean info):
   ```toml
   "$schema" = "https://starship.rs/config-schema.json"

   format = """
   $directory\
   $git_branch\
   $git_status\
   $nodejs\
   $python\
   $cmd_duration\
   $line_break$character"""

   [character]
   success_symbol = "[❯](bold cyan)"
   error_symbol = "[❯](bold red)"

   [directory]
   style = "bold cyan"
   truncation_length = 3
   truncate_to_repo = true

   [git_branch]
   symbol = " "
   style = "bold magenta"

   [git_status]
   style = "bold magenta"

   [cmd_duration]
   min_time = 500
   format = "[took $duration]($style) "
   style = "yellow"
   ```

6. Verify the shell config sources cleanly:
   ```bash
   zsh -i -c 'echo SHELL_OK; type starship'
   ```
   Expected output contains `SHELL_OK` and `starship is /opt/homebrew/bin/starship`.

7. Print:
   ========================================
   ✅ PHASE 2 DONE — oh-my-zsh + Starship + autosuggest + syntax highlighting
   Proof:
     - `~/.oh-my-zsh/` exists
     - `which starship` → /opt/homebrew/bin/starship
     - `~/.config/starship.toml` written
     - plugins line in ~/.zshrc includes zsh-autosuggestions + zsh-syntax-highlighting
   Next: open a NEW Ghostty tab (Cmd+T) to see the new prompt. Then /clear and paste Phase 3.
   ========================================

Phase 3 — Dev runtimes + GitHub auth + SSH key

Important

What this does: Installs version managers for Node and Python (mise, uv) so you can have different versions per project. Configures git with your name/email. Generates an SSH key and uploads it to GitHub so you can git push without typing passwords. ~5 min. You'll do: (1) Tell Claude your name + GitHub email when it asks. (2) Open a browser and approve GitHub when prompted (2x — once for login, once for the SSH-key-upload permission). Success looks like: ssh -T git@github.com says "Hi piyush! You've successfully authenticated."

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. Phase 2 done (smart shell installed). Now do Phase 3: install Node/Python version managers, configure git, generate SSH key, and authenticate to GitHub.

BEFORE YOU START
1. Register every step below as todos.
2. Preflight: `which brew`, `which zsh`, `[[ -d ~/.oh-my-zsh ]]`. If any fails, STOP.

STOP RULES (this phase has TWO mandatory stops)
- When `gh auth login` runs it will print an 8-character code and open a browser. Stop and tell Piyush:
  🛑 GITHUB LOGIN
  What:  Copy the 8-char code from terminal (looks like ABCD-1234).
         Browser opens to github.com/login/device — paste the code, click Authorize.
  Then:  Reply "done"
- After login, you need a 2nd browser flow to add the `admin:public_key` scope (needed to upload SSH keys).
- If you need git identity info (name + email), use AskUserQuestion with sensible defaults.

STEPS

1. Install mise (polyglot version manager), uv (Python tooling), and a fresh git:
   ```bash
   brew install mise uv git
   ```

2. Wire mise into the shell — add to BOTH files:
   - `~/.zprofile` (login shells, non-interactive):  `eval "$(mise activate zsh --shims)"`
   - `~/.zshrc` (interactive shells):  `eval "$(mise activate zsh)"`
   Use `cat >> file` with a heredoc. Do NOT duplicate if the line already exists.

3. Install the dev runtimes globally:
   ```bash
   mise use --global node@lts python@3.13
   ```
   This may take 2-3 min (Python builds from source on M-series). Use run_in_background and Monitor.

4. Ask Piyush for git identity via AskUserQuestion. Two questions, one screen if possible:
   - "What name should appear on git commits?" (offer "Piyush <LastName>" as the suggestion shape)
   - "What email is tied to your GitHub account?" (gmail / company email)
   Then:
   ```bash
   git config --global user.name "<answer 1>"
   git config --global user.email "<answer 2>"
   git config --global init.defaultBranch main
   git config --global pull.rebase false
   ```

5. Generate an SSH key (only if it doesn't already exist — `test -f ~/.ssh/id_ed25519`):
   ```bash
   ssh-keygen -t ed25519 -C "<piyush's email>" -N "" -f ~/.ssh/id_ed25519
   ```

6. STOP for GitHub login:
   🛑 banner as above. Run:
   ```bash
   gh auth login --hostname github.com --git-protocol ssh --web
   ```
   When the 8-char code prints, include it IN the banner so Piyush can copy it. Wait for "done".

7. Add the SSH-key-upload scope (another browser flow):
   🛑 banner again. Run:
   ```bash
   gh auth refresh -h github.com -s admin:public_key
   ```
   Wait for "done".

8. Upload the SSH key to GitHub:
   ```bash
   gh ssh-key add ~/.ssh/id_ed25519.pub --title "$(scutil --get ComputerName)"
   ```

9. Verify GitHub SSH auth (use accept-new to skip the host-key prompt):
   ```bash
   ssh -o StrictHostKeyChecking=accept-new -T git@github.com
   ```
   Expected: "Hi <piyush-github-username>! You've successfully authenticated..."

10. Print:
    ========================================
    ✅ PHASE 3 DONE — Node + Python + git config + GitHub SSH auth
    Proof:
      - `mise current` shows node + python
      - `git config user.email` returns Piyush's email
      - `ssh -T git@github.com` says "Hi <username>!"
      - ~/.ssh/id_ed25519 exists, uploaded to GitHub
    Next: /clear, paste Phase 4.
    ========================================

Phase 4 — Install all the modern CLI tools (Brewfile, formulae only)

Important

What this does: Installs ~30 better command-line tools — eza (prettier ls), bat (prettier cat), ripgrep (10× faster grep), lazygit (visual git), jq (JSON), and many more. Each one replaces a clunky default and saves you time daily. ~10 min download. You'll do: Nothing — automatic. (Long install, you can walk away.) Success looks like: eza -la shows your home folder with colors + icons + git status per file.

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. Phase 3 done (runtimes + GitHub auth). Now do Phase 4: install ~30 modern CLI tools via a Brewfile.

BEFORE YOU START
1. Register todos.
2. Preflight: `which brew`, `gh auth status` (should be authed). STOP if either fails.

THIS PHASE HAS NO STOPS — it's a long-running brew bundle. Run it in the background and Monitor.

STEPS

1. Download Piyush's Brewfile from this gist into the current directory:
   ```bash
   curl -sSL https://gist.githubusercontent.com/Aboudjem/da6b37f5d58a9e8b1b238e11a860d3d3/raw/Brewfile -o /tmp/Brewfile-piyush
   ```
   If curl fails, the Brewfile is also visible in the gist UI — Piyush can save it manually. STOP and ask.

2. Split the Brewfile into two passes (formulae now, casks in Phase 5 — casks need sudo, separate handling):
   ```bash
   grep -E '^(brew|tap) ' /tmp/Brewfile-piyush > /tmp/Brewfile-cli
   ```

3. Pre-cache sudo so brew doesn't hang on any sudo-needing formula (rare but defensive):
   🛑 banner:
   What:  Run `sudo -v` in your terminal NOW (not in Claude). Type your Mac password.
          This pre-caches your password for the next 5 min so the brew install runs silently.
   Then:  Reply "done"

4. Install formulae in the background:
   ```bash
   brew bundle install --file=/tmp/Brewfile-cli --verbose 2>&1 | tee /tmp/brew-cli.log
   ```
   Use run_in_background. Monitor the log for completion ("Homebrew Bundle complete").

5. Activate fzf keybindings (Ctrl+R history search, Ctrl+T find file, Alt+C jump to dir):
   ```bash
   $(brew --prefix)/opt/fzf/install --all --no-bash
   ```
   `--all` says yes to all 3 prompts (autocompletion, keybindings, shell config). `--no-bash` skips bash.

6. Append the runtime hooks for zoxide and fzf to `~/.zshrc` (only if not already there — grep first):
   ```bash
   eval "$(zoxide init zsh)"
   [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
   ```
   Also append modern-CLI aliases (use eza for ls, bat for cat, etc):
   ```bash
   alias ls='eza --icons --git'
   alias ll='eza -la --icons --git'
   alias lt='eza --tree --level=2 --icons'
   alias cat='bat --paging=never'
   alias grep='rg'
   alias find='fd'
   alias top='btop'
   alias g='git'
   alias lg='lazygit'
   ```

7. Source ~/.zshrc and verify each tool exists:
   ```bash
   zsh -i -c 'for c in eza bat fd rg fzf zoxide lazygit gh jq mise uv ollama; do command -v $c >/dev/null && echo "✓ $c" || echo "✗ $c MISSING"; done'
   ```
   Every tool should show ✓.

8. Print:
   ========================================
   ✅ PHASE 4 DONE — modern CLI stack installed
   Proof:
     - `brew list --formula | wc -l` >= 33
     - `eza --version` works
     - `zsh -i -c 'type rg'` returns the ripgrep path
   Next: /clear, paste Phase 5. (Phase 5 is the BIG one — many GUI apps + manual sign-ins.)
   ========================================

Phase 5 — Install all GUI apps (Brewfile, casks)

Important

What this does: Installs ~28 GUI apps: Cursor (your code editor), Brave/Chrome/Firefox (browsers), Raycast (launcher — replaces Spotlight), Rectangle (window snapping), 1Password, Notion, Slack, etc. ~25 min download + a LOT of permission popups. You'll do: Type your Mac password a few times when popups appear. Then after install, open each app once and grant Accessibility / Screen Recording perms (Claude prints an exact checklist). Phone-paired apps (WhatsApp, Signal, Telegram) need a QR scan from your phone — defer those to the end. Success looks like: All apps appear in Launchpad. Raycast, Rectangle, 1Password ready to sign in.

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. Phase 4 done (CLI tools installed). Now do Phase 5: install ~28 GUI apps via Brewfile casks, then walk Piyush through the necessary permission grants.

BEFORE YOU START
1. Register todos.
2. Preflight: `which brew`. STOP if missing.

THIS IS THE HARDEST PHASE. Expect ~8 STOP banners:
  - sudo password warmup
  - Cursor "Install 'cursor' command in PATH" GUI click
  - Raycast Accessibility + onboarding wizard
  - Rectangle Accessibility
  - AltTab Accessibility + Screen Recording
  - CleanShot Screen Recording (+ license key)
  - 1Password sign-in + Settings → Developer → Integrate CLI + Touch ID
  - OrbStack first-launch admin prompt
  - (Phone-app QR scans — defer to a final checklist, don't block here)

KNOWN BREAKAGE
  - `jordanbaird-ice` cask is BROKEN on macOS Tahoe stable (Ice Bar invisible). Install it, mention it, tell Piyush to either skip or grab beta 0.11.13+ from GitHub releases manually.
  - `notion-calendar` requires a Google account — call this out, don't try to auth without one.

STEPS

1. Extract cask lines from the Brewfile:
   ```bash
   grep -E '^cask ' /tmp/Brewfile-piyush > /tmp/Brewfile-casks
   ```

2. Pre-cache sudo (some casks invoke sudo for /Applications writes):
   🛑 banner — "Run `sudo -v` in your terminal now, password please, reply done"

3. Install casks in the background (15-25 min):
   ```bash
   NONINTERACTIVE=1 HOMEBREW_NO_AUTO_UPDATE=1 \
     brew bundle install --file=/tmp/Brewfile-casks --verbose 2>&1 | tee /tmp/brew-casks.log
   ```
   Use run_in_background + Monitor. If macOS pops a sudo dialog mid-stream, STOP and tell Piyush.

4. After install completes, print this consolidated checklist as a STOP banner — Piyush will work through it:

   🛑 ===== OPEN EACH APP ONCE + GRANT PERMS =====
   Do these IN ORDER. Reply "done" when finished (about 15 min of clicking).

   A. Open Cursor → Cmd+Shift+P → type "Shell Command" → pick "Install 'cursor' command in PATH" → enter password.

   B. Open Raycast (Launchpad → Raycast) → walk through onboarding → grant Accessibility when asked
      → in Raycast Settings → General → set Hotkey to Cmd+Space
      → System Settings → Keyboard → Keyboard Shortcuts → Spotlight → uncheck Cmd+Space (so they don't fight)

   C. Open Rectangle (Launchpad) → click "Open System Settings" on the prompt → enable Rectangle under Privacy → Accessibility.

   D. Open AltTab → grant Accessibility + Screen Recording (two separate System Settings toggles).

   E. Open CleanShot X → grant Screen Recording + Accessibility. If you have a license, paste it. Otherwise skip CleanShot, use Shottr (free).

   F. Open 1Password → sign in to your existing account (or create one at 1password.com first)
      → Settings → Developer → check "Integrate with 1Password CLI" and "Touch ID" (so `op` CLI works)

   G. Open OrbStack → enter your password on the Docker compatibility prompt → choose "Docker" mode.

   H. Open Ice (`jordanbaird-ice`) — KNOWN BROKEN on Tahoe stable. Either skip, or download beta 0.11.13+ from github.com/jordanbaird/Ice/releases and install manually.

   Phone-paired apps (you'll do at the very end, NOT now):
     - WhatsApp / Signal / Telegram all need QR scans from your phone. Defer to Phase 8's final checklist.

   Reply "done" when you've finished A-H. Skip anything you don't need.
   ============================================

5. After Piyush replies "done", verify the cask install:
   ```bash
   brew list --cask | wc -l   # should be >= 28
   ```

6. Print:
   ========================================
   ✅ PHASE 5 DONE — GUI apps installed, base perms granted
   Proof:
     - 28+ casks listed in `brew list --cask`
     - cursor CLI works: `which cursor`
     - 1Password CLI works: `op account list` returns your account
   Pending (final checklist in Phase 8): phone-app QR scans, optional license keys.
   Next: /clear, paste Phase 6.
   ========================================

Phase 6 — Claude Code skills, plugins, MCPs

Important

What this does: Wires Claude Code up with the best skills/plugins/MCPs for an AI/RAG developer: live docs lookup (Context7), web scraping (Firecrawl), Postgres queries, browser automation (Playwright), semantic code search (Serena), and more. Makes Claude much more powerful inside your projects. ~10 min. You'll do: Generate a GitHub Personal Access Token at github.com/settings/tokens (Claude will tell you exactly what scopes to pick) + paste API keys for Firecrawl and Brave Search if you have them (both have free tiers — sign-up links provided). Success looks like: claude mcp list shows 10+ servers connected (green ✓). Inside Claude, /mcp shows all servers ready.

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. Phase 5 done. Now do Phase 6: install Claude Code marketplaces, skills, and MCP servers.

BEFORE YOU START
1. Register todos.
2. Preflight: `which claude`, `which npx`, `which uvx` (skip Serena/time/fetch if uvx missing — but `brew install uv` should've handled it). STOP only if `claude` is missing.

THIS PHASE HAS 1-3 STOPS (API key prompts).

KEY FACTS (May 2026)
- `anthropics/claude-plugins-official` is PRE-REGISTERED — do NOT try to `marketplace add` it.
- `@modelcontextprotocol/server-github` is ARCHIVED — use GitHub's remote MCP with a PAT.
- `@modelcontextprotocol/server-brave-search` is ARCHIVED — use `@brave/brave-search-mcp-server`.
- Serena CANNOT be added via marketplace — must be `uv tool install` first.

STEPS

1. Add 2 useful marketplaces (skip if already added):
   ```bash
   claude plugin marketplace add obra/superpowers-marketplace 2>/dev/null || true
   claude plugin marketplace add shinpr/claude-code-workflows 2>/dev/null || true
   ```

2. Install first-party skills:
   ```bash
   claude plugin install superpowers@claude-plugins-official
   claude plugin install frontend-design@claude-plugins-official
   ```
   superpowers bundles brainstorming + systematic-debugging + TDD + verification-before-completion automatically.

3. Install MCP servers — start with the ones that need NO API key:
   ```bash
   claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem "$HOME/projects"
   claude mcp add context7 -- npx -y @upstash/context7-mcp
   claude mcp add chrome-devtools -- npx -y chrome-devtools-mcp@latest
   claude mcp add playwright -- npx -y @playwright/mcp@latest
   claude mcp add repomix -- npx -y repomix --mcp
   claude mcp add sequential-thinking -- npx -y @modelcontextprotocol/server-sequential-thinking
   ```

4. Install Serena (semantic code search — needs uv):
   ```bash
   uv tool install -p 3.13 serena-agent
   claude mcp add serena -- serena start-mcp-server
   ```

5. Install time + fetch + git MCPs (also via uvx):
   ```bash
   claude mcp add time -- uvx mcp-server-time
   claude mcp add fetch -- uvx mcp-server-fetch
   ```

6. GitHub MCP (needs a PAT) — STOP and ask:
   🛑 GITHUB TOKEN
   What:  Open github.com/settings/tokens → Generate new token (classic)
          Note: "claude-code-mcp"  | Scopes: check `repo` + `read:org` + `workflow`
          Generate → copy the token (ghp_...).
   Then:  Reply with the token (just paste it in chat).
   
   Then run:
   ```bash
   claude mcp add-json github "{\"type\":\"http\",\"url\":\"https://api.githubcopilot.com/mcp\",\"headers\":{\"Authorization\":\"Bearer <token>\"}}"
   ```

7. Firecrawl (optional but useful for RAG ingestion) — STOP and ask:
   🛑 FIRECRAWL KEY (optional, skip if not interested)
   What:  Go to firecrawl.dev → sign up → copy your API key (starts with fc-)
          Free tier: 500 scrapes/month — enough for trying.
   Then:  Paste key, or reply "skip".
   
   ```bash
   FIRECRAWL_API_KEY=fc-... claude mcp add firecrawl -- npx -y firecrawl-mcp
   ```

8. Brave Search MCP (optional) — STOP and ask:
   🛑 BRAVE SEARCH KEY (optional, skip if not interested)
   What:  Go to brave.com/search/api → free tier 2000 queries/month
   Then:  Paste key, or "skip".
   
   ```bash
   BRAVE_API_KEY=... claude mcp add brave-search -- npx -y @brave/brave-search-mcp-server --transport stdio
   ```

9. Verify everything:
   ```bash
   claude mcp list
   ```
   Should show 8-11 servers, status green ✓. Red ✗ means restart Claude (Cmd+Q, re-run `claude`).

10. Tell Piyush about optional Nitya add-ons (don't install — just inform):
    "If Nitya uses these tools, add the matching MCP later:
      - Linear:    claude mcp add --transport http linear https://mcp.linear.app/mcp
      - Notion:    claude mcp add --transport http notion https://mcp.notion.com/mcp
      - Supabase:  claude mcp add-json supabase '{\"type\":\"http\",\"url\":\"https://mcp.supabase.com/mcp\"}'
      - Postgres:  see claude-skills-install.sh in the gist for the Docker command
     Each requires `/mcp` in Claude to complete OAuth."

11. Print:
    ========================================
    ✅ PHASE 6 DONE — Claude Code MCPs + skills wired
    Proof:
      - `claude mcp list` shows 8-11 servers (most green ✓)
      - `claude plugin list` shows superpowers, frontend-design
    Next: /clear, paste Phase 7.
    ========================================

Phase 7 — macOS quality-of-life defaults + Cursor extensions

Important

What this does: Flips a bunch of macOS settings that every developer wants (faster key repeat, show hidden files, kill smart-quotes that break code paste, screenshots-to-folder, hide the Dock instantly). Then installs your Cursor extensions for Python and TypeScript. ~3 min. You'll do: Log out + log back in once at the end (needed to apply the key repeat change). Success looks like: Holding j fills the screen with js in under a second (vs slow keyboard before).

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. Phase 6 done. Now do Phase 7: apply developer-friendly macOS defaults + install Cursor extensions.

BEFORE YOU START
1. Register todos.
2. No preflights needed — these are independent of prior phases.

NO STOPS in this phase. End by telling Piyush to log out / log in.

STEPS

1. Apply macOS defaults (these write directly to plists — no clicks needed):
   ```bash
   # Finder: show hidden files + full path in title
   defaults write com.apple.finder AppleShowAllFiles -bool true
   defaults write com.apple.finder _FXShowPosixPathInTitle -bool true
   defaults write com.apple.finder ShowPathbar -bool true
   defaults write com.apple.finder ShowStatusBar -bool true

   # Faster key repeat (game-changer for coding)
   defaults write -g KeyRepeat -int 2
   defaults write -g InitialKeyRepeat -int 15

   # Kill smart quotes / dashes / spelling correction (they break code paste)
   defaults write -g NSAutomaticDashSubstitutionEnabled -bool false
   defaults write -g NSAutomaticQuoteSubstitutionEnabled -bool false
   defaults write -g NSAutomaticSpellingCorrectionEnabled -bool false

   # Dock: auto-hide instantly, no recent apps
   defaults write com.apple.dock autohide -bool true
   defaults write com.apple.dock autohide-delay -float 0
   defaults write com.apple.dock autohide-time-modifier -float 0.3
   defaults write com.apple.dock show-recents -bool false

   # Screenshots go to a dedicated folder (cleaner Desktop)
   mkdir -p ~/Pictures/Screenshots
   defaults write com.apple.screencapture location ~/Pictures/Screenshots

   # Apply changes
   killall Finder Dock SystemUIServer
   ```

2. Install useful Cursor extensions (if `cursor` CLI was installed in Phase 5):
   ```bash
   if command -v cursor >/dev/null; then
     cursor --install-extension ms-python.python
     cursor --install-extension ms-python.vscode-pylance
     cursor --install-extension dbaeumer.vscode-eslint
     cursor --install-extension esbenp.prettier-vscode
     cursor --install-extension bradlc.vscode-tailwindcss
     cursor --install-extension ms-azuretools.vscode-docker
     cursor --install-extension eamodio.gitlens
   fi
   ```

3. Create a tidy project structure (purely optional — Piyush may already have his own):
   ```bash
   mkdir -p ~/projects ~/Pictures/Screenshots
   ```

4. STOP banner — final manual step for this phase:
   🛑 LOG OUT + LOG IN ONCE
   What:  The faster key repeat won't kick in until you log out + back in.
          Apple Menu → Log Out — then log back in.
   Then:  Open a new Ghostty tab and try holding a key. Should be MUCH faster.
          Reply "done"

5. Print:
   ========================================
   ✅ PHASE 7 DONE — macOS defaults + Cursor extensions
   Proof:
     - `defaults read -g KeyRepeat` = 2
     - `defaults read com.apple.finder AppleShowAllFiles` = 1
     - ~/Pictures/Screenshots exists
     - cursor extensions installed (run `cursor --list-extensions` to see)
   Next: /clear, paste Phase 8 (the verify-and-finish phase).
   ========================================

Phase 8 — Verify everything + final manual checklist

Important

What this does: Runs a health check across the whole install (verify.sh) and prints a final checklist of "stuff only you can do" — phone QR scans for messaging apps, sign-ins for cloud services, optional license keys. ~5 min. You'll do: Work through the printed checklist on your own time. Success looks like: verify.sh exits with "✅ All required items installed" and you have a clear todo list for the rest.

Copy ↓, paste into Claude:

You are helping Piyush set up his Mac. Phases 0-7 done. Now do Phase 8: run the verify script and print the final manual checklist.

STEPS

1. Download verify.sh from the gist:
   ```bash
   curl -sSL https://gist.githubusercontent.com/Aboudjem/da6b37f5d58a9e8b1b238e11a860d3d3/raw/verify.sh -o /tmp/verify-piyush.sh
   chmod +x /tmp/verify-piyush.sh
   ```

2. Run it and capture output:
   ```bash
   bash /tmp/verify-piyush.sh
   ```
   Show Piyush the full output.

3. If verify shows failures, ask Piyush whether to re-attempt the failing items now or defer (use AskUserQuestion):
   - "Want me to re-run the missing installs now?" (yes / no / show me first)

4. Print the consolidated FINAL MANUAL CHECKLIST below — these are things Claude CANNOT do, Piyush has to:

   ========================================
   🛑 FINAL MANUAL CHECKLIST — your turn
   (Estimate: 30-45 min total, do at your own pace)

   PHONE-PAIRED APPS (need your phone)
     [ ] WhatsApp → on phone: Settings → Linked Devices → Link a Device → scan QR on Mac
     [ ] Signal   → on phone: Settings → Linked Devices → + → scan QR on Mac
     [ ] Telegram → enter phone number, approve from existing Telegram session on phone

   APP SIGN-INS (browser/OAuth)
     [ ] Notion → sign in to your Nitya workspace
     [ ] Notion Calendar → sign in WITH GOOGLE (Google account required — no other auth supported)
     [ ] Slack → sign in to each Nitya workspace (separate browser flow each)
     [ ] Zoom → sign in
     [ ] Brave / Chrome / Firefox → sign in to sync (optional)
     [ ] Cursor → sign in (only needed for Pro features — skip if free tier)
     [ ] Postman → sign in (optional)

   CLI CREDENTIALS (you'll need access keys)
     [ ] `aws configure`         — paste your AWS access key + secret + region (ask Nitya admin if unsure)
     [ ] `doctl auth init`       — paste DigitalOcean token (only if Nitya uses DO)
     [ ] `op signin`             — verify 1Password CLI works (the desktop app needs CLI integration ON — see Phase 5 step F)

   LICENSE KEYS (optional paid apps)
     [ ] CleanShot X — buy at cleanshot.com if you want it past the trial
     [ ] TablePlus — free tier limited to 2 tabs; license at tableplus.com for more
     [ ] Cursor Pro — $20/mo, optional, unlocks Composer + Agent
     [ ] Raycast Pro — $8/mo, unlocks AI commands (skip if you have ChatGPT/Claude already)

   KNOWN-BROKEN ON TAHOE
     [ ] Ice menubar app — the brew cask is broken. Either skip, or grab beta 0.11.13+ from
         github.com/jordanbaird/Ice/releases (manual download).

   PERMISSION RE-PROMPTS (macOS Tahoe re-prompts these MONTHLY)
     [ ] Every month, macOS will re-prompt for Accessibility / Screen Recording on:
         Raycast, Rectangle, AltTab, CleanShot, Zoom. Just re-grant.

   BACKUPS / DOTFILES
     [ ] Consider committing your `~/.zshrc`, `~/.gitconfig`, `~/.config/ghostty/config`,
         `~/.claude/settings.json` to a private GitHub repo so you can restore on any new Mac.

   ========================================

5. Print final message:
   ========================================
   ✅ PHASE 8 DONE — install complete
   Total install time: ~75 min Claude work + ~30 min your interactive time
   You now have:
     - Modern terminal (Ghostty + premium config + notification hooks)
     - Smart shell (oh-my-zsh + Starship + autosuggest + syntax highlighting)
     - Node + Python pinned via mise
     - GitHub SSH auth + git config
     - 33+ modern CLI tools (eza, bat, rg, fzf, lazygit, jq, mise, uv, ollama, ...)
     - 28+ GUI apps (Cursor, Brave, Raycast, 1Password, Obsidian, Notion, Slack, ...)
     - Claude Code wired with 8-11 MCPs + superpowers + frontend-design
     - Dev-friendly macOS defaults

   Work through the final manual checklist when you have time.
   Welcome to your new Mac. 🚀
   ========================================

Troubleshooting

Warning

If a phase fails halfway and you want to restart it, just paste the same prompt again. Claude will detect what's already done (via the preflight checks) and pick up where it left off.

Symptom Fix
command not found: brew Re-run eval "$(/opt/homebrew/bin/brew shellenv)". Verify which brew returns /opt/homebrew/bin/brew.
command not found: npm or node Mise didn't activate. Open new tab, or eval "$(mise activate zsh)".
claude mcp list shows red ✗ on a server Restart Claude (Cmd+Q, re-run claude). MCPs initialize on Claude startup.
Permission prompts keep coming back macOS Tahoe re-prompts monthly. Annoying but normal — just re-grant.
Ghostty looks wrong (boxes for icons) The JetBrains Mono Nerd Font cask installed but Ghostty was open — Cmd+Q Ghostty and re-open.
Spotlight still steals Cmd+Space from Raycast System Settings → Keyboard → Keyboard Shortcuts → Spotlight → uncheck both. Logout/login.
oh-my-zsh subshell trap (terminal hangs) Use the install with RUNZSH=no CHSH=no env vars — Phase 2 already does this.

Why this stack? (the short version)

  • Ghostty — fastest Mac terminal, native AppKit, the new consensus pick in 2026.
  • oh-my-zsh — beginner-friendly framework, well-documented, huge plugin ecosystem.
  • Starship — modern cross-shell prompt, much lighter than Powerlevel10k.
  • mise — one tool to manage Node + Python + Rust + Go versions (replaces nvm + pyenv + ...).
  • uv — Astral's Python tool, 10-100x faster than pip, absorbed Rye in Feb 2026.
  • Cursor — VS Code with AI built in; pairs with Claude Code (Cursor for inline, Claude for multi-file).
  • Brave — Chromium with native ad/tracker block, fewer extensions to manage than Chrome.
  • Raycast — replaces Spotlight + Alfred + clipboard managers in one launcher.
  • Rectangle — free window snapping; minimal, doesn't fight with macOS.
  • 1Password — gold-standard password manager + secrets injection via op CLI.
  • OrbStack — 10× lighter than Docker Desktop, same docker CLI.
  • TablePlus — fast Postgres GUI, handles pgvector for Nitya's RAG dev.

Credits

Stack curated by Adam Boudjemaa. Verified May 2026 against formulae.brew.sh, official MCP repos, and live Ghostty/Claude Code docs. Bug reports / improvements → ping Adam on Slack.

#!/usr/bin/env zsh
# ============================================================
# Piyush Mac install — verification script
#
# Usage: bash verify.sh
# (or: zsh verify.sh)
#
# Checks:
# 1. Foundation (Xcode CLT, Homebrew, paths)
# 2. Every Brewfile formula installed
# 3. Every Brewfile cask installed
# 4. Dev runtimes via mise (node, python)
# 5. SSH + GitHub auth
# 6. Claude Code installed + OAuth healthy
# 7. Config files present (.zshrc, .gitconfig, ghostty, claude settings)
# 8. macOS defaults applied
# 9. Shell config sources without errors
#
# Exit 0 = all green. Non-zero = issues found (counted at bottom).
# ============================================================
C_GREEN='\033[0;32m'
C_BLUE='\033[0;34m'
C_YELLOW='\033[0;33m'
C_RED='\033[0;31m'
C_GRAY='\033[0;90m'
C_RESET='\033[0m'
PASS=0
FAIL=0
WARN=0
TO_FIX=()
ok() { echo -e " ${C_GREEN}✓${C_RESET} $1"; PASS=$((PASS+1)); }
miss() { echo -e " ${C_RED}✗${C_RESET} $1"; FAIL=$((FAIL+1)); }
warn() { echo -e " ${C_YELLOW}⚠${C_RESET} $1"; WARN=$((WARN+1)); }
info() { echo -e " ${C_GRAY}·${C_RESET} $1"; }
head() { echo -e "\n${C_BLUE}▶ $1${C_RESET}"; }
# ============================================================
# 1. Foundation
# ============================================================
head "1. Foundation"
xcode-select -p &>/dev/null && ok "Xcode CLI tools installed" || { miss "Xcode CLI tools missing — run: xcode-select --install"; TO_FIX+=("xcode-select --install"); }
command -v brew &>/dev/null && ok "Homebrew at $(which brew)" || miss "Homebrew not installed"
[[ "$(which brew)" == "/opt/homebrew/bin/brew" ]] && ok "Homebrew on Apple Silicon path (/opt/homebrew)" || warn "Brew not at /opt/homebrew — Intel/Rosetta path?"
[[ "$(uname -m)" == "arm64" ]] && ok "Apple Silicon (arm64)" || warn "Not Apple Silicon"
grep -q "brew shellenv" ~/.zprofile 2>/dev/null && ok "brew shellenv wired in ~/.zprofile" || warn "brew shellenv missing in ~/.zprofile — new shells won't see brew"
# ============================================================
# 2. Required brew formulae (Brewfile spec)
# ============================================================
head "2. Required brew formulae"
REQUIRED_FORMULAE=(
starship
eza bat fd ripgrep fzf zoxide
lazygit gh jq yq tree
htop btop dust duf
direnv tlrc gnupg mkcert
mas xh doggo wget watch
imagemagick yt-dlp ncdu
mise uv git
libpq pgcli redis
ollama ffmpeg
awscli doctl
)
INSTALLED_FORMULAE=$(brew list --formula 2>/dev/null)
for f in "${REQUIRED_FORMULAE[@]}"; do
if echo "$INSTALLED_FORMULAE" | grep -qx "$f"; then
ok "formula $f"
else
miss "formula $f"
TO_FIX+=("brew install $f")
fi
done
# ============================================================
# 3. Required brew casks
# ============================================================
head "3. Required brew casks"
REQUIRED_CASKS=(
ghostty iterm2 cursor
brave-browser google-chrome firefox
raycast rectangle
jordanbaird-ice alt-tab stats
obsidian notion notion-calendar
1password 1password-cli
cleanshot shottr
iina the-unarchiver appcleaner
tableplus orbstack postman
whatsapp telegram slack zoom signal
font-jetbrains-mono-nerd-font
)
INSTALLED_CASKS=$(brew list --cask 2>/dev/null)
for c in "${REQUIRED_CASKS[@]}"; do
if echo "$INSTALLED_CASKS" | grep -qx "$c"; then
ok "cask $c"
else
miss "cask $c"
TO_FIX+=("brew install --cask $c")
fi
done
# ============================================================
# 4. Dev runtimes (mise)
# ============================================================
head "4. Dev runtimes (mise)"
if command -v mise &>/dev/null; then
CURRENT=$(mise current 2>/dev/null)
echo "$CURRENT" | grep -q "node" && ok "node ($(echo "$CURRENT" | grep node | awk '{print $3}'))" || miss "node not pinned via mise — run: mise use --global node@lts"
echo "$CURRENT" | grep -q "python" && ok "python ($(echo "$CURRENT" | grep python | awk '{print $3}'))" || miss "python not pinned — run: mise use --global python@3.13"
else
miss "mise not installed"
fi
# ============================================================
# 5. SSH + GitHub
# ============================================================
head "5. SSH + GitHub"
[[ -f ~/.ssh/id_ed25519 ]] && ok "SSH key exists at ~/.ssh/id_ed25519" || miss "SSH key missing — run: ssh-keygen -t ed25519 -C \"\$(git config --global user.email)\""
if gh auth status &>/dev/null; then
ok "gh CLI authenticated"
else
miss "gh CLI not authenticated — run: gh auth login --web"
fi
if ssh -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new -T git@github.com 2>&1 | grep -q "successfully authenticated"; then
ok "GitHub SSH auth working (ssh -T git@github.com)"
else
miss "GitHub SSH auth failing — see Phase 3 of the gist"
fi
# ============================================================
# 6. Claude Code
# ============================================================
head "6. Claude Code"
if command -v claude &>/dev/null; then
ok "claude CLI at $(which claude)"
CLAUDE_VER=$(claude --version 2>/dev/null | head -1)
[[ -n "$CLAUDE_VER" ]] && info "version: $CLAUDE_VER" || warn "claude --version returned nothing"
else
miss "claude CLI missing — run: npm install -g @anthropic-ai/claude-code"
fi
# Claude Code config dir
[[ -d ~/.claude ]] && ok "~/.claude config dir exists" || warn "~/.claude missing — run claude once to initialize"
[[ -f ~/.claude/settings.json ]] && ok "~/.claude/settings.json present" || warn "~/.claude/settings.json missing"
# ============================================================
# 7. Config files
# ============================================================
head "7. Config files"
CONFIGS=(
"$HOME/.zshrc"
"$HOME/.zprofile"
"$HOME/.gitconfig"
"$HOME/.config/ghostty/config"
"$HOME/.config/starship.toml"
)
for f in "${CONFIGS[@]}"; do
[[ -f "$f" ]] && ok "$f" || miss "$f missing"
done
# ============================================================
# 8. macOS defaults
# ============================================================
head "8. macOS defaults (quality-of-life)"
[[ "$(defaults read com.apple.finder AppleShowAllFiles 2>/dev/null)" == "1" ]] && ok "Finder shows hidden files" || warn "Finder hidden files OFF"
[[ "$(defaults read -g KeyRepeat 2>/dev/null)" == "2" ]] && ok "Key repeat at max speed" || warn "Key repeat not maxed (defaults write -g KeyRepeat -int 2)"
[[ "$(defaults read -g NSAutomaticDashSubstitutionEnabled 2>/dev/null)" == "0" ]] && ok "Smart dashes OFF (won't break code paste)" || warn "Smart dashes ON — breaks code paste"
[[ "$(defaults read -g NSAutomaticQuoteSubstitutionEnabled 2>/dev/null)" == "0" ]] && ok "Smart quotes OFF" || warn "Smart quotes ON — breaks code paste"
# ============================================================
# 9. Shell config sources cleanly
# ============================================================
head "9. Shell health"
if zsh -i -c "exit" 2>/dev/null; then
ok "~/.zshrc sources without errors"
else
miss "~/.zshrc errors on source — run: zsh -i -c 'echo ok' and read errors"
fi
# Check key tools are on PATH inside interactive zsh
for cmd in starship eza zoxide mise uv gh claude; do
if zsh -i -c "command -v $cmd" &>/dev/null; then
ok "PATH: $cmd reachable in interactive zsh"
else
warn "$cmd not on PATH in interactive zsh — check ~/.zshrc"
fi
done
# ============================================================
# Summary
# ============================================================
echo ""
echo -e "${C_BLUE}═══════════════════════════════════════════════════════${C_RESET}"
echo -e "${C_BLUE} Verification summary${C_RESET}"
echo -e "${C_BLUE}═══════════════════════════════════════════════════════${C_RESET}"
echo -e " ${C_GREEN}✓ PASS: $PASS${C_RESET}"
echo -e " ${C_RED}✗ FAIL: $FAIL${C_RESET}"
echo -e " ${C_YELLOW}⚠ WARN: $WARN${C_RESET}"
if [[ ${#TO_FIX[@]} -gt 0 ]]; then
echo ""
echo -e "${C_BLUE}── To install / fix ──${C_RESET}"
for cmd in "${TO_FIX[@]}"; do
echo " $cmd"
done
fi
echo ""
if [[ "$FAIL" -eq 0 ]]; then
echo -e "${C_GREEN} ✅ All required items installed${C_RESET}"
echo -e "${C_GRAY} (Warnings are nice-to-haves, not blockers.)${C_RESET}"
exit 0
else
echo -e "${C_RED} ❌ $FAIL items missing — see list above${C_RESET}"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment