Skip to content

Your Vibe Coding Toolkit ​

The scenarios in the previous lesson are real. Here is how you make them happen on your own machine. Claude Code is the tool you will use for most of the vibe coding in this course. The difference between using it casually and using it well comes down to five specific habits: giving it persistent memory of your project, scripting repeatable commands, feeding it real file context, knowing when to let it run unattended, and always having an undo button ready. Five short labs, one habit each.

What you'll learn

  • Persistent project memory via CLAUDE.md, loaded automatically every session
  • Building custom slash commands to script repetitive workflows
  • --dangerously-skip-permissions for batch tasks, kept deliberate and scoped
  • Git as the undo button for every AI-driven change

The CLI landscape ​

Before the labs, a quick lay of the land. The course uses Claude Code because it is the most widely adopted agentic coding CLI, but the five habits below apply to any AI terminal tool. If you prefer OpenCode, Gemini CLI, or Aider, the specific commands differ but the workflow is the same: persistent context, reusable commands, real file input, and a deliberate relationship with auto-approve mode.

This lesson covers Claude Code specifically. For a deeper reference, see the Claude Code course which goes into skills, hooks, subagents, and CI/CD integration, or the Terminal Agents course which compares OpenCode, Aider, OpenHands, and Goose side by side.


Lab 1: Persistent Project Context with CLAUDE.md ​

Stop repeating setup instructions in every chat. A CLAUDE.md file at your project root holds permanent rules, conventions, and environment details. Claude Code reads it automatically at the start of every session.

Goal ​

Give Claude Code a clear picture of your project so it never needs to ask "what Python version?" or "where is the database?" again.

Step-by-Step ​

1. Install Claude Code:

bash
npm install -g @anthropic-ai/claude-code

Verify it is available:

bash
claude --version

2. Create your CLAUDE.md:

bash
cd ~/projects/my-agent-project

Create CLAUDE.md at the project root with your stack and conventions:

markdown
# Project Context

## Environment
- Python 3.12 with uv for package management
- PostgreSQL on localhost:5432
- Node.js 20 LTS via NVM

## Conventions
- Use async Python with asyncio wherever possible
- Validate all data with Pydantic v2
- Never leave TODO placeholders -- write real implementations
- Environment variables in `.env`, never committed

3. Verify it loaded:

Start Claude Code and ask it what it knows about your project:

bash
claude
> What does my project use for Python and database?

Claude Code should reference the details from your CLAUDE.md without you repeating them. If it does not, check that CLAUDE.md is in the directory you launched claude from, it reads from the current working directory upward.


Lab 2: Custom Slash Commands ​

Package a complex, multi-line prompt you use often, a security audit, a test-writing pass, a schema generator, into an instant, reusable custom slash command instead of retyping it every time.

Goal ​

Create a custom slash command /agent:new that takes a name as an argument and generates a boilerplate async FastAPI agent script.

Step-by-Step ​

1. Create the commands directory:

bash
mkdir -p .claude/commands

2. Create the command file:

Create .claude/commands/agent-new.md:

markdown
---
description: Generate a boilerplate async FastAPI agent
argument-hint: AgentName
---

Write a fully implemented, production-grade async Python FastAPI agent.

Specifications:
- The agent class name must be: $ARGUMENTS
- Use Pydantic v2 for request validation
- Include a mock cognitive loop using asyncio.sleep()
- Use Python's standard logging library
- Save to `agents/$ARGUMENTS.py`

The $ARGUMENTS placeholder receives whatever text you type after the command name.

3. Run it:

bash
claude
> /agent-new WorkflowOrchestrator

Claude Code parses the command file, substitutes the argument, and generates the agent. The file lands in agents/WorkflowOrchestrator.py.

Custom commands can have frontmatter for metadata (description, argument-hint, allowed-tools, model) and a markdown body for the prompt. The ! backtick syntax lets you inline shell output. The @ syntax injects file contents. Both are covered in the next lab.


Lab 3: File Injection and Shell Passthrough ​

Never let the model guess at file contents. Use @ to inject a real file into the prompt, and ! to run a system command without leaving the REPL.

Goal ​

Perform a security and performance audit on your generated agent file using explicit file context and direct terminal feedback.

Step-by-Step ​

1. Inject a file into the prompt:

bash
claude
> Audit this file for async race conditions, missing error handling, and performance issues: @agents/WorkflowOrchestrator.py

The @ symbol followed by a file path reads the file and includes its full contents in the prompt. Claude Code sees the actual code, not your description of it.

2. Review the diff:

Claude Code shows proposed changes as a diff before applying them. Read through it, approve what looks right, ask for revisions on what does not.

3. Run shell commands without leaving the session:

bash
> !pytest -v agents/

The ! prefix runs a shell command and pipes the output back into your chat. You can also use backtick syntax in custom commands and CLAUDE.md:

markdown
Current git branch: !`git branch --show-current`

This keeps your context current without manual updates.


Lab 4: Batch Execution with Auto-Approve ​

--dangerously-skip-permissions skips the per-action confirmation prompt. It is what makes large batch tasks fast, and what makes it genuinely risky on a filesystem you care about. Use it deliberately, not as a default.

Goal ​

Write an autonomous helper tool that scans all .py files for hardcoded secrets and flags them, running in auto-approve mode to skip confirmation on every file write.

Step-by-Step ​

1. Commit or stash your current work:

bash
git add -A && git commit -m "checkpoint before auto-approve batch"

This is your undo button. If the batch run does something you did not intend, git reset --hard HEAD~1 reverts everything.

2. Launch with auto-approve:

bash
claude --dangerously-skip-permissions

The terminal shows a warning that confirmations are disabled. This is not a default, it is a deliberate mode you opt into.

3. Run the batch task:

> Create a python script 'tools/secret_scanner.py' that recursively searches the current directory for hardcoded API keys, passwords, or tokens using regex. Then execute it and show the results.

Because auto-approve is active, Claude Code writes the scanner, runs it, and returns results without pausing for confirmation on each step.

4. Return to normal mode:

Exit the session and restart without the flag. Auto-approve should not be your default, it is a tool you reach for when you have a clear, scoped batch task and a git commit behind you.


Lab 5: Git as Your Safety Net ​

Auto-approve mode and multi-file refactors both carry risk. The undo button is git, and the habit is committing before anything you are not certain about.

Goal ​

Start an auto-approve session, make a deliberately destructive change, and recover using git.

Step-by-Step ​

1. Checkpoint with git:

bash
git add -A && git commit -m "checkpoint"

2. Make a destructive change:

bash
claude --dangerously-skip-permissions
> Delete all comments and docstrings in tools/secret_scanner.py and rename every variable to single characters.

3. Inspect the damage:

bash
cat tools/secret_scanner.py

The file is broken and unreadable. Good. This is why step 1 exists.

4. Revert:

bash
git checkout -- tools/secret_scanner.py

Or if there were multiple files:

bash
git reset --hard HEAD

The file is back to its pre-change state.

The habit to build: git commit before any auto-approve session, any multi-file refactor, any prompt where the words "delete," "rename all," or "refactor every" appear. One command, zero drama.


What goes wrong ​

MistakeHow you notice itThe fix
Repeating the same setup context in every promptYou are retyping your stack and conventions constantly, and the model still sometimes forgets them mid-sessionPut it in CLAUDE.md once, it loads automatically every session
Running auto-approve as a default habitAn unattended edit does something you did not intend, with no confirmation step to catch itRestart without --dangerously-skip-permissions. Reserve the flag for batch tasks you have thought through
Refactoring without a git commit behind youA broken multi-file edit has no clean way backgit commit before any refactor you are not certain about. Two seconds of typing saves an hour of recovery
Asking the model to reason about a file it has not actually seenConfidently wrong suggestions about code that does not match what is really on diskInject the real file with @path/to/file instead of describing it from memory
Custom command has a typo in the argument placeholder$ARGUMENTS appears literally in the output instead of being replacedCheck your command file: the placeholder is $ARGUMENTS (all caps, with S). Claude Code also supports $1, $2 for positional args

Confirm it worked ​

Open Claude Code and ask: "What does my project use for Python and database?" If the answer matches what you put in CLAUDE.md, Lab 1 is working. Run /agent-new TestAgent and confirm the file lands in agents/TestAgent.py, not somewhere unexpected. Inject a file with @path/to/file and confirm Claude Code references real function names from the file, not guesses. Run a one-line batch task with --dangerously-skip-permissions (after a git commit) and confirm it completes without pausing. Then git reset --hard HEAD and confirm the file reverts. If all five check out, you are using Claude Code as a tool, not a chatbot.

Next: Prompting & Context Engineering -- the craft underneath every prompt you wrote in these labs.