Practices/ Claude Code · The Terminal Craft
3 days · 15 units
Pradhya Practice 02 · Claude Code Beginner → Pro

Claude Code — The Terminal Craft.

For engineers and technical builders. The CLI patterns that take Claude from a chat companion to a senior collaborator: plan mode, subagents, slash commands, hooks, plugins, MCP servers. By the end you ship a plugin that customizes how Claude works on your code.

Audience
Developers · senior engineers
Length
3 sessions · ~3 hours each
Walk-away
A working plugin on your repo
Prereq
Comfortable in a terminal
What you’ll be able to do by the end
  • Configure CLAUDE.md so any teammate’s Claude session inherits your conventions
  • Dispatch 3–5 subagents in parallel for independent investigation
  • Write hooks that enforce your team’s rules at the harness level
  • Package your slash commands and agents into a shareable plugin
§ 02.01.01 · Unit 01

Why Claude in the terminal.

A chat window is a place to think. The terminal is where engineering happens. Claude Code is what you reach for when you want the model to operate at the level your code does.

Three differences from the chat app worth naming:

  • It lives where your work lives. The CLI runs in the directory of your project. It reads the repo. It runs your tests. It commits.
  • It is automatable. Slash commands, hooks, plugins, and MCP servers turn one-time prompts into reusable patterns.
  • It is a teammate, not a tool. Plan mode, subagents, and TaskCreate let Claude do multi-step work the way a senior engineer does — investigate, plan, dispatch parallel work, verify.
Chat app you ⇄ model talk think Claude Code your repo read · edit · test · commit agent agent agent + hooks · skills · plugins
The chat app is a place to think · Claude Code is a place to build

Validated against official Claude Code docs: it reads codebases, edits files, runs commands, integrates with development tools, and supports terminal, IDE, desktop, and browser surfaces. Source: Claude Code overview.

The shift The chat app is a place to draft. Claude Code is a place to build. The same model, in two different rooms.
§ 02.01.02 · Unit 02

Install & first run.

Install once. Authenticate once. Then claude from any project directory drops you in.

Prereq: Claude Code requires a Pro, Max, Team, Enterprise, or Console account. The free Claude.ai plan is enough for Monday Setup, but not for this practice.

macOS / Linux / WSL

# Native installer, recommended
curl -fsSL https://claude.ai/install.sh | bash
claude    # opens a browser to authenticate

macOS alternative

brew install --cask claude-code
brew upgrade claude-code    # Homebrew installs do not auto-update

Windows

# PowerShell
irm https://claude.ai/install.ps1 | iex
claude

Then, from any project

cd ~/Code/my-project
claude

You’ll get a prompt. Type a question, press enter, watch Claude work. Press Esc at any time to stop. Press Shift+Tab to switch between modes.

Install & confirm the CLI is live.

You’ll do
Run the installer for your OS, then prove the binary is on your PATH before you open a single project.
Steps
  1. Run the install command for your platform from the block above (macOS/Linux/WSL: curl -fsSL https://claude.ai/install.sh | bash).
  2. Open a new terminal tab so the updated PATH is picked up.
  3. Run claude --version.
  4. Run claude in any folder, complete the browser sign-in, then type /status and press enter.
Verify
claude --version prints a version string (e.g. 2.0.x (Claude Code)), and /status shows you signed in with a plan name. If claude is “command not found,” you skipped the new tab in step 2.

Stretch. Run claude --help and skim the flags. Note --add-dir and --print — you’ll use both later.

§ 02.01.03 · Unit 03

The CLAUDE.md file.

A markdown file at the root of your project. The most important file in Claude Code. Everything in it goes into Claude’s context at the start of every session.

Use it for: the project’s domain, how to run tests, the conventions you actually want enforced, the layout of important folders, things the model would otherwise have to guess at.

# CLAUDE.md

## What this repo is
A practice site teaching working professionals to use Claude. Static HTML, no build step.

## How to run it
Open index.html in a browser. Or `python3 -m http.server` from the root.

## Conventions
- HTML/CSS uses the Pradhya design system in assets/css/main.css.
- All JS uses createElement / textContent — never innerHTML (XSS).
- Brand voice: claim-first, no hype words (leverage / robust / transformative).

## Layout
- /index.html          — multi-practice hub
- /workshops/*.html    — individual practice pages
- /days/day{1..4}.html — Capable Series day pages
- /agents/*.py         — runnable Python scripts
- /assets/             — shared CSS and JS

## Do not
- Add a build step.
- Pull in JavaScript frameworks.
- Write 'leverage' or 'unlock'.
One rule Treat CLAUDE.md the way you treat a new hire’s first-week onboarding document. Tell it what it would take you a year to learn by reading the code.

Hand-write a four-section CLAUDE.md.

You’ll do
Drop one CLAUDE.md at the root of a repo you know, then prove Claude actually loaded it.
Steps
  1. cd into a real repo. Create CLAUDE.md at its root.
  2. Copy the template above into it and edit the four sections (What this repo is, How to run it, Conventions, Do not) to match this repo. No section may be blank.
  3. Start claude in that folder.
  4. Ask Claude:
    What conventions from CLAUDE.md should I follow in this repo? List them as bullets, quoting the file.
Verify
ls CLAUDE.md shows the file exists, and Claude’s reply quotes at least one line you wrote in the Conventions section verbatim. If it invents conventions you didn’t write, it didn’t read the file — confirm the filename is exactly CLAUDE.md at the repo root.

Stretch. Add a deliberately specific rule (“tests live in /tests, never /__tests__”), then ask Claude where a new test should go. It should cite your rule.

§ 02.01.04 · Unit 04

Onboarding with /init.

Don’t write CLAUDE.md from scratch. Run /init and let Claude read your repo and propose one.

$ claude
> /init

Claude explores the repo, infers the language and frameworks, finds your test command, and proposes a CLAUDE.md. You edit it before accepting. The first time it’s right about ~70% of conventions; you fill in the rest.

The other useful first-week commands

  • /help — list every command available.
  • /config — model, theme, status line.
  • /memory — durable preferences across sessions.
  • /review — review uncommitted changes.
  • /clear — start a fresh conversation.

Let /init draft the file, then audit it.

You’ll do
Run /init on a repo that has no CLAUDE.md, accept it, and check what Claude got right.
Steps
  1. Pick a repo with no CLAUDE.md yet (or temporarily rename an existing one). Start claude there.
  2. Run /init. Let Claude explore the repo and propose a CLAUDE.md.
  3. Read the proposal. Fix at least one thing it got wrong or left vague, then accept so the file is written.
  4. Start a fresh session (/clear or relaunch) and ask Claude:
    Recite one convention from this repo’s CLAUDE.md and tell me which section it came from.
Verify
ls CLAUDE.md shows the generated file exists, and the fresh session recites one convention from it and names the section. If it says “no CLAUDE.md found,” you didn’t accept the proposal in step 3.

Stretch. Run git diff on the file after a week of edits — the conventions you add by hand are the ones /init couldn’t infer. Those are the highest-value lines.

§ 02.01.05 · Unit 05

Plan mode.

For any change bigger than a one-line fix, enter Plan mode first. Claude investigates, thinks, and proposes a plan — without touching the code. You approve. Then it executes.

user prompt Plan mode read · think · propose no writes approve execute Shift+Tab twice to enter
Read-only investigation · then approval · then execution

Enter plan mode with Shift+Tab twice (cycles through Auto → Plan → AcceptEdits). Or any prompt that starts with “plan” or “design” will trigger it.

> [plan mode]
Plan how to add a dark-mode toggle to this practice site.
- Read the CSS to see how color tokens are defined.
- Identify which surfaces need dark variants.
- Propose the toggle's location and behavior.
- Suggest where the preference should be stored.
Do not touch any files yet.

Plan mode is read-only. Claude can look at anything, but cannot edit until you exit plan mode and approve the plan. This is the difference between a senior engineer and an over-eager intern.

The rule Plan first if the change touches more than one file, modifies a public interface, or you can’t fully predict the diff in your head.

Get a plan before a single edit.

You’ll do
Enter plan mode on a real multi-file change and confirm Claude proposes before it touches anything.
Steps
  1. Start claude in a repo. Press Shift+Tab twice until the mode indicator reads plan.
  2. Ask for something that spans more than one file, e.g.:
    Plan how to add a /health endpoint that returns build version and uptime. List exactly which files you’d touch and what each change is. Do not edit anything yet.
  3. Read the plan. Push back on one step you disagree with and ask it to revise.
  4. Approve to exit plan mode and let it execute — or /clear if you just wanted the plan.
Verify
The plan names specific files (a list like src/app.py, tests/test_health.py) before any edit, and git status shows zero changed files while you were still in plan mode. If files changed before you approved, you were not in plan mode — re-check the indicator in step 1.

Stretch. Ask the plan-mode session for a 1–5 confidence score on its own plan. Low confidence is your cue to add detail before you approve.

§ 02.02.01 · Unit 06

Slash commands.

A slash command is your own prompt, named, versioned, in your repo. Write the prompt once, call it from any session.

Put them in .claude/commands/ in your repo (project-scoped) or ~/.claude/commands/ (user-scoped).

A working example: /audit-typescript

---
description: Audit TypeScript files for `any` usage and missing null checks.
allowed-tools: [Bash, Read, Grep]
---

# Audit TypeScript hygiene

You are a senior TypeScript engineer reviewing this codebase for type-safety hygiene.

Steps:
1. Find every `: any` and `as any` in `src/**/*.ts`.
2. For each one, decide if it is justified (escape hatch for a known limitation) or accidental.
3. Find every `!.` (non-null assertion) and verify the line above it actually guarantees non-null.
4. Produce a markdown table: file | line | severity (low/med/high) | suggested fix.

No preamble. Just the table.

Then in any session: /audit-typescript. Claude reads the prompt, follows the steps, and outputs the table. The exact file above ships with this practice — download audit-typescript.md (right-click → Save As) and drop it in .claude/commands/ to use it verbatim. You’ll bundle this same command into a plugin in Unit 11.

Slash commands accept arguments ($1, $ARGUMENTS), can include bash with !`...`, and can reference files with @path/to/file. The full spec is in the official docs.

Write a slash command for your repo.

You’ll do
Turn a prompt you keep retyping into a named command, then run it.
Steps
  1. In a repo, create .claude/commands/. Add a file named after the command you want, e.g. standup.md.
  2. Give it frontmatter and a prompt. Starter you can paste and edit (no repo of your own? this works on any git repo):
    --- description: Summarize what changed since yesterday for a standup. allowed-tools: [Bash, Read] --- # Standup summary Run `git log --since="1 day ago" --oneline` and read the diff stat. Write three bullets: what landed, what is in progress, what is blocked. No preamble.
  3. Start claude (or run /clear if already open so it re-scans commands). Type /help.
  4. Run your command: /standup.
Verify
/help lists /standup (or your chosen name), and running it produces the three-bullet output. If it’s missing from /help, the file isn’t in .claude/commands/ or you didn’t restart/clear the session.

Stretch. Make it take an argument: change the body to summarize $ARGUMENTS days back, then call /standup 7.

§ 02.02.02 · Unit 07

Hooks.

A hook is a shell command (or prompt) the harness runs in response to an event — before a tool call, after one, on session start, etc. This is where you enforce your conventions.

Events worth hooking

EventUse it for
PreToolUseBlock destructive commands. Inject context.
PostToolUseAuto-format on Write. Run a linter.
SessionStartInject project context. Set status line.
UserPromptSubmitRewrite or augment the user’s prompt.
Stop / SubagentStopVerify the goal is met before ending.
PreCompactSave state before context summarization.

Example: block npm install of unknown packages

# .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/check-package.sh"
          }
        ]
      }
    ]
  }
}

# The script reads the tool call as JSON from stdin:
#   command=$(jq -r ".tool_input.command")
#   if [[ "$command" == "npm install"* ]]; then ... ; fi
# Exit 0 to allow, exit 2 to block (with stderr message).

The script reads the tool-call payload as JSON on stdin (use jq to parse). Exit 0 to allow the action, exit 2 with stderr to block. Hooks are how you turn “rules I keep typing into every conversation” into actual guardrails.

The complete, working script above ships with this practice: download check-package.sh (right-click → Save As). It blocks npm install <pkg> whenever the package is not already in package.json or on a .claude/allowlist.txt — forcing the change into a reviewable diff. You’ll reuse this exact hook inside the plugin in Unit 11.

Install the shipped hook and watch it block.

You’ll do
Wire the shipped check-package.sh into a repo, then ask Claude to do the forbidden thing and confirm it’s refused.
Steps
  1. In a repo that has a package.json (any Node project; or run npm init -y in an empty folder), make .claude/hooks/ and save check-package.sh into it. Make it executable: chmod +x .claude/hooks/check-package.sh. Confirm jq is installed (jq --version; else brew install jq).
  2. Create .claude/settings.json with the PreToolUse hook from the block above, pointing command at .claude/hooks/check-package.sh.
  3. Start claude. Ask it:
    Run: npm install left-pad
Verify
The Bash tool call is blocked and Claude surfaces the script’s message (❌ Blocked: left-pad … “not in package.json and not on the allowlist”). Now ask it to install a package that is already in package.json — that one is allowed. If nothing is blocked, the hook isn’t executable (re-run chmod +x) or jq is missing.

Stretch. Add left-pad to .claude/allowlist.txt (one name per line) and re-ask. It should now pass — the allowlist is your escape hatch.

§ 02.02.03 · Unit 08

Output styles.

An output style changes how Claude communicates — tone, length, format — without changing what it does. A persistent persona for the session.

Built-in styles include explanatory (educational, with insights), learning (interactive, asks you to write some code), and the default. You can write your own under .claude/output-styles/.

$ claude
> /output-style explanatory

# from now on, Claude will explain its choices as it works

Output styles are good for: pair-programming sessions where you want to learn, demos where the audience is watching, and reviews where the reasoning matters more than the diff.

Flip the style and see the difference.

You’ll do
Ask the same question under two styles and compare the answers.
Steps
  1. Start claude in any repo. Ask a small task, e.g. “Add a docstring to the first function in <file>.” Note how terse the reply is.
  2. Run /output-style explanatory.
  3. Ask an equivalent task on a different function.
  4. Run /output-style with no argument to see the list and switch back to default.
Verify
Under explanatory the reply now contains a short rationale (a “why” or “insight” aside) that the default reply did not. The diff it produces is the same; only the narration changed. If both replies read identically, the style didn’t switch — re-run step 2 and check for a confirmation line.

Stretch. Write your own style file under .claude/output-styles/ (e.g. “reply as terse code-review notes, no prose”) and activate it by name.

§ 02.02.04 · Unit 09

Subagents in parallel.

A subagent is a separate Claude instance, dispatched from the main one, with its own conversation and its own tools. Use them for independent work that can run in parallel.

main agent subagent A search src/ subagent B audit deps subagent C check tests three in parallel · each its own context
Parallel subagents · independent context · summaries to parent

Two scenarios where subagents earn their cost:

  • Independent investigation. “Find every place we use feature X” can dispatch 5 subagents over 5 directories, each searching in parallel. The main agent gets the summaries back, not the raw output.
  • Isolation. A subagent with its own context window can do exploratory work without polluting the main agent’s context. The main agent only sees the conclusion.
# In the main session
> Use 3 subagents in parallel:
>   1. one searching src/ for any TODO comments older than 6 months
>   2. one auditing package.json for outdated dependencies
>   3. one looking for tests that haven't run in CI in the last month
> Each returns a 5-bullet summary. Combine into one report.
The trade-off Subagents cost more tokens (you pay for each one’s context). The win is wall-clock time: three 20-second searches in parallel beat one 60-second sequential search. Use them when the work is genuinely independent, not just to look impressive.

Dispatch three subagents at once.

You’ll do
Send three independent investigations into the same repo and get one merged report.
Steps
  1. Start claude in a repo with some history (any project you have works).
  2. Ask for three parallel jobs:
    Use 3 subagents in parallel: (1) list the 5 largest files in the repo, (2) find every TODO/FIXME comment, (3) summarize what the README claims the project does. Each returns 3 bullets. Combine into one report with three labeled sections.
  3. Watch the tool calls fan out, then merge back.
Verify
You get one report with three clearly labeled sections, and the transcript shows three Task/subagent calls dispatched together (not three sequential searches in the main thread). If it did the work inline without subagents, say “use actual subagents, in parallel” and re-run.

Stretch. Re-run the same three jobs sequentially in one prompt and compare wall-clock time. The parallel version should finish noticeably sooner.

§ 02.02.05 · Unit 10

Memory and preferences.

Memory is the system that lets Claude remember things across sessions. Use it for the preferences and corrections that should not have to be repeated.

Memory entries are typed:

  • user — who you are, your role, your knowledge.
  • feedback — corrections and validations of approach.
  • project — in-progress work, goals, decisions.
  • reference — pointers to external systems (where Linear tickets live, etc.).
> Remember: I prefer terse responses with no trailing summaries.
> Remember: for this repo, tests live in /tests not /__tests__.

The next session, Claude reads the relevant memories before it starts. Use memory to stop repeating yourself; use CLAUDE.md for things that belong with the repo.

Make a memory survive a restart.

You’ll do
Store one preference, end the session, start a new one, and confirm Claude still knows it.
Steps
  1. Start claude. Save a preference:
    Remember: I prefer terse responses with no trailing summaries.
  2. Confirm it was captured (run /memory to see stored entries).
  3. Quit Claude completely, then start a brand-new session in the same place.
  4. Ask:
    What response style do you remember I prefer?
Verify
The fresh session answers “terse, no trailing summaries” without you repeating it, and /memory lists the entry. If it doesn’t recall it, the “Remember:” line wasn’t committed — check it appears under /memory in step 2.

Stretch. Store a repo-specific fact instead (“Remember: tests live in /tests”), then decide: did that belong in memory, or in CLAUDE.md where the whole team inherits it?

§ 02.03.01 · Unit 11 · Hands-on · 30 min

Plugins.

A plugin bundles slash commands, hooks, agents, and skills into one package. The shape of every Claude Code customization that ships beyond your laptop.

my-plugin/ plugin.json commands/ hooks/ agents/ skills/ one zip · install with one command
A plugin · commands + hooks + agents + skills, bundled

The plugin layout

The manifest lives in a .claude-plugin/ folder; the component directories sit at the plugin root, where Claude Code auto-discovers them. You only create the folders you actually use.

pradhya-review/
├── .claude-plugin/
│   └── plugin.json       # manifest — MUST be inside .claude-plugin/
├── commands/             # slash commands (auto-discovered)
│   └── audit-typescript.md
├── hooks/
│   └── hooks.json        # event handlers
├── check-package.sh      # the hook script hooks.json points at
└── agents/               # (optional) subagents this plugin defines

The manifest

Just metadata — no components block. Claude Code finds commands/ and hooks/ by convention. This is the exact plugin.json that ships with this practice:

{
  "name": "pradhya-review",
  "version": "0.1.0",
  "description": "Pradhya-flavored hooks + slash commands for AI workshop content. Use to enforce house style in repos that follow the Pradhya voice guide.",
  "author": {
    "name": "Pradhya",
    "url": "https://pradhya.studio"
  },
  "license": "MIT",
  "keywords": ["claude-code", "code-review", "typescript", "linting", "style-guide"]
}

The hook wiring

The plugin’s hooks/hooks.json registers the PreToolUse hook from Unit 07 against every Bash call. The shipped hooks.json uses a bare ./check-package.sh — right for the standalone .claude/ setup in Unit 07. Inside a plugin, point at the script with ${CLAUDE_PLUGIN_ROOT} so it resolves no matter which project the plugin is installed into:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/check-package.sh" }
        ]
      }
    ]
  }
}

Install it the way W10 teaches: a local marketplace

Claude Code installs plugins from marketplaces — a folder (or repo) with a .claude-plugin/marketplace.json listing one or more plugins. Point one at your local plugin, then install by name@marketplace, exactly the syntax from Power Patterns → Plugins as installable packages.

# In Claude Code, register the folder that holds your plugin as a marketplace:
/plugin marketplace add ./pradhya-review

# Then install your plugin from it (name@marketplace):
/plugin install pradhya-review@pradhya-review

# Quicker for a throwaway test — load the folder directly, no marketplace:
#   claude --plugin-dir ./pradhya-review

Build & install the pradhya-review plugin.

You’ll do
Assemble Unit 06’s command and Unit 07’s hook into one installable plugin, then prove both halves work.
Steps
  1. Make the folders: mkdir -p pradhya-review/.claude-plugin pradhya-review/commands pradhya-review/hooks.
  2. Save the manifest above into pradhya-review/.claude-plugin/plugin.json (or download the shipped plugin.json there).
  3. Put the command in place: save audit-typescript.md into pradhya-review/commands/.
  4. Wire the hook: save check-package.sh into pradhya-review/ (the plugin root). Make it executable: chmod +x pradhya-review/check-package.sh. Save the ${CLAUDE_PLUGIN_ROOT} version of hooks.json shown above into pradhya-review/hooks/hooks.json (start from the shipped hooks.json and change the one command line).
  5. Start claude from the directory that contains pradhya-review/, in a repo that has a package.json. Register and install:
    /plugin marketplace add ./pradhya-review
    /plugin install pradhya-review@pradhya-review
  6. Type /help, then ask Claude to run npm install left-pad.
Verify
Two observable checks: (1) /help lists /audit-typescript (the command came from your plugin); and (2) asking Claude to npm install left-pad is blocked by the hook with the ❌ Blocked: left-pad message. If /help omits the command, the manifest isn’t in .claude-plugin/; if the install isn’t blocked, check-package.sh isn’t executable, isn’t at the plugin root, or jq isn’t installed (jq --version).

Stretch. Run /audit-typescript against a TypeScript repo and read its table. Then publish for real: push pradhya-review/ to a Git repo and have a teammate /plugin marketplace add <your-repo-url> — the same install, one command, on their machine.

Walk-away artifact You now have pradhya-review: one installable plugin bundling a slash command and a guardrail hook. That is the shape of every Claude Code customization that ships beyond your laptop — and the exact thing your team installs with one /plugin install.
§ 02.03.02 · Unit 12

MCP servers.

The Model Context Protocol lets Claude talk to external systems through a standard interface. Write one MCP server, and every Claude app — chat, Cowork, Code — can use it.

An MCP server exposes:

  • Tools — functions Claude can call (read a Slack message, query a database).
  • Resources — data Claude can read (a Notion page, a row in Postgres).
  • Prompts — reusable templates the user can pick from.

MCP servers are usually small Python or TypeScript programs. The official SDK does most of the work. Here’s the smallest possible MCP server in Python:

# weather_mcp.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather")

@mcp.tool()
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    # imagine a real API call here
    return f"{city}: 102F, sunny"

if __name__ == "__main__":
    mcp.run()

Wire it up in Claude Code via .mcp.json at the project root. Now every session in this repo can call get_weather. The same server can be wired into Claude Desktop (Cowork) with no changes — one protocol, many surfaces.

Stand up the weather MCP server and call it.

You’ll do
Run the 9-line server above, register it, and have Claude invoke your tool.
Steps
  1. In an empty folder, save the code above as weather_mcp.py. Install the SDK: pip install "mcp[cli]".
  2. Create .mcp.json at the folder root registering the server:
    { "mcpServers": { "weather": { "command": "python3", "args": ["weather_mcp.py"] } } }
  3. Start claude in that folder. Run /mcp to confirm the weather server connected.
  4. Ask:
    Use the weather tool to tell me the weather in Austin.
Verify
/mcp lists weather as connected with a get_weather tool, and Claude’s answer returns Austin: 102F, sunny — the stub string from your code, proving it called your server (not its own knowledge). If /mcp shows no server, check .mcp.json is at the folder root and python3 weather_mcp.py runs without import errors.

Stretch. Replace the stub return with a real call to a free weather API. The tool signature stays the same; every surface that already has it keeps working.

§ 02.03.03 · Unit 13

Fast mode and effort.

Two knobs that change how Claude trades off speed against quality. Reach for them when the default isn’t the right shape.

Fast mode

Trades a bit of reasoning depth for noticeably faster responses. Available on Opus 4.6+. Good for: short interactive turns, chat-like back-and-forth, anything where wall-clock latency matters more than the last 5% of quality.

> /fast

Effort levels

Effort controls how much computation Claude spends on each turn. Higher effort = more careful work, more cost, slower turns. Lower effort = quicker, cheaper, looser. Set per-session.

> /effort max     # for the hard ones
> /effort medium  # the default
> /effort low     # quick edits

Use max when the cost of being wrong is high. Use low when you’re iterating fast on small changes.

Going deeper: Power Patterns → Effort & fast mode compares diffs across effort levels and covers the “strong model + high effort to plan, fast model to execute” combo.

Feel the effort dial on one task.

You’ll do
Run the same small task at two effort levels and compare what comes back.
Steps
  1. Pick a task with a tricky edge case (e.g. “write a function that parses a duration like 1h30m into seconds”).
  2. In a fresh session run /effort low, then ask for it. Note the result.
  3. /clear, run /effort max, ask for the same thing.
  4. Compare: does the max answer handle more edge cases (empty input, 90m, bad format)?
Verify
The max run visibly does more — more edge cases covered, or tests added, or a caveat the low run skipped. You can point to a concrete difference between the two outputs. If they’re identical, the task was too easy to show the dial; pick a harder one.

Stretch. Try /fast on a chat-like back-and-forth and notice the latency drop versus the quality you give up.

§ 02.03.04 · Unit 14 · Real workflow

Real workflow: feature development.

A realistic feature-dev session, end to end. The pattern that turns Claude Code from a typing aid into a collaborator.

  1. Worktree. /worktree or git worktree add ../feature-X feature-X. Isolate from main.
  2. Plan. Shift+Tab Shift+Tab. Describe the feature. Read the plan carefully. Push back where it’s wrong.
  3. Dispatch. Exit plan mode. Let Claude implement. For multi-file changes, ask it to use TaskCreate to track its own steps.
  4. Verify. npm test or pytest. Read the diff with /diff or git diff. Don’t merge what you didn’t read.
  5. Critique. /review dispatches a fresh subagent to review the diff with no context bias.
  6. Commit. Claude can write the commit message — but you write the PR description. The model knows the diff; you know why it matters.
The trap to avoid The temptation to let Claude commit and push and open a PR in one breath. Don’t. Every step is a chance to catch a mistake the model couldn’t see. The slowdown is the value.

Run the full loop on one real change.

You’ll do
Take a small feature from worktree to reviewed diff using all six steps above — without letting Claude commit-and-push in one breath.
Steps
  1. Worktree: git worktree add ../feat-x feat-x and start claude there.
  2. Plan: Shift+Tab twice, describe a small feature (a flag, an endpoint, a helper), read the plan, push back on one step.
  3. Dispatch: approve and let it implement.
  4. Verify: run the test command, then read the change with git diff.
  5. Critique: run /review on the diff.
  6. Commit: let Claude write the commit message; you write the PR description.
Verify
At the end: the work is on a separate worktree (git worktree list shows it), the feature’s tests pass, and you read the full diff before committing. The commit exists but is not pushed automatically — you decide when to push. If Claude pushed on its own, you skipped the deliberate stop in step 6.

Stretch. Add a Stop hook (Unit 07 pattern) that runs your tests and refuses to let the session end while they’re red.

§ 02.03.05 · Unit 15 · Real workflow

Real workflow: PR review.

A multi-agent PR review pipeline that catches the things humans miss. Six specialized agents, one orchestrator, one report.

Each agent focuses on a single failure mode. They run in parallel against the diff. The orchestrator merges their reports, drops duplicates, and ranks by severity.

AgentLooks for
code-reviewer Style violations, project convention drift, logic errors.
silent-failure-hunter Bare except blocks, swallowed errors, inappropriate fallbacks.
type-design-analyzer Types that fail to enforce their invariants.
comment-analyzer Comments that have drifted from the code they describe.
pr-test-analyzer Coverage gaps for the new functionality and edge cases.
security-review Injection vectors, credential exposure, auth gaps.

Wire it up as a slash command plus six agent files (the /ultrareview pattern). Each agent is one markdown file in agents/. The orchestrator is a single slash command that dispatches them in parallel and aggregates results. The complete pack ships with this practice — the orchestrator ultrareview.md, the six agents (security, performance, tests, types, comments, simplify), and the README with copy-paste install steps.

$ claude
> /ultrareview
# dispatches 6 agents in parallel against the current diff
# returns a ranked report of issues, with confidence scores

The shape generalizes: every quality gate worth automating is one specialized agent. The orchestrator is what makes the team feel like a team.

Install /ultrareview and run it on a real diff.

You’ll do
Drop the shipped six-agent pack into .claude/, then review an actual change with one command.
Steps
  1. In a repo, make .claude/commands/ and .claude/agents/.
  2. Save ultrareview.md into .claude/commands/, and all six agent files (security, performance, tests, types, comments, simplify) into .claude/agents/.
  3. Make a small change in the repo (edit a file, or check out a feature branch). Leave it unstaged or staged.
  4. Start claude, type /help to confirm /ultrareview is listed, then run /ultrareview.
Verify
You get back one report with a ranked “Top issues” list and six labeled sections (Security, Performance, Tests, Types, Comments, Simplify), each finding carrying a severity and a file:line. If /ultrareview says there’s nothing to review, you have no diff — make a change first (step 3).

Stretch. Wrap the pack into your pradhya-review plugin from Unit 11 (move the files under commands/ and agents/ at the plugin root) so a teammate installs the whole reviewer with one /plugin install.

Your closing exercise Pick one workflow from your week that takes more than 15 minutes and is the same shape every time. Build it as a plugin. Use the patterns from Days 01–03. The compound is not the plugin — it is the practice of building plugins.