# Your first repo

**A plain-language guide to GitHub + Claude Code — for someone who has never used either.**

By [Joy](https://joyzhaozheng.com) ·
Source: [github.com/joyzhzh/first-repo](https://github.com/joyzhzh/first-repo) ·
Updated 23 July 2026

> ## ▶ Start here
>
> **[`WALKTHROUGH.md`](WALKTHROUGH.md)** takes you from this folder to a live website in
> eight stages. Each stage is one short prompt you paste into Claude Code, and it stops
> after each one so you can check. To begin: read [Part 0](#part-0--the-mental-model)
> below — five ideas, a few minutes. Then:
>
> 1. Install [Claude Code](https://claude.com/code) — the desktop app is the easiest way in.
> 2. **[Download this kit](https://github.com/joyzhzh/first-repo/archive/refs/heads/main.zip)**
>    — a zip from GitHub. Unzip it into your **Downloads** and open the folder in Claude
>    Code as your **project** — the folder a session reads and works in. ⚠️ It unzips as
>    `first-repo-main`; rename it to `first-repo` so the paths below match.
> 3. Start a session and paste: `Do Stage 0 of WALKTHROUGH.md.`
>
> (Prefer a terminal? The same thing is `cd ~/Downloads/first-repo`, then `claude`.)
>
> This README is the reference behind the walkthrough. You do not need to read it front
> to back — each part stands alone, so come back for the part you need, when you need it.

Everything here is written from a real setup that has been running since June 2026 —
[ai-entrepreneurship.wiki](https://ai-entrepreneurship.wiki) and a handful of research
repos. The commands are the ones actually in use. Where something is a known trap, it is
marked **⚠️ Trap** — every one of those cost someone real time.

## Contents

| Part | What it answers |
|---|---|
| [0 · The mental model](#part-0--the-mental-model) | What is a repo? **Read this one now — the rest can wait.** |
| [1 · Install the tools](#part-1--install-the-tools) | What goes on the laptop, in what order |
| [2 · Link GitHub and Claude Code](#part-2--link-github-and-claude-code) | The sign-in everyone asks about |
| [3 · What is a repo, really](#part-3--what-is-a-repo-really) | `.gitignore`, public vs private, the Google Drive trap |
| [4 · Adopting a repo](#part-4--adopting-a-repo) | Your folder → a repo · joining a project · teaching Claude Code a repo |
| [5 · Turning a repo into a website](#part-5--turning-a-repo-into-a-website) | GitHub Pages, Netlify, custom domains |
| [6 · Working with Claude Code](#part-6--working-with-claude-code) | How to ask, how to size a session, when to stop — **read before your first real session** |
| [7 · The everyday loop](#part-7--the-everyday-loop) | The four commands you will use forever |
| [8 · When it breaks](#part-8--when-it-breaks) | The common errors, what they mean, what to do |
| [Quick reference](#quick-reference) | All of the above on one screen |

## Who this is for

- Your work lives in folders on a laptop, and you want it safe, versioned, and maybe online.
- You have heard "git" and "GitHub" and "repo" and never had them explained.
- You use (or are about to use) Claude Code, and want it to save and publish your work.
- Someone said "just clone the repo" and you did not know what that meant.

You do **not** need to know how to code. Everything below is copy-paste. By the end you
will have a live website, a private backup of your work, and — this is
[Part 6](#part-6--working-with-claude-code), the part people skip — a way of asking for
work that gets good results instead of frustrating ones.

---

## What's in this kit

Two halves. One teaches you; one teaches your tools.

**For you to read:**

| | |
|---|---|
| **[`WALKTHROUGH.md`](WALKTHROUGH.md)** | **Start here.** Eight stages, nothing → live website. One short prompt each. |
| **[`README.md`](README.md)** (this file) | The reference — the *why* behind the walkthrough. |
| **[`index.html`](index.html)** | This same guide as a web page, if you prefer a browser. |
| **[`PROMPTS.md`](PROMPTS.md)** | Copy-paste prompts for every task here. Keep it open while you work. |
| **[`templates/`](templates/)** | Three finished academic web pages and one theme file, so you never start from a blank screen. |

**For Claude Code to adopt:**

| | |
|---|---|
| **[`starter/`](starter/)** | Safety rules and a change queue you copy into **your own project**, so the agent knows what never to do there from day one. |
| **[`RUNBOOK.md`](RUNBOOK.md)** | For an agent walking a beginner through setup, live. |

**The habit this kit teaches: keep the instructions in a file, then point at the file.**
That is why every walkthrough prompt is one line — the real instructions live in files you
can read and correct. A long prompt drifts every time you retype it. A file does not.

### Safety first, simplicity second

Private by default. Nothing published without you saying so. Nothing deleted, ever.
Secrets kept out of git from the first commit. Every irreversible step is yours to take,
never the agent's. And every piece is the smallest thing that works — no build steps, no
frameworks, nothing you cannot read and understand yourself.

Nothing here is clever. That is deliberate. Clever is how beginners get stuck somewhere
they cannot debug.

---

## What only you can do

Almost everything else can be handed to Claude Code. These moments are yours — either
because a machine genuinely cannot do them, or because they are irreversible.

| Moment | Why it is yours |
|---|---|
| **The GitHub browser sign-in** ([Part 2](#part-2--link-github-and-claude-code)) | You are proving you are you. The agent runs the command and hands you the browser. |
| **Typing your Mac password** (Homebrew install) | Never type a password at an agent's request in any other context. |
| **Choosing public or private** | Public is a one-way door. What people copied stays copied. |
| **Clicking publish, deploy, or send** | The moment work leaves your laptop. Decide it deliberately. |
| **Adding someone to your repo** | You are granting access to your work. |
| **Buying a domain, changing DNS** | Money, and your name. |
| **Approving anything that deletes** | See the rule below. |
| **Revoking a leaked key** | Do this yourself, immediately, before anything else. |
| **Taste** | Which font, which colour, what it should say. Ask for options and a recommendation — then pick. |

**The one rule underneath all of these:** if you do not understand what is about to happen,
say *"explain it first, don't do it yet."* That sentence costs thirty seconds and is the
single most useful thing in this guide. An agent that cannot explain a step clearly should
not be running it.

Throughout the guide, steps that need you are marked **🧑 You**.

---

# Part 0 — The mental model

Read this part even if you skip the rest. Five ideas do all the work.

### 1. A repo is a folder with a memory

That is genuinely it. A **repo** (short for repository) is an ordinary folder on your
laptop, plus a hidden `.git` sub-folder that remembers every version of every file you
ever saved.

Nothing else about the folder changes. Your files are still just files. You can open
them, edit them, and email them exactly as before. The memory sits quietly alongside.

### 2. Saving a version is called a *commit*

When you finish a chunk of work, you take a snapshot. In git that snapshot is a
**commit**, and it is permanent — you can always come back to it.

The important thing, and the thing that surprises people coming from Google Drive or
Dropbox: **git never saves anything on its own.** It only takes a snapshot when you ask.
This is a feature. Drive syncing a half-finished file at the wrong moment is how you lose
an afternoon; git cannot do that to you.

### 3. GitHub is the copy that lives on the internet

Git runs on your laptop and needs no internet and no account. **GitHub** is a website
that stores a copy of your repo in the cloud.

Two words move work between them:

- **push** — send my snapshots up to GitHub
- **pull** — bring down snapshots other people (or my other laptop) pushed

That is the whole vocabulary. Everything else is detail.

### 4. Two people can work on the same repo, and git sorts it out

This is why repos exist rather than emailing zip files. You edit chapter 3, someone else
edits chapter 7, you both push, and git merges both. It only asks for help when you both
edited *the same lines* — which is rarer than you would think.

### 5. If your repo is a website, pushing *is* publishing

This is the part that surprises people most, and it is the payoff of the whole guide.

You connect your GitHub repo to a hosting service once. From then on, every time you
push, the site rebuilds and goes live — typically within about two minutes. There is no
"upload" step, no FTP, no dragging files anywhere. **You save your work, and the world
sees it.**

---

# Part 1 — Install the tools

macOS instructions. You need four things: `git`, the GitHub CLI (`gh`), Node, and
Claude Code.

### Step 1 — Xcode Command Line Tools

This has to come first on a fresh Mac. It provides `git` and the compilers everything
else needs.

```bash
xcode-select --install
```

> **🧑 You:** a macOS dialog pops up. Click **Install**, accept, and wait — it takes
> several minutes. If it says "already installed", that is fine, move on.

⚠️ **Trap:** the very first time you run `git --version`, *that* can trigger the same
dialog. Expected. Let it install, then carry on.

### Step 2 — Check what you already have

```bash
git --version
gh --version
node --version
npm --version
```

Anything that says "command not found" needs installing below.

### Step 3 — Homebrew, if you do not have it

Check first — `which brew`. If it prints a path, **skip this entirely.**

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

> **🧑 You:** first-time Homebrew install only — the script prints what it will do, waits
> for you to press **Return**, then asks once for your **Mac login password**. Run it in a
> real terminal window and type your password when asked.

⚠️ **Trap:** if `brew` was already installed, there is no prompt. Do not sit waiting for
one.

### Step 4 — The actual tools

```bash
brew install gh node@22 git
brew link --overwrite node@22
```

⚠️ **Trap — Node version matters.** Use **Node 22**. Hosting services build your site on
a specific Node version, and "works on my laptop, fails when published" is almost always
a version mismatch. Avoid Node 21.x and 20.0–20.2.

### Step 5 — Claude Code

Install it from [claude.com/code](https://claude.com/code) — the **desktop app** is the
easiest way in: open it, choose a folder as your project, and you are in a session. The
terminal version is the same tool — run `claude` from inside any folder.

---

# Part 2 — Link GitHub and Claude Code

This is the step everyone asks about, and it is smaller than expected.

**There is no special "connect Claude Code to GitHub" button.** What actually happens: you
sign your *laptop* in to GitHub once, using the GitHub CLI. Claude Code then uses that
same sign-in, because it runs commands on your laptop as you. Sign in once, and Claude
Code can read and push to your repos from then on.

### Step 1 — Make a GitHub account

Go to [github.com](https://github.com) and sign up. Note your username — you will need it.

### Step 2 — Sign in from the terminal

```bash
gh auth login
```

You get four questions. Answer them like this:

| Question | Answer |
|---|---|
| Where do you use GitHub? | **GitHub.com** |
| Preferred protocol for Git operations? | **HTTPS** |
| Authenticate Git with your GitHub credentials? | **Yes** |
| How would you like to authenticate? | **Login with a web browser** |

`gh` then prints a one-time code like `ABCD-1234` and says *"Press Enter to open
github.com in your browser…"*

⚠️ **Trap:** **the browser does not open until you press Enter.** People sit staring at a
terminal waiting for a browser that is waiting for them. Press Enter.

> **🧑 You — the one genuinely human step in this whole guide:**
> 1. Note the one-time code.
> 2. Sign in to GitHub in the browser.
> 3. Type the code, click **Authorize**.
> 4. The terminal prints `✓ Logged in as <your-username>`.

### Step 3 — Hand the sign-in to git, and check it

```bash
gh auth setup-git
gh auth status
```

`gh auth status` must show your account and a list of scopes that includes **`repo`**.
`repo` is what lets you read and write private repositories. If it is missing:

```bash
gh auth refresh -s repo
```

(and authorize in the browser again).

### Step 4 — Tell git who you are

Every snapshot is signed with a name and email. Set them once:

```bash
git config --global user.name  "Your Name"
git config --global user.email "you@example.com"
```

⚠️ **Trap:** this name and email are stamped into every snapshot you make, and if a repo
is ever made public they are published with it — permanently, in its history. **Choose an
email you are happy to see in public** before your first commit.

⚠️ **Trap:** some projects require a *specific* email on every commit. Set this **before**
your first commit — fixing it afterwards is annoying. If you get it wrong on a commit you
have not pushed yet: `git commit --amend --reset-author`.

### Step 5 — Prove it worked

```bash
gh api user -q .login
```

If that prints your username, your laptop is linked to GitHub, and so is Claude Code.

**From here on you can just ask Claude Code in plain English** — *"push my changes"*,
*"what changed since yesterday?"*, *"undo that last commit"*. You do not have to memorize
git commands. But it helps to know what it is doing on your behalf, which is what the rest
of this guide is for.

---

# Part 3 — What is a repo, really

### The anatomy

```
my-project/          ← an ordinary folder
├── .git/            ← the memory. Never touch this by hand.
├── .gitignore       ← a list of things NOT to remember
├── README.md        ← what this project is (GitHub shows this on the front page)
└── ...your actual files...
```

### `.gitignore` — the most useful file you have never heard of

Some things should not go into the memory: they are enormous, they regenerate
automatically, or they are secret.

A real `.gitignore`, from a working research repo:

```gitignore
# Regenerable — will be rebuilt automatically, no need to remember
node_modules/
.venv/
__pycache__/
dist/
.DS_Store

# Too big to be useful in a repo
data/huge-export.csv
```

⚠️ **Trap — the one that actually matters:** **never commit passwords, API keys, or
tokens.** Once something is in git history it is *very* hard to remove, and if the repo
is public, assume it is compromised the moment it lands. Keep secrets in files that
`.gitignore` excludes.

### Public vs private

- **Private** — only you and people you invite. Default choice for research, drafts, unpublished work.
- **Public** — anyone can read it. Required for some free features (including free GitHub Pages hosting).

You can flip private → public later. Going the other way does not un-publish what people
already copied, so **start private if you are unsure.**

### ⚠️ Trap — do not put a repo inside Google Drive or iCloud

This one is worth its own heading, because it is the single most expensive mistake in
this guide.

Google Drive and git both want to manage the same files, and they fight. Drive corrupts
git's internal files and strips the "executable" flag off scripts. The repo appears to
work and then breaks in confusing ways days later.

**Keep repos in a plain local folder.** A common convention:

```bash
mkdir -p ~/code
```

Git is already your sync layer — `push` and `pull` move work between machines. You do not
need Drive to do it too.

---

# Part 4 — Adopting a repo

"Adopting" covers three different situations. They come up in this order in real life.

## 4a. A folder you already have → a repo

You have a folder of work. You want it remembered and backed up.

**Do the local part first.** Git works perfectly with no GitHub account at all, and this
is the safest place to start — a local repo is a Time Machine for your folder that
nothing can publish by accident.

```bash
cd ~/my-project
git init
```

Now write a `.gitignore` **before** the first snapshot. Ask Claude Code: *"look at this
folder and write me a .gitignore"* — it will spot the huge and regenerable things.

```bash
git add -A
git commit -m "First snapshot"
```

That folder now has a memory. You can stop here for as long as you like.

**Then, when you want an internet copy:**

```bash
gh repo create my-project --private --source=. --push
```

One command: makes the GitHub repo, connects it, and pushes. Change `--private` to
`--public` when you want the world to see it.

> **A gentler on-ramp.** In the wiki project this started as a file called
> `SAVE-SNAPSHOT.command` that you double-click — it runs `git add -A` and `git commit`
> for you and prints your recent snapshots. No terminal, no GitHub, one double-click at
> the end of the day. If the terminal is the intimidating part, ask Claude Code to make
> you one. GitHub can come later; it is genuinely optional.

## 4b. A repo that already exists → joining a project

Someone has a project and wants you on it. Three things have to be true, in order.

**First — they add you.** ⚠️ **Trap:** if the repo is private and you have not been added
as a collaborator, `git clone` fails with **"repository not found."** That message is a
lie; the repo exists, you just cannot see it. It is *not* a typo in the URL.

The owner adds you at: repo → **Settings → Collaborators → Add people**.

**Second — you sign in.** Part 2, above. Cloning a private repo without being signed in
fails the same misleading way.

**Third — you clone.** "Clone" means download a full copy, memory and all.

```bash
mkdir -p ~/code && cd ~/code
git clone https://github.com/THEIR-USERNAME/THE-REPO.git
cd THE-REPO
```

Check you got what you expected:

```bash
git remote -v              # where this repo came from
git branch --show-current  # usually: main
```

**Prove you can write, without touching anything real.** This is worth doing on day one,
because discovering you lack write access halfway through a piece of work is miserable.
It pushes a throwaway branch and deletes it — no commit, no change to anyone's work:

```bash
git push origin HEAD:refs/heads/_authtest
git push origin --delete _authtest
```

If the first line is rejected, you do not have write access — go back to the owner.

**Then read before you write.** Well-run projects put their rules in the repo itself.
Look for `README.md`, `START_HERE.md`, `AGENTS.md`, or `CLAUDE.md` and read them first.
They exist precisely so a new person can start without breaking things.

## 4c. A repo → something Claude Code understands

Claude Code reads two special files automatically when it starts in a folder:

- **`CLAUDE.md`** — instructions for Claude Code specifically
- **`AGENTS.md`** — instructions for any AI coding tool

To create one, open a Claude Code session in the repo and type:

```
/init
```

It reads the codebase and writes a `CLAUDE.md` describing the project.

**The pattern worth copying.** In the wiki project, `CLAUDE.md` is four lines that say
"read `AGENTS.md`, that is the real source of truth" — because Claude Code is not the only
tool that touches the repo. One set of rules, every tool reads it, nothing drifts out of
sync:

```markdown
# CLAUDE.md

This project's operating brief for all AI agents is **AGENTS.md** — read it first.
It is the single source of truth. Do not duplicate its content here.

@AGENTS.md
```

That `@AGENTS.md` line pulls the other file in automatically.

What belongs in `AGENTS.md`: where things go, what must never be done (deleting data,
committing secrets, publishing without asking), and which commands to run to check work.
Keep it short — it is read at the start of every single session.

---

# Part 5 — Turning a repo into a website

Three routes, smallest first. Start simple even if you want the big one later, because
the simple ones teach the thing that matters: **push equals publish.**

> ### Do not start from a blank page
>
> [**`templates/`**](templates/) has three finished pages you can open right now — an
> academic **homepage**, a **project/paper page**, and a long-form **reading page** — plus
> one `theme.css` where all the colours, fonts and spacing live. Change a value there and
> every page changes together.
>
> No build step, no frameworks. Double-click `templates/index.html` and it works.
>
> [**`templates/README.md`**](templates/README.md) covers font pairings for academic work,
> the one-accent-colour rule, why line length matters more than typeface — and a set of
> copy-paste prompts for restyling the whole thing through Claude Code without touching
> CSS by hand.

## 5a. The simplest possible version — GitHub Pages

No build step, no other services, no cost. A `.html` file in a public repo becomes a
website.

**This repo is the demonstration.** It contains an `index.html`, and that file is the
page you may be reading right now.

1. Put an `index.html` in the repo root. (Ask Claude Code: *"make me a simple one-page
   site about X"*.)
2. Push it.
3. On GitHub: repo → **Settings → Pages** → under "Build and deployment", set **Source**
   to *Deploy from a branch*, branch **main**, folder **/ (root)** → **Save**.
4. Wait a minute. Your site is at `https://YOUR-USERNAME.github.io/YOUR-REPO/`.

From then on: edit, commit, push, and the live page updates itself.

⚠️ **Trap:** free GitHub Pages requires a **public** repo. Do not put anything private in
a repo you are about to publish this way.

## 5b. Netlify — the repo stays private, and every push publishes

This is the route the walkthrough takes ([Stage 5](WALKTHROUGH.md)), and the middle
ground between the other two: your repo stays **private**, and there is still no build
step.

1. Sign in to [Netlify](https://netlify.com) → **Add new site → Import an existing
   project** → pick your repo.
2. For a plain-HTML site like the templates: **no build command**, and leave the
   **publish directory** blank (or `.`).
3. Netlify gives you a live URL immediately, something like `random-name-123.netlify.app`.

> **🧑 You:** creating the Netlify account, authorising it to see your GitHub, picking
> the repo, clicking **Deploy**.

**From then on, `git push` is the deploy.** Netlify watches the repo: every push
republishes the site, live in about two minutes. There is no separate "upload to Netlify"
step to remember — the everyday loop in [Part 7](#part-7--the-everyday-loop) is the whole
publishing workflow.

After a push: wait about two minutes, load the live URL, and check the change is really
there. If it is not, hard-refresh first (you may be seeing a cached page), then check the
deploy log on Netlify.

## 5c. What a real site looks like

The wiki — [ai-entrepreneurship.wiki](https://ai-entrepreneurship.wiki) — has hundreds of
pages generated from research data, plus full-text search. Same principle, more machinery:

```
   you edit a file
        ↓
   git push
        ↓
   GitHub receives it
        ↓
   Netlify notices, runs `npm run build`   ← turns source into a finished site
        ↓
   live at ai-entrepreneurship.wiki        ← about 2 minutes, start to finish
```

The pieces:

| Piece | What it does |
|---|---|
| **[Astro](https://astro.build)** | Turns source files + data into plain HTML pages |
| **GitHub** | Holds the repo; every push notifies the host |
| **[Netlify](https://netlify.com)** | Watches the repo, runs the build, serves the site (free tier is generous) |
| **A domain registrar** | Where you buy `yourname.com` |

**Setting it up, once:**

1. Build a site locally. Ask Claude Code: *"set up an Astro site in this folder."* Check
   it works with `npm run build` — it must finish without errors.
2. Push the repo to GitHub.
3. Sign in to Netlify → **Add new site → Import an existing project** → pick your repo.
   Build command `npm run build`, publish directory `dist`.
4. It gives you a live URL immediately, something like `random-name-123.netlify.app`.
5. **Custom domain:** buy one, then in Netlify → **Domain management → Add a custom
   domain**, and add the DNS records Netlify shows you at your registrar. Usually a
   `CNAME` for `www` and an `A`/`ALIAS` record (or Netlify's nameservers) for the bare
   domain. DNS changes can take a few hours to take effect.

A `netlify.toml` in the repo pins the settings so they live in git rather than in a web
dashboard someone can change by accident:

```toml
[build]
  command = "npm run build"
  publish = "dist"

[build.environment]
  NODE_VERSION = "22"
```

**Even simpler, if you just want it online today:** [Netlify
Drop](https://app.netlify.com/drop) — build locally, drag the output folder onto the page,
get a live URL. No git at all. Fine for a one-off; you lose auto-deploy.

---

# Part 6 — Working with Claude Code

Everything above is *what* to do. This part is *how to ask for it* — which matters more
than any individual command. The danger with a vague ask is not that Claude Code fails;
it is that you get a confident, plausible, **wrong** result, and a beginner cannot tell
the difference. The copy-paste versions of everything here live in the
[**prompt sheet**](PROMPTS.md); this part is the reasoning behind them.

## 6a. What counts as one session

A **session** is one conversation with Claude Code, from opening it to closing it.

> **One session = one objective with one checkable finish.**

If you cannot write the finish line in a single sentence, you are looking at more than
one session. Split it.

| Sized right | Too big — split it |
|---|---|
| "Set up git in this folder and make the first snapshot" | "Set up my whole workflow" |
| "Write a `.gitignore` and explain each line" | "Clean up this project" |
| "Get this repo deploying to Netlify" | "Build me a website and put it online" |
| "Fix this error: *(paste it all)*" | "Make the site better" |

The right-hand column has no finish line, so the session never ends — it just drifts until
you lose track of what changed. "Build me a website and put it online" is really three
sessions: build it locally until `npm run build` passes → make it a repo and push →
connect the host and get a live URL. Each has an obvious moment where you can say *that
worked*.

Four rules of thumb:

- **A session should fit in one sitting.** If you need a break, that is a session boundary — end it properly (6e).
- **One working folder per session.** Say which folder it may write in. Sessions that roam across a whole disk are how surprises happen.
- **Anything risky gets its own session.** Publishing, deleting, anything touching money — on its own, with your full attention, never bolted onto the end of something else.
- **When the topic changes, start fresh.** A long conversation that has wandered gets worse, not better. Ending and restarting costs nothing.

## 6b. The six things a good ask contains

A weak ask is weak in predictable ways. Before you hit enter:

| # | The question | Weak | Strong |
|---|---|---|---|
| 1 | **What one thing should this produce?** | "clean up my repo" | "write a `.gitignore` for this folder" |
| 2 | **What shape is the output?** | "document this" | "a `README.md` at the repo root, under 200 lines" |
| 3 | **What should it read or use?** | — | "read `START_HERE.md` first; use the existing `scripts/bootstrap`" |
| 4 | **What must it NOT touch?** | — | "only edit files in `src/`. Do not touch `data/`" |
| 5 | **How much effort is this worth?** | — | "quick pass, don't over-engineer" / "this is the important one, take your time" |
| 6 | **How will we know it worked?** | "make it good" | "`npm run build` exits 0 and the page shows the new heading" |

You will not write all six every time. But **1 and 6 are not optional**, and 6 is the one
beginners skip.

**Why 6 matters most:** "done" has to be something you can *check*, not something the
agent *claims*. An agent that says "I've fixed it" has told you nothing. An agent that
says "`npm run build` now exits 0, here's the output" has told you something. Ask for the
evidence, every time, until it becomes a habit on both sides.

**Why 4 matters more than it looks:** naming what is off-limits is how you stay in control
of a tool that is faster than you are. "Don't touch anything already committed" is a
sentence that has saved a lot of afternoons.

## 6c. Chat is not storage

The rule that took the longest to learn on the project this guide comes from, and the one
worth adopting on day one:

> **If this session died right now, could a completely fresh session pick up the work from
> the files on disk alone?**

If the answer is no, something important exists only in the conversation — and
conversations end. They crash, they time out, you close the laptop, you hit a limit.
Anything that lived only in the chat is simply gone.

So: **ask for things to be written down as they happen**, not summarised at the end.
Plans, decisions, what you tried that did not work, the reason you chose one option over
another. A file in the folder, written when the decision is made.

This is also why the [`AGENTS.md`](AGENTS.md) pattern in Part 4c is worth the ten minutes.
It is the project's memory, and it survives every session.

## 6d. When it is stuck: three strikes, then stop

If the same step fails three times, **stop.** Do not ask for a fourth attempt.

Repeated failure almost never means the agent needs another go. It means something in the
situation is not what either of you thinks it is — a missing tool, a wrong assumption, a
permission you do not have. A fourth attempt just produces a more elaborate wrong answer,
and each one is harder to undo than the last.

Change the question instead. Not *"try again"* but:

```text
Stop. Don't try again. Tell me why this is failing —
what did you expect to happen, and what actually happened?
```

The related trap: when something is broken and you do not understand why, the danger is
not the original problem. It is the confident fix that throws away your only copy of your
work. Anything involving `reset --hard`, force-pushing, or deleting — make it explain
first and act second.

## 6e. Ending a session properly

When you stop mid-task, spend the last two minutes writing down where you are. Otherwise
tomorrow starts with twenty minutes of archaeology.

```text
We're stopping here. Write a handoff file in this folder covering:
- what's done and verified
- what's half-finished
- the exact next action
- anything you learned this session that isn't written down anywhere yet

Write it so a fresh session with no memory of this conversation could pick it
up from the file alone.
```

That last category — *things learned that are not written down anywhere* — is the one
people forget and the one that hurts most. The dead end you already explored, the flag
that does not work on this machine, the command that needs a different name here. Nobody
remembers it in a week, and the next session will happily walk into the same wall.

## 6f. Which model to use

Claude Code lets you pick a model. The instinct is to use the fastest one for small jobs
and the strongest for big ones. **Size is the wrong axis.** Use this instead:

| Use the strong model when | Use a faster model when |
|---|---|
| The task is ambiguous, or you are not sure what you want yet | The task is fully specified and mechanical |
| Something is broken and you do not know why | You know exactly what to change and where |
| The decision is hard to reverse — publishing, deleting, restructuring | It is small, obvious, and easy to undo |
| You are asking *what should I do here* | You are asking *do this specific thing* |

The mistake worth avoiding is backwards-routing: **never hand vague work to a fast model.**
Working out *what to do* is the expensive part, not the typing. If a job is
underspecified, tightening the spec is itself the strong model's work — and once the spec
is tight, the cheap model does the rest fine.

---

# Part 7 — The everyday loop

Once set up, this is the entire routine. Four commands, in this order, forever:

```bash
git pull                          # 1. get everyone else's latest work FIRST
# ...do your work...
git add -A                        # 2. stage everything you changed
git commit -m "what you changed"  # 3. take the snapshot
git push                          # 4. send it up (and, if it is a site, publish it)
```

⚠️ **Trap:** `git pull` **first**, always. Pulling at the end, after you have already
committed, is where merge headaches come from.

If the project is a website, that `git push` just published it. Wait about two minutes,
then load the real URL to confirm.

Or skip all of it and tell Claude Code: *"pull, then commit my changes with a sensible
message, then push."*

---

# Part 8 — When it breaks

Every one of these is common. None is a disaster.

| What you see | What it means | What to do |
|---|---|---|
| `repository not found` on clone or push | Almost always **not signed in**, or **not added as a collaborator** on a private repo. Rarely a typo. | `gh auth status` — check for `repo` scope. Then ask the owner to add you. |
| `Updates were rejected… non-fast-forward` | Someone pushed while you were working. | `git pull --rebase`, then `git push`. **Never** force-push a shared branch. |
| `Please tell me who you are` | Identity not set. | Part 2, Step 4. |
| Build fails after push, worked locally | Usually a Node version mismatch. | `node --version` → should be 22. Match what the host builds with. |
| Committed something secret | Serious. History is hard to rewrite. | Stop. **Revoke the key immediately** — assume it is compromised. Then ask for help cleaning history. |
| Want to undo the last commit (already pushed) | | `git revert HEAD && git push` — makes a *new* commit that undoes it. Safe on shared branches. |
| Want to undo the last commit (not pushed) | | `git reset --soft HEAD~1` — keeps your file changes, drops the snapshot. |
| Site did not update after push | Build may have failed. | Check the deploy log on your host. Also try a hard refresh — you may be seeing a cached page. |
| Genuinely lost | | Tell Claude Code exactly what you did and paste the full error. Do not guess at commands you do not understand — that is how a small problem becomes a big one. |

---

# Quick reference

```
SETUP (once per laptop)
  xcode-select --install
  brew install gh node@22 git
  gh auth login              → GitHub.com · HTTPS · Yes · web browser
                               (PRESS ENTER to open the browser)
  gh auth setup-git
  gh auth status             → must list the `repo` scope
  git config --global user.name  "Your Name"
  git config --global user.email "you@example.com"

ADOPT A FOLDER YOU HAVE
  cd ~/my-project
  git init
  # write .gitignore FIRST
  git add -A && git commit -m "First snapshot"
  gh repo create my-project --private --source=. --push

JOIN A PROJECT
  # owner adds you as collaborator first
  mkdir -p ~/code && cd ~/code
  git clone https://github.com/OWNER/REPO.git
  # prove write access without touching anything:
  git push origin HEAD:refs/heads/_authtest
  git push origin --delete _authtest
  # then READ: README.md / START_HERE.md / AGENTS.md

EVERY DAY
  git pull → work → git add -A → git commit -m "..." → git push

RULES
  Repos live in ~/code — NEVER in Google Drive or iCloud
  Never commit secrets, keys, or tokens
  Commit name + email go public with the repo — use ones you'd publish
  git pull BEFORE you start, not after
  Never force-push a shared branch

ASKING CLAUDE CODE  (full sheet: PROMPTS.md)
  One session = one objective with one CHECKABLE finish
  Always say: what to produce · what not to touch · how we'll know it worked
  "Done" means evidence you can see, never a claim
  Same step fails 3× → STOP. Ask "why is this failing?", not "try again"
  Broken and you don't know why → "explain first, don't act"
  Write it to a FILE as you go — chat is not storage
  Stopping mid-task → ask for a handoff file before you close
  Vague work → strong model. Tight spec → fast model. Never backwards.
```

---

## How this was actually built

Worth knowing, because the tidy version would be misleading. The **website** behind this
guide was a repo from its first day — 10 June 2026, first commit — and has been pushed to
and deployed from ever since. That part went the way Part 5 describes. The **research
folder behind it** was not: it lived in Google Drive for months, Drive corrupted git's
internal files, and the folder eventually had to be recovered and migrated out. The first
commit of that repo, on 18 July 2026, is literally titled *"recovered and migrated off
Google Drive."*

Two lessons from that shaped this guide:

- **The Google Drive warning in [Part 3](#part-3--what-is-a-repo-really) is not theoretical.** It is the single most expensive lesson here.
- **"Adopting a folder you already have" ([Part 4a](#4a-a-folder-you-already-have--a-repo)) is the normal case, not the edge case.** Most people do not start clean. You have a folder full of work, and you want it safe. Start there.

## For Claude Code

If you are an AI agent reading this repo, start with [AGENTS.md](AGENTS.md). To walk a
beginner through setup step by step, follow [RUNBOOK.md](RUNBOOK.md).

## Provenance

Written from a working setup, not from memory.

**Parts 1–5, 7–8** — the install sequence, the `gh auth login` prompts, the "browser does
not open until you press Enter" behaviour, the "repository not found" diagnosis, the
Google-Drive corruption warning, and the push-to-deploy pipeline — come from a new-laptop
setup guide written and independently verified against a live machine's real
`git`/`gh`/Netlify configuration on 2026-07-06, plus the deploy and snapshot documentation
of the [ai-entrepreneurship.wiki](https://ai-entrepreneurship.wiki) project.

**"How this was actually built"** is read from the two repos' own commit histories: the
site repo's first commit (2026-06-10) and the working repo's first commit (2026-07-18,
titled *"recovered and migrated off Google Drive"*).

**Part 6 and [PROMPTS.md](PROMPTS.md)** are the beginner-sized translation of a working
practice used on that project — a six-field brief for assigning a session, a task-folder
structure with explicit scope/non-scope/done-conditions, a written handoff at every
session boundary, a stop-after-three-failures rule, and routing work by how
*underspecified* it is rather than how large. The jargon has been removed; the shape is
unchanged.

## Version

**v6** — the front door drops the terminal: install the Claude Code desktop app, open
the folder as your project. **v5** — the readability pass: shorter front matter, a
contents table, the walkthrough stage map, and the commit-email warning. Before them:
**v4** added the staged walkthrough and the edit-request loop, **v3** split the kit into
its two halves and added the starter pack, **v2** added Part 6 and the prompt sheet and
corrected the build history that v1 had told too tidily.

## License

MIT — see [LICENSE](LICENSE). Copy it, fork it, rewrite it for your own friends.
