Vibe coding with AI course Β· Module 15: Claude Code CLI
CLAUDE.md and Plan Mode
In this lesson5
We have reached the real treasure! These two features are what separate plain "chatting with an AI" from professional vibecoding with Claude Code.
CLAUDE.md - the heart of the project
The most important file in your work with Claude Code is CLAUDE.md - a markdown file in the root directory of the project that Claude loads automatically at the start of every session. It is the map you hand to your navigator before he even sets foot on deck.
It pays to be precise about what that file is, because sailors get it wrong. CLAUDE.md is a markdown project-memory file holding your conventions, architecture and commands. It is not an npm config that replaces package.json, it is not a log of TypeScript compiler errors, and it is certainly not a binary file with the Claude model inside. It is plain text you can read, edit and commit like any other file in the repo.
What to put in CLAUDE.md?
- Conventions - how to name files, what code style to use, how to format
- Architecture - directory structure, key modules
- Commands - how to run the project, the tests, the linter, the build
How do you generate it?
The easiest route is to let Claude do it for you. Type this in a session:
1/initThe process always runs in the same four steps: you type the /init command in a session, Claude analyzes the project structure, a ready CLAUDE.md file is created in the root directory, and from that point on Claude automatically loads it in every subsequent session. You can still edit it by hand afterwards, or open it from inside a session with the /memory command - that is the command that edits your project memory, not /save and not /file.
The CLAUDE.md file hierarchy
~/.claude/CLAUDE.md- global, works across all projectsCLAUDE.md- in the project root directoryCLAUDE.mdin subdirectories - for specific parts of the project
Read that list from the most global to the most specific: the one in your home directory applies everywhere, the one in the project root applies to this ship only, and a nested one applies to a single deck of it. Claude does not pick one file: it adds all of them to the context, from the most general to the closest, and it loads a subdirectory's file only when it reads files in that subdirectory. When two files contradict each other, Claude may follow either one, so keep the levels from fighting.
An example CLAUDE.md:
1# My Project - Online Store
2
3## Stack
4- Next.js + TypeScript
5- Tailwind CSS
6- Prisma + PostgreSQL
7
8## Commands
9- `npm run dev` - development server
10- `npm test` - tests
11- `npm run lint` - linter
12
13## Conventions
14- Components: PascalCase in src/components/
15- Always add TypeScript types
16- Tests next to the files, in a __tests__/ directoryNotice the shape of that file, because it is a good default: the project title first, then the Stack (Next.js, TypeScript, Tailwind), then the Commands (npm run dev, npm test), then the Conventions (PascalCase, TypeScript types). Stack before commands before conventions - you tell Claude what the ship is made of, then how to sail it, then the rules of the crew.
Plan Mode - the newest power
This is one of the newest and most important features in Claude Code. In Plan Mode Claude first explores the project and proposes a PLAN of action, and only edits files after you approve it.
That makes it perfect for large, risky changes - you see what Claude intends to do BEFORE it touches a single line of code.
How do you enable Plan Mode?
There are three ways:
- The Shift+Tab key - it cycles through the permission modes inside a session, and one of them is exactly Plan Mode
- The
/plancommand typed before your request, for example/plan rebuild the auth system - A flag at startup:
1claude --permission-mode plan "Rebuild the auth system to use JWT"The flag is --permission-mode followed by the value plan, then your prompt in quotes. Watch out for look-alikes that simply do not exist in Claude Code: there is no --temperature plan, no --glob plan and no --output plan. Among the flags, only --permission-mode plan starts the session straight in planning mode.
Permission modes
Claude Code has a handful of modes that decide how much it may do on its own:
default(shown as Manual) - reads without asking, asks before edits and commandsplan- explores and plans, does not edit your code until you approve the planacceptEdits- automatically accepts Claude's file editsauto- a second model (a classifier) reviews actions instead of you; newer versions start terminal sessions in this modedontAsk- denies anything that would otherwise ask for permission (handy in CI)bypassPermissions- skips permission prompts entirely (only in a container or a virtual machine!)
Line up the four basic ones from the most cautious to the most autonomous and you get: plan, then default, then acceptEdits, then bypassPermissions. Note that acceptEdits accepts edits automatically - it does not block editing, it does the opposite. You switch between modes on the fly with Shift+Tab or with the --permission-mode flag.
The Plan Mode workflow
1# 1. Enable Plan Mode
2claude --permission-mode plan "Add a shopping cart to the store"
3
4# 2. Claude explores the project and presents a PLAN:
5# - which files it will create
6# - which it will modify
7# - in what order
8
9# 3. You read the plan and approve it
10
11# 4. Only now does Claude make the changes in the codeThose four steps never swap places: enable the mode, let Claude explore and present the plan of changes, read the plan and approve it, and only then does Claude make the changes in the code. If the plan looks wrong, you correct it in conversation and nothing has been broken - the cheapest mistake is the one caught on the map, not on the reef.
Settings and permissions (settings.json)
You steer the behaviour of Claude Code through settings files:
.claude/settings.json- project settings (committed to the repo).claude/settings.local.json- your private settings for this project (kept out of Git)~/.claude/settings.json- global settings
In the settings you define permission rules - allow and deny patterns. Here is what .claude/settings.json contains (it is strict JSON, so do not put comments in it):
1{
2 "permissions": {
3 "allow": [
4 "Bash(git *)",
5 "Bash(npm run test)"
6 ],
7 "deny": [
8 "Bash(rm -rf *)"
9 ]
10 }
11}Read the pattern Bash(git *) piece by piece: the tool name Bash, an opening parenthesis, the command pattern git *, a closing parenthesis. It means "allow any git command without asking". The space before the star matters: git * matches git status and git log, but not gitk. Thanks to rules like these your git commands run without a prompt, while the deny rule blocks rm -rf in every mode - just remember that it matches the text literally, so rm -fr is a different string to it. The same file also holds environment variables, the default model and hooks (more on those in the next exercise). And note the filename - permission rules live in .claude/settings.json. There is no .claude/temperature.json, no claude.config.js, and tsconfig.json belongs to TypeScript, not to Claude.
Managing context in long sessions
The longer the conversation, the more context you burn. Two commands matter here:
1# Clear the context and start from a clean slate
2/clear
3
4# Summarize the conversation so far and continue (keeps the gist, saves tokens)
5/compactSo /clear resets the context and starts the conversation fresh, while /compact summarizes and continues a long conversation. You type the second one as a slash followed by the word compact. On top of that, /context shows how much context the conversation takes up, but it clears nothing (there are no /context show or /context clear commands), and you never have to restart the terminal to get a clean slate.
You can check the cost of a session with:
1/usage/usage (or /cost, which is now its alias) shows the cost of the current session, and on the Pro, Max, Team and Enterprise plans also your plan's usage limits - useful when a long refactor starts to feel expensive. Neither /save nor /file will show you the bill (those commands do not exist), and neither will /context, which only counts the context in use.
Context discipline also decides how you handle many files at once. There is no --glob flag that processes everything in one shot, but batch processing absolutely works - you just steer it yourself. Either write a bash for-loop that calls claude -p once per file, or pass several files via @ in one prompt:
1# One file at a time - a bash for-loop calling claude -p per file
2for file in src/components/*.tsx; do
3 claude -p "Add JSDoc comments to the component @$file" --permission-mode acceptEdits
4done
5
6# Or several files at once, referenced with @ in a single prompt
7claude "Compare @src/api/users.ts and @src/api/orders.ts and unify the error handling"The loop keeps every file in its own small, clean context, which is what you want for repetitive work across a whole directory. The single prompt with several @ references is what you want when the files have to be understood together - a comparison, a shared refactor, a bug that spans two modules. The same trick - claude -p wired into a script - is behind the practice tasks waiting for you next: a commit message generator, a component factory and a code search that understands plain sentences instead of regular expressions.
Two of those scripts take arguments from the command line. When you run ./generate-component.sh Button, the word Button lands in the variable $1, and all the words typed after the script name land in "$*" at once. You simply put such a variable into the prompt for Claude:
1NAME=$1
2claude -p "Create the React component $NAME in TypeScript and save it in src/components/$NAME.tsx,
3 tests in src/components/$NAME.test.tsx and stories in src/components/$NAME.stories.tsx" \
4 --permission-mode acceptEditsA .stories.tsx file describes a component's variants for Storybook, a tool that shows components in isolation. You build the search the same way: claude -p "Find the code in this project that deals with: $*" hands Claude the whole sentence typed after the script name, and Claude searches the files itself, because in -p mode it may read without asking.
Summary
CLAUDE.md - project memory, loaded automatically; generate it with /init
Hierarchy - global ~/.claude/CLAUDE.md + project root + nested files
Plan Mode - Claude plans before editing; Shift+Tab, /plan or --permission-mode plan
Permission modes - plan / default / acceptEdits / auto / dontAsk / bypassPermissions
settings.json - allow/deny rules (e.g. Bash(git *)), env, model
Context - /clear, /compact, a look at it via /context, cost via /usage
In the last two exercises you will meet subagents, skills, MCP and hooks - the genuinely new powers of Claude Code!
See you there!
Code for this lesson: init-and-claudemd.sh
1#!/bin/bash
2# CLAUDE.md - the project memory in Claude Code
3
4# The easiest way: let Claude generate CLAUDE.md for you.
5# Inside a 'claude' session, type the command:
6# /init
7
8# Claude analyzes the project and creates a ready CLAUDE.md.
9# You can edit it by hand afterwards, or with the /memory command.
10
11# The CLAUDE.md hierarchy (from the most general):
12# ~/.claude/CLAUDE.md - global, for every project
13# CLAUDE.md - in the project root directory
14# src/.../CLAUDE.md - nested, for one part of the project
15
16# Claude loads CLAUDE.md AUTOMATICALLY at the start of every session,
17# so it knows your conventions, architecture and commands right away.
18# The files do not override each other: all of them go into the context,
19# and a subdirectory's file loads when Claude works in that subdirectory.
20
21echo "Type /init in a claude session to generate CLAUDE.md"Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. How do you manage context in an ongoing Claude Code session?
2. What is the CLAUDE.md file in a project?
These are 2 of 10 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Vertical ordering
Put the process of creating and using a CLAUDE.md file via /init in order:
- Vertical ordering
Put the sections of an example CLAUDE.md file in order from top to bottom:
- Code editor
In commands.sh write the smart-commit.sh script: take the staged diff (git diff --cached), ask claude -p for a message in Conventional Commits format, show it, ask for approval (read) and run git commit -m.
- Vertical ordering
Order the CLAUDE.md files from the most global to the most specific:
- Code editor
In commands.sh write the generate-component.sh script: take the component name from $1 and ask claude -p for three files in src/components: <Name>.tsx, <Name>.test.tsx and <Name>.stories.tsx (Storybook).
- Vertical ordering
Put the steps of working with Plan Mode in order:
- Code editor
In commands.sh write the ai-search.sh script: take the query from the script arguments ($1 or "$*") and pass it to claude -p so that Claude finds the matching code itself and lists files and line numbers.
- Vertical ordering
Order the permission modes from the most cautious to the most autonomous:
- Horizontal ordering
Arrange the permission rule pattern that allows git commands without prompting:
- Click in order
Click the elements in order to run Claude in Plan Mode:
- Click in order
Click the elements in order to type the command that summarizes the conversation and continues the session: