Skip to content

Instantly share code, notes, and snippets.

@ashwch
Last active January 19, 2026 10:03
Show Gist options
  • Select an option

  • Save ashwch/e69a92c7d46b7f608174e948f4bf8e46 to your computer and use it in GitHub Desktop.

Select an option

Save ashwch/e69a92c7d46b7f608174e948f4bf8e46 to your computer and use it in GitHub Desktop.
PM Mac Setup Guide (M1) - Diversio

PM Mac Setup Guide (M1) - Diversio

Last updated: 2026-01-19

Goal

Get an M1 Mac ready for daily work with Claude Code, Codex CLI, ZSH + dotfiles, Postgres 17, Redis, and the Diversio monolith. Every step is copy/paste friendly with a clear "why" and a quick success check.


Setup Overview

[0 Access] → [1 Claude Code] → [2 Git + Homebrew + SSH] → [3 Dotfiles + Ghostty] → [4 Node + Codex] → [5 Python + UV] → [6 Services] → [7 Monolith]

Progress Checklist

  • 0 Access
  • 1 Claude Code
  • 2 Git + Homebrew + SSH
  • 3 Dotfiles + Ghostty
  • 4 Node + Codex
  • 5 Python + UV
  • 6 Services
  • 7 Monolith
  • Final verification

Mental Model

You type → Shell (zsh) → Tools (git, node, python) → Project (monolith)

How to Use This Guide

  1. Open your terminal app (see below)
  2. Copy/paste commands one line at a time
  3. After each step, run the Check command
  4. If it fails, jump to "If stuck" at the end of that step
  5. If something looks scary, do not guess—ask or paste the output into Claude Code or Codex

Terminal App: Ghostty (Recommended)

We use Ghostty as our terminal app. It's fast, modern, and designed for developers.

First time? Start with macOS Terminal (already on your Mac) for Steps 1-2, then install and switch to Ghostty in Step 3.

Why Ghostty over macOS Terminal?

Feature Ghostty macOS Terminal
Speed GPU-accelerated, instant Slower rendering
Font rendering Crisp, modern Basic
Quick terminal Cmd+Shift+1 from anywhere Not supported
Team setup Pre-configured in dotfiles Needs manual config

Ghostty is installed automatically in Step 3 via brew bundle. After Step 3, you'll switch to Ghostty for all remaining work.


Safety & First Principles

You are building layers. If a layer is missing, everything above it breaks. Do not skip ahead.

⚠️ Do NOT Why
Paste tokens or secrets into Claude Code/Codex Security risk
Run rm -rf unless a teammate tells you exactly what to delete Data loss
Force overwrite files with >| unless you are sure Accidental overwrites

Note: If a command asks for a password, it's your Mac login password (not a website password).


Command Line & .zshrc Basics

Terminal Basics

+--------------------------------------+
| Command = verb + options + args      |
| Example: ls -la ~/Documents          |
+--------------------------------------+
Syntax Purpose Example
cmd1 | cmd2 Pipe (connect commands) ps aux | rg python
> Redirect output (blocked by NO_CLOBBER) echo "hi" > file.txt
>| Force overwrite echo "hi" >| file.txt
>> Append echo "hi" >> file.txt

What .zshrc Does

Your shell config:

  • Exits early for non-interactive shells (scripts stay fast)
  • Keeps huge shared history across tabs with de-dupe
  • Safer defaults: pipefail (pipes fail if any step fails), NO_CLOBBER (blocks accidental overwrites)
  • Fast tab completions with menus and colors
  • Python via UV: helpers like pynew, pyrun, activate
  • Node via lazy-loaded NVM (ignore if using Volta)
  • Speed aliases: gs = git status, ni = npm install
  • Modern tools: lseza, cdz (zoxide), greprg (ripgrep)
  • Auto-activates Python envs when pyproject.toml is found
  • FZF helpers for fuzzy find
  • Starship prompt + syntax highlighting + autosuggestions

Want personal tweaks? Use ~/.zshrc.work for overrides. Leave .zshrc alone.

Load Order

~/.zshenv → ~/.zshrc → ~/.zshrc.work
            (team defaults)  (personal overrides)

Environment Variables

+------------------------------------------+
| VAR = a setting tools can read           |
|                                          |
| export FOO=bar       # for this terminal |
| FOO=bar command      # for one command   |
| echo $FOO            # read it           |
| env                  # list all          |
+------------------------------------------+

The source command loads a file into the current shell:

source ~/.zshrc   # or just: reload

Essential Commands

Command Purpose
pwd Where am I?
ls List files (pretty via eza)
cd <folder> Move to folder
cd .. Up one level
cd - Jump back to previous folder
open . Open current folder in Finder
zed . Open current folder in Zed editor
git status See uncommitted changes
git pull Download latest code
git checkout <branch> Switch branch

Tips & Gotchas

  • NO_CLOBBER means > won't overwrite files—use >\| only when you mean it
  • cd is zoxide, so it learns your folders (cd project might jump to your most-used path)
  • Lazy-loaded tools might say "command not found" until you open a new terminal tab
  • Dangerous commands (rm -rf, kill -9, findreplace): only use when someone tells you exactly what to do

Productivity Shortcuts (Use These Daily!)

These shortcuts will save you hours. Practice them until they become muscle memory.

1. Command History Search (Ctrl+R)

This is your most powerful shortcut. Press Ctrl+R and start typing any part of a previous command.

+---------------------------------------------------------+
| Ctrl+R  ->  type "migrate"  ->  finds your last migrate |
|                                 command instantly       |
+---------------------------------------------------------+
  • Press Ctrl+R, then type a few letters (e.g., mig for migrate, yarn for yarn commands)
  • Use arrow keys to scroll through matches
  • Press Enter to run, or Esc to cancel
  • Works with partial matches anywhere in the command

Example: You ran uv run python manage.py migrate --configuration=DevApp yesterday. Press Ctrl+R, type migrate, and it appears instantly.

2. Autosuggestions (Gray Ghost Text)

As you type, you'll see gray "ghost" text suggesting a command from your history.

+---------------------------------------------------------+
| You type: git pu                                        |
| You see:  git push origin HEAD   <- gray suggestion     |
|                                                         |
| Press Shift+Tab to accept the whole suggestion          |
| Or keep typing to ignore it                             |
+---------------------------------------------------------+
Action What happens
Shift+Tab Accept the entire suggestion
Right arrow Accept one character at a time
Keep typing Ignore suggestion, it updates as you type

3. Tab Completion

Press Tab to autocomplete file names, folder names, and commands.

+---------------------------------------------------------+
| cd ~/wo[Tab]  ->  cd ~/work/                            |
| cd ~/work/di[Tab]  ->  cd ~/work/diversio/              |
|                                                         |
| If multiple matches: press Tab twice to see options     |
+---------------------------------------------------------+

4. Smart Directory Jumping (zoxide)

The cd command learns your frequently-used folders.

# Instead of typing the full path:
cd ~/work/diversio/monolith/backend

# After visiting once, just type:
cd backend
# or even:
cd back

It remembers where you go most often and jumps there.

5. Fuzzy Directory Finder (fcd)

Type fcd to interactively search and jump to any folder:

fcd
# A searchable list appears - type to filter, Enter to jump

6. Quick Edits with show_aliases

Forgot a shortcut? Type show_aliases to see all available shortcuts organized by category.

Shortcut Cheat Sheet

Shortcut What it does
Ctrl+R Search command history (fuzzy)
Shift+Tab Accept autosuggestion
Tab Autocomplete file/folder names
Ctrl+A Jump to start of line
Ctrl+E Jump to end of line
Ctrl+W Delete word before cursor
Ctrl+U Delete entire line
Ctrl+L Clear screen
cd - Go back to previous directory
!! Repeat last command

Practice Exercise

Try this sequence to build muscle memory:

  1. Run: echo "Hello from terminal"
  2. Press Ctrl+R, type echo, press Enter (runs it again)
  3. Type cd ~/ then press Tab twice (see folder options)
  4. Type cd Doc and press Tab to complete (becomes cd Documents/)
  5. Type cd - to go back to where you were

When You're Stuck

Paste this into Claude Code or Codex:

I am stuck on step: <step name>

Command I ran:
<command>

Output:
<paste full terminal output here>

What I expected:
<expected result>

Step 0: Access & Accounts

Time: 10-20 min

Why: You cannot clone private repos or use AI tools without accounts.

Do

  1. Install 1Password (company password manager)
  2. Sign in and confirm you can see shared vaults
  3. Verify your GitHub account is added to the DiversioTeam org
  4. Confirm AI accounts are active:
    • Claude Code requires Pro/Max
    • Codex CLI requires ChatGPT Pro or supported business plan

Check

  • Can open 1Password and see shared vaults
  • GitHub org membership confirmed (check with Engineering if unsure)

If Stuck

Ask Engineering to confirm your GitHub org access and AI tool seats.


Step 1: Install Claude Code

Time: 5-10 min

Why: This becomes your helper for the rest of the setup.

Do

curl -fsSL https://claude.ai/install.sh | bash
claude --version
claude doctor

Then run claude and follow the login prompts (use your Pro/Max account).

Check

  • claude --version prints a version
  • claude doctor shows all green checks

If Stuck

Re-open Terminal and run claude doctor again. If install fails, re-run the install command. If it still fails, ask a teammate for help or continue to Step 2—you can install Claude Code later.


Step 2: Base Tools (Git + Homebrew + SSH)

Time: 15-25 min

Why: Homebrew installs most of our tools and services.

Do

# Trigger Xcode Command Line Tools install (includes git)
git --version

If macOS prompts you, accept and wait. Then install Homebrew:

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

Important (Apple Silicon only): After Homebrew installs, add it to your PATH:

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

Set Up GitHub SSH (Required for Cloning)

SSH lets you securely connect to GitHub without entering your password every time.

+-----------------------------------------------------------------------+
|  How SSH works (simple version):                                      |
|                                                                       |
|  Your Mac                            GitHub                           |
|  +-----------+                      +-----------+                     |
|  |  Private  |  ---proves you--->   |  Public   |                     |
|  |    Key    |                      |    Key    |                     |
|  |  (secret) |                      |  (shared) |                     |
|  +-----------+                      +-----------+                     |
|                                                                       |
|  You keep the private key. GitHub gets the public key.                |
+-----------------------------------------------------------------------+

Step 1: Generate your SSH key

# Create a new SSH key (replace with YOUR email)
ssh-keygen -t ed25519 -C "your.email@diversio.com"

When prompted:

  • File location: Press Enter to accept the default (~/.ssh/id_ed25519)
  • Passphrase: Press Enter twice for no passphrase (simpler for beginners)
+-----------------------------------------------------------------------+
|  You'll see something like:                                           |
|                                                                       |
|  Generating public/private ed25519 key pair.                          |
|  Enter file in which to save the key (/Users/you/.ssh/id_ed25519):    |
|  [Press Enter]                                                        |
|  Enter passphrase (empty for no passphrase): [Press Enter]            |
|  Enter same passphrase again: [Press Enter]                           |
|  Your identification has been saved in /Users/you/.ssh/id_ed25519     |
|  Your public key has been saved in /Users/you/.ssh/id_ed25519.pub     |
+-----------------------------------------------------------------------+

Step 2: Start the SSH agent

eval "$(ssh-agent -s)"

You should see: Agent pid 12345 (number will vary)

Step 3: Add your key to the agent

ssh-add ~/.ssh/id_ed25519

You should see: Identity added: /Users/you/.ssh/id_ed25519

Step 4: Copy your public key

pbcopy < ~/.ssh/id_ed25519.pub

This copies your public key to the clipboard. You won't see any output—that's normal!

Step 5: Add the key to GitHub

+-----------------------------------------------------------------------+
|  1. Open: https://github.com/settings/keys                            |
|                                                                       |
|  2. Click the green "New SSH key" button                              |
|                                                                       |
|  3. Fill in:                                                          |
|     - Title: "Work MacBook" (or any name you'll remember)             |
|     - Key type: "Authentication Key" (default)                        |
|     - Key: Press Cmd+V to paste your key                              |
|                                                                       |
|  4. Click "Add SSH key"                                               |
|                                                                       |
|  5. GitHub may ask for your password - enter it                       |
+-----------------------------------------------------------------------+

Step 6: Test the connection

ssh -T git@github.com

First time only: Type yes when asked about fingerprint.

+-----------------------------------------------------------------------+
|  Success looks like:                                                  |
|                                                                       |
|  Hi yourname! You've successfully authenticated, but GitHub does      |
|  not provide shell access.                                            |
|                                                                       |
|  (This message is GOOD! It means SSH is working.)                     |
+-----------------------------------------------------------------------+

Check

  • git --version prints a version
  • brew --version prints a version
  • ssh -T git@github.com says "Hi yourname! You've successfully authenticated"

If Stuck

  • If git is missing, re-run git --version to trigger the install prompt
  • If brew is not found, re-run the Homebrew install command, then run the three PATH commands again
  • If SSH test fails, make sure you copied the .pub file (public key) and added it to GitHub

Step 3: Dotfiles (ZSH + Ghostty)

Time: 10-20 min

Why: Gives you the same shell and terminal workflow as the team.

Do

# Clone dotfiles (path must be ~/dotfiles for setup.sh)
git clone git@github.com:ashwch/dotfiles.git ~/dotfiles

# Install tools + symlinks
cd ~/dotfiles
./setup.sh

# Install Ghostty, Zed, and other tools
brew bundle --file ~/dotfiles/Brewfile

If git clone fails with "permission denied": Go back to Step 2 and make sure SSH is set up correctly. Run ssh -T git@github.com to test.

Simplify Ghostty (Remove tmux)

The default setup uses tmux (an advanced tool). Run these commands to simplify Ghostty for basic use:

# Remove the symlinks (they point to the shared dotfiles)
rm -f ~/.config/ghostty/config
rm -f ~/Library/Application\ Support/com.mitchellh.ghostty/config

# Create a simple Ghostty config
cat > ~/.config/ghostty/config << 'EOF'
# Ghostty config (simplified for PM setup)
# Documentation: https://ghostty.org/docs/config

# Quick terminal (Cmd+Shift+1 from anywhere)
keybind = global:super+shift+1=toggle_quick_terminal
quick-terminal-position = top
quick-terminal-animation-duration = 0.15
EOF

# Copy to macOS config location
cp ~/.config/ghostty/config ~/Library/Application\ Support/com.mitchellh.ghostty/config

# Remove tmux and its config (not needed for this setup)
rm -f ~/.tmux.conf
rm -rf ~/.tmux
brew uninstall --ignore-dependencies tmux 2>/dev/null || true

Terminal Architecture

Ghostty window/tab → zsh shell → your commands

After This Step: Switch to Ghostty

  1. Open Ghostty from Applications (or Spotlight: Cmd+Space, type "Ghostty")
  2. Drag Ghostty to your Dock for quick access
  3. Close macOS Terminal—use Ghostty for all remaining steps

Ghostty is now configured for simple, direct shell access.

Check

  • zsh --version prints a version
  • Ghostty is open and working

If Stuck

  • If ./setup.sh stops after Xcode tools install, re-run it
  • If Ghostty won't open, continue with macOS Terminal for now and ask a teammate

Step 4: Node + Codex CLI

Time: 10-15 min

Why: Codex CLI is installed with npm, so we need Node first.

Do (Recommended: Volta)

curl https://get.volta.sh | bash

Open a new Ghostty tab (Cmd+T), then:

volta install node@20.11.0
node -v

# Install Yarn (used by frontend)
npm install -g yarn
yarn --version

Install Codex CLI:

npm i -g @openai/codex
codex --version

Run once to log in:

codex

Check

  • node -v prints v20.11.0
  • yarn --version prints a version
  • codex --version prints a version

If Stuck

  • If volta not found, open a new Ghostty tab (Cmd+T)
  • If codex fails to log in, verify your ChatGPT Pro access

Step 5: Python + UV

Time: 2-5 min

Why: Backend uses UV for Python and dependencies. (UV was already installed by setup.sh in Step 3.)

Do

Verify UV is working:

uv --version

Check

  • uv --version prints a version (e.g., uv 0.5.x)

If Stuck

If uv is not found, close and re-open Ghostty, then try again. If still missing:

curl -LsSf https://astral.sh/uv/install.sh | sh

Step 6: Services (Postgres 17 + Redis)

Time: 15-25 min

Why: Backend uses Postgres and Redis locally.

Install Postgres 17

brew install postgresql@17

Add to PATH (use .zshrc.work so dotfiles stay safe):

cat <<'SH' >> ~/.zshrc.work
export PATH="/opt/homebrew/opt/postgresql@17/bin:$PATH"
SH

source ~/.zshrc.work

Start and configure:

brew services start postgresql@17
psql --version

# Create local database user and db (matches backend sample .env)
createuser -s postgres
psql -d postgres -c "ALTER USER postgres WITH PASSWORD 'password';"
createdb diversio_db

"role already exists" is OK.

Install Redis

brew install redis
brew services start redis
redis-cli ping

Check

  • psql --version prints 17.x
  • redis-cli ping prints PONG

If Stuck

  • If psql not found, open a new Ghostty tab (Cmd+T)
  • If Redis fails, run brew services list and paste output into Claude Code

Step 7: Monolith Setup

Time: 20-40 min

Why: The unified repo containing all core projects.

Clone (New Machine)

mkdir -p ~/work/diversio
cd ~/work/diversio
git clone --recursive git@github.com:DiversioTeam/monolith.git
cd monolith

If clone fails with "permission denied": Go back to Step 2 and verify SSH is working (ssh -T git@github.com).

Update Submodules (If Already Cloned)

cd ~/work/diversio/monolith
git submodule update --init --recursive

Backend Quick Start

Requires .env from teammate

cd ~/work/diversio/monolith/backend
uv sync
uv run python manage.py migrate --configuration=DevApp
uv run python manage.py runserver --configuration=DevApp

Frontend Quick Start

Requires NPM_TOKEN for design system (get this from 1Password or ask a coworker)

cd ~/work/diversio/monolith/frontend

# Replace YOUR_TOKEN_HERE with the actual token from 1Password
export NPM_TOKEN=YOUR_TOKEN_HERE

yarn install
yarn start

⚠️ Do not commit NPM_TOKEN. The token is secret—never paste it into AI tools or commit it to git.

Optimo Frontend Quick Start

cd ~/work/diversio/monolith/optimo-frontend
yarn install
yarn dev

Check

If Stuck

  • Ask a teammate for the backend .env file
  • If yarn missing: npm install -g yarn

Step 8: VM (Only If Told You Need One)

Why: Some workflows require a Linux or Windows VM.

Do

  1. Ask Engineering which VM tool is approved
  2. If UTM: download from https://mac.getutm.app
  3. If other (Parallels, VMware): follow official installer

Check

  • Can open VM app and create a new VM

If Stuck

Ask Engineering which VM image you should use.


Final Verification Checklist

Run these and confirm no errors:

claude --version
codex --version
brew --version
zsh --version
uv --version
node -v
psql --version
redis-cli ping
Command Expected
claude --version Version number
codex --version Version number
brew --version Version number
zsh --version Version number
uv --version Version number
node -v v20.11.0
psql --version 17.x
redis-cli ping PONG

If any command fails, paste the output into Claude Code or Codex CLI.


Quick Troubleshooting

Problem Solution
"command not found" Close Ghostty, open new window, retry
"permission denied" while cloning Go back to Step 2 and verify SSH setup (run ssh -T git@github.com to test)
Postgres not running brew services list → check postgresql@17 status
Redis not running brew services list → check redis status
AI tools fail login Confirm Claude Pro/Max and ChatGPT Pro access
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment