Claude Code CLI
← Back to labs index

Claude Code CLI

These exercises follow the build-your-own labs capability sequence, using Claude Code’s built-in agent loop instead of writing one. Rather than a toy prompt per lab, you build one small Python app (a synthetic pet-store order calculator) in Lab 2A and keep extending it. Each later lab adds one harness capability to the same codebase, so you see what the harness adds to real work rather than to a quiz question.

Lab Capability What you do to the app
0 Foundry setup and authentication Create app/ as a git repo; verify a live call
1 Constrained baseline vs agent Same question with tools off and on
2A Built-in tool loop (files, shell, git, tests) Build the app; find a regression with git history
2B Scoped rules and hooks Rule for money math; hooks that block edits and auto-run tests
3 Sessions: continue, resume, fork Pause work, change the repo outside Claude, resume, fork
4 Plan mode Plan, critique and then execute a discount-codes feature
5 Project memory (CLAUDE.md) and freshness /init, team conventions, edit memory mid-session
6 Permissions and approval Allow/ask/deny rules vs a fake secret and a prompt injection
7 Observability Headless JSON event stream, cost, context, transcripts, OTel
8 Skills and MCP release-notes skill; a local synthetic orders MCP server
9 Subagents and background agents Parallel security review + test writing; --bg sessions
10 Context compaction 6,000-line log, /context, focused /compact, fact check
11 Bounded loops Prompted loop vs a deterministic Stop-hook gate; budget caps
12 Human-orchestrated routing graph Classifier routes tickets to tool-scoped specialist calls
13 Planner, generator, evaluator Scripted PGE loop with an independent evaluator
14 Honest comparison Same task across Claude Code, Codex and your own harness

Prerequisites

Working in app/

existing-harnesses/claude-code/
├── claude-code.env.ps1 / .sh   # Lab 0, gitignored: Foundry settings
├── .azure-cli/                 # Lab 0, gitignored: scoped az login
├── app/                        # Lab 0, gitignored: YOUR practice app (own git repo)
└── labNN-*/                    # instructions + assets you copy into app/

Every lab starts the same way. Open a terminal in app/ and load the Lab 0 setup:

cd existing-harnesses\claude-code\app
. ..\claude-code.env.ps1
cd existing-harnesses/claude-code/app
source ../claude-code.env.sh

Always run claude from app/, never from the repo root. Claude Code reads CLAUDE.md, .claude/ settings and git state from where it starts, and you want only the practice app in scope.

Checkpoints are git tags. Each lab ends with git tag labNN-done, and each lab README states which tag it starts from. The model’s output varies between runs, so your code will differ from someone else’s. That is expected; the prompts describe goals, not exact code.

To redo a lab, return to its starting tag:

git switch main
git reset --hard lab02a-done   # the tag the lab starts from
git clean -fd                  # remove untracked files (keeps gitignored .env, .runs)

If you fall far behind, or your app drifted too far to follow along, re-run Lab 2A from lab00-done.

Seeing what the harness did

In interactive mode, each tool call appears inline above the answer, as lines like ⏺ Bash(python -m pytest -q) or ⏺ Update(pricing.py). Press Ctrl+O to expand a collapsed tool result. In headless mode (claude -p "...") only the final answer prints, unless you add --output-format stream-json --verbose (used from Lab 7 on). Every session is also saved as a JSONL transcript under ~/.claude/projects/<encoded-app-path>/ (%USERPROFILE%\.claude\projects\... on Windows).

Safety

Use only the synthetic data these labs create. Plan mode, CLAUDE.md, and .claude/rules/ are instructions, not security boundaries. Permission rules and hooks are enforcement, but only for the tools and patterns they match (Lab 6 shows the gaps). Do not point the agent at real files, production resources or secrets. Never commit keys or tokens, or paste them into prompts or transcripts. Live runs use your Foundry quota and may incur charges. The cost figures Claude Code reports are list-price estimates, not your bill. Record unavailable metrics as unavailable. The build-your-own labs remain Entra-only.