Claudecode-Masterclass

Modules

02 · Your first session

The loop that everything else in this course is built on: ask, review, approve, test, commit. By the end of this module the blog project exists and has its first checkpoint.

Before you start

You will be able to
Get Claude to create and change files in a project you control, read the diffs, test the result in a browser, and save a checkpoint you can return to.
You need
  • A working desktop install from module 1
  • Git installed. Check by asking Claude is git installed, and what version? — if not, it will tell you where to get it
  • A browser
Starting state
The claude-course folder from module 0, containing hello.html. This module creates claude-course/my-blog, which every later module uses.

Set up the project and a way back

Start a new session — Cmd+N on a Mac, Ctrl+N on Windows, or the new-session control at the top left. Shortcuts drift between releases, so if that does nothing, open the app's own keyboard-shortcuts list; the current set is also in the desktop documentation.

Point the session at your claude-course folder, and check the permission mode is the one that asks before acting. Then:

Type this into the conversation
Create a folder called my-blog inside this project, initialise a
git repository in it with main as the branch name, and make an
empty first commit so I have a starting point.

You will get permission prompts for the git commands. Read the first few rather than clicking through them: the command text is right there, and it is a fast way to learn what git actually does.

Asking for a checkpoint before there is anything to lose feels like ceremony. It is the opposite: it is the only cheap moment to do it.

Ask for something real

Type this into the conversation
In my-blog, create index.html: a personal blog homepage with a
header containing the title "My Adventures" and a nav menu, a
short welcome paragraph, and a grid of 3 post previews with
placeholder titles and excerpts.

Plain HTML and CSS, no frameworks. Put the CSS in
styles/main.css and link it. Ask me at most 3 questions if
anything is genuinely ambiguous.

Notice how much of that is decisions rather than description. Plain HTML, no frameworks, CSS in its own file — those are choices you are making, and making them explicitly is most of the difference between a useful result and a surprising one.

Claude may ask a couple of multiple-choice questions. They will not be the same questions every time, so do not expect to match anything you have seen in a screenshot. If an option list does not contain what you want, there is always a free-text choice, and asking what the options mean is a perfectly good use of it.

The approval prompts

As Claude works, files appear in preview and permission prompts interrupt the flow. Broadly you get three answers, and they do not all last the same length of time:

AnswerMeaningHow long it lasts
DenyNo. Claude finds another way, or stops and asks.This once
Allow onceYes, this one action.This once
Don't ask againYes, and stop asking about this.Depends what you approved. A file edit: the rest of this session. A shell command or a web domain: written to .claude/settings.local.json in this repository, so it holds for future sessions too.

That last column is the one to internalise now, because "don't ask again" is not always the small, temporary convenience it sounds like. Module 7 shows you exactly where those saved decisions land and how to read them back. Until then, prefer Allow once for anything that writes, and save the standing approvals for things like creating a directory.

The exact wording and number of buttons depends on the release and on the rules already in effect. Treat the prompts in this course as illustrations of the kinds of answer available, not as a script of what your screen will say.

Look at what you got

Open my-blog/index.html in a browser — right-click it in the file list and choose Open in browser, or find it in Finder or File Explorer and double-click it.

A working homepage from one instruction, and almost certainly some things you now want to change. That is the point of looking rather than reading.

Changing what you built

Now ask for something you could not have specified up front, because you had not seen the thing yet.

Type this into the conversation
Warm the background up to a cream tint, and give the post cards
a soft shadow that lifts slightly on hover.

Show me the diff before applying it.

Reading a diff

Claude now shows you a change rather than a file, which is the format you will be reading for the rest of your time with this tool:

  • Red lines are being removed.
  • Green lines are being added.
  • Grey lines are unchanged, and are only there so you can see where in the file you are.

Two questions are worth asking of every diff: is it touching only the file I expected, and is it bigger than the request. A three-line request that produces a sixty-line diff is not necessarily wrong, but it is always worth a sentence of explanation before you accept it.

If a diff does not make sense to you, ask. Explain what this change does and why is a normal thing to say, and the answer will refer to the actual lines in your actual file.

About auto-accept

There is a mode that applies edits without asking. It is genuinely useful — for a mechanical change you have already agreed to, stopping at every file is pure friction. It is not a way to skip review; it moves the review from before each edit to after the batch. If you turn it on, the diff still gets read, just later. Module 4 covers where it belongs in the cycle.

Test it, then commit it

Refresh the browser and check the change actually happened. Then:

Type this into the conversation
Commit everything in my-blog with a message describing what
changed, then tag this commit module-02.

The tag is a named checkpoint. Every module in this course ends with one, so any later exercise can tell you exactly where to start from — and so you can always get back:

If you ever want to start a module over
Show me the difference between my working files and the tag
module-02, then put the project back to that tag. Tell me what
would be lost before you do it.
The tagging habit — set it now, it is assumed from here on

At the end of every module from here to the end of the course: commit, then tag the commit module-NN, using that module's number. You have just made module-02. Module 3 ends with module-03, and so on. It takes five seconds and three later modules stop working without it.

  • Every module's Starting state names a tag. That is how an exercise can tell you exactly where to begin, and how you get back if a module goes badly.
  • Module 9 builds a skill that reads the commits since your last tag. With no tags, it reads nothing and writes a confident summary of nothing.
  • Module 12 has you find which change broke something by comparing against a tag.

If you skip a module, tag anyway at the point you stop. A missing tag is not an error you will see straight away — it is one that surfaces four modules later, which is the worst kind.

Asking instead of instructing

Not every message has to be a job.

Type this into the conversation
Explain how the CSS in styles/main.css works. Assume I have not
written CSS before.

Claude reads the file and explains it against your own code rather than in the abstract. Building something and then asking how it works is a faster way to learn a language than reading about it first.

Sessions

Everything you have said so far is in one session. Within it, Claude remembers earlier instructions and the thread of what you were doing stays intact. A new session is a clean slate: the previous context is gone and you choose a directory again.

That is not a limitation to work around; it is a control. Module 13 is about using it deliberately.

Writing instructions that work

Instead ofSay
Make a websiteCreate index.html: a blog homepage with a header, a welcome paragraph and three post previews. Plain HTML and CSS.
Add a buttonAdd a header with the title "My Adventures" and warm the background to a cream tint.
Fix the bugThe hover shadow stopped appearing after the last change. Explain why, then fix it.

And go one step at a time. Small change, look at the result, next change. Claude picks up your corrections within a session, so the third request already reflects what you pushed back on in the first.

One caveat worth stating plainly: phrasing helps a lot, and it is not the only variable. A request can be perfectly worded and still go wrong because a file was not where Claude expected, a tool was missing, or the task was ambiguous in a way neither of you noticed. When something fails, "I must have phrased it badly" is one hypothesis, not the explanation.

Where you are now

A project with a git history, a page you can open, one reviewed change, and a checkpoint. Module 3 turns it into a small site.

You have finished when

  • my-blog/index.html exists and opens in a browser showing a heading and three post cards
  • You changed the page a second time and read the diff before accepting it
  • git log shows at least two commits, and the tag module-02 points at the last one
  • You can say what your permission mode is set to and what it does

If it goes wrong

What you seeWhat to do
Claude edits a file you did not expectReject the change and say which file you meant. Then check the folder shown in the session — a session opened one level up will happily create files beside your project instead of inside it.
The browser shows a blank pageCheck you opened my-blog/index.html and not the folder. If the file is right and the page is still blank, ask Claude: this page renders blank in the browser. Find out why before changing anything.
Git commands are refusedThe prompt for a git command is normal the first time. If you denied it, ask again — and read module 7, which is about deciding these once instead of every time.

On your own

Ask for one more visible change — a footer with the current year, say — but this time predict the diff before you look at it: which file, roughly how many lines, added or changed. Then compare. Being wrong is useful information about how well you understood the request you just made.

Before you start

You will be able to
Get Claude to create and change files in a project you control, read the diffs, test the result in a browser, and save a checkpoint you can return to.
You need
  • A working CLI install from module 1
  • Git installed: git --version should print a number
  • A browser
Starting state
The claude-course folder from module 0, containing hello.html. This module creates claude-course/my-blog, which every later module uses.

Set up the project and a way back

All of this is in your shell, before any session starts:

Your shell
$ cd ~/Documents/claude-course
$ mkdir my-blog && cd my-blog
$ git init -b main
$ git commit --allow-empty -m "Start of the project"

git init -b main names the branch explicitly. Do not assume it: what a fresh repository calls its first branch depends on your git version and configuration, and module 6 has you switching branches by name. If your git is too old for -b, use git init followed by git branch -M main.

The empty commit gives you a point to return to before anything exists. It costs nothing and it is the only cheap moment to make it.

If git complains that it does not know who you are, set that once per machine:

Your shell, once ever
$ git config --global user.name "Your Name"
$ git config --global user.email "you@example.com"

Open a session

Your shell
$ pwd            # should end in claude-course/my-blog
$ claude

From here the blocks marked inside the session use >. Everything marked your shell uses $ and only works after you have left the session with /exit. Getting these two mixed up is the most common stumble on this track, which is why they look different on this site.

Ask for something real

Inside the session
> Create index.html: a personal blog homepage with a header
  containing the title "My Adventures" and a nav menu, a short
  welcome paragraph, and a grid of 3 post previews with
  placeholder titles and excerpts.

  Plain HTML and CSS, no frameworks. Put the CSS in
  styles/main.css and link it.

Notice how much of that is decisions rather than description. Plain HTML, no frameworks, CSS in its own file — stating those explicitly is most of the difference between a useful result and a surprising one.

Claude prints what it intends to write and waits for you to approve it. The exact wording of that prompt depends on the release and on any rules already in effect; what is constant is that nothing lands on disk until you say so.

Roughly what it looks like
[File: index.html]
<!DOCTYPE html>
<html lang="en">
  ...
</html>

Create this file? (y/n)

Look at what you got

Leave the session for a moment — or better, use a second terminal window so you do not lose your place:

Your shell
$ ls -R
$ open index.html      # macOS
$ start index.html     # Windows, Git Bash
$ xdg-open index.html  # Linux

Changing it, and reading the diff

Inside the session
> Warm the background up to a cream tint, and give the post
  cards a soft shadow that lifts slightly on hover.
A diff, not a file
--- styles/main.css
+++ styles/main.css
@@ -8,7 +8,8 @@
     body {
         font-family: Arial, sans-serif;
-        background-color: #f5f5f5;
+        background-color: #f5f0e8;
     }
+    .card:hover {

Apply these changes? (y/n)

How to read it

  • - at the start of a line: that line goes away.
  • + at the start of a line: that line arrives.
  • @@ -8,7 +8,8 @@: line numbers. Ignore them until the day you need them.

Two questions for every diff: is it touching only the file you expected, and is it bigger than the request. A three-line request that produces a sixty-line diff is not necessarily wrong, but it always deserves a sentence of explanation first.

Saying no costs nothing

Inside the session
> Make the background hot pink.

Answer n and the file is untouched. There is no half-applied state to clean up, which is what makes it reasonable to try things.

Test it, then commit it

Refresh the browser first — approving a diff proves the change was written, not that it works. Then leave the session and commit:

Inside the session
> /exit
Your shell
$ git status
$ git add .
$ git commit -m "Add blog homepage with cream background and card hover"
$ git tag module-02

The tag is a named checkpoint. Every module in this course ends with one, so a later exercise can say exactly where to start — and so you can always get back:

Your shell — to start a module over
$ git status                 # check what you would lose first
$ git stash                   # keep it, if there is anything
$ git checkout module-02
The tagging habit — set it now, it is assumed from here on

At the end of every module from here to the end of the course: commit, then tag the commit module-NN, using that module's number. You have just made module-02. Module 3 ends with module-03, and so on. It takes five seconds and three later modules stop working without it.

  • Every module's Starting state names a tag. That is how an exercise can tell you exactly where to begin, and how you get back if a module goes badly.
  • Module 9 builds a skill that reads the commits since your last tag. With no tags, it reads nothing and writes a confident summary of nothing.
  • Module 12 has you find which change broke something by comparing against a tag.

If you skip a module, tag anyway at the point you stop. A missing tag is not an error you will see straight away — it is one that surfaces four modules later, which is the worst kind.

Your shell — the two lines to end every module with
$ git add . && git commit -m "what changed"
$ git tag module-02          # the number of the module you just finished
$ git tag                    # confirm it is there

Composing with the rest of your tools

Claude Code is a normal command-line program, but only in one-shot mode. Use -p whenever the output is going into a pipe, a file, or another program — without it you are opening an interactive session with a pipe attached, and it will not behave the way you expect.

Your shell
$ claude -p "Explain how this page is structured" > notes.md
$ git diff | claude -p "Review these uncommitted changes"

Two things to know about -p runs. There is nobody there to answer a permission prompt, so anything not already permitted fails rather than pausing — module 7 is about pre-deciding that. And a -p run is its own conversation: it does not inherit the session you had open.

Continuing a conversation

Your shell
$ claude -c          # continue the last session here
$ claude --resume    # pick from a list

A new terminal window in the same directory is not automatically the same conversation. -c is what makes it one.

Small things that add up

  • Up arrow in your shell recalls the last command; inside a session it recalls your last message.
  • Two terminal windows — one holding a session, one for git — save more time than any alias.
  • An alias for the commit dance: alias gc="git add . && git commit -m" in your ~/.zshrc or ~/.bashrc.

Where you are now

A project with a git history, a page you can open, one reviewed change, a tagged checkpoint, and a clear sense of when you are talking to Claude and when you are talking to your shell. Module 3 turns this into a small site.

You have finished when

  • my-blog/index.html exists and opens in a browser showing a heading and three post cards
  • You changed the page a second time and read the diff before accepting it
  • git log shows at least two commits, and the tag module-02 points at the last one
  • You can say what your permission mode is set to and what it does

If it goes wrong

What you seeWhat to do
You type git status and Claude answers instead of your shellYou are still inside the session. Leave it with /exit, or open a second terminal window and use that for git.
The browser shows a blank pageCheck the path you opened. Then, inside a session: this page renders blank in the browser. Find out why before changing anything.
git commit refuses with a message about identityGit needs a name and an email once per machine: git config --global user.name "Your Name" and git config --global user.email "you@example.com".

On your own

Ask for one more visible change — a footer with the current year, say — but this time predict the diff before you look at it: which file, roughly how many lines, added or changed. Then compare. Being wrong is useful information about how well you understood the request you just made.

Kept in this browser only. Nothing is sent anywhere.