Coding agent

Claude Code

Claude Code is Anthropic’s agent that reads a repository, edits files, and runs commands from the terminal. Asking it a question is easy. Leaving it alone with real work means controlling permissions, memory, and the procedures it repeats.

IntermediateTerminal, IDE, or CI

What it does on each task

AnalogyClaude Code is a coworker who can open the repo, run the tests, and edit files. Trusting the folder lets them in the room. It is not a blank cheque to push, delete, or send data out.
Data flow
You describe an outcome→Read / search→Command or edit→Ask if not allowed→Diff

The same agent runs in the terminal, VS Code, JetBrains, a desktop app, and on the web. It needs a paid plan or an API key. Permissions, hooks, and a short project file are how the cheque stays small. Ask for a plan before a multi-file edit.

Starter

print("cd your-repo")
print("claude")
print("Explain how a short code is created. Do not edit files.")

Example

“Do not edit files” is a real first prompt on a codebase you do not know. You get a map before a diff.

You describe an outcome. Claude Code reads files, searches, runs commands, and edits, one tool call at a time. It asks before actions you have not allowed. The same agent runs in the terminal, VS Code, JetBrains, a desktop app, and on the web. It needs a paid Claude plan or an Anthropic API key.

cd your-repo
claude
# trust the folder when asked, then:
# "Explain how a short code is created and resolved. Do not edit files."

Trusting a folder lets the agent read it. It is not a blank cheque to push, delete, or curl data out. Permissions, hooks, and a tight CLAUDE.md are how you keep the cheque small.

Start with an explanation, not an edit

AnalogyThe first session is a tour, not a renovation. You ask where the pipes are. You do not start knocking down walls.
Data flow
Trust the folder→Ask for a map→Read the map→Then a plan→Then a diff

On a repo you did not write, “analyse this project” replaces a one-hour knowledge transfer. Correct a wrong plan in one paragraph instead of reverting six files. Review prompts should say “flag missing tests,” not “improve this,” or you get a noisy rewrite.

Starter

prompts = [
    "Explain how a short code is created and resolved. Do not edit files.",
    "Where would a 4-character code collide with a 6-character code?",
    "Add a failing test for that, then fix it, then show the diff.",
]
print(prompts[0])

Example

A stack trace pasted in should name the file to open first. You still confirm before anyone edits.

The highest-value first prompt on a codebase you do not know is “analyse this project”. On a small LangChain bootcamp repo that means: which notebooks exist, what they teach, what is uncommitted. You get a knowledge transfer without booking a teammate.

Prompts that stay useful

  • “Where is the bug if a short code of length 4 sometimes collides? Only read.”
  • “Add a failing test for that collision, then fix it, then show me the diff.”
  • “Review this change the way a teammate would. Do not rewrite style.”

Ask for a plan before a multi-file edit. If the plan touches the wrong module, you correct one paragraph instead of reverting six files.

CLAUDE.md is project memory

AnalogyCLAUDE.md is the note on the fridge. It is there every morning. You stop repeating yourself, and the next person sees the same note.
Data flow
Repo root→CLAUDE.md→Every new session reads it→CI can read it too

Keep it short and true. A 400-line style guide gets ignored in the middle. User-level memory is for preferences across repos. Project rules stay in the repo. If the file lies, the agent will follow the lie confidently.

Starter

# CLAUDE.md
Short codes are 6 characters, [a-z0-9].
Run tests with: python -m pytest
Do not add dependencies.
Never commit .env.
Prefer a failing test before a fix.

Example

“Use pytest, not unittest” in that file saves the argument on every session, including a review bot in CI.

Instructions you retype every session belong in CLAUDE.md at the repo root. Claude reads it when a session starts.

# CLAUDE.md
This repo is a tiny URL shortener: three Python files, no framework.

- Short codes are 6 characters, [a-z0-9].
- Run tests with: python -m pytest
- Do not add dependencies.
- Never commit .env or print secrets.
- Prefer a failing test before a fix.

Keep it short and true. A 400-line style guide gets ignored in the middle. A user-level memory is for preferences across repos (“use pytest”). Project rules stay in the repo so the next person, and CI, see the same file.

Slash commands, skills, hooks, subagents

AnalogyA slash command is a saved sentence. A skill is a saved procedure. A hook is a lock. A subagent is a coworker in another room so your room does not fill with clutter.
Data flow
Prompt you retype→Slash command→Multi-step procedure→Skill→Must never happen→Hook

Hooks beat reminders. “Please do not read .env” is a request. A deny rule is a control. Use requests for taste and rules for secrets. MCP servers attach external tools (issues, browsers, internal APIs) without teaching the agent a one-off shell pipeline. A subagent is for a wide search that would flood the main conversation.

Starter

deny = ["git push", "cat .env", "rm -rf"]
allow = ["python -m pytest", "git diff", "git status"]
print("deny", deny)
print("allow", allow)

Example

“Run the tests and summarise failures” becomes a slash command. Blocking `cat .env` becomes a deny rule, not a sentence in the prompt.

PieceWhat it isUse it for
Slash commandA saved prompt you invoke with /nameThe paragraph you retype: “write a pytest for the function I mention”
SkillA procedure, often a folder with a SKILL.mdA multi-step job that should happen the same way every time, such as “add an API endpoint”
HookYour script at a fixed point (before a tool, after an edit)A rule that is code. A prompt can be talked out of a hook. A hook that rejects rm -rf cannot.
SubagentA side task with its own contextA wide search that would flood the main conversation
MCP serverExternal tools over the Model Context ProtocolIssue trackers, browsers, internal APIs
# A hook idea: block edits outside the repo, and block reading .env
# Settings also support allow and deny lists for shell commands.
# Deny: git push, curl | sh, cat .env
# Allow: python -m pytest, git diff, git status
Hooks beat reminders. “Please do not read .env” is a request. A deny rule is a control. Use requests for taste, and rules for secrets and production systems.

Practice on a link shortener

AnalogyPractice on a program you can hold in your head. If you cannot tell the agent is wrong, the repo is too big for a first lesson.
Data flow
Read the three files→Failing test→Fix→You run pytest

A link shortener with one bug (codes shorter than 6) is enough. Ask for the explanation, then a test that fails on "ab", then the fix. Run pytest yourself. Unattended mode comes after the tests exist, not before.

Starter

ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"

def looks_like_code(text: str) -> bool:
    return len(text) == 6 and all(ch in ALPHABET for ch in text)

print(looks_like_code("ab"))      # False, too short
print(looks_like_code("ab12cd"))  # True

Example

The bug is an alias: a 2-character string matching a 6-character code. The test is assert not looks_like_code('ab'). The fix is the length check.

A good teaching repo is three files: create a short code, resolve it, and a bug that only appears sometimes (a collision, an off-by-one, a missing character in the alphabet). You can hold the whole program in your head, so you can tell when the agent is wrong.

# shortener.py  (the bug: codes can be shorter than 6, so "ab" aliases "ab12cd")
import secrets
ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"

def create_code(length: int = 6) -> str:
    return "".join(secrets.choice(ALPHABET) for _ in range(length))

def looks_like_code(text: str) -> bool:
    return all(ch in ALPHABET for ch in text)  # forgot: len(text) == 6

A solid session: ask for an explanation, ask for a test that fails on "ab", then ask for the fix, then run pytest yourself. Unattended mode (“fix the bug and stop”) is something you turn on after the tests exist, not before.

Day-to-day uses beyond the tutorial repo

  • Onboarding: “map the request path from the HTTP handler to the database”.
  • Migrations: “list every caller of create_code before we change its signature”.
  • Incident: paste a stack trace and ask which file to open first. You still confirm before editing.

Headless mode and review in CI

AnalogyHeadless mode is the same coworker on a night shift. They are useful with a narrow job and the same project note. They are noisy if the job is “improve this pull request.”
Data flow
Pull request→CI starts the agent→CLAUDE.md→Comment: missing tests or secrets→You decide

A review bot should share the repo’s CLAUDE.md. Compare this with an open agent harness: both can plan, edit, spawn subagents, and speak MCP. This one is wired to Claude. An open harness can point at other models. Procedures you write as files travel further than a habit that only lives in one chat.

Starter

job = "Flag missing tests and anything that looks like a secret. Do not rewrite style."
print(job)

Example

“Flag a missing test for looks_like_code” is a good CI comment. “Clean up the whole file” is how you get a drive-by rewrite.

The same agent can run without an interactive terminal: a script, or a GitHub Action that comments on a pull request. That reviewer is useful when it has the same CLAUDE.md and a narrow job (“flag missing tests and secrets”). It is noisy when the prompt is “improve this PR”.

Compare this with Deep Agents: both plan, edit files, spawn subagents, and speak MCP. Claude Code is Anthropic’s product around Claude. Deep Agents is the open harness you can point at other models. Skills you write as markdown travel further than a habit that only lives in one chat.

Practice

  • Write a 8-line CLAUDE.md for a repo you actually work in.
  • Add one deny rule you wish a past agent had obeyed.
  • Turn “run the tests and summarise failures” into a slash command.
  • Fix looks_like_code only after a test fails on a 2-character string.